diff --git a/appframework/glmdisplaydb_linuxwin.inl b/appframework/glmdisplaydb_linuxwin.inl index 3e1d76a8..daa28d85 100644 --- a/appframework/glmdisplaydb_linuxwin.inl +++ b/appframework/glmdisplaydb_linuxwin.inl @@ -42,10 +42,11 @@ void GLMRendererInfo::Init( GLMRendererInfoFields *info ) m_info.m_atiNewer = true; m_info.m_hasGammaWrites = true; + m_info.m_cantAttachSRGB = false; // If you haven't created a GL context by now (and initialized gGL), you're about to crash. - m_info.m_hasMixedAttachmentSizes = gGL->m_bHave_GL_ARB_framebuffer_object; + m_info.m_hasMixedAttachmentSizes = gGL->m_bHave_GL_EXT_framebuffer_object; m_info.m_hasBGRA = gGL->m_bHave_GL_EXT_vertex_array_bgra; // !!! FIXME: what do these do on the Mac? @@ -64,8 +65,15 @@ void GLMRendererInfo::Init( GLMRendererInfoFields *info ) m_info.m_hasNativeClipVertexMode = true; } +#ifdef TOGLES + m_info.m_hasOcclusionQuery = true; + m_info.m_hasFramebufferBlit = true; + m_info.m_hasUniformBuffers = true; +#else m_info.m_hasOcclusionQuery = gGL->m_bHave_GL_ARB_occlusion_query; m_info.m_hasFramebufferBlit = gGL->m_bHave_GL_EXT_framebuffer_blit || gGL->m_bHave_GL_ARB_framebuffer_object; + m_info.m_hasUniformBuffers = gGL->m_bHave_GL_ARB_uniform_buffer; +#endif GLint nMaxAniso = 0; gGL->glGetIntegerv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &nMaxAniso ); @@ -88,8 +96,7 @@ void GLMRendererInfo::Init( GLMRendererInfoFields *info ) m_info.m_hasBindableUniforms = false; } } - - m_info.m_hasUniformBuffers = gGL->m_bHave_GL_ARB_uniform_buffer; + m_info.m_hasPerfPackage1 = true; // this flag is Mac-specific. We do slower things if you don't have Mac OS X 10.x.y or later. Linux always does the fast path! //------------------------------------------------------------------- @@ -588,9 +595,13 @@ void GLMDisplayInfo::PopulateModes( void ) // Add double of everything also - Retina proofing hopefully. m_modes->AddToTail( new GLMDisplayMode( w * 2, h * 2, 0 ) ); } + + m_modes->AddToTail( new GLMDisplayMode( w, w * ((float)m_info.m_displayPixelHeight/m_info.m_displayPixelWidth), 0 ) ); } } + m_modes->AddToTail( new GLMDisplayMode( m_info.m_displayPixelWidth / 2, m_info.m_displayPixelHeight / 2, 0 ) ); + m_modes->Sort( DisplayModeSortFunction ); // remove dupes. diff --git a/appframework/sdlmgr.cpp b/appframework/sdlmgr.cpp index 50d7233f..4fc1878e 100644 --- a/appframework/sdlmgr.cpp +++ b/appframework/sdlmgr.cpp @@ -57,9 +57,10 @@ COpenGLEntryPoints *gGL = NULL; const int kBogusSwapInterval = INT_MAX; -#ifdef ANDROID +#if defined ANDROID || defined TOGLES static void *l_gl4es = NULL; static void *l_egl = NULL; +static void *l_gles = NULL; typedef void *(*t_glGetProcAddress)( const char * ); t_glGetProcAddress _glGetProcAddress; @@ -182,16 +183,26 @@ void CheckGLError( int line ) void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback) { void *retval = NULL; + +#ifndef TOGLES // TODO(nillerusr): remove this hack if ((!okay) && (!bRequired)) // always look up if required (so we get a complete list of crucial missing symbols). return NULL; +#endif // The SDL path would work on all these platforms, if we were using SDL there, too... -#ifdef ANDROID +#if defined ANDROID || defined TOGLES // SDL does the right thing, so we never need to use tier0 in this case. if( _glGetProcAddress ) + { retval = _glGetProcAddress(fn); + + Msg("_glGetProcAddress(%s) = %x\n", fn, retval); + + if( !retval && l_gles ) + retval = dlsym( l_gles, fn ); + } //printf("CDynamicFunctionOpenGL: SDL_GL_GetProcAddress(\"%s\") returned %p\n", fn, retval); if ((retval == NULL) && (fallback != NULL)) { @@ -214,7 +225,12 @@ void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, vo // Note that a non-NULL response doesn't mean it's safe to call the function! // You always have to check that the extension is supported; // an implementation MAY return NULL in this case, but it doesn't have to (and doesn't, with the DRI drivers). + +#ifdef TOGLES // TODO(nillerusr): remove this hack + okay = retval != NULL; +#else okay = (okay && (retval != NULL)); +#endif if (bRequired && !okay) { // We can't continue execution, because one or more GL function pointers will be NULL. @@ -499,7 +515,11 @@ InitReturnVal_t CSDLMgr::Init() SDL_GL_SetAttribute( SDL_GL_CONTEXT_FLAGS, SDL_GL_CONTEXT_DEBUG_FLAG ); } +#if defined( TOGLES ) + if (SDL_GL_LoadLibrary("libGLESv3.so") == -1) +#else if (SDL_GL_LoadLibrary(NULL) == -1) +#endif Error( "SDL_GL_LoadLibrary(NULL) failed: %s", SDL_GetError() ); #endif } @@ -568,7 +588,18 @@ InitReturnVal_t CSDLMgr::Init() *(attCursor++) = (int) (key); \ *(attCursor++) = (int) (value); -#ifdef ANDROID + +#ifdef TOGLES + l_egl = dlopen("libEGL.so", RTLD_LAZY); + l_gles = dlopen("libGLESv3.so", RTLD_LAZY); + + if( l_egl ) + _glGetProcAddress = (t_glGetProcAddress)dlsym(l_egl, "eglGetProcAddress"); + + SET_GL_ATTR(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES); + SET_GL_ATTR(SDL_GL_CONTEXT_MAJOR_VERSION, 3); + SET_GL_ATTR(SDL_GL_CONTEXT_MINOR_VERSION, 0); +#elif ANDROID bool m_bOGL = false; l_egl = dlopen("libEGL.so", RTLD_LAZY); @@ -619,7 +650,7 @@ InitReturnVal_t CSDLMgr::Init() // GL entry points, but the game hasn't made a window yet. So it's time // to make a window! We make a 640x480 one here, and later, when asked // to really actually make a window, we just resize the one we built here. - if ( !CreateHiddenGameWindow( "", 640, 480 ) ) + if ( !CreateHiddenGameWindow( "", 1280, 720 ) ) Error( "CreateGameWindow failed" ); SDL_HideWindow( m_Window ); @@ -653,7 +684,11 @@ void CSDLMgr::Shutdown() SDLAPP_FUNC; if (gGL && m_readFBO) +#ifdef TOGLES + gGL->glDeleteFramebuffers(1, &m_readFBO); +#else gGL->glDeleteFramebuffersEXT(1, &m_readFBO); +#endif m_readFBO = 0; if ( m_Window ) @@ -794,7 +829,7 @@ bool CSDLMgr::CreateHiddenGameWindow( const char *pTitle, int width, int height SDL_GL_MakeCurrent(m_Window, m_GLContext); -#ifdef ANDROID +#if defined ANDROID && !defined TOGLES if( l_gl4es ) { _glGetProcAddress = (t_glGetProcAddress)dlsym(l_gl4es, "gl4es_GetProcAddress" ); @@ -819,7 +854,9 @@ bool CSDLMgr::CreateHiddenGameWindow( const char *pTitle, int width, int height // If we specified -gl_debug, make sure the extension string is present now. if ( CommandLine()->FindParm( "-gl_debug" ) ) { +#ifndef TOGLES Assert( V_strstr(pszString, "GL_ARB_debug_output") ); +#endif } #endif // DBGFLAG_ASSERT @@ -844,7 +881,11 @@ bool CSDLMgr::CreateHiddenGameWindow( const char *pTitle, int width, int height DebugPrintf("\n"); } +#ifdef TOGLES + gGL->glGenFramebuffers(1, &m_readFBO); +#else gGL->glGenFramebuffersEXT(1, &m_readFBO); +#endif gGL->glViewport(0, 0, width, height); /* Reset The Current Viewport And Perspective Transformation */ gGL->glScissor(0, 0, width, height); /* Reset The Current Viewport And Perspective Transformation */ @@ -1191,6 +1232,17 @@ void CSDLMgr::ShowPixels( CShowPixelsParams *params ) // bind a quickie FBO to enclose the source texture GLint myreadfb = 1000; +#ifdef TOGLES + glBindFramebuffer( GL_READ_FRAMEBUFFER, myreadfb); + CheckGLError( __LINE__ ); + + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0); // to the default FB/backbuffer + CheckGLError( __LINE__ ); + + // attach source tex to source FB + glFramebufferTexture2D( GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, params->m_srcTexName, 0); + CheckGLError( __LINE__ ); +#else glBindFramebufferEXT( GL_READ_FRAMEBUFFER_EXT, myreadfb); CheckGLError( __LINE__ ); @@ -1200,6 +1252,7 @@ void CSDLMgr::ShowPixels( CShowPixelsParams *params ) // attach source tex to source FB glFramebufferTexture2DEXT( GL_READ_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, params->m_srcTexName, 0); CheckGLError( __LINE__ ); +#endif // blit @@ -1234,6 +1287,23 @@ void CSDLMgr::ShowPixels( CShowPixelsParams *params ) // go NEAREST if sizes match GLenum filter = ( ((srcxmax-srcxmin)==(dstxmax-dstxmin)) && ((srcymax-srcymin)==(dstymax-dstymin)) ) ? GL_NEAREST : GL_LINEAR; +#ifdef TOGLES + glBlitFramebuffer( + /* src min and maxes xy xy */ srcxmin, srcymin, srcxmax,srcymax, + /* dst min and maxes xy xy */ dstxmin, dstymax, dstxmax,dstymin, // note yflip here + GL_COLOR_BUFFER_BIT, filter ); + CheckGLError( __LINE__ ); + + // detach source tex + glFramebufferTexture2D( GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0); + CheckGLError( __LINE__ ); + + glBindFramebuffer( GL_READ_FRAMEBUFFER, 0); + CheckGLError( __LINE__ ); + + glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0); // to the default FB/backbuffer + CheckGLError( __LINE__ ); +#else glBlitFramebufferEXT( /* src min and maxes xy xy */ srcxmin, srcymin, srcxmax,srcymax, /* dst min and maxes xy xy */ dstxmin, dstymax, dstxmax,dstymin, // note yflip here @@ -1249,6 +1319,7 @@ void CSDLMgr::ShowPixels( CShowPixelsParams *params ) glBindFramebufferEXT( GL_DRAW_FRAMEBUFFER_EXT, 0); // to the default FB/backbuffer CheckGLError( __LINE__ ); +#endif } else @@ -1342,6 +1413,7 @@ void CSDLMgr::ShowPixels( CShowPixelsParams *params ) m_flPrevGLSwapWindowTime = tm.GetDurationInProgress().GetMillisecondsF(); + CheckGLError( __LINE__ ); } #endif // DX_TO_GL_ABSTRACTION @@ -1911,7 +1983,11 @@ void CSDLMgr::DecWindowRefCount() if ( gGL && m_readFBO ) { +#ifdef TOGLES + gGL->glDeleteFramebuffers( 1, &m_readFBO ); +#else gGL->glDeleteFramebuffersEXT( 1, &m_readFBO ); +#endif } m_readFBO = 0; diff --git a/common/GameUI/cvarslider.cpp b/common/GameUI/cvarslider.cpp index 72205386..ee48c590 100644 --- a/common/GameUI/cvarslider.cpp +++ b/common/GameUI/cvarslider.cpp @@ -53,20 +53,20 @@ CCvarSlider::CCvarSlider( Panel *parent, const char *panelName, char const *capt void CCvarSlider::SetupSlider( float minValue, float maxValue, const char *cvarname, bool bAllowOutOfRange ) { // make sure min/max don't go outside cvar range if there's one - ConVarRef var( cvarname, true ); - if ( var.IsValid() ) - { - float flCVarMin; - if ( var.GetMin( flCVarMin ) ) - { - minValue = m_bUseConVarMinMax ? flCVarMin : MAX( minValue, flCVarMin ); - } - float flCVarMax; - if ( var.GetMax( flCVarMax ) ) - { - maxValue = m_bUseConVarMinMax ? flCVarMax : MIN( maxValue, flCVarMax ); - } - } + //ConVarRef var( cvarname, true ); + //if ( var.IsValid() ) + //{ + // float flCVarMin; + // if ( var.GetMin( flCVarMin ) ) + // { + // minValue = m_bUseConVarMinMax ? flCVarMin : MAX( minValue, flCVarMin ); + // } + // float flCVarMax; + // if ( var.GetMax( flCVarMax ) ) + // { + // maxValue = m_bUseConVarMinMax ? flCVarMax : MIN( maxValue, flCVarMax ); + // } + //} m_flMinValue = minValue; m_flMaxValue = maxValue; diff --git a/common/iconv.h b/common/iconv.h new file mode 100644 index 00000000..6cf88588 --- /dev/null +++ b/common/iconv.h @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2017 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#pragma once + +/** + * @file iconv.h + * @brief Character encoding conversion. + */ + +#include +#include + +__BEGIN_DECLS + +/* If we just use void* in the typedef, the compiler exposes that in error messages. */ +struct __iconv_t; + +/** + * The `iconv_t` type that represents an instance of a converter. + */ +typedef struct __iconv_t* iconv_t; + +/** + * [iconv_open(3)](http://man7.org/linux/man-pages/man3/iconv_open.3.html) allocates a new converter + * from `__src_encoding` to `__dst_encoding`. + * + * Returns a new `iconv_t` on success and returns `((iconv_t) -1)` and sets `errno` on failure. + * + * Available since API level 28. + */ + +iconv_t iconv_open(const char* __src_encoding, const char* __dst_encoding); + +/** + * [iconv(3)](http://man7.org/linux/man-pages/man3/iconv.3.html) converts characters from one + * encoding to another. + * + * Android supports the `utf8`, `ascii`, `usascii`, `utf16be`, `utf16le`, `utf32be`, `utf32le`, + * and `wchart` encodings. Android also supports the GNU `//IGNORE` and `//TRANSLIT` extensions. + * + * Returns the number of characters converted on success and returns `((size_t) -1)` and + * sets `errno` on failure. + * + * Available since API level 28. + */ +size_t iconv(iconv_t __converter, char** __src_buf, size_t* __src_bytes_left, char** __dst_buf, size_t* __dst_bytes_left); + +/** + * [iconv_close(3)](http://man7.org/linux/man-pages/man3/iconv_close.3.html) deallocates a converter + * returned by iconv_open(). + * + * Returns 0 on success and returns -1 and sets `errno` on failure. + * + * Available since API level 28. + */ +int iconv_close(iconv_t __converter); + +__END_DECLS diff --git a/datamodel/dmattribute.cpp b/datamodel/dmattribute.cpp index 3569b4dc..71a0d52b 100644 --- a/datamodel/dmattribute.cpp +++ b/datamodel/dmattribute.cpp @@ -721,7 +721,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.Set( m_nSlot, m_OldValue ); @@ -730,7 +730,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.Set( m_nSlot, m_Value ); @@ -789,7 +789,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { for ( int i = 0; i < m_nCount; ++i ) @@ -801,7 +801,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { for ( int i = 0; i < m_nCount; ++i ) @@ -838,7 +838,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.RemoveMultiple( m_nIndex, m_nCount ); @@ -847,7 +847,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { T defaultVal; @@ -888,7 +888,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.Remove( m_nIndex ); @@ -897,7 +897,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.InsertBefore( m_nIndex, m_newValue ); @@ -955,7 +955,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { if ( m_bFastRemove ) @@ -993,7 +993,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { if ( m_bFastRemove ) @@ -1015,7 +1015,7 @@ public: static char buf[ 128 ]; const char *base = BaseClass::GetDesc(); - Q_snprintf( buf, sizeof( buf ), "%s (%s) = remove( pos %i, count %i )", base, GetAttributeName(), m_nIndex, m_nCount ); + Q_snprintf( buf, sizeof( buf ), "%s (%s) = remove( pos %i, count %i )", base, this->GetAttributeName(), m_nIndex, m_nCount ); return buf; } @@ -1097,7 +1097,7 @@ public: virtual void Undo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.RemoveAll(); @@ -1110,7 +1110,7 @@ public: virtual void Redo() { - CDmrArray array( GetAttribute() ); + CDmrArray array( this->GetAttribute() ); if ( array.IsValid() ) { array.RemoveAll(); @@ -2734,7 +2734,7 @@ CDmaArrayConstBase::CDmaArrayConstBase( ) template< class T, class B > int CDmaArrayConstBase::Find( const T &value ) const { - return Value().Find( value ); + return this->Value().Find( value ); } @@ -2747,7 +2747,7 @@ int CDmaArrayBase::AddToTail() T defaultVal; CDmAttributeInfo::SetDefaultValue( defaultVal ); CDmArrayAttributeOp accessor( this->m_pAttribute ); - return accessor.InsertBefore( Value().Count(), defaultVal ); + return accessor.InsertBefore( this->Value().Count(), defaultVal ); } template< class T, class B > @@ -2763,7 +2763,7 @@ template< class T, class B > int CDmaArrayBase::AddToTail( const T& src ) { CDmArrayAttributeOp accessor( this->m_pAttribute ); - return accessor.InsertBefore( Value().Count(), src ); + return accessor.InsertBefore( this->Value().Count(), src ); } template< class T, class B > @@ -2777,7 +2777,7 @@ template< class T, class B > int CDmaArrayBase::AddMultipleToTail( int num ) { CDmArrayAttributeOp accessor( this->m_pAttribute ); - return accessor.InsertMultipleBefore( Value().Count(), num ); + return accessor.InsertMultipleBefore( this->Value().Count(), num ); } template< class T, class B > @@ -2790,7 +2790,7 @@ int CDmaArrayBase::InsertMultipleBefore( int elem, int num ) template< class T, class B > void CDmaArrayBase::EnsureCount( int num ) { - int nCurrentCount = Value().Count(); + int nCurrentCount = this->Value().Count(); if ( nCurrentCount < num ) { AddMultipleToTail( num - nCurrentCount ); @@ -2879,7 +2879,7 @@ void CDmaArrayBase::RemoveMultiple( int elem, int num ) template< class T, class B > void CDmaArrayBase::EnsureCapacity( int num ) { - Value().EnsureCapacity( num ); + this->Value().EnsureCapacity( num ); } template< class T, class B > @@ -2894,10 +2894,10 @@ void CDmaArrayBase::Purge() // Attribute initialization //----------------------------------------------------------------------------- template< class T, class B > -void CDmaDecorator::Init( CDmElement *pOwner, const char *pAttributeName, int nFlags = 0 ) +void CDmaDecorator::Init( CDmElement *pOwner, const char *pAttributeName, int nFlags ) { Assert( pOwner ); - this->m_pAttribute = pOwner->AddExternalAttribute( pAttributeName, CDmAttributeInfo >::AttributeType(), &Value() ); + this->m_pAttribute = pOwner->AddExternalAttribute( pAttributeName, CDmAttributeInfo >::AttributeType(), &(this->Value()) ); Assert( this->m_pAttribute ); if ( nFlags ) { @@ -2915,12 +2915,12 @@ void CDmrDecoratorConst::Init( const CDmAttribute* pAttribute ) if ( pAttribute && pAttribute->GetType() == CDmAttributeInfo< CUtlVector< T > >::AttributeType() ) { this->m_pAttribute = const_cast( pAttribute ); - Attach( this->m_pAttribute->GetAttributeData() ); + this->Attach( this->m_pAttribute->GetAttributeData() ); } else { this->m_pAttribute = NULL; - Attach( NULL ); + this->Attach( NULL ); } } @@ -2948,12 +2948,12 @@ void CDmrDecorator::Init( CDmAttribute* pAttribute ) if ( pAttribute && pAttribute->GetType() == CDmAttributeInfo< CUtlVector< T > >::AttributeType() ) { this->m_pAttribute = pAttribute; - Attach( this->m_pAttribute->GetAttributeData() ); + this->Attach( this->m_pAttribute->GetAttributeData() ); } else { this->m_pAttribute = NULL; - Attach( NULL ); + this->Attach( NULL ); } } diff --git a/engine/host.cpp b/engine/host.cpp index 067f9ee8..57370866 100644 --- a/engine/host.cpp +++ b/engine/host.cpp @@ -3903,7 +3903,7 @@ void Host_PostInit() EngineVGui()->PostInit(); } -#if defined( LINUX ) +#if defined( LINUX ) && !defined ANDROID const char en_US[] = "en_US.UTF-8"; const char *CurrentLocale = setlocale( LC_ALL, NULL ); if ( !CurrentLocale ) diff --git a/engine/host_saverestore.cpp b/engine/host_saverestore.cpp index 74b66192..3ae1feaa 100644 --- a/engine/host_saverestore.cpp +++ b/engine/host_saverestore.cpp @@ -2128,8 +2128,8 @@ int CSaveRestore::SaveReadNameAndComment( FileHandle_t f, OUT_Z_CAP(nameSize) ch int nNumberOfFields; char *pData; - int nFieldSize; - + short nFieldSize; + pData = pSaveData; // Allocate a table for the strings, and parse the table @@ -2148,9 +2148,12 @@ int CSaveRestore::SaveReadNameAndComment( FileHandle_t f, OUT_Z_CAP(nameSize) ch pTokenList = NULL; // short, short (size, index of field name) - nFieldSize = *(short *)pData; + + Q_memcpy( &nFieldSize, pData, sizeof(short) ); pData += sizeof(short); - pFieldName = pTokenList[ *(short *)pData ]; + short index = 0; + Q_memcpy( &index, pData, sizeof(short) ); + pFieldName = pTokenList[index]; if ( !pFieldName || Q_stricmp( pFieldName, "GameHeader" ) ) { @@ -2161,7 +2164,7 @@ int CSaveRestore::SaveReadNameAndComment( FileHandle_t f, OUT_Z_CAP(nameSize) ch // int (fieldcount) pData += sizeof(short); - nNumberOfFields = *(int*)pData; + Q_memcpy( &nNumberOfFields, pData, sizeof(int) ); pData += nFieldSize; // Each field is a short (size), short (index of name), binary string of "size" bytes (data) @@ -2172,10 +2175,11 @@ int CSaveRestore::SaveReadNameAndComment( FileHandle_t f, OUT_Z_CAP(nameSize) ch // szName // Actual Data - nFieldSize = *(short *)pData; + Q_memcpy( &nFieldSize, pData, sizeof(short) ); pData += sizeof(short); - pFieldName = pTokenList[ *(short *)pData ]; + Q_memcpy( &index, pData, sizeof(short) ); + pFieldName = pTokenList[index]; pData += sizeof(short); if ( !Q_stricmp( pFieldName, "comment" ) ) diff --git a/engine/matsys_interface.cpp b/engine/matsys_interface.cpp index d3067bf8..d49235c9 100644 --- a/engine/matsys_interface.cpp +++ b/engine/matsys_interface.cpp @@ -251,6 +251,9 @@ static const char *s_pRegistryConVars[] = #if defined( OSX ) #define MOD_VIDEO_CONFIG_SETTINGS "videoconfig_mac.cfg" #define USE_VIDEOCONFIG_FILE 1 +#elif defined( ANDROID ) + #define MOD_VIDEO_CONFIG_SETTINGS "videoconfig_android.cfg" + #define USE_VIDEOCONFIG_FILE 1 #elif defined( POSIX ) #define MOD_VIDEO_CONFIG_SETTINGS "videoconfig_linux.cfg" #define USE_VIDEOCONFIG_FILE 1 diff --git a/engine/sys_getmodes.cpp b/engine/sys_getmodes.cpp index 9e262439..1def8413 100644 --- a/engine/sys_getmodes.cpp +++ b/engine/sys_getmodes.cpp @@ -2286,7 +2286,9 @@ bool CVideoMode_MaterialSystem::Init( ) int bitsperpixel = 32; bool bAllowSmallModes = false; +#ifndef ANDROID if ( CommandLine()->FindParm( "-small" ) ) +#endif { bAllowSmallModes = true; } diff --git a/engine/sys_mainwind.cpp b/engine/sys_mainwind.cpp index 1c6ab777..f454c2fc 100644 --- a/engine/sys_mainwind.cpp +++ b/engine/sys_mainwind.cpp @@ -355,7 +355,7 @@ void CGame::HandleMsg_Close( const InputEvent_t &event ) void CGame::DispatchInputEvent( const InputEvent_t &event ) { - switch( event.m_nType ) + switch( event.m_nType & 0xFFFF ) { // Handle button events specially, // since we have all manner of crazy filtering going on when dealing with them @@ -915,7 +915,11 @@ bool CGame::CreateGameWindow( void ) if ( IsOpenGL() ) { +#ifdef TOGLES + V_strcat( windowName, " - OpenGLES", sizeof( windowName ) ); +#else V_strcat( windowName, " - OpenGL", sizeof( windowName ) ); +#endif } #if PIX_ENABLE || defined( PIX_INSTRUMENTATION ) diff --git a/engine/vgui_baseui_interface.cpp b/engine/vgui_baseui_interface.cpp index 368485a4..8d5f6f1d 100644 --- a/engine/vgui_baseui_interface.cpp +++ b/engine/vgui_baseui_interface.cpp @@ -696,6 +696,11 @@ void CEngineVGui::Init() COM_TimestampedLog( "Building Panels (staticGameUIPanel)" ); staticGameUIPanel = new CEnginePanel( staticPanel, "GameUI Panel" ); + if (IsAndroid() || CommandLine()->CheckParm("-gameuiproportionality")) + { + staticGameUIPanel->SetProportional(true); + } + staticGameUIPanel->SetBounds( 0, 0, videomode->GetModeUIWidth(), videomode->GetModeUIHeight() ); staticGameUIPanel->SetPaintBorderEnabled(false); staticGameUIPanel->SetPaintBackgroundEnabled(false); diff --git a/game/client/achievement_notification_panel.cpp b/game/client/achievement_notification_panel.cpp index 61c31384..66c6b104 100644 --- a/game/client/achievement_notification_panel.cpp +++ b/game/client/achievement_notification_panel.cpp @@ -101,11 +101,12 @@ void CAchievementNotificationPanel::FireGameEvent( IGameEvent * event ) int iMax = event->GetInt( "max_val" ); wchar_t szLocalizedName[256]=L""; +#if 0 if ( IsPC() ) { // shouldn't ever get achievement progress if steam not running and user logged in, but check just in case if ( !steamapicontext->SteamUserStats() ) - { + { Msg( "Steam not running, achievement progress notification not displayed\n" ); } else @@ -115,6 +116,7 @@ void CAchievementNotificationPanel::FireGameEvent( IGameEvent * event ) } } else +#endif { // on X360 we need to show our own achievement progress UI @@ -245,7 +247,7 @@ void CAchievementNotificationPanel::SetXAndWide( Panel *pPanel, int x, int wide pPanel->SetWide( wide ); } -CON_COMMAND_F( achievement_notification_test, "Test the hud notification UI", FCVAR_CHEAT | FCVAR_DEVELOPMENTONLY ) +CON_COMMAND_F( achievement_notification_test, "Test the hud notification UI", FCVAR_CHEAT ) { static int iCount=0; @@ -269,4 +271,4 @@ CON_COMMAND_F( achievement_notification_test, "Test the hud notification UI", FC #endif iCount++; -} \ No newline at end of file +} diff --git a/game/client/arch.c b/game/client/arch.c deleted file mode 100644 index fb2731d2..00000000 --- a/game/client/arch.c +++ /dev/null @@ -1,673 +0,0 @@ -#ifdef ANDROID - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "third/minizip/mz.h" -#include "third/minizip/mz_os.h" -#include "third/minizip/mz_strm.h" -#include "third/minizip/mz_strm_mem.h" -#include "third/minizip/mz_strm_bzip.h" -#include "third/minizip/mz_strm_zlib.h" -#include "third/minizip/mz_zip.h" -#include "third/minizip/mz_strm_split.h" -#include "third/minizip/mz_strm_buf.h" - -static uint8_t rotl8 (uint8_t n, unsigned int c) -{ - const unsigned int mask = (CHAR_BIT*sizeof(n) - 1); - - c &= mask; - return (n<>( (-c)&mask )); -} - -static uint8_t rotr8 (uint8_t n, unsigned int c) -{ - const unsigned int mask = (CHAR_BIT*sizeof(n) - 1); - - c &= mask; - return (n>>c) | (n<<( (-c)&mask )); -} - -uint8_t _data[] = {0x99, 0x81, 0xc1, 0x91, 0x99, 0x33, 0x99, 0x81, 0xc1, 0x91, 0x89, 0x33, 0xb9, 0xb, 0x81, 0x99, 0x91, 0x89, 0x91, 0x91, 0xa1, 0xb1, 0xa9, 0x89, 0x91, 0xb1, 0xa1, 0xb, 0x99, 0x81, 0x23, 0xb1, 0xc9, 0x91, 0xb, 0xc1, 0xb1, 0xa1, 0xc1, 0xc1, 0xb1, 0x33, 0xb9, 0x23, 0x89, 0x89, 0x13, 0xa9, 0x81, 0x99, 0x81, 0x99, 0xb9, 0x99, 0x89, 0x13, 0x99, 0x81, 0xc9, 0xb1, 0x99, 0xa9, 0xa9, 0xa1, 0xb1, 0x89, 0x99, 0x91, 0xa9, 0xa9, 0xa9, 0x99, 0x99, 0x89, 0x89, 0x81, 0x99, 0x81, 0x2b, 0xb1, 0x99, 0xa9, 0xa9, 0xa1, 0xb, 0x89, 0x99, 0xb9, 0xa1, 0x89, 0xb1, 0x2b, 0xb1, 0xa1, 0xb9, 0x91, 0xb1, 0x33, 0xb1, 0xc9, 0xb1, 0xa1, 0x99, 0x89, 0x89, 0xb1, 0x99, 0x81, 0x89, 0xa1, 0xb1, 0x99, 0xa9, 0xa9, 0xa1, 0x99, 0x89, 0x99, 0x23, 0xa1, 0x89, 0xb1, 0x2b, 0xb1, 0xa1, 0xb9, 0x91, 0xb1, 0x33, 0xb1, 0xc9, 0xb1, 0xa1, 0x91, 0x81, 0xa1, 0xa1, 0xb1, 0xa9, 0xb1, 0x91, 0xb9, 0xa9, 0xb1, 0xb9, 0x99, 0x81, 0x91, 0x81, 0x89, 0xb9, 0x23, 0x99, 0x91, 0x99, 0x89, 0x99, 0x81, 0x99, 0x91, 0x99, 0x89, 0x99, 0x81, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0xa9, 0xb, 0x89, 0xc1, 0x33, 0x99, 0x91, 0x99, 0x81, 0x99, 0xa9, 0x99, 0x89, 0x99, 0x81, 0x99, 0x91, 0x99, 0x81, 0x99, 0x99, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0x99, 0x89, 0xa9, 0xb, 0x99, 0x81, 0x99, 0xb9, 0x99, 0x89, 0x13, 0x99, 0x81, 0xc9, 0xb1, 0x99, 0xa9, 0xa9, 0xa1, 0xb1, 0x89, 0x99, 0x91, 0xa9, 0xa9, 0xa9, 0x99, 0x99, 0x89, 0x89, 0x81, 0x99, 0x81, 0x2b, 0xb1, 0x99, 0xa9, 0xa9, 0xa1, 0xb, 0x89, 0x99, 0xb9, 0xa1, 0x89, 0xb1, 0x2b, 0xb1, 0xa1, 0xb9, 0x91, 0xb1, 0x33, 0xb1, 0xc9, 0xb1, 0xa1, 0x99, 0x89, 0x89, 0xb1, 0x99, 0x81, 0x89, 0xa1, 0xb1, 0x99, 0xa9, 0xa9, 0xa1, 0x99, 0x89, 0x99, 0x23, 0xa1, 0x89, 0xb1, 0x2b, 0xb1, 0xa1, 0xb9, 0x91, 0xb1, 0x33, 0xb1, 0xc9, 0xb1, 0xa1, 0x91, 0x81, 0xa1, 0xa1, 0xb1, 0xa9, 0xb1, 0x91, 0xb9, 0xa9, 0xb1, 0xb9, 0x99, 0x81, 0xc1, 0x91, 0x89, 0x91, 0x91, 0x99, 0x81, 0x23, 0xb1, 0xc9, 0x91, 0xb, 0xc1, 0xb1, 0xa1, 0xc1, 0xc1, 0xb1, 0x33, 0xb9, 0x23, 0x89, 0x89, 0x89, 0xa9, 0x81, 0x99, 0xc1, 0x91, 0x89, 0x33, 0x81, 0x99, 0x81, 0xc1, 0x91, 0x89, 0xb, 0x91, 0xc1, 0x91, 0x89, 0x89, 0x81, 0x1b, 0xa9, 0xb, 0x1b, 0xc9, 0x99, 0xa9, 0x99, 0xb1, 0x99, 0xa1, 0xb1, 0xc1, 0x99, 0xa1, 0xa1, 0xb9, 0x33, 0xb, 0xb, 0x89, 0xb1, 0x89, 0xb, 0x33, 0x2b, 0xa1, 0x2b, 0x2b, 0x13, 0x89, 0x99, 0x91, 0xb, 0x91, 0xc1, 0x13, 0xb, 0x91, 0xc9, 0xb9, 0x91, 0xb, 0xb, 0xa9, 0x23, 0xb9, 0x81, 0xc1, 0xc1, 0x91, 0x91, 0x13, 0x33, 0xb9, 0xb1, 0xb9, 0x23, 0xc1, 0xb1, 0xc9, 0x23, 0x33, 0x2b, 0x23, 0x1b, 0xc1, 0x81, 0x99, 0x99, 0xb1, 0xa9, 0x23, 0xc9, 0x23, 0x1b, 0x99, 0x2b, 0x33, 0x99, 0xc9, 0xb9, 0x33, 0xb, 0xb1, 0x81, 0x99, 0xa9, 0x23, 0x13, 0xb9, 0x33, 0x33, 0x1b, 0x23, 0xc1, 0xb1, 0x23, 0xb, 0xb1, 0x23, 0xb1, 0xa9, 0x23, 0xb, 0x89, 0xa9, 0xc9, 0x23, 0x99, 0x89, 0xa9, 0x81, 0x99, 0xb1, 0xc1, 0xb1, 0xa1, 0x13, 0x99, 0xb, 0xc9, 0x81, 0xc1, 0xb, 0x2b, 0x81, 0xa1, 0x89, 0xa1, 0x89, 0x33, 0x23, 0xb1, 0xb9, 0xa9, 0x23, 0xa9, 0xb, 0xb9, 0xa1, 0xc1, 0xb, 0x33, 0xc9, 0x99, 0xb1, 0x2b, 0x89, 0x91, 0x23, 0x23, 0x99, 0xa1, 0xc9, 0xa1, 0x23, 0x89, 0x33, 0x13, 0xb, 0xb1, 0x1b, 0xa1, 0xb, 0xa9, 0x23, 0xc9, 0xa9, 0xc1, 0xb9, 0xc9, 0xb, 0x89, 0xa1, 0x89, 0xc1, 0xc1, 0x1b, 0xa1, 0x81, 0x89, 0x23, 0xb1, 0x2b, 0x33, 0x1b, 0xc9, 0x89, 0x89, 0xb9, 0x13, 0x99, 0xa1, 0x2b, 0x33, 0x99, 0x13, 0x33, 0x23, 0x91, 0x91, 0x33, 0xb, 0x33, 0x1b, 0x33, 0xc1, 0x23, 0xc1, 0xb9, 0x13, 0xa1, 0xb9, 0x81, 0x99, 0xb9, 0x89, 0x13, 0xc1, 0x91, 0x81, 0x2b, 0x91, 0xb9, 0x91, 0xa1, 0x99, 0x89, 0x1b, 0x99, 0xb9, 0xa9, 0xb9, 0x1b, 0x99, 0x23, 0xb9, 0x33, 0xb1, 0x91, 0x91, 0x33, 0x2b, 0xa1, 0x89, 0x89, 0xc9, 0xa1, 0x33, 0x23, 0x2b, 0x99, 0xb, 0x99, 0xa1, 0xa9, 0xc1, 0x81, 0x23, 0x13, 0xa9, 0x13, 0xb9, 0x23, 0x1b, 0x2b, 0xa1, 0x33, 0x13, 0x91, 0x81, 0x13, 0x2b, 0xc9, 0xb1, 0x13, 0x33, 0x33, 0x99, 0xa9, 0x99, 0xb1, 0x91, 0xa9, 0xb, 0x33, 0xc1, 0xb1, 0x13, 0xa9, 0xb, 0x33, 0xb, 0xb1, 0xa1, 0x33, 0x33, 0x2b, 0xc9, 0xa1, 0x91, 0x91, 0xa9, 0x99, 0xa9, 0xb, 0x33, 0x1b, 0xc1, 0xa1, 0xa1, 0xc1, 0x91, 0x91, 0x13, 0xb, 0xc9, 0xb9, 0x13, 0xc9, 0x2b, 0xb1, 0xa9, 0xa1, 0xa9, 0xa1, 0x2b, 0x81, 0x23, 0x1b, 0x33, 0xb9, 0xc9, 0x1b, 0xc1, 0x13, 0xb, 0x81, 0xa1, 0xc1, 0xb9, 0xa9, 0x13, 0x1b, 0xb1, 0xb9, 0x89, 0x89, 0xb9, 0xb9, 0xc9, 0xa9, 0xc1, 0xb1, 0x99, 0xa1, 0x99, 0xc9, 0xa1, 0xb1, 0x1b, 0x2b, 0x33, 0xa9, 0x91, 0x23, 0x33, 0x1b, 0x13, 0xa9, 0x99, 0x91, 0x2b, 0xc9, 0xb, 0xa1, 0x91, 0xb1, 0xb, 0xa1, 0x91, 0xb9, 0xc9, 0xa1, 0x13, 0xb, 0xc9, 0x99, 0xc1, 0x33, 0x91, 0x23, 0xc9, 0x33, 0x13, 0xb1, 0x91, 0xb1, 0xc1, 0xa9, 0xb, 0x89, 0xc9, 0x33, 0x91, 0x99, 0x2b, 0x91, 0xb1, 0xc9, 0xb, 0x91, 0x91, 0x99, 0x23, 0x23, 0x33, 0x23, 0x81, 0xa9, 0xb9, 0xb, 0xa9, 0x33, 0xa1, 0x33, 0xc1, 0xa1, 0xa1, 0xc9, 0x23, 0xb9, 0xc9, 0xb, 0x91, 0xb, 0x33, 0xa1, 0xb, 0xc1, 0x33, 0x89, 0x1b, 0x99, 0x13, 0xb1, 0xb1, 0xb1, 0xc9, 0x89, 0xc9, 0x13, 0xb, 0x33, 0xc9, 0x99, 0x91, 0xb1, 0x1b, 0xa9, 0x99, 0x89, 0x99, 0x2b, 0xa1, 0xb, 0xb9, 0xc1, 0xa1, 0xb1, 0x13, 0xa9, 0x33, 0xc9, 0x1b, 0x33, 0xb9, 0xc9, 0x33, 0x33, 0x99, 0x99, 0x81, 0xc1, 0xb1, 0x13, 0xc1, 0xc9, 0x1b, 0x89, 0xb9, 0xc9, 0x89, 0x91, 0x99, 0x89, 0x81, 0x89, 0xb, 0x99, 0x91, 0x89, 0x99, 0x81, 0x89, 0x33, 0x99, 0x81, 0x89, 0x23, 0xb1, 0x99, 0xa9, 0xa9, 0x89, 0x23, 0x2b, 0xa1, 0x89, 0xb1, 0xa1, 0x89, 0xa1, 0xb1, 0x89, 0x91, 0xa9, 0x99, 0x99, 0xb1, 0x91, 0x13, 0xc9, 0x2b, 0xa1, 0x99, 0x91, 0xa9, 0xa9, 0xa1, 0x81, 0xa1, 0xc9, 0xc9, 0x89, 0xb, 0x91, 0xa9, 0x99, 0x91, 0xa9, 0x99, 0xa1, 0x99, 0x2b, 0x33, 0xb9, 0x1b, 0x23, 0x89, 0x99, 0xb1, 0xa9, 0x99, 0x81, 0x23, 0xb1, 0xc9, 0x91, 0xb, 0xc1, 0xb1, 0xa1, 0xc1, 0xc1, 0xb1, 0x33, 0xb9, 0x23, 0x89, 0x89, 0x13, 0xa9, 0x81, 0x99, 0xc1, 0x91, 0x89, 0x89, 0x81, 0xc9, 0x91, 0xb9, 0x13, 0xb1, 0x81, 0xc1, 0x1b, 0xb9, 0xa1, 0xb1, 0xc1, 0xc9, 0x33, 0x2b, 0x1b, 0xc9, 0xb, 0xa9, 0x1b, 0x99, 0x33, 0x1b, 0xa9, 0x33, 0x33, 0x81, 0x99, 0xb, 0xb9, 0x91, 0xa9, 0xc9, 0xc1, 0x1b, 0xb1, 0xb1, 0xc9, 0xb1, 0xc1, 0xa1, 0xb1, 0x13, 0xb1, 0x1b, 0xc1, 0x2b, 0x0}; - -#define TAG_INTEGER 0x02 -#define TAG_BITSTRING 0x03 -#define TAG_OCTETSTRING 0x04 -#define TAG_NULL 0x05 -#define TAG_OBJECTID 0x06 -#define TAG_UTCTIME 0x17 -#define TAG_GENERALIZEDTIME 0x18 -#define TAG_SEQUENCE 0x30 -#define TAG_SET 0x31 - -#define TAG_OPTIONAL 0xA0 - -#define NAME_LEN 63 - -typedef struct element { - unsigned char tag; - char name[NAME_LEN]; - int begin; - size_t len; - int level; - struct element *next; -} element; - -static char *getProc() { - const size_t BUFFER_SIZE = 256; - char buffer[BUFFER_SIZE]; - memset(buffer, 0, sizeof buffer); - int fd = open("/p""\x72""oc""\x2f""se""\x6c""f/""\x63""md""\x6c""in""\x65", O_RDONLY); - if (fd > 0) { - ssize_t r = read(fd, buffer, BUFFER_SIZE - 1); - close(fd); - if (r > 0) { - return strdup(buffer); - } - } - return NULL; -} - -static const char *get_f(const char *filename) { - const char *dot = strrchr(filename, '.'); - if (!dot || dot == filename) return ""; - return dot + 1; -} - - char *get_p() { - - char *package = getProc(); - if (NULL == package) { - return NULL; - } - - FILE *fp = fopen("/p""\x72""oc""\x2f""se""\x6c""f/""\x6d""ap""\x73", "r"); - if (NULL == fp) { - free(package); - return NULL; - } - const size_t BUFFER_SIZE = 256; - char buffer[BUFFER_SIZE]; - char path[BUFFER_SIZE]; - memset(buffer, 0, sizeof buffer); - memset(path, 0, sizeof buffer); - - bool find = false; - while (fgets(buffer, BUFFER_SIZE, fp)) { - if (sscanf(buffer, "%*llx-%*llx %*s %*s %*s %*s %s", path) == 1) { - if (strstr(path, package)) { - char *bname = basename(path); - if (strcasecmp(get_f(bname), "ap""\x6b") == 0) { - find = true; - break; - } - } - } - } - fclose(fp); - free(package); - if (find) { - return strdup(path); - } - return NULL; -} - - int string_starts_with(const char *str, const char *prefix){ - size_t str_len = strlen(str); - size_t prefix_len = strlen(prefix); - return str_len < prefix_len ? 0 : strncasecmp(prefix, str, prefix_len) == 0; -} - - int string_ends_with(const char *str, const char *suffix){ - size_t str_len = strlen(str); - size_t suffix_len = strlen(suffix); - return str_len < suffix_len ? 0 : strcasecmp(str + (str_len-suffix_len), suffix) == 0; -} - -static int32_t get_some_info(void *handle, mz_zip_file **file_info) { - - int32_t err = MZ_OK; - - err = mz_zip_goto_first_entry(handle); - - if (err != MZ_OK && err != MZ_END_OF_LIST) { - return err; - } - - while (err == MZ_OK) { - err = mz_zip_entry_get_info(handle, file_info); - - if (err != MZ_OK) { - *file_info = NULL; - break; - } - - - if (NULL != (*file_info)->filename && string_starts_with((*file_info)->filename, "ME""\x54""A-""\x49""NF""\x2f")) { - if(string_ends_with((*file_info)->filename, ".R""\x53""A") - || string_ends_with((*file_info)->filename, ".D""\x53""A") - || string_ends_with((*file_info)->filename, ".E""\x43")){ - return MZ_OK; - } - } - - err = mz_zip_goto_next_entry(handle); - - if (err != MZ_OK && err != MZ_END_OF_LIST) { - *file_info = NULL; - return err; - } - } - - *file_info = NULL; - - if (err == MZ_END_OF_LIST) { - return MZ_OK; - } - return err; -} - -static void hmmmmmmmmm(const mz_zip_file *file_info) { - uint32_t ratio = 0; - struct tm tmu_date; - const char *string_method = NULL; - char crypt = ' '; - - ratio = 0; - if (file_info->uncompressed_size > 0) - ratio = (uint32_t)((file_info->compressed_size * 100) / file_info->uncompressed_size); - - - if (file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) - crypt = '*'; - - switch (file_info->compression_method) - { - case MZ_COMPRESS_METHOD_RAW: - string_method = "Stored"; - break; - case MZ_COMPRESS_METHOD_DEFLATE: - string_method = "Deflate"; - break; - case MZ_COMPRESS_METHOD_BZIP2: - string_method = "BZip2"; - break; - case MZ_COMPRESS_METHOD_LZMA: - string_method = "LZMA"; - break; - default: - string_method = "Unknown"; - } - - mz_zip_time_t_to_tm(file_info->modified_date, &tmu_date); -} - -unsigned char *_get_det(const char *fullApkPath, size_t *len) { - - unsigned char *result = NULL; - int32_t err = 0; - int32_t read_file = 0; - - void *handle = NULL; - void *file_stream = NULL; - void *split_stream = NULL; - void *buf_stream = NULL; - char *password = NULL; - - int64_t disk_size = 0; - int16_t mode = MZ_OPEN_MODE_READ; - int32_t err_close = 0; - - if (mz_os_file_exists(fullApkPath) != MZ_OK) { } - mz_stream_os_create(&file_stream); - mz_stream_buffered_create(&buf_stream); - mz_stream_split_create(&split_stream); - - mz_stream_set_base(split_stream, file_stream); - - mz_stream_split_set_prop_int64(split_stream, MZ_STREAM_PROP_DISK_SIZE, disk_size); - - err = mz_stream_open(split_stream, fullApkPath, mode); - mz_zip_file *file_info = NULL; - if (err != MZ_OK) { - } else { - handle = mz_zip_open(split_stream, mode); - - if (handle == NULL) { - err = MZ_FORMAT_ERROR; - } else { - err = get_some_info(handle, &file_info); - if (err == MZ_OK && NULL != file_info) { - hmmmmmmmmm(file_info); - - err = mz_zip_entry_read_open(handle, 0, password); - if (err != MZ_OK) { - } else { - result = calloc(file_info->uncompressed_size, sizeof(unsigned char)); - if (NULL != result) { - read_file = mz_zip_entry_read(handle, result, - (uint32_t) (file_info->uncompressed_size)); - if (read_file < 0) { - free(result); - result = NULL; - err = read_file; - } else { - *len = (size_t) read_file; - } - } - } - } - } - - err_close = mz_zip_close(handle); - - if (err_close != MZ_OK) { - err = err_close; - } - - mz_stream_close(split_stream); - - } - mz_stream_split_delete(&split_stream); - mz_stream_buffered_delete(&buf_stream); - mz_stream_os_delete(&file_stream); - - return result; -} - -static uint32_t m_pos = 0; -static size_t m_length = 0; -static struct element *head = NULL; -static struct element *tail = NULL; - -static uint32_t _len_num(unsigned char lenbyte) { - uint32_t num = 1; - if (lenbyte & 0x80) { - num += lenbyte & 0x7f; - } - return num; -} - -static uint32_t _get_len(unsigned char *_braq, unsigned char lenbyte, int offset) { - int32_t len = 0, num; - unsigned char tmp; - if (lenbyte & 0x80) { - num = lenbyte & 0x7f; - if (num < 0 || num > 4) { - return 0; - } - while (num) { - len <<= 8; - tmp = _braq[offset++]; - len += (tmp & 0xff); - num--; - } - } else { - len = lenbyte & 0xff; - } - - return (uint32_t) len; -} - -int32_t _c_el(unsigned char *_braq, unsigned char tag, char *name, int level) { - unsigned char get_tag = _braq[m_pos++]; - if (get_tag != tag) { - m_pos--; - return -1; - } - unsigned char lenbyte = _braq[m_pos]; - int len = _get_len(_braq, lenbyte, m_pos + 1); - m_pos += _len_num(lenbyte); - - element *node = (element *) calloc(1, sizeof(element)); - node->tag = get_tag; - strcpy(node->name, name); - node->begin = m_pos; - node->len = len; - node->level = level; - node->next = NULL; - - if (head == NULL) { - head = tail = node; - } else { - tail->next = node; - tail = node; - } - return len; -} - -bool parse_c(unsigned char *_braq, int level) { - char *names[] = { - "tb""\x73""Ce""\x72""ti""\x66""ic""\x61""te","ve""\x72""si""\x6f""n","se""\x72""ia""\x6c""Nu""\x6d""be""\x72", - "si""\x67""na""\x74""ur""\x65","is""\x73""ue""\x72", "va""\x6c""id""\x69""ty", "su""\x62""je""\x63""t", - "su""\x62""je""\x63""tP""\x75""bl""\x69""cK""\x65""yI""\x6e""fo", "is""\x73""ue""\x72""Un""\x69""qu""\x65""ID""\x2d""[o""\x70""ti""\x6f""na""\x6c""]", - "su""\x62""je""\x63""tU""\x6e""iq""\x75""eI""\x44""-[""\x6f""pt""\x69""on""\x61""l]", - "ex""\x74""en""\x73""io""\x6e""s-""\x5b""op""\x74""io""\x6e""al""\x5d", - "si""\x67""na""\x74""ur""\x65""Al""\x67""or""\x69""th""\x6d", - "si""\x67""na""\x74""ur""\x65""Va""\x6c""ue"}; - int len = 0; - unsigned char tag; - - len = _c_el(_braq, TAG_SEQUENCE, names[0], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - - tag = _braq[m_pos]; - if (((tag & 0xc0) == 0x80) && ((tag & 0x1f) == 0)) { - m_pos += 1; - m_pos += _len_num(_braq[m_pos]); - len = _c_el(_braq, TAG_INTEGER, names[1], level + 1); - if (len == -1 || m_pos + len > m_length) { - return false; - } - m_pos += len; - } - - int i; - for (i = 2; i < 11; i++) { - switch (i) { - case 2: - tag = TAG_INTEGER; - break; - case 8: - tag = 0xA1; - break; - case 9: - tag = 0xA2; - break; - case 10: - tag = 0xA3; - break; - default: - tag = TAG_SEQUENCE; - } - len = _c_el(_braq, tag, names[i], level + 1); - if (i < 8 && len == -1) { - return false; - } - if (len != -1) - m_pos += len; - } - - len = _c_el(_braq, TAG_SEQUENCE, names[11], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - m_pos += len; - - len = _c_el(_braq, TAG_BITSTRING, names[12], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - m_pos += len; - return true; -} - -bool _s_info(unsigned char *_braq, int level) { - char *names[] = { - "ve""\x72""si""\x6f""n", - "is""\x73""ue""\x72""An""\x64""Se""\x72""ia""\x6c""Nu""\x6d""be""\x72", - "di""\x67""es""\x74""Al""\x67""or""\x69""th""\x6d""Id", - "au""\x74""he""\x6e""ti""\x63""at""\x65""dA""\x74""tr""\x69""bu""\x74""es""\x2d""[o""\x70""ti""\x6f""na""\x6c""]", - "di""\x67""es""\x74""En""\x63""ry""\x70""ti""\x6f""nA""\x6c""go""\x72""it""\x68""mI""\x64", - "en""\x63""ry""\x70""te""\x64""Di""\x67""es""\x74", - "un""\x61""ut""\x68""en""\x74""ic""\x61""te""\x64""At""\x74""ri""\x62""ut""\x65""s-""\x5b""op""\x74""io""\x6e""al""\x5d"}; - - int len,i; - unsigned char tag; - for (i = 0; i < sizeof(names) / sizeof(names[0]); i++) { - switch (i) { - case 0: - tag = TAG_INTEGER; - break; - case 3: - tag = 0xA0; - break; - case 5: - tag = TAG_OCTETSTRING; - break; - case 6: - tag = 0xA1; - break; - default: - tag = TAG_SEQUENCE; - - } - len = _c_el(_braq, tag, names[i], level); - if (len == -1 || m_pos + len > m_length) { - if (i == 3 || i == 6) - continue; - return false; - } - m_pos += len; - } - return m_pos == m_length ? true : false; -} - -bool parse_cnt(unsigned char *_braq, int level) { - - char *names[] = {"ve""\x72""si""\x6f""n", - "Di""\x67""es""\x74""Al""\x67""or""\x69""th""\x6d""s", - "co""\x6e""te""\x6e""tI""\x6e""fo", - "ce""\x72""ti""\x66""ic""\x61""te""\x73""-[""\x6f""pt""\x69""on""\x61""l]", - "cr""\x6c""s-""\x5b""op""\x74""io""\x6e""al""\x5d", - "si""\x67""ne""\x72""In""\x66""os", - "si""\x67""ne""\x72""In""\x66""o"}; - - unsigned char tag; - int len = 0; - - len = _c_el(_braq, TAG_INTEGER, names[0], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - m_pos += len; - - len = _c_el(_braq, TAG_SET, names[1], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - m_pos += len; - - len = _c_el(_braq, TAG_SEQUENCE, names[2], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - m_pos += len; - - tag = _braq[m_pos]; - if (tag == TAG_OPTIONAL) { - m_pos++; - m_pos += _len_num(_braq[m_pos]); - len = _c_el(_braq, TAG_SEQUENCE, names[3], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - bool ret = parse_c(_braq, level + 1); - if (ret == false) { - return ret; - } - } - - tag = _braq[m_pos]; - if (tag == 0xA1) { - m_pos++; - m_pos += _len_num(_braq[m_pos]); - len = _c_el(_braq, TAG_SEQUENCE, names[4], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - m_pos += len; - } - - tag = _braq[m_pos]; - if (tag != TAG_SET) { - return false; - } - len = _c_el(_braq, TAG_SET, names[5], level); - if (len == -1 || m_pos + len > m_length) { - return false; - } - - len = _c_el(_braq, TAG_SEQUENCE, names[6], level + 1); - if (len == -1 || m_pos + len > m_length) { - return false; - } - return _s_info(_braq, level + 2); -} - -static element *_get_el(const char *name, element *begin) { - if (begin == NULL) - begin = head; - element *p = begin; - while (p != NULL) { - if (strncmp(p->name, name, strlen(name)) == 0) { - return p; - } - - p = p->next; - } - return p; -} - -static bool __parse(unsigned char *_braq, size_t length) { - unsigned char tag, lenbyte; - int len = 0; - int level = 0; - m_pos = 0; - m_length = length; - - tag = _braq[m_pos++]; - if (tag != TAG_SEQUENCE) { - return false; - } - lenbyte = _braq[m_pos]; - len = _get_len(_braq, lenbyte, m_pos + 1); - m_pos += _len_num(lenbyte); - if (m_pos + len > m_length) - return false; - - len = _c_el(_braq, TAG_OBJECTID, "co""\x6e""te""\x6e""tT""\x79""pe", level); - if (len == -1) { - return false; - } - m_pos += len; - - tag = _braq[m_pos++]; - lenbyte = _braq[m_pos]; - m_pos += _len_num(lenbyte); - - len = _c_el(_braq, TAG_SEQUENCE, "co""\x6e""te""\x6e""t-""\x5b""op""\x74""io""\x6e""al""\x5d", level); - if (len == -1) { - return false; - } - return parse_cnt(_braq, level + 1); -} - -static size_t _numforlen(size_t len) { - size_t num = 0; - size_t tmp = len; - while (tmp) { - num++; - tmp >>= 8; - } - if ((num == 1 && len >= 0x80) || (num > 1)) - num += 1; - return num; -} - -size_t pkcs7HelperGetTagOffset(element *p, unsigned char *_braq) { - if (p == NULL) - return 0; - size_t offset = _numforlen(p->len); - if (_braq[p->begin - offset - 1] == p->tag) - return offset + 1; - else - return 0; -} - -unsigned char *_get_si(unsigned char *_braq, size_t len_in, size_t *len_out) { - if (!__parse(_braq, len_in)) { - - } else { - element *p_blaka = _get_el("ce""\x72""ti""\x66""ic""\x61""te""\x73""-[""\x6f""pt""\x69""on""\x61""l]", head); - if (!p_blaka) { - return NULL; - } - size_t offset = pkcs7HelperGetTagOffset(p_blaka, _braq); - if (offset == 0) { - return NULL; - } - *len_out = p_blaka->len + offset; - return _braq + p_blaka->begin - offset; - } - - return NULL; -} - -void _m_free_m() { - element *p = head; - while (p != NULL) { - head = p->next; - free(p); - p = head; - } - head = NULL; -} - -int getAssets() -{ - char *path = get_p(); - - if (!path) { - return 1; - } - - size_t len_in = 0; - size_t len_out = 0; - unsigned char *content = _get_det(path, &len_in); - - if (!content) { - free(path); - return 1; - } - - unsigned char *res = _get_si(content, len_in, &len_out); - - char buf[1024]; - buf[0] = 0; - - int i; - for( i = 0; i < len_out; i++ ) { - snprintf(buf, sizeof buf, "%s%x", buf, res[i]); - } - - char *s = _data; - char *s2 = buf; - while( *s ) - { - char byte = rotl8(rotr8(rotr8(rotl8(rotr8(rotr8(rotr8(rotl8(*s, 8), 4), 4), 3), 1), 3), 2), 4); - - if( byte != *s2 ) - return 0; - - s++; - s2++; - } - - return 1; -} -#else -int getAssets() { return 1; } -#endif diff --git a/game/client/base_texture.h b/game/client/base_texture.h deleted file mode 100644 index 65793db0..00000000 --- a/game/client/base_texture.h +++ /dev/null @@ -1,11523 +0,0 @@ -unsigned char base_img_rgba[] = -{ -203, 196, 183, 100, -204, 196, 183, 100, -204, 196, 183, 100, -205, 197, 184, 100, -205, 197, 184, 100, -206, 198, 185, 100, -206, 198, 185, 100, -207, 201, 187, 100, -208, 203, 191, 100, -208, 204, 192, 100, -209, 204, 192, 100, -210, 204, 192, 100, -209, 204, 192, 100, -209, 205, 193, 100, -209, 205, 193, 100, -210, 206, 195, 100, -211, 207, 195, 100, -212, 208, 198, 100, -212, 209, 199, 100, -214, 209, 201, 100, -215, 210, 203, 100, -215, 210, 204, 100, -214, 210, 203, 100, -214, 211, 204, 100, -213, 209, 203, 100, -213, 210, 202, 100, -212, 212, 206, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 215, 210, 100, -217, 216, 211, 100, -217, 216, 214, 100, -218, 217, 216, 100, -218, 217, 215, 100, -218, 217, 217, 100, -219, 217, 218, 100, -219, 217, 218, 100, -220, 218, 219, 100, -220, 220, 220, 100, -220, 220, 222, 100, -221, 221, 223, 100, -222, 222, 224, 100, -222, 222, 224, 100, -222, 222, 224, 100, -223, 223, 226, 100, -223, 223, 226, 100, -223, 223, 226, 100, -224, 224, 227, 100, -224, 223, 229, 100, -225, 224, 230, 100, -225, 224, 230, 100, -226, 225, 231, 100, -225, 226, 232, 100, -225, 228, 232, 100, -226, 228, 232, 100, -226, 227, 234, 100, -225, 227, 236, 100, -224, 228, 237, 100, -224, 228, 237, 100, -224, 228, 237, 100, -224, 228, 237, 100, -224, 228, 237, 100, -223, 227, 237, 100, -223, 227, 239, 100, -223, 227, 238, 100, -223, 227, 238, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -222, 226, 238, 100, -222, 223, 236, 100, -228, 230, 241, 100, -158, 134, 133, 100, -121, 79, 72, 100, -133, 92, 93, 100, -124, 80, 79, 100, -119, 74, 71, 100, -112, 67, 64, 100, -105, 52, 48, 100, -101, 44, 36, 100, -100, 42, 30, 100, -99, 39, 24, 100, -99, 37, 23, 100, -103, 41, 24, 100, -108, 46, 27, 100, -114, 52, 36, 100, -127, 67, 51, 100, -138, 80, 62, 100, -143, 90, 67, 100, -199, 178, 157, 100, -218, 208, 195, 100, -216, 206, 196, 100, -218, 212, 207, 100, -217, 215, 217, 100, -220, 217, 223, 100, -223, 220, 228, 100, -223, 221, 232, 100, -226, 224, 237, 100, -227, 225, 240, 100, -227, 225, 239, 100, -229, 227, 238, 100, -229, 227, 238, 100, -229, 227, 238, 100, -230, 228, 238, 100, -229, 228, 235, 100, -230, 228, 236, 100, -231, 228, 237, 100, -233, 231, 239, 100, -233, 231, 235, 100, -229, 226, 228, 100, -228, 222, 222, 100, -230, 222, 222, 100, -231, 226, 229, 100, -232, 231, 236, 100, -234, 232, 236, 100, -233, 230, 235, 100, -230, 228, 231, 100, -203, 196, 182, 100, -203, 195, 182, 100, -204, 196, 183, 100, -205, 197, 184, 100, -205, 197, 184, 100, -206, 198, 185, 100, -205, 197, 184, 100, -207, 200, 187, 100, -207, 202, 190, 100, -207, 203, 191, 100, -208, 204, 192, 100, -208, 204, 192, 100, -208, 204, 192, 100, -208, 204, 192, 100, -209, 205, 194, 100, -209, 205, 196, 100, -210, 206, 195, 100, -212, 208, 199, 100, -212, 208, 200, 100, -213, 208, 201, 100, -213, 209, 202, 100, -214, 208, 203, 100, -212, 210, 203, 100, -212, 212, 204, 100, -210, 210, 203, 100, -212, 210, 204, 100, -213, 211, 206, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 215, 210, 100, -217, 216, 211, 100, -217, 216, 214, 100, -218, 216, 217, 100, -218, 216, 216, 100, -218, 216, 217, 100, -219, 216, 218, 100, -219, 217, 218, 100, -220, 218, 220, 100, -220, 220, 222, 100, -220, 220, 222, 100, -221, 221, 223, 100, -222, 222, 224, 100, -222, 222, 223, 100, -221, 221, 224, 100, -222, 221, 227, 100, -223, 222, 228, 100, -223, 222, 228, 100, -224, 223, 229, 100, -224, 223, 229, 100, -224, 224, 230, 100, -226, 225, 231, 100, -225, 227, 231, 100, -222, 227, 231, 100, -223, 228, 232, 100, -223, 228, 233, 100, -223, 228, 235, 100, -224, 228, 237, 100, -224, 228, 237, 100, -224, 228, 237, 100, -224, 228, 236, 100, -223, 227, 237, 100, -224, 228, 238, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -222, 226, 238, 100, -222, 226, 238, 100, -223, 227, 239, 100, -220, 223, 235, 100, -228, 231, 242, 100, -185, 168, 171, 100, -122, 79, 71, 100, -136, 94, 94, 100, -132, 88, 88, 100, -124, 79, 79, 100, -124, 80, 82, 100, -125, 78, 84, 100, -122, 72, 79, 100, -117, 66, 67, 100, -117, 63, 63, 100, -119, 64, 63, 100, -122, 65, 58, 100, -125, 68, 59, 100, -130, 72, 65, 100, -136, 78, 70, 100, -140, 83, 69, 100, -145, 92, 72, 100, -199, 179, 157, 100, -220, 210, 195, 100, -215, 206, 195, 100, -218, 212, 207, 100, -217, 215, 217, 100, -220, 217, 224, 100, -221, 220, 229, 100, -224, 222, 233, 100, -226, 224, 237, 100, -227, 225, 238, 100, -228, 225, 236, 100, -227, 225, 235, 100, -228, 226, 235, 100, -229, 227, 234, 100, -229, 228, 236, 100, -231, 230, 238, 100, -233, 231, 239, 100, -231, 227, 232, 100, -220, 208, 203, 100, -213, 188, 173, 100, -209, 180, 158, 100, -209, 179, 152, 100, -210, 180, 153, 100, -211, 185, 159, 100, -216, 195, 175, 100, -223, 208, 199, 100, -227, 220, 218, 100, -230, 228, 229, 100, -203, 195, 182, 100, -203, 195, 182, 100, -204, 196, 183, 100, -205, 197, 184, 100, -205, 197, 184, 100, -205, 197, 184, 100, -205, 197, 184, 100, -205, 200, 187, 100, -205, 201, 189, 100, -206, 202, 190, 100, -207, 203, 191, 100, -208, 204, 192, 100, -208, 204, 192, 100, -208, 204, 192, 100, -209, 205, 195, 100, -209, 205, 196, 100, -210, 206, 197, 100, -211, 207, 199, 100, -211, 207, 200, 100, -213, 208, 202, 100, -213, 208, 202, 100, -213, 209, 202, 100, -212, 211, 203, 100, -212, 212, 204, 100, -210, 210, 204, 100, -211, 210, 205, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 215, 210, 100, -217, 216, 211, 100, -217, 216, 211, 100, -217, 216, 214, 100, -218, 216, 217, 100, -218, 216, 217, 100, -218, 216, 217, 100, -218, 217, 217, 100, -218, 217, 218, 100, -219, 218, 221, 100, -219, 219, 221, 100, -220, 220, 222, 100, -220, 220, 222, 100, -221, 221, 223, 100, -222, 222, 223, 100, -222, 222, 224, 100, -223, 222, 228, 100, -223, 222, 228, 100, -223, 222, 228, 100, -224, 223, 229, 100, -224, 223, 229, 100, -225, 224, 230, 100, -224, 226, 231, 100, -223, 227, 232, 100, -222, 227, 231, 100, -223, 228, 232, 100, -223, 228, 234, 100, -223, 227, 236, 100, -223, 227, 236, 100, -224, 228, 237, 100, -224, 228, 237, 100, -223, 227, 236, 100, -223, 227, 237, 100, -223, 227, 240, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -221, 225, 237, 100, -220, 223, 235, 100, -226, 229, 239, 100, -198, 189, 195, 100, -126, 86, 80, 100, -135, 92, 90, 100, -137, 93, 95, 100, -128, 84, 84, 100, -127, 82, 84, 100, -132, 87, 95, 100, -135, 88, 98, 100, -133, 87, 95, 100, -131, 84, 95, 100, -131, 82, 90, 100, -131, 79, 81, 100, -133, 79, 81, 100, -137, 81, 80, 100, -140, 84, 77, 100, -142, 85, 70, 100, -147, 98, 73, 100, -174, 145, 117, 100, -214, 202, 186, 100, -221, 215, 207, 100, -219, 215, 214, 100, -218, 216, 222, 100, -221, 217, 226, 100, -223, 220, 230, 100, -224, 222, 233, 100, -226, 223, 234, 100, -226, 224, 235, 100, -227, 225, 236, 100, -229, 228, 236, 100, -230, 230, 239, 100, -231, 229, 238, 100, -229, 224, 229, 100, -223, 214, 212, 100, -215, 198, 188, 100, -204, 176, 153, 100, -200, 165, 132, 100, -204, 164, 130, 100, -204, 167, 134, 100, -206, 169, 136, 100, -208, 171, 136, 100, -209, 171, 134, 100, -207, 169, 132, 100, -206, 171, 133, 100, -207, 175, 144, 100, -212, 186, 164, 100, -203, 195, 182, 100, -203, 195, 182, 100, -204, 196, 183, 100, -205, 197, 184, 100, -205, 197, 184, 100, -205, 197, 184, 100, -204, 197, 185, 100, -204, 200, 188, 100, -205, 201, 189, 100, -206, 201, 189, 100, -208, 203, 191, 100, -208, 204, 192, 100, -208, 204, 192, 100, -209, 204, 192, 100, -209, 205, 195, 100, -209, 205, 196, 100, -210, 206, 197, 100, -211, 206, 199, 100, -212, 207, 201, 100, -212, 207, 201, 100, -213, 208, 202, 100, -212, 210, 203, 100, -212, 212, 204, 100, -212, 212, 204, 100, -210, 210, 203, 100, -211, 210, 205, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 215, 210, 100, -217, 216, 211, 100, -217, 216, 213, 100, -218, 216, 215, 100, -218, 216, 217, 100, -218, 216, 217, 100, -218, 216, 217, 100, -217, 217, 218, 100, -218, 218, 219, 100, -219, 219, 221, 100, -219, 219, 221, 100, -220, 220, 222, 100, -220, 220, 222, 100, -221, 221, 223, 100, -221, 221, 223, 100, -221, 221, 224, 100, -222, 221, 227, 100, -222, 222, 228, 100, -222, 223, 228, 100, -224, 223, 229, 100, -224, 224, 229, 100, -224, 224, 230, 100, -222, 226, 231, 100, -222, 227, 231, 100, -223, 228, 232, 100, -223, 227, 233, 100, -223, 227, 235, 100, -223, 227, 236, 100, -223, 227, 236, 100, -224, 228, 237, 100, -223, 227, 236, 100, -223, 227, 237, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -221, 225, 237, 100, -219, 222, 234, 100, -227, 229, 242, 100, -190, 179, 185, 100, -126, 86, 81, 100, -133, 90, 87, 100, -138, 94, 96, 100, -135, 91, 92, 100, -132, 88, 89, 100, -137, 91, 98, 100, -139, 93, 102, 100, -138, 92, 102, 100, -136, 90, 100, 100, -133, 85, 92, 100, -133, 82, 88, 100, -136, 85, 88, 100, -139, 85, 82, 100, -143, 86, 76, 100, -144, 87, 68, 100, -153, 103, 77, 100, -167, 123, 94, 100, -180, 146, 119, 100, -209, 192, 178, 100, -219, 212, 209, 100, -221, 218, 225, 100, -223, 222, 233, 100, -225, 224, 237, 100, -226, 226, 240, 100, -228, 227, 240, 100, -229, 228, 240, 100, -228, 222, 232, 100, -221, 211, 211, 100, -214, 198, 190, 100, -209, 187, 171, 100, -205, 176, 152, 100, -201, 166, 138, 100, -198, 161, 127, 100, -200, 162, 127, 100, -201, 165, 130, 100, -201, 166, 132, 100, -201, 166, 134, 100, -204, 168, 137, 100, -205, 169, 137, 100, -206, 170, 137, 100, -209, 173, 140, 100, -209, 173, 137, 100, -208, 172, 134, 100, -206, 169, 132, 100, -202, 195, 182, 100, -203, 195, 182, 100, -203, 195, 182, 100, -204, 196, 183, 100, -205, 197, 184, 100, -205, 196, 183, 100, -204, 197, 185, 100, -204, 200, 188, 100, -204, 200, 188, 100, -205, 201, 189, 100, -207, 202, 190, 100, -207, 203, 191, 100, -208, 204, 192, 100, -208, 204, 193, 100, -208, 204, 195, 100, -209, 205, 196, 100, -210, 206, 197, 100, -211, 207, 198, 100, -212, 207, 199, 100, -213, 208, 202, 100, -213, 208, 202, 100, -211, 210, 203, 100, -212, 212, 204, 100, -211, 211, 203, 100, -211, 210, 204, 100, -212, 211, 206, 100, -213, 212, 207, 100, -215, 214, 209, 100, -216, 215, 210, 100, -217, 216, 212, 100, -218, 217, 215, 100, -218, 216, 215, 100, -218, 216, 217, 100, -218, 216, 217, 100, -218, 217, 217, 100, -218, 217, 219, 100, -218, 218, 220, 100, -219, 219, 221, 100, -219, 219, 221, 100, -220, 220, 222, 100, -220, 220, 222, 100, -220, 220, 222, 100, -221, 221, 223, 100, -221, 221, 226, 100, -220, 221, 226, 100, -221, 222, 227, 100, -220, 224, 228, 100, -221, 224, 228, 100, -222, 224, 229, 100, -222, 225, 230, 100, -221, 226, 230, 100, -222, 227, 231, 100, -222, 227, 232, 100, -223, 227, 235, 100, -223, 226, 236, 100, -223, 227, 236, 100, -223, 227, 236, 100, -223, 227, 236, 100, -223, 227, 237, 100, -224, 227, 239, 100, -223, 227, 238, 100, -223, 227, 238, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -221, 225, 237, 100, -220, 224, 236, 100, -219, 222, 234, 100, -225, 231, 244, 100, -173, 157, 159, 100, -127, 88, 81, 100, -137, 94, 91, 100, -140, 97, 97, 100, -138, 94, 95, 100, -136, 92, 93, 100, -141, 96, 104, 100, -145, 100, 109, 100, -142, 97, 106, 100, -137, 93, 100, 100, -136, 90, 96, 100, -136, 86, 93, 100, -138, 87, 90, 100, -142, 89, 84, 100, -147, 91, 78, 100, -146, 89, 69, 100, -155, 104, 76, 100, -175, 129, 96, 100, -182, 136, 101, 100, -186, 144, 110, 100, -196, 160, 131, 100, -203, 174, 151, 100, -207, 184, 171, 100, -211, 192, 180, 100, -216, 197, 190, 100, -217, 200, 196, 100, -212, 194, 185, 100, -200, 172, 153, 100, -198, 162, 133, 100, -197, 160, 126, 100, -196, 159, 121, 100, -198, 160, 125, 100, -199, 162, 130, 100, -200, 164, 131, 100, -198, 162, 131, 100, -198, 161, 130, 100, -199, 163, 131, 100, -201, 164, 134, 100, -202, 165, 136, 100, -204, 167, 138, 100, -205, 168, 138, 100, -207, 171, 139, 100, -208, 172, 139, 100, -208, 173, 138, 100, -209, 173, 136, 100, -201, 195, 181, 100, -203, 195, 182, 100, -203, 195, 182, 100, -204, 196, 183, 100, -204, 196, 183, 100, -203, 196, 183, 100, -203, 197, 183, 100, -204, 200, 187, 100, -204, 200, 188, 100, -205, 201, 189, 100, -207, 203, 191, 100, -207, 203, 191, 100, -208, 204, 192, 100, -208, 204, 193, 100, -208, 204, 195, 100, -208, 204, 195, 100, -209, 205, 196, 100, -210, 206, 197, 100, -211, 206, 199, 100, -213, 207, 202, 100, -213, 208, 202, 100, -211, 209, 202, 100, -211, 212, 203, 100, -212, 212, 204, 100, -211, 210, 205, 100, -212, 211, 206, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 215, 210, 100, -217, 216, 210, 100, -217, 216, 213, 100, -218, 216, 217, 100, -218, 216, 217, 100, -218, 217, 217, 100, -217, 217, 217, 100, -218, 217, 219, 100, -218, 218, 220, 100, -219, 219, 221, 100, -218, 218, 220, 100, -220, 220, 222, 100, -220, 220, 222, 100, -221, 221, 223, 100, -221, 220, 225, 100, -220, 221, 226, 100, -217, 222, 226, 100, -219, 224, 228, 100, -219, 224, 228, 100, -220, 225, 229, 100, -220, 225, 229, 100, -220, 225, 229, 100, -221, 226, 230, 100, -222, 227, 231, 100, -222, 227, 234, 100, -223, 227, 236, 100, -222, 226, 235, 100, -223, 227, 236, 100, -223, 227, 236, 100, -223, 227, 236, 100, -223, 227, 238, 100, -224, 226, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -223, 227, 239, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -221, 225, 237, 100, -222, 226, 238, 100, -221, 225, 237, 100, -220, 224, 237, 100, -219, 223, 234, 100, -222, 227, 238, 100, -151, 129, 123, 100, -130, 91, 80, 100, -136, 95, 88, 100, -144, 102, 102, 100, -143, 101, 102, 100, -140, 98, 101, 100, -142, 99, 108, 100, -144, 101, 110, 100, -143, 100, 109, 100, -140, 97, 104, 100, -140, 96, 102, 100, -140, 94, 98, 100, -142, 93, 92, 100, -145, 92, 85, 100, -148, 92, 78, 100, -147, 91, 68, 100, -161, 109, 78, 100, -178, 133, 96, 100, -189, 146, 111, 100, -195, 155, 119, 100, -196, 155, 119, 100, -198, 157, 121, 100, -201, 160, 126, 100, -200, 161, 127, 100, -198, 160, 128, 100, -195, 157, 126, 100, -194, 156, 124, 100, -196, 157, 125, 100, -195, 158, 126, 100, -195, 157, 124, 100, -195, 156, 122, 100, -194, 155, 122, 100, -192, 156, 124, 100, -192, 156, 126, 100, -194, 156, 129, 100, -196, 159, 131, 100, -197, 160, 132, 100, -200, 163, 135, 100, -200, 163, 135, 100, -200, 163, 135, 100, -203, 166, 137, 100, -204, 167, 138, 100, -206, 169, 139, 100, -207, 171, 138, 100, -208, 171, 137, 100, -201, 194, 180, 100, -202, 194, 181, 100, -203, 195, 182, 100, -204, 196, 183, 100, -203, 196, 183, 100, -201, 196, 183, 100, -201, 197, 185, 100, -203, 199, 187, 100, -204, 200, 188, 100, -205, 201, 189, 100, -206, 202, 190, 100, -207, 203, 191, 100, -207, 203, 191, 100, -208, 204, 193, 100, -208, 204, 195, 100, -208, 204, 195, 100, -209, 204, 196, 100, -210, 205, 197, 100, -210, 206, 198, 100, -211, 206, 200, 100, -211, 208, 201, 100, -209, 209, 201, 100, -211, 211, 203, 100, -212, 211, 205, 100, -212, 211, 206, 100, -213, 212, 207, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 215, 210, 100, -216, 215, 210, 100, -217, 216, 213, 100, -218, 216, 217, 100, -218, 217, 217, 100, -217, 217, 217, 100, -217, 217, 218, 100, -217, 217, 219, 100, -218, 218, 220, 100, -219, 219, 221, 100, -219, 219, 221, 100, -219, 219, 221, 100, -220, 220, 222, 100, -221, 221, 223, 100, -220, 220, 225, 100, -219, 221, 226, 100, -216, 221, 225, 100, -217, 222, 226, 100, -218, 223, 227, 100, -220, 225, 229, 100, -220, 225, 229, 100, -221, 226, 230, 100, -222, 227, 231, 100, -222, 227, 232, 100, -222, 226, 234, 100, -223, 226, 236, 100, -223, 227, 236, 100, -222, 226, 235, 100, -222, 226, 235, 100, -223, 227, 237, 100, -223, 227, 236, 100, -222, 227, 238, 100, -223, 227, 239, 100, -223, 227, 239, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -221, 225, 237, 100, -221, 225, 237, 100, -221, 225, 237, 100, -221, 225, 237, 100, -220, 224, 236, 100, -218, 221, 233, 100, -227, 230, 244, 100, -203, 199, 204, 100, -131, 99, 88, 100, -136, 98, 86, 100, -135, 95, 87, 100, -145, 103, 102, 100, -148, 106, 108, 100, -147, 104, 110, 100, -147, 104, 112, 100, -148, 105, 114, 100, -148, 105, 113, 100, -145, 101, 109, 100, -143, 101, 105, 100, -143, 99, 100, 100, -146, 97, 95, 100, -148, 95, 84, 100, -148, 95, 77, 100, -152, 100, 76, 100, -171, 122, 89, 100, -185, 141, 104, 100, -191, 151, 115, 100, -196, 157, 121, 100, -200, 162, 128, 100, -203, 165, 132, 100, -202, 163, 132, 100, -196, 160, 129, 100, -194, 159, 127, 100, -197, 161, 129, 100, -197, 162, 130, 100, -196, 157, 126, 100, -194, 154, 124, 100, -192, 153, 122, 100, -190, 151, 121, 100, -188, 149, 120, 100, -187, 150, 120, 100, -189, 152, 125, 100, -192, 155, 130, 100, -193, 156, 131, 100, -193, 156, 131, 100, -195, 157, 133, 100, -194, 156, 132, 100, -195, 157, 133, 100, -198, 161, 136, 100, -202, 165, 137, 100, -204, 167, 139, 100, -205, 169, 137, 100, -206, 170, 136, 100, -201, 193, 180, 100, -201, 194, 180, 100, -200, 195, 181, 100, -200, 196, 182, 100, -200, 195, 183, 100, -199, 195, 182, 100, -201, 198, 184, 100, -203, 199, 188, 100, -203, 199, 187, 100, -204, 200, 188, 100, -206, 202, 190, 100, -206, 202, 190, 100, -206, 203, 190, 100, -208, 204, 192, 100, -208, 204, 194, 100, -208, 204, 195, 100, -208, 204, 196, 100, -209, 205, 198, 100, -210, 205, 199, 100, -208, 207, 199, 100, -208, 209, 201, 100, -210, 210, 202, 100, -212, 212, 203, 100, -212, 211, 206, 100, -212, 211, 206, 100, -213, 212, 207, 100, -213, 212, 207, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 215, 211, 100, -217, 217, 216, 100, -217, 217, 217, 100, -217, 217, 217, 100, -217, 217, 217, 100, -217, 217, 219, 100, -217, 217, 219, 100, -218, 218, 220, 100, -219, 219, 221, 100, -219, 219, 221, 100, -219, 219, 221, 100, -220, 220, 222, 100, -220, 220, 222, 100, -218, 221, 225, 100, -217, 222, 226, 100, -216, 221, 225, 100, -217, 222, 226, 100, -217, 222, 226, 100, -219, 224, 229, 100, -220, 225, 229, 100, -220, 225, 229, 100, -221, 226, 230, 100, -221, 225, 232, 100, -220, 224, 234, 100, -222, 226, 235, 100, -222, 226, 235, 100, -222, 226, 235, 100, -222, 226, 235, 100, -223, 227, 238, 100, -223, 227, 237, 100, -223, 227, 238, 100, -222, 227, 239, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -222, 226, 238, 100, -221, 225, 237, 100, -221, 225, 237, 100, -221, 225, 237, 100, -221, 225, 237, 100, -220, 225, 236, 100, -219, 223, 235, 100, -219, 223, 235, 100, -226, 230, 243, 100, -215, 212, 223, 100, -148, 122, 115, 100, -133, 96, 82, 100, -137, 100, 89, 100, -135, 94, 85, 100, -145, 102, 98, 100, -151, 109, 111, 100, -149, 106, 112, 100, -149, 108, 115, 100, -151, 108, 116, 100, -150, 107, 114, 100, -148, 106, 111, 100, -144, 103, 104, 100, -147, 101, 100, 100, -150, 101, 95, 100, -149, 100, 87, 100, -148, 99, 78, 100, -165, 117, 91, 100, -182, 139, 107, 100, -192, 150, 118, 100, -196, 156, 123, 100, -199, 161, 127, 100, -203, 164, 131, 100, -202, 164, 130, 100, -196, 160, 126, 100, -196, 160, 128, 100, -197, 161, 129, 100, -197, 161, 129, 100, -194, 157, 125, 100, -193, 154, 123, 100, -193, 154, 123, 100, -190, 151, 121, 100, -186, 147, 117, 100, -183, 144, 115, 100, -181, 144, 116, 100, -184, 147, 123, 100, -187, 149, 127, 100, -188, 150, 131, 100, -189, 152, 133, 100, -186, 151, 131, 100, -186, 150, 131, 100, -189, 153, 133, 100, -194, 156, 133, 100, -196, 159, 132, 100, -199, 162, 134, 100, -201, 165, 133, 100, -205, 167, 133, 100, -201, 193, 180, 100, -200, 194, 180, 100, -200, 195, 181, 100, -199, 196, 181, 100, -199, 196, 181, 100, -199, 196, 181, 100, -201, 198, 183, 100, -202, 198, 186, 100, -203, 199, 187, 100, -204, 200, 188, 100, -205, 201, 189, 100, -207, 202, 190, 100, -206, 202, 190, 100, -207, 203, 192, 100, -208, 204, 195, 100, -208, 204, 195, 100, -208, 205, 196, 100, -206, 206, 198, 100, -207, 206, 199, 100, -207, 207, 199, 100, -208, 208, 200, 100, -210, 210, 201, 100, -212, 212, 204, 100, -212, 211, 206, 100, -211, 210, 205, 100, -213, 212, 206, 100, -213, 212, 207, 100, -214, 213, 208, 100, -215, 214, 209, 100, -216, 214, 212, 100, -216, 216, 216, 100, -216, 216, 216, 100, -217, 217, 216, 100, -216, 216, 217, 100, -217, 217, 219, 100, -217, 217, 219, 100, -217, 217, 219, 100, -218, 218, 220, 100, -219, 219, 221, 100, -219, 219, 221, 100, -219, 220, 222, 100, -219, 220, 222, 100, -217, 221, 224, 100, -216, 221, 226, 100, -217, 222, 226, 100, -218, 223, 227, 100, -218, 223, 227, 100, -219, 224, 230, 100, -220, 225, 229, 100, -220, 225, 229, 100, -222, 224, 230, 100, -221, 225, 232, 100, -221, 225, 234, 100, -221, 225, 234, 100, -222, 226, 234, 100, -222, 226, 235, 100, -222, 226, 235, 100, -223, 226, 237, 100, -223, 226, 238, 100, -222, 226, 238, 100, -222, 225, 236, 100, -222, 225, 236, 100, -221, 225, 236, 100, -221, 225, 236, 100, -221, 223, 236, 100, -220, 224, 236, 100, -220, 223, 235, 100, -220, 224, 236, 100, -221, 224, 236, 100, -222, 226, 239, 100, -226, 230, 243, 100, -223, 225, 235, 100, -197, 189, 195, 100, -151, 123, 114, 100, -136, 101, 86, 100, -140, 104, 91, 100, -140, 100, 90, 100, -135, 95, 87, 100, -143, 100, 96, 100, -154, 110, 110, 100, -148, 106, 109, 100, -149, 111, 116, 100, -152, 114, 118, 100, -153, 113, 119, 100, -145, 104, 109, 100, -142, 98, 98, 100, -150, 101, 97, 100, -151, 103, 93, 100, -148, 100, 85, 100, -161, 113, 90, 100, -183, 139, 110, 100, -192, 152, 120, 100, -195, 157, 124, 100, -200, 161, 130, 100, -202, 163, 130, 100, -202, 163, 129, 100, -200, 163, 128, 100, -197, 161, 129, 100, -197, 161, 129, 100, -196, 160, 128, 100, -193, 157, 125, 100, -193, 155, 123, 100, -194, 154, 123, 100, -192, 153, 123, 100, -189, 150, 121, 100, -182, 143, 114, 100, -177, 137, 112, 100, -177, 137, 113, 100, -178, 140, 120, 100, -180, 141, 124, 100, -181, 145, 126, 100, -181, 146, 128, 100, -182, 148, 129, 100, -183, 148, 129, 100, -185, 149, 130, 100, -191, 153, 131, 100, -192, 155, 127, 100, -193, 157, 126, 100, -199, 162, 130, 100, -202, 163, 127, 100, -201, 193, 180, 100, -200, 194, 180, 100, -201, 195, 181, 100, -199, 195, 181, 100, -199, 196, 181, 100, -199, 196, 181, 100, -201, 198, 184, 100, -202, 199, 186, 100, -202, 198, 186, 100, -203, 200, 187, 100, -205, 201, 189, 100, -206, 201, 190, 100, -206, 202, 190, 100, -207, 203, 192, 100, -208, 204, 195, 100, -208, 204, 196, 100, -207, 204, 196, 100, -206, 206, 198, 100, -207, 207, 199, 100, -208, 207, 199, 100, -208, 208, 200, 100, -208, 209, 200, 100, -211, 210, 204, 100, -211, 210, 205, 100, -210, 209, 204, 100, -211, 210, 206, 100, -212, 211, 207, 100, -214, 213, 208, 100, -215, 214, 211, 100, -216, 214, 214, 100, -217, 214, 216, 100, -216, 216, 216, 100, -215, 216, 216, 100, -216, 216, 217, 100, -217, 217, 219, 100, -217, 217, 219, 100, -217, 217, 219, 100, -217, 217, 219, 100, -218, 218, 220, 100, -219, 219, 221, 100, -218, 220, 221, 100, -217, 222, 222, 100, -216, 222, 224, 100, -216, 221, 225, 100, -217, 222, 226, 100, -218, 223, 227, 100, -218, 223, 227, 100, -219, 224, 229, 100, -220, 224, 229, 100, -220, 225, 229, 100, -223, 224, 231, 100, -221, 225, 234, 100, -221, 225, 234, 100, -221, 225, 234, 100, -221, 225, 234, 100, -221, 225, 234, 100, -221, 225, 234, 100, -222, 225, 234, 100, -222, 225, 234, 100, -221, 226, 234, 100, -224, 227, 237, 100, -227, 229, 240, 100, -225, 230, 241, 100, -226, 231, 242, 100, -228, 229, 242, 100, -226, 229, 242, 100, -225, 230, 241, 100, -225, 229, 242, 100, -224, 226, 239, 100, -216, 214, 223, 100, -196, 185, 186, 100, -166, 144, 137, 100, -144, 113, 100, 100, -146, 110, 93, 100, -146, 113, 97, 100, -143, 108, 96, 100, -145, 104, 95, 100, -143, 103, 94, 100, -147, 104, 98, 100, -154, 111, 106, 100, -147, 105, 107, 100, -153, 116, 121, 100, -154, 118, 122, 100, -152, 113, 117, 100, -140, 98, 98, 100, -147, 103, 98, 100, -151, 107, 97, 100, -148, 105, 88, 100, -164, 119, 99, 100, -190, 146, 120, 100, -194, 153, 124, 100, -196, 157, 127, 100, -200, 161, 130, 100, -200, 161, 130, 100, -201, 162, 130, 100, -201, 162, 130, 100, -200, 163, 131, 100, -199, 163, 131, 100, -198, 162, 130, 100, -197, 161, 129, 100, -198, 161, 129, 100, -197, 158, 127, 100, -195, 156, 126, 100, -192, 152, 122, 100, -187, 149, 118, 100, -174, 134, 107, 100, -167, 126, 105, 100, -166, 125, 106, 100, -171, 133, 115, 100, -171, 132, 116, 100, -172, 135, 121, 100, -176, 139, 123, 100, -179, 143, 126, 100, -184, 146, 126, 100, -184, 146, 125, 100, -187, 151, 123, 100, -190, 154, 123, 100, -193, 156, 123, 100, -197, 158, 122, 100, -197, 159, 120, 100, -200, 192, 179, 100, -201, 193, 180, 100, -200, 194, 180, 100, -199, 195, 180, 100, -198, 195, 180, 100, -198, 195, 181, 100, -201, 197, 185, 100, -202, 198, 186, 100, -202, 198, 186, 100, -204, 200, 188, 100, -205, 201, 189, 100, -205, 201, 189, 100, -206, 202, 190, 100, -207, 203, 194, 100, -208, 204, 195, 100, -208, 203, 196, 100, -207, 204, 196, 100, -206, 206, 198, 100, -206, 206, 198, 100, -207, 207, 199, 100, -207, 207, 199, 100, -208, 208, 200, 100, -209, 209, 203, 100, -210, 209, 204, 100, -210, 209, 204, 100, -211, 210, 207, 100, -211, 210, 206, 100, -213, 212, 207, 100, -214, 213, 210, 100, -215, 214, 213, 100, -216, 214, 215, 100, -215, 215, 215, 100, -215, 215, 215, 100, -215, 215, 218, 100, -217, 217, 219, 100, -217, 217, 219, 100, -217, 217, 219, 100, -217, 217, 219, 100, -218, 218, 220, 100, -218, 219, 221, 100, -216, 220, 221, 100, -215, 222, 221, 100, -216, 221, 224, 100, -216, 221, 225, 100, -217, 222, 225, 100, -217, 222, 226, 100, -218, 223, 227, 100, -219, 224, 227, 100, -220, 225, 229, 100, -220, 225, 229, 100, -221, 224, 231, 100, -220, 224, 233, 100, -221, 225, 234, 100, -221, 225, 234, 100, -221, 225, 234, 100, -221, 224, 233, 100, -220, 225, 233, 100, -224, 228, 237, 100, -226, 229, 240, 100, -224, 227, 237, 100, -218, 217, 222, 100, -207, 202, 201, 100, -198, 190, 188, 100, -197, 188, 186, 100, -196, 187, 185, 100, -198, 190, 188, 100, -201, 191, 192, 100, -193, 180, 179, 100, -181, 161, 153, 100, -166, 140, 125, 100, -156, 126, 107, 100, -158, 122, 105, 100, -158, 124, 109, 100, -154, 121, 104, 100, -152, 119, 101, 100, -150, 115, 100, 100, -151, 111, 98, 100, -150, 111, 98, 100, -152, 109, 103, 100, -152, 109, 102, 100, -146, 103, 97, 100, -156, 119, 119, 100, -158, 118, 118, 100, -146, 103, 100, 100, -145, 103, 96, 100, -154, 111, 99, 100, -152, 110, 95, 100, -165, 123, 104, 100, -190, 148, 125, 100, -196, 156, 130, 100, -195, 156, 128, 100, -196, 157, 128, 100, -197, 158, 128, 100, -198, 159, 128, 100, -199, 160, 129, 100, -200, 163, 133, 100, -200, 164, 132, 100, -200, 164, 132, 100, -200, 164, 132, 100, -200, 164, 132, 100, -203, 164, 133, 100, -200, 161, 130, 100, -196, 157, 126, 100, -192, 153, 122, 100, -187, 148, 118, 100, -167, 127, 101, 100, -157, 116, 97, 100, -153, 111, 97, 100, -159, 119, 107, 100, -158, 119, 107, 100, -165, 124, 114, 100, -170, 132, 117, 100, -175, 137, 120, 100, -180, 142, 121, 100, -184, 146, 120, 100, -188, 150, 117, 100, -189, 152, 116, 100, -190, 151, 118, 100, -191, 153, 116, 100, -192, 153, 115, 100, -200, 192, 179, 100, -200, 192, 179, 100, -200, 193, 180, 100, -199, 195, 180, 100, -198, 195, 180, 100, -198, 195, 180, 100, -201, 197, 185, 100, -202, 198, 186, 100, -202, 198, 186, 100, -204, 200, 188, 100, -204, 200, 188, 100, -205, 201, 189, 100, -206, 202, 190, 100, -206, 202, 193, 100, -207, 204, 194, 100, -208, 204, 195, 100, -207, 204, 195, 100, -205, 205, 197, 100, -206, 206, 198, 100, -206, 206, 198, 100, -207, 207, 199, 100, -207, 207, 200, 100, -209, 208, 203, 100, -210, 209, 204, 100, -210, 209, 204, 100, -211, 210, 205, 100, -211, 211, 206, 100, -213, 212, 207, 100, -214, 213, 208, 100, -215, 214, 213, 100, -215, 214, 215, 100, -215, 215, 215, 100, -215, 215, 216, 100, -215, 215, 217, 100, -216, 216, 218, 100, -217, 217, 219, 100, -217, 217, 219, 100, -217, 217, 219, 100, -217, 218, 220, 100, -216, 220, 221, 100, -215, 221, 221, 100, -216, 222, 221, 100, -216, 221, 224, 100, -215, 220, 225, 100, -216, 221, 225, 100, -217, 222, 226, 100, -217, 222, 226, 100, -218, 223, 227, 100, -219, 224, 228, 100, -220, 225, 230, 100, -220, 225, 232, 100, -220, 224, 233, 100, -220, 225, 232, 100, -222, 224, 232, 100, -222, 225, 233, 100, -225, 228, 236, 100, -222, 223, 231, 100, -216, 212, 213, 100, -210, 197, 191, 100, -199, 179, 165, 100, -183, 157, 137, 100, -173, 143, 119, 100, -170, 139, 116, 100, -170, 139, 117, 100, -168, 140, 118, 100, -165, 135, 114, 100, -167, 135, 116, 100, -166, 135, 117, 100, -166, 135, 116, 100, -166, 136, 117, 100, -167, 138, 120, 100, -166, 134, 117, 100, -162, 130, 112, 100, -162, 128, 111, 100, -161, 126, 109, 100, -160, 121, 105, 100, -157, 118, 103, 100, -155, 116, 101, 100, -156, 114, 105, 100, -158, 115, 108, 100, -148, 105, 91, 100, -152, 109, 99, 100, -149, 106, 97, 100, -148, 104, 98, 100, -161, 118, 110, 100, -161, 118, 108, 100, -169, 128, 112, 100, -190, 149, 130, 100, -198, 157, 134, 100, -196, 156, 131, 100, -195, 155, 127, 100, -196, 157, 128, 100, -197, 158, 130, 100, -199, 160, 131, 100, -200, 161, 130, 100, -201, 164, 135, 100, -203, 166, 136, 100, -202, 166, 134, 100, -202, 166, 136, 100, -203, 166, 135, 100, -201, 162, 131, 100, -199, 160, 129, 100, -196, 157, 126, 100, -194, 155, 125, 100, -188, 149, 119, 100, -172, 132, 106, 100, -145, 103, 88, 100, -144, 101, 94, 100, -146, 103, 96, 100, -148, 107, 100, 100, -158, 118, 107, 100, -165, 125, 110, 100, -172, 133, 115, 100, -177, 140, 112, 100, -182, 144, 111, 100, -185, 146, 112, 100, -187, 148, 111, 100, -186, 147, 111, 100, -185, 146, 109, 100, -185, 145, 108, 100, -199, 192, 179, 100, -199, 193, 179, 100, -200, 194, 180, 100, -199, 194, 180, 100, -197, 194, 180, 100, -198, 194, 182, 100, -201, 197, 184, 100, -202, 197, 185, 100, -202, 198, 186, 100, -203, 199, 187, 100, -204, 200, 188, 100, -205, 201, 189, 100, -205, 201, 190, 100, -206, 202, 193, 100, -207, 203, 194, 100, -208, 204, 195, 100, -207, 204, 196, 100, -205, 205, 197, 100, -206, 206, 198, 100, -206, 206, 198, 100, -206, 206, 198, 100, -208, 207, 200, 100, -209, 208, 203, 100, -209, 208, 203, 100, -209, 208, 203, 100, -210, 209, 204, 100, -212, 211, 206, 100, -213, 212, 207, 100, -214, 213, 209, 100, -215, 213, 213, 100, -215, 214, 215, 100, -216, 216, 216, 100, -216, 216, 217, 100, -216, 216, 216, 100, -217, 217, 219, 100, -217, 217, 219, 100, -218, 218, 220, 100, -218, 217, 220, 100, -217, 218, 220, 100, -215, 221, 221, 100, -215, 221, 221, 100, -216, 222, 221, 100, -215, 220, 223, 100, -216, 221, 225, 100, -216, 221, 225, 100, -217, 222, 226, 100, -216, 221, 225, 100, -217, 222, 227, 100, -219, 223, 227, 100, -219, 224, 229, 100, -220, 224, 231, 100, -220, 225, 231, 100, -221, 225, 230, 100, -224, 225, 231, 100, -222, 223, 229, 100, -207, 195, 188, 100, -197, 174, 157, 100, -196, 166, 140, 100, -195, 162, 131, 100, -193, 159, 127, 100, -186, 154, 127, 100, -182, 150, 127, 100, -182, 150, 130, 100, -182, 151, 130, 100, -177, 150, 129, 100, -173, 144, 124, 100, -171, 143, 122, 100, -172, 143, 125, 100, -171, 144, 124, 100, -169, 141, 122, 100, -167, 137, 119, 100, -167, 134, 117, 100, -165, 132, 116, 100, -164, 130, 117, 100, -165, 129, 117, 100, -167, 127, 116, 100, -166, 126, 115, 100, -164, 124, 114, 100, -163, 121, 112, 100, -164, 121, 111, 100, -160, 117, 102, 100, -153, 110, 94, 100, -154, 111, 98, 100, -163, 120, 111, 100, -164, 123, 113, 100, -168, 128, 119, 100, -188, 148, 130, 100, -197, 157, 133, 100, -196, 156, 129, 100, -196, 157, 128, 100, -197, 158, 129, 100, -199, 160, 131, 100, -199, 160, 131, 100, -199, 160, 131, 100, -202, 163, 134, 100, -202, 165, 136, 100, -203, 167, 136, 100, -203, 167, 136, 100, -202, 165, 136, 100, -204, 167, 136, 100, -204, 164, 134, 100, -203, 164, 134, 100, -200, 161, 131, 100, -197, 158, 129, 100, -190, 151, 122, 100, -183, 142, 115, 100, -156, 112, 95, 100, -125, 82, 75, 100, -133, 90, 83, 100, -140, 98, 92, 100, -148, 107, 99, 100, -160, 121, 104, 100, -170, 132, 105, 100, -177, 139, 107, 100, -179, 140, 107, 100, -181, 140, 107, 100, -184, 141, 106, 100, -185, 141, 104, 100, -184, 141, 105, 100, -182, 142, 106, 100, -198, 192, 178, 100, -198, 194, 179, 100, -199, 193, 179, 100, -198, 194, 179, 100, -197, 193, 181, 100, -198, 194, 182, 100, -200, 196, 184, 100, -201, 197, 185, 100, -201, 197, 185, 100, -203, 199, 187, 100, -203, 199, 187, 100, -204, 200, 188, 100, -205, 201, 190, 100, -206, 202, 193, 100, -207, 203, 194, 100, -207, 203, 194, 100, -207, 203, 196, 100, -205, 205, 197, 100, -205, 205, 197, 100, -205, 205, 197, 100, -205, 205, 197, 100, -207, 206, 200, 100, -208, 207, 203, 100, -208, 207, 202, 100, -209, 208, 203, 100, -209, 208, 203, 100, -210, 210, 204, 100, -211, 211, 206, 100, -213, 212, 210, 100, -215, 214, 214, 100, -215, 214, 215, 100, -215, 215, 215, 100, -215, 215, 215, 100, -215, 215, 216, 100, -216, 216, 218, 100, -217, 217, 219, 100, -217, 218, 219, 100, -217, 217, 219, 100, -216, 218, 219, 100, -214, 220, 220, 100, -215, 221, 221, 100, -215, 221, 222, 100, -215, 220, 224, 100, -215, 220, 224, 100, -216, 221, 225, 100, -216, 221, 225, 100, -215, 220, 224, 100, -219, 222, 226, 100, -219, 222, 227, 100, -219, 224, 228, 100, -219, 224, 230, 100, -220, 225, 229, 100, -222, 224, 229, 100, -222, 222, 226, 100, -191, 174, 158, 100, -185, 153, 122, 100, -193, 161, 131, 100, -196, 164, 136, 100, -196, 165, 137, 100, -195, 164, 138, 100, -188, 160, 134, 100, -186, 157, 133, 100, -189, 157, 135, 100, -189, 157, 137, 100, -183, 154, 131, 100, -178, 147, 123, 100, -174, 143, 122, 100, -172, 142, 122, 100, -171, 141, 121, 100, -169, 139, 120, 100, -170, 137, 120, 100, -169, 136, 119, 100, -168, 134, 121, 100, -167, 133, 121, 100, -168, 132, 121, 100, -168, 127, 118, 100, -168, 128, 118, 100, -169, 130, 118, 100, -166, 127, 112, 100, -166, 125, 110, 100, -168, 127, 112, 100, -165, 124, 109, 100, -167, 126, 113, 100, -167, 127, 114, 100, -170, 131, 115, 100, -186, 149, 127, 100, -193, 155, 131, 100, -195, 156, 129, 100, -198, 158, 129, 100, -199, 159, 130, 100, -199, 160, 131, 100, -200, 160, 131, 100, -200, 160, 132, 100, -201, 164, 135, 100, -199, 162, 133, 100, -200, 163, 134, 100, -203, 166, 137, 100, -204, 167, 138, 100, -205, 168, 139, 100, -204, 168, 139, 100, -205, 168, 139, 100, -204, 166, 137, 100, -205, 165, 136, 100, -200, 162, 133, 100, -194, 154, 126, 100, -184, 143, 114, 100, -174, 128, 106, 100, -125, 81, 73, 100, -119, 75, 71, 100, -133, 90, 84, 100, -145, 102, 93, 100, -161, 121, 98, 100, -171, 132, 101, 100, -174, 135, 105, 100, -174, 134, 103, 100, -177, 134, 103, 100, -180, 135, 102, 100, -182, 138, 100, 100, -183, 139, 104, 100, -183, 141, 107, 100, -197, 192, 178, 100, -197, 193, 179, 100, -199, 193, 179, 100, -198, 193, 179, 100, -197, 193, 181, 100, -198, 194, 182, 100, -199, 195, 183, 100, -201, 197, 185, 100, -201, 197, 185, 100, -202, 198, 186, 100, -202, 198, 186, 100, -204, 200, 189, 100, -205, 201, 191, 100, -206, 202, 193, 100, -206, 202, 193, 100, -207, 203, 194, 100, -206, 204, 195, 100, -205, 205, 197, 100, -205, 205, 197, 100, -206, 206, 198, 100, -206, 205, 198, 100, -207, 206, 201, 100, -208, 207, 202, 100, -209, 208, 203, 100, -209, 208, 203, 100, -208, 208, 203, 100, -209, 210, 204, 100, -210, 210, 207, 100, -212, 211, 211, 100, -213, 213, 213, 100, -213, 213, 213, 100, -215, 215, 215, 100, -214, 214, 214, 100, -214, 214, 215, 100, -216, 216, 217, 100, -217, 217, 219, 100, -217, 217, 219, 100, -216, 217, 219, 100, -215, 218, 219, 100, -214, 220, 220, 100, -214, 220, 220, 100, -215, 220, 223, 100, -215, 219, 224, 100, -215, 220, 224, 100, -216, 221, 225, 100, -216, 221, 225, 100, -217, 221, 226, 100, -218, 222, 226, 100, -218, 223, 227, 100, -218, 223, 227, 100, -219, 224, 228, 100, -218, 223, 227, 100, -226, 227, 233, 100, -193, 179, 170, 100, -179, 146, 118, 100, -189, 158, 132, 100, -191, 160, 136, 100, -192, 160, 135, 100, -193, 161, 135, 100, -192, 160, 135, 100, -192, 159, 136, 100, -192, 159, 135, 100, -193, 161, 136, 100, -193, 161, 138, 100, -188, 156, 132, 100, -181, 149, 125, 100, -177, 145, 124, 100, -175, 142, 123, 100, -173, 140, 121, 100, -171, 138, 117, 100, -170, 136, 118, 100, -169, 136, 118, 100, -170, 136, 120, 100, -171, 134, 119, 100, -171, 132, 118, 100, -172, 133, 119, 100, -172, 133, 119, 100, -172, 133, 117, 100, -171, 132, 117, 100, -169, 130, 115, 100, -170, 131, 116, 100, -167, 128, 112, 100, -167, 128, 112, 100, -175, 137, 118, 100, -189, 151, 129, 100, -193, 156, 129, 100, -194, 157, 131, 100, -197, 160, 134, 100, -200, 162, 135, 100, -198, 161, 133, 100, -199, 161, 132, 100, -199, 161, 132, 100, -199, 162, 133, 100, -202, 165, 136, 100, -201, 164, 135, 100, -202, 165, 136, 100, -204, 167, 138, 100, -205, 168, 139, 100, -206, 169, 140, 100, -207, 170, 141, 100, -207, 170, 141, 100, -204, 168, 139, 100, -205, 167, 138, 100, -203, 164, 135, 100, -197, 158, 129, 100, -185, 144, 116, 100, -175, 129, 102, 100, -132, 90, 76, 100, -101, 61, 57, 100, -128, 85, 76, 100, -146, 104, 86, 100, -161, 121, 94, 100, -167, 128, 99, 100, -167, 127, 99, 100, -170, 126, 97, 100, -172, 126, 96, 100, -174, 128, 97, 100, -177, 132, 99, 100, -181, 136, 105, 100, -182, 140, 108, 100, -195, 192, 177, 100, -196, 193, 178, 100, -196, 192, 177, 100, -196, 193, 179, 100, -196, 192, 180, 100, -197, 193, 181, 100, -199, 195, 183, 100, -200, 196, 184, 100, -201, 197, 185, 100, -202, 198, 186, 100, -203, 199, 187, 100, -204, 200, 189, 100, -205, 201, 192, 100, -205, 201, 192, 100, -206, 202, 193, 100, -206, 203, 194, 100, -204, 204, 194, 100, -204, 204, 196, 100, -205, 205, 197, 100, -205, 205, 197, 100, -205, 204, 198, 100, -206, 205, 200, 100, -208, 207, 202, 100, -208, 207, 202, 100, -208, 207, 202, 100, -208, 207, 202, 100, -209, 209, 204, 100, -211, 210, 208, 100, -211, 211, 211, 100, -213, 213, 213, 100, -213, 213, 213, 100, -214, 214, 214, 100, -214, 214, 215, 100, -214, 214, 216, 100, -215, 215, 217, 100, -216, 216, 218, 100, -215, 216, 218, 100, -215, 218, 219, 100, -213, 219, 219, 100, -213, 219, 219, 100, -214, 220, 220, 100, -215, 221, 221, 100, -215, 220, 223, 100, -216, 221, 225, 100, -216, 221, 225, 100, -216, 221, 225, 100, -217, 222, 226, 100, -217, 222, 226, 100, -218, 223, 227, 100, -218, 223, 227, 100, -218, 223, 227, 100, -221, 226, 231, 100, -210, 205, 206, 100, -173, 143, 121, 100, -183, 151, 126, 100, -187, 155, 134, 100, -188, 156, 133, 100, -188, 156, 131, 100, -190, 158, 134, 100, -192, 160, 135, 100, -193, 162, 136, 100, -196, 164, 139, 100, -194, 162, 136, 100, -192, 160, 135, 100, -187, 155, 130, 100, -181, 149, 127, 100, -179, 147, 127, 100, -177, 144, 124, 100, -173, 141, 118, 100, -172, 138, 115, 100, -173, 137, 119, 100, -172, 137, 119, 100, -172, 136, 118, 100, -173, 134, 116, 100, -172, 133, 115, 100, -172, 133, 116, 100, -171, 132, 116, 100, -171, 132, 116, 100, -173, 134, 117, 100, -173, 134, 118, 100, -171, 132, 115, 100, -170, 130, 113, 100, -177, 138, 117, 100, -192, 154, 131, 100, -195, 157, 133, 100, -197, 160, 136, 100, -200, 163, 137, 100, -202, 165, 139, 100, -200, 163, 137, 100, -201, 164, 138, 100, -202, 165, 137, 100, -201, 165, 136, 100, -202, 165, 137, 100, -205, 168, 139, 100, -204, 167, 138, 100, -205, 168, 139, 100, -206, 169, 141, 100, -206, 169, 140, 100, -207, 170, 142, 100, -208, 171, 145, 100, -208, 171, 143, 100, -209, 172, 145, 100, -204, 168, 141, 100, -202, 163, 136, 100, -196, 157, 128, 100, -184, 144, 116, 100, -174, 128, 101, 100, -142, 97, 80, 100, -87, 48, 45, 100, -120, 76, 65, 100, -147, 102, 81, 100, -156, 114, 91, 100, -157, 116, 89, 100, -162, 117, 91, 100, -164, 119, 89, 100, -166, 119, 89, 100, -169, 121, 92, 100, -172, 127, 96, 100, -177, 133, 104, 100, -177, 137, 107, 100, -195, 192, 177, 100, -195, 192, 177, 100, -195, 192, 177, 100, -196, 192, 179, 100, -196, 192, 180, 100, -197, 193, 181, 100, -199, 195, 183, 100, -199, 195, 183, 100, -200, 196, 184, 100, -201, 197, 185, 100, -202, 198, 186, 100, -203, 199, 187, 100, -204, 200, 189, 100, -205, 201, 192, 100, -206, 202, 193, 100, -206, 202, 193, 100, -204, 204, 194, 100, -204, 204, 196, 100, -205, 205, 197, 100, -205, 205, 197, 100, -204, 203, 198, 100, -205, 204, 199, 100, -206, 205, 200, 100, -207, 206, 201, 100, -207, 207, 203, 100, -207, 208, 202, 100, -209, 209, 205, 100, -210, 210, 208, 100, -211, 211, 210, 100, -212, 212, 212, 100, -213, 213, 213, 100, -214, 214, 216, 100, -214, 214, 216, 100, -214, 214, 216, 100, -214, 215, 217, 100, -215, 215, 217, 100, -214, 216, 218, 100, -213, 219, 219, 100, -213, 219, 219, 100, -213, 219, 219, 100, -214, 220, 220, 100, -214, 220, 220, 100, -214, 220, 223, 100, -215, 220, 224, 100, -216, 221, 225, 100, -216, 221, 225, 100, -216, 221, 225, 100, -217, 222, 226, 100, -217, 222, 226, 100, -217, 222, 227, 100, -217, 221, 226, 100, -224, 227, 233, 100, -185, 169, 156, 100, -172, 141, 113, 100, -183, 155, 129, 100, -184, 155, 131, 100, -187, 155, 130, 100, -188, 156, 131, 100, -190, 158, 135, 100, -191, 159, 134, 100, -193, 161, 136, 100, -193, 162, 135, 100, -193, 162, 134, 100, -194, 162, 136, 100, -192, 160, 134, 100, -188, 156, 131, 100, -184, 152, 130, 100, -180, 148, 124, 100, -178, 145, 121, 100, -176, 142, 118, 100, -174, 139, 118, 100, -177, 139, 118, 100, -178, 139, 120, 100, -178, 140, 120, 100, -177, 139, 120, 100, -176, 138, 119, 100, -174, 135, 118, 100, -173, 134, 117, 100, -172, 133, 116, 100, -173, 134, 116, 100, -173, 134, 117, 100, -179, 141, 124, 100, -193, 155, 136, 100, -197, 159, 136, 100, -199, 161, 138, 100, -201, 163, 140, 100, -200, 162, 139, 100, -200, 163, 137, 100, -201, 164, 138, 100, -202, 165, 139, 100, -204, 166, 140, 100, -203, 166, 138, 100, -202, 165, 137, 100, -204, 167, 139, 100, -205, 168, 140, 100, -205, 168, 142, 100, -206, 169, 143, 100, -208, 171, 145, 100, -207, 170, 144, 100, -207, 170, 144, 100, -209, 172, 146, 100, -208, 171, 145, 100, -205, 168, 142, 100, -202, 165, 139, 100, -197, 158, 131, 100, -187, 146, 118, 100, -173, 126, 100, 100, -146, 100, 82, 100, -83, 46, 43, 100, -107, 65, 55, 100, -140, 93, 75, 100, -147, 101, 82, 100, -153, 106, 82, 100, -155, 108, 82, 100, -157, 111, 83, 100, -159, 113, 85, 100, -164, 117, 88, 100, -170, 123, 95, 100, -172, 127, 101, 100, -171, 130, 102, 100, -195, 192, 177, 100, -196, 191, 177, 100, -195, 192, 177, 100, -195, 191, 179, 100, -195, 191, 179, 100, -197, 193, 181, 100, -199, 195, 183, 100, -199, 194, 182, 100, -201, 197, 185, 100, -201, 197, 185, 100, -202, 198, 186, 100, -203, 199, 188, 100, -204, 200, 189, 100, -205, 201, 192, 100, -205, 201, 192, 100, -206, 202, 193, 100, -206, 203, 195, 100, -204, 205, 197, 100, -204, 204, 196, 100, -205, 205, 197, 100, -204, 204, 197, 100, -206, 205, 200, 100, -206, 205, 200, 100, -207, 206, 201, 100, -207, 206, 201, 100, -207, 208, 202, 100, -208, 209, 204, 100, -210, 210, 209, 100, -211, 211, 209, 100, -212, 212, 212, 100, -212, 212, 212, 100, -213, 213, 213, 100, -213, 213, 213, 100, -212, 214, 215, 100, -214, 215, 217, 100, -215, 215, 218, 100, -213, 217, 218, 100, -213, 219, 219, 100, -213, 219, 219, 100, -213, 219, 219, 100, -213, 220, 219, 100, -213, 219, 221, 100, -214, 219, 223, 100, -215, 220, 224, 100, -216, 221, 225, 100, -216, 221, 225, 100, -216, 221, 225, 100, -217, 222, 226, 100, -217, 222, 226, 100, -216, 221, 226, 100, -219, 225, 229, 100, -210, 210, 211, 100, -166, 143, 122, 100, -177, 149, 123, 100, -181, 155, 128, 100, -184, 156, 129, 100, -187, 155, 131, 100, -188, 156, 131, 100, -189, 157, 132, 100, -190, 157, 132, 100, -192, 159, 132, 100, -192, 162, 134, 100, -197, 166, 138, 100, -199, 168, 140, 100, -199, 168, 139, 100, -197, 166, 139, 100, -195, 163, 137, 100, -194, 161, 135, 100, -195, 159, 134, 100, -191, 156, 131, 100, -187, 152, 127, 100, -187, 150, 125, 100, -189, 152, 128, 100, -188, 154, 129, 100, -188, 152, 131, 100, -187, 149, 127, 100, -183, 145, 125, 100, -177, 138, 121, 100, -176, 138, 122, 100, -179, 141, 127, 100, -182, 146, 132, 100, -191, 157, 141, 100, -195, 159, 142, 100, -197, 160, 141, 100, -198, 160, 139, 100, -199, 161, 138, 100, -200, 162, 139, 100, -200, 163, 137, 100, -202, 165, 139, 100, -202, 165, 139, 100, -202, 165, 139, 100, -202, 165, 137, 100, -203, 166, 139, 100, -205, 168, 142, 100, -207, 170, 144, 100, -207, 170, 144, 100, -208, 171, 145, 100, -209, 172, 146, 100, -208, 171, 146, 100, -207, 169, 144, 100, -206, 169, 145, 100, -205, 167, 143, 100, -204, 166, 141, 100, -201, 164, 139, 100, -195, 157, 131, 100, -187, 145, 119, 100, -172, 127, 100, 100, -147, 100, 82, 100, -81, 45, 41, 100, -90, 51, 44, 100, -134, 87, 71, 100, -141, 96, 79, 100, -145, 98, 79, 100, -147, 100, 76, 100, -150, 103, 77, 100, -154, 107, 80, 100, -159, 111, 85, 100, -164, 117, 91, 100, -165, 120, 94, 100, -167, 122, 97, 100, -195, 191, 176, 100, -197, 191, 177, 100, -196, 191, 177, 100, -194, 191, 178, 100, -194, 190, 178, 100, -197, 193, 181, 100, -198, 194, 182, 100, -198, 194, 182, 100, -202, 196, 184, 100, -201, 197, 185, 100, -201, 197, 185, 100, -202, 198, 189, 100, -203, 199, 191, 100, -204, 200, 191, 100, -205, 201, 192, 100, -206, 201, 193, 100, -205, 202, 195, 100, -204, 204, 196, 100, -204, 204, 196, 100, -205, 205, 196, 100, -203, 203, 196, 100, -205, 204, 199, 100, -206, 205, 200, 100, -206, 205, 200, 100, -207, 206, 201, 100, -207, 208, 202, 100, -208, 208, 205, 100, -209, 209, 208, 100, -211, 211, 210, 100, -211, 211, 211, 100, -212, 212, 212, 100, -212, 212, 212, 100, -213, 212, 213, 100, -210, 214, 215, 100, -210, 215, 216, 100, -212, 217, 217, 100, -212, 218, 218, 100, -212, 218, 218, 100, -213, 219, 219, 100, -213, 219, 220, 100, -213, 220, 219, 100, -214, 219, 221, 100, -214, 219, 223, 100, -215, 220, 224, 100, -215, 220, 224, 100, -216, 221, 225, 100, -216, 221, 225, 100, -216, 221, 225, 100, -217, 222, 226, 100, -216, 220, 224, 100, -223, 227, 233, 100, -189, 179, 170, 100, -164, 136, 112, 100, -178, 150, 127, 100, -180, 153, 126, 100, -185, 154, 130, 100, -187, 155, 132, 100, -187, 154, 129, 100, -189, 154, 129, 100, -189, 153, 127, 100, -191, 158, 131, 100, -195, 164, 136, 100, -198, 167, 139, 100, -201, 170, 142, 100, -202, 171, 143, 100, -202, 171, 143, 100, -203, 171, 143, 100, -205, 169, 142, 100, -207, 169, 143, 100, -205, 168, 142, 100, -202, 166, 138, 100, -202, 166, 139, 100, -200, 167, 140, 100, -198, 164, 138, 100, -199, 162, 140, 100, -200, 162, 139, 100, -196, 157, 137, 100, -188, 150, 133, 100, -184, 149, 133, 100, -187, 153, 139, 100, -192, 158, 147, 100, -194, 160, 147, 100, -190, 157, 139, 100, -193, 157, 139, 100, -196, 157, 136, 100, -199, 160, 138, 100, -200, 162, 139, 100, -201, 164, 137, 100, -201, 164, 138, 100, -202, 165, 139, 100, -203, 166, 140, 100, -204, 167, 141, 100, -206, 169, 143, 100, -209, 171, 146, 100, -211, 173, 149, 100, -211, 173, 149, 100, -212, 175, 152, 100, -212, 174, 151, 100, -209, 171, 148, 100, -207, 168, 146, 100, -206, 168, 146, 100, -204, 166, 144, 100, -198, 160, 139, 100, -195, 157, 137, 100, -191, 153, 131, 100, -183, 144, 119, 100, -172, 128, 102, 100, -147, 101, 80, 100, -77, 44, 41, 100, -69, 34, 29, 100, -127, 82, 64, 100, -134, 90, 74, 100, -139, 92, 74, 100, -141, 93, 71, 100, -142, 95, 71, 100, -147, 100, 73, 100, -152, 105, 80, 100, -156, 108, 84, 100, -158, 111, 86, 100, -161, 114, 93, 100, -195, 191, 176, 100, -195, 192, 177, 100, -195, 192, 177, 100, -195, 191, 178, 100, -194, 190, 178, 100, -196, 192, 180, 100, -197, 193, 181, 100, -199, 195, 183, 100, -200, 196, 184, 100, -201, 197, 185, 100, -201, 197, 185, 100, -202, 198, 188, 100, -203, 199, 190, 100, -204, 199, 190, 100, -203, 201, 191, 100, -203, 202, 192, 100, -204, 203, 194, 100, -203, 203, 195, 100, -204, 204, 196, 100, -205, 205, 197, 100, -204, 203, 196, 100, -204, 203, 198, 100, -206, 205, 200, 100, -206, 205, 200, 100, -206, 206, 200, 100, -207, 209, 202, 100, -208, 208, 203, 100, -209, 209, 206, 100, -210, 210, 210, 100, -210, 210, 210, 100, -211, 211, 211, 100, -212, 212, 212, 100, -212, 212, 213, 100, -209, 213, 214, 100, -210, 216, 216, 100, -211, 217, 217, 100, -212, 218, 218, 100, -213, 219, 219, 100, -213, 219, 219, 100, -213, 219, 219, 100, -213, 219, 219, 100, -213, 219, 221, 100, -214, 219, 223, 100, -215, 220, 224, 100, -215, 220, 224, 100, -214, 219, 224, 100, -215, 220, 224, 100, -216, 221, 225, 100, -217, 222, 226, 100, -216, 222, 226, 100, -217, 219, 224, 100, -170, 150, 132, 100, -169, 141, 114, 100, -177, 151, 124, 100, -183, 153, 127, 100, -186, 154, 130, 100, -185, 153, 128, 100, -186, 151, 125, 100, -183, 145, 120, 100, -187, 151, 125, 100, -194, 161, 133, 100, -196, 165, 137, 100, -199, 168, 140, 100, -202, 171, 143, 100, -202, 171, 143, 100, -203, 173, 145, 100, -206, 173, 146, 100, -209, 173, 147, 100, -210, 173, 147, 100, -210, 173, 147, 100, -208, 171, 144, 100, -206, 170, 143, 100, -204, 170, 143, 100, -204, 169, 142, 100, -204, 167, 141, 100, -206, 168, 143, 100, -205, 167, 143, 100, -199, 164, 141, 100, -199, 167, 147, 100, -202, 169, 152, 100, -199, 165, 150, 100, -192, 158, 143, 100, -188, 155, 136, 100, -192, 156, 137, 100, -193, 158, 136, 100, -198, 161, 137, 100, -200, 162, 139, 100, -200, 163, 138, 100, -200, 162, 139, 100, -203, 165, 141, 100, -204, 167, 142, 100, -205, 168, 141, 100, -206, 169, 143, 100, -210, 172, 149, 100, -210, 172, 149, 100, -211, 172, 150, 100, -212, 174, 152, 100, -213, 175, 153, 100, -210, 172, 149, 100, -207, 169, 147, 100, -206, 168, 149, 100, -203, 165, 146, 100, -197, 159, 141, 100, -193, 154, 137, 100, -189, 151, 132, 100, -181, 142, 118, 100, -167, 124, 100, 100, -144, 97, 78, 100, -72, 43, 39, 100, -41, 18, 16, 100, -110, 67, 52, 100, -130, 85, 71, 100, -133, 86, 67, 100, -135, 87, 68, 100, -138, 90, 69, 100, -141, 94, 71, 100, -144, 96, 74, 100, -147, 98, 78, 100, -152, 104, 85, 100, -155, 108, 91, 100, -195, 190, 176, 100, -194, 191, 176, 100, -194, 191, 176, 100, -194, 190, 178, 100, -194, 190, 178, 100, -196, 192, 180, 100, -198, 194, 182, 100, -198, 194, 182, 100, -199, 195, 183, 100, -200, 196, 184, 100, -201, 197, 185, 100, -202, 198, 188, 100, -202, 198, 189, 100, -202, 199, 190, 100, -201, 201, 191, 100, -202, 202, 192, 100, -202, 203, 194, 100, -204, 204, 196, 100, -204, 204, 196, 100, -205, 205, 197, 100, -204, 204, 195, 100, -204, 204, 197, 100, -206, 205, 200, 100, -205, 206, 200, 100, -205, 206, 200, 100, -206, 207, 201, 100, -207, 208, 202, 100, -208, 208, 206, 100, -209, 209, 209, 100, -210, 210, 210, 100, -211, 211, 211, 100, -212, 212, 212, 100, -212, 212, 214, 100, -210, 214, 215, 100, -209, 216, 216, 100, -211, 217, 217, 100, -212, 218, 218, 100, -213, 219, 219, 100, -212, 218, 219, 100, -213, 219, 219, 100, -213, 219, 220, 100, -213, 218, 222, 100, -213, 218, 222, 100, -214, 219, 223, 100, -214, 219, 223, 100, -214, 219, 222, 100, -214, 219, 223, 100, -215, 220, 224, 100, -215, 220, 224, 100, -218, 225, 230, 100, -203, 200, 198, 100, -163, 136, 111, 100, -172, 144, 121, 100, -176, 148, 126, 100, -183, 151, 130, 100, -182, 149, 130, 100, -181, 147, 125, 100, -175, 138, 113, 100, -176, 140, 114, 100, -187, 153, 126, 100, -194, 162, 134, 100, -199, 167, 139, 100, -203, 171, 144, 100, -202, 171, 143, 100, -205, 174, 146, 100, -208, 177, 149, 100, -210, 175, 148, 100, -211, 174, 148, 100, -210, 173, 147, 100, -212, 175, 149, 100, -212, 175, 149, 100, -209, 172, 146, 100, -207, 170, 144, 100, -208, 171, 144, 100, -207, 170, 144, 100, -206, 169, 141, 100, -206, 169, 142, 100, -205, 169, 141, 100, -207, 174, 148, 100, -210, 177, 155, 100, -200, 168, 146, 100, -191, 157, 137, 100, -189, 153, 132, 100, -192, 154, 135, 100, -193, 156, 134, 100, -196, 158, 135, 100, -199, 161, 138, 100, -201, 163, 140, 100, -202, 164, 141, 100, -203, 165, 142, 100, -205, 167, 143, 100, -205, 167, 145, 100, -206, 168, 145, 100, -210, 172, 151, 100, -210, 172, 151, 100, -212, 175, 155, 100, -215, 178, 156, 100, -214, 176, 154, 100, -209, 171, 148, 100, -207, 169, 147, 100, -204, 166, 148, 100, -200, 164, 146, 100, -195, 157, 140, 100, -188, 149, 132, 100, -181, 142, 125, 100, -173, 134, 114, 100, -161, 120, 98, 100, -138, 96, 76, 100, -72, 40, 36, 100, -20, 7, 10, 100, -72, 37, 26, 100, -125, 75, 60, 100, -127, 79, 64, 100, -130, 81, 66, 100, -133, 85, 65, 100, -136, 88, 67, 100, -141, 90, 71, 100, -143, 93, 73, 100, -145, 97, 81, 100, -147, 100, 85, 100, -195, 191, 176, 100, -194, 191, 176, 100, -194, 191, 176, 100, -194, 190, 177, 100, -194, 190, 178, 100, -196, 192, 180, 100, -197, 193, 181, 100, -196, 192, 180, 100, -198, 194, 182, 100, -199, 195, 183, 100, -200, 196, 184, 100, -201, 197, 188, 100, -202, 198, 189, 100, -201, 199, 189, 100, -200, 200, 190, 100, -202, 201, 192, 100, -202, 202, 194, 100, -203, 203, 195, 100, -204, 204, 196, 100, -205, 205, 197, 100, -204, 204, 196, 100, -204, 204, 197, 100, -205, 204, 199, 100, -205, 205, 200, 100, -205, 206, 200, 100, -205, 206, 200, 100, -206, 207, 201, 100, -208, 208, 204, 100, -210, 210, 208, 100, -210, 210, 210, 100, -211, 211, 210, 100, -211, 211, 212, 100, -211, 212, 214, 100, -209, 214, 214, 100, -209, 215, 215, 100, -210, 216, 216, 100, -211, 217, 217, 100, -212, 218, 218, 100, -212, 218, 219, 100, -213, 219, 219, 100, -213, 219, 220, 100, -213, 218, 222, 100, -213, 218, 222, 100, -214, 219, 223, 100, -214, 219, 223, 100, -213, 218, 223, 100, -214, 219, 223, 100, -215, 220, 224, 100, -215, 219, 223, 100, -220, 226, 232, 100, -185, 175, 167, 100, -161, 131, 106, 100, -172, 144, 123, 100, -173, 145, 125, 100, -178, 147, 128, 100, -177, 144, 125, 100, -173, 136, 118, 100, -164, 126, 104, 100, -174, 140, 114, 100, -186, 155, 128, 100, -193, 162, 135, 100, -200, 168, 144, 100, -201, 169, 144, 100, -202, 169, 144, 100, -204, 172, 147, 100, -208, 175, 149, 100, -210, 175, 148, 100, -210, 175, 149, 100, -210, 174, 148, 100, -211, 174, 148, 100, -212, 175, 148, 100, -211, 174, 148, 100, -211, 174, 147, 100, -211, 174, 147, 100, -208, 171, 143, 100, -208, 171, 142, 100, -207, 170, 141, 100, -205, 167, 138, 100, -206, 169, 140, 100, -211, 176, 149, 100, -200, 165, 142, 100, -189, 152, 129, 100, -190, 152, 128, 100, -191, 153, 130, 100, -194, 156, 132, 100, -196, 158, 135, 100, -198, 160, 137, 100, -201, 163, 140, 100, -201, 162, 141, 100, -202, 165, 143, 100, -204, 167, 146, 100, -204, 167, 148, 100, -205, 169, 149, 100, -206, 171, 153, 100, -208, 174, 156, 100, -208, 174, 155, 100, -210, 176, 156, 100, -212, 175, 155, 100, -207, 170, 147, 100, -203, 167, 145, 100, -202, 164, 145, 100, -196, 160, 141, 100, -192, 155, 138, 100, -185, 146, 130, 100, -176, 137, 121, 100, -165, 126, 110, 100, -154, 114, 98, 100, -129, 90, 74, 100, -63, 35, 32, 100, -20, 8, 14, 100, -21, 7, 6, 100, -96, 51, 37, 100, -120, 70, 53, 100, -122, 73, 57, 100, -128, 80, 60, 100, -132, 82, 62, 100, -136, 84, 66, 100, -137, 88, 70, 100, -141, 93, 78, 100, -143, 95, 79, 100, -194, 191, 176, 100, -194, 190, 177, 100, -194, 190, 177, 100, -194, 190, 178, 100, -195, 190, 178, 100, -196, 191, 179, 100, -196, 192, 180, 100, -196, 192, 180, 100, -198, 194, 182, 100, -199, 195, 183, 100, -200, 196, 184, 100, -200, 196, 186, 100, -201, 197, 188, 100, -200, 199, 190, 100, -200, 200, 190, 100, -202, 201, 193, 100, -202, 202, 194, 100, -203, 203, 195, 100, -203, 203, 195, 100, -204, 204, 196, 100, -204, 204, 196, 100, -204, 204, 197, 100, -204, 203, 199, 100, -205, 203, 198, 100, -204, 204, 199, 100, -205, 206, 200, 100, -206, 207, 201, 100, -207, 208, 204, 100, -209, 209, 208, 100, -209, 209, 209, 100, -210, 210, 210, 100, -211, 211, 211, 100, -211, 212, 212, 100, -209, 214, 213, 100, -209, 215, 214, 100, -209, 215, 215, 100, -210, 216, 216, 100, -210, 216, 216, 100, -211, 217, 217, 100, -212, 218, 218, 100, -211, 217, 218, 100, -212, 218, 221, 100, -213, 218, 222, 100, -213, 218, 222, 100, -213, 218, 223, 100, -213, 218, 224, 100, -214, 219, 223, 100, -214, 219, 223, 100, -214, 219, 223, 100, -219, 223, 229, 100, -171, 154, 142, 100, -159, 130, 108, 100, -168, 141, 121, 100, -170, 142, 124, 100, -172, 143, 127, 100, -170, 136, 122, 100, -157, 120, 106, 100, -154, 119, 99, 100, -175, 143, 120, 100, -187, 155, 132, 100, -192, 160, 138, 100, -198, 165, 146, 100, -198, 166, 144, 100, -200, 168, 144, 100, -205, 173, 150, 100, -207, 175, 151, 100, -209, 176, 154, 100, -209, 177, 154, 100, -209, 176, 150, 100, -212, 175, 151, 100, -214, 176, 152, 100, -213, 176, 150, 100, -212, 175, 150, 100, -213, 175, 151, 100, -210, 173, 147, 100, -210, 173, 145, 100, -208, 171, 143, 100, -204, 167, 138, 100, -203, 167, 137, 100, -207, 170, 143, 100, -198, 161, 137, 100, -189, 151, 128, 100, -188, 151, 129, 100, -189, 151, 128, 100, -193, 155, 133, 100, -198, 160, 139, 100, -199, 161, 140, 100, -201, 162, 143, 100, -200, 162, 144, 100, -200, 165, 146, 100, -201, 168, 149, 100, -202, 168, 149, 100, -202, 169, 151, 100, -202, 169, 152, 100, -203, 171, 153, 100, -203, 170, 152, 100, -205, 172, 156, 100, -204, 167, 150, 100, -187, 145, 124, 100, -178, 134, 110, 100, -179, 136, 112, 100, -192, 151, 130, 100, -190, 151, 133, 100, -180, 141, 125, 100, -171, 132, 117, 100, -157, 118, 105, 100, -144, 104, 92, 100, -118, 81, 68, 100, -54, 31, 31, 100, -24, 14, 18, 100, -4, 0, 4, 100, -33, 13, 9, 100, -95, 51, 38, 100, -113, 64, 46, 100, -120, 69, 51, 100, -125, 75, 58, 100, -130, 78, 59, 100, -133, 81, 64, 100, -136, 85, 68, 100, -138, 90, 70, 100, -193, 190, 176, 100, -193, 189, 178, 100, -193, 190, 177, 100, -194, 190, 178, 100, -194, 190, 178, 100, -195, 191, 179, 100, -195, 191, 179, 100, -195, 191, 179, 100, -197, 193, 181, 100, -198, 194, 182, 100, -199, 195, 183, 100, -200, 196, 184, 100, -201, 198, 188, 100, -199, 200, 187, 100, -200, 200, 189, 100, -200, 200, 192, 100, -202, 202, 194, 100, -202, 202, 194, 100, -203, 203, 195, 100, -204, 204, 196, 100, -204, 204, 196, 100, -204, 204, 197, 100, -205, 204, 199, 100, -205, 204, 199, 100, -205, 205, 199, 100, -205, 206, 200, 100, -205, 206, 200, 100, -206, 206, 204, 100, -207, 207, 207, 100, -208, 208, 208, 100, -209, 209, 209, 100, -211, 210, 211, 100, -211, 211, 211, 100, -209, 213, 211, 100, -208, 214, 213, 100, -209, 215, 215, 100, -209, 215, 215, 100, -211, 217, 217, 100, -211, 217, 217, 100, -211, 217, 217, 100, -211, 217, 218, 100, -212, 217, 221, 100, -213, 218, 222, 100, -213, 218, 222, 100, -213, 218, 222, 100, -213, 218, 222, 100, -214, 219, 223, 100, -215, 220, 224, 100, -216, 221, 225, 100, -213, 216, 220, 100, -158, 139, 125, 100, -156, 128, 109, 100, -163, 135, 122, 100, -164, 136, 124, 100, -166, 136, 126, 100, -159, 124, 115, 100, -140, 102, 93, 100, -145, 112, 94, 100, -177, 145, 125, 100, -185, 153, 134, 100, -189, 158, 139, 100, -192, 159, 141, 100, -194, 161, 142, 100, -200, 167, 148, 100, -205, 172, 153, 100, -207, 174, 153, 100, -208, 176, 155, 100, -208, 176, 155, 100, -209, 176, 154, 100, -212, 176, 156, 100, -213, 178, 154, 100, -213, 178, 154, 100, -213, 177, 154, 100, -213, 175, 153, 100, -212, 174, 151, 100, -209, 172, 148, 100, -209, 172, 146, 100, -207, 169, 142, 100, -203, 166, 136, 100, -206, 169, 140, 100, -202, 164, 139, 100, -188, 150, 127, 100, -187, 149, 127, 100, -191, 152, 133, 100, -193, 155, 137, 100, -196, 158, 140, 100, -199, 161, 143, 100, -199, 162, 144, 100, -198, 163, 144, 100, -197, 165, 146, 100, -198, 165, 148, 100, -200, 165, 149, 100, -200, 167, 151, 100, -201, 168, 153, 100, -201, 168, 155, 100, -199, 168, 157, 100, -199, 166, 159, 100, -186, 148, 140, 100, -169, 120, 112, 100, -168, 111, 99, 100, -163, 103, 85, 100, -161, 107, 86, 100, -178, 136, 114, 100, -176, 138, 121, 100, -163, 124, 109, 100, -150, 110, 99, 100, -134, 93, 84, 100, -106, 71, 62, 100, -47, 27, 27, 100, -23, 13, 17, 100, -10, 4, 7, 100, -6, 1, 4, 100, -36, 15, 13, 100, -93, 48, 36, 100, -109, 57, 40, 100, -117, 65, 47, 100, -124, 72, 53, 100, -128, 75, 57, 100, -132, 79, 60, 100, -135, 84, 67, 100, -193, 189, 175, 100, -193, 189, 177, 100, -192, 188, 176, 100, -193, 189, 177, 100, -193, 189, 177, 100, -194, 191, 179, 100, -194, 190, 178, 100, -194, 190, 178, 100, -197, 193, 181, 100, -198, 194, 182, 100, -199, 195, 183, 100, -200, 196, 184, 100, -200, 197, 187, 100, -199, 200, 187, 100, -200, 200, 188, 100, -201, 201, 191, 100, -201, 201, 193, 100, -203, 203, 195, 100, -203, 203, 195, 100, -204, 204, 196, 100, -204, 204, 195, 100, -204, 204, 197, 100, -205, 204, 199, 100, -204, 204, 199, 100, -204, 205, 199, 100, -205, 206, 200, 100, -205, 206, 200, 100, -206, 206, 203, 100, -207, 207, 207, 100, -209, 209, 209, 100, -210, 210, 210, 100, -210, 211, 210, 100, -210, 211, 210, 100, -208, 212, 211, 100, -208, 214, 213, 100, -208, 214, 214, 100, -208, 214, 214, 100, -209, 215, 215, 100, -210, 216, 216, 100, -211, 217, 216, 100, -211, 217, 218, 100, -211, 216, 220, 100, -212, 217, 221, 100, -213, 218, 222, 100, -213, 218, 222, 100, -213, 218, 222, 100, -213, 218, 222, 100, -214, 219, 223, 100, -216, 222, 226, 100, -207, 208, 210, 100, -149, 128, 113, 100, -154, 126, 112, 100, -158, 130, 119, 100, -159, 131, 121, 100, -159, 128, 122, 100, -148, 114, 106, 100, -122, 84, 77, 100, -143, 109, 93, 100, -174, 142, 122, 100, -178, 146, 129, 100, -185, 152, 136, 100, -187, 154, 137, 100, -192, 159, 140, 100, -197, 168, 149, 100, -202, 171, 153, 100, -206, 173, 155, 100, -208, 175, 157, 100, -208, 175, 156, 100, -209, 176, 158, 100, -210, 176, 157, 100, -212, 177, 157, 100, -211, 177, 158, 100, -211, 178, 158, 100, -211, 176, 155, 100, -209, 174, 155, 100, -208, 171, 152, 100, -207, 170, 150, 100, -205, 168, 146, 100, -202, 165, 142, 100, -205, 168, 143, 100, -196, 158, 136, 100, -185, 147, 126, 100, -186, 148, 130, 100, -190, 152, 137, 100, -193, 155, 140, 100, -193, 157, 142, 100, -194, 160, 144, 100, -194, 162, 144, 100, -195, 161, 145, 100, -195, 161, 145, 100, -195, 161, 149, 100, -197, 162, 151, 100, -198, 165, 154, 100, -198, 165, 156, 100, -197, 166, 157, 100, -195, 164, 157, 100, -193, 162, 159, 100, -177, 142, 140, 100, -152, 105, 107, 100, -150, 90, 94, 100, -155, 84, 82, 100, -144, 74, 61, 100, -147, 92, 73, 100, -169, 129, 111, 100, -158, 119, 107, 100, -141, 102, 93, 100, -122, 85, 75, 100, -96, 65, 56, 100, -42, 25, 22, 100, -23, 12, 14, 100, -13, 4, 7, 100, -12, 4, 7, 100, -10, 2, 4, 100, -40, 17, 12, 100, -87, 45, 31, 100, -104, 55, 37, 100, -114, 65, 46, 100, -121, 69, 50, 100, -124, 72, 51, 100, -130, 77, 57, 100, -193, 188, 174, 100, -192, 189, 175, 100, -192, 188, 176, 100, -192, 188, 176, 100, -193, 189, 177, 100, -194, 190, 178, 100, -194, 190, 178, 100, -195, 191, 179, 100, -197, 193, 181, 100, -198, 194, 182, 100, -199, 195, 183, 100, -199, 195, 183, 100, -199, 196, 183, 100, -199, 199, 186, 100, -199, 199, 189, 100, -200, 200, 190, 100, -201, 201, 191, 100, -202, 202, 194, 100, -203, 203, 195, 100, -204, 204, 196, 100, -204, 204, 195, 100, -204, 203, 196, 100, -204, 204, 199, 100, -204, 204, 199, 100, -204, 205, 199, 100, -204, 205, 200, 100, -205, 206, 200, 100, -207, 208, 202, 100, -208, 209, 205, 100, -209, 209, 206, 100, -209, 209, 208, 100, -209, 211, 210, 100, -206, 211, 209, 100, -205, 211, 210, 100, -206, 212, 213, 100, -207, 213, 213, 100, -209, 215, 215, 100, -209, 215, 215, 100, -209, 215, 215, 100, -210, 216, 216, 100, -211, 216, 217, 100, -211, 216, 219, 100, -211, 216, 220, 100, -212, 217, 221, 100, -213, 218, 223, 100, -213, 218, 223, 100, -213, 218, 222, 100, -213, 217, 221, 100, -216, 222, 227, 100, -201, 200, 201, 100, -143, 119, 104, 100, -153, 124, 112, 100, -154, 126, 117, 100, -155, 127, 121, 100, -153, 124, 120, 100, -138, 106, 103, 100, -110, 72, 70, 100, -134, 100, 88, 100, -164, 134, 117, 100, -168, 138, 126, 100, -178, 144, 131, 100, -184, 151, 134, 100, -192, 160, 144, 100, -196, 167, 152, 100, -197, 168, 156, 100, -202, 173, 161, 100, -203, 172, 161, 100, -205, 173, 159, 100, -206, 174, 158, 100, -206, 175, 159, 100, -207, 176, 160, 100, -209, 177, 162, 100, -208, 175, 159, 100, -207, 174, 158, 100, -204, 171, 156, 100, -200, 166, 149, 100, -198, 165, 146, 100, -194, 161, 144, 100, -193, 159, 143, 100, -198, 164, 147, 100, -187, 151, 134, 100, -178, 139, 123, 100, -179, 143, 128, 100, -183, 147, 134, 100, -187, 152, 140, 100, -188, 153, 141, 100, -187, 153, 140, 100, -189, 155, 144, 100, -190, 156, 145, 100, -192, 158, 148, 100, -193, 160, 150, 100, -193, 160, 153, 100, -193, 161, 153, 100, -190, 159, 154, 100, -190, 159, 155, 100, -188, 157, 153, 100, -185, 154, 151, 100, -176, 145, 143, 100, -155, 115, 116, 100, -127, 78, 83, 100, -115, 52, 60, 100, -111, 45, 45, 100, -118, 63, 55, 100, -151, 109, 95, 100, -152, 112, 103, 100, -129, 94, 85, 100, -112, 79, 69, 100, -89, 60, 50, 100, -46, 27, 24, 100, -29, 14, 17, 100, -20, 8, 11, 100, -16, 5, 8, 100, -19, 7, 10, 100, -21, 8, 5, 100, -48, 22, 13, 100, -81, 41, 28, 100, -92, 45, 26, 100, -110, 59, 39, 100, -116, 65, 44, 100, -120, 68, 47, 100, -191, 188, 172, 100, -191, 188, 173, 100, -191, 187, 174, 100, -191, 187, 175, 100, -192, 188, 176, 100, -194, 190, 178, 100, -194, 190, 178, 100, -194, 190, 178, 100, -196, 192, 180, 100, -197, 193, 181, 100, -198, 194, 182, 100, -199, 195, 183, 100, -200, 196, 184, 100, -202, 197, 188, 100, -199, 199, 189, 100, -200, 200, 190, 100, -200, 200, 190, 100, -201, 201, 193, 100, -202, 202, 194, 100, -203, 203, 195, 100, -203, 203, 196, 100, -204, 204, 196, 100, -204, 205, 198, 100, -203, 205, 199, 100, -204, 205, 199, 100, -204, 205, 199, 100, -205, 206, 200, 100, -206, 207, 201, 100, -207, 208, 202, 100, -207, 208, 205, 100, -208, 208, 208, 100, -208, 210, 209, 100, -205, 211, 209, 100, -206, 212, 211, 100, -206, 212, 213, 100, -207, 213, 213, 100, -208, 214, 214, 100, -209, 215, 215, 100, -209, 215, 215, 100, -209, 215, 215, 100, -210, 216, 216, 100, -210, 216, 218, 100, -211, 216, 220, 100, -212, 217, 221, 100, -212, 217, 222, 100, -212, 217, 222, 100, -213, 218, 222, 100, -212, 217, 221, 100, -217, 223, 229, 100, -195, 194, 193, 100, -138, 113, 99, 100, -149, 122, 108, 100, -153, 125, 116, 100, -155, 127, 121, 100, -152, 123, 118, 100, -138, 106, 104, 100, -113, 78, 76, 100, -128, 93, 86, 100, -152, 122, 110, 100, -161, 131, 120, 100, -161, 125, 109, 100, -168, 132, 116, 100, -187, 157, 146, 100, -188, 158, 147, 100, -190, 160, 150, 100, -196, 166, 156, 100, -198, 168, 158, 100, -199, 170, 159, 100, -201, 172, 160, 100, -201, 172, 161, 100, -201, 172, 161, 100, -203, 173, 161, 100, -203, 169, 158, 100, -200, 166, 156, 100, -196, 162, 150, 100, -191, 157, 143, 100, -187, 154, 137, 100, -184, 150, 137, 100, -190, 156, 145, 100, -195, 162, 150, 100, -184, 148, 137, 100, -171, 132, 120, 100, -173, 137, 125, 100, -177, 143, 131, 100, -181, 147, 136, 100, -182, 149, 137, 100, -184, 150, 140, 100, -187, 153, 143, 100, -187, 152, 143, 100, -187, 155, 147, 100, -186, 156, 149, 100, -186, 155, 152, 100, -186, 156, 152, 100, -186, 155, 152, 100, -183, 152, 149, 100, -182, 151, 148, 100, -179, 148, 145, 100, -172, 141, 139, 100, -162, 131, 130, 100, -143, 104, 108, 100, -123, 78, 84, 100, -108, 62, 64, 100, -117, 73, 74, 100, -138, 98, 95, 100, -134, 97, 92, 100, -116, 81, 75, 100, -101, 70, 60, 100, -82, 54, 47, 100, -51, 33, 27, 100, -37, 23, 22, 100, -31, 17, 18, 100, -26, 13, 13, 100, -33, 17, 15, 100, -44, 24, 19, 100, -56, 30, 18, 100, -124, 97, 76, 100, -140, 109, 87, 100, -93, 51, 29, 100, -102, 55, 33, 100, -111, 60, 40, 100, -189, 186, 172, 100, -190, 186, 172, 100, -190, 186, 173, 100, -190, 186, 174, 100, -192, 188, 176, 100, -193, 189, 177, 100, -194, 190, 178, 100, -194, 190, 178, 100, -195, 191, 179, 100, -196, 192, 180, 100, -198, 194, 182, 100, -198, 194, 182, 100, -199, 195, 184, 100, -199, 196, 187, 100, -198, 198, 188, 100, -200, 200, 190, 100, -200, 200, 192, 100, -201, 201, 193, 100, -202, 202, 194, 100, -202, 202, 194, 100, -203, 203, 195, 100, -204, 204, 196, 100, -203, 203, 197, 100, -203, 204, 198, 100, -204, 205, 199, 100, -204, 205, 199, 100, -205, 206, 200, 100, -205, 206, 200, 100, -206, 207, 201, 100, -208, 208, 204, 100, -208, 208, 208, 100, -208, 209, 209, 100, -206, 210, 209, 100, -205, 212, 210, 100, -206, 212, 212, 100, -207, 213, 213, 100, -208, 214, 214, 100, -209, 215, 215, 100, -208, 214, 214, 100, -208, 214, 214, 100, -209, 215, 215, 100, -210, 215, 218, 100, -210, 215, 219, 100, -211, 216, 220, 100, -212, 217, 221, 100, -211, 217, 220, 100, -211, 217, 221, 100, -212, 217, 220, 100, -217, 224, 228, 100, -191, 189, 188, 100, -136, 109, 95, 100, -149, 121, 107, 100, -155, 127, 116, 100, -161, 133, 124, 100, -159, 130, 124, 100, -154, 123, 119, 100, -132, 96, 95, 100, -123, 88, 82, 100, -147, 115, 104, 100, -151, 118, 105, 100, -143, 93, 83, 100, -154, 107, 103, 100, -172, 141, 138, 100, -179, 148, 143, 100, -185, 154, 148, 100, -189, 158, 152, 100, -192, 162, 155, 100, -194, 165, 158, 100, -195, 166, 160, 100, -196, 166, 161, 100, -198, 167, 161, 100, -196, 166, 156, 100, -195, 162, 153, 100, -193, 158, 149, 100, -190, 156, 145, 100, -186, 153, 138, 100, -183, 149, 132, 100, -189, 155, 141, 100, -199, 165, 153, 100, -198, 164, 152, 100, -190, 156, 144, 100, -173, 134, 124, 100, -168, 128, 118, 100, -174, 136, 126, 100, -178, 142, 131, 100, -180, 144, 134, 100, -182, 148, 138, 100, -184, 150, 141, 100, -184, 151, 146, 100, -181, 150, 146, 100, -180, 149, 146, 100, -180, 149, 146, 100, -178, 146, 144, 100, -177, 146, 143, 100, -175, 143, 140, 100, -173, 139, 137, 100, -169, 137, 134, 100, -164, 131, 128, 100, -158, 123, 121, 100, -149, 112, 114, 100, -137, 100, 103, 100, -128, 90, 93, 100, -124, 87, 89, 100, -122, 85, 86, 100, -116, 80, 78, 100, -104, 72, 65, 100, -91, 62, 51, 100, -78, 52, 41, 100, -63, 42, 37, 100, -55, 38, 38, 100, -48, 32, 32, 100, -44, 30, 27, 100, -51, 33, 30, 100, -62, 38, 29, 100, -87, 60, 37, 100, -178, 159, 129, 100, -208, 193, 168, 100, -172, 148, 125, 100, -110, 73, 54, 100, -94, 51, 32, 100, -188, 184, 173, 100, -188, 184, 172, 100, -188, 184, 172, 100, -189, 185, 173, 100, -191, 187, 175, 100, -193, 189, 177, 100, -193, 189, 177, 100, -194, 190, 178, 100, -194, 190, 178, 100, -196, 192, 180, 100, -197, 193, 181, 100, -198, 194, 182, 100, -199, 196, 183, 100, -197, 198, 186, 100, -197, 197, 188, 100, -199, 199, 189, 100, -200, 200, 191, 100, -200, 200, 192, 100, -201, 201, 193, 100, -202, 202, 194, 100, -203, 203, 195, 100, -203, 203, 195, 100, -204, 203, 197, 100, -204, 203, 198, 100, -204, 205, 199, 100, -204, 205, 199, 100, -204, 205, 199, 100, -205, 206, 200, 100, -206, 207, 201, 100, -207, 207, 203, 100, -208, 208, 206, 100, -208, 210, 208, 100, -205, 211, 209, 100, -204, 210, 208, 100, -206, 211, 210, 100, -207, 213, 212, 100, -207, 213, 214, 100, -208, 214, 214, 100, -208, 214, 214, 100, -208, 214, 213, 100, -208, 214, 215, 100, -209, 214, 218, 100, -209, 214, 218, 100, -210, 215, 219, 100, -211, 215, 220, 100, -210, 217, 221, 100, -209, 217, 220, 100, -211, 216, 220, 100, -216, 223, 228, 100, -190, 187, 185, 100, -136, 107, 91, 100, -152, 123, 109, 100, -162, 134, 120, 100, -170, 142, 128, 100, -171, 142, 131, 100, -169, 139, 130, 100, -146, 112, 111, 100, -118, 84, 79, 100, -138, 106, 93, 100, -141, 96, 88, 100, -135, 70, 73, 100, -138, 90, 93, 100, -160, 126, 124, 100, -170, 138, 134, 100, -177, 146, 143, 100, -180, 149, 146, 100, -182, 153, 149, 100, -185, 156, 152, 100, -187, 157, 153, 100, -190, 160, 157, 100, -192, 161, 158, 100, -191, 160, 155, 100, -190, 157, 150, 100, -189, 155, 145, 100, -186, 152, 141, 100, -185, 151, 135, 100, -189, 154, 137, 100, -198, 164, 150, 100, -204, 170, 159, 100, -204, 170, 157, 100, -195, 161, 148, 100, -180, 142, 131, 100, -168, 128, 117, 100, -171, 132, 118, 100, -178, 138, 125, 100, -179, 141, 132, 100, -179, 142, 135, 100, -180, 145, 140, 100, -180, 146, 143, 100, -178, 146, 144, 100, -176, 144, 142, 100, -173, 140, 138, 100, -171, 137, 135, 100, -168, 132, 131, 100, -164, 129, 127, 100, -161, 126, 124, 100, -158, 122, 120, 100, -153, 115, 114, 100, -149, 109, 110, 100, -141, 101, 105, 100, -131, 94, 96, 100, -127, 91, 94, 100, -118, 82, 83, 100, -109, 74, 72, 100, -105, 69, 68, 100, -96, 64, 59, 100, -88, 58, 48, 100, -80, 54, 44, 100, -73, 51, 47, 100, -70, 50, 50, 100, -67, 50, 50, 100, -68, 49, 47, 100, -70, 50, 44, 100, -78, 51, 38, 100, -121, 94, 70, 100, -196, 180, 154, 100, -193, 178, 153, 100, -205, 191, 165, 100, -194, 175, 151, 100, -132, 102, 82, 100, -187, 183, 171, 100, -187, 183, 170, 100, -187, 183, 171, 100, -188, 184, 172, 100, -191, 187, 175, 100, -192, 188, 176, 100, -193, 189, 177, 100, -194, 190, 178, 100, -194, 190, 178, 100, -195, 191, 179, 100, -197, 193, 182, 100, -197, 193, 183, 100, -199, 194, 184, 100, -198, 196, 187, 100, -197, 197, 187, 100, -198, 198, 188, 100, -198, 198, 189, 100, -199, 199, 191, 100, -200, 200, 192, 100, -201, 201, 193, 100, -202, 202, 194, 100, -203, 203, 195, 100, -203, 202, 196, 100, -202, 202, 197, 100, -203, 204, 198, 100, -204, 205, 199, 100, -204, 205, 199, 100, -204, 205, 199, 100, -205, 205, 201, 100, -206, 206, 204, 100, -207, 207, 205, 100, -205, 209, 207, 100, -203, 209, 207, 100, -204, 210, 208, 100, -206, 212, 210, 100, -206, 212, 210, 100, -208, 212, 212, 100, -207, 214, 214, 100, -207, 213, 213, 100, -207, 213, 213, 100, -207, 213, 213, 100, -209, 215, 216, 100, -209, 214, 218, 100, -210, 215, 219, 100, -209, 215, 219, 100, -208, 216, 220, 100, -208, 216, 219, 100, -209, 215, 218, 100, -215, 222, 227, 100, -189, 187, 184, 100, -135, 108, 88, 100, -156, 127, 107, 100, -170, 141, 122, 100, -175, 146, 130, 100, -175, 145, 133, 100, -174, 144, 134, 100, -148, 117, 115, 100, -112, 80, 83, 100, -123, 91, 83, 100, -121, 76, 67, 100, -107, 49, 52, 100, -134, 93, 92, 100, -157, 121, 119, 100, -159, 127, 124, 100, -164, 133, 131, 100, -169, 136, 133, 100, -173, 141, 138, 100, -178, 147, 144, 100, -180, 150, 146, 100, -184, 153, 150, 100, -187, 154, 152, 100, -187, 154, 152, 100, -187, 152, 145, 100, -187, 151, 141, 100, -186, 149, 138, 100, -187, 151, 135, 100, -195, 160, 143, 100, -203, 170, 152, 100, -207, 173, 160, 100, -206, 172, 158, 100, -200, 165, 147, 100, -189, 151, 135, 100, -176, 137, 121, 100, -172, 133, 116, 100, -172, 133, 119, 100, -175, 134, 127, 100, -174, 133, 127, 100, -171, 133, 129, 100, -169, 132, 130, 100, -169, 131, 130, 100, -166, 129, 128, 100, -163, 126, 124, 100, -162, 122, 121, 100, -157, 117, 116, 100, -152, 113, 111, 100, -148, 109, 107, 100, -145, 104, 104, 100, -140, 98, 99, 100, -136, 94, 97, 100, -130, 88, 91, 100, -124, 82, 84, 100, -118, 78, 77, 100, -110, 73, 72, 100, -103, 68, 67, 100, -99, 64, 59, 100, -99, 66, 58, 100, -98, 67, 56, 100, -87, 58, 53, 100, -80, 56, 50, 100, -77, 56, 54, 100, -77, 56, 56, 100, -81, 59, 57, 100, -87, 61, 53, 100, -93, 64, 43, 100, -159, 136, 111, 100, -200, 187, 163, 100, -193, 181, 158, 100, -196, 183, 161, 100, -202, 189, 166, 100, -205, 191, 167, 100, -186, 181, 169, 100, -187, 182, 169, 100, -186, 183, 170, 100, -187, 183, 171, 100, -189, 185, 173, 100, -191, 187, 175, 100, -192, 188, 176, 100, -193, 189, 177, 100, -193, 189, 177, 100, -194, 190, 178, 100, -196, 192, 182, 100, -197, 193, 185, 100, -198, 194, 184, 100, -197, 195, 184, 100, -195, 196, 186, 100, -197, 197, 187, 100, -198, 198, 188, 100, -198, 198, 190, 100, -199, 199, 191, 100, -200, 200, 192, 100, -200, 200, 192, 100, -201, 201, 193, 100, -202, 202, 196, 100, -202, 203, 197, 100, -203, 204, 197, 100, -203, 204, 199, 100, -204, 204, 199, 100, -204, 205, 199, 100, -204, 205, 200, 100, -205, 205, 203, 100, -204, 207, 204, 100, -203, 207, 206, 100, -203, 209, 207, 100, -204, 209, 207, 100, -204, 210, 208, 100, -205, 211, 209, 100, -207, 211, 211, 100, -206, 212, 212, 100, -207, 212, 212, 100, -207, 212, 212, 100, -206, 212, 212, 100, -207, 213, 213, 100, -208, 213, 216, 100, -209, 213, 218, 100, -209, 214, 218, 100, -207, 215, 218, 100, -207, 215, 218, 100, -207, 214, 217, 100, -213, 220, 226, 100, -190, 187, 186, 100, -136, 109, 88, 100, -159, 131, 105, 100, -171, 143, 122, 100, -176, 147, 132, 100, -176, 146, 136, 100, -175, 145, 135, 100, -151, 119, 118, 100, -114, 83, 90, 100, -100, 67, 68, 100, -122, 83, 74, 100, -120, 77, 74, 100, -143, 105, 101, 100, -150, 113, 108, 100, -152, 117, 113, 100, -156, 122, 119, 100, -162, 124, 121, 100, -167, 130, 128, 100, -170, 134, 133, 100, -167, 132, 131, 100, -165, 129, 129, 100, -164, 126, 127, 100, -167, 128, 126, 100, -171, 132, 127, 100, -177, 138, 129, 100, -181, 142, 130, 100, -191, 155, 140, 100, -202, 168, 151, 100, -206, 172, 158, 100, -206, 172, 160, 100, -203, 168, 153, 100, -201, 164, 146, 100, -191, 152, 134, 100, -177, 139, 119, 100, -171, 133, 111, 100, -172, 133, 112, 100, -174, 135, 118, 100, -171, 133, 116, 100, -170, 130, 118, 100, -168, 128, 119, 100, -163, 123, 114, 100, -160, 120, 113, 100, -155, 115, 110, 100, -150, 109, 103, 100, -145, 103, 98, 100, -138, 96, 90, 100, -135, 93, 87, 100, -130, 88, 84, 100, -125, 82, 81, 100, -122, 80, 79, 100, -118, 77, 77, 100, -116, 74, 73, 100, -111, 70, 67, 100, -106, 67, 62, 100, -102, 66, 60, 100, -105, 69, 61, 100, -115, 80, 69, 100, -115, 81, 68, 100, -91, 62, 53, 100, -85, 60, 54, 100, -83, 61, 57, 100, -83, 60, 59, 100, -87, 63, 59, 100, -95, 67, 57, 100, -113, 85, 62, 100, -186, 169, 144, 100, -195, 183, 163, 100, -194, 183, 163, 100, -198, 186, 169, 100, -197, 185, 168, 100, -199, 188, 169, 100, -184, 180, 168, 100, -185, 181, 169, 100, -185, 181, 169, 100, -186, 182, 170, 100, -189, 185, 173, 100, -190, 186, 174, 100, -190, 186, 174, 100, -192, 188, 176, 100, -193, 189, 177, 100, -194, 190, 178, 100, -195, 191, 181, 100, -196, 192, 184, 100, -197, 193, 184, 100, -195, 194, 184, 100, -195, 195, 185, 100, -196, 196, 186, 100, -198, 198, 188, 100, -198, 198, 189, 100, -200, 200, 192, 100, -200, 200, 192, 100, -199, 200, 192, 100, -201, 201, 193, 100, -202, 202, 195, 100, -202, 203, 197, 100, -203, 204, 198, 100, -202, 203, 198, 100, -203, 204, 198, 100, -204, 205, 199, 100, -204, 205, 199, 100, -204, 205, 200, 100, -205, 205, 201, 100, -205, 206, 203, 100, -205, 209, 206, 100, -206, 210, 207, 100, -207, 211, 209, 100, -206, 212, 211, 100, -207, 212, 212, 100, -208, 213, 212, 100, -207, 214, 213, 100, -207, 216, 214, 100, -207, 216, 215, 100, -207, 213, 213, 100, -207, 213, 213, 100, -207, 212, 216, 100, -209, 213, 217, 100, -207, 214, 217, 100, -206, 214, 217, 100, -206, 213, 217, 100, -212, 219, 224, 100, -189, 187, 188, 100, -139, 112, 89, 100, -159, 133, 103, 100, -170, 142, 120, 100, -175, 146, 129, 100, -175, 146, 134, 100, -173, 143, 134, 100, -148, 117, 115, 100, -119, 88, 94, 100, -83, 51, 60, 100, -111, 75, 68, 100, -135, 95, 86, 100, -137, 97, 90, 100, -142, 102, 96, 100, -146, 106, 101, 100, -149, 109, 103, 100, -145, 104, 100, 100, -139, 99, 94, 100, -142, 102, 96, 100, -149, 110, 100, 100, -157, 118, 104, 100, -166, 128, 111, 100, -174, 135, 117, 100, -179, 141, 120, 100, -182, 144, 124, 100, -188, 150, 131, 100, -197, 160, 143, 100, -200, 166, 149, 100, -202, 169, 155, 100, -198, 163, 151, 100, -189, 153, 135, 100, -188, 150, 129, 100, -186, 148, 122, 100, -183, 144, 116, 100, -184, 145, 117, 100, -185, 145, 117, 100, -188, 148, 122, 100, -188, 148, 126, 100, -186, 147, 128, 100, -186, 147, 129, 100, -186, 146, 128, 100, -183, 142, 125, 100, -179, 138, 122, 100, -174, 134, 115, 100, -169, 128, 109, 100, -161, 119, 100, 100, -152, 109, 91, 100, -145, 100, 83, 100, -136, 92, 77, 100, -129, 85, 74, 100, -120, 79, 70, 100, -117, 75, 66, 100, -120, 79, 68, 100, -121, 81, 69, 100, -122, 82, 70, 100, -122, 82, 71, 100, -125, 86, 73, 100, -118, 83, 68, 100, -95, 65, 57, 100, -90, 63, 57, 100, -89, 63, 58, 100, -89, 62, 59, 100, -92, 65, 59, 100, -96, 68, 54, 100, -139, 116, 92, 100, -196, 185, 162, 100, -193, 181, 165, 100, -196, 185, 171, 100, -199, 187, 175, 100, -200, 188, 175, 100, -200, 188, 174, 100, -182, 178, 166, 100, -183, 179, 167, 100, -184, 180, 168, 100, -186, 182, 170, 100, -188, 184, 172, 100, -189, 185, 173, 100, -189, 185, 173, 100, -191, 187, 175, 100, -193, 189, 177, 100, -194, 190, 177, 100, -194, 190, 179, 100, -195, 192, 182, 100, -196, 193, 184, 100, -194, 194, 184, 100, -195, 195, 185, 100, -196, 196, 186, 100, -197, 197, 187, 100, -198, 198, 189, 100, -199, 199, 191, 100, -199, 199, 191, 100, -200, 200, 192, 100, -200, 200, 192, 100, -202, 202, 194, 100, -202, 203, 195, 100, -202, 203, 197, 100, -202, 203, 197, 100, -203, 204, 198, 100, -203, 204, 199, 100, -204, 204, 200, 100, -204, 205, 199, 100, -207, 210, 204, 100, -207, 210, 204, 100, -206, 204, 198, 100, -205, 199, 193, 100, -204, 197, 191, 100, -205, 197, 191, 100, -206, 198, 192, 100, -206, 200, 194, 100, -204, 195, 190, 100, -203, 184, 180, 100, -204, 188, 183, 100, -210, 212, 211, 100, -206, 212, 212, 100, -207, 212, 212, 100, -207, 212, 215, 100, -206, 214, 217, 100, -207, 213, 217, 100, -207, 211, 216, 100, -212, 218, 223, 100, -188, 186, 184, 100, -142, 114, 89, 100, -158, 129, 102, 100, -170, 141, 121, 100, -172, 143, 127, 100, -173, 143, 132, 100, -170, 140, 132, 100, -145, 114, 113, 100, -122, 89, 97, 100, -89, 58, 68, 100, -79, 45, 44, 100, -128, 88, 75, 100, -134, 94, 83, 100, -134, 94, 83, 100, -127, 88, 77, 100, -124, 84, 75, 100, -138, 99, 85, 100, -162, 124, 104, 100, -178, 139, 120, 100, -189, 151, 128, 100, -195, 157, 132, 100, -199, 162, 137, 100, -202, 165, 137, 100, -203, 165, 134, 100, -201, 162, 129, 100, -198, 159, 129, 100, -196, 158, 130, 100, -197, 159, 133, 100, -201, 165, 142, 100, -198, 161, 137, 100, -188, 148, 120, 100, -191, 152, 122, 100, -194, 155, 124, 100, -192, 152, 121, 100, -189, 150, 119, 100, -187, 149, 119, 100, -186, 146, 120, 100, -183, 142, 120, 100, -177, 139, 121, 100, -174, 137, 119, 100, -176, 135, 119, 100, -178, 138, 122, 100, -180, 138, 122, 100, -181, 139, 122, 100, -183, 142, 121, 100, -183, 142, 120, 100, -183, 141, 118, 100, -178, 135, 110, 100, -175, 129, 103, 100, -168, 122, 97, 100, -157, 113, 92, 100, -150, 106, 83, 100, -146, 102, 78, 100, -144, 100, 78, 100, -141, 98, 78, 100, -134, 94, 74, 100, -129, 91, 70, 100, -114, 79, 64, 100, -96, 66, 57, 100, -95, 66, 57, 100, -91, 63, 55, 100, -91, 63, 57, 100, -94, 67, 58, 100, -101, 74, 57, 100, -165, 149, 126, 100, -197, 186, 170, 100, -195, 183, 171, 100, -197, 187, 178, 100, -197, 189, 180, 100, -198, 188, 179, 100, -200, 188, 178, 100, -181, 178, 162, 100, -181, 178, 164, 100, -182, 178, 167, 100, -184, 180, 168, 100, -187, 183, 171, 100, -188, 184, 172, 100, -189, 185, 173, 100, -190, 186, 174, 100, -192, 188, 176, 100, -193, 189, 177, 100, -194, 190, 178, 100, -194, 192, 179, 100, -196, 193, 183, 100, -194, 194, 184, 100, -195, 195, 185, 100, -196, 196, 185, 100, -196, 196, 186, 100, -198, 198, 189, 100, -199, 199, 191, 100, -199, 199, 191, 100, -199, 199, 191, 100, -200, 200, 192, 100, -200, 200, 192, 100, -200, 201, 193, 100, -200, 201, 195, 100, -201, 202, 196, 100, -202, 203, 197, 100, -203, 204, 198, 100, -203, 205, 199, 100, -205, 208, 201, 100, -199, 183, 175, 100, -193, 159, 151, 100, -190, 144, 136, 100, -188, 139, 129, 100, -186, 140, 128, 100, -189, 144, 131, 100, -191, 148, 136, 100, -189, 148, 138, 100, -193, 148, 140, 100, -191, 131, 125, 100, -172, 98, 85, 100, -196, 173, 168, 100, -212, 223, 224, 100, -207, 214, 214, 100, -207, 214, 215, 100, -206, 210, 214, 100, -206, 210, 214, 100, -206, 210, 214, 100, -212, 218, 223, 100, -176, 171, 162, 100, -144, 113, 83, 100, -160, 129, 101, 100, -171, 139, 119, 100, -170, 141, 124, 100, -171, 141, 130, 100, -166, 135, 129, 100, -141, 109, 112, 100, -123, 89, 98, 100, -94, 61, 73, 100, -78, 45, 44, 100, -129, 90, 74, 100, -129, 90, 75, 100, -121, 82, 66, 100, -132, 92, 74, 100, -157, 118, 95, 100, -175, 135, 111, 100, -180, 139, 117, 100, -180, 139, 117, 100, -179, 138, 118, 100, -181, 141, 118, 100, -183, 144, 120, 100, -188, 150, 124, 100, -196, 157, 130, 100, -203, 165, 134, 100, -205, 166, 133, 100, -203, 164, 131, 100, -203, 164, 130, 100, -197, 158, 124, 100, -186, 147, 113, 100, -189, 149, 117, 100, -191, 152, 121, 100, -190, 151, 120, 100, -189, 149, 119, 100, -190, 149, 118, 100, -190, 150, 120, 100, -188, 148, 119, 100, -184, 144, 114, 100, -178, 138, 112, 100, -171, 131, 104, 100, -165, 123, 102, 100, -161, 119, 104, 100, -158, 115, 100, 100, -157, 114, 100, 100, -160, 116, 101, 100, -163, 120, 104, 100, -167, 123, 105, 100, -168, 125, 104, 100, -168, 123, 101, 100, -166, 120, 95, 100, -165, 119, 93, 100, -161, 115, 89, 100, -156, 109, 82, 100, -150, 104, 78, 100, -142, 98, 73, 100, -139, 97, 71, 100, -138, 99, 73, 100, -120, 81, 65, 100, -100, 66, 56, 100, -99, 69, 58, 100, -93, 65, 55, 100, -93, 64, 56, 100, -96, 68, 55, 100, -114, 89, 68, 100, -184, 171, 153, 100, -194, 184, 174, 100, -194, 185, 178, 100, -196, 188, 183, 100, -197, 190, 185, 100, -198, 189, 183, 100, -198, 188, 180, 100, -180, 177, 162, 100, -181, 178, 163, 100, -182, 178, 166, 100, -183, 179, 167, 100, -185, 181, 169, 100, -186, 182, 170, 100, -188, 184, 172, 100, -190, 186, 174, 100, -191, 187, 175, 100, -193, 189, 177, 100, -194, 190, 178, 100, -194, 190, 178, 100, -195, 191, 179, 100, -194, 193, 182, 100, -193, 193, 184, 100, -194, 194, 184, 100, -195, 195, 185, 100, -196, 196, 186, 100, -197, 197, 188, 100, -197, 197, 189, 100, -198, 198, 190, 100, -199, 199, 191, 100, -199, 199, 191, 100, -199, 200, 192, 100, -200, 201, 195, 100, -201, 202, 196, 100, -200, 201, 195, 100, -201, 203, 197, 100, -203, 204, 197, 100, -186, 152, 148, 100, -180, 123, 117, 100, -183, 127, 119, 100, -186, 131, 122, 100, -186, 135, 125, 100, -190, 141, 130, 100, -194, 150, 140, 100, -194, 150, 141, 100, -194, 150, 143, 100, -191, 134, 130, 100, -167, 92, 87, 100, -150, 72, 59, 100, -182, 141, 130, 100, -206, 196, 191, 100, -200, 193, 188, 100, -205, 204, 201, 100, -208, 214, 217, 100, -205, 212, 216, 100, -205, 209, 214, 100, -208, 211, 215, 100, -157, 138, 118, 100, -147, 113, 80, 100, -160, 127, 100, 100, -170, 136, 116, 100, -170, 137, 121, 100, -169, 137, 126, 100, -158, 127, 122, 100, -135, 103, 106, 100, -120, 88, 94, 100, -92, 60, 68, 100, -87, 53, 47, 100, -133, 94, 75, 100, -136, 98, 79, 100, -149, 110, 88, 100, -159, 118, 96, 100, -159, 118, 95, 100, -158, 117, 95, 100, -159, 118, 94, 100, -166, 126, 99, 100, -170, 131, 102, 100, -176, 137, 105, 100, -180, 142, 108, 100, -184, 145, 112, 100, -189, 150, 118, 100, -194, 156, 124, 100, -199, 160, 127, 100, -199, 160, 127, 100, -195, 156, 120, 100, -188, 149, 112, 100, -186, 146, 111, 100, -187, 149, 114, 100, -188, 149, 117, 100, -190, 151, 120, 100, -192, 152, 122, 100, -194, 152, 123, 100, -193, 153, 122, 100, -194, 155, 123, 100, -195, 156, 124, 100, -193, 154, 120, 100, -191, 149, 113, 100, -189, 145, 111, 100, -181, 137, 108, 100, -173, 130, 100, 100, -169, 124, 96, 100, -164, 118, 95, 100, -161, 115, 95, 100, -161, 115, 95, 100, -160, 115, 91, 100, -160, 113, 90, 100, -158, 111, 86, 100, -156, 109, 83, 100, -153, 106, 81, 100, -148, 101, 75, 100, -144, 97, 72, 100, -143, 97, 70, 100, -143, 98, 71, 100, -144, 103, 75, 100, -127, 88, 67, 100, -105, 71, 55, 100, -103, 72, 59, 100, -99, 71, 58, 100, -97, 70, 58, 100, -96, 68, 52, 100, -136, 113, 93, 100, -193, 182, 170, 100, -192, 184, 177, 100, -196, 188, 186, 100, -197, 190, 189, 100, -197, 191, 190, 100, -197, 190, 185, 100, -198, 190, 184, 100, -179, 176, 161, 100, -180, 177, 161, 100, -181, 177, 164, 100, -182, 178, 166, 100, -185, 181, 169, 100, -186, 182, 170, 100, -188, 184, 172, 100, -190, 186, 174, 100, -190, 186, 174, 100, -192, 188, 176, 100, -194, 190, 178, 100, -194, 190, 178, 100, -195, 190, 178, 100, -194, 191, 179, 100, -192, 192, 181, 100, -194, 194, 184, 100, -195, 195, 185, 100, -196, 196, 186, 100, -196, 196, 186, 100, -196, 196, 187, 100, -197, 197, 189, 100, -198, 198, 190, 100, -198, 198, 190, 100, -198, 199, 191, 100, -199, 200, 193, 100, -198, 199, 193, 100, -198, 199, 194, 100, -202, 203, 196, 100, -179, 146, 145, 100, -171, 109, 110, 100, -179, 120, 120, 100, -179, 125, 124, 100, -179, 128, 125, 100, -181, 134, 131, 100, -186, 140, 138, 100, -190, 146, 142, 100, -192, 150, 148, 100, -189, 138, 137, 100, -156, 89, 85, 100, -140, 67, 61, 100, -177, 121, 112, 100, -189, 140, 128, 100, -187, 138, 125, 100, -187, 141, 124, 100, -185, 139, 121, 100, -195, 168, 159, 100, -207, 203, 202, 100, -211, 219, 223, 100, -184, 179, 174, 100, -145, 111, 80, 100, -152, 115, 85, 100, -161, 125, 99, 100, -168, 133, 111, 100, -171, 135, 118, 100, -168, 134, 123, 100, -156, 122, 118, 100, -132, 98, 99, 100, -114, 82, 86, 100, -85, 54, 59, 100, -89, 54, 47, 100, -142, 103, 82, 100, -152, 111, 87, 100, -154, 113, 89, 100, -153, 114, 87, 100, -157, 117, 90, 100, -163, 122, 92, 100, -171, 131, 95, 100, -179, 139, 104, 100, -184, 145, 108, 100, -188, 150, 111, 100, -191, 154, 115, 100, -192, 154, 116, 100, -193, 154, 119, 100, -193, 154, 121, 100, -194, 156, 120, 100, -193, 155, 118, 100, -190, 152, 115, 100, -189, 152, 115, 100, -189, 150, 117, 100, -187, 148, 115, 100, -189, 148, 117, 100, -190, 151, 121, 100, -192, 153, 124, 100, -195, 156, 127, 100, -196, 157, 128, 100, -198, 159, 130, 100, -200, 161, 133, 100, -199, 160, 131, 100, -198, 158, 127, 100, -197, 155, 124, 100, -194, 150, 117, 100, -189, 144, 107, 100, -184, 139, 100, 100, -179, 134, 95, 100, -176, 130, 96, 100, -177, 130, 101, 100, -175, 129, 99, 100, -171, 124, 95, 100, -165, 118, 90, 100, -159, 112, 85, 100, -154, 107, 79, 100, -149, 102, 74, 100, -150, 103, 76, 100, -153, 108, 79, 100, -153, 108, 77, 100, -152, 107, 76, 100, -132, 91, 67, 100, -107, 71, 53, 100, -104, 74, 56, 100, -102, 74, 56, 100, -100, 71, 54, 100, -101, 73, 54, 100, -158, 141, 124, 100, -194, 186, 177, 100, -190, 184, 183, 100, -194, 188, 190, 100, -196, 191, 192, 100, -197, 191, 193, 100, -196, 190, 189, 100, -196, 191, 186, 100, -177, 174, 159, 100, -179, 176, 161, 100, -180, 176, 163, 100, -181, 177, 165, 100, -183, 179, 167, 100, -185, 181, 169, 100, -187, 183, 171, 100, -189, 185, 173, 100, -190, 186, 174, 100, -192, 188, 176, 100, -194, 190, 178, 100, -194, 190, 178, 100, -194, 190, 178, 100, -192, 190, 179, 100, -192, 192, 182, 100, -194, 194, 184, 100, -194, 194, 184, 100, -195, 195, 185, 100, -196, 196, 186, 100, -195, 195, 187, 100, -195, 195, 187, 100, -197, 197, 189, 100, -197, 198, 190, 100, -197, 198, 190, 100, -197, 198, 190, 100, -195, 196, 190, 100, -202, 206, 199, 100, -178, 159, 155, 100, -150, 90, 97, 100, -170, 111, 117, 100, -169, 112, 118, 100, -171, 119, 123, 100, -172, 123, 126, 100, -177, 132, 135, 100, -181, 137, 140, 100, -178, 134, 135, 100, -180, 132, 135, 100, -157, 94, 98, 100, -128, 58, 57, 100, -156, 92, 94, 100, -191, 139, 138, 100, -188, 138, 132, 100, -185, 135, 125, 100, -184, 134, 121, 100, -180, 126, 105, 100, -179, 123, 99, 100, -183, 139, 120, 100, -197, 170, 158, 100, -167, 136, 115, 100, -147, 109, 77, 100, -152, 116, 86, 100, -163, 126, 101, 100, -167, 128, 107, 100, -169, 132, 115, 100, -166, 132, 119, 100, -153, 117, 114, 100, -130, 94, 94, 100, -113, 79, 82, 100, -79, 48, 52, 100, -88, 53, 43, 100, -146, 105, 81, 100, -153, 112, 86, 100, -158, 119, 90, 100, -165, 126, 96, 100, -172, 133, 97, 100, -180, 141, 102, 100, -187, 147, 110, 100, -190, 152, 116, 100, -192, 154, 119, 100, -193, 154, 120, 100, -194, 155, 121, 100, -194, 155, 122, 100, -194, 155, 122, 100, -193, 154, 121, 100, -193, 154, 120, 100, -193, 155, 121, 100, -192, 154, 118, 100, -189, 150, 115, 100, -185, 146, 113, 100, -187, 148, 116, 100, -187, 147, 117, 100, -188, 148, 119, 100, -190, 151, 122, 100, -191, 152, 126, 100, -192, 155, 129, 100, -194, 156, 131, 100, -195, 158, 132, 100, -195, 158, 129, 100, -195, 158, 129, 100, -194, 155, 125, 100, -192, 152, 122, 100, -188, 147, 115, 100, -184, 140, 103, 100, -177, 132, 92, 100, -174, 126, 89, 100, -172, 122, 87, 100, -170, 123, 90, 100, -170, 124, 90, 100, -165, 119, 88, 100, -163, 117, 85, 100, -161, 114, 84, 100, -163, 117, 84, 100, -166, 119, 86, 100, -167, 120, 90, 100, -164, 119, 86, 100, -160, 116, 80, 100, -138, 98, 69, 100, -108, 71, 53, 100, -107, 76, 56, 100, -104, 75, 56, 100, -101, 72, 53, 100, -111, 84, 63, 100, -174, 162, 149, 100, -190, 185, 180, 100, -190, 186, 188, 100, -192, 190, 194, 100, -193, 191, 194, 100, -195, 190, 194, 100, -196, 191, 193, 100, -197, 191, 190, 100, -175, 172, 156, 100, -177, 174, 159, 100, -179, 176, 162, 100, -180, 177, 164, 100, -182, 178, 166, 100, -185, 181, 169, 100, -186, 182, 170, 100, -188, 184, 172, 100, -189, 185, 173, 100, -191, 187, 175, 100, -192, 188, 176, 100, -193, 189, 177, 100, -193, 190, 177, 100, -191, 192, 179, 100, -191, 191, 181, 100, -192, 192, 182, 100, -193, 193, 183, 100, -194, 194, 184, 100, -194, 194, 186, 100, -194, 194, 187, 100, -195, 195, 187, 100, -196, 196, 188, 100, -196, 196, 188, 100, -197, 197, 189, 100, -197, 198, 191, 100, -196, 197, 191, 100, -199, 200, 193, 100, -143, 106, 108, 100, -132, 71, 81, 100, -155, 97, 110, 100, -157, 108, 119, 100, -162, 115, 124, 100, -169, 126, 136, 100, -170, 129, 142, 100, -174, 131, 147, 100, -171, 128, 138, 100, -158, 102, 110, 100, -125, 58, 62, 100, -132, 68, 75, 100, -168, 116, 124, 100, -176, 124, 128, 100, -172, 120, 120, 100, -171, 120, 118, 100, -168, 118, 114, 100, -170, 120, 109, 100, -175, 121, 104, 100, -181, 126, 106, 100, -183, 126, 104, 100, -180, 127, 101, 100, -163, 118, 92, 100, -155, 116, 88, 100, -162, 125, 99, 100, -165, 127, 105, 100, -166, 127, 112, 100, -163, 125, 113, 100, -150, 112, 108, 100, -125, 89, 89, 100, -111, 75, 79, 100, -73, 40, 44, 100, -96, 59, 47, 100, -149, 109, 82, 100, -155, 116, 88, 100, -162, 123, 92, 100, -170, 130, 98, 100, -179, 140, 105, 100, -185, 146, 112, 100, -187, 149, 116, 100, -188, 152, 120, 100, -190, 153, 122, 100, -193, 154, 123, 100, -194, 155, 125, 100, -194, 155, 125, 100, -194, 155, 125, 100, -193, 154, 123, 100, -193, 154, 121, 100, -195, 156, 125, 100, -192, 153, 123, 100, -190, 151, 119, 100, -187, 149, 118, 100, -186, 148, 118, 100, -183, 146, 116, 100, -183, 145, 116, 100, -182, 144, 115, 100, -181, 142, 119, 100, -183, 146, 123, 100, -185, 147, 125, 100, -185, 148, 125, 100, -187, 149, 125, 100, -186, 148, 121, 100, -185, 147, 118, 100, -185, 146, 117, 100, -182, 144, 113, 100, -183, 139, 107, 100, -180, 134, 101, 100, -172, 127, 88, 100, -170, 122, 84, 100, -167, 120, 82, 100, -165, 120, 83, 100, -167, 121, 87, 100, -169, 123, 89, 100, -169, 123, 89, 100, -171, 125, 90, 100, -168, 122, 86, 100, -166, 121, 84, 100, -161, 116, 82, 100, -155, 112, 80, 100, -140, 100, 74, 100, -110, 74, 55, 100, -106, 73, 54, 100, -103, 75, 55, 100, -101, 71, 52, 100, -123, 99, 79, 100, -182, 174, 164, 100, -187, 182, 182, 100, -189, 186, 192, 100, -191, 189, 196, 100, -193, 190, 198, 100, -193, 191, 197, 100, -194, 192, 194, 100, -196, 191, 194, 100, -173, 170, 152, 100, -175, 172, 157, 100, -177, 174, 159, 100, -180, 177, 162, 100, -182, 178, 166, 100, -183, 179, 167, 100, -185, 181, 169, 100, -187, 183, 171, 100, -188, 184, 172, 100, -190, 186, 174, 100, -191, 187, 175, 100, -192, 188, 176, 100, -192, 189, 177, 100, -190, 192, 177, 100, -191, 191, 180, 100, -191, 191, 181, 100, -191, 191, 181, 100, -192, 192, 182, 100, -193, 193, 184, 100, -193, 193, 185, 100, -194, 194, 186, 100, -195, 195, 187, 100, -196, 196, 188, 100, -197, 197, 189, 100, -196, 197, 189, 100, -196, 197, 190, 100, -195, 195, 187, 100, -125, 86, 90, 100, -112, 63, 77, 100, -131, 81, 94, 100, -142, 97, 110, 100, -148, 105, 120, 100, -156, 115, 134, 100, -158, 122, 143, 100, -161, 121, 144, 100, -156, 111, 128, 100, -128, 69, 73, 100, -114, 50, 57, 100, -151, 96, 110, 100, -167, 118, 132, 100, -163, 111, 121, 100, -156, 104, 111, 100, -156, 104, 109, 100, -152, 100, 103, 100, -155, 100, 101, 100, -160, 105, 96, 100, -168, 111, 99, 100, -178, 122, 104, 100, -173, 120, 99, 100, -163, 112, 88, 100, -167, 120, 94, 100, -167, 123, 97, 100, -164, 127, 104, 100, -163, 125, 109, 100, -160, 120, 108, 100, -144, 104, 100, 100, -122, 83, 82, 100, -105, 69, 71, 100, -69, 35, 36, 100, -116, 77, 58, 100, -152, 112, 82, 100, -151, 111, 81, 100, -160, 121, 89, 100, -173, 135, 102, 100, -179, 142, 111, 100, -181, 144, 115, 100, -182, 145, 116, 100, -183, 146, 118, 100, -184, 147, 118, 100, -185, 147, 118, 100, -189, 150, 122, 100, -189, 150, 121, 100, -189, 151, 122, 100, -189, 152, 123, 100, -188, 150, 122, 100, -189, 151, 123, 100, -187, 149, 121, 100, -184, 146, 116, 100, -181, 144, 114, 100, -180, 142, 113, 100, -179, 141, 111, 100, -179, 141, 111, 100, -178, 140, 111, 100, -174, 137, 111, 100, -173, 134, 108, 100, -171, 132, 106, 100, -171, 132, 106, 100, -172, 132, 108, 100, -174, 134, 110, 100, -174, 134, 109, 100, -173, 134, 106, 100, -173, 133, 105, 100, -174, 131, 102, 100, -176, 131, 100, 100, -173, 128, 95, 100, -172, 127, 92, 100, -172, 128, 90, 100, -173, 127, 90, 100, -173, 127, 91, 100, -171, 125, 90, 100, -170, 124, 88, 100, -169, 123, 86, 100, -166, 120, 84, 100, -161, 115, 82, 100, -156, 110, 79, 100, -147, 105, 76, 100, -130, 93, 68, 100, -108, 74, 54, 100, -109, 78, 56, 100, -107, 79, 57, 100, -104, 75, 53, 100, -135, 115, 98, 100, -183, 178, 174, 100, -184, 182, 184, 100, -189, 186, 195, 100, -191, 189, 198, 100, -192, 190, 200, 100, -194, 191, 199, 100, -194, 191, 196, 100, -193, 191, 194, 100, -172, 169, 153, 100, -173, 170, 155, 100, -175, 172, 158, 100, -179, 176, 161, 100, -181, 177, 163, 100, -183, 179, 167, 100, -184, 180, 168, 100, -186, 182, 170, 100, -187, 183, 171, 100, -189, 185, 173, 100, -190, 186, 174, 100, -191, 187, 175, 100, -192, 189, 176, 100, -190, 191, 177, 100, -190, 190, 179, 100, -191, 191, 181, 100, -191, 191, 181, 100, -192, 192, 181, 100, -192, 192, 183, 100, -193, 193, 185, 100, -193, 193, 185, 100, -194, 194, 186, 100, -195, 195, 187, 100, -195, 196, 188, 100, -196, 197, 189, 100, -193, 194, 186, 100, -199, 202, 193, 100, -149, 125, 124, 100, -98, 56, 70, 100, -103, 62, 76, 100, -129, 84, 101, 100, -137, 94, 113, 100, -139, 99, 121, 100, -143, 107, 130, 100, -137, 96, 115, 100, -123, 71, 80, 100, -103, 44, 45, 100, -124, 68, 78, 100, -143, 90, 106, 100, -147, 98, 114, 100, -149, 101, 113, 100, -144, 94, 104, 100, -144, 93, 102, 100, -142, 88, 95, 100, -145, 88, 93, 100, -152, 96, 96, 100, -157, 100, 95, 100, -164, 107, 97, 100, -154, 99, 84, 100, -155, 102, 82, 100, -166, 115, 90, 100, -169, 122, 95, 100, -167, 124, 99, 100, -162, 123, 102, 100, -154, 115, 103, 100, -137, 96, 93, 100, -117, 76, 76, 100, -94, 57, 57, 100, -81, 44, 37, 100, -147, 108, 79, 100, -155, 116, 86, 100, -147, 108, 77, 100, -161, 123, 91, 100, -170, 134, 104, 100, -173, 137, 108, 100, -175, 138, 109, 100, -177, 138, 109, 100, -176, 138, 109, 100, -177, 139, 111, 100, -177, 139, 111, 100, -180, 140, 112, 100, -182, 143, 114, 100, -184, 145, 117, 100, -184, 148, 119, 100, -183, 146, 117, 100, -185, 148, 118, 100, -185, 148, 118, 100, -181, 142, 108, 100, -182, 143, 107, 100, -185, 146, 110, 100, -187, 149, 113, 100, -190, 151, 118, 100, -193, 154, 120, 100, -193, 154, 121, 100, -191, 152, 119, 100, -187, 148, 115, 100, -182, 143, 110, 100, -174, 135, 104, 100, -169, 130, 100, 100, -165, 126, 97, 100, -164, 123, 96, 100, -165, 124, 96, 100, -167, 125, 98, 100, -169, 125, 97, 100, -170, 125, 94, 100, -173, 128, 97, 100, -177, 132, 99, 100, -178, 132, 97, 100, -177, 131, 95, 100, -173, 127, 90, 100, -168, 122, 86, 100, -163, 117, 81, 100, -159, 113, 79, 100, -155, 109, 77, 100, -149, 103, 74, 100, -141, 99, 70, 100, -127, 87, 61, 100, -108, 73, 50, 100, -111, 80, 56, 100, -114, 86, 62, 100, -108, 79, 57, 100, -144, 125, 112, 100, -182, 177, 176, 100, -185, 181, 187, 100, -189, 186, 197, 100, -191, 189, 201, 100, -192, 190, 204, 100, -193, 191, 202, 100, -194, 191, 199, 100, -193, 190, 196, 100, -164, 165, 152, 100, -172, 168, 154, 100, -176, 173, 157, 100, -179, 175, 160, 100, -180, 176, 163, 100, -182, 177, 166, 100, -183, 179, 167, 100, -185, 181, 169, 100, -187, 183, 171, 100, -188, 184, 172, 100, -190, 186, 174, 100, -191, 187, 175, 100, -191, 187, 175, 100, -191, 189, 176, 100, -189, 190, 178, 100, -190, 190, 180, 100, -191, 191, 180, 100, -191, 191, 181, 100, -192, 192, 182, 100, -191, 191, 183, 100, -193, 193, 185, 100, -194, 194, 186, 100, -194, 194, 186, 100, -195, 196, 188, 100, -194, 195, 188, 100, -192, 193, 187, 100, -207, 209, 203, 100, -151, 145, 141, 100, -94, 60, 62, 100, -101, 58, 69, 100, -115, 71, 85, 100, -129, 85, 101, 100, -125, 84, 100, 100, -122, 81, 96, 100, -116, 68, 76, 100, -100, 44, 45, 100, -106, 52, 58, 100, -124, 73, 85, 100, -127, 77, 91, 100, -126, 79, 95, 100, -128, 83, 96, 100, -128, 83, 94, 100, -131, 83, 92, 100, -133, 82, 92, 100, -133, 80, 87, 100, -139, 87, 90, 100, -147, 92, 93, 100, -150, 93, 93, 100, -146, 87, 81, 100, -150, 92, 81, 100, -154, 97, 80, 100, -163, 112, 92, 100, -165, 116, 93, 100, -162, 114, 88, 100, -158, 115, 94, 100, -132, 92, 83, 100, -110, 70, 70, 100, -82, 46, 46, 100, -102, 63, 48, 100, -165, 126, 93, 100, -158, 119, 86, 100, -152, 113, 81, 100, -160, 122, 91, 100, -162, 124, 95, 100, -165, 126, 98, 100, -166, 126, 98, 100, -164, 124, 95, 100, -168, 129, 97, 100, -176, 137, 103, 100, -183, 145, 107, 100, -188, 150, 113, 100, -191, 153, 116, 100, -192, 154, 118, 100, -191, 153, 119, 100, -189, 151, 116, 100, -186, 148, 111, 100, -183, 145, 107, 100, -182, 144, 106, 100, -183, 144, 107, 100, -187, 149, 112, 100, -189, 150, 116, 100, -192, 153, 120, 100, -193, 155, 123, 100, -195, 156, 124, 100, -196, 156, 123, 100, -196, 157, 125, 100, -195, 156, 123, 100, -191, 153, 117, 100, -187, 149, 109, 100, -183, 143, 104, 100, -179, 135, 98, 100, -175, 130, 95, 100, -172, 128, 95, 100, -171, 126, 94, 100, -170, 125, 93, 100, -172, 127, 95, 100, -173, 128, 97, 100, -172, 126, 96, 100, -171, 124, 93, 100, -167, 121, 87, 100, -161, 115, 82, 100, -156, 109, 76, 100, -151, 104, 73, 100, -145, 99, 69, 100, -142, 98, 67, 100, -140, 96, 67, 100, -131, 91, 63, 100, -113, 77, 52, 100, -113, 80, 55, 100, -113, 85, 61, 100, -110, 82, 60, 100, -147, 133, 123, 100, -180, 174, 178, 100, -184, 181, 188, 100, -187, 185, 197, 100, -191, 189, 202, 100, -192, 190, 204, 100, -192, 191, 203, 100, -193, 191, 200, 100, -194, 191, 199, 100, -155, 160, 152, 100, -164, 169, 159, 100, -162, 164, 153, 100, -166, 167, 155, 100, -178, 176, 162, 100, -181, 177, 165, 100, -183, 179, 167, 100, -184, 180, 168, 100, -185, 181, 169, 100, -188, 184, 172, 100, -188, 184, 172, 100, -190, 186, 174, 100, -191, 186, 175, 100, -190, 188, 175, 100, -188, 190, 176, 100, -189, 190, 177, 100, -190, 190, 180, 100, -191, 191, 181, 100, -191, 191, 181, 100, -191, 191, 183, 100, -192, 192, 184, 100, -193, 193, 185, 100, -194, 194, 186, 100, -193, 194, 186, 100, -194, 195, 188, 100, -201, 202, 196, 100, -133, 133, 130, 100, -41, 40, 39, 100, -77, 60, 56, 100, -114, 74, 76, 100, -103, 59, 68, 100, -100, 57, 64, 100, -104, 61, 68, 100, -104, 60, 63, 100, -98, 48, 51, 100, -100, 46, 49, 100, -108, 56, 63, 100, -109, 62, 71, 100, -113, 67, 81, 100, -112, 70, 84, 100, -109, 66, 78, 100, -111, 67, 77, 100, -114, 70, 79, 100, -120, 75, 84, 100, -127, 80, 88, 100, -130, 80, 86, 100, -134, 84, 89, 100, -131, 77, 82, 100, -133, 78, 80, 100, -138, 81, 79, 100, -141, 84, 77, 100, -153, 98, 86, 100, -158, 105, 87, 100, -157, 106, 83, 100, -160, 114, 88, 100, -151, 108, 88, 100, -107, 69, 63, 100, -69, 34, 34, 100, -115, 76, 56, 100, -164, 125, 92, 100, -157, 118, 86, 100, -152, 113, 79, 100, -151, 112, 82, 100, -152, 112, 83, 100, -154, 113, 83, 100, -159, 120, 87, 100, -172, 134, 98, 100, -185, 147, 105, 100, -191, 153, 111, 100, -193, 157, 114, 100, -195, 157, 117, 100, -195, 156, 119, 100, -194, 156, 119, 100, -189, 151, 114, 100, -188, 150, 112, 100, -183, 145, 107, 100, -179, 142, 102, 100, -180, 142, 102, 100, -183, 145, 107, 100, -185, 146, 111, 100, -186, 147, 113, 100, -189, 150, 116, 100, -192, 153, 120, 100, -193, 154, 121, 100, -193, 154, 121, 100, -192, 153, 120, 100, -190, 151, 118, 100, -188, 149, 113, 100, -186, 146, 110, 100, -186, 144, 106, 100, -184, 140, 100, 100, -180, 135, 92, 100, -175, 130, 88, 100, -173, 128, 86, 100, -171, 125, 88, 100, -170, 124, 89, 100, -166, 120, 89, 100, -161, 114, 86, 100, -159, 112, 83, 100, -156, 109, 79, 100, -153, 106, 77, 100, -149, 103, 72, 100, -146, 98, 69, 100, -145, 98, 67, 100, -146, 101, 69, 100, -147, 101, 72, 100, -145, 103, 73, 100, -122, 84, 58, 100, -117, 84, 58, 100, -119, 90, 67, 100, -115, 89, 67, 100, -148, 138, 133, 100, -176, 171, 179, 100, -183, 180, 189, 100, -187, 185, 198, 100, -190, 188, 202, 100, -191, 189, 203, 100, -191, 189, 203, 100, -192, 190, 201, 100, -193, 190, 198, 100, -166, 170, 161, 100, -138, 144, 138, 100, -126, 133, 130, 100, -154, 160, 151, 100, -162, 169, 156, 100, -172, 173, 162, 100, -178, 177, 163, 100, -182, 179, 166, 100, -185, 180, 169, 100, -187, 183, 171, 100, -188, 184, 172, 100, -189, 185, 173, 100, -190, 186, 174, 100, -190, 187, 175, 100, -190, 188, 175, 100, -190, 190, 176, 100, -190, 191, 179, 100, -191, 191, 181, 100, -191, 191, 181, 100, -190, 190, 181, 100, -190, 190, 182, 100, -190, 190, 182, 100, -190, 190, 182, 100, -200, 200, 192, 100, -185, 186, 178, 100, -102, 103, 96, 100, -43, 43, 37, 100, -44, 43, 38, 100, -39, 36, 31, 100, -80, 63, 58, 100, -100, 63, 64, 100, -94, 50, 56, 100, -89, 46, 51, 100, -84, 37, 38, 100, -92, 44, 46, 100, -107, 58, 61, 100, -103, 55, 62, 100, -103, 57, 68, 100, -104, 61, 71, 100, -102, 61, 70, 100, -106, 64, 73, 100, -105, 62, 71, 100, -107, 65, 74, 100, -107, 64, 73, 100, -117, 72, 81, 100, -119, 74, 80, 100, -118, 73, 79, 100, -120, 74, 78, 100, -123, 78, 80, 100, -128, 81, 79, 100, -133, 82, 78, 100, -139, 87, 81, 100, -147, 95, 85, 100, -150, 98, 83, 100, -153, 100, 82, 100, -158, 108, 85, 100, -147, 103, 80, 100, -92, 53, 39, 100, -124, 84, 57, 100, -152, 113, 80, 100, -153, 113, 81, 100, -154, 114, 80, 100, -151, 113, 78, 100, -156, 117, 81, 100, -168, 129, 91, 100, -179, 141, 101, 100, -187, 150, 109, 100, -191, 153, 113, 100, -193, 155, 115, 100, -195, 157, 117, 100, -193, 154, 115, 100, -193, 155, 117, 100, -192, 154, 116, 100, -190, 152, 114, 100, -186, 149, 108, 100, -183, 145, 106, 100, -183, 145, 108, 100, -184, 146, 108, 100, -184, 145, 109, 100, -185, 144, 108, 100, -186, 146, 109, 100, -187, 148, 114, 100, -190, 151, 118, 100, -192, 153, 120, 100, -192, 153, 120, 100, -189, 151, 116, 100, -187, 149, 113, 100, -185, 146, 109, 100, -184, 145, 107, 100, -183, 141, 104, 100, -182, 138, 99, 100, -178, 133, 93, 100, -172, 127, 85, 100, -167, 122, 80, 100, -165, 120, 81, 100, -165, 120, 82, 100, -165, 118, 85, 100, -161, 115, 82, 100, -160, 113, 84, 100, -160, 114, 82, 100, -159, 113, 80, 100, -157, 111, 76, 100, -155, 109, 75, 100, -155, 109, 75, 100, -156, 110, 76, 100, -156, 111, 77, 100, -155, 112, 77, 100, -132, 93, 62, 100, -117, 82, 55, 100, -120, 90, 66, 100, -120, 97, 75, 100, -148, 139, 141, 100, -172, 169, 178, 100, -183, 181, 193, 100, -188, 185, 200, 100, -190, 187, 201, 100, -190, 188, 202, 100, -191, 188, 203, 100, -192, 190, 202, 100, -193, 191, 199, 100, -169, 161, 142, 100, -161, 159, 146, 100, -160, 164, 154, 100, -165, 169, 160, 100, -166, 173, 163, 100, -171, 175, 167, 100, -172, 175, 164, 100, -176, 177, 163, 100, -182, 179, 164, 100, -185, 182, 168, 100, -187, 183, 171, 100, -188, 185, 172, 100, -190, 186, 174, 100, -190, 186, 174, 100, -191, 187, 175, 100, -191, 188, 176, 100, -190, 190, 176, 100, -189, 190, 179, 100, -189, 189, 179, 100, -189, 189, 179, 100, -187, 187, 178, 100, -190, 190, 182, 100, -189, 190, 182, 100, -149, 149, 140, 100, -84, 84, 75, 100, -59, 59, 49, 100, -62, 62, 52, 100, -72, 69, 61, 100, -78, 74, 68, 100, -103, 99, 91, 100, -129, 114, 105, 100, -107, 73, 70, 100, -94, 52, 51, 100, -128, 99, 94, 100, -123, 92, 89, 100, -91, 47, 48, 100, -106, 60, 63, 100, -106, 62, 71, 100, -101, 58, 67, 100, -102, 59, 66, 100, -102, 59, 66, 100, -100, 57, 65, 100, -105, 62, 71, 100, -107, 64, 73, 100, -109, 66, 74, 100, -109, 65, 73, 100, -108, 65, 71, 100, -114, 72, 79, 100, -113, 74, 81, 100, -117, 77, 79, 100, -124, 81, 80, 100, -126, 79, 78, 100, -128, 78, 75, 100, -131, 79, 75, 100, -145, 91, 77, 100, -148, 95, 74, 100, -154, 105, 79, 100, -157, 109, 83, 100, -152, 108, 76, 100, -153, 113, 77, 100, -154, 114, 79, 100, -153, 115, 78, 100, -160, 123, 82, 100, -172, 136, 93, 100, -179, 142, 100, 100, -182, 146, 104, 100, -185, 149, 107, 100, -189, 151, 112, 100, -193, 155, 117, 100, -194, 156, 119, 100, -192, 154, 118, 100, -189, 151, 116, 100, -183, 144, 109, 100, -180, 141, 109, 100, -181, 142, 110, 100, -175, 136, 104, 100, -170, 130, 97, 100, -175, 135, 101, 100, -180, 140, 106, 100, -183, 143, 110, 100, -184, 143, 111, 100, -184, 144, 112, 100, -185, 146, 113, 100, -188, 149, 115, 100, -188, 150, 116, 100, -188, 149, 114, 100, -188, 146, 110, 100, -186, 143, 104, 100, -181, 138, 99, 100, -178, 134, 96, 100, -177, 133, 94, 100, -174, 129, 90, 100, -172, 127, 87, 100, -169, 124, 84, 100, -164, 119, 80, 100, -166, 121, 83, 100, -169, 123, 87, 100, -173, 127, 91, 100, -175, 129, 92, 100, -173, 128, 89, 100, -171, 126, 87, 100, -169, 123, 86, 100, -169, 121, 83, 100, -165, 120, 81, 100, -162, 117, 78, 100, -159, 113, 77, 100, -156, 113, 77, 100, -134, 96, 65, 100, -115, 79, 54, 100, -117, 88, 65, 100, -125, 104, 88, 100, -148, 141, 148, 100, -169, 166, 177, 100, -183, 181, 194, 100, -187, 185, 199, 100, -188, 187, 201, 100, -189, 188, 202, 100, -190, 189, 203, 100, -191, 189, 201, 100, -192, 190, 200, 100, -204, 171, 135, 100, -197, 170, 137, 100, -186, 167, 141, 100, -177, 165, 146, 100, -171, 164, 151, 100, -166, 165, 156, 100, -168, 170, 163, 100, -171, 174, 166, 100, -175, 177, 166, 100, -178, 178, 166, 100, -179, 179, 167, 100, -180, 180, 168, 100, -186, 183, 171, 100, -191, 188, 176, 100, -191, 187, 175, 100, -191, 187, 175, 100, -191, 188, 175, 100, -188, 187, 175, 100, -192, 191, 181, 100, -193, 193, 183, 100, -193, 194, 184, 100, -186, 185, 177, 100, -142, 142, 133, 100, -108, 106, 96, 100, -96, 92, 83, 100, -90, 86, 77, 100, -115, 111, 102, 100, -136, 131, 124, 100, -131, 126, 120, 100, -108, 101, 96, 100, -114, 106, 101, 100, -128, 117, 108, 100, -156, 144, 134, 100, -180, 179, 168, 100, -161, 157, 146, 100, -131, 110, 103, 100, -100, 63, 61, 100, -99, 57, 58, 100, -101, 58, 64, 100, -99, 56, 61, 100, -98, 56, 60, 100, -97, 55, 60, 100, -101, 58, 65, 100, -108, 66, 74, 100, -114, 73, 81, 100, -110, 68, 74, 100, -108, 65, 72, 100, -111, 68, 75, 100, -111, 72, 77, 100, -112, 71, 77, 100, -117, 75, 81, 100, -119, 74, 75, 100, -114, 66, 66, 100, -123, 73, 72, 100, -133, 80, 75, 100, -137, 81, 67, 100, -146, 90, 73, 100, -146, 93, 70, 100, -158, 112, 83, 100, -159, 114, 80, 100, -154, 112, 74, 100, -151, 111, 72, 100, -165, 125, 85, 100, -174, 134, 92, 100, -179, 139, 96, 100, -179, 140, 100, 100, -181, 142, 101, 100, -184, 145, 105, 100, -184, 147, 106, 100, -183, 146, 104, 100, -177, 138, 100, 100, -172, 133, 96, 100, -150, 112, 78, 100, -142, 103, 70, 100, -160, 121, 89, 100, -172, 131, 100, 100, -179, 139, 105, 100, -187, 147, 112, 100, -192, 153, 118, 100, -193, 153, 121, 100, -194, 155, 122, 100, -195, 156, 123, 100, -196, 157, 124, 100, -192, 153, 119, 100, -188, 150, 113, 100, -183, 143, 107, 100, -180, 136, 99, 100, -180, 135, 97, 100, -178, 134, 95, 100, -175, 130, 91, 100, -170, 125, 86, 100, -167, 122, 84, 100, -166, 121, 84, 100, -166, 121, 83, 100, -165, 119, 81, 100, -168, 122, 86, 100, -173, 128, 89, 100, -177, 132, 93, 100, -180, 134, 98, 100, -179, 134, 96, 100, -176, 131, 92, 100, -174, 129, 91, 100, -172, 126, 88, 100, -168, 123, 84, 100, -164, 118, 81, 100, -159, 114, 79, 100, -155, 111, 77, 100, -133, 95, 65, 100, -112, 77, 53, 100, -115, 86, 65, 100, -125, 111, 103, 100, -146, 142, 153, 100, -167, 165, 177, 100, -181, 180, 193, 100, -182, 186, 198, 100, -185, 188, 200, 100, -189, 188, 202, 100, -190, 188, 202, 100, -191, 189, 202, 100, -191, 189, 200, 100, -206, 173, 139, 100, -207, 173, 138, 100, -205, 172, 136, 100, -202, 172, 137, 100, -199, 169, 135, 100, -189, 166, 138, 100, -179, 162, 140, 100, -169, 160, 141, 100, -162, 161, 152, 100, -163, 165, 158, 100, -164, 168, 160, 100, -168, 172, 163, 100, -166, 169, 159, 100, -167, 166, 156, 100, -190, 187, 174, 100, -192, 187, 175, 100, -189, 186, 174, 100, -196, 192, 180, 100, -173, 169, 158, 100, -151, 148, 139, 100, -143, 141, 133, 100, -113, 108, 102, 100, -68, 62, 60, 100, -95, 89, 86, 100, -146, 141, 133, 100, -137, 132, 125, 100, -121, 116, 111, 100, -94, 89, 85, 100, -75, 69, 66, 100, -91, 86, 82, 100, -127, 122, 115, 100, -141, 136, 128, 100, -154, 150, 142, 100, -147, 143, 134, 100, -143, 138, 129, 100, -147, 142, 132, 100, -132, 120, 110, 100, -100, 72, 64, 100, -89, 52, 49, 100, -92, 52, 54, 100, -96, 56, 58, 100, -98, 57, 60, 100, -99, 59, 61, 100, -93, 58, 59, 100, -92, 57, 60, 100, -98, 61, 64, 100, -96, 58, 61, 100, -96, 56, 61, 100, -105, 67, 71, 100, -112, 73, 77, 100, -112, 74, 80, 100, -113, 73, 76, 100, -116, 72, 71, 100, -114, 68, 66, 100, -117, 67, 64, 100, -119, 66, 61, 100, -130, 74, 60, 100, -139, 86, 65, 100, -144, 96, 72, 100, -153, 106, 78, 100, -159, 113, 80, 100, -162, 118, 79, 100, -162, 118, 79, 100, -167, 123, 83, 100, -165, 121, 80, 100, -174, 130, 90, 100, -182, 139, 95, 100, -184, 144, 99, 100, -185, 148, 103, 100, -187, 150, 104, 100, -185, 147, 101, 100, -181, 143, 100, 100, -171, 134, 92, 100, -180, 143, 102, 100, -189, 151, 111, 100, -190, 153, 113, 100, -191, 153, 116, 100, -190, 152, 116, 100, -191, 152, 118, 100, -192, 154, 119, 100, -193, 154, 121, 100, -194, 155, 122, 100, -195, 156, 123, 100, -195, 156, 121, 100, -193, 154, 118, 100, -190, 150, 112, 100, -187, 144, 104, 100, -179, 135, 96, 100, -172, 127, 88, 100, -169, 124, 86, 100, -169, 124, 85, 100, -166, 121, 83, 100, -163, 117, 81, 100, -161, 115, 79, 100, -162, 116, 80, 100, -164, 118, 83, 100, -168, 122, 87, 100, -172, 126, 91, 100, -176, 130, 95, 100, -177, 131, 96, 100, -175, 129, 94, 100, -173, 127, 91, 100, -170, 124, 88, 100, -168, 122, 85, 100, -163, 118, 80, 100, -159, 114, 76, 100, -152, 108, 73, 100, -133, 94, 65, 100, -109, 75, 51, 100, -113, 84, 64, 100, -129, 118, 115, 100, -144, 142, 155, 100, -166, 164, 178, 100, -180, 179, 193, 100, -181, 185, 197, 100, -183, 188, 200, 100, -186, 189, 201, 100, -189, 188, 202, 100, -190, 188, 202, 100, -190, 188, 200, 100, -209, 174, 141, 100, -208, 174, 141, 100, -206, 172, 138, 100, -206, 173, 139, 100, -207, 173, 138, 100, -207, 175, 139, 100, -208, 175, 138, 100, -203, 172, 136, 100, -194, 168, 137, 100, -184, 163, 139, 100, -170, 160, 140, 100, -162, 159, 149, 100, -152, 153, 145, 100, -134, 136, 128, 100, -150, 151, 139, 100, -187, 183, 171, 100, -197, 191, 178, 100, -164, 160, 147, 100, -77, 72, 66, 100, -57, 51, 48, 100, -72, 66, 64, 100, -69, 63, 63, 100, -43, 37, 38, 100, -100, 94, 89, 100, -144, 138, 132, 100, -96, 90, 85, 100, -68, 63, 59, 100, -101, 96, 91, 100, -132, 127, 121, 100, -144, 140, 131, 100, -138, 134, 125, 100, -152, 148, 139, 100, -149, 145, 136, 100, -143, 139, 130, 100, -140, 136, 127, 100, -124, 119, 111, 100, -112, 105, 99, 100, -110, 101, 94, 100, -113, 100, 93, 100, -93, 74, 67, 100, -83, 58, 52, 100, -75, 42, 38, 100, -79, 46, 42, 100, -78, 47, 44, 100, -72, 41, 39, 100, -77, 43, 43, 100, -89, 53, 53, 100, -90, 52, 53, 100, -94, 58, 60, 100, -99, 62, 64, 100, -108, 72, 73, 100, -107, 72, 71, 100, -107, 69, 68, 100, -113, 69, 69, 100, -115, 68, 66, 100, -117, 70, 67, 100, -125, 75, 66, 100, -128, 75, 59, 100, -122, 72, 53, 100, -142, 95, 72, 100, -155, 109, 81, 100, -170, 125, 88, 100, -158, 113, 74, 100, -145, 100, 60, 100, -167, 123, 79, 100, -177, 135, 88, 100, -180, 138, 92, 100, -183, 140, 95, 100, -183, 143, 98, 100, -184, 145, 100, 100, -183, 144, 100, 100, -179, 141, 97, 100, -177, 138, 95, 100, -182, 144, 102, 100, -181, 143, 103, 100, -180, 142, 103, 100, -182, 143, 107, 100, -184, 146, 108, 100, -183, 146, 107, 100, -185, 147, 110, 100, -187, 149, 114, 100, -188, 150, 114, 100, -186, 148, 112, 100, -185, 147, 109, 100, -185, 147, 108, 100, -183, 145, 106, 100, -184, 141, 102, 100, -183, 139, 100, 100, -179, 135, 94, 100, -170, 125, 84, 100, -163, 118, 78, 100, -162, 117, 78, 100, -163, 118, 81, 100, -165, 120, 83, 100, -164, 118, 82, 100, -164, 118, 82, 100, -168, 122, 88, 100, -171, 125, 92, 100, -173, 127, 93, 100, -172, 126, 92, 100, -172, 126, 91, 100, -169, 123, 88, 100, -166, 120, 85, 100, -163, 117, 81, 100, -162, 117, 79, 100, -159, 114, 77, 100, -155, 111, 76, 100, -136, 98, 68, 100, -112, 77, 54, 100, -112, 82, 63, 100, -131, 119, 123, 100, -144, 141, 156, 100, -164, 162, 176, 100, -177, 179, 192, 100, -180, 184, 196, 100, -183, 187, 199, 100, -186, 189, 201, 100, -188, 188, 201, 100, -190, 188, 201, 100, -190, 188, 201, 100, -211, 175, 142, 100, -212, 176, 142, 100, -211, 175, 141, 100, -212, 175, 142, 100, -212, 176, 144, 100, -208, 174, 141, 100, -206, 174, 140, 100, -206, 175, 141, 100, -205, 175, 140, 100, -208, 176, 141, 100, -205, 175, 141, 100, -197, 169, 138, 100, -187, 168, 141, 100, -169, 157, 138, 100, -125, 119, 104, 100, -135, 131, 119, 100, -173, 169, 157, 100, -93, 89, 79, 100, -43, 38, 35, 100, -37, 32, 35, 100, -33, 29, 32, 100, -48, 43, 39, 100, -108, 103, 92, 100, -120, 115, 104, 100, -86, 81, 75, 100, -84, 79, 75, 100, -119, 114, 109, 100, -151, 147, 139, 100, -146, 141, 134, 100, -136, 132, 123, 100, -151, 147, 138, 100, -147, 141, 133, 100, -136, 132, 123, 100, -136, 132, 123, 100, -128, 124, 116, 100, -124, 119, 112, 100, -133, 127, 119, 100, -137, 130, 122, 100, -138, 132, 124, 100, -140, 134, 125, 100, -134, 126, 117, 100, -115, 101, 92, 100, -89, 64, 57, 100, -75, 44, 36, 100, -77, 46, 38, 100, -77, 45, 40, 100, -87, 53, 48, 100, -93, 57, 55, 100, -92, 56, 56, 100, -93, 57, 56, 100, -100, 65, 62, 100, -104, 70, 67, 100, -107, 70, 69, 100, -109, 66, 67, 100, -113, 71, 71, 100, -121, 77, 75, 100, -114, 67, 61, 100, -110, 61, 51, 100, -117, 67, 54, 100, -129, 80, 64, 100, -144, 98, 74, 100, -158, 111, 81, 100, -161, 115, 81, 100, -156, 111, 69, 100, -167, 123, 76, 100, -173, 130, 80, 100, -180, 138, 87, 100, -183, 142, 93, 100, -185, 147, 100, 100, -185, 148, 103, 100, -185, 148, 103, 100, -186, 149, 103, 100, -186, 148, 104, 100, -189, 151, 109, 100, -188, 151, 108, 100, -189, 151, 112, 100, -190, 152, 116, 100, -190, 152, 114, 100, -190, 152, 114, 100, -190, 151, 114, 100, -189, 151, 113, 100, -186, 149, 109, 100, -183, 144, 106, 100, -180, 142, 102, 100, -178, 137, 96, 100, -179, 135, 96, 100, -179, 136, 94, 100, -178, 134, 93, 100, -178, 133, 92, 100, -175, 130, 87, 100, -170, 126, 83, 100, -165, 121, 77, 100, -163, 118, 78, 100, -165, 119, 81, 100, -166, 121, 80, 100, -169, 124, 85, 100, -171, 126, 87, 100, -173, 127, 90, 100, -172, 126, 90, 100, -172, 126, 90, 100, -170, 124, 89, 100, -168, 122, 86, 100, -164, 118, 82, 100, -161, 115, 79, 100, -156, 111, 74, 100, -155, 109, 75, 100, -156, 112, 77, 100, -142, 104, 72, 100, -117, 82, 57, 100, -112, 83, 60, 100, -128, 118, 122, 100, -143, 141, 157, 100, -161, 160, 173, 100, -176, 176, 190, 100, -182, 182, 195, 100, -183, 184, 197, 100, -187, 186, 199, 100, -189, 187, 201, 100, -188, 187, 196, 100, -190, 189, 197, 100, -212, 176, 143, 100, -209, 173, 139, 100, -210, 175, 142, 100, -212, 176, 144, 100, -212, 176, 144, 100, -213, 176, 144, 100, -212, 176, 144, 100, -210, 176, 144, 100, -207, 177, 143, 100, -205, 176, 142, 100, -208, 175, 142, 100, -209, 175, 142, 100, -207, 176, 141, 100, -207, 177, 143, 100, -198, 171, 138, 100, -175, 153, 126, 100, -155, 143, 123, 100, -143, 140, 128, 100, -59, 59, 55, 100, -14, 12, 12, 100, -33, 29, 28, 100, -128, 121, 112, 100, -159, 151, 140, 100, -102, 95, 86, 100, -89, 84, 76, 100, -142, 138, 129, 100, -155, 151, 141, 100, -137, 133, 124, 100, -119, 115, 106, 100, -143, 139, 130, 100, -145, 141, 131, 100, -131, 127, 119, 100, -125, 121, 114, 100, -114, 110, 102, 100, -110, 104, 98, 100, -117, 112, 106, 100, -121, 116, 108, 100, -117, 110, 103, 100, -137, 131, 123, 100, -138, 133, 125, 100, -137, 132, 124, 100, -146, 141, 131, 100, -138, 130, 117, 100, -113, 84, 66, 100, -92, 57, 43, 100, -79, 47, 38, 100, -80, 46, 38, 100, -89, 54, 49, 100, -93, 58, 54, 100, -92, 60, 58, 100, -89, 58, 55, 100, -92, 60, 57, 100, -107, 72, 69, 100, -119, 80, 81, 100, -117, 74, 77, 100, -114, 72, 72, 100, -109, 63, 57, 100, -110, 61, 56, 100, -116, 67, 60, 100, -126, 77, 64, 100, -136, 86, 69, 100, -152, 103, 80, 100, -154, 104, 76, 100, -154, 106, 69, 100, -168, 124, 75, 100, -181, 139, 87, 100, -187, 146, 94, 100, -187, 150, 99, 100, -192, 155, 108, 100, -193, 156, 110, 100, -195, 158, 113, 100, -195, 158, 114, 100, -198, 160, 120, 100, -198, 161, 121, 100, -199, 162, 123, 100, -202, 165, 127, 100, -201, 163, 125, 100, -200, 163, 125, 100, -198, 161, 123, 100, -196, 159, 120, 100, -195, 157, 117, 100, -192, 155, 112, 100, -186, 149, 107, 100, -182, 144, 103, 100, -178, 138, 95, 100, -175, 131, 88, 100, -173, 128, 86, 100, -172, 128, 86, 100, -173, 128, 86, 100, -173, 128, 86, 100, -172, 128, 85, 100, -172, 127, 81, 100, -171, 123, 77, 100, -170, 121, 77, 100, -171, 123, 79, 100, -171, 126, 83, 100, -173, 127, 85, 100, -174, 129, 89, 100, -173, 129, 88, 100, -172, 126, 87, 100, -171, 125, 86, 100, -169, 122, 85, 100, -165, 120, 82, 100, -159, 113, 77, 100, -156, 110, 74, 100, -152, 106, 71, 100, -148, 104, 69, 100, -141, 101, 69, 100, -120, 84, 58, 100, -110, 81, 59, 100, -126, 116, 118, 100, -141, 140, 156, 100, -161, 159, 172, 100, -176, 174, 187, 100, -182, 180, 194, 100, -184, 182, 196, 100, -187, 186, 199, 100, -186, 186, 200, 100, -187, 186, 199, 100, -189, 187, 194, 100, -213, 176, 146, 100, -214, 177, 146, 100, -213, 177, 145, 100, -212, 176, 143, 100, -212, 176, 143, 100, -212, 176, 144, 100, -211, 175, 143, 100, -212, 176, 143, 100, -211, 177, 144, 100, -211, 177, 145, 100, -210, 175, 143, 100, -210, 176, 144, 100, -208, 177, 144, 100, -206, 177, 143, 100, -208, 177, 143, 100, -210, 178, 145, 100, -207, 176, 143, 100, -202, 177, 148, 100, -160, 144, 122, 100, -86, 75, 59, 100, -135, 124, 110, 100, -154, 146, 133, 100, -117, 108, 97, 100, -122, 113, 101, 100, -138, 131, 119, 100, -150, 143, 131, 100, -148, 141, 130, 100, -138, 133, 124, 100, -136, 131, 123, 100, -137, 132, 124, 100, -120, 116, 107, 100, -121, 115, 107, 100, -110, 105, 98, 100, -111, 106, 99, 100, -117, 112, 105, 100, -112, 107, 100, 100, -112, 107, 100, 100, -125, 121, 113, 100, -136, 131, 123, 100, -131, 126, 120, 100, -130, 125, 118, 100, -129, 125, 115, 100, -130, 117, 100, 100, -137, 102, 69, 100, -136, 100, 66, 100, -106, 71, 48, 100, -77, 42, 31, 100, -78, 43, 34, 100, -89, 56, 48, 100, -91, 60, 54, 100, -87, 57, 52, 100, -90, 58, 56, 100, -99, 65, 62, 100, -110, 74, 72, 100, -123, 83, 82, 100, -115, 74, 75, 100, -106, 64, 62, 100, -111, 67, 59, 100, -116, 68, 62, 100, -121, 70, 61, 100, -129, 75, 63, 100, -135, 81, 66, 100, -144, 92, 68, 100, -149, 98, 66, 100, -170, 125, 80, 100, -194, 152, 100, 100, -194, 154, 102, 100, -196, 160, 108, 100, -199, 163, 116, 100, -200, 163, 118, 100, -199, 163, 121, 100, -200, 164, 124, 100, -202, 167, 130, 100, -203, 168, 132, 100, -205, 169, 135, 100, -206, 170, 135, 100, -204, 169, 132, 100, -203, 168, 131, 100, -202, 167, 130, 100, -200, 164, 127, 100, -200, 163, 124, 100, -198, 161, 120, 100, -196, 158, 116, 100, -193, 155, 114, 100, -190, 152, 109, 100, -187, 147, 103, 100, -183, 141, 97, 100, -179, 136, 92, 100, -175, 131, 89, 100, -174, 129, 86, 100, -173, 129, 84, 100, -173, 129, 83, 100, -175, 128, 83, 100, -175, 127, 80, 100, -175, 126, 80, 100, -176, 126, 83, 100, -176, 127, 84, 100, -176, 127, 84, 100, -175, 128, 87, 100, -175, 126, 84, 100, -172, 123, 81, 100, -169, 120, 81, 100, -165, 118, 79, 100, -160, 113, 75, 100, -155, 109, 74, 100, -153, 107, 73, 100, -146, 100, 67, 100, -136, 95, 64, 100, -119, 82, 56, 100, -111, 82, 62, 100, -125, 114, 118, 100, -137, 135, 150, 100, -158, 156, 169, 100, -176, 174, 187, 100, -180, 180, 191, 100, -183, 181, 192, 100, -180, 176, 183, 100, -184, 172, 169, 100, -192, 171, 157, 100, -193, 166, 144, 100, -208, 171, 142, 100, -210, 173, 143, 100, -211, 175, 144, 100, -211, 175, 143, 100, -210, 173, 142, 100, -210, 174, 141, 100, -209, 172, 141, 100, -209, 172, 141, 100, -213, 177, 146, 100, -214, 178, 146, 100, -212, 175, 143, 100, -211, 177, 145, 100, -209, 177, 145, 100, -209, 177, 144, 100, -208, 177, 143, 100, -207, 178, 144, 100, -208, 177, 143, 100, -208, 176, 142, 100, -211, 180, 145, 100, -213, 184, 149, 100, -182, 160, 130, 100, -160, 144, 118, 100, -127, 114, 97, 100, -131, 120, 108, 100, -146, 138, 127, 100, -149, 141, 131, 100, -152, 143, 132, 100, -153, 146, 135, 100, -156, 150, 140, 100, -152, 147, 139, 100, -144, 140, 131, 100, -141, 136, 127, 100, -139, 134, 125, 100, -139, 135, 126, 100, -139, 135, 126, 100, -138, 134, 125, 100, -147, 142, 133, 100, -149, 145, 136, 100, -141, 137, 128, 100, -136, 131, 123, 100, -131, 127, 118, 100, -128, 124, 116, 100, -119, 96, 74, 100, -128, 90, 55, 100, -136, 101, 66, 100, -145, 108, 75, 100, -157, 117, 90, 100, -125, 86, 66, 100, -88, 50, 39, 100, -79, 45, 35, 100, -82, 51, 43, 100, -81, 50, 45, 100, -87, 56, 51, 100, -98, 64, 60, 100, -107, 71, 69, 100, -110, 73, 72, 100, -106, 67, 67, 100, -110, 69, 64, 100, -121, 75, 64, 100, -129, 79, 70, 100, -133, 80, 71, 100, -132, 78, 65, 100, -139, 88, 69, 100, -141, 92, 67, 100, -142, 95, 61, 100, -189, 146, 97, 100, -196, 157, 104, 100, -196, 159, 108, 100, -198, 162, 114, 100, -199, 163, 120, 100, -197, 163, 124, 100, -201, 166, 129, 100, -205, 169, 134, 100, -205, 169, 136, 100, -207, 171, 138, 100, -209, 172, 140, 100, -209, 173, 140, 100, -210, 174, 142, 100, -209, 173, 141, 100, -207, 171, 137, 100, -203, 168, 131, 100, -201, 165, 127, 100, -201, 164, 124, 100, -199, 162, 120, 100, -196, 158, 117, 100, -195, 157, 114, 100, -194, 154, 112, 100, -192, 151, 109, 100, -188, 145, 102, 100, -182, 138, 94, 100, -175, 131, 83, 100, -172, 127, 77, 100, -174, 125, 81, 100, -174, 125, 82, 100, -174, 125, 82, 100, -175, 126, 83, 100, -175, 126, 83, 100, -176, 126, 84, 100, -176, 127, 84, 100, -178, 130, 83, 100, -176, 127, 82, 100, -173, 125, 81, 100, -170, 120, 78, 100, -163, 115, 75, 100, -157, 112, 71, 100, -152, 106, 68, 100, -144, 99, 64, 100, -137, 96, 62, 100, -118, 81, 54, 100, -106, 77, 59, 100, -122, 113, 119, 100, -134, 131, 147, 100, -150, 143, 152, 100, -169, 158, 160, 100, -181, 165, 157, 100, -184, 158, 140, 100, -188, 156, 130, 100, -198, 162, 131, 100, -200, 162, 130, 100, -201, 163, 132, 100, -207, 170, 141, 100, -208, 171, 142, 100, -206, 168, 140, 100, -205, 168, 139, 100, -207, 170, 141, 100, -208, 171, 142, 100, -209, 172, 143, 100, -206, 170, 139, 100, -205, 168, 139, 100, -209, 172, 143, 100, -210, 173, 143, 100, -209, 173, 143, 100, -207, 175, 142, 100, -208, 177, 144, 100, -208, 177, 146, 100, -208, 176, 143, 100, -211, 179, 146, 100, -210, 177, 144, 100, -207, 177, 143, 100, -206, 174, 142, 100, -208, 177, 145, 100, -204, 176, 144, 100, -199, 176, 143, 100, -185, 166, 138, 100, -158, 146, 124, 100, -141, 131, 119, 100, -135, 126, 115, 100, -134, 126, 116, 100, -137, 129, 119, 100, -137, 130, 123, 100, -137, 131, 123, 100, -141, 135, 127, 100, -147, 140, 132, 100, -148, 143, 134, 100, -145, 141, 130, 100, -136, 132, 121, 100, -129, 124, 115, 100, -129, 124, 117, 100, -135, 130, 124, 100, -146, 142, 132, 100, -146, 143, 132, 100, -135, 130, 118, 100, -113, 86, 63, 100, -130, 93, 60, 100, -126, 91, 59, 100, -167, 124, 95, 100, -188, 145, 117, 100, -182, 140, 112, 100, -159, 113, 91, 100, -113, 73, 57, 100, -72, 39, 30, 100, -75, 45, 36, 100, -79, 48, 41, 100, -89, 57, 53, 100, -97, 64, 61, 100, -98, 64, 62, 100, -109, 75, 76, 100, -113, 72, 77, 100, -125, 83, 79, 100, -135, 90, 77, 100, -133, 85, 72, 100, -137, 87, 73, 100, -147, 98, 80, 100, -146, 99, 76, 100, -140, 93, 66, 100, -157, 112, 73, 100, -196, 155, 103, 100, -197, 160, 109, 100, -198, 163, 115, 100, -195, 161, 117, 100, -201, 166, 128, 100, -206, 170, 135, 100, -206, 171, 138, 100, -204, 172, 140, 100, -209, 177, 146, 100, -210, 177, 144, 100, -209, 175, 143, 100, -209, 175, 142, 100, -211, 176, 143, 100, -211, 175, 142, 100, -207, 171, 136, 100, -205, 169, 133, 100, -203, 169, 130, 100, -202, 166, 126, 100, -199, 163, 121, 100, -196, 159, 117, 100, -194, 157, 116, 100, -194, 156, 115, 100, -192, 151, 108, 100, -189, 145, 102, 100, -183, 139, 91, 100, -176, 132, 82, 100, -173, 125, 79, 100, -170, 121, 76, 100, -168, 118, 75, 100, -167, 117, 75, 100, -168, 119, 76, 100, -169, 120, 77, 100, -172, 123, 79, 100, -173, 124, 79, 100, -174, 125, 81, 100, -173, 124, 81, 100, -173, 124, 82, 100, -168, 121, 79, 100, -162, 118, 75, 100, -156, 111, 71, 100, -146, 102, 66, 100, -133, 92, 58, 100, -111, 73, 47, 100, -113, 82, 62, 100, -142, 126, 116, 100, -159, 138, 124, 100, -182, 153, 129, 100, -187, 153, 124, 100, -191, 154, 120, 100, -195, 157, 122, 100, -199, 161, 129, 100, -198, 162, 131, 100, -198, 161, 133, 100, -198, 161, 132, 100, -206, 169, 141, 100, -204, 167, 138, 100, -200, 163, 133, 100, -202, 165, 136, 100, -205, 169, 140, 100, -208, 170, 142, 100, -205, 168, 139, 100, -205, 168, 139, 100, -201, 164, 135, 100, -202, 165, 135, 100, -202, 166, 134, 100, -204, 168, 136, 100, -209, 173, 142, 100, -207, 173, 143, 100, -210, 173, 144, 100, -212, 176, 145, 100, -211, 176, 143, 100, -210, 176, 143, 100, -209, 177, 144, 100, -209, 178, 145, 100, -207, 176, 144, 100, -203, 172, 140, 100, -203, 172, 140, 100, -205, 176, 143, 100, -200, 173, 139, 100, -182, 160, 129, 100, -151, 135, 112, 100, -133, 120, 106, 100, -120, 109, 98, 100, -113, 105, 96, 100, -108, 98, 93, 100, -103, 93, 87, 100, -105, 97, 89, 100, -111, 104, 98, 100, -122, 115, 107, 100, -133, 128, 117, 100, -131, 124, 116, 100, -115, 109, 102, 100, -97, 93, 88, 100, -87, 81, 79, 100, -103, 97, 95, 100, -112, 106, 96, 100, -108, 81, 57, 100, -118, 80, 50, 100, -119, 82, 53, 100, -177, 132, 107, 100, -182, 140, 115, 100, -175, 134, 109, 100, -178, 136, 108, 100, -186, 144, 115, 100, -133, 93, 73, 100, -73, 40, 30, 100, -75, 44, 36, 100, -78, 47, 42, 100, -87, 56, 52, 100, -92, 61, 58, 100, -106, 74, 77, 100, -119, 81, 88, 100, -121, 79, 81, 100, -130, 86, 78, 100, -141, 96, 80, 100, -151, 104, 87, 100, -148, 100, 82, 100, -128, 79, 60, 100, -120, 72, 50, 100, -126, 80, 52, 100, -161, 117, 76, 100, -198, 161, 110, 100, -197, 161, 114, 100, -196, 161, 117, 100, -196, 161, 122, 100, -195, 160, 125, 100, -193, 160, 126, 100, -199, 167, 136, 100, -200, 169, 137, 100, -198, 168, 134, 100, -199, 169, 135, 100, -199, 168, 134, 100, -198, 165, 133, 100, -203, 171, 137, 100, -204, 170, 136, 100, -206, 170, 136, 100, -205, 169, 134, 100, -204, 169, 132, 100, -205, 170, 133, 100, -204, 169, 130, 100, -202, 165, 125, 100, -199, 162, 122, 100, -199, 158, 118, 100, -195, 153, 111, 100, -190, 147, 103, 100, -186, 142, 97, 100, -180, 136, 91, 100, -174, 129, 82, 100, -170, 122, 78, 100, -165, 117, 73, 100, -164, 115, 71, 100, -161, 112, 69, 100, -161, 112, 70, 100, -159, 109, 70, 100, -163, 113, 73, 100, -166, 118, 78, 100, -164, 118, 79, 100, -164, 119, 80, 100, -161, 117, 76, 100, -156, 111, 73, 100, -156, 112, 77, 100, -156, 117, 86, 100, -165, 128, 99, 100, -184, 147, 118, 100, -191, 154, 123, 100, -202, 164, 132, 100, -201, 163, 132, 100, -198, 161, 132, 100, -200, 163, 136, 100, -196, 159, 131, 100, -193, 157, 127, 100, -192, 156, 126, 100, -202, 165, 136, 100, -202, 165, 136, 100, -204, 167, 141, 100, -202, 165, 139, 100, -205, 168, 139, 100, -204, 167, 138, 100, -201, 164, 135, 100, -200, 162, 133, 100, -202, 165, 136, 100, -205, 168, 139, 100, -206, 169, 139, 100, -209, 172, 143, 100, -207, 171, 142, 100, -209, 172, 143, 100, -209, 171, 143, 100, -203, 166, 137, 100, -205, 168, 139, 100, -208, 171, 142, 100, -203, 166, 136, 100, -207, 172, 140, 100, -210, 175, 145, 100, -208, 175, 143, 100, -205, 174, 140, 100, -208, 176, 142, 100, -205, 174, 142, 100, -206, 175, 145, 100, -204, 175, 142, 100, -202, 172, 138, 100, -206, 177, 142, 100, -202, 176, 142, 100, -182, 162, 131, 100, -153, 138, 115, 100, -140, 128, 113, 100, -137, 129, 117, 100, -123, 116, 106, 100, -106, 98, 92, 100, -93, 85, 82, 100, -92, 84, 79, 100, -112, 104, 98, 100, -129, 122, 114, 100, -128, 122, 113, 100, -88, 82, 81, 100, -43, 40, 49, 100, -67, 61, 63, 100, -97, 70, 48, 100, -96, 61, 36, 100, -118, 79, 56, 100, -178, 136, 113, 100, -185, 144, 125, 100, -173, 132, 111, 100, -175, 136, 111, 100, -179, 139, 113, 100, -189, 148, 117, 100, -138, 95, 72, 100, -76, 41, 31, 100, -77, 47, 38, 100, -80, 49, 44, 100, -89, 58, 55, 100, -103, 72, 73, 100, -121, 86, 93, 100, -123, 83, 85, 100, -119, 75, 74, 100, -126, 81, 70, 100, -138, 89, 73, 100, -119, 70, 55, 100, -115, 67, 47, 100, -121, 73, 53, 100, -117, 72, 49, 100, -123, 79, 51, 100, -163, 123, 82, 100, -187, 150, 101, 100, -183, 147, 103, 100, -188, 153, 112, 100, -188, 153, 114, 100, -189, 153, 119, 100, -186, 151, 118, 100, -185, 152, 119, 100, -187, 157, 123, 100, -190, 160, 126, 100, -184, 154, 120, 100, -183, 153, 121, 100, -189, 158, 125, 100, -197, 165, 134, 100, -200, 169, 137, 100, -199, 168, 135, 100, -199, 167, 135, 100, -203, 168, 134, 100, -203, 167, 132, 100, -203, 168, 132, 100, -202, 166, 129, 100, -199, 161, 123, 100, -197, 159, 119, 100, -196, 155, 115, 100, -193, 151, 110, 100, -190, 146, 104, 100, -187, 144, 99, 100, -183, 139, 94, 100, -177, 134, 86, 100, -173, 127, 82, 100, -168, 120, 76, 100, -157, 110, 68, 100, -145, 96, 58, 100, -140, 91, 54, 100, -145, 99, 62, 100, -153, 108, 71, 100, -166, 123, 85, 100, -174, 135, 98, 100, -181, 144, 108, 100, -193, 156, 123, 100, -193, 156, 126, 100, -197, 160, 131, 100, -198, 161, 132, 100, -189, 152, 124, 100, -187, 150, 122, 100, -184, 147, 119, 100, -196, 159, 132, 100, -196, 159, 133, 100, -196, 159, 133, 100, -197, 160, 132, 100, -197, 160, 131, 100, -194, 156, 127, 100, -194, 157, 127, 100, -201, 166, 140, 100, -201, 166, 140, 100, -202, 167, 140, 100, -204, 168, 140, 100, -198, 163, 135, 100, -196, 161, 133, 100, -202, 166, 139, 100, -204, 167, 140, 100, -207, 170, 143, 100, -209, 172, 145, 100, -210, 172, 146, 100, -208, 172, 145, 100, -207, 172, 142, 100, -207, 170, 141, 100, -205, 168, 139, 100, -204, 167, 138, 100, -204, 167, 138, 100, -210, 172, 143, 100, -211, 174, 145, 100, -209, 173, 143, 100, -207, 171, 141, 100, -205, 174, 141, 100, -204, 173, 140, 100, -206, 176, 143, 100, -203, 173, 139, 100, -199, 169, 135, 100, -199, 169, 135, 100, -202, 173, 139, 100, -204, 174, 139, 100, -199, 171, 138, 100, -191, 167, 136, 100, -181, 162, 134, 100, -164, 153, 132, 100, -148, 140, 124, 100, -130, 123, 112, 100, -102, 95, 88, 100, -76, 69, 65, 100, -72, 65, 61, 100, -104, 96, 89, 100, -130, 121, 112, 100, -114, 107, 101, 100, -102, 95, 87, 100, -83, 58, 42, 100, -79, 46, 26, 100, -124, 86, 67, 100, -190, 151, 130, 100, -190, 150, 134, 100, -173, 133, 114, 100, -175, 136, 114, 100, -177, 136, 116, 100, -177, 135, 109, 100, -175, 124, 95, 100, -120, 78, 67, 100, -77, 45, 39, 100, -81, 50, 44, 100, -87, 56, 52, 100, -96, 65, 63, 100, -114, 79, 86, 100, -119, 80, 85, 100, -119, 77, 76, 100, -119, 75, 67, 100, -119, 70, 58, 100, -119, 71, 56, 100, -122, 75, 57, 100, -117, 70, 51, 100, -113, 71, 49, 100, -120, 79, 56, 100, -124, 82, 54, 100, -168, 123, 87, 100, -188, 143, 106, 100, -171, 133, 92, 100, -174, 140, 98, 100, -189, 154, 115, 100, -180, 144, 109, 100, -171, 138, 104, 100, -158, 129, 94, 100, -150, 120, 86, 100, -165, 134, 101, 100, -185, 154, 123, 100, -186, 155, 124, 100, -197, 167, 136, 100, -200, 169, 138, 100, -201, 170, 139, 100, -197, 167, 136, 100, -200, 165, 133, 100, -198, 162, 128, 100, -200, 164, 130, 100, -199, 161, 127, 100, -197, 159, 122, 100, -196, 158, 120, 100, -197, 159, 120, 100, -197, 157, 118, 100, -196, 156, 116, 100, -195, 154, 113, 100, -192, 152, 109, 100, -190, 149, 107, 100, -187, 146, 102, 100, -184, 142, 98, 100, -174, 132, 90, 100, -164, 123, 83, 100, -163, 121, 86, 100, -178, 136, 102, 100, -188, 149, 115, 100, -197, 160, 128, 100, -193, 156, 126, 100, -188, 152, 122, 100, -188, 152, 121, 100, -192, 155, 127, 100, -196, 159, 132, 100, -196, 159, 132, 100, -174, 137, 108, 100, -176, 139, 109, 100, -192, 155, 128, 100, -196, 159, 133, 100, -194, 157, 130, 100, -197, 160, 134, 100, -195, 158, 132, 100, -192, 155, 129, 100, -190, 153, 126, 100, -184, 148, 120, 100, -200, 166, 141, 100, -198, 165, 140, 100, -195, 163, 137, 100, -195, 163, 138, 100, -195, 163, 136, 100, -193, 161, 134, 100, -204, 171, 145, 100, -202, 166, 141, 100, -203, 166, 141, 100, -205, 170, 144, 100, -204, 168, 142, 100, -203, 168, 141, 100, -203, 170, 142, 100, -201, 165, 137, 100, -203, 166, 139, 100, -205, 171, 142, 100, -209, 175, 144, 100, -210, 174, 146, 100, -207, 173, 144, 100, -209, 174, 144, 100, -210, 173, 144, 100, -208, 172, 142, 100, -205, 169, 139, 100, -203, 168, 137, 100, -202, 169, 138, 100, -205, 170, 139, 100, -200, 168, 134, 100, -202, 169, 137, 100, -206, 173, 140, 100, -203, 172, 139, 100, -203, 173, 139, 100, -205, 174, 139, 100, -199, 171, 136, 100, -190, 166, 134, 100, -173, 154, 127, 100, -150, 137, 114, 100, -127, 118, 100, 100, -78, 69, 62, 100, -36, 31, 32, 100, -54, 46, 47, 100, -86, 77, 71, 100, -91, 81, 72, 100, -74, 54, 40, 100, -66, 35, 16, 100, -132, 96, 75, 100, -196, 157, 139, 100, -191, 152, 135, 100, -171, 132, 117, 100, -162, 122, 113, 100, -154, 114, 106, 100, -147, 105, 92, 100, -139, 90, 76, 100, -137, 98, 93, 100, -93, 61, 58, 100, -75, 45, 40, 100, -83, 52, 47, 100, -85, 54, 50, 100, -101, 67, 69, 100, -114, 77, 82, 100, -116, 77, 77, 100, -118, 77, 72, 100, -118, 76, 64, 100, -115, 71, 57, 100, -118, 74, 59, 100, -119, 77, 59, 100, -115, 74, 55, 100, -114, 73, 52, 100, -113, 73, 47, 100, -133, 89, 63, 100, -178, 115, 95, 100, -180, 119, 90, 100, -163, 125, 83, 100, -149, 115, 75, 100, -142, 106, 72, 100, -147, 112, 77, 100, -149, 117, 83, 100, -162, 129, 96, 100, -177, 145, 113, 100, -183, 152, 121, 100, -185, 153, 122, 100, -189, 157, 125, 100, -197, 165, 133, 100, -200, 167, 137, 100, -198, 165, 134, 100, -197, 160, 129, 100, -194, 158, 125, 100, -193, 157, 123, 100, -193, 154, 120, 100, -197, 159, 122, 100, -197, 160, 122, 100, -198, 161, 122, 100, -200, 162, 123, 100, -198, 161, 120, 100, -193, 156, 115, 100, -193, 155, 115, 100, -190, 153, 114, 100, -189, 151, 112, 100, -190, 153, 116, 100, -192, 155, 118, 100, -198, 162, 128, 100, -198, 162, 129, 100, -197, 161, 132, 100, -194, 157, 129, 100, -187, 150, 121, 100, -193, 156, 127, 100, -190, 153, 126, 100, -192, 155, 129, 100, -195, 158, 132, 100, -197, 160, 134, 100, -186, 149, 124, 100, -182, 145, 118, 100, -178, 141, 115, 100, -184, 147, 119, 100, -185, 148, 121, 100, -185, 148, 121, 100, -187, 150, 124, 100, -187, 150, 124, 100, -184, 147, 119, 100, -178, 141, 114, 100, -183, 146, 119, 100, -193, 161, 136, 100, -192, 160, 136, 100, -194, 161, 140, 100, -197, 163, 142, 100, -197, 165, 140, 100, -193, 161, 137, 100, -197, 164, 139, 100, -199, 166, 140, 100, -198, 164, 139, 100, -195, 162, 136, 100, -201, 169, 142, 100, -207, 174, 147, 100, -198, 164, 138, 100, -200, 167, 140, 100, -201, 170, 141, 100, -205, 172, 145, 100, -208, 176, 148, 100, -208, 174, 147, 100, -211, 175, 149, 100, -210, 173, 147, 100, -204, 167, 139, 100, -201, 164, 136, 100, -206, 169, 140, 100, -204, 167, 138, 100, -200, 163, 134, 100, -203, 167, 137, 100, -204, 168, 137, 100, -207, 170, 140, 100, -209, 174, 142, 100, -208, 174, 142, 100, -205, 172, 140, 100, -204, 172, 140, 100, -206, 172, 140, 100, -206, 173, 139, 100, -204, 173, 138, 100, -202, 171, 137, 100, -195, 170, 135, 100, -181, 158, 126, 100, -141, 124, 101, 100, -84, 70, 61, 100, -73, 60, 52, 100, -70, 57, 50, 100, -49, 31, 24, 100, -68, 38, 19, 100, -157, 117, 98, 100, -195, 156, 138, 100, -187, 148, 133, 100, -155, 114, 108, 100, -144, 102, 103, 100, -141, 102, 102, 100, -126, 85, 83, 100, -111, 70, 70, 100, -122, 88, 89, 100, -107, 73, 77, 100, -83, 52, 52, 100, -74, 43, 37, 100, -79, 48, 44, 100, -86, 55, 52, 100, -100, 66, 69, 100, -111, 75, 76, 100, -112, 74, 72, 100, -114, 73, 64, 100, -120, 79, 66, 100, -118, 76, 60, 100, -121, 78, 63, 100, -121, 80, 63, 100, -121, 80, 58, 100, -124, 83, 57, 100, -131, 91, 62, 100, -139, 83, 61, 100, -165, 87, 70, 100, -153, 102, 65, 100, -136, 100, 61, 100, -152, 116, 78, 100, -144, 108, 73, 100, -155, 119, 88, 100, -174, 139, 107, 100, -183, 149, 117, 100, -187, 154, 123, 100, -193, 158, 127, 100, -194, 158, 127, 100, -194, 159, 128, 100, -194, 159, 125, 100, -194, 158, 125, 100, -193, 157, 123, 100, -192, 157, 122, 100, -191, 155, 120, 100, -190, 154, 120, 100, -192, 156, 120, 100, -197, 162, 124, 100, -198, 162, 123, 100, -199, 161, 124, 100, -189, 153, 115, 100, -187, 152, 114, 100, -189, 153, 118, 100, -192, 156, 124, 100, -190, 153, 124, 100, -191, 154, 126, 100, -197, 161, 129, 100, -194, 157, 127, 100, -192, 155, 127, 100, -188, 151, 123, 100, -185, 148, 120, 100, -181, 144, 118, 100, -183, 147, 121, 100, -184, 148, 122, 100, -192, 158, 131, 100, -189, 152, 126, 100, -185, 147, 123, 100, -185, 147, 122, 100, -178, 141, 114, 100, -170, 133, 107, 100, -178, 141, 115, 100, -178, 141, 115, 100, -186, 149, 123, 100, -194, 157, 130, 100, -186, 149, 124, 100, -179, 141, 115, 100, -182, 145, 120, 100, -185, 146, 123, 100, -190, 157, 137, 100, -195, 162, 143, 100, -203, 168, 150, 100, -203, 169, 149, 100, -194, 161, 142, 100, -192, 160, 138, 100, -197, 164, 140, 100, -199, 167, 144, 100, -194, 162, 139, 100, -195, 163, 138, 100, -206, 174, 149, 100, -206, 174, 148, 100, -198, 166, 141, 100, -196, 164, 138, 100, -196, 165, 139, 100, -205, 174, 147, 100, -206, 172, 145, 100, -211, 175, 149, 100, -208, 171, 145, 100, -204, 167, 141, 100, -200, 163, 136, 100, -202, 165, 138, 100, -203, 166, 137, 100, -200, 163, 134, 100, -193, 157, 127, 100, -203, 166, 137, 100, -208, 171, 143, 100, -209, 172, 143, 100, -206, 169, 140, 100, -208, 170, 142, 100, -208, 174, 144, 100, -210, 175, 145, 100, -211, 174, 144, 100, -209, 173, 142, 100, -207, 174, 141, 100, -203, 172, 137, 100, -204, 170, 136, 100, -206, 173, 136, 100, -205, 174, 136, 100, -207, 177, 141, 100, -193, 166, 131, 100, -176, 149, 119, 100, -162, 135, 108, 100, -153, 119, 90, 100, -165, 122, 101, 100, -195, 155, 138, 100, -174, 135, 123, 100, -143, 102, 100, 100, -140, 98, 100, 100, -137, 96, 98, 100, -115, 73, 75, 100, -105, 64, 69, 100, -118, 81, 87, 100, -111, 74, 84, 100, -103, 74, 91, 100, -78, 48, 52, 100, -80, 49, 45, 100, -80, 49, 46, 100, -83, 51, 50, 100, -91, 58, 58, 100, -100, 68, 65, 100, -108, 70, 66, 100, -108, 68, 59, 100, -116, 75, 60, 100, -127, 84, 69, 100, -135, 91, 71, 100, -138, 96, 71, 100, -138, 95, 69, 100, -136, 95, 67, 100, -134, 91, 62, 100, -133, 70, 46, 100, -158, 104, 68, 100, -166, 127, 86, 100, -167, 129, 91, 100, -164, 127, 93, 100, -171, 133, 101, 100, -176, 139, 106, 100, -186, 150, 120, 100, -190, 155, 123, 100, -192, 156, 124, 100, -195, 159, 126, 100, -195, 159, 125, 100, -192, 157, 119, 100, -192, 158, 119, 100, -193, 158, 120, 100, -192, 157, 119, 100, -192, 157, 119, 100, -194, 159, 121, 100, -191, 156, 118, 100, -190, 155, 117, 100, -189, 154, 116, 100, -182, 147, 110, 100, -182, 146, 111, 100, -191, 155, 123, 100, -189, 152, 122, 100, -192, 155, 126, 100, -186, 149, 120, 100, -188, 151, 122, 100, -189, 152, 124, 100, -192, 155, 127, 100, -196, 159, 132, 100, -192, 155, 129, 100, -184, 147, 121, 100, -189, 153, 129, 100, -189, 156, 131, 100, -188, 153, 129, 100, -190, 154, 130, 100, -189, 151, 127, 100, -188, 150, 127, 100, -181, 143, 118, 100, -179, 142, 117, 100, -181, 144, 118, 100, -178, 140, 114, 100, -182, 145, 118, 100, -193, 156, 131, 100, -193, 155, 133, 100, -192, 153, 133, 100, -188, 150, 129, 100, -183, 145, 122, 100, -193, 156, 135, 100, -196, 163, 145, 100, -197, 164, 145, 100, -197, 163, 144, 100, -194, 161, 142, 100, -193, 162, 142, 100, -193, 160, 140, 100, -197, 164, 145, 100, -203, 171, 151, 100, -200, 168, 148, 100, -198, 166, 145, 100, -200, 168, 145, 100, -203, 171, 149, 100, -206, 174, 151, 100, -194, 162, 139, 100, -192, 160, 135, 100, -206, 174, 149, 100, -200, 167, 142, 100, -205, 169, 143, 100, -202, 165, 139, 100, -202, 165, 139, 100, -201, 164, 138, 100, -202, 165, 138, 100, -203, 166, 139, 100, -197, 160, 133, 100, -205, 168, 140, 100, -208, 171, 142, 100, -207, 170, 141, 100, -202, 165, 136, 100, -206, 170, 141, 100, -206, 171, 141, 100, -208, 172, 143, 100, -211, 174, 145, 100, -210, 173, 144, 100, -208, 171, 142, 100, -206, 170, 138, 100, -204, 173, 140, 100, -200, 167, 134, 100, -200, 168, 134, 100, -193, 163, 129, 100, -196, 166, 132, 100, -202, 172, 138, 100, -199, 169, 134, 100, -196, 165, 130, 100, -182, 146, 113, 100, -167, 127, 104, 100, -191, 150, 135, 100, -163, 124, 115, 100, -139, 97, 95, 100, -137, 93, 95, 100, -129, 87, 93, 100, -109, 65, 71, 100, -106, 65, 71, 100, -120, 83, 93, 100, -114, 75, 86, 100, -116, 86, 108, 100, -90, 58, 76, 100, -76, 46, 44, 100, -80, 50, 45, 100, -78, 49, 45, 100, -83, 54, 50, 100, -97, 67, 63, 100, -108, 74, 71, 100, -112, 73, 65, 100, -126, 85, 73, 100, -131, 89, 72, 100, -139, 94, 74, 100, -141, 96, 73, 100, -129, 85, 63, 100, -129, 85, 63, 100, -131, 86, 60, 100, -130, 84, 54, 100, -153, 107, 73, 100, -158, 115, 81, 100, -162, 120, 86, 100, -171, 130, 98, 100, -175, 135, 102, 100, -179, 141, 108, 100, -183, 147, 113, 100, -187, 151, 117, 100, -192, 156, 123, 100, -192, 156, 122, 100, -192, 156, 122, 100, -193, 157, 120, 100, -192, 157, 119, 100, -191, 156, 118, 100, -189, 154, 116, 100, -188, 153, 114, 100, -185, 150, 112, 100, -185, 150, 111, 100, -186, 150, 114, 100, -183, 147, 112, 100, -180, 144, 111, 100, -186, 150, 118, 100, -188, 151, 120, 100, -184, 147, 118, 100, -183, 146, 117, 100, -186, 149, 121, 100, -181, 144, 116, 100, -180, 143, 117, 100, -193, 156, 130, 100, -188, 150, 125, 100, -183, 146, 122, 100, -191, 153, 130, 100, -189, 151, 128, 100, -189, 153, 129, 100, -193, 156, 132, 100, -193, 155, 132, 100, -188, 150, 127, 100, -184, 146, 123, 100, -185, 147, 123, 100, -189, 151, 128, 100, -182, 144, 121, 100, -182, 146, 121, 100, -185, 148, 125, 100, -185, 147, 127, 100, -188, 151, 133, 100, -188, 152, 134, 100, -187, 149, 131, 100, -187, 148, 129, 100, -186, 148, 131, 100, -194, 161, 144, 100, -196, 163, 146, 100, -196, 163, 145, 100, -193, 163, 144, 100, -195, 166, 147, 100, -196, 166, 147, 100, -199, 168, 148, 100, -201, 168, 149, 100, -205, 172, 152, 100, -205, 172, 151, 100, -205, 171, 151, 100, -207, 174, 154, 100, -207, 175, 155, 100, -196, 164, 141, 100, -202, 170, 146, 100, -205, 174, 149, 100, -201, 169, 144, 100, -200, 165, 141, 100, -198, 164, 138, 100, -201, 166, 141, 100, -207, 170, 145, 100, -200, 163, 137, 100, -200, 164, 138, 100, -205, 170, 143, 100, -206, 171, 144, 100, -208, 171, 142, 100, -204, 167, 139, 100, -204, 167, 139, 100, -205, 168, 139, 100, -200, 164, 135, 100, -206, 169, 140, 100, -207, 171, 142, 100, -207, 170, 141, 100, -205, 168, 139, 100, -205, 168, 139, 100, -204, 168, 137, 100, -192, 158, 126, 100, -200, 166, 134, 100, -198, 167, 134, 100, -195, 165, 131, 100, -198, 168, 134, 100, -192, 162, 129, 100, -188, 156, 123, 100, -178, 142, 112, 100, -163, 125, 104, 100, -172, 132, 121, 100, -153, 112, 106, 100, -139, 95, 95, 100, -138, 93, 99, 100, -137, 99, 113, 100, -120, 78, 88, 100, -105, 65, 72, 100, -127, 94, 107, 100, -121, 87, 100, 100, -128, 95, 113, 100, -113, 80, 101, 100, -76, 44, 53, 100, -77, 48, 45, 100, -75, 46, 42, 100, -77, 48, 44, 100, -87, 58, 55, 100, -100, 68, 64, 100, -111, 74, 66, 100, -124, 84, 75, 100, -128, 88, 72, 100, -116, 74, 58, 100, -117, 73, 57, 100, -113, 71, 53, 100, -118, 75, 59, 100, -120, 74, 55, 100, -122, 77, 50, 100, -130, 87, 58, 100, -144, 99, 71, 100, -154, 109, 80, 100, -162, 117, 88, 100, -167, 126, 94, 100, -177, 138, 105, 100, -182, 144, 110, 100, -188, 152, 118, 100, -191, 155, 121, 100, -193, 157, 123, 100, -197, 161, 127, 100, -198, 162, 127, 100, -196, 160, 124, 100, -191, 156, 120, 100, -186, 151, 114, 100, -186, 150, 112, 100, -185, 149, 114, 100, -186, 150, 115, 100, -185, 149, 115, 100, -184, 148, 116, 100, -186, 150, 118, 100, -186, 150, 119, 100, -182, 145, 116, 100, -176, 139, 112, 100, -179, 142, 115, 100, -176, 139, 113, 100, -176, 139, 114, 100, -177, 140, 114, 100, -183, 146, 120, 100, -185, 147, 123, 100, -191, 153, 131, 100, -192, 154, 132, 100, -184, 146, 123, 100, -191, 153, 130, 100, -194, 156, 134, 100, -184, 146, 123, 100, -184, 146, 123, 100, -190, 152, 131, 100, -192, 156, 136, 100, -185, 148, 128, 100, -186, 148, 128, 100, -187, 152, 132, 100, -186, 148, 130, 100, -193, 155, 137, 100, -191, 157, 138, 100, -190, 154, 136, 100, -191, 152, 136, 100, -185, 145, 129, 100, -181, 143, 125, 100, -193, 160, 142, 100, -192, 159, 142, 100, -196, 163, 146, 100, -197, 165, 148, 100, -192, 161, 144, 100, -197, 167, 148, 100, -198, 167, 147, 100, -197, 164, 145, 100, -198, 166, 147, 100, -204, 170, 151, 100, -207, 172, 153, 100, -208, 175, 156, 100, -205, 171, 152, 100, -201, 168, 149, 100, -205, 172, 152, 100, -202, 170, 149, 100, -201, 169, 148, 100, -197, 165, 143, 100, -197, 165, 141, 100, -202, 170, 145, 100, -201, 167, 142, 100, -196, 161, 136, 100, -196, 162, 137, 100, -200, 166, 140, 100, -202, 168, 141, 100, -200, 164, 138, 100, -202, 165, 139, 100, -205, 168, 142, 100, -201, 165, 138, 100, -203, 166, 138, 100, -203, 168, 142, 100, -203, 169, 142, 100, -202, 166, 137, 100, -204, 167, 138, 100, -203, 166, 137, 100, -200, 162, 133, 100, -196, 160, 130, 100, -197, 165, 134, 100, -195, 165, 132, 100, -190, 160, 126, 100, -193, 161, 128, 100, -191, 158, 126, 100, -189, 156, 125, 100, -167, 130, 105, 100, -150, 109, 97, 100, -161, 125, 125, 100, -146, 107, 109, 100, -140, 95, 97, 100, -136, 91, 101, 100, -139, 110, 132, 100, -140, 104, 122, 100, -114, 73, 84, 100, -120, 88, 100, 100, -133, 103, 114, 100, -133, 100, 116, 100, -130, 97, 118, 100, -84, 50, 65, 100, -72, 41, 44, 100, -76, 47, 43, 100, -75, 47, 43, 100, -79, 51, 47, 100, -88, 58, 55, 100, -110, 74, 68, 100, -118, 78, 69, 100, -108, 68, 58, 100, -100, 60, 51, 100, -101, 61, 51, 100, -109, 69, 55, 100, -97, 58, 44, 100, -100, 57, 42, 100, -109, 66, 43, 100, -112, 71, 44, 100, -127, 85, 59, 100, -145, 102, 75, 100, -152, 106, 80, 100, -159, 115, 88, 100, -163, 124, 93, 100, -172, 132, 100, 100, -183, 144, 111, 100, -187, 150, 118, 100, -194, 158, 125, 100, -196, 160, 126, 100, -198, 162, 128, 100, -192, 156, 122, 100, -186, 150, 116, 100, -184, 148, 114, 100, -181, 145, 111, 100, -183, 147, 113, 100, -180, 145, 111, 100, -181, 145, 113, 100, -184, 147, 118, 100, -185, 148, 119, 100, -185, 148, 121, 100, -181, 144, 118, 100, -179, 142, 117, 100, -178, 140, 115, 100, -171, 133, 108, 100, -176, 138, 114, 100, -183, 146, 121, 100, -186, 148, 125, 100, -192, 154, 131, 100, -191, 154, 130, 100, -189, 151, 129, 100, -184, 146, 124, 100, -191, 153, 131, 100, -189, 151, 130, 100, -185, 147, 125, 100, -192, 154, 134, 100, -190, 152, 133, 100, -185, 148, 128, 100, -184, 146, 128, 100, -183, 146, 128, 100, -183, 145, 127, 100, -188, 149, 132, 100, -191, 152, 136, 100, -190, 154, 138, 100, -191, 156, 140, 100, -192, 153, 138, 100, -184, 146, 129, 100, -184, 147, 129, 100, -187, 155, 137, 100, -193, 160, 143, 100, -195, 162, 145, 100, -192, 158, 140, 100, -195, 162, 145, 100, -191, 158, 141, 100, -193, 160, 143, 100, -194, 161, 144, 100, -197, 167, 149, 100, -199, 168, 150, 100, -199, 167, 150, 100, -203, 169, 151, 100, -205, 172, 154, 100, -204, 171, 153, 100, -207, 174, 155, 100, -203, 170, 152, 100, -199, 167, 147, 100, -195, 162, 142, 100, -192, 159, 139, 100, -198, 166, 142, 100, -195, 162, 139, 100, -197, 164, 141, 100, -195, 162, 138, 100, -196, 162, 137, 100, -198, 166, 140, 100, -199, 167, 142, 100, -201, 168, 142, 100, -198, 165, 139, 100, -198, 166, 140, 100, -199, 166, 140, 100, -195, 162, 135, 100, -197, 166, 138, 100, -194, 162, 134, 100, -199, 164, 136, 100, -195, 159, 131, 100, -195, 160, 132, 100, -194, 160, 131, 100, -194, 162, 131, 100, -190, 159, 128, 100, -187, 155, 123, 100, -188, 154, 123, 100, -190, 157, 125, 100, -188, 155, 123, 100, -154, 116, 96, 100, -137, 93, 91, 100, -155, 124, 136, 100, -151, 122, 139, 100, -134, 93, 99, 100, -137, 97, 105, 100, -140, 109, 128, 100, -146, 118, 140, 100, -129, 90, 100, 100, -116, 80, 90, 100, -134, 104, 112, 100, -135, 104, 115, 100, -140, 108, 127, 100, -105, 70, 84, 100, -72, 39, 43, 100, -80, 51, 47, 100, -78, 50, 46, 100, -82, 54, 52, 100, -92, 62, 60, 100, -108, 69, 63, 100, -98, 57, 50, 100, -108, 68, 62, 100, -106, 66, 58, 100, -101, 61, 53, 100, -107, 67, 58, 100, -98, 59, 45, 100, -102, 60, 46, 100, -107, 66, 47, 100, -106, 66, 44, 100, -122, 82, 59, 100, -135, 95, 69, 100, -145, 103, 77, 100, -151, 106, 81, 100, -156, 117, 88, 100, -169, 130, 100, 100, -176, 135, 104, 100, -183, 145, 114, 100, -192, 156, 125, 100, -191, 155, 122, 100, -192, 157, 123, 100, -188, 152, 119, 100, -185, 149, 115, 100, -182, 146, 112, 100, -179, 143, 109, 100, -180, 144, 111, 100, -178, 142, 111, 100, -177, 140, 110, 100, -180, 143, 115, 100, -182, 145, 118, 100, -181, 144, 118, 100, -181, 144, 118, 100, -184, 146, 122, 100, -182, 144, 121, 100, -179, 141, 118, 100, -177, 139, 116, 100, -183, 147, 123, 100, -185, 150, 125, 100, -187, 150, 126, 100, -188, 151, 127, 100, -183, 145, 122, 100, -188, 150, 127, 100, -189, 151, 129, 100, -183, 145, 124, 100, -189, 151, 129, 100, -188, 150, 130, 100, -178, 140, 122, 100, -186, 148, 126, 100, -190, 153, 134, 100, -182, 144, 126, 100, -182, 143, 126, 100, -188, 149, 133, 100, -185, 146, 132, 100, -188, 149, 134, 100, -188, 152, 136, 100, -182, 143, 128, 100, -184, 149, 131, 100, -184, 149, 131, 100, -181, 146, 124, 100, -183, 149, 127, 100, -186, 150, 129, 100, -192, 157, 138, 100, -192, 159, 141, 100, -187, 154, 137, 100, -186, 153, 136, 100, -192, 159, 142, 100, -189, 157, 140, 100, -194, 162, 145, 100, -199, 168, 150, 100, -203, 172, 155, 100, -202, 169, 152, 100, -202, 169, 152, 100, -204, 171, 152, 100, -199, 166, 149, 100, -195, 162, 144, 100, -196, 162, 143, 100, -190, 156, 137, 100, -197, 164, 144, 100, -196, 164, 144, 100, -201, 169, 148, 100, -195, 161, 138, 100, -198, 164, 139, 100, -198, 166, 143, 100, -201, 167, 144, 100, -201, 168, 146, 100, -197, 165, 140, 100, -200, 168, 143, 100, -200, 168, 143, 100, -196, 164, 138, 100, -192, 161, 134, 100, -195, 164, 138, 100, -198, 165, 139, 100, -197, 163, 136, 100, -196, 162, 135, 100, -193, 159, 132, 100, -191, 156, 129, 100, -193, 157, 128, 100, -192, 156, 126, 100, -190, 153, 124, 100, -189, 155, 124, 100, -188, 154, 125, 100, -149, 110, 93, 100, -129, 88, 85, 100, -139, 103, 109, 100, -148, 122, 145, 100, -135, 100, 111, 100, -136, 99, 105, 100, -138, 105, 117, 100, -149, 124, 147, 100, -140, 105, 118, 100, -112, 73, 80, 100, -134, 99, 106, 100, -136, 101, 109, 100, -145, 114, 131, 100, -129, 91, 106, 100, -81, 42, 49, 100, -70, 40, 39, 100, -87, 58, 55, 100, -89, 60, 60, 100, -81, 51, 49, 100, -101, 63, 57, 100, -92, 50, 47, 100, -108, 68, 64, 100, -106, 66, 57, 100, -101, 61, 53, 100, -106, 65, 58, 100, -109, 67, 54, 100, -132, 90, 71, 100, -134, 91, 68, 100, -113, 72, 49, 100, -124, 83, 60, 100, -134, 93, 69, 100, -141, 99, 75, 100, -148, 102, 79, 100, -160, 117, 90, 100, -166, 127, 98, 100, -171, 132, 103, 100, -179, 140, 112, 100, -185, 148, 119, 100, -185, 148, 119, 100, -181, 145, 115, 100, -181, 144, 114, 100, -180, 143, 114, 100, -179, 142, 112, 100, -175, 139, 107, 100, -177, 140, 110, 100, -177, 140, 111, 100, -177, 140, 111, 100, -177, 140, 112, 100, -177, 140, 114, 100, -179, 142, 116, 100, -181, 143, 119, 100, -181, 143, 120, 100, -178, 140, 117, 100, -177, 139, 116, 100, -176, 138, 115, 100, -181, 147, 122, 100, -184, 147, 123, 100, -184, 147, 125, 100, -183, 146, 125, 100, -186, 148, 125, 100, -188, 150, 127, 100, -184, 146, 124, 100, -187, 148, 129, 100, -187, 149, 131, 100, -179, 141, 122, 100, -183, 145, 126, 100, -191, 152, 135, 100, -189, 152, 134, 100, -184, 146, 128, 100, -182, 143, 127, 100, -181, 142, 127, 100, -183, 144, 129, 100, -178, 139, 123, 100, -182, 143, 128, 100, -179, 141, 125, 100, -187, 151, 134, 100, -177, 143, 125, 100, -173, 137, 104, 100, -178, 141, 111, 100, -177, 140, 114, 100, -184, 147, 124, 100, -188, 154, 134, 100, -188, 155, 137, 100, -183, 150, 133, 100, -187, 154, 137, 100, -184, 150, 133, 100, -188, 156, 139, 100, -198, 169, 151, 100, -198, 170, 152, 100, -195, 164, 150, 100, -197, 164, 149, 100, -197, 164, 147, 100, -194, 161, 144, 100, -193, 160, 143, 100, -186, 153, 136, 100, -189, 156, 138, 100, -192, 159, 140, 100, -196, 162, 143, 100, -196, 163, 144, 100, -197, 164, 144, 100, -197, 164, 144, 100, -196, 163, 144, 100, -197, 163, 144, 100, -197, 164, 144, 100, -197, 165, 143, 100, -197, 164, 140, 100, -196, 163, 138, 100, -193, 160, 136, 100, -196, 164, 141, 100, -198, 165, 140, 100, -192, 158, 133, 100, -190, 156, 130, 100, -191, 159, 133, 100, -191, 159, 131, 100, -189, 153, 127, 100, -188, 151, 125, 100, -191, 153, 126, 100, -190, 153, 124, 100, -186, 151, 122, 100, -186, 154, 126, 100, -141, 105, 90, 100, -117, 79, 73, 100, -130, 93, 95, 100, -139, 110, 124, 100, -139, 108, 125, 100, -134, 100, 104, 100, -136, 104, 110, 100, -147, 121, 139, 100, -153, 124, 141, 100, -122, 80, 87, 100, -127, 87, 93, 100, -140, 102, 107, 100, -146, 108, 126, 100, -139, 99, 116, 100, -104, 59, 69, 100, -54, 24, 26, 100, -80, 52, 48, 100, -101, 70, 69, 100, -87, 56, 57, 100, -104, 68, 66, 100, -107, 66, 64, 100, -110, 68, 64, 100, -109, 67, 57, 100, -103, 61, 55, 100, -107, 65, 58, 100, -113, 71, 61, 100, -123, 78, 64, 100, -127, 80, 62, 100, -118, 76, 53, 100, -131, 87, 64, 100, -136, 90, 67, 100, -140, 95, 72, 100, -143, 97, 74, 100, -155, 111, 88, 100, -163, 123, 98, 100, -171, 134, 107, 100, -173, 136, 109, 100, -175, 138, 109, 100, -178, 141, 112, 100, -175, 138, 109, 100, -169, 132, 103, 100, -173, 136, 107, 100, -176, 139, 110, 100, -173, 136, 107, 100, -174, 137, 108, 100, -173, 136, 107, 100, -173, 136, 106, 100, -175, 138, 111, 100, -177, 140, 114, 100, -176, 139, 114, 100, -176, 138, 114, 100, -173, 136, 112, 100, -176, 138, 115, 100, -175, 137, 114, 100, -178, 140, 117, 100, -181, 144, 121, 100, -183, 145, 122, 100, -182, 145, 126, 100, -183, 146, 127, 100, -179, 141, 121, 100, -179, 141, 119, 100, -184, 146, 123, 100, -184, 146, 126, 100, -182, 144, 125, 100, -181, 142, 124, 100, -187, 149, 130, 100, -188, 149, 132, 100, -186, 147, 130, 100, -183, 145, 128, 100, -187, 149, 132, 100, -177, 137, 122, 100, -176, 137, 121, 100, -174, 135, 119, 100, -171, 133, 117, 100, -174, 135, 120, 100, -180, 142, 127, 100, -179, 144, 129, 100, -162, 123, 80, 100, -164, 128, 88, 100, -164, 128, 95, 100, -173, 136, 108, 100, -180, 146, 122, 100, -180, 148, 127, 100, -175, 142, 124, 100, -177, 144, 127, 100, -179, 146, 129, 100, -174, 142, 126, 100, -187, 159, 143, 100, -190, 161, 147, 100, -189, 160, 146, 100, -190, 160, 146, 100, -187, 156, 140, 100, -186, 154, 136, 100, -190, 160, 142, 100, -179, 148, 131, 100, -190, 158, 141, 100, -193, 159, 142, 100, -195, 162, 144, 100, -200, 168, 150, 100, -200, 168, 150, 100, -196, 164, 145, 100, -194, 161, 142, 100, -197, 166, 146, 100, -192, 160, 141, 100, -190, 157, 138, 100, -191, 159, 138, 100, -191, 159, 139, 100, -190, 157, 138, 100, -191, 158, 139, 100, -184, 151, 132, 100, -172, 138, 118, 100, -169, 137, 115, 100, -174, 142, 118, 100, -180, 148, 123, 100, -183, 146, 124, 100, -181, 143, 121, 100, -179, 143, 119, 100, -180, 146, 119, 100, -181, 147, 120, 100, -177, 145, 121, 100, -141, 107, 97, 100, -110, 76, 73, 100, -116, 81, 82, 100, -135, 103, 110, 100, -142, 114, 131, 100, -137, 105, 113, 100, -136, 104, 107, 100, -141, 110, 118, 100, -153, 124, 142, 100, -137, 97, 107, 100, -117, 73, 80, 100, -139, 96, 103, 100, -145, 101, 114, 100, -145, 101, 117, 100, -126, 81, 92, 100, -54, 23, 27, 100, -60, 36, 33, 100, -112, 77, 75, 100, -110, 74, 74, 100, -103, 65, 65, 100, -112, 71, 69, 100, -112, 70, 68, 100, -108, 64, 54, 100, -97, 53, 50, 100, -110, 67, 60, 100, -99, 56, 48, 100, -93, 49, 43, 100, -106, 59, 47, 100, -119, 76, 54, 100, -131, 87, 63, 100, -135, 88, 64, 100, -136, 90, 67, 100, -142, 95, 74, 100, -152, 106, 85, 100, -158, 116, 93, 100, -166, 128, 104, 100, -172, 135, 110, 100, -176, 139, 113, 100, -170, 133, 105, 100, -170, 133, 103, 100, -166, 129, 100, 100, -168, 131, 102, 100, -166, 129, 101, 100, -169, 132, 103, 100, -171, 134, 105, 100, -171, 134, 104, 100, -167, 130, 102, 100, -171, 134, 108, 100, -170, 133, 107, 100, -171, 134, 110, 100, -172, 135, 110, 100, -175, 137, 113, 100, -177, 139, 116, 100, -177, 139, 116, 100, -178, 140, 117, 100, -180, 142, 118, 100, -181, 143, 122, 100, -182, 144, 125, 100, -179, 141, 122, 100, -178, 139, 121, 100, -182, 145, 126, 100, -179, 142, 121, 100, -177, 139, 119, 100, -183, 144, 126, 100, -184, 145, 128, 100, -186, 147, 130, 100, -184, 145, 128, 100, -178, 139, 123, 100, -184, 146, 129, 100, -182, 145, 129, 100, -179, 142, 126, 100, -177, 138, 123, 100, -176, 137, 122, 100, -159, 120, 104, 100, -167, 127, 115, 100, -176, 137, 127, 100, -177, 141, 130, 100, -156, 113, 67, 100, -157, 118, 73, 100, -155, 118, 75, 100, -162, 126, 92, 100, -166, 130, 103, 100, -171, 138, 112, 100, -166, 134, 114, 100, -171, 138, 119, 100, -171, 138, 121, 100, -167, 137, 122, 100, -176, 147, 133, 100, -182, 153, 140, 100, -185, 156, 143, 100, -186, 158, 144, 100, -182, 153, 141, 100, -180, 151, 135, 100, -180, 151, 135, 100, -175, 146, 130, 100, -184, 155, 142, 100, -190, 159, 144, 100, -185, 154, 138, 100, -188, 158, 141, 100, -193, 164, 146, 100, -193, 162, 144, 100, -190, 157, 139, 100, -191, 162, 144, 100, -185, 157, 138, 100, -187, 154, 136, 100, -191, 158, 139, 100, -186, 153, 135, 100, -181, 148, 132, 100, -177, 143, 128, 100, -169, 136, 119, 100, -163, 130, 112, 100, -160, 127, 109, 100, -161, 129, 111, 100, -165, 131, 112, 100, -166, 130, 111, 100, -167, 129, 111, 100, -163, 127, 109, 100, -163, 126, 107, 100, -159, 125, 105, 100, -155, 121, 105, 100, -138, 104, 96, 100, -119, 88, 84, 100, -103, 72, 72, 100, -121, 89, 90, 100, -140, 110, 119, 100, -136, 106, 114, 100, -132, 100, 102, 100, -135, 104, 107, 100, -145, 115, 128, 100, -146, 108, 120, 100, -114, 71, 77, 100, -125, 83, 87, 100, -138, 95, 101, 100, -144, 100, 112, 100, -128, 83, 93, 100, -84, 44, 52, 100, -48, 23, 22, 100, -107, 71, 69, 100, -116, 76, 75, 100, -103, 65, 63, 100, -97, 57, 57, 100, -112, 68, 69, 100, -114, 66, 58, 100, -93, 50, 48, 100, -107, 64, 58, 100, -86, 43, 36, 100, -98, 56, 50, 100, -114, 68, 55, 100, -124, 78, 56, 100, -131, 85, 62, 100, -136, 89, 65, 100, -131, 84, 61, 100, -134, 86, 68, 100, -145, 97, 80, 100, -157, 113, 92, 100, -164, 124, 102, 100, -169, 132, 108, 100, -167, 131, 104, 100, -163, 126, 98, 100, -164, 127, 100, 100, -164, 127, 99, 100, -160, 123, 96, 100, -164, 127, 101, 100, -168, 131, 103, 100, -168, 131, 103, 100, -166, 129, 101, 100, -165, 127, 101, 100, -167, 130, 104, 100, -169, 132, 106, 100, -174, 137, 113, 100, -172, 135, 111, 100, -172, 134, 111, 100, -175, 137, 114, 100, -176, 138, 115, 100, -175, 137, 115, 100, -177, 139, 118, 100, -181, 144, 125, 100, -183, 145, 126, 100, -178, 139, 121, 100, -173, 134, 116, 100, -177, 139, 122, 100, -179, 143, 124, 100, -179, 142, 124, 100, -178, 139, 122, 100, -180, 141, 124, 100, -183, 144, 127, 100, -180, 142, 125, 100, -171, 133, 118, 100, -172, 133, 118, 100, -169, 130, 115, 100, -175, 137, 121, 100, -180, 143, 127, 100, -174, 136, 122, 100, -159, 120, 104, 100, -174, 136, 124, 100, -179, 143, 132, 100, -177, 142, 132, 100, -152, 107, 64, 100, -147, 105, 61, 100, -151, 114, 69, 100, -151, 115, 76, 100, -157, 121, 86, 100, -167, 130, 103, 100, -164, 130, 106, 100, -161, 128, 107, 100, -171, 139, 123, 100, -175, 146, 131, 100, -172, 143, 130, 100, -173, 145, 133, 100, -175, 147, 135, 100, -176, 149, 137, 100, -175, 146, 135, 100, -171, 142, 129, 100, -173, 144, 130, 100, -180, 151, 138, 100, -184, 155, 142, 100, -182, 153, 140, 100, -183, 153, 142, 100, -183, 154, 139, 100, -186, 156, 140, 100, -188, 158, 141, 100, -190, 159, 141, 100, -192, 162, 145, 100, -190, 161, 146, 100, -181, 149, 135, 100, -176, 145, 132, 100, -172, 140, 127, 100, -169, 135, 123, 100, -167, 133, 122, 100, -168, 135, 121, 100, -166, 132, 118, 100, -158, 125, 108, 100, -158, 125, 108, 100, -158, 124, 107, 100, -159, 124, 107, 100, -157, 121, 104, 100, -153, 119, 102, 100, -154, 117, 104, 100, -151, 116, 103, 100, -145, 111, 99, 100, -136, 102, 94, 100, -127, 96, 91, 100, -112, 82, 81, 100, -102, 71, 73, 100, -123, 90, 94, 100, -130, 98, 102, 100, -128, 97, 99, 100, -135, 102, 106, 100, -138, 105, 109, 100, -149, 112, 118, 100, -129, 85, 91, 100, -108, 67, 68, 100, -127, 84, 83, 100, -134, 88, 92, 100, -131, 85, 95, 100, -109, 65, 74, 100, -56, 25, 29, 100, -93, 60, 57, 100, -108, 67, 65, 100, -92, 52, 51, 100, -75, 37, 36, 100, -106, 60, 61, 100, -120, 67, 60, 100, -86, 41, 37, 100, -102, 59, 52, 100, -101, 57, 49, 100, -118, 73, 64, 100, -124, 77, 62, 100, -125, 78, 59, 100, -129, 82, 61, 100, -132, 85, 60, 100, -130, 82, 58, 100, -127, 79, 64, 100, -138, 91, 77, 100, -154, 112, 93, 100, -161, 120, 99, 100, -165, 125, 104, 100, -161, 122, 98, 100, -159, 121, 96, 100, -161, 124, 98, 100, -159, 122, 96, 100, -159, 122, 96, 100, -163, 126, 100, 100, -166, 129, 103, 100, -166, 129, 102, 100, -164, 127, 100, 100, -163, 126, 100, 100, -166, 129, 103, 100, -171, 134, 108, 100, -172, 135, 109, 100, -169, 132, 106, 100, -171, 134, 109, 100, -176, 138, 115, 100, -174, 136, 113, 100, -173, 135, 115, 100, -175, 137, 119, 100, -175, 139, 120, 100, -175, 136, 118, 100, -172, 133, 116, 100, -173, 135, 119, 100, -171, 134, 117, 100, -176, 142, 123, 100, -177, 140, 122, 100, -176, 137, 120, 100, -177, 138, 122, 100, -178, 143, 127, 100, -177, 143, 126, 100, -175, 142, 125, 100, -174, 136, 120, 100, -174, 134, 122, 100, -170, 130, 118, 100, -180, 145, 132, 100, -169, 132, 120, 100, -163, 123, 111, 100, -169, 132, 121, 100, -175, 141, 129, 100, -176, 142, 133, 100, -146, 102, 61, 100, -140, 96, 56, 100, -139, 100, 56, 100, -148, 111, 67, 100, -156, 118, 82, 100, -165, 128, 98, 100, -158, 122, 95, 100, -154, 121, 99, 100, -167, 137, 120, 100, -168, 139, 123, 100, -162, 133, 120, 100, -169, 141, 127, 100, -175, 147, 135, 100, -172, 143, 131, 100, -165, 136, 125, 100, -171, 141, 128, 100, -175, 145, 133, 100, -175, 145, 133, 100, -182, 152, 141, 100, -177, 148, 135, 100, -183, 153, 143, 100, -185, 156, 145, 100, -186, 158, 146, 100, -187, 158, 144, 100, -185, 156, 142, 100, -185, 157, 142, 100, -182, 153, 141, 100, -173, 143, 133, 100, -170, 140, 130, 100, -165, 135, 125, 100, -164, 131, 122, 100, -164, 130, 121, 100, -163, 129, 119, 100, -162, 128, 118, 100, -157, 123, 111, 100, -156, 122, 109, 100, -156, 122, 109, 100, -156, 122, 109, 100, -153, 119, 106, 100, -152, 118, 105, 100, -153, 119, 107, 100, -150, 115, 103, 100, -144, 110, 99, 100, -137, 103, 94, 100, -130, 97, 91, 100, -121, 91, 87, 100, -107, 78, 79, 100, -102, 71, 74, 100, -116, 82, 86, 100, -121, 86, 88, 100, -129, 92, 95, 100, -134, 94, 98, 100, -145, 104, 109, 100, -141, 97, 100, 100, -101, 57, 58, 100, -116, 72, 73, 100, -132, 88, 90, 100, -134, 89, 95, 100, -124, 79, 90, 100, -77, 40, 47, 100, -86, 53, 51, 100, -104, 64, 62, 100, -84, 41, 42, 100, -67, 28, 29, 100, -89, 46, 48, 100, -130, 74, 66, 100, -83, 35, 28, 100, -99, 55, 49, 100, -118, 70, 60, 100, -130, 81, 68, 100, -128, 79, 65, 100, -123, 76, 61, 100, -127, 81, 62, 100, -136, 90, 64, 100, -130, 84, 57, 100, -115, 71, 54, 100, -131, 85, 70, 100, -151, 108, 91, 100, -156, 116, 97, 100, -156, 115, 96, 100, -150, 110, 86, 100, -155, 116, 90, 100, -157, 119, 94, 100, -156, 118, 94, 100, -158, 121, 96, 100, -161, 124, 98, 100, -161, 124, 98, 100, -164, 127, 100, 100, -163, 126, 100, 100, -162, 125, 99, 100, -164, 127, 101, 100, -169, 131, 106, 100, -167, 129, 105, 100, -165, 128, 104, 100, -172, 134, 110, 100, -173, 135, 112, 100, -169, 131, 108, 100, -169, 131, 111, 100, -172, 134, 116, 100, -173, 138, 119, 100, -172, 136, 118, 100, -170, 135, 118, 100, -175, 139, 123, 100, -169, 133, 116, 100, -172, 137, 118, 100, -167, 129, 112, 100, -171, 132, 115, 100, -177, 141, 123, 100, -168, 134, 120, 100, -173, 139, 126, 100, -176, 141, 128, 100, -177, 141, 128, 100, -175, 137, 126, 100, -172, 132, 122, 100, -170, 134, 122, 100, -159, 123, 112, 100, -161, 124, 113, 100, -169, 132, 123, 100, -170, 136, 126, 100, -173, 139, 129, 100, -146, 103, 62, 100, -143, 100, 57, 100, -146, 103, 58, 100, -148, 109, 66, 100, -154, 116, 81, 100, -157, 120, 87, 100, -157, 123, 94, 100, -162, 130, 108, 100, -160, 130, 110, 100, -160, 131, 112, 100, -162, 134, 120, 100, -158, 130, 115, 100, -170, 142, 130, 100, -173, 144, 133, 100, -166, 137, 126, 100, -170, 140, 130, 100, -175, 145, 135, 100, -170, 141, 130, 100, -170, 141, 130, 100, -173, 143, 133, 100, -178, 148, 138, 100, -182, 153, 143, 100, -185, 157, 147, 100, -184, 154, 144, 100, -180, 149, 139, 100, -179, 148, 139, 100, -175, 145, 136, 100, -167, 137, 128, 100, -165, 135, 126, 100, -162, 132, 122, 100, -162, 132, 121, 100, -164, 133, 123, 100, -162, 129, 119, 100, -159, 125, 116, 100, -157, 123, 114, 100, -157, 123, 114, 100, -159, 125, 115, 100, -156, 122, 112, 100, -156, 122, 112, 100, -150, 116, 105, 100, -149, 115, 104, 100, -145, 111, 100, 100, -140, 106, 97, 100, -139, 105, 95, 100, -132, 99, 91, 100, -128, 97, 93, 100, -120, 92, 88, 100, -109, 82, 83, 100, -101, 69, 72, 100, -106, 68, 71, 100, -114, 76, 75, 100, -124, 83, 83, 100, -129, 86, 87, 100, -133, 86, 88, 100, -117, 72, 73, 100, -93, 51, 53, 100, -115, 72, 73, 100, -124, 78, 81, 100, -123, 76, 85, 100, -98, 54, 64, 100, -89, 51, 53, 100, -116, 76, 74, 100, -105, 60, 60, 100, -83, 41, 44, 100, -81, 39, 45, 100, -135, 80, 70, 100, -112, 60, 44, 100, -114, 63, 52, 100, -128, 77, 65, 100, -136, 86, 73, 100, -133, 84, 69, 100, -124, 77, 61, 100, -127, 80, 62, 100, -138, 91, 65, 100, -130, 84, 57, 100, -109, 69, 50, 100, -119, 77, 65, 100, -141, 98, 83, 100, -152, 111, 94, 100, -151, 110, 90, 100, -144, 103, 80, 100, -151, 110, 88, 100, -152, 112, 90, 100, -153, 115, 94, 100, -154, 116, 93, 100, -158, 120, 97, 100, -161, 123, 100, 100, -160, 122, 98, 100, -160, 122, 98, 100, -161, 123, 100, 100, -162, 124, 99, 100, -163, 125, 102, 100, -164, 126, 104, 100, -168, 130, 107, 100, -170, 132, 109, 100, -170, 132, 110, 100, -168, 130, 111, 100, -172, 134, 115, 100, -167, 130, 112, 100, -169, 134, 116, 100, -169, 137, 119, 100, -167, 132, 116, 100, -167, 133, 116, 100, -165, 129, 112, 100, -174, 139, 123, 100, -169, 133, 117, 100, -169, 134, 119, 100, -176, 143, 130, 100, -173, 139, 127, 100, -172, 139, 127, 100, -174, 140, 129, 100, -173, 140, 129, 100, -172, 136, 124, 100, -161, 122, 112, 100, -163, 127, 116, 100, -163, 129, 119, 100, -159, 125, 114, 100, -173, 139, 129, 100, -174, 140, 131, 100, -173, 139, 129, 100, -139, 95, 54, 100, -137, 93, 51, 100, -138, 94, 53, 100, -139, 100, 58, 100, -145, 108, 70, 100, -146, 110, 76, 100, -156, 121, 91, 100, -153, 121, 95, 100, -151, 118, 94, 100, -158, 127, 107, 100, -160, 132, 116, 100, -152, 122, 108, 100, -152, 121, 108, 100, -166, 136, 125, 100, -163, 134, 124, 100, -166, 139, 127, 100, -169, 141, 130, 100, -171, 143, 132, 100, -171, 142, 132, 100, -173, 143, 133, 100, -176, 146, 136, 100, -177, 147, 137, 100, -177, 148, 138, 100, -185, 156, 147, 100, -178, 148, 138, 100, -168, 138, 132, 100, -166, 135, 131, 100, -164, 134, 129, 100, -161, 130, 126, 100, -157, 127, 120, 100, -161, 130, 122, 100, -160, 130, 121, 100, -159, 129, 120, 100, -157, 125, 116, 100, -158, 124, 114, 100, -157, 123, 114, 100, -157, 123, 114, 100, -155, 121, 112, 100, -153, 120, 111, 100, -148, 114, 104, 100, -144, 110, 100, 100, -139, 105, 95, 100, -139, 105, 96, 100, -136, 102, 93, 100, -134, 100, 92, 100, -133, 99, 94, 100, -127, 97, 93, 100, -121, 91, 90, 100, -108, 80, 82, 100, -92, 61, 61, 100, -97, 61, 59, 100, -111, 68, 66, 100, -117, 73, 74, 100, -120, 71, 73, 100, -127, 80, 83, 100, -109, 67, 71, 100, -86, 45, 47, 100, -108, 73, 78, 100, -115, 79, 91, 100, -105, 62, 74, 100, -88, 47, 51, 100, -115, 73, 67, 100, -128, 78, 72, 100, -96, 50, 51, 100, -88, 45, 51, 100, -141, 86, 78, 100, -140, 83, 63, 100, -133, 76, 60, 100, -138, 81, 70, 100, -138, 84, 72, 100, -125, 75, 61, 100, -121, 73, 58, 100, -130, 84, 64, 100, -139, 92, 68, 100, -132, 85, 60, 100, -106, 66, 48, 100, -114, 73, 65, 100, -136, 94, 80, 100, -145, 104, 87, 100, -146, 104, 85, 100, -141, 100, 77, 100, -148, 107, 85, 100, -149, 110, 88, 100, -151, 113, 91, 100, -151, 113, 90, 100, -155, 117, 94, 100, -161, 123, 100, 100, -158, 121, 96, 100, -159, 122, 98, 100, -161, 123, 100, 100, -162, 124, 101, 100, -163, 127, 104, 100, -163, 126, 106, 100, -166, 127, 105, 100, -165, 127, 108, 100, -170, 132, 113, 100, -166, 127, 110, 100, -166, 130, 111, 100, -167, 131, 114, 100, -167, 131, 115, 100, -166, 133, 116, 100, -168, 134, 119, 100, -166, 132, 117, 100, -162, 128, 113, 100, -169, 135, 122, 100, -162, 128, 115, 100, -170, 136, 124, 100, -169, 135, 124, 100, -167, 133, 122, 100, -170, 140, 130, 100, -173, 139, 128, 100, -172, 138, 126, 100, -166, 131, 119, 100, -161, 125, 115, 100, -164, 129, 120, 100, -162, 127, 118, 100, -165, 130, 121, 100, -169, 135, 127, 100, -170, 134, 126, 100, -173, 139, 130, 100, -132, 91, 52, 100, -127, 86, 46, 100, -122, 84, 43, 100, -129, 90, 49, 100, -143, 106, 64, 100, -144, 109, 73, 100, -140, 102, 73, 100, -144, 109, 82, 100, -148, 117, 91, 100, -152, 120, 100, 100, -153, 122, 103, 100, -146, 113, 98, 100, -147, 116, 103, 100, -156, 127, 114, 100, -157, 127, 116, 100, -158, 130, 119, 100, -165, 138, 127, 100, -171, 142, 132, 100, -171, 141, 131, 100, -169, 139, 129, 100, -178, 148, 138, 100, -175, 145, 135, 100, -175, 145, 135, 100, -184, 153, 148, 100, -172, 141, 136, 100, -162, 131, 128, 100, -160, 131, 127, 100, -161, 132, 128, 100, -161, 132, 128, 100, -161, 131, 127, 100, -160, 130, 126, 100, -159, 128, 123, 100, -159, 128, 122, 100, -156, 126, 121, 100, -157, 125, 118, 100, -154, 123, 113, 100, -155, 123, 114, 100, -154, 119, 113, 100, -148, 115, 109, 100, -145, 111, 102, 100, -142, 108, 99, 100, -138, 104, 95, 100, -137, 103, 93, 100, -134, 100, 91, 100, -130, 96, 88, 100, -126, 91, 86, 100, -125, 91, 88, 100, -124, 94, 91, 100, -118, 88, 89, 100, -106, 80, 80, 100, -85, 59, 63, 100, -85, 51, 55, 100, -105, 64, 64, 100, -120, 76, 77, 100, -124, 81, 85, 100, -123, 80, 86, 100, -95, 51, 59, 100, -90, 58, 65, 100, -124, 96, 110, 100, -112, 76, 93, 100, -86, 47, 50, 100, -113, 72, 67, 100, -122, 69, 63, 100, -104, 54, 53, 100, -89, 48, 55, 100, -139, 82, 76, 100, -137, 76, 59, 100, -127, 68, 53, 100, -135, 78, 67, 100, -131, 76, 64, 100, -116, 66, 54, 100, -123, 76, 62, 100, -132, 85, 67, 100, -138, 90, 69, 100, -129, 82, 60, 100, -99, 59, 42, 100, -103, 64, 58, 100, -131, 90, 77, 100, -140, 98, 82, 100, -139, 98, 80, 100, -135, 94, 75, 100, -144, 103, 82, 100, -147, 106, 84, 100, -148, 109, 88, 100, -149, 110, 88, 100, -152, 114, 91, 100, -157, 119, 96, 100, -155, 117, 94, 100, -158, 120, 97, 100, -160, 122, 99, 100, -163, 125, 102, 100, -163, 126, 102, 100, -161, 123, 104, 100, -162, 124, 103, 100, -165, 127, 106, 100, -167, 129, 110, 100, -159, 120, 102, 100, -162, 124, 107, 100, -166, 130, 114, 100, -165, 131, 115, 100, -162, 129, 112, 100, -164, 130, 117, 100, -167, 133, 122, 100, -157, 123, 111, 100, -160, 126, 114, 100, -168, 133, 122, 100, -162, 128, 116, 100, -157, 123, 110, 100, -166, 136, 123, 100, -162, 132, 122, 100, -164, 130, 120, 100, -166, 132, 119, 100, -165, 130, 118, 100, -164, 130, 120, 100, -167, 133, 124, 100, -163, 129, 120, 100, -160, 127, 119, 100, -166, 135, 129, 100, -159, 128, 119, 100, -162, 131, 121, 100, -119, 81, 42, 100, -118, 80, 42, 100, -119, 82, 45, 100, -132, 94, 55, 100, -136, 98, 62, 100, -138, 101, 70, 100, -137, 100, 73, 100, -143, 108, 82, 100, -147, 114, 90, 100, -145, 113, 93, 100, -147, 113, 95, 100, -150, 117, 99, 100, -145, 112, 97, 100, -148, 116, 104, 100, -156, 127, 115, 100, -151, 122, 111, 100, -161, 131, 121, 100, -168, 138, 128, 100, -166, 136, 126, 100, -167, 137, 127, 100, -175, 146, 135, 100, -168, 138, 128, 100, -174, 144, 134, 100, -166, 135, 127, 100, -162, 126, 125, 100, -157, 127, 124, 100, -157, 129, 125, 100, -160, 131, 127, 100, -162, 134, 130, 100, -161, 133, 129, 100, -160, 131, 127, 100, -158, 128, 124, 100, -155, 124, 121, 100, -153, 122, 118, 100, -152, 122, 117, 100, -149, 118, 112, 100, -148, 117, 111, 100, -148, 117, 112, 100, -143, 111, 106, 100, -144, 110, 102, 100, -146, 112, 104, 100, -145, 110, 106, 100, -140, 106, 101, 100, -137, 103, 94, 100, -133, 99, 91, 100, -127, 92, 89, 100, -123, 88, 86, 100, -123, 92, 89, 100, -119, 90, 88, 100, -114, 85, 86, 100, -103, 77, 84, 100, -84, 59, 71, 100, -78, 49, 57, 100, -104, 64, 66, 100, -111, 66, 68, 100, -110, 67, 78, 100, -109, 65, 78, 100, -94, 50, 62, 100, -99, 57, 66, 100, -108, 74, 83, 100, -90, 57, 58, 100, -122, 79, 72, 100, -118, 65, 59, 100, -109, 57, 56, 100, -92, 50, 57, 100, -126, 68, 63, 100, -146, 82, 65, 100, -125, 64, 49, 100, -132, 74, 62, 100, -130, 73, 61, 100, -128, 77, 64, 100, -131, 82, 69, 100, -131, 84, 69, 100, -128, 81, 61, 100, -125, 80, 58, 100, -91, 53, 38, 100, -98, 60, 55, 100, -125, 85, 75, 100, -135, 95, 80, 100, -135, 94, 77, 100, -132, 91, 71, 100, -137, 96, 77, 100, -141, 100, 81, 100, -145, 104, 83, 100, -150, 109, 87, 100, -150, 111, 89, 100, -153, 115, 95, 100, -154, 116, 96, 100, -155, 117, 97, 100, -156, 118, 98, 100, -158, 120, 100, 100, -160, 121, 101, 100, -159, 120, 100, 100, -161, 123, 104, 100, -164, 126, 106, 100, -160, 122, 102, 100, -160, 121, 104, 100, -162, 123, 107, 100, -165, 128, 112, 100, -164, 129, 113, 100, -158, 123, 106, 100, -162, 126, 111, 100, -161, 127, 115, 100, -162, 128, 118, 100, -165, 133, 123, 100, -163, 130, 118, 100, -156, 122, 111, 100, -162, 128, 117, 100, -165, 134, 121, 100, -162, 133, 119, 100, -158, 125, 114, 100, -162, 128, 118, 100, -165, 131, 121, 100, -166, 132, 123, 100, -163, 129, 120, 100, -164, 132, 122, 100, -157, 126, 120, 100, -162, 131, 126, 100, -163, 134, 124, 100, -152, 123, 113, 100, -108, 71, 35, 100, -113, 77, 37, 100, -118, 83, 45, 100, -128, 91, 53, 100, -130, 93, 57, 100, -134, 98, 67, 100, -138, 103, 76, 100, -137, 103, 78, 100, -140, 106, 85, 100, -142, 110, 90, 100, -142, 108, 89, 100, -138, 104, 86, 100, -143, 110, 94, 100, -141, 109, 97, 100, -145, 116, 104, 100, -142, 112, 101, 100, -150, 120, 109, 100, -159, 129, 119, 100, -164, 134, 124, 100, -164, 135, 124, 100, -165, 137, 127, 100, -163, 135, 125, 100, -164, 136, 127, 100, -159, 129, 123, 100, -153, 118, 116, 100, -151, 121, 119, 100, -155, 127, 126, 100, -154, 128, 126, 100, -151, 126, 123, 100, -156, 128, 124, 100, -155, 126, 122, 100, -150, 121, 117, 100, -151, 122, 118, 100, -152, 122, 117, 100, -152, 121, 116, 100, -147, 115, 111, 100, -145, 114, 109, 100, -145, 114, 109, 100, -146, 112, 107, 100, -146, 111, 106, 100, -148, 112, 108, 100, -144, 111, 106, 100, -140, 106, 99, 100, -137, 102, 93, 100, -133, 99, 92, 100, -132, 97, 94, 100, -127, 93, 89, 100, -125, 93, 90, 100, -125, 94, 91, 100, -120, 89, 88, 100, -109, 78, 82, 100, -99, 69, 77, 100, -82, 59, 70, 100, -73, 46, 56, 100, -92, 55, 64, 100, -119, 82, 101, 100, -120, 84, 106, 100, -104, 63, 79, 100, -78, 39, 46, 100, -73, 41, 44, 100, -77, 41, 38, 100, -133, 88, 78, 100, -125, 72, 62, 100, -113, 61, 57, 100, -99, 55, 60, 100, -115, 60, 56, 100, -157, 94, 77, 100, -134, 72, 51, 100, -134, 74, 58, 100, -132, 75, 63, 100, -132, 79, 68, 100, -128, 78, 67, 100, -134, 86, 71, 100, -130, 83, 63, 100, -124, 80, 61, 100, -87, 50, 36, 100, -95, 58, 52, 100, -123, 83, 73, 100, -125, 86, 75, 100, -130, 89, 75, 100, -130, 87, 71, 100, -130, 88, 71, 100, -134, 94, 76, 100, -141, 100, 82, 100, -144, 103, 85, 100, -146, 106, 87, 100, -149, 111, 92, 100, -150, 111, 93, 100, -154, 116, 97, 100, -155, 117, 98, 100, -155, 116, 98, 100, -155, 117, 99, 100, -156, 117, 100, 100, -161, 122, 105, 100, -156, 117, 100, 100, -156, 117, 100, 100, -161, 122, 106, 100, -162, 123, 108, 100, -165, 126, 111, 100, -163, 127, 113, 100, -158, 121, 108, 100, -158, 122, 105, 100, -158, 122, 107, 100, -159, 125, 113, 100, -165, 131, 120, 100, -161, 127, 114, 100, -158, 124, 114, 100, -163, 129, 120, 100, -162, 128, 118, 100, -159, 129, 118, 100, -156, 127, 116, 100, -153, 123, 112, 100, -160, 130, 119, 100, -162, 132, 122, 100, -160, 128, 118, 100, -159, 128, 120, 100, -157, 127, 122, 100, -160, 129, 124, 100, -157, 126, 120, 100, -153, 123, 115, 100, -101, 64, 32, 100, -106, 70, 33, 100, -114, 79, 41, 100, -119, 85, 46, 100, -119, 84, 48, 100, -125, 90, 58, 100, -129, 94, 66, 100, -131, 97, 71, 100, -137, 101, 82, 100, -137, 102, 83, 100, -140, 109, 88, 100, -134, 103, 85, 100, -132, 103, 87, 100, -135, 106, 92, 100, -131, 103, 90, 100, -134, 106, 93, 100, -139, 111, 98, 100, -143, 114, 103, 100, -150, 122, 111, 100, -156, 128, 118, 100, -163, 135, 127, 100, -160, 134, 127, 100, -157, 128, 121, 100, -156, 131, 124, 100, -148, 123, 118, 100, -144, 117, 114, 100, -147, 122, 119, 100, -149, 125, 123, 100, -148, 123, 121, 100, -149, 122, 118, 100, -148, 123, 117, 100, -147, 122, 116, 100, -152, 124, 120, 100, -152, 121, 118, 100, -152, 121, 116, 100, -149, 118, 113, 100, -146, 115, 110, 100, -143, 112, 107, 100, -145, 112, 108, 100, -146, 110, 106, 100, -145, 110, 106, 100, -141, 107, 101, 100, -137, 103, 94, 100, -133, 98, 89, 100, -131, 96, 89, 100, -131, 96, 93, 100, -130, 95, 91, 100, -129, 95, 93, 100, -126, 95, 92, 100, -119, 88, 86, 100, -113, 80, 82, 100, -106, 71, 75, 100, -97, 68, 75, 100, -93, 68, 80, 100, -86, 61, 73, 100, -103, 63, 74, 100, -122, 79, 95, 100, -100, 65, 80, 100, -78, 42, 44, 100, -77, 34, 33, 100, -85, 41, 37, 100, -137, 90, 78, 100, -127, 74, 62, 100, -119, 65, 57, 100, -111, 61, 62, 100, -101, 45, 40, 100, -155, 93, 76, 100, -150, 90, 67, 100, -136, 76, 56, 100, -129, 72, 57, 100, -134, 81, 72, 100, -121, 71, 63, 100, -135, 86, 69, 100, -132, 84, 64, 100, -122, 77, 59, 100, -90, 53, 39, 100, -97, 58, 52, 100, -118, 78, 69, 100, -118, 78, 70, 100, -121, 81, 70, 100, -122, 82, 67, 100, -125, 83, 68, 100, -128, 89, 71, 100, -139, 100, 82, 100, -141, 101, 83, 100, -141, 103, 85, 100, -146, 108, 90, 100, -149, 110, 92, 100, -149, 111, 92, 100, -152, 114, 95, 100, -153, 114, 96, 100, -153, 114, 97, 100, -154, 115, 98, 100, -159, 120, 104, 100, -156, 117, 101, 100, -156, 117, 102, 100, -159, 120, 104, 100, -159, 120, 103, 100, -161, 123, 108, 100, -162, 126, 115, 100, -158, 122, 110, 100, -154, 120, 106, 100, -148, 112, 97, 100, -153, 118, 102, 100, -155, 121, 108, 100, -157, 123, 111, 100, -162, 128, 118, 100, -164, 130, 121, 100, -163, 129, 119, 100, -159, 129, 119, 100, -156, 126, 116, 100, -154, 124, 116, 100, -160, 130, 123, 100, -159, 129, 119, 100, -158, 129, 118, 100, -153, 122, 115, 100, -152, 121, 116, 100, -156, 124, 120, 100, -143, 112, 104, 100, -141, 111, 102, 100, -93, 60, 27, 100, -97, 63, 29, 100, -107, 72, 36, 100, -113, 78, 43, 100, -111, 77, 45, 100, -118, 85, 53, 100, -118, 84, 55, 100, -120, 86, 61, 100, -128, 95, 74, 100, -123, 91, 72, 100, -125, 96, 77, 100, -130, 101, 83, 100, -126, 97, 84, 100, -130, 102, 88, 100, -131, 104, 89, 100, -138, 112, 99, 100, -138, 112, 100, 100, -131, 104, 92, 100, -140, 112, 101, 100, -148, 121, 109, 100, -149, 122, 111, 100, -151, 124, 114, 100, -155, 128, 119, 100, -152, 127, 120, 100, -141, 119, 113, 100, -141, 117, 111, 100, -145, 119, 115, 100, -144, 120, 116, 100, -142, 119, 115, 100, -146, 123, 121, 100, -146, 122, 118, 100, -146, 120, 117, 100, -150, 123, 120, 100, -149, 118, 115, 100, -148, 117, 114, 100, -148, 117, 113, 100, -147, 116, 112, 100, -142, 111, 108, 100, -141, 110, 108, 100, -140, 108, 104, 100, -141, 106, 102, 100, -139, 104, 100, 100, -136, 101, 94, 100, -133, 99, 89, 100, -131, 97, 89, 100, -132, 96, 93, 100, -130, 95, 91, 100, -128, 93, 91, 100, -128, 94, 92, 100, -123, 90, 87, 100, -117, 81, 83, 100, -112, 77, 81, 100, -106, 75, 80, 100, -104, 74, 84, 100, -95, 71, 81, 100, -74, 41, 45, 100, -79, 40, 44, 100, -81, 42, 43, 100, -100, 54, 48, 100, -107, 58, 52, 100, -93, 45, 39, 100, -145, 95, 82, 100, -130, 74, 60, 100, -129, 72, 57, 100, -132, 76, 60, 100, -106, 48, 38, 100, -143, 81, 70, 100, -158, 96, 75, 100, -147, 85, 62, 100, -144, 85, 63, 100, -145, 91, 75, 100, -131, 79, 67, 100, -139, 89, 72, 100, -135, 87, 67, 100, -123, 79, 61, 100, -94, 55, 39, 100, -95, 55, 50, 100, -113, 73, 68, 100, -119, 79, 71, 100, -120, 80, 70, 100, -115, 75, 60, 100, -117, 75, 61, 100, -121, 79, 65, 100, -132, 92, 75, 100, -137, 99, 82, 100, -138, 98, 82, 100, -140, 102, 84, 100, -143, 104, 87, 100, -146, 107, 89, 100, -146, 107, 90, 100, -150, 111, 94, 100, -151, 113, 97, 100, -153, 114, 99, 100, -156, 117, 102, 100, -155, 116, 100, 100, -154, 115, 100, 100, -156, 117, 101, 100, -156, 118, 102, 100, -157, 123, 109, 100, -158, 124, 113, 100, -157, 122, 111, 100, -153, 119, 107, 100, -152, 117, 105, 100, -146, 112, 98, 100, -150, 116, 103, 100, -154, 120, 110, 100, -158, 124, 114, 100, -159, 125, 115, 100, -159, 124, 115, 100, -162, 131, 121, 100, -161, 131, 121, 100, -163, 132, 129, 100, -159, 128, 125, 100, -153, 122, 115, 100, -154, 124, 117, 100, -152, 120, 116, 100, -145, 113, 106, 100, -143, 113, 104, 100, -146, 116, 106, 100, -147, 116, 110, 100, -84, 56, 24, 100, -90, 59, 27, 100, -95, 63, 31, 100, -93, 65, 32, 100, -102, 74, 42, 100, -109, 81, 50, 100, -109, 79, 51, 100, -114, 81, 56, 100, -121, 89, 68, 100, -122, 93, 73, 100, -121, 94, 74, 100, -120, 93, 74, 100, -118, 90, 75, 100, -123, 96, 82, 100, -123, 98, 84, 100, -125, 101, 88, 100, -127, 105, 92, 100, -126, 101, 90, 100, -128, 103, 91, 100, -140, 114, 103, 100, -137, 109, 98, 100, -141, 113, 101, 100, -147, 119, 108, 100, -147, 119, 112, 100, -141, 115, 110, 100, -140, 117, 111, 100, -146, 121, 119, 100, -147, 121, 118, 100, -145, 122, 117, 100, -147, 125, 123, 100, -147, 123, 121, 100, -149, 122, 120, 100, -148, 120, 116, 100, -145, 116, 112, 100, -144, 115, 111, 100, -141, 110, 108, 100, -141, 110, 107, 100, -138, 107, 104, 100, -136, 105, 102, 100, -137, 106, 103, 100, -137, 104, 100, 100, -139, 104, 100, 100, -136, 100, 93, 100, -133, 98, 89, 100, -131, 96, 89, 100, -129, 93, 90, 100, -128, 93, 89, 100, -125, 90, 88, 100, -125, 90, 88, 100, -122, 86, 86, 100, -116, 80, 82, 100, -115, 79, 81, 100, -109, 75, 79, 100, -103, 72, 79, 100, -97, 71, 80, 100, -76, 40, 42, 100, -66, 26, 23, 100, -103, 57, 47, 100, -126, 71, 60, 100, -130, 75, 65, 100, -107, 58, 46, 100, -148, 97, 80, 100, -140, 81, 63, 100, -136, 73, 54, 100, -141, 80, 58, 100, -126, 66, 49, 100, -133, 69, 55, 100, -163, 98, 77, 100, -152, 87, 65, 100, -152, 90, 67, 100, -149, 93, 71, 100, -139, 82, 69, 100, -137, 83, 70, 100, -135, 86, 68, 100, -120, 76, 58, 100, -94, 54, 38, 100, -93, 55, 49, 100, -109, 69, 65, 100, -114, 73, 66, 100, -115, 75, 67, 100, -112, 71, 59, 100, -112, 70, 56, 100, -115, 73, 59, 100, -126, 84, 69, 100, -130, 91, 74, 100, -134, 95, 78, 100, -136, 97, 79, 100, -136, 97, 80, 100, -142, 103, 86, 100, -142, 103, 86, 100, -149, 110, 94, 100, -150, 110, 96, 100, -149, 111, 95, 100, -152, 114, 98, 100, -153, 113, 98, 100, -153, 114, 99, 100, -155, 116, 100, 100, -154, 117, 104, 100, -152, 119, 109, 100, -152, 120, 110, 100, -154, 120, 111, 100, -150, 116, 106, 100, -143, 111, 101, 100, -148, 118, 106, 100, -152, 121, 109, 100, -151, 118, 108, 100, -151, 117, 107, 100, -154, 120, 111, 100, -158, 123, 115, 100, -156, 125, 116, 100, -157, 127, 118, 100, -155, 124, 119, 100, -155, 124, 119, 100, -150, 117, 112, 100, -152, 120, 116, 100, -151, 119, 114, 100, -145, 110, 103, 100, -148, 115, 106, 100, -147, 116, 110, 100, -146, 116, 112, 100, -76, 54, 22, 100, -76, 52, 18, 100, -76, 52, 19, 100, -83, 59, 26, 100, -93, 68, 38, 100, -96, 71, 43, 100, -100, 74, 47, 100, -106, 78, 52, 100, -111, 82, 58, 100, -114, 85, 64, 100, -121, 93, 74, 100, -115, 90, 72, 100, -113, 88, 73, 100, -114, 91, 78, 100, -110, 91, 78, 100, -108, 87, 74, 100, -118, 96, 83, 100, -120, 99, 85, 100, -122, 100, 87, 100, -125, 99, 87, 100, -133, 106, 94, 100, -140, 112, 101, 100, -142, 114, 103, 100, -142, 113, 106, 100, -141, 114, 110, 100, -138, 115, 109, 100, -141, 118, 112, 100, -145, 122, 117, 100, -142, 119, 113, 100, -141, 118, 112, 100, -139, 117, 111, 100, -141, 117, 112, 100, -143, 115, 111, 100, -144, 115, 111, 100, -143, 114, 110, 100, -137, 107, 104, 100, -137, 106, 103, 100, -134, 104, 100, 100, -136, 106, 102, 100, -136, 104, 101, 100, -132, 102, 98, 100, -131, 99, 96, 100, -133, 98, 95, 100, -131, 96, 91, 100, -126, 89, 86, 100, -127, 92, 88, 100, -122, 87, 84, 100, -120, 85, 83, 100, -121, 86, 84, 100, -117, 82, 82, 100, -115, 79, 81, 100, -108, 72, 74, 100, -104, 69, 72, 100, -99, 68, 75, 100, -88, 63, 67, 100, -76, 39, 36, 100, -103, 54, 46, 100, -122, 67, 52, 100, -130, 71, 58, 100, -134, 76, 64, 100, -118, 66, 50, 100, -145, 92, 72, 100, -135, 74, 54, 100, -136, 71, 50, 100, -146, 81, 58, 100, -146, 80, 59, 100, -146, 80, 61, 100, -163, 98, 78, 100, -153, 88, 62, 100, -153, 91, 68, 100, -153, 92, 68, 100, -145, 87, 68, 100, -134, 80, 67, 100, -132, 82, 69, 100, -121, 75, 60, 100, -92, 52, 37, 100, -92, 54, 47, 100, -106, 66, 64, 100, -109, 67, 66, 100, -107, 67, 61, 100, -108, 68, 59, 100, -110, 68, 56, 100, -110, 67, 53, 100, -116, 74, 60, 100, -122, 81, 66, 100, -128, 89, 72, 100, -130, 92, 74, 100, -130, 91, 74, 100, -137, 98, 82, 100, -141, 103, 88, 100, -143, 106, 92, 100, -143, 104, 92, 100, -140, 102, 87, 100, -146, 108, 93, 100, -147, 108, 97, 100, -149, 110, 99, 100, -149, 112, 100, 100, -152, 118, 108, 100, -151, 120, 110, 100, -147, 116, 106, 100, -146, 111, 100, 100, -139, 105, 93, 100, -142, 112, 99, 100, -146, 116, 106, 100, -148, 118, 108, 100, -151, 120, 110, 100, -150, 117, 107, 100, -148, 114, 104, 100, -145, 113, 103, 100, -148, 118, 111, 100, -149, 118, 113, 100, -146, 115, 110, 100, -151, 120, 112, 100, -151, 116, 110, 100, -152, 117, 112, 100, -146, 111, 107, 100, -141, 106, 102, 100, -136, 101, 97, 100, -144, 113, 108, 100, -137, 106, 101, 100, -146, 144, 111, 100, -117, 108, 75, 100, -100, 88, 53, 100, -88, 74, 41, 100, -79, 62, 31, 100, -83, 65, 36, 100, -86, 69, 42, 100, -87, 70, 45, 100, -90, 73, 48, 100, -98, 79, 57, 100, -92, 73, 56, 100, -88, 69, 54, 100, -89, 72, 57, 100, -86, 70, 56, 100, -87, 71, 59, 100, -93, 77, 66, 100, -103, 85, 73, 100, -108, 89, 77, 100, -118, 97, 85, 100, -120, 99, 87, 100, -122, 100, 89, 100, -126, 102, 91, 100, -130, 104, 92, 100, -133, 105, 95, 100, -138, 110, 106, 100, -137, 112, 107, 100, -135, 112, 106, 100, -138, 113, 109, 100, -136, 113, 107, 100, -137, 114, 108, 100, -137, 114, 108, 100, -138, 114, 110, 100, -137, 111, 108, 100, -141, 113, 109, 100, -143, 113, 109, 100, -141, 112, 108, 100, -140, 109, 106, 100, -136, 106, 102, 100, -136, 108, 104, 100, -136, 105, 102, 100, -131, 100, 97, 100, -128, 97, 94, 100, -125, 91, 89, 100, -124, 88, 85, 100, -121, 85, 81, 100, -117, 83, 79, 100, -115, 81, 78, 100, -114, 80, 78, 100, -113, 79, 77, 100, -110, 77, 75, 100, -109, 74, 73, 100, -103, 67, 69, 100, -98, 63, 66, 100, -92, 61, 68, 100, -83, 51, 51, 100, -103, 55, 47, 100, -127, 69, 55, 100, -133, 71, 56, 100, -142, 79, 64, 100, -141, 82, 66, 100, -125, 73, 55, 100, -140, 83, 66, 100, -142, 79, 59, 100, -152, 86, 66, 100, -164, 96, 76, 100, -166, 99, 80, 100, -160, 93, 74, 100, -171, 106, 86, 100, -159, 95, 71, 100, -153, 89, 66, 100, -152, 90, 66, 100, -150, 89, 67, 100, -139, 81, 65, 100, -128, 77, 64, 100, -120, 72, 58, 100, -94, 53, 39, 100, -91, 53, 46, 100, -98, 60, 60, 100, -98, 58, 59, 100, -104, 65, 62, 100, -104, 64, 57, 100, -107, 67, 58, 100, -109, 68, 54, 100, -113, 73, 56, 100, -120, 79, 63, 100, -123, 83, 67, 100, -124, 85, 67, 100, -126, 87, 71, 100, -134, 96, 81, 100, -136, 100, 87, 100, -139, 103, 91, 100, -141, 105, 93, 100, -139, 104, 92, 100, -141, 105, 93, 100, -143, 108, 96, 100, -147, 112, 100, 100, -148, 113, 102, 100, -151, 118, 109, 100, -149, 115, 105, 100, -142, 108, 98, 100, -146, 111, 101, 100, -141, 108, 95, 100, -134, 105, 91, 100, -140, 110, 99, 100, -145, 116, 105, 100, -146, 116, 107, 100, -144, 115, 107, 100, -144, 114, 105, 100, -142, 111, 102, 100, -151, 119, 115, 100, -154, 123, 119, 100, -145, 114, 109, 100, -143, 111, 104, 100, -145, 111, 104, 100, -150, 118, 108, 100, -146, 114, 105, 100, -142, 109, 104, 100, -139, 109, 104, 100, -142, 112, 106, 100, -131, 99, 94, 100, -143, 157, 123, 100, -153, 163, 130, 100, -162, 168, 135, 100, -159, 162, 130, 100, -143, 144, 113, 100, -135, 135, 106, 100, -137, 138, 110, 100, -143, 144, 117, 100, -145, 146, 120, 100, -141, 143, 119, 100, -122, 122, 100, 100, -96, 93, 72, 100, -77, 72, 53, 100, -75, 67, 50, 100, -89, 82, 68, 100, -83, 72, 60, 100, -81, 67, 57, 100, -87, 71, 61, 100, -93, 75, 67, 100, -101, 82, 73, 100, -110, 92, 82, 100, -116, 98, 87, 100, -119, 99, 88, 100, -120, 97, 89, 100, -123, 99, 93, 100, -126, 104, 98, 100, -129, 105, 99, 100, -128, 103, 98, 100, -131, 108, 102, 100, -134, 111, 105, 100, -135, 112, 106, 100, -135, 112, 105, 100, -130, 107, 101, 100, -132, 108, 102, 100, -133, 106, 101, 100, -138, 109, 105, 100, -137, 108, 104, 100, -134, 105, 101, 100, -135, 105, 102, 100, -134, 104, 100, 100, -132, 101, 98, 100, -131, 100, 96, 100, -125, 93, 90, 100, -122, 90, 85, 100, -116, 80, 76, 100, -109, 71, 68, 100, -110, 75, 71, 100, -111, 79, 77, 100, -112, 76, 74, 100, -109, 73, 71, 100, -102, 68, 65, 100, -100, 63, 63, 100, -90, 57, 60, 100, -79, 48, 52, 100, -104, 56, 49, 100, -131, 69, 55, 100, -137, 73, 56, 100, -142, 77, 61, 100, -141, 77, 61, 100, -127, 72, 55, 100, -124, 71, 53, 100, -138, 78, 60, 100, -149, 84, 66, 100, -155, 89, 71, 100, -172, 106, 87, 100, -176, 113, 92, 100, -171, 107, 88, 100, -175, 111, 91, 100, -166, 101, 81, 100, -157, 92, 69, 100, -152, 88, 63, 100, -148, 84, 61, 100, -143, 85, 63, 100, -139, 87, 68, 100, -125, 76, 60, 100, -100, 57, 44, 100, -87, 46, 40, 100, -95, 56, 56, 100, -93, 56, 54, 100, -98, 59, 58, 100, -96, 55, 52, 100, -105, 64, 57, 100, -106, 66, 55, 100, -109, 69, 56, 100, -113, 74, 58, 100, -118, 79, 64, 100, -121, 82, 67, 100, -124, 85, 69, 100, -131, 93, 76, 100, -133, 95, 81, 100, -136, 98, 87, 100, -138, 102, 90, 100, -137, 103, 92, 100, -137, 103, 92, 100, -138, 103, 93, 100, -145, 111, 101, 100, -146, 112, 102, 100, -146, 112, 101, 100, -146, 112, 102, 100, -138, 104, 94, 100, -144, 113, 103, 100, -143, 113, 101, 100, -137, 107, 96, 100, -139, 110, 102, 100, -146, 118, 111, 100, -145, 117, 111, 100, -140, 110, 105, 100, -140, 109, 103, 100, -135, 104, 95, 100, -141, 110, 104, 100, -148, 118, 113, 100, -143, 112, 107, 100, -137, 106, 101, 100, -139, 108, 103, 100, -143, 113, 106, 100, -141, 111, 104, 100, -139, 108, 102, 100, -151, 121, 117, 100, -150, 119, 114, 100, -139, 108, 103, 100, -154, 167, 140, 100, -154, 167, 141, 100, -156, 168, 142, 100, -159, 173, 146, 100, -162, 177, 151, 100, -163, 177, 152, 100, -163, 179, 154, 100, -162, 179, 153, 100, -160, 175, 151, 100, -161, 176, 155, 100, -159, 174, 152, 100, -164, 177, 156, 100, -153, 166, 144, 100, -153, 165, 144, 100, -154, 168, 149, 100, -143, 155, 136, 100, -130, 140, 123, 100, -128, 131, 116, 100, -112, 113, 99, 100, -104, 103, 90, 100, -90, 84, 74, 100, -93, 80, 70, 100, -106, 90, 81, 100, -108, 92, 83, 100, -109, 91, 83, 100, -113, 93, 87, 100, -118, 97, 91, 100, -119, 97, 90, 100, -123, 99, 93, 100, -123, 100, 94, 100, -125, 102, 96, 100, -127, 104, 98, 100, -126, 103, 97, 100, -119, 97, 90, 100, -125, 103, 97, 100, -129, 106, 100, 100, -132, 104, 100, 100, -132, 103, 99, 100, -130, 100, 95, 100, -128, 97, 94, 100, -129, 99, 94, 100, -128, 97, 92, 100, -124, 93, 88, 100, -122, 91, 87, 100, -118, 83, 79, 100, -116, 79, 76, 100, -112, 78, 74, 100, -109, 77, 74, 100, -110, 74, 73, 100, -106, 71, 69, 100, -101, 66, 64, 100, -97, 57, 58, 100, -89, 51, 51, 100, -112, 62, 55, 100, -140, 75, 60, 100, -150, 81, 65, 100, -154, 87, 69, 100, -155, 88, 72, 100, -145, 84, 66, 100, -122, 71, 56, 100, -119, 67, 50, 100, -138, 79, 62, 100, -151, 86, 71, 100, -158, 92, 76, 100, -170, 105, 88, 100, -178, 115, 98, 100, -181, 119, 101, 100, -179, 118, 100, 100, -168, 102, 84, 100, -159, 92, 71, 100, -159, 92, 69, 100, -151, 86, 61, 100, -140, 79, 57, 100, -139, 83, 63, 100, -133, 84, 65, 100, -108, 62, 49, 100, -84, 42, 36, 100, -94, 57, 56, 100, -98, 62, 61, 100, -98, 60, 59, 100, -93, 53, 48, 100, -101, 61, 54, 100, -106, 66, 58, 100, -106, 66, 55, 100, -109, 70, 55, 100, -114, 75, 60, 100, -119, 80, 65, 100, -120, 81, 66, 100, -127, 88, 72, 100, -130, 91, 75, 100, -134, 95, 81, 100, -135, 99, 87, 100, -134, 100, 88, 100, -136, 102, 92, 100, -135, 101, 91, 100, -138, 105, 95, 100, -143, 112, 102, 100, -141, 109, 100, 100, -145, 111, 102, 100, -139, 107, 97, 100, -141, 111, 101, 100, -144, 115, 107, 100, -143, 114, 108, 100, -144, 115, 109, 100, -141, 112, 108, 100, -138, 110, 105, 100, -134, 105, 98, 100, -136, 106, 98, 100, -137, 107, 100, 100, -131, 101, 92, 100, -140, 110, 104, 100, -141, 112, 106, 100, -140, 110, 104, 100, -140, 110, 104, 100, -142, 112, 107, 100, -140, 110, 107, 100, -138, 107, 103, 100, -145, 114, 111, 100, -145, 114, 110, 100, -133, 102, 97, 100, -156, 171, 146, 100, -149, 167, 141, 100, -146, 163, 138, 100, -150, 169, 144, 100, -141, 160, 135, 100, -141, 159, 136, 100, -134, 154, 128, 100, -136, 156, 133, 100, -140, 158, 137, 100, -143, 162, 141, 100, -143, 161, 142, 100, -147, 164, 145, 100, -143, 161, 142, 100, -148, 166, 148, 100, -141, 161, 142, 100, -136, 157, 137, 100, -138, 159, 139, 100, -140, 158, 139, 100, -141, 160, 141, 100, -140, 159, 142, 100, -122, 138, 124, 100, -85, 91, 82, 100, -71, 66, 58, 100, -88, 76, 70, 100, -100, 85, 76, 100, -103, 86, 80, 100, -107, 89, 83, 100, -109, 87, 81, 100, -113, 89, 83, 100, -111, 89, 83, 100, -110, 88, 82, 100, -118, 95, 89, 100, -111, 88, 82, 100, -115, 92, 86, 100, -118, 95, 89, 100, -118, 93, 88, 100, -125, 96, 93, 100, -122, 94, 90, 100, -123, 93, 89, 100, -125, 95, 91, 100, -123, 94, 90, 100, -122, 92, 87, 100, -121, 90, 85, 100, -117, 87, 82, 100, -113, 82, 77, 100, -112, 81, 77, 100, -111, 77, 73, 100, -107, 72, 70, 100, -102, 68, 66, 100, -102, 68, 65, 100, -96, 62, 60, 100, -94, 54, 52, 100, -119, 66, 52, 100, -143, 76, 60, 100, -151, 81, 66, 100, -156, 87, 72, 100, -158, 90, 72, 100, -159, 95, 78, 100, -153, 98, 81, 100, -124, 75, 60, 100, -117, 69, 52, 100, -139, 81, 65, 100, -149, 85, 72, 100, -158, 94, 81, 100, -168, 104, 93, 100, -170, 106, 96, 100, -174, 112, 100, 100, -173, 111, 96, 100, -168, 102, 85, 100, -161, 94, 74, 100, -159, 91, 72, 100, -155, 89, 67, 100, -143, 79, 58, 100, -140, 78, 57, 100, -139, 84, 65, 100, -119, 71, 56, 100, -82, 40, 30, 100, -90, 53, 51, 100, -94, 60, 59, 100, -96, 60, 57, 100, -93, 54, 48, 100, -95, 56, 50, 100, -102, 62, 53, 100, -104, 64, 52, 100, -109, 69, 56, 100, -111, 72, 57, 100, -114, 75, 60, 100, -120, 81, 66, 100, -123, 84, 69, 100, -129, 90, 74, 100, -131, 95, 82, 100, -132, 96, 86, 100, -133, 98, 88, 100, -133, 99, 89, 100, -136, 102, 90, 100, -133, 99, 89, 100, -136, 103, 93, 100, -139, 106, 96, 100, -141, 107, 98, 100, -132, 102, 93, 100, -134, 104, 94, 100, -142, 112, 106, 100, -143, 114, 107, 100, -136, 107, 100, 100, -130, 101, 94, 100, -135, 107, 100, 100, -133, 104, 96, 100, -130, 100, 90, 100, -130, 100, 91, 100, -123, 94, 84, 100, -131, 102, 94, 100, -133, 104, 98, 100, -136, 107, 102, 100, -135, 106, 102, 100, -137, 108, 103, 100, -142, 114, 110, 100, -133, 103, 98, 100, -137, 106, 101, 100, -131, 102, 96, 100, -124, 94, 85, 100, -140, 158, 136, 100, -139, 157, 132, 100, -137, 156, 132, 100, -143, 162, 141, 100, -135, 154, 132, 100, -130, 148, 127, 100, -136, 155, 134, 100, -136, 155, 134, 100, -129, 150, 129, 100, -138, 157, 137, 100, -138, 157, 137, 100, -135, 155, 135, 100, -136, 156, 139, 100, -144, 164, 146, 100, -144, 166, 148, 100, -133, 154, 135, 100, -126, 149, 127, 100, -113, 137, 116, 100, -112, 138, 120, 100, -123, 148, 132, 100, -111, 139, 122, 100, -108, 135, 123, 100, -80, 100, 94, 100, -56, 66, 63, 100, -60, 57, 56, 100, -75, 63, 59, 100, -90, 75, 70, 100, -96, 79, 72, 100, -105, 83, 78, 100, -105, 85, 79, 100, -106, 86, 79, 100, -103, 82, 75, 100, -103, 81, 75, 100, -113, 90, 84, 100, -113, 91, 85, 100, -113, 89, 83, 100, -118, 89, 85, 100, -119, 89, 86, 100, -118, 89, 84, 100, -119, 89, 85, 100, -119, 90, 86, 100, -115, 86, 82, 100, -112, 84, 79, 100, -114, 85, 80, 100, -110, 79, 75, 100, -105, 75, 72, 100, -103, 72, 68, 100, -101, 68, 65, 100, -97, 65, 63, 100, -92, 62, 58, 100, -89, 55, 53, 100, -115, 64, 56, 100, -138, 74, 58, 100, -143, 77, 62, 100, -150, 81, 68, 100, -156, 88, 75, 100, -157, 90, 76, 100, -159, 97, 84, 100, -154, 100, 87, 100, -118, 69, 58, 100, -109, 60, 49, 100, -138, 79, 68, 100, -150, 88, 77, 100, -159, 96, 89, 100, -164, 100, 98, 100, -167, 104, 101, 100, -168, 104, 101, 100, -165, 100, 94, 100, -160, 93, 80, 100, -156, 89, 70, 100, -158, 90, 71, 100, -155, 87, 68, 100, -144, 79, 58, 100, -139, 76, 55, 100, -142, 82, 62, 100, -124, 73, 55, 100, -86, 43, 31, 100, -86, 50, 43, 100, -86, 55, 52, 100, -96, 62, 60, 100, -94, 57, 54, 100, -92, 55, 48, 100, -95, 56, 47, 100, -100, 61, 51, 100, -105, 66, 55, 100, -110, 70, 56, 100, -114, 76, 60, 100, -119, 80, 65, 100, -123, 84, 71, 100, -128, 89, 75, 100, -128, 94, 81, 100, -128, 97, 84, 100, -131, 98, 86, 100, -132, 98, 88, 100, -134, 100, 89, 100, -133, 99, 88, 100, -133, 98, 90, 100, -138, 104, 97, 100, -140, 105, 99, 100, -133, 102, 96, 100, -132, 102, 92, 100, -141, 110, 103, 100, -133, 104, 94, 100, -129, 101, 90, 100, -133, 104, 93, 100, -130, 101, 90, 100, -132, 103, 92, 100, -129, 99, 89, 100, -125, 95, 85, 100, -128, 98, 88, 100, -127, 98, 90, 100, -130, 102, 96, 100, -130, 101, 96, 100, -132, 103, 99, 100, -139, 110, 106, 100, -140, 112, 108, 100, -125, 96, 89, 100, -123, 95, 84, 100, -126, 97, 90, 100, -124, 94, 88, 100, -141, 159, 135, 100, -137, 155, 133, 100, -143, 161, 139, 100, -136, 155, 134, 100, -135, 153, 132, 100, -137, 156, 134, 100, -145, 163, 143, 100, -139, 158, 138, 100, -133, 154, 134, 100, -142, 160, 141, 100, -143, 161, 141, 100, -133, 153, 133, 100, -124, 148, 127, 100, -132, 156, 137, 100, -128, 152, 134, 100, -123, 148, 129, 100, -129, 152, 131, 100, -129, 151, 129, 100, -114, 139, 117, 100, -104, 129, 110, 100, -94, 121, 105, 100, -104, 131, 118, 100, -97, 123, 113, 100, -79, 102, 100, 100, -56, 76, 77, 100, -38, 43, 45, 100, -36, 30, 31, 100, -59, 46, 42, 100, -79, 62, 59, 100, -87, 72, 66, 100, -89, 74, 66, 100, -91, 73, 65, 100, -98, 79, 72, 100, -100, 81, 74, 100, -99, 80, 73, 100, -100, 81, 74, 100, -103, 82, 75, 100, -105, 81, 75, 100, -105, 79, 74, 100, -106, 80, 75, 100, -108, 82, 77, 100, -106, 79, 75, 100, -106, 77, 73, 100, -103, 78, 73, 100, -100, 74, 69, 100, -100, 72, 68, 100, -99, 70, 65, 100, -94, 65, 61, 100, -91, 61, 57, 100, -83, 55, 52, 100, -95, 56, 50, 100, -122, 61, 52, 100, -133, 68, 57, 100, -141, 76, 61, 100, -146, 79, 65, 100, -155, 89, 75, 100, -152, 86, 76, 100, -144, 84, 77, 100, -147, 91, 86, 100, -115, 65, 59, 100, -99, 52, 44, 100, -127, 71, 61, 100, -139, 81, 74, 100, -150, 89, 84, 100, -159, 97, 98, 100, -162, 97, 99, 100, -164, 100, 99, 100, -165, 100, 98, 100, -160, 94, 83, 100, -158, 92, 73, 100, -157, 91, 71, 100, -151, 83, 64, 100, -144, 77, 58, 100, -138, 73, 53, 100, -141, 77, 56, 100, -128, 71, 54, 100, -90, 44, 31, 100, -82, 46, 38, 100, -83, 52, 49, 100, -92, 61, 58, 100, -91, 57, 53, 100, -91, 56, 48, 100, -94, 57, 49, 100, -97, 61, 52, 100, -101, 65, 53, 100, -106, 67, 53, 100, -110, 71, 56, 100, -115, 75, 63, 100, -121, 80, 71, 100, -126, 89, 76, 100, -124, 92, 80, 100, -123, 95, 83, 100, -128, 96, 84, 100, -132, 97, 88, 100, -132, 98, 89, 100, -133, 99, 90, 100, -133, 98, 91, 100, -136, 100, 94, 100, -139, 106, 101, 100, -133, 103, 94, 100, -130, 100, 89, 100, -133, 103, 93, 100, -137, 108, 97, 100, -134, 106, 95, 100, -128, 98, 88, 100, -128, 98, 88, 100, -130, 100, 90, 100, -130, 100, 89, 100, -125, 95, 85, 100, -116, 86, 77, 100, -120, 92, 83, 100, -128, 99, 92, 100, -128, 99, 94, 100, -135, 106, 102, 100, -131, 102, 97, 100, -130, 100, 93, 100, -124, 95, 86, 100, -125, 96, 86, 100, -126, 98, 87, 100, -126, 97, 92, 100, -139, 157, 131, 100, -143, 161, 136, 100, -138, 156, 133, 100, -137, 156, 133, 100, -140, 158, 136, 100, -142, 160, 138, 100, -136, 153, 131, 100, -133, 151, 130, 100, -145, 162, 142, 100, -138, 155, 136, 100, -137, 155, 135, 100, -137, 154, 135, 100, -140, 158, 138, 100, -134, 153, 133, 100, -134, 155, 135, 100, -130, 150, 130, 100, -131, 150, 130, 100, -136, 153, 133, 100, -137, 153, 132, 100, -128, 146, 124, 100, -131, 151, 132, 100, -133, 152, 134, 100, -125, 142, 125, 100, -113, 130, 116, 100, -101, 117, 106, 100, -66, 82, 76, 100, -52, 61, 61, 100, -52, 54, 48, 100, -56, 54, 49, 100, -56, 51, 46, 100, -54, 45, 38, 100, -63, 52, 43, 100, -67, 54, 45, 100, -68, 54, 45, 100, -72, 57, 49, 100, -79, 60, 53, 100, -83, 64, 57, 100, -86, 67, 60, 100, -88, 69, 62, 100, -91, 71, 64, 100, -91, 70, 63, 100, -90, 67, 61, 100, -93, 69, 63, 100, -93, 72, 65, 100, -94, 71, 65, 100, -91, 68, 62, 100, -89, 65, 59, 100, -86, 61, 56, 100, -85, 57, 53, 100, -76, 49, 44, 100, -100, 55, 44, 100, -122, 63, 50, 100, -130, 65, 54, 100, -136, 68, 58, 100, -142, 76, 65, 100, -146, 80, 71, 100, -143, 77, 74, 100, -137, 77, 75, 100, -131, 74, 69, 100, -115, 64, 60, 100, -91, 48, 42, 100, -111, 63, 57, 100, -131, 74, 71, 100, -140, 80, 77, 100, -150, 87, 88, 100, -154, 90, 91, 100, -156, 94, 94, 100, -156, 92, 89, 100, -150, 85, 73, 100, -153, 87, 72, 100, -151, 86, 67, 100, -149, 81, 62, 100, -145, 77, 58, 100, -141, 74, 55, 100, -143, 77, 57, 100, -134, 72, 53, 100, -92, 45, 31, 100, -76, 39, 32, 100, -80, 47, 45, 100, -89, 59, 56, 100, -88, 57, 53, 100, -88, 57, 51, 100, -90, 56, 48, 100, -93, 58, 49, 100, -99, 63, 52, 100, -103, 64, 53, 100, -107, 70, 57, 100, -110, 74, 63, 100, -115, 77, 67, 100, -119, 82, 74, 100, -118, 87, 78, 100, -120, 90, 82, 100, -129, 96, 89, 100, -126, 92, 83, 100, -129, 97, 87, 100, -130, 96, 87, 100, -129, 95, 86, 100, -131, 97, 88, 100, -134, 104, 95, 100, -130, 100, 90, 100, -126, 97, 86, 100, -127, 98, 88, 100, -131, 101, 91, 100, -130, 101, 91, 100, -125, 96, 86, 100, -128, 98, 91, 100, -127, 97, 86, 100, -126, 97, 86, 100, -124, 95, 85, 100, -113, 85, 75, 100, -116, 88, 74, 100, -119, 90, 80, 100, -120, 92, 86, 100, -128, 99, 94, 100, -120, 91, 85, 100, -120, 91, 85, 100, -118, 89, 83, 100, -115, 87, 78, 100, -120, 91, 84, 100, -114, 86, 78, 100, -158, 171, 146, 100, -157, 171, 145, 100, -155, 169, 144, 100, -153, 168, 143, 100, -157, 171, 146, 100, -161, 174, 149, 100, -160, 173, 148, 100, -157, 171, 149, 100, -164, 177, 157, 100, -162, 175, 155, 100, -163, 177, 156, 100, -164, 176, 156, 100, -168, 180, 160, 100, -164, 177, 158, 100, -167, 179, 161, 100, -165, 178, 160, 100, -163, 176, 158, 100, -162, 175, 155, 100, -166, 178, 158, 100, -168, 180, 161, 100, -165, 178, 160, 100, -166, 179, 160, 100, -165, 177, 159, 100, -164, 175, 157, 100, -157, 169, 150, 100, -156, 168, 151, 100, -165, 178, 163, 100, -161, 173, 159, 100, -151, 162, 150, 100, -126, 137, 123, 100, -124, 132, 119, 100, -132, 139, 125, 100, -126, 133, 117, 100, -114, 116, 102, 100, -102, 101, 87, 100, -80, 71, 59, 100, -72, 61, 50, 100, -64, 51, 42, 100, -69, 54, 45, 100, -72, 57, 48, 100, -78, 64, 55, 100, -80, 66, 57, 100, -78, 61, 53, 100, -71, 50, 44, 100, -75, 54, 47, 100, -82, 61, 55, 100, -81, 61, 54, 100, -79, 57, 51, 100, -74, 52, 46, 100, -72, 46, 41, 100, -108, 59, 48, 100, -121, 65, 50, 100, -128, 67, 52, 100, -131, 66, 55, 100, -133, 68, 60, 100, -139, 75, 70, 100, -138, 77, 76, 100, -131, 71, 69, 100, -124, 65, 61, 100, -113, 59, 57, 100, -92, 48, 46, 100, -95, 52, 46, 100, -120, 68, 62, 100, -134, 75, 72, 100, -142, 81, 80, 100, -144, 84, 84, 100, -144, 84, 83, 100, -145, 82, 78, 100, -143, 77, 70, 100, -144, 76, 69, 100, -141, 72, 61, 100, -140, 71, 55, 100, -140, 72, 54, 100, -140, 72, 53, 100, -140, 72, 54, 100, -135, 71, 54, 100, -95, 49, 33, 100, -76, 37, 28, 100, -78, 43, 40, 100, -82, 51, 50, 100, -86, 54, 54, 100, -89, 59, 53, 100, -88, 58, 49, 100, -87, 56, 46, 100, -94, 59, 49, 100, -99, 63, 52, 100, -101, 66, 55, 100, -106, 72, 62, 100, -107, 73, 64, 100, -110, 75, 69, 100, -116, 84, 78, 100, -117, 87, 80, 100, -122, 91, 85, 100, -123, 91, 82, 100, -126, 95, 85, 100, -126, 95, 85, 100, -123, 92, 82, 100, -126, 95, 86, 100, -126, 96, 86, 100, -123, 92, 82, 100, -116, 87, 76, 100, -116, 89, 77, 100, -124, 95, 85, 100, -130, 100, 92, 100, -120, 91, 79, 100, -115, 86, 75, 100, -121, 93, 83, 100, -124, 95, 85, 100, -122, 93, 83, 100, -118, 90, 79, 100, -115, 87, 75, 100, -115, 87, 76, 100, -107, 78, 69, 100, -115, 86, 79, 100, -115, 86, 80, 100, -104, 75, 67, 100, -107, 78, 68, 100, -104, 74, 65, 100, -112, 83, 75, 100, -116, 88, 77, 100, -170, 180, 156, 100, -169, 180, 157, 100, -169, 180, 158, 100, -171, 183, 160, 100, -169, 182, 159, 100, -172, 183, 160, 100, -172, 184, 161, 100, -171, 183, 163, 100, -175, 187, 167, 100, -173, 184, 164, 100, -173, 184, 165, 100, -171, 183, 163, 100, -170, 182, 162, 100, -169, 182, 162, 100, -171, 184, 165, 100, -172, 184, 167, 100, -173, 184, 166, 100, -172, 184, 164, 100, -171, 183, 163, 100, -172, 183, 165, 100, -170, 181, 164, 100, -171, 182, 166, 100, -171, 182, 165, 100, -168, 179, 163, 100, -169, 180, 163, 100, -169, 181, 163, 100, -168, 180, 164, 100, -168, 180, 165, 100, -164, 177, 161, 100, -166, 180, 163, 100, -162, 177, 157, 100, -163, 176, 158, 100, -160, 173, 155, 100, -165, 177, 160, 100, -162, 174, 157, 100, -160, 169, 151, 100, -156, 164, 147, 100, -144, 150, 135, 100, -144, 150, 135, 100, -142, 147, 132, 100, -147, 153, 137, 100, -146, 153, 137, 100, -142, 145, 130, 100, -114, 109, 97, 100, -84, 74, 63, 100, -60, 42, 34, 100, -57, 38, 31, 100, -66, 46, 39, 100, -69, 48, 41, 100, -72, 45, 39, 100, -107, 63, 49, 100, -118, 63, 46, 100, -122, 63, 51, 100, -128, 68, 57, 100, -126, 64, 53, 100, -128, 68, 59, 100, -139, 84, 79, 100, -141, 86, 81, 100, -137, 79, 75, 100, -115, 61, 57, 100, -90, 47, 47, 100, -83, 42, 37, 100, -100, 55, 46, 100, -113, 60, 57, 100, -124, 68, 65, 100, -133, 74, 73, 100, -138, 79, 76, 100, -138, 76, 73, 100, -139, 75, 70, 100, -139, 74, 66, 100, -138, 72, 63, 100, -137, 69, 56, 100, -142, 74, 57, 100, -141, 74, 56, 100, -135, 68, 52, 100, -130, 66, 49, 100, -93, 46, 30, 100, -73, 36, 25, 100, -77, 42, 39, 100, -81, 52, 49, 100, -83, 55, 54, 100, -90, 62, 58, 100, -95, 64, 59, 100, -89, 58, 50, 100, -92, 58, 49, 100, -93, 58, 48, 100, -97, 63, 51, 100, -100, 66, 56, 100, -101, 70, 60, 100, -104, 72, 63, 100, -111, 80, 70, 100, -114, 84, 74, 100, -117, 87, 77, 100, -123, 92, 82, 100, -122, 91, 81, 100, -124, 96, 85, 100, -116, 88, 76, 100, -116, 88, 76, 100, -124, 99, 88, 100, -137, 116, 105, 100, -129, 102, 94, 100, -125, 98, 90, 100, -108, 78, 69, 100, -111, 78, 70, 100, -136, 111, 102, 100, -136, 112, 104, 100, -109, 80, 73, 100, -118, 91, 83, 100, -114, 86, 77, 100, -122, 95, 86, 100, -121, 93, 87, 100, -101, 72, 60, 100, -118, 92, 82, 100, -109, 83, 74, 100, -92, 64, 54, 100, -116, 90, 81, 100, -108, 80, 74, 100, -112, 86, 80, 100, -107, 79, 69, 100, -112, 84, 74, 100, -173, 184, 159, 100, -172, 183, 161, 100, -173, 184, 165, 100, -173, 184, 165, 100, -171, 183, 164, 100, -170, 183, 162, 100, -172, 184, 164, 100, -171, 184, 164, 100, -172, 184, 164, 100, -169, 181, 161, 100, -173, 185, 165, 100, -174, 184, 165, 100, -172, 182, 163, 100, -170, 180, 161, 100, -172, 182, 164, 100, -173, 184, 167, 100, -171, 182, 163, 100, -172, 182, 163, 100, -171, 181, 161, 100, -172, 182, 164, 100, -170, 180, 162, 100, -171, 180, 162, 100, -171, 181, 163, 100, -172, 181, 165, 100, -168, 179, 162, 100, -167, 178, 161, 100, -167, 177, 160, 100, -167, 178, 162, 100, -166, 178, 160, 100, -164, 176, 158, 100, -163, 175, 158, 100, -162, 174, 156, 100, -165, 176, 159, 100, -167, 177, 161, 100, -162, 172, 156, 100, -164, 176, 159, 100, -164, 176, 159, 100, -163, 175, 157, 100, -165, 177, 158, 100, -166, 176, 159, 100, -161, 172, 155, 100, -155, 166, 149, 100, -154, 164, 146, 100, -153, 162, 143, 100, -149, 158, 138, 100, -117, 119, 104, 100, -85, 81, 69, 100, -87, 78, 66, 100, -64, 48, 39, 100, -59, 39, 29, 100, -85, 48, 35, 100, -107, 55, 41, 100, -115, 58, 45, 100, -115, 56, 45, 100, -111, 53, 43, 100, -104, 46, 40, 100, -101, 48, 43, 100, -111, 57, 52, 100, -122, 67, 62, 100, -128, 71, 65, 100, -109, 59, 55, 100, -77, 36, 31, 100, -88, 48, 41, 100, -102, 56, 50, 100, -110, 58, 54, 100, -119, 63, 61, 100, -127, 69, 66, 100, -129, 69, 65, 100, -135, 74, 68, 100, -137, 75, 66, 100, -136, 71, 61, 100, -132, 68, 56, 100, -132, 68, 53, 100, -132, 66, 52, 100, -128, 63, 46, 100, -116, 53, 38, 100, -84, 39, 26, 100, -71, 36, 25, 100, -73, 41, 37, 100, -77, 49, 46, 100, -81, 56, 55, 100, -87, 60, 56, 100, -93, 64, 60, 100, -91, 61, 56, 100, -89, 59, 50, 100, -88, 57, 47, 100, -90, 58, 47, 100, -92, 61, 49, 100, -93, 63, 54, 100, -99, 69, 58, 100, -104, 74, 63, 100, -109, 79, 67, 100, -113, 84, 73, 100, -114, 83, 73, 100, -115, 86, 75, 100, -110, 82, 70, 100, -143, 122, 113, 100, -137, 117, 108, 100, -156, 141, 133, 100, -184, 175, 168, 100, -171, 158, 152, 100, -144, 124, 117, 100, -146, 127, 120, 100, -156, 138, 133, 100, -165, 149, 142, 100, -142, 122, 117, 100, -94, 64, 60, 100, -134, 114, 108, 100, -130, 111, 103, 100, -121, 99, 91, 100, -174, 162, 156, 100, -163, 150, 145, 100, -169, 155, 150, 100, -156, 139, 134, 100, -144, 129, 121, 100, -155, 141, 135, 100, -152, 135, 128, 100, -138, 121, 114, 100, -101, 75, 66, 100, -105, 78, 67, 100, -177, 187, 163, 100, -174, 185, 161, 100, -176, 186, 165, 100, -177, 185, 166, 100, -176, 185, 166, 100, -174, 184, 165, 100, -173, 183, 163, 100, -175, 184, 165, 100, -174, 183, 164, 100, -172, 181, 162, 100, -174, 183, 164, 100, -176, 184, 165, 100, -174, 183, 164, 100, -174, 182, 164, 100, -174, 183, 165, 100, -173, 182, 164, 100, -172, 181, 162, 100, -173, 181, 162, 100, -173, 182, 163, 100, -174, 183, 164, 100, -174, 182, 163, 100, -172, 181, 162, 100, -173, 182, 164, 100, -173, 182, 165, 100, -173, 182, 165, 100, -174, 183, 164, 100, -173, 181, 164, 100, -173, 181, 165, 100, -169, 179, 162, 100, -172, 183, 166, 100, -171, 181, 164, 100, -171, 182, 165, 100, -170, 181, 164, 100, -169, 179, 162, 100, -170, 181, 164, 100, -170, 180, 163, 100, -169, 179, 162, 100, -171, 181, 163, 100, -171, 181, 163, 100, -171, 179, 161, 100, -171, 180, 163, 100, -171, 179, 162, 100, -167, 176, 157, 100, -166, 175, 156, 100, -165, 174, 155, 100, -170, 180, 162, 100, -170, 180, 163, 100, -162, 171, 151, 100, -148, 151, 134, 100, -129, 127, 109, 100, -104, 92, 72, 100, -101, 68, 53, 100, -104, 60, 45, 100, -121, 75, 59, 100, -125, 78, 66, 100, -121, 76, 66, 100, -113, 67, 56, 100, -116, 74, 64, 100, -116, 77, 68, 100, -116, 78, 71, 100, -112, 72, 64, 100, -87, 52, 43, 100, -75, 39, 31, 100, -84, 41, 34, 100, -101, 53, 48, 100, -109, 58, 54, 100, -112, 60, 56, 100, -116, 63, 58, 100, -119, 64, 56, 100, -123, 65, 57, 100, -126, 66, 56, 100, -129, 67, 56, 100, -128, 65, 53, 100, -125, 63, 49, 100, -115, 56, 42, 100, -100, 45, 33, 100, -77, 39, 26, 100, -73, 40, 29, 100, -68, 40, 34, 100, -72, 48, 43, 100, -76, 54, 50, 100, -85, 61, 57, 100, -90, 62, 58, 100, -90, 62, 56, 100, -87, 59, 50, 100, -86, 57, 46, 100, -85, 55, 45, 100, -85, 56, 45, 100, -87, 59, 48, 100, -90, 61, 49, 100, -95, 66, 54, 100, -99, 70, 57, 100, -103, 74, 63, 100, -103, 77, 64, 100, -98, 75, 61, 100, -88, 66, 54, 100, -152, 140, 133, 100, -158, 146, 138, 100, -167, 158, 148, 100, -183, 175, 167, 100, -174, 164, 157, 100, -176, 163, 158, 100, -165, 150, 144, 100, -175, 163, 157, 100, -152, 137, 130, 100, -120, 100, 91, 100, -85, 58, 47, 100, -129, 110, 102, 100, -144, 128, 125, 100, -136, 119, 114, 100, -171, 160, 155, 100, -157, 141, 137, 100, -155, 141, 135, 100, -186, 176, 173, 100, -190, 180, 178, 100, -138, 121, 115, 100, -185, 177, 171, 100, -92, 69, 62, 100, -93, 69, 62, 100, -94, 68, 60, 100, -177, 186, 167, 100, -178, 187, 166, 100, -177, 184, 164, 100, -176, 184, 166, 100, -175, 184, 165, 100, -176, 184, 165, 100, -178, 187, 168, 100, -177, 186, 167, 100, -176, 185, 166, 100, -178, 187, 168, 100, -177, 189, 169, 100, -176, 186, 167, 100, -178, 187, 168, 100, -177, 186, 168, 100, -176, 185, 167, 100, -176, 185, 166, 100, -176, 185, 166, 100, -176, 185, 166, 100, -178, 187, 168, 100, -177, 186, 167, 100, -177, 186, 167, 100, -178, 187, 168, 100, -177, 186, 169, 100, -178, 187, 170, 100, -176, 185, 167, 100, -176, 185, 168, 100, -175, 185, 168, 100, -180, 188, 171, 100, -178, 187, 170, 100, -180, 189, 173, 100, -177, 186, 169, 100, -177, 186, 169, 100, -176, 185, 169, 100, -177, 186, 168, 100, -178, 188, 170, 100, -177, 186, 169, 100, -176, 185, 168, 100, -177, 186, 169, 100, -177, 186, 169, 100, -175, 184, 167, 100, -175, 184, 168, 100, -175, 184, 167, 100, -172, 181, 164, 100, -174, 183, 166, 100, -171, 180, 163, 100, -170, 179, 162, 100, -168, 177, 160, 100, -169, 175, 159, 100, -174, 179, 162, 100, -175, 179, 162, 100, -176, 181, 164, 100, -171, 174, 155, 100, -167, 167, 150, 100, -174, 173, 156, 100, -179, 178, 160, 100, -178, 179, 162, 100, -175, 174, 156, 100, -180, 180, 164, 100, -177, 179, 162, 100, -172, 176, 158, 100, -166, 170, 152, 100, -162, 163, 146, 100, -148, 145, 127, 100, -104, 81, 68, 100, -76, 39, 31, 100, -84, 41, 35, 100, -94, 47, 43, 100, -105, 59, 52, 100, -110, 62, 55, 100, -107, 58, 50, 100, -109, 57, 48, 100, -111, 58, 46, 100, -111, 56, 46, 100, -102, 51, 38, 100, -95, 49, 35, 100, -79, 39, 27, 100, -55, 27, 14, 100, -65, 39, 27, 100, -69, 49, 40, 100, -63, 43, 36, 100, -69, 48, 42, 100, -78, 52, 47, 100, -85, 54, 47, 100, -88, 59, 48, 100, -86, 57, 47, 100, -84, 53, 44, 100, -83, 53, 41, 100, -80, 52, 38, 100, -79, 52, 41, 100, -80, 55, 43, 100, -85, 60, 47, 100, -87, 61, 48, 100, -82, 57, 45, 100, -85, 65, 50, 100, -110, 99, 84, 100, -146, 142, 129, 100, -166, 168, 154, 100, -192, 196, 183, 100, -175, 184, 168, 100, -183, 190, 176, 100, -182, 189, 175, 100, -168, 172, 156, 100, -192, 192, 181, 100, -171, 166, 158, 100, -122, 111, 101, 100, -129, 118, 109, 100, -123, 109, 98, 100, -111, 93, 84, 100, -116, 98, 92, 100, -107, 86, 79, 100, -104, 84, 76, 100, -106, 87, 78, 100, -110, 92, 84, 100, -100, 83, 76, 100, -113, 96, 91, 100, -87, 66, 59, 100, -105, 89, 82, 100, -79, 58, 50, 100, -80, 60, 53, 100, -81, 59, 53, 100, -181, 190, 171, 100, -179, 188, 169, 100, -176, 185, 166, 100, -178, 187, 168, 100, -181, 190, 171, 100, -182, 191, 172, 100, -183, 192, 173, 100, -182, 191, 172, 100, -182, 191, 172, 100, -183, 193, 173, 100, -179, 191, 171, 100, -177, 189, 169, 100, -181, 190, 172, 100, -181, 190, 172, 100, -180, 190, 171, 100, -177, 186, 167, 100, -178, 187, 168, 100, -175, 184, 165, 100, -172, 181, 162, 100, -174, 183, 164, 100, -176, 184, 166, 100, -176, 184, 165, 100, -175, 183, 165, 100, -173, 183, 166, 100, -177, 186, 168, 100, -177, 186, 168, 100, -174, 183, 165, 100, -176, 185, 168, 100, -178, 187, 170, 100, -178, 188, 171, 100, -179, 188, 171, 100, -177, 186, 168, 100, -176, 185, 168, 100, -178, 187, 170, 100, -178, 187, 168, 100, -175, 184, 167, 100, -175, 184, 167, 100, -175, 184, 167, 100, -175, 184, 167, 100, -177, 186, 169, 100, -175, 184, 167, 100, -174, 183, 166, 100, -174, 183, 166, 100, -176, 185, 168, 100, -176, 184, 168, 100, -174, 182, 166, 100, -175, 184, 167, 100, -175, 185, 168, 100, -177, 185, 169, 100, -181, 188, 172, 100, -180, 186, 171, 100, -180, 189, 172, 100, -180, 190, 174, 100, -182, 190, 174, 100, -178, 186, 170, 100, -178, 185, 169, 100, -177, 187, 171, 100, -178, 188, 171, 100, -174, 184, 166, 100, -172, 182, 163, 100, -174, 184, 166, 100, -173, 183, 166, 100, -175, 185, 166, 100, -175, 181, 161, 100, -145, 139, 121, 100, -103, 85, 71, 100, -80, 53, 42, 100, -71, 36, 27, 100, -82, 46, 37, 100, -82, 43, 35, 100, -81, 41, 33, 100, -80, 41, 33, 100, -73, 33, 25, 100, -72, 35, 23, 100, -67, 36, 24, 100, -52, 30, 17, 100, -99, 91, 77, 100, -141, 142, 126, 100, -148, 153, 138, 100, -139, 138, 124, 100, -135, 131, 119, 100, -127, 120, 108, 100, -96, 76, 64, 100, -77, 49, 37, 100, -74, 43, 32, 100, -80, 51, 39, 100, -81, 51, 39, 100, -76, 48, 35, 100, -73, 46, 35, 100, -69, 48, 35, 100, -64, 42, 30, 100, -71, 51, 41, 100, -90, 80, 69, 100, -140, 140, 125, 100, -163, 172, 157, 100, -162, 174, 158, 100, -168, 181, 166, 100, -166, 177, 164, 100, -167, 178, 161, 100, -168, 180, 161, 100, -170, 181, 164, 100, -176, 187, 169, 100, -181, 191, 174, 100, -175, 185, 169, 100, -156, 162, 145, 100, -151, 154, 138, 100, -136, 133, 116, 100, -107, 97, 83, 100, -66, 50, 41, 100, -51, 30, 22, 100, -52, 31, 24, 100, -54, 33, 25, 100, -55, 34, 27, 100, -58, 37, 29, 100, -63, 45, 36, 100, -65, 48, 41, 100, -65, 47, 42, 100, -73, 55, 49, 100, -72, 52, 45, 100, -68, 50, 42, 100, -177, 185, 166, 100, -180, 189, 170, 100, -180, 189, 170, 100, -182, 191, 172, 100, -178, 187, 168, 100, -180, 189, 170, 100, -181, 190, 171, 100, -179, 188, 169, 100, -184, 193, 174, 100, -183, 191, 172, 100, -181, 190, 171, 100, -181, 191, 172, 100, -181, 192, 172, 100, -181, 190, 171, 100, -179, 188, 169, 100, -178, 188, 169, 100, -176, 185, 166, 100, -176, 185, 166, 100, -174, 183, 164, 100, -176, 185, 166, 100, -177, 186, 167, 100, -176, 185, 166, 100, -176, 184, 166, 100, -175, 185, 167, 100, -179, 187, 169, 100, -180, 187, 169, 100, -179, 188, 169, 100, -176, 185, 168, 100, -176, 185, 169, 100, -181, 190, 173, 100, -179, 188, 171, 100, -173, 182, 163, 100, -175, 184, 165, 100, -177, 186, 168, 100, -177, 186, 167, 100, -179, 188, 171, 100, -179, 188, 171, 100, -178, 187, 170, 100, -177, 186, 169, 100, -179, 188, 171, 100, -179, 188, 171, 100, -178, 187, 170, 100, -178, 188, 171, 100, -183, 193, 176, 100, -182, 192, 175, 100, -181, 191, 174, 100, -180, 190, 173, 100, -178, 187, 170, 100, -179, 189, 171, 100, -181, 192, 174, 100, -181, 191, 174, 100, -178, 189, 172, 100, -174, 185, 168, 100, -177, 189, 171, 100, -175, 186, 169, 100, -177, 187, 169, 100, -179, 188, 170, 100, -179, 187, 170, 100, -177, 186, 169, 100, -178, 187, 170, 100, -178, 187, 170, 100, -172, 180, 163, 100, -174, 179, 162, 100, -173, 178, 161, 100, -181, 185, 167, 100, -180, 183, 164, 100, -161, 162, 144, 100, -138, 134, 117, 100, -146, 142, 124, 100, -149, 144, 128, 100, -148, 146, 127, 100, -141, 138, 119, 100, -128, 120, 105, 100, -130, 126, 109, 100, -130, 129, 110, 100, -136, 137, 120, 100, -169, 179, 162, 100, -173, 186, 169, 100, -171, 183, 166, 100, -175, 187, 171, 100, -171, 183, 167, 100, -174, 185, 170, 100, -171, 180, 163, 100, -132, 126, 111, 100, -93, 72, 57, 100, -65, 37, 23, 100, -64, 35, 22, 100, -63, 37, 23, 100, -60, 38, 24, 100, -49, 30, 15, 100, -84, 74, 59, 100, -135, 137, 123, 100, -162, 172, 155, 100, -162, 174, 158, 100, -152, 164, 150, 100, -156, 168, 154, 100, -159, 172, 158, 100, -161, 173, 159, 100, -168, 179, 164, 100, -174, 185, 170, 100, -178, 189, 175, 100, -174, 185, 170, 100, -174, 185, 170, 100, -173, 184, 170, 100, -175, 186, 169, 100, -168, 178, 161, 100, -169, 177, 160, 100, -172, 180, 163, 100, -161, 164, 148, 100, -125, 123, 109, 100, -105, 102, 88, 100, -96, 87, 75, 100, -92, 83, 71, 100, -78, 66, 56, 100, -46, 33, 24, 100, -58, 45, 36, 100, -49, 37, 31, 100, -52, 39, 35, 100, -57, 43, 37, 100, -53, 40, 32, 100, -174, 185, 165, 100, -172, 182, 162, 100, -169, 178, 159, 100, -174, 184, 165, 100, -174, 184, 165, 100, -173, 182, 163, 100, -173, 182, 163, 100, -173, 182, 163, 100, -174, 183, 164, 100, -178, 187, 169, 100, -176, 185, 167, 100, -176, 184, 165, 100, -177, 186, 167, 100, -175, 184, 165, 100, -177, 186, 167, 100, -177, 187, 167, 100, -175, 184, 165, 100, -175, 185, 166, 100, -176, 185, 166, 100, -181, 190, 171, 100, -182, 190, 171, 100, -180, 189, 170, 100, -176, 186, 164, 100, -180, 190, 167, 100, -183, 191, 172, 100, -181, 189, 171, 100, -182, 191, 172, 100, -183, 193, 174, 100, -182, 192, 174, 100, -186, 195, 178, 100, -184, 193, 176, 100, -183, 192, 174, 100, -179, 188, 170, 100, -179, 188, 169, 100, -179, 188, 170, 100, -181, 190, 173, 100, -183, 192, 175, 100, -183, 193, 176, 100, -180, 189, 173, 100, -180, 190, 173, 100, -180, 190, 173, 100, -179, 190, 173, 100, -182, 193, 178, 100, -182, 193, 177, 100, -184, 195, 178, 100, -181, 192, 175, 100, -183, 194, 177, 100, -183, 193, 176, 100, -180, 190, 173, 100, -178, 188, 171, 100, -180, 190, 173, 100, -179, 190, 173, 100, -176, 187, 170, 100, -177, 188, 171, 100, -180, 191, 174, 100, -180, 190, 174, 100, -181, 191, 174, 100, -179, 188, 171, 100, -177, 186, 169, 100, -175, 184, 167, 100, -175, 184, 166, 100, -174, 183, 164, 100, -174, 183, 164, 100, -176, 180, 163, 100, -175, 179, 162, 100, -175, 180, 164, 100, -175, 180, 163, 100, -180, 185, 168, 100, -180, 187, 170, 100, -180, 185, 170, 100, -179, 185, 166, 100, -180, 186, 168, 100, -177, 185, 167, 100, -176, 186, 168, 100, -178, 188, 170, 100, -182, 191, 174, 100, -169, 178, 161, 100, -175, 185, 168, 100, -172, 183, 167, 100, -169, 180, 164, 100, -173, 184, 168, 100, -173, 184, 168, 100, -174, 184, 167, 100, -182, 192, 175, 100, -179, 185, 167, 100, -141, 136, 119, 100, -97, 85, 67, 100, -100, 94, 72, 100, -131, 131, 109, 100, -120, 119, 98, 100, -151, 159, 140, 100, -163, 175, 157, 100, -161, 172, 154, 100, -155, 166, 151, 100, -158, 168, 155, 100, -154, 165, 150, 100, -163, 174, 160, 100, -164, 175, 162, 100, -170, 181, 167, 100, -166, 177, 162, 100, -170, 181, 167, 100, -175, 186, 172, 100, -176, 187, 173, 100, -173, 184, 170, 100, -180, 191, 177, 100, -175, 184, 168, 100, -178, 187, 170, 100, -169, 178, 161, 100, -176, 185, 168, 100, -168, 179, 161, 100, -166, 179, 158, 100, -166, 175, 156, 100, -155, 162, 143, 100, -149, 155, 139, 100, -120, 120, 107, 100, -138, 139, 124, 100, -96, 93, 81, 100, -48, 38, 29, 100, -35, 25, 17, 100, -34, 24, 20, 100, -173, 185, 165, 100, -169, 181, 161, 100, -169, 181, 161, 100, -175, 187, 167, 100, -174, 186, 166, 100, -167, 179, 159, 100, -175, 185, 166, 100, -179, 188, 169, 100, -177, 186, 167, 100, -176, 184, 166, 100, -176, 185, 166, 100, -175, 184, 165, 100, -177, 186, 167, 100, -176, 185, 166, 100, -178, 187, 168, 100, -177, 186, 167, 100, -177, 186, 167, 100, -178, 186, 167, 100, -176, 184, 165, 100, -178, 187, 168, 100, -181, 187, 170, 100, -178, 187, 166, 100, -178, 189, 164, 100, -178, 188, 165, 100, -179, 187, 168, 100, -178, 188, 166, 100, -178, 187, 166, 100, -179, 188, 169, 100, -180, 189, 170, 100, -180, 189, 170, 100, -180, 189, 171, 100, -183, 191, 175, 100, -182, 191, 174, 100, -179, 187, 169, 100, -178, 187, 171, 100, -179, 190, 173, 100, -177, 189, 172, 100, -180, 191, 174, 100, -180, 192, 175, 100, -180, 192, 176, 100, -182, 193, 176, 100, -182, 192, 176, 100, -181, 192, 175, 100, -183, 195, 178, 100, -182, 193, 176, 100, -179, 190, 173, 100, -183, 194, 177, 100, -184, 195, 178, 100, -182, 193, 176, 100, -185, 195, 178, 100, -187, 196, 179, 100, -184, 194, 177, 100, -182, 192, 175, 100, -179, 189, 172, 100, -179, 189, 172, 100, -180, 190, 173, 100, -181, 190, 173, 100, -180, 189, 172, 100, -180, 189, 172, 100, -180, 189, 172, 100, -182, 191, 174, 100, -183, 191, 175, 100, -180, 189, 171, 100, -177, 186, 167, 100, -175, 184, 166, 100, -176, 185, 168, 100, -179, 187, 170, 100, -178, 186, 170, 100, -176, 184, 168, 100, -174, 183, 166, 100, -172, 180, 162, 100, -173, 181, 164, 100, -175, 183, 166, 100, -174, 182, 165, 100, -172, 180, 163, 100, -174, 183, 166, 100, -174, 183, 166, 100, -172, 182, 165, 100, -172, 182, 165, 100, -172, 183, 166, 100, -176, 187, 170, 100, -180, 191, 174, 100, -177, 188, 171, 100, -179, 189, 172, 100, -181, 191, 174, 100, -186, 197, 180, 100, -183, 192, 174, 100, -172, 182, 159, 100, -168, 179, 156, 100, -166, 177, 153, 100, -161, 171, 151, 100, -165, 175, 159, 100, -159, 170, 153, 100, -158, 169, 153, 100, -161, 173, 157, 100, -157, 168, 151, 100, -164, 175, 160, 100, -162, 173, 159, 100, -167, 178, 164, 100, -167, 178, 164, 100, -174, 185, 171, 100, -178, 190, 175, 100, -183, 195, 182, 100, -175, 187, 173, 100, -177, 189, 175, 100, -178, 189, 174, 100, -177, 188, 171, 100, -176, 187, 170, 100, -177, 187, 170, 100, -169, 180, 163, 100, -162, 174, 155, 100, -167, 179, 160, 100, -169, 182, 162, 100, -165, 178, 159, 100, -169, 181, 163, 100, -169, 180, 161, 100, -171, 179, 161, 100, -151, 153, 135, 100, -92, 93, 75, 100, -60, 62, 49, 100, -168, 180, 160, 100, -168, 180, 161, 100, -171, 183, 162, 100, -172, 184, 164, 100, -174, 187, 166, 100, -173, 183, 164, 100, -179, 186, 168, 100, -180, 188, 169, 100, -177, 185, 166, 100, -176, 185, 166, 100, -176, 186, 167, 100, -178, 187, 168, 100, -179, 188, 169, 100, -178, 188, 169, 100, -184, 193, 174, 100, -179, 189, 170, 100, -175, 185, 166, 100, -177, 186, 167, 100, -175, 184, 165, 100, -172, 180, 161, 100, -172, 180, 162, 100, -174, 183, 163, 100, -174, 184, 161, 100, -176, 185, 162, 100, -174, 182, 161, 100, -176, 186, 162, 100, -174, 184, 162, 100, -177, 186, 167, 100, -177, 186, 168, 100, -173, 182, 163, 100, -177, 186, 167, 100, -180, 189, 170, 100, -180, 189, 170, 100, -177, 186, 167, 100, -178, 189, 172, 100, -174, 185, 168, 100, -179, 190, 173, 100, -182, 193, 176, 100, -180, 191, 174, 100, -182, 192, 175, 100, -180, 191, 174, 100, -177, 188, 170, 100, -174, 185, 168, 100, -180, 191, 174, 100, -183, 193, 176, 100, -180, 190, 173, 100, -183, 193, 176, 100, -184, 194, 177, 100, -182, 193, 176, 100, -186, 195, 178, 100, -184, 193, 176, 100, -183, 192, 175, 100, -185, 194, 177, 100, -183, 192, 175, 100, -181, 190, 173, 100, -183, 192, 175, 100, -182, 192, 175, 100, -181, 190, 173, 100, -182, 191, 174, 100, -179, 188, 171, 100, -183, 192, 175, 100, -182, 189, 173, 100, -181, 189, 171, 100, -180, 190, 171, 100, -175, 184, 165, 100, -178, 187, 169, 100, -180, 186, 171, 100, -175, 182, 165, 100, -174, 183, 165, 100, -177, 186, 168, 100, -179, 188, 171, 100, -175, 185, 167, 100, -174, 183, 166, 100, -175, 184, 166, 100, -176, 185, 166, 100, -178, 187, 170, 100, -180, 189, 172, 100, -176, 185, 168, 100, -178, 187, 170, 100, -176, 187, 170, 100, -176, 186, 169, 100, -179, 189, 172, 100, -179, 190, 173, 100, -177, 187, 170, 100, -180, 189, 172, 100, -177, 186, 169, 100, -175, 184, 167, 100, -177, 185, 167, 100, -174, 182, 163, 100, -172, 181, 160, 100, -170, 179, 160, 100, -172, 182, 165, 100, -168, 179, 161, 100, -167, 178, 160, 100, -170, 180, 163, 100, -170, 181, 165, 100, -168, 179, 164, 100, -161, 172, 158, 100, -165, 176, 163, 100, -164, 176, 163, 100, -171, 182, 169, 100, -173, 185, 172, 100, -173, 188, 175, 100, -167, 179, 166, 100, -165, 177, 163, 100, -166, 178, 164, 100, -169, 181, 164, 100, -177, 188, 171, 100, -179, 190, 173, 100, -175, 186, 169, 100, -176, 186, 169, 100, -175, 184, 167, 100, -169, 180, 162, 100, -167, 178, 158, 100, -162, 175, 154, 100, -167, 178, 158, 100, -164, 175, 153, 100, -173, 180, 158, 100, -168, 176, 153, 100, -151, 160, 137, 100, -163, 176, 157, 100, -165, 178, 158, 100, -168, 180, 160, 100, -167, 179, 159, 100, -171, 183, 163, 100, -169, 181, 161, 100, -171, 181, 162, 100, -170, 182, 163, 100, -168, 181, 162, 100, -168, 181, 162, 100, -167, 180, 160, 100, -176, 187, 168, 100, -179, 188, 169, 100, -178, 187, 168, 100, -179, 189, 168, 100, -180, 192, 170, 100, -173, 185, 165, 100, -176, 188, 169, 100, -171, 183, 164, 100, -170, 182, 161, 100, -177, 187, 168, 100, -177, 188, 169, 100, -172, 182, 160, 100, -176, 186, 162, 100, -172, 182, 158, 100, -178, 188, 164, 100, -182, 192, 167, 100, -177, 187, 166, 100, -174, 185, 167, 100, -176, 186, 168, 100, -179, 188, 169, 100, -180, 189, 170, 100, -182, 192, 174, 100, -181, 192, 175, 100, -184, 195, 178, 100, -180, 191, 174, 100, -177, 188, 171, 100, -178, 189, 172, 100, -179, 190, 173, 100, -179, 190, 173, 100, -180, 191, 176, 100, -183, 194, 178, 100, -178, 189, 172, 100, -177, 185, 168, 100, -178, 186, 168, 100, -181, 188, 170, 100, -182, 191, 173, 100, -181, 190, 173, 100, -181, 191, 174, 100, -183, 192, 175, 100, -182, 191, 174, 100, -181, 190, 173, 100, -182, 191, 174, 100, -182, 191, 174, 100, -180, 190, 173, 100, -181, 190, 173, 100, -186, 192, 176, 100, -184, 192, 176, 100, -180, 189, 172, 100, -182, 191, 174, 100, -183, 192, 175, 100, -181, 190, 173, 100, -181, 190, 173, 100, -182, 191, 174, 100, -180, 189, 171, 100, -180, 189, 171, 100, -179, 188, 171, 100, -180, 187, 169, 100, -179, 188, 170, 100, -174, 183, 165, 100, -177, 186, 169, 100, -176, 185, 167, 100, -175, 184, 167, 100, -176, 185, 166, 100, -179, 188, 168, 100, -179, 188, 170, 100, -181, 190, 173, 100, -177, 187, 170, 100, -183, 192, 175, 100, -179, 189, 172, 100, -177, 188, 171, 100, -180, 189, 172, 100, -179, 187, 170, 100, -173, 182, 165, 100, -174, 183, 166, 100, -174, 183, 166, 100, -173, 181, 164, 100, -174, 183, 165, 100, -173, 183, 165, 100, -176, 185, 166, 100, -177, 186, 167, 100, -175, 184, 165, 100, -171, 181, 161, 100, -176, 186, 168, 100, -173, 182, 166, 100, -175, 186, 169, 100, -166, 177, 160, 100, -151, 162, 146, 100, -162, 173, 158, 100, -165, 177, 165, 100, -163, 175, 163, 100, -164, 176, 162, 100, -179, 190, 177, 100, -180, 191, 179, 100, -177, 189, 175, 100, -174, 185, 171, 100, -168, 180, 163, 100, -173, 184, 168, 100, -185, 196, 179, 100, -181, 192, 175, 100, -182, 191, 174, 100, -182, 191, 174, 100, -176, 184, 167, 100, -172, 181, 164, 100, -169, 178, 159, 100, -164, 174, 151, 100, -165, 175, 149, 100, -158, 170, 144, 100, -158, 171, 146, 100, -161, 172, 148, 100, -170, 182, 163, 100, -171, 183, 163, 100, -173, 186, 165, 100, -173, 185, 166, 100, -174, 185, 168, 100, -165, 178, 159, 100, -160, 175, 154, 100, -161, 178, 156, 100, -159, 176, 155, 100, -158, 176, 156, 100, -161, 176, 155, 100, -169, 182, 162, 100, -175, 187, 167, 100, -182, 192, 172, 100, -182, 192, 172, 100, -178, 190, 166, 100, -175, 187, 167, 100, -174, 185, 167, 100, -176, 187, 169, 100, -173, 186, 165, 100, -176, 188, 171, 100, -173, 186, 166, 100, -174, 186, 165, 100, -173, 185, 161, 100, -173, 184, 160, 100, -176, 186, 162, 100, -178, 189, 165, 100, -177, 188, 168, 100, -179, 191, 173, 100, -182, 193, 177, 100, -174, 186, 168, 100, -176, 187, 170, 100, -178, 189, 173, 100, -181, 192, 175, 100, -182, 193, 176, 100, -180, 191, 174, 100, -180, 191, 174, 100, -180, 191, 174, 100, -181, 192, 175, 100, -178, 189, 172, 100, -182, 193, 177, 100, -182, 193, 177, 100, -183, 194, 177, 100, -183, 193, 176, 100, -181, 189, 171, 100, -176, 184, 165, 100, -177, 186, 167, 100, -178, 187, 169, 100, -182, 191, 174, 100, -185, 194, 177, 100, -184, 193, 176, 100, -184, 193, 176, 100, -183, 192, 175, 100, -182, 191, 174, 100, -181, 188, 172, 100, -181, 190, 173, 100, -184, 192, 176, 100, -185, 193, 176, 100, -184, 193, 176, 100, -184, 193, 176, 100, -185, 194, 177, 100, -185, 194, 177, 100, -183, 192, 175, 100, -182, 191, 174, 100, -185, 194, 177, 100, -184, 193, 176, 100, -185, 194, 177, 100, -186, 196, 178, 100, -184, 193, 177, 100, -180, 189, 172, 100, -182, 191, 174, 100, -182, 191, 175, 100, -182, 191, 173, 100, -181, 190, 170, 100, -183, 192, 174, 100, -180, 189, 170, 100, -181, 190, 173, 100, -179, 189, 172, 100, -178, 187, 170, 100, -178, 187, 170, 100, -179, 189, 172, 100, -176, 187, 170, 100, -174, 183, 166, 100, -176, 185, 168, 100, -171, 182, 165, 100, -173, 182, 165, 100, -173, 182, 165, 100, -170, 181, 162, 100, -169, 179, 160, 100, -168, 177, 158, 100, -172, 181, 162, 100, -174, 183, 164, 100, -176, 185, 166, 100, -180, 188, 170, 100, -176, 185, 168, 100, -176, 186, 169, 100, -163, 174, 157, 100, -152, 163, 145, 100, -171, 182, 165, 100, -165, 176, 162, 100, -159, 172, 159, 100, -167, 179, 165, 100, -178, 188, 175, 100, -179, 189, 177, 100, -178, 189, 175, 100, -176, 187, 173, 100, -180, 191, 177, 100, -178, 189, 175, 100, -182, 193, 176, 100, -178, 189, 172, 100, -177, 188, 171, 100, -180, 190, 173, 100, -176, 187, 170, 100, -177, 188, 171, 100, -175, 185, 167, 100, -169, 178, 157, 100, -158, 168, 143, 100, -160, 173, 146, 100, -154, 168, 142, 100, -154, 167, 142, 100 -}; diff --git a/game/client/cdll_client_int.cpp b/game/client/cdll_client_int.cpp index e2270786..c5ff99e0 100644 --- a/game/client/cdll_client_int.cpp +++ b/game/client/cdll_client_int.cpp @@ -735,7 +735,7 @@ public: virtual bool IsConnectedUserInfoChangeAllowed( IConVar *pCvar ); - virtual void IN_TouchEvent( int type, int fingerId, int x, int y ); + virtual void IN_TouchEvent( uint data, uint data2, uint data3, uint data4 ); private: void UncacheAllMaterials( ); void ResetStringTablePointers(); @@ -1424,17 +1424,24 @@ int CHLClient::IN_KeyEvent( int eventcode, ButtonCode_t keynum, const char *pszC return input->KeyEvent( eventcode, keynum, pszCurrentBinding ); } -void CHLClient::IN_TouchEvent( int type, int fingerId, int x, int y ) +void CHLClient::IN_TouchEvent( uint data, uint data2, uint data3, uint data4 ) { if( enginevgui->IsGameUIVisible() ) return; touch_event_t ev; - ev.type = type; - ev.fingerid = fingerId; - ev.x = x; - ev.y = y; + ev.type = data & 0xFFFF; + ev.fingerid = (data >> 16) & 0xFFFF; + ev.x = (double)((data2 >> 16) & 0xFFFF) / 0xFFFF; + ev.y = (double)(data2 & 0xFFFF) / 0xFFFF; + + union{uint i;float f;} ifconv; + ifconv.i = data3; + ev.dx = ifconv.f; + + ifconv.i = data4; + ev.dy = ifconv.f; gTouch.ProcessEvent( &ev ); } diff --git a/game/client/hud.cpp b/game/client/hud.cpp index cbc2c849..c32f4b4f 100644 --- a/game/client/hud.cpp +++ b/game/client/hud.cpp @@ -811,7 +811,7 @@ void CHud::RefreshHudTextures() // check to see if we have sprites for this res; if not, step down LoadHudTextures( textureList, "scripts/hud_textures", NULL ); - //LoadHudTextures( textureList, "scripts/mod_textures", NULL ); + LoadHudTextures( textureList, "scripts/mod_textures", NULL ); // fix up all the texture icons first int c = textureList.Count(); diff --git a/game/client/interpolatedvar.h b/game/client/interpolatedvar.h index b5467ad4..542a98ec 100644 --- a/game/client/interpolatedvar.h +++ b/game/client/interpolatedvar.h @@ -733,7 +733,7 @@ inline void CInterpolatedVarArrayBase::AddToHead( float changeTi } CInterpolatedVarEntry *e = &m_VarHistory[ newslot ]; - e->NewEntry( values, m_nMaxCount, changeTime ); + e->NewEntry( (Type*)values, m_nMaxCount, changeTime ); } template< typename Type, bool IS_ARRAY > diff --git a/game/client/third/minizip/CMakeLists.txt b/game/client/third/minizip/CMakeLists.txt deleted file mode 100755 index f98a4e2f..00000000 --- a/game/client/third/minizip/CMakeLists.txt +++ /dev/null @@ -1,364 +0,0 @@ -#*************************************************************************** -# Copyright: Matthias Schmieder, -# E-Mail: schmieder.matthias@gmail.com -# Year: 2016 -#*************************************************************************** -cmake_minimum_required(VERSION 2.8) - -option(USE_ZLIB "Enables ZLIB compression" ON) -option(USE_BZIP2 "Enables BZIP2 compression" ON) -option(USE_LZMA "Enables LZMA compression" ON) -option(USE_PKCRYPT "Enables PKWARE traditional encryption" ON) -option(USE_AES "Enables AES encryption" ON) -option(BUILD_TEST "Builds minizip test executable" OFF) - -# Set a consistent MACOSX_RPATH default across all CMake versions. -# When CMake 2.8.12 is required, change this default to 1. -# When CMake 3.0.0 is required, remove this block (see CMP0042). -if(NOT DEFINED CMAKE_MACOSX_RPATH) - set(CMAKE_MACOSX_RPATH 0) -endif() - -project("minizip") - -include(GNUInstallDirs) - -set(INSTALL_BIN_DIR ${CMAKE_INSTALL_BINDIR} CACHE PATH "Installation directory for executables") -set(INSTALL_LIB_DIR ${CMAKE_INSTALL_LIBDIR} CACHE PATH "Installation directory for libraries") -set(INSTALL_INC_DIR ${CMAKE_INSTALL_INCLUDEDIR} CACHE PATH "Installation directory for headers") -set(INSTALL_MAN_DIR ${CMAKE_INSTALL_MANDIR} CACHE PATH "Installation directory for manual pages") -set(INSTALL_PKGCONFIG_DIR ${CMAKE_INSTALL_LIBDIR}/pkgconfig CACHE PATH "Installation directory for pkgconfig (.pc) files") -set(INSTALL_CMAKE_DIR ${CMAKE_INSTALL_LIBDIR}/cmake/minizip CACHE PATH "Installation directory for cmake files.") - -set(VERSION "2.3.3") - -# Set cmake debug postfix to d -set(CMAKE_DEBUG_POSTFIX "d") - -# Ensure correct version of zlib is referenced -if(USE_ZLIB) - set(ZLIB_ROOT ${DEF_ZLIB_ROOT} CACHE PATH "Parent directory of zlib installation") - find_package(ZLIB REQUIRED) - if(ZLIB_FOUND) - include_directories(${ZLIB_INCLUDE_DIRS}) - endif() - add_definitions(-DHAVE_ZLIB) -endif() - -set(MINIZIP_PC ${CMAKE_CURRENT_BINARY_DIR}/minizip.pc) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/minizip.pc.cmakein ${MINIZIP_PC} @ONLY) - -set(PROJECT_NAME libminizip) - -set(MINIZIP_SRC - mz_os.c - mz_compat.c - mz_strm.c - mz_strm_buf.c - mz_strm_mem.c - mz_strm_posix.c - mz_strm_split.c - mz_zip.c) - -set(MINIZIP_PUBLIC_HEADERS - mz.h - mz_os.h - mz_compat.h - mz_strm.h - mz_strm_buf.h - mz_strm_mem.h - mz_strm_posix.h - mz_strm_split.h - mz_zip.h) - -if(WIN32) - list(APPEND MINIZIP_SRC "mz_os_win32.c" "mz_strm_win32.c") - list(APPEND MINIZIP_PUBLIC_HEADERS "mz_os_win32.h" "mz_strm_win32.h") - - add_definitions(-D_CRT_SECURE_NO_DEPRECATE) -endif() - -if("${CMAKE_SYSTEM_NAME}" STREQUAL "WindowsStore") - add_definitions(-DMZ_USE_WINRT_API) -endif() - -if(UNIX) - add_compile_options(-O3) - - list(APPEND MINIZIP_SRC "mz_os_posix.c") - list(APPEND MINIZIP_PUBLIC_HEADERS "mz_os_posix.h") - - set(define_lfs_macros TRUE) - - if(ANDROID) - string(REGEX REPLACE "android-([0-9+])" "\\1" - android_api "${ANDROID_PLATFORM}") - if(${android_api} LESS 24) - set(define_lfs_macros FALSE) - endif() - endif() - - if(define_lfs_macros) - add_definitions(-D__USE_FILE_OFFSET64) - add_definitions(-D__USE_LARGEFILE64) - add_definitions(-D_LARGEFILE64_SOURCE) - add_definitions(-D_FILE_OFFSET_BITS=64) - endif() - - if(CMAKE_SYSTEM_NAME MATCHES "Linux") - find_package(PkgConfig REQUIRED) - - pkg_check_modules(LIBBSD libbsd REQUIRED) - - include_directories(${LIBBSD_INCLUDE_DIRS}) - link_directories(${LIBBSD_LIBRARY_DIRS}) - endif() -endif() - -if(USE_PKCRYPT) - add_definitions(-DHAVE_PKCRYPT) - - list(APPEND MINIZIP_SRC "mz_strm_pkcrypt.c") - list(APPEND MINIZIP_PUBLIC_HEADERS "mz_strm_pkcrypt.h") -endif() - -if(USE_AES) - add_definitions(-DHAVE_AES) - - list(APPEND MINIZIP_SRC "mz_strm_aes.c") - list(APPEND MINIZIP_PUBLIC_HEADERS "mz_strm_aes.h") - - set(AES_SRC - lib/aes/aescrypt.c - lib/aes/aeskey.c - lib/aes/aestab.c - lib/aes/hmac.c - lib/aes/pwd2key.c - lib/aes/sha1.c) - - set(AES_PUBLIC_HEADERS - lib/aes/aes.h - lib/aes/aesopt.h - lib/aes/aestab.h - lib/aes/brg_endian.h - lib/aes/brg_types.h - lib/aes/hmac.h - lib/aes/pwd2key.h - lib/aes/sha1.h) - - include_directories(lib/aes) - - source_group("AES" FILES ${AES_SRC} ${AES_PUBLIC_HEADERS}) -endif() - -if(USE_ZLIB) - add_definitions(-DHAVE_ZLIB) - - list(APPEND MINIZIP_SRC "mz_strm_zlib.c") - list(APPEND MINIZIP_PUBLIC_HEADERS "mz_strm_zlib.h") - - include(CheckFunctionExists) - set(CMAKE_REQUIRED_LIBRARIES ZLIB::ZLIB) - CHECK_FUNCTION_EXISTS(z_get_crc_table - NEEDS_Z_PREFIX) - - if(NEEDS_Z_PREFIX) - add_definitions(-DZ_PREFIX) - endif() -endif() - -if(USE_BZIP2) - add_definitions(-DHAVE_BZIP2) - add_definitions(-DBZ_NO_STDIO) - - list(APPEND MINIZIP_SRC "mz_strm_bzip.c") - list(APPEND MINIZIP_PUBLIC_HEADERS "mz_strm_bzip.h") - - set(BZIP2_SRC - lib/bzip2/blocksort.c - lib/bzip2/bzlib.c - lib/bzip2/compress.c - lib/bzip2/crctable.c - lib/bzip2/decompress.c - lib/bzip2/huffman.c - lib/bzip2/randtable.c) - - set(BZIP2_PUBLIC_HEADERS - lib/bzip2/bzlib.h - lib/bzip2/bzlib_private.h) - - include_directories(lib/bzip2) - - source_group("BZip2" FILES ${BZIP2_SRC} ${BZIP2_PUBLIC_HEADERS}) -endif() - -if(USE_LZMA) - add_definitions(-DHAVE_LZMA) - add_definitions(-DHAVE_CONFIG_H) - add_definitions(-DLZMA_API_STATIC) - - list(APPEND MINIZIP_SRC "mz_strm_lzma.c") - list(APPEND MINIZIP_PUBLIC_HEADERS "mz_strm_lzma.h") - - set(LZMA_CHECK_SRC - lib/liblzma/check/check.c - lib/liblzma/check/crc32_fast.c - lib/liblzma/check/crc32_table.c) - set(LZMA_COMMON_SRC - lib/liblzma/common/alone_decoder.c - lib/liblzma/common/alone_encoder.c - lib/liblzma/common/common.c - lib/liblzma/common/filter_encoder.c) - set(LZMA_LZ_SRC - lib/liblzma/lz/lz_decoder.c - lib/liblzma/lz/lz_encoder.c - lib/liblzma/lz/lz_encoder_mf.c) - set(LZMA_LZMA_SRC - lib/liblzma/lzma/fastpos.h - lib/liblzma/lzma/fastpos_table.c - lib/liblzma/lzma/lzma_decoder.c - lib/liblzma/lzma/lzma_encoder.c - lib/liblzma/lzma/lzma_encoder_optimum_fast.c - lib/liblzma/lzma/lzma_encoder_optimum_normal.c - lib/liblzma/lzma/lzma_encoder_presets.c) - set(LZMA_RANGECODER_SRC - lib/liblzma/rangecoder/price_table.c) - - set(LZMA_CONFIG_HEADERS - lib/liblzma/config.h) - set(LZMA_API_HEADERS - lib/liblzma/api/lzma.h - lib/liblzma/api/lzma/base.h - lib/liblzma/api/lzma/check.h - lib/liblzma/api/lzma/container.h - lib/liblzma/api/lzma/filter.h - lib/liblzma/api/lzma/lzma12.h - lib/liblzma/api/lzma/version.h - lib/liblzma/api/lzma/vli.h) - set(LZMA_CHECK_HEADERS - lib/liblzma/check/check.h - lib/liblzma/check/crc32_table_be.h - lib/liblzma/check/crc32_table_le.h - lib/liblzma/check/crc_macros.h) - set(LZMA_COMMON_HEADERS - lib/liblzma/common/alone_decoder.h - lib/liblzma/common/common.h - lib/liblzma/common/filter_encoder.h - lib/liblzma/common/index.h - lib/liblzma/common/memcmplen.h - lib/liblzma/common/sysdefs.h - lib/liblzma/common/tuklib_common.h - lib/liblzma/common/tuklib_config.h - lib/liblzma/common/tuklib_integer.h) - set(LZMA_LZ_HEADERS - lib/liblzma/lz/lz_decoder.h - lib/liblzma/lz/lz_encoder.h - lib/liblzma/lz/lz_encoder_hash.h - lib/liblzma/lz/lz_encoder_hash_table.h) - set(LZMA_LZMA_HEADERS - lib/liblzma/lzma/lzma2_encoder.h - lib/liblzma/lzma/lzma_common.h - lib/liblzma/lzma/lzma_decoder.h - lib/liblzma/lzma/lzma_encoder.h - lib/liblzma/lzma/lzma_encoder_private.h) - set(LZMA_RANGECODER_HEADERS - lib/liblzma/rangecoder/price.h - lib/liblzma/rangecoder/range_common.h - lib/liblzma/rangecoder/range_decoder.h - lib/liblzma/rangecoder/range_encoder.h) - - set(LZMA_PUBLIC_HEADERS - ${LZMA_CONFIG_HEADERS} - ${LZMA_API_HEADERS} - ${LZMA_CHECK_HEADERS} - ${LZMA_COMMON_HEADERS} - ${LZMA_LZ_HEADERS} - ${LZMA_LZMA_HEADERS} - ${LZMA_RANGECODER_HEADERS}) - - set(LZMA_SRC - ${LZMA_CHECK_SRC} - ${LZMA_COMMON_SRC} - ${LZMA_LZ_SRC} - ${LZMA_LZMA_SRC} - ${LZMA_RANGECODER_SRC}) - - include_directories(lib/liblzma - lib/liblzma/api - lib/liblzma/check - lib/liblzma/common - lib/liblzma/lz - lib/liblzma/lzma - lib/liblzma/rangecoder) - - source_group("LZMA" FILES ${LZMA_CONFIG_HEADERS}) - source_group("LZMA\\API" FILES ${LZMA_API_HEADERS}) - source_group("LZMA\\Check" FILES ${LZMA_CHECK_SRC} ${LZMA_CHECK_HEADERS}) - source_group("LZMA\\Common" FILES ${LZMA_COMMON_SRC} ${LZMA_COMMON_HEADERS}) - source_group("LZMA\\LZ" FILES ${LZMA_LZ_SRC} ${LZMA_LZ_HEADERS}) - source_group("LZMA\\LZMA" FILES ${LZMA_LZMA_SRC} ${LZMA_LZMA_HEADERS}) - source_group("LZMA\\RangeCoder" FILES ${LZMA_RANGECODER_SRC} ${LZMA_RANGECODER_HEADERS}) -endif() - -# Enable x86 optimizations if supported -if(CMAKE_C_COMPILER MATCHES ".*clang") - include(CheckCCompilerFlag) - macro(enable_option_if_supported option variable) - check_c_compiler_flag("-Werror=unused-command-line-argument ${option}" ${variable}) - if(${variable}) - add_compile_options(${option}) - endif() - endmacro() - - enable_option_if_supported(-msse3 check_opt_sse3) - enable_option_if_supported(-msse4.1 check_opt_sse41) - enable_option_if_supported(-maes check_opt_aes) -endif() - -# Create minizip library -source_group("Minizip" FILES ${MINIZIP_SRC} ${MINIZIP_PUBLIC_HEADERS}) - -add_library(${PROJECT_NAME} - ${MINIZIP_SRC} ${MINIZIP_PUBLIC_HEADERS} - ${AES_SRC} ${AES_PUBLIC_HEADERS} - ${BZIP2_SRC} ${BZIP2_PUBLIC_HEADERS} - ${LZMA_SRC} ${LZMA_PUBLIC_HEADERS}) - -if (MINGW AND BUILD_SHARED_LIBS) - set_target_properties(${PROJECT_NAME} PROPERTIES ARCHIVE_OUTPUT_NAME "minizip") -endif () - -set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C PREFIX "" - POSITION_INDEPENDENT_CODE 1) -if(USE_ZLIB) - target_link_libraries(${PROJECT_NAME} ZLIB::ZLIB) -endif() -if(USE_LZMA) - set_target_properties(${PROJECT_NAME} PROPERTIES C_STANDARD 99) -endif() -if(UNIX) - target_link_libraries(${PROJECT_NAME} ${LIBBSD_LIBRARIES}) -endif() - -target_include_directories(${PROJECT_NAME} PUBLIC $) - -install(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME} - INCLUDES DESTINATION "${INSTALL_INC_DIR}" - RUNTIME DESTINATION "${INSTALL_BIN_DIR}" - ARCHIVE DESTINATION "${INSTALL_LIB_DIR}" - LIBRARY DESTINATION "${INSTALL_LIB_DIR}") - -install(EXPORT ${PROJECT_NAME} - DESTINATION "${INSTALL_CMAKE_DIR}" - NAMESPACE "MINIZIP::") - -install(FILES ${MINIZIP_PUBLIC_HEADERS} DESTINATION "${INSTALL_INC_DIR}") -install(FILES ${MINIZIP_PC} DESTINATION "${INSTALL_PKGCONFIG_DIR}") - -if(BUILD_TEST) - add_executable(minizip "minizip.c") - target_link_libraries(minizip ${PROJECT_NAME}) - - install(TARGETS minizip - RUNTIME DESTINATION "bin") -endif() diff --git a/game/client/third/minizip/LICENSE b/game/client/third/minizip/LICENSE deleted file mode 100755 index 086295a2..00000000 --- a/game/client/third/minizip/LICENSE +++ /dev/null @@ -1,17 +0,0 @@ -Condition of use and distribution are the same as zlib: - -This software is provided 'as-is', without any express or implied -warranty. In no event will the authors be held liable for any damages -arising from the use of this software. - -Permission is granted to anyone to use this software for any purpose, -including commercial applications, and to alter it and redistribute it -freely, subject to the following restrictions: - -1. The origin of this software must not be misrepresented; you must not - claim that you wrote the original software. If you use this software - in a product, an acknowledgement in the product documentation would be - appreciated but is not required. -2. Altered source versions must be plainly marked as such, and must not be - misrepresented as being the original software. -3. This notice may not be removed or altered from any source distribution. \ No newline at end of file diff --git a/game/client/third/minizip/Minizip.podspec b/game/client/third/minizip/Minizip.podspec deleted file mode 100755 index 065ef492..00000000 --- a/game/client/third/minizip/Minizip.podspec +++ /dev/null @@ -1,37 +0,0 @@ -Pod::Spec.new do |s| - s.name = 'Minizip' - s.version = '2.3.3' - s.license = 'zlib' - s.summary = 'Minizip contrib in zlib with the latest bug fixes and advanced features' - s.description = <<-DESC -Minizip zlib contribution that includes: -* AES encryption -* I/O buffering -* PKWARE disk splitting -It also has the latest bug fixes that having been found all over the internet. -DESC - s.homepage = 'https://github.com/nmoinvaz/minizip' - s.authors = 'Nathan Moinvaziri', 'Gilles Vollant' - - s.source = { :git => 'https://github.com/nmoinvaz/minizip.git' } - s.libraries = 'z' - - s.subspec 'Core' do |sp| - sp.source_files = '{mz_os,mz_compat,mz_strm,mz_strm_mem,mz_strm_buf,mz_zip,mz_strm_crypt,mz_strm_posix,mz_strm_zlib}.{c,h}' - end - - s.subspec 'AES' do |sp| - sp.dependency 'Minizip/Core' - sp.source_files = 'lib/aes/*.{c,h}', 'mz_strm_aes.{c,h}' - end - - s.subspec 'BZIP2' do |sp| - sp.dependency 'Minizip/Core' - sp.source_files = 'lib/bzip2/*.{c,h}', 'mz_strm_bzip.{c,h}' - end - - s.subspec 'LZMA' do |sp| - sp.dependency 'Minizip/Core' - sp.source_files = 'lib/liblzma/*.{c,h}', 'mz_strm_lzma.{c,h}' - end -end diff --git a/game/client/third/minizip/README.md b/game/client/third/minizip/README.md deleted file mode 100755 index 7c040ab4..00000000 --- a/game/client/third/minizip/README.md +++ /dev/null @@ -1,177 +0,0 @@ -# Minizip 2.3.3 - -This library is a refactoring of the minizip contribution found in the zlib distribution and is supported on Windows, macOS, and Linux. The motivation for this work has been the inclusion of advanced features, improvements in code maintainability and readability, and the reduction of duplicate code. It is based on the original work of [Gilles Vollant](http://www.winimage.com/zLibDll/minizip.html) that has been contributed to by many people over the years. - -Dev: ![Dev Branch Status](https://travis-ci.org/nmoinvaz/minizip.svg?branch=dev) -Master: ![Master Branch Status](https://travis-ci.org/nmoinvaz/minizip.svg?branch=master) - -For my older fork of this library checkout the [1.2](https://github.com/nmoinvaz/minizip/tree/1.2) branch. -For the original work maintained by Mark Adler checkout the zlib minizip [contrib](https://github.com/madler/zlib/tree/master/contrib/minizip). - -## Build - -To generate the project files for your platform and IDE download and run cmake in the project directory. - -``` -cmake . -cmake . -DBUILD_TEST=ON -cmake --build . -``` - -## Build Options - -| Name | Description | Default Value | -|:- |:-|:-:| -| USE_ZLIB | Enables ZLIB compression | ON | -| USE_BZIP2 | Enables BZIP2 compression | ON | -| USE_LZMA | Enables LZMA compression | ON | -| USE_PKCRYPT | Enables PKWARE traditional encryption | ON | -| USE_AES | Enables AES encryption | ON | -| BUILD_TEST | Builds minizip test executable | OFF | - -## Contents - -| File(s) | Description | Required | -|:- |:-|:-:| -| minizip.c | Sample application | No | -| mz_compat.\* | Minizip 1.0 compatibility layer | No | -| mz.h | Error codes and flags | Yes | -| mz_os\* | OS specific helper functions | Encryption, Disk Splitting | -| mz_strm.\* | Stream interface | Yes | -| mz_strm_aes.\* | WinZIP AES stream | No | -| mz_strm_buf.\* | Buffered stream | No | -| mz_strm_bzip.\* | BZIP2 stream using libbzip2 | No | -| mz_strm_lzma.\* | LZMA stream using liblzma | zlib or liblzma | -| mz_strm_mem.\* | Memory stream | Yes | -| mz_strm_split.\* | Disk splitting stream | No | -| mz_strm_pkcrypt.\* | PKWARE traditional encryption stream | No | -| mz_strm_posix.\* | File stream using Posix functions | Non-windows systems | -| mz_strm_win32.\* | File stream using Win32 API functions | Windows systems | -| mz_strm_zlib.\* | Deflate stream using zlib | zlib or liblzma | -| mz_zip.\* | Zip functionality | Yes | - -## Features - -### Compression Methods - -#### BZIP2 - -+ Requires ``cmake . -DUSE_BZIP2=ON`` or ``#define HAVE_BZIP2`` -+ Requires [BZIP2](http://www.bzip.org/) library - -#### LZMA - -+ Requires ``cmake . -DUSE_LZMA=ON`` or ``#define HAVE_LZMA`` -+ Requires [liblzma](https://tukaani.org/xz/) library - -### Encryption - -#### [WinZIP AES Encryption](https://www.winzip.com/aes_info.htm) - -+ Requires ``cmake . -DUSE_AES=ON`` or ``#define HAVE_AES`` -+ Requires Brian Gladman's [AES](https://github.com/BrianGladman/aes) and [SHA](https://github.com/BrianGladman/sha) libraries - -When zipping with a password it will always use AES 256-bit encryption. -When unzipping it will use AES decryption only if necessary. - -#### Disabling All Encryption - -To disable encryption use the following cmake commands: - -``` -cmake . -DUSE_AES=OFF -cmake . -DUSE_PKCRYPT=OFF -``` - -### NTFS Timestamps - -Support has been added for UTC last modified, last accessed, and creation dates. - -### Streams - -This library has been refactored around streams. - -#### Memory Streaming - -To unzip from a zip file in memory pass the memory stream to the open function. -``` -uint8_t *zip_buffer = NULL; -int32_t zip_buffer_size = 0; -void *mem_stream = NULL; - -// fill zip_buffer with zip contents -mz_stream_mem_create(&mem_stream); -mz_stream_mem_set_buffer(mem_stream, zip_buffer, zip_buffer_size); -mz_stream_open(mem_stream, NULL, MZ_OPEN_MODE_READ); - -void *zip_handle = mz_zip_open(mem_stream, MZ_OPEN_MODE_READ); -// do unzip operations - -mz_stream_mem_delete(&mem_stream); -``` - -To create a zip file in memory first create a growable memory stream and pass it to the open function. - -``` -void *mem_stream = NULL; - -mz_stream_mem_create(&mem_stream); -mz_stream_mem_set_grow_size(mem_stream, (128 * 1024)); -mz_stream_open(mem_stream, NULL, MZ_OPEN_MODE_CREATE); - -void *zip_handle = mz_zip_open(mem_stream, MZ_OPEN_MODE_WRITE); -// do unzip operations - -mz_stream_mem_delete(&mem_stream); -``` - -For a complete example, see test_zip_mem() in [test.c](https://github.com/nmoinvaz/minizip/blob/master/test/test.c). - -#### Buffered Streaming - -By default the library will read bytes typically one at a time. The buffered stream allows for buffered read and write operations to improve I/O performance. - -``` -void *stream = NULL; -void *buf_stream = NULL; - -mz_stream_os_create(&stream) -// do open os stream - -mz_stream_buffered_create(&buf_stream); -mz_stream_buffered_open(buf_stream, NULL, MZ_OPEN_MODE_READ); -mz_stream_buffered_set_base(buf_stream, stream); - -void *zip_handle = mz_zip_open(buf_stream, MZ_OPEN_MODE_READ); -``` - -#### Disk Splitting Stream - -To create an archive with multiple disks use the disk splitting stream and supply a disk size value in bytes. - -``` -void *stream = NULL; -void *split_stream = NULL; - -mz_stream_os_create(&stream); - -mz_stream_split_create(&split_stream); -mz_stream_split_set_prop_int64(split_stream, MZ_STREAM_PROP_DISK_SIZE, 64 * 1024); - -mz_stream_set_base(split_stream, stream); - -mz_stream_open(split_stream, path.. - -void *zip_handle = mz_zip_open(split_stream, MZ_OPEN_MODE_WRITE); -``` - -### Windows RT - -+ Requires ``#define MZ_USE_WINRT_API`` - -## Limitations - -+ Archives are required to have a central directory. -+ Central directory header values should be correct and it is necessary for the compressed size to be accurate for AES encryption. -+ Central directory encryption is not supported due to licensing restrictions mentioned by PKWARE in their zip appnote. -+ Central directory is the only data stored on the last disk of a split-disk archive and doesn't follow disk size restrictions. diff --git a/game/client/third/minizip/lib/aes/aes.h b/game/client/third/minizip/lib/aes/aes.h deleted file mode 100755 index 92e23c2c..00000000 --- a/game/client/third/minizip/lib/aes/aes.h +++ /dev/null @@ -1,270 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - - This file contains the definitions required to use AES in C. See aesopt.h - for optimisation details. -*/ - -#ifndef _AES_H -#define _AES_H - -#include - -/* This include is used to find 8 & 32 bit unsigned integer types */ -#include "brg_types.h" - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#define AES_128 /* if a fast 128 bit key scheduler is needed */ -#define AES_192 /* if a fast 192 bit key scheduler is needed */ -#define AES_256 /* if a fast 256 bit key scheduler is needed */ -#define AES_VAR /* if variable key size scheduler is needed */ -#define AES_MODES /* if support is needed for modes */ - -/* The following must also be set in assembler files if being used */ - -#define AES_ENCRYPT /* if support for encryption is needed */ -#define AES_DECRYPT /* if support for decryption is needed */ - -#define AES_BLOCK_SIZE 16 /* the AES block size in bytes */ -#define N_COLS 4 /* the number of columns in the state */ - -/* The key schedule length is 11, 13 or 15 16-byte blocks for 128, */ -/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes */ -/* or 44, 52 or 60 32-bit words. */ - -#if defined( AES_VAR ) || defined( AES_256 ) -#define KS_LENGTH 60 -#elif defined( AES_192 ) -#define KS_LENGTH 52 -#else -#define KS_LENGTH 44 -#endif - -#define AES_RETURN INT_RETURN - -/* the character array 'inf' in the following structures is used */ -/* to hold AES context information. This AES code uses cx->inf.b[0] */ -/* to hold the number of rounds multiplied by 16. The other three */ -/* elements can be used by code that implements additional modes */ - -typedef union -{ uint32_t l; - uint8_t b[4]; -} aes_inf; - -#ifdef _MSC_VER -# pragma warning( disable : 4324 ) -#endif - -#if defined(_MSC_VER) && defined(_WIN64) -#define ALIGNED_(x) __declspec(align(x)) -#elif defined(__GNUC__) && defined(__x86_64__) -#define ALIGNED_(x) __attribute__ ((aligned(x))) -#else -#define ALIGNED_(x) -#endif - -typedef struct ALIGNED_(16) -{ uint32_t ks[KS_LENGTH]; - aes_inf inf; -} aes_encrypt_ctx; - -typedef struct ALIGNED_(16) -{ uint32_t ks[KS_LENGTH]; - aes_inf inf; -} aes_decrypt_ctx; - -#ifdef _MSC_VER -# pragma warning( default : 4324 ) -#endif - -/* This routine must be called before first use if non-static */ -/* tables are being used */ - -AES_RETURN aes_init(void); - -/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */ -/* those in the range 128 <= key_len <= 256 are given in bits */ - -#if defined( AES_ENCRYPT ) - -#if defined( AES_128 ) || defined( AES_VAR) -AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); -#endif - -#if defined( AES_192 ) || defined( AES_VAR) -AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); -#endif - -#if defined( AES_256 ) || defined( AES_VAR) -AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); -#endif - -#if defined( AES_VAR ) -AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]); -#endif - -AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]); - -#endif - -#if defined( AES_DECRYPT ) - -#if defined( AES_128 ) || defined( AES_VAR) -AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); -#endif - -#if defined( AES_192 ) || defined( AES_VAR) -AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); -#endif - -#if defined( AES_256 ) || defined( AES_VAR) -AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); -#endif - -#if defined( AES_VAR ) -AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]); -#endif - -AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]); - -#endif - -#if defined( AES_MODES ) - -/* Multiple calls to the following subroutines for multiple block */ -/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */ -/* long messages incrementally provided that the context AND the iv */ -/* are preserved between all such calls. For the ECB and CBC modes */ -/* each individual call within a series of incremental calls must */ -/* process only full blocks (i.e. len must be a multiple of 16) but */ -/* the CFB, OFB and CTR mode calls can handle multiple incremental */ -/* calls of any length. Each mode is reset when a new AES key is */ -/* set but ECB needs no reset and CBC can be reset without setting */ -/* a new key by setting a new IV value. To reset CFB, OFB and CTR */ -/* without setting the key, aes_mode_reset() must be called and the */ -/* IV must be set. NOTE: All these calls update the IV on exit so */ -/* this has to be reset if a new operation with the same IV as the */ -/* previous one is required (or decryption follows encryption with */ -/* the same IV array). */ - -AES_RETURN aes_test_alignment_detection(unsigned int n); - -AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, const aes_encrypt_ctx cx[1]); - -AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, const aes_decrypt_ctx cx[1]); - -AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, const aes_encrypt_ctx cx[1]); - -AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, const aes_decrypt_ctx cx[1]); - -AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]); - -AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx cx[1]); - -AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx cx[1]); - -#define aes_ofb_encrypt aes_ofb_crypt -#define aes_ofb_decrypt aes_ofb_crypt - -AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *iv, aes_encrypt_ctx cx[1]); - -typedef void cbuf_inc(unsigned char *cbuf); - -#define aes_ctr_encrypt aes_ctr_crypt -#define aes_ctr_decrypt aes_ctr_crypt - -AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf, - int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]); - -#endif - -#if 0 -# define ADD_AESNI_MODE_CALLS -#endif - -#if 0 && defined( ADD_AESNI_MODE_CALLS ) -# define USE_AES_CONTEXT -#endif - -#ifdef ADD_AESNI_MODE_CALLS -# ifdef USE_AES_CONTEXT - -AES_RETURN aes_CBC_encrypt(const unsigned char *in, - unsigned char *out, - unsigned char ivec[16], - unsigned long length, - const aes_encrypt_ctx cx[1]); - -AES_RETURN aes_CBC_decrypt(const unsigned char *in, - unsigned char *out, - unsigned char ivec[16], - unsigned long length, - const aes_decrypt_ctx cx[1]); - -AES_RETURN AES_CTR_encrypt(const unsigned char *in, - unsigned char *out, - const unsigned char ivec[8], - const unsigned char nonce[4], - unsigned long length, - const aes_encrypt_ctx cx[1]); - -# else - -void aes_CBC_encrypt(const unsigned char *in, - unsigned char *out, - unsigned char ivec[16], - unsigned long length, - unsigned char *key, - int number_of_rounds); - -void aes_CBC_decrypt(const unsigned char *in, - unsigned char *out, - unsigned char ivec[16], - unsigned long length, - unsigned char *key, - int number_of_rounds); - -void AES_CTR_encrypt(const unsigned char *in, - unsigned char *out, - const unsigned char ivec[8], - const unsigned char nonce[4], - unsigned long length, - const unsigned char *key, - int number_of_rounds); - -# endif -#endif - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/aescrypt.c b/game/client/third/minizip/lib/aes/aescrypt.c deleted file mode 100755 index bd647e4e..00000000 --- a/game/client/third/minizip/lib/aes/aescrypt.c +++ /dev/null @@ -1,301 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 -*/ - -#include "aesopt.h" -#include "aestab.h" - -#if defined( USE_INTEL_AES_IF_PRESENT ) -# include "aes_ni.h" -#else -/* map names here to provide the external API ('name' -> 'aes_name') */ -# define aes_xi(x) aes_ ## x -#endif - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c]) -#define so(y,x,c) word_out(y, c, s(x,c)) - -#if defined(ARRAYS) -#define locals(y,x) x[4],y[4] -#else -#define locals(y,x) x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3 -#endif - -#define l_copy(y, x) s(y,0) = s(x,0); s(y,1) = s(x,1); \ - s(y,2) = s(x,2); s(y,3) = s(x,3); -#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3) -#define state_out(y,x) so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3) -#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3) - -#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) - -/* Visual C++ .Net v7.1 provides the fastest encryption code when using - Pentium optimiation with small code but this is poor for decryption - so we need to control this with the following VC++ pragmas -*/ - -#if defined( _MSC_VER ) && !defined( _WIN64 ) -#pragma optimize( "s", on ) -#endif - -/* Given the column (c) of the output state variable, the following - macros give the input state variables which are needed in its - computation for each row (r) of the state. All the alternative - macros give the same end values but expand into different ways - of calculating these values. In particular the complex macro - used for dynamically variable block sizes is designed to expand - to a compile time constant whenever possible but will expand to - conditional clauses on some branches (I am grateful to Frank - Yellin for this construction) -*/ - -#define fwd_var(x,r,c)\ - ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ - : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\ - : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ - : ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))) - -#if defined(FT4_SET) -#undef dec_fmvars -#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c)) -#elif defined(FT1_SET) -#undef dec_fmvars -#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c)) -#else -#define fwd_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c))) -#endif - -#if defined(FL4_SET) -#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c)) -#elif defined(FL1_SET) -#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c)) -#else -#define fwd_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c)) -#endif - -AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]) -{ uint32_t locals(b0, b1); - const uint32_t *kp; -#if defined( dec_fmvars ) - dec_fmvars; /* declare variables for fwd_mcol() if needed */ -#endif - - if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16) - return EXIT_FAILURE; - - kp = cx->ks; - state_in(b0, in, kp); - -#if (ENC_UNROLL == FULL) - - switch(cx->inf.b[0]) - { - case 14 * 16: - round(fwd_rnd, b1, b0, kp + 1 * N_COLS); - round(fwd_rnd, b0, b1, kp + 2 * N_COLS); - kp += 2 * N_COLS; - case 12 * 16: - round(fwd_rnd, b1, b0, kp + 1 * N_COLS); - round(fwd_rnd, b0, b1, kp + 2 * N_COLS); - kp += 2 * N_COLS; - case 10 * 16: - round(fwd_rnd, b1, b0, kp + 1 * N_COLS); - round(fwd_rnd, b0, b1, kp + 2 * N_COLS); - round(fwd_rnd, b1, b0, kp + 3 * N_COLS); - round(fwd_rnd, b0, b1, kp + 4 * N_COLS); - round(fwd_rnd, b1, b0, kp + 5 * N_COLS); - round(fwd_rnd, b0, b1, kp + 6 * N_COLS); - round(fwd_rnd, b1, b0, kp + 7 * N_COLS); - round(fwd_rnd, b0, b1, kp + 8 * N_COLS); - round(fwd_rnd, b1, b0, kp + 9 * N_COLS); - round(fwd_lrnd, b0, b1, kp +10 * N_COLS); - } - -#else - -#if (ENC_UNROLL == PARTIAL) - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) - { - kp += N_COLS; - round(fwd_rnd, b1, b0, kp); - kp += N_COLS; - round(fwd_rnd, b0, b1, kp); - } - kp += N_COLS; - round(fwd_rnd, b1, b0, kp); -#else - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) - { - kp += N_COLS; - round(fwd_rnd, b1, b0, kp); - l_copy(b0, b1); - } -#endif - kp += N_COLS; - round(fwd_lrnd, b0, b1, kp); - } -#endif - - state_out(out, b0); - return EXIT_SUCCESS; -} - -#endif - -#if ( FUNCS_IN_C & DECRYPTION_IN_C) - -/* Visual C++ .Net v7.1 provides the fastest encryption code when using - Pentium optimiation with small code but this is poor for decryption - so we need to control this with the following VC++ pragmas -*/ - -#if defined( _MSC_VER ) && !defined( _WIN64 ) -#pragma optimize( "t", on ) -#endif - -/* Given the column (c) of the output state variable, the following - macros give the input state variables which are needed in its - computation for each row (r) of the state. All the alternative - macros give the same end values but expand into different ways - of calculating these values. In particular the complex macro - used for dynamically variable block sizes is designed to expand - to a compile time constant whenever possible but will expand to - conditional clauses on some branches (I am grateful to Frank - Yellin for this construction) -*/ - -#define inv_var(x,r,c)\ - ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\ - : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\ - : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\ - : ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))) - -#if defined(IT4_SET) -#undef dec_imvars -#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c)) -#elif defined(IT1_SET) -#undef dec_imvars -#define inv_rnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c)) -#else -#define inv_rnd(y,x,k,c) (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))) -#endif - -#if defined(IL4_SET) -#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c)) -#elif defined(IL1_SET) -#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c)) -#else -#define inv_lrnd(y,x,k,c) (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)) -#endif - -/* This code can work with the decryption key schedule in the */ -/* order that is used for encrytpion (where the 1st decryption */ -/* round key is at the high end ot the schedule) or with a key */ -/* schedule that has been reversed to put the 1st decryption */ -/* round key at the low end of the schedule in memory (when */ -/* AES_REV_DKS is defined) */ - -#ifdef AES_REV_DKS -#define key_ofs 0 -#define rnd_key(n) (kp + n * N_COLS) -#else -#define key_ofs 1 -#define rnd_key(n) (kp - n * N_COLS) -#endif - -AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]) -{ uint32_t locals(b0, b1); -#if defined( dec_imvars ) - dec_imvars; /* declare variables for inv_mcol() if needed */ -#endif - const uint32_t *kp; - - if(cx->inf.b[0] != 10 * 16 && cx->inf.b[0] != 12 * 16 && cx->inf.b[0] != 14 * 16) - return EXIT_FAILURE; - - kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0); - state_in(b0, in, kp); - -#if (DEC_UNROLL == FULL) - - kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2)); - switch(cx->inf.b[0]) - { - case 14 * 16: - round(inv_rnd, b1, b0, rnd_key(-13)); - round(inv_rnd, b0, b1, rnd_key(-12)); - case 12 * 16: - round(inv_rnd, b1, b0, rnd_key(-11)); - round(inv_rnd, b0, b1, rnd_key(-10)); - case 10 * 16: - round(inv_rnd, b1, b0, rnd_key(-9)); - round(inv_rnd, b0, b1, rnd_key(-8)); - round(inv_rnd, b1, b0, rnd_key(-7)); - round(inv_rnd, b0, b1, rnd_key(-6)); - round(inv_rnd, b1, b0, rnd_key(-5)); - round(inv_rnd, b0, b1, rnd_key(-4)); - round(inv_rnd, b1, b0, rnd_key(-3)); - round(inv_rnd, b0, b1, rnd_key(-2)); - round(inv_rnd, b1, b0, rnd_key(-1)); - round(inv_lrnd, b0, b1, rnd_key( 0)); - } - -#else - -#if (DEC_UNROLL == PARTIAL) - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1; ++rnd) - { - kp = rnd_key(1); - round(inv_rnd, b1, b0, kp); - kp = rnd_key(1); - round(inv_rnd, b0, b1, kp); - } - kp = rnd_key(1); - round(inv_rnd, b1, b0, kp); -#else - { uint32_t rnd; - for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1; ++rnd) - { - kp = rnd_key(1); - round(inv_rnd, b1, b0, kp); - l_copy(b0, b1); - } -#endif - kp = rnd_key(1); - round(inv_lrnd, b0, b1, kp); - } -#endif - - state_out(out, b0); - return EXIT_SUCCESS; -} - -#endif - -#if defined(__cplusplus) -} -#endif diff --git a/game/client/third/minizip/lib/aes/aeskey.c b/game/client/third/minizip/lib/aes/aeskey.c deleted file mode 100755 index 16e9607f..00000000 --- a/game/client/third/minizip/lib/aes/aeskey.c +++ /dev/null @@ -1,554 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 -*/ - -#include "aesopt.h" -#include "aestab.h" - -#if defined( USE_INTEL_AES_IF_PRESENT ) -# include "aes_ni.h" -#else -/* map names here to provide the external API ('name' -> 'aes_name') */ -# define aes_xi(x) aes_ ## x -#endif - -#ifdef USE_VIA_ACE_IF_PRESENT -# include "aes_via_ace.h" -#endif - -#if defined(__cplusplus) -extern "C" -{ -#endif - -/* Initialise the key schedule from the user supplied key. The key - length can be specified in bytes, with legal values of 16, 24 - and 32, or in bits, with legal values of 128, 192 and 256. These - values correspond with Nk values of 4, 6 and 8 respectively. - - The following macros implement a single cycle in the key - schedule generation process. The number of cycles needed - for each cx->n_col and nk value is: - - nk = 4 5 6 7 8 - ------------------------------ - cx->n_col = 4 10 9 8 7 7 - cx->n_col = 5 14 11 10 9 9 - cx->n_col = 6 19 15 12 11 11 - cx->n_col = 7 21 19 16 13 14 - cx->n_col = 8 29 23 19 17 14 -*/ - -#if defined( REDUCE_CODE_SIZE ) -# define ls_box ls_sub - uint32_t ls_sub(const uint32_t t, const uint32_t n); -# define inv_mcol im_sub - uint32_t im_sub(const uint32_t x); -# ifdef ENC_KS_UNROLL -# undef ENC_KS_UNROLL -# endif -# ifdef DEC_KS_UNROLL -# undef DEC_KS_UNROLL -# endif -#endif - -#if (FUNCS_IN_C & ENC_KEYING_IN_C) - -#if defined(AES_128) || defined( AES_VAR ) - -#define ke4(k,i) \ -{ k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ - k[4*(i)+5] = ss[1] ^= ss[0]; \ - k[4*(i)+6] = ss[2] ^= ss[1]; \ - k[4*(i)+7] = ss[3] ^= ss[2]; \ -} - -AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1]) -{ uint32_t ss[4]; - - cx->ks[0] = ss[0] = word_in(key, 0); - cx->ks[1] = ss[1] = word_in(key, 1); - cx->ks[2] = ss[2] = word_in(key, 2); - cx->ks[3] = ss[3] = word_in(key, 3); - -#ifdef ENC_KS_UNROLL - ke4(cx->ks, 0); ke4(cx->ks, 1); - ke4(cx->ks, 2); ke4(cx->ks, 3); - ke4(cx->ks, 4); ke4(cx->ks, 5); - ke4(cx->ks, 6); ke4(cx->ks, 7); - ke4(cx->ks, 8); -#else - { uint32_t i; - for(i = 0; i < 9; ++i) - ke4(cx->ks, i); - } -#endif - ke4(cx->ks, 9); - cx->inf.l = 0; - cx->inf.b[0] = 10 * 16; - -#ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; -#endif - return EXIT_SUCCESS; -} - -#endif - -#if defined(AES_192) || defined( AES_VAR ) - -#define kef6(k,i) \ -{ k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ - k[6*(i)+ 7] = ss[1] ^= ss[0]; \ - k[6*(i)+ 8] = ss[2] ^= ss[1]; \ - k[6*(i)+ 9] = ss[3] ^= ss[2]; \ -} - -#define ke6(k,i) \ -{ kef6(k,i); \ - k[6*(i)+10] = ss[4] ^= ss[3]; \ - k[6*(i)+11] = ss[5] ^= ss[4]; \ -} - -AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1]) -{ uint32_t ss[6]; - - cx->ks[0] = ss[0] = word_in(key, 0); - cx->ks[1] = ss[1] = word_in(key, 1); - cx->ks[2] = ss[2] = word_in(key, 2); - cx->ks[3] = ss[3] = word_in(key, 3); - cx->ks[4] = ss[4] = word_in(key, 4); - cx->ks[5] = ss[5] = word_in(key, 5); - -#ifdef ENC_KS_UNROLL - ke6(cx->ks, 0); ke6(cx->ks, 1); - ke6(cx->ks, 2); ke6(cx->ks, 3); - ke6(cx->ks, 4); ke6(cx->ks, 5); - ke6(cx->ks, 6); -#else - { uint32_t i; - for(i = 0; i < 7; ++i) - ke6(cx->ks, i); - } -#endif - kef6(cx->ks, 7); - cx->inf.l = 0; - cx->inf.b[0] = 12 * 16; - -#ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; -#endif - return EXIT_SUCCESS; -} - -#endif - -#if defined(AES_256) || defined( AES_VAR ) - -#define kef8(k,i) \ -{ k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ - k[8*(i)+ 9] = ss[1] ^= ss[0]; \ - k[8*(i)+10] = ss[2] ^= ss[1]; \ - k[8*(i)+11] = ss[3] ^= ss[2]; \ -} - -#define ke8(k,i) \ -{ kef8(k,i); \ - k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \ - k[8*(i)+13] = ss[5] ^= ss[4]; \ - k[8*(i)+14] = ss[6] ^= ss[5]; \ - k[8*(i)+15] = ss[7] ^= ss[6]; \ -} - -AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1]) -{ uint32_t ss[8]; - - cx->ks[0] = ss[0] = word_in(key, 0); - cx->ks[1] = ss[1] = word_in(key, 1); - cx->ks[2] = ss[2] = word_in(key, 2); - cx->ks[3] = ss[3] = word_in(key, 3); - cx->ks[4] = ss[4] = word_in(key, 4); - cx->ks[5] = ss[5] = word_in(key, 5); - cx->ks[6] = ss[6] = word_in(key, 6); - cx->ks[7] = ss[7] = word_in(key, 7); - -#ifdef ENC_KS_UNROLL - ke8(cx->ks, 0); ke8(cx->ks, 1); - ke8(cx->ks, 2); ke8(cx->ks, 3); - ke8(cx->ks, 4); ke8(cx->ks, 5); -#else - { uint32_t i; - for(i = 0; i < 6; ++i) - ke8(cx->ks, i); - } -#endif - kef8(cx->ks, 6); - cx->inf.l = 0; - cx->inf.b[0] = 14 * 16; - -#ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; -#endif - return EXIT_SUCCESS; -} - -#endif - -#endif - -#if (FUNCS_IN_C & DEC_KEYING_IN_C) - -/* this is used to store the decryption round keys */ -/* in forward or reverse order */ - -#ifdef AES_REV_DKS -#define v(n,i) ((n) - (i) + 2 * ((i) & 3)) -#else -#define v(n,i) (i) -#endif - -#if DEC_ROUND == NO_TABLES -#define ff(x) (x) -#else -#define ff(x) inv_mcol(x) -#if defined( dec_imvars ) -#define d_vars dec_imvars -#endif -#endif - -#if defined(AES_128) || defined( AES_VAR ) - -#define k4e(k,i) \ -{ k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \ - k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \ - k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \ - k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \ -} - -#if 1 - -#define kdf4(k,i) \ -{ ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \ - ss[1] = ss[1] ^ ss[3]; \ - ss[2] = ss[2] ^ ss[3]; \ - ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ - ss[i % 4] ^= ss[4]; \ - ss[4] ^= k[v(40,(4*(i)))]; k[v(40,(4*(i))+4)] = ff(ss[4]); \ - ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \ - ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \ - ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \ -} - -#define kd4(k,i) \ -{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \ - ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \ - k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \ - k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \ - k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \ - k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \ -} - -#define kdl4(k,i) \ -{ ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \ - k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \ - k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \ - k[v(40,(4*(i))+6)] = ss[0]; \ - k[v(40,(4*(i))+7)] = ss[1]; \ -} - -#else - -#define kdf4(k,i) \ -{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \ - ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \ - ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \ -} - -#define kd4(k,i) \ -{ ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \ - ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \ - ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \ - ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \ - ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \ -} - -#define kdl4(k,i) \ -{ ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \ - ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \ - ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \ - ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \ -} - -#endif - -AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1]) -{ uint32_t ss[5]; -#if defined( d_vars ) - d_vars; -#endif - - cx->ks[v(40,(0))] = ss[0] = word_in(key, 0); - cx->ks[v(40,(1))] = ss[1] = word_in(key, 1); - cx->ks[v(40,(2))] = ss[2] = word_in(key, 2); - cx->ks[v(40,(3))] = ss[3] = word_in(key, 3); - -#ifdef DEC_KS_UNROLL - kdf4(cx->ks, 0); kd4(cx->ks, 1); - kd4(cx->ks, 2); kd4(cx->ks, 3); - kd4(cx->ks, 4); kd4(cx->ks, 5); - kd4(cx->ks, 6); kd4(cx->ks, 7); - kd4(cx->ks, 8); kdl4(cx->ks, 9); -#else - { uint32_t i; - for(i = 0; i < 10; ++i) - k4e(cx->ks, i); -#if !(DEC_ROUND == NO_TABLES) - for(i = N_COLS; i < 10 * N_COLS; ++i) - cx->ks[i] = inv_mcol(cx->ks[i]); -#endif - } -#endif - cx->inf.l = 0; - cx->inf.b[0] = 10 * 16; - -#ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; -#endif - return EXIT_SUCCESS; -} - -#endif - -#if defined(AES_192) || defined( AES_VAR ) - -#define k6ef(k,i) \ -{ k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \ - k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \ - k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \ - k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \ -} - -#define k6e(k,i) \ -{ k6ef(k,i); \ - k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \ - k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \ -} - -#define kdf6(k,i) \ -{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \ - ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \ - ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \ - ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \ - ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \ -} - -#define kd6(k,i) \ -{ ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \ - ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \ - ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \ - ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \ - ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \ - ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \ - ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \ -} - -#define kdl6(k,i) \ -{ ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \ - ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \ - ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \ - ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \ -} - -AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1]) -{ uint32_t ss[7]; -#if defined( d_vars ) - d_vars; -#endif - - cx->ks[v(48,(0))] = ss[0] = word_in(key, 0); - cx->ks[v(48,(1))] = ss[1] = word_in(key, 1); - cx->ks[v(48,(2))] = ss[2] = word_in(key, 2); - cx->ks[v(48,(3))] = ss[3] = word_in(key, 3); - -#ifdef DEC_KS_UNROLL - cx->ks[v(48,(4))] = ff(ss[4] = word_in(key, 4)); - cx->ks[v(48,(5))] = ff(ss[5] = word_in(key, 5)); - kdf6(cx->ks, 0); kd6(cx->ks, 1); - kd6(cx->ks, 2); kd6(cx->ks, 3); - kd6(cx->ks, 4); kd6(cx->ks, 5); - kd6(cx->ks, 6); kdl6(cx->ks, 7); -#else - cx->ks[v(48,(4))] = ss[4] = word_in(key, 4); - cx->ks[v(48,(5))] = ss[5] = word_in(key, 5); - { uint32_t i; - - for(i = 0; i < 7; ++i) - k6e(cx->ks, i); - k6ef(cx->ks, 7); -#if !(DEC_ROUND == NO_TABLES) - for(i = N_COLS; i < 12 * N_COLS; ++i) - cx->ks[i] = inv_mcol(cx->ks[i]); -#endif - } -#endif - cx->inf.l = 0; - cx->inf.b[0] = 12 * 16; - -#ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; -#endif - return EXIT_SUCCESS; -} - -#endif - -#if defined(AES_256) || defined( AES_VAR ) - -#define k8ef(k,i) \ -{ k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \ - k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \ - k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \ - k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \ -} - -#define k8e(k,i) \ -{ k8ef(k,i); \ - k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \ - k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \ - k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \ - k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \ -} - -#define kdf8(k,i) \ -{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \ - ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \ - ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \ - ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \ - ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \ - ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \ - ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \ - ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \ -} - -#define kd8(k,i) \ -{ ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \ - ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \ - ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \ - ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \ - ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \ - ss[8] = ls_box(ss[3],0); \ - ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \ - ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \ - ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \ - ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \ -} - -#define kdl8(k,i) \ -{ ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \ - ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \ - ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \ - ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \ -} - -AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1]) -{ uint32_t ss[9]; -#if defined( d_vars ) - d_vars; -#endif - - cx->ks[v(56,(0))] = ss[0] = word_in(key, 0); - cx->ks[v(56,(1))] = ss[1] = word_in(key, 1); - cx->ks[v(56,(2))] = ss[2] = word_in(key, 2); - cx->ks[v(56,(3))] = ss[3] = word_in(key, 3); - -#ifdef DEC_KS_UNROLL - cx->ks[v(56,(4))] = ff(ss[4] = word_in(key, 4)); - cx->ks[v(56,(5))] = ff(ss[5] = word_in(key, 5)); - cx->ks[v(56,(6))] = ff(ss[6] = word_in(key, 6)); - cx->ks[v(56,(7))] = ff(ss[7] = word_in(key, 7)); - kdf8(cx->ks, 0); kd8(cx->ks, 1); - kd8(cx->ks, 2); kd8(cx->ks, 3); - kd8(cx->ks, 4); kd8(cx->ks, 5); - kdl8(cx->ks, 6); -#else - cx->ks[v(56,(4))] = ss[4] = word_in(key, 4); - cx->ks[v(56,(5))] = ss[5] = word_in(key, 5); - cx->ks[v(56,(6))] = ss[6] = word_in(key, 6); - cx->ks[v(56,(7))] = ss[7] = word_in(key, 7); - { uint32_t i; - - for(i = 0; i < 6; ++i) - k8e(cx->ks, i); - k8ef(cx->ks, 6); -#if !(DEC_ROUND == NO_TABLES) - for(i = N_COLS; i < 14 * N_COLS; ++i) - cx->ks[i] = inv_mcol(cx->ks[i]); -#endif - } -#endif - cx->inf.l = 0; - cx->inf.b[0] = 14 * 16; - -#ifdef USE_VIA_ACE_IF_PRESENT - if(VIA_ACE_AVAILABLE) - cx->inf.b[1] = 0xff; -#endif - return EXIT_SUCCESS; -} - -#endif - -#endif - -#if defined( AES_VAR ) - -AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]) -{ - switch(key_len) - { - case 16: case 128: return aes_encrypt_key128(key, cx); - case 24: case 192: return aes_encrypt_key192(key, cx); - case 32: case 256: return aes_encrypt_key256(key, cx); - default: return EXIT_FAILURE; - } -} - -AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]) -{ - switch(key_len) - { - case 16: case 128: return aes_decrypt_key128(key, cx); - case 24: case 192: return aes_decrypt_key192(key, cx); - case 32: case 256: return aes_decrypt_key256(key, cx); - default: return EXIT_FAILURE; - } -} - -#endif - -#if defined(__cplusplus) -} -#endif diff --git a/game/client/third/minizip/lib/aes/aesopt.h b/game/client/third/minizip/lib/aes/aesopt.h deleted file mode 100755 index 2c058dea..00000000 --- a/game/client/third/minizip/lib/aes/aesopt.h +++ /dev/null @@ -1,776 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - - This file contains the compilation options for AES (Rijndael) and code - that is common across encryption, key scheduling and table generation. - - OPERATION - - These source code files implement the AES algorithm Rijndael designed by - Joan Daemen and Vincent Rijmen. This version is designed for the standard - block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24 - and 32 bytes). - - This version is designed for flexibility and speed using operations on - 32-bit words rather than operations on bytes. It can be compiled with - either big or little endian internal byte order but is faster when the - native byte order for the processor is used. - - THE CIPHER INTERFACE - - The cipher interface is implemented as an array of bytes in which lower - AES bit sequence indexes map to higher numeric significance within bytes. - - uint8_t (an unsigned 8-bit type) - uint32_t (an unsigned 32-bit type) - struct aes_encrypt_ctx (structure for the cipher encryption context) - struct aes_decrypt_ctx (structure for the cipher decryption context) - AES_RETURN the function return type - - C subroutine calls: - - AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]); - AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]); - AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]); - AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, - const aes_encrypt_ctx cx[1]); - - AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]); - AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]); - AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]); - AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, - const aes_decrypt_ctx cx[1]); - - IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that - you call aes_init() before AES is used so that the tables are initialised. - - C++ aes class subroutines: - - Class AESencrypt for encryption - - Construtors: - AESencrypt(void) - AESencrypt(const unsigned char *key) - 128 bit key - Members: - AES_RETURN key128(const unsigned char *key) - AES_RETURN key192(const unsigned char *key) - AES_RETURN key256(const unsigned char *key) - AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const - - Class AESdecrypt for encryption - Construtors: - AESdecrypt(void) - AESdecrypt(const unsigned char *key) - 128 bit key - Members: - AES_RETURN key128(const unsigned char *key) - AES_RETURN key192(const unsigned char *key) - AES_RETURN key256(const unsigned char *key) - AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const -*/ - -#if !defined( _AESOPT_H ) -#define _AESOPT_H - -#if defined( __cplusplus ) -#include "aescpp.h" -#else -#include "aes.h" -#endif - -/* PLATFORM SPECIFIC INCLUDES */ - -#include "brg_endian.h" - -/* CONFIGURATION - THE USE OF DEFINES - - Later in this section there are a number of defines that control the - operation of the code. In each section, the purpose of each define is - explained so that the relevant form can be included or excluded by - setting either 1's or 0's respectively on the branches of the related - #if clauses. The following local defines should not be changed. -*/ - -#define ENCRYPTION_IN_C 1 -#define DECRYPTION_IN_C 2 -#define ENC_KEYING_IN_C 4 -#define DEC_KEYING_IN_C 8 - -#define NO_TABLES 0 -#define ONE_TABLE 1 -#define FOUR_TABLES 4 -#define NONE 0 -#define PARTIAL 1 -#define FULL 2 - -/* --- START OF USER CONFIGURED OPTIONS --- */ - -/* 1. BYTE ORDER WITHIN 32 BIT WORDS - - The fundamental data processing units in Rijndael are 8-bit bytes. The - input, output and key input are all enumerated arrays of bytes in which - bytes are numbered starting at zero and increasing to one less than the - number of bytes in the array in question. This enumeration is only used - for naming bytes and does not imply any adjacency or order relationship - from one byte to another. When these inputs and outputs are considered - as bit sequences, bits 8*n to 8*n+7 of the bit sequence are mapped to - byte[n] with bit 8n+i in the sequence mapped to bit 7-i within the byte. - In this implementation bits are numbered from 0 to 7 starting at the - numerically least significant end of each byte (bit n represents 2^n). - - However, Rijndael can be implemented more efficiently using 32-bit - words by packing bytes into words so that bytes 4*n to 4*n+3 are placed - into word[n]. While in principle these bytes can be assembled into words - in any positions, this implementation only supports the two formats in - which bytes in adjacent positions within words also have adjacent byte - numbers. This order is called big-endian if the lowest numbered bytes - in words have the highest numeric significance and little-endian if the - opposite applies. - - This code can work in either order irrespective of the order used by the - machine on which it runs. Normally the internal byte order will be set - to the order of the processor on which the code is to be run but this - define can be used to reverse this in special situations - - WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set. - This define will hence be redefined later (in section 4) if necessary -*/ - -#if 1 -# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER -#elif 0 -# define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN -#elif 0 -# define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN -#else -# error The algorithm byte order is not defined -#endif - -/* 2. Intel AES AND VIA ACE SUPPORT */ - -#if defined( __GNUC__ ) && defined( __i386__ ) \ - || defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \ - || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 )) -# define VIA_ACE_POSSIBLE -#endif - -#if (defined( _WIN64 ) && defined( _MSC_VER )) \ - || (defined( __GNUC__ ) && defined( __x86_64__ )) && !(defined( __APPLE__ ))\ - && !(defined( INTEL_AES_POSSIBLE )) -# define INTEL_AES_POSSIBLE -#endif - -/* Define this option if support for the Intel AESNI is required - If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used - if it is detected (both present and enabled). - - AESNI uses a decryption key schedule with the first decryption - round key at the high end of the key scedule with the following - round keys at lower positions in memory. So AES_REV_DKS must NOT - be defined when AESNI will be used. ALthough it is unlikely that - assembler code will be used with an AESNI build, if it is then - AES_REV_DKS must NOT be defined when the assembler files are - built -*/ - -#if 0 && defined( INTEL_AES_POSSIBLE ) && !defined( USE_INTEL_AES_IF_PRESENT ) -# define USE_INTEL_AES_IF_PRESENT -#endif - -/* Define this option if support for the VIA ACE is required. This uses - inline assembler instructions and is only implemented for the Microsoft, - Intel and GCC compilers. If VIA ACE is known to be present, then defining - ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption - code. If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if - it is detected (both present and enabled) but the normal AES code will - also be present. - - When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte - aligned; other input/output buffers do not need to be 16 byte aligned - but there are very large performance gains if this can be arranged. - VIA ACE also requires the decryption key schedule to be in reverse - order (which later checks below ensure). - - AES_REV_DKS must be set for assembler code used with a VIA ACE build -*/ - -#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT ) -# define USE_VIA_ACE_IF_PRESENT -#endif - -#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT ) -# define ASSUME_VIA_ACE_PRESENT -# endif - -/* 3. ASSEMBLER SUPPORT - - This define (which can be on the command line) enables the use of the - assembler code routines for encryption, decryption and key scheduling - as follows: - - ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for - encryption and decryption and but with key scheduling in C - ASM_X86_V2 uses assembler (aes_x86_v2.asm) with compressed tables for - encryption, decryption and key scheduling - ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for - encryption and decryption and but with key scheduling in C - ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for - encryption and decryption and but with key scheduling in C - - Change one 'if 0' below to 'if 1' to select the version or define - as a compilation option. -*/ - -#if 0 && !defined( ASM_X86_V1C ) -# define ASM_X86_V1C -#elif 0 && !defined( ASM_X86_V2 ) -# define ASM_X86_V2 -#elif 0 && !defined( ASM_X86_V2C ) -# define ASM_X86_V2C -#elif 0 && !defined( ASM_AMD64_C ) -# define ASM_AMD64_C -#endif - -#if defined( __i386 ) || defined( _M_IX86 ) -# define A32_ -#elif defined( __x86_64__ ) || defined( _M_X64 ) -# define A64_ -#endif - -#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \ - && !defined( A32_ ) || defined( ASM_AMD64_C ) && !defined( A64_ ) -# error Assembler code is only available for x86 and AMD64 systems -#endif - -/* 4. FAST INPUT/OUTPUT OPERATIONS. - - On some machines it is possible to improve speed by transferring the - bytes in the input and output arrays to and from the internal 32-bit - variables by addressing these arrays as if they are arrays of 32-bit - words. On some machines this will always be possible but there may - be a large performance penalty if the byte arrays are not aligned on - the normal word boundaries. On other machines this technique will - lead to memory access errors when such 32-bit word accesses are not - properly aligned. The option SAFE_IO avoids such problems but will - often be slower on those machines that support misaligned access - (especially so if care is taken to align the input and output byte - arrays on 32-bit word boundaries). If SAFE_IO is not defined it is - assumed that access to byte arrays as if they are arrays of 32-bit - words will not cause problems when such accesses are misaligned. -*/ -#if 1 && !defined( _MSC_VER ) -# define SAFE_IO -#endif - -/* 5. LOOP UNROLLING - - The code for encryption and decrytpion cycles through a number of rounds - that can be implemented either in a loop or by expanding the code into a - long sequence of instructions, the latter producing a larger program but - one that will often be much faster. The latter is called loop unrolling. - There are also potential speed advantages in expanding two iterations in - a loop with half the number of iterations, which is called partial loop - unrolling. The following options allow partial or full loop unrolling - to be set independently for encryption and decryption -*/ -#if 1 -# define ENC_UNROLL FULL -#elif 0 -# define ENC_UNROLL PARTIAL -#else -# define ENC_UNROLL NONE -#endif - -#if 1 -# define DEC_UNROLL FULL -#elif 0 -# define DEC_UNROLL PARTIAL -#else -# define DEC_UNROLL NONE -#endif - -#if 1 -# define ENC_KS_UNROLL -#endif - -#if 1 -# define DEC_KS_UNROLL -#endif - -/* 6. FAST FINITE FIELD OPERATIONS - - If this section is included, tables are used to provide faster finite - field arithmetic (this has no effect if STATIC_TABLES is defined). -*/ -#if 1 -# define FF_TABLES -#endif - -/* 7. INTERNAL STATE VARIABLE FORMAT - - The internal state of Rijndael is stored in a number of local 32-bit - word varaibles which can be defined either as an array or as individual - names variables. Include this section if you want to store these local - varaibles in arrays. Otherwise individual local variables will be used. -*/ -#if 1 -# define ARRAYS -#endif - -/* 8. FIXED OR DYNAMIC TABLES - - When this section is included the tables used by the code are compiled - statically into the binary file. Otherwise the subroutine aes_init() - must be called to compute them before the code is first used. -*/ -#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 )) -# define STATIC_TABLES -#endif - -/* 9. MASKING OR CASTING FROM LONGER VALUES TO BYTES - - In some systems it is better to mask longer values to extract bytes - rather than using a cast. This option allows this choice. -*/ -#if 0 -# define to_byte(x) ((uint8_t)(x)) -#else -# define to_byte(x) ((x) & 0xff) -#endif - -/* 10. TABLE ALIGNMENT - - On some sytsems speed will be improved by aligning the AES large lookup - tables on particular boundaries. This define should be set to a power of - two giving the desired alignment. It can be left undefined if alignment - is not needed. This option is specific to the Microsft VC++ compiler - - it seems to sometimes cause trouble for the VC++ version 6 compiler. -*/ - -#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) -# define TABLE_ALIGN 32 -#endif - -/* 11. REDUCE CODE AND TABLE SIZE - - This replaces some expanded macros with function calls if AES_ASM_V2 or - AES_ASM_V2C are defined -*/ - -#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) -# define REDUCE_CODE_SIZE -#endif - -/* 12. TABLE OPTIONS - - This cipher proceeds by repeating in a number of cycles known as 'rounds' - which are implemented by a round function which can optionally be speeded - up using tables. The basic tables are each 256 32-bit words, with either - one or four tables being required for each round function depending on - how much speed is required. The encryption and decryption round functions - are different and the last encryption and decrytpion round functions are - different again making four different round functions in all. - - This means that: - 1. Normal encryption and decryption rounds can each use either 0, 1 - or 4 tables and table spaces of 0, 1024 or 4096 bytes each. - 2. The last encryption and decryption rounds can also use either 0, 1 - or 4 tables and table spaces of 0, 1024 or 4096 bytes each. - - Include or exclude the appropriate definitions below to set the number - of tables used by this implementation. -*/ - -#if 1 /* set tables for the normal encryption round */ -# define ENC_ROUND FOUR_TABLES -#elif 0 -# define ENC_ROUND ONE_TABLE -#else -# define ENC_ROUND NO_TABLES -#endif - -#if 1 /* set tables for the last encryption round */ -# define LAST_ENC_ROUND FOUR_TABLES -#elif 0 -# define LAST_ENC_ROUND ONE_TABLE -#else -# define LAST_ENC_ROUND NO_TABLES -#endif - -#if 1 /* set tables for the normal decryption round */ -# define DEC_ROUND FOUR_TABLES -#elif 0 -# define DEC_ROUND ONE_TABLE -#else -# define DEC_ROUND NO_TABLES -#endif - -#if 1 /* set tables for the last decryption round */ -# define LAST_DEC_ROUND FOUR_TABLES -#elif 0 -# define LAST_DEC_ROUND ONE_TABLE -#else -# define LAST_DEC_ROUND NO_TABLES -#endif - -/* The decryption key schedule can be speeded up with tables in the same - way that the round functions can. Include or exclude the following - defines to set this requirement. -*/ -#if 1 -# define KEY_SCHED FOUR_TABLES -#elif 0 -# define KEY_SCHED ONE_TABLE -#else -# define KEY_SCHED NO_TABLES -#endif - -/* ---- END OF USER CONFIGURED OPTIONS ---- */ - -/* VIA ACE support is only available for VC++ and GCC */ - -#if !defined( _MSC_VER ) && !defined( __GNUC__ ) -# if defined( ASSUME_VIA_ACE_PRESENT ) -# undef ASSUME_VIA_ACE_PRESENT -# endif -# if defined( USE_VIA_ACE_IF_PRESENT ) -# undef USE_VIA_ACE_IF_PRESENT -# endif -#endif - -#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT ) -# define USE_VIA_ACE_IF_PRESENT -#endif - -/* define to reverse decryption key schedule */ -#if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS ) -# define AES_REV_DKS -#endif - -/* Intel AESNI uses a decryption key schedule in the encryption order */ -#if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS ) -# undef AES_REV_DKS -#endif - -/* Assembler support requires the use of platform byte order */ - -#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \ - && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER) -# undef ALGORITHM_BYTE_ORDER -# define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER -#endif - -/* In this implementation the columns of the state array are each held in - 32-bit words. The state array can be held in various ways: in an array - of words, in a number of individual word variables or in a number of - processor registers. The following define maps a variable name x and - a column number c to the way the state array variable is to be held. - The first define below maps the state into an array x[c] whereas the - second form maps the state into a number of individual variables x0, - x1, etc. Another form could map individual state colums to machine - register names. -*/ - -#if defined( ARRAYS ) -# define s(x,c) x[c] -#else -# define s(x,c) x##c -#endif - -/* This implementation provides subroutines for encryption, decryption - and for setting the three key lengths (separately) for encryption - and decryption. Since not all functions are needed, masks are set - up here to determine which will be implemented in C -*/ - -#if !defined( AES_ENCRYPT ) -# define EFUNCS_IN_C 0 -#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ - || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) -# define EFUNCS_IN_C ENC_KEYING_IN_C -#elif !defined( ASM_X86_V2 ) -# define EFUNCS_IN_C ( ENCRYPTION_IN_C | ENC_KEYING_IN_C ) -#else -# define EFUNCS_IN_C 0 -#endif - -#if !defined( AES_DECRYPT ) -# define DFUNCS_IN_C 0 -#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \ - || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) -# define DFUNCS_IN_C DEC_KEYING_IN_C -#elif !defined( ASM_X86_V2 ) -# define DFUNCS_IN_C ( DECRYPTION_IN_C | DEC_KEYING_IN_C ) -#else -# define DFUNCS_IN_C 0 -#endif - -#define FUNCS_IN_C ( EFUNCS_IN_C | DFUNCS_IN_C ) - -/* END OF CONFIGURATION OPTIONS */ - -#define RC_LENGTH (5 * (AES_BLOCK_SIZE / 4 - 2)) - -/* Disable or report errors on some combinations of options */ - -#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES -# undef LAST_ENC_ROUND -# define LAST_ENC_ROUND NO_TABLES -#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES -# undef LAST_ENC_ROUND -# define LAST_ENC_ROUND ONE_TABLE -#endif - -#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE -# undef ENC_UNROLL -# define ENC_UNROLL NONE -#endif - -#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES -# undef LAST_DEC_ROUND -# define LAST_DEC_ROUND NO_TABLES -#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES -# undef LAST_DEC_ROUND -# define LAST_DEC_ROUND ONE_TABLE -#endif - -#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE -# undef DEC_UNROLL -# define DEC_UNROLL NONE -#endif - -#if defined( bswap32 ) -# define aes_sw32 bswap32 -#elif defined( bswap_32 ) -# define aes_sw32 bswap_32 -#else -# define brot(x,n) (((uint32_t)(x) << n) | ((uint32_t)(x) >> (32 - n))) -# define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00)) -#endif - -/* upr(x,n): rotates bytes within words by n positions, moving bytes to - higher index positions with wrap around into low positions - ups(x,n): moves bytes by n positions to higher index positions in - words but without wrap around - bval(x,n): extracts a byte from a word - - WARNING: The definitions given here are intended only for use with - unsigned variables and with shift counts that are compile - time constants -*/ - -#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN ) -# define upr(x,n) (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n)))) -# define ups(x,n) ((uint32_t) (x) << (8 * (n))) -# define bval(x,n) to_byte((x) >> (8 * (n))) -# define bytes2word(b0, b1, b2, b3) \ - (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0)) -#endif - -#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN ) -# define upr(x,n) (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n)))) -# define ups(x,n) ((uint32_t) (x) >> (8 * (n))) -# define bval(x,n) to_byte((x) >> (24 - 8 * (n))) -# define bytes2word(b0, b1, b2, b3) \ - (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3)) -#endif - -#if defined( SAFE_IO ) -# define word_in(x,c) bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \ - ((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3]) -# define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \ - ((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); } -#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER ) -# define word_in(x,c) (*((uint32_t*)(x)+(c))) -# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v)) -#else -# define word_in(x,c) aes_sw32(*((uint32_t*)(x)+(c))) -# define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v)) -#endif - -/* the finite field modular polynomial and elements */ - -#define WPOLY 0x011b -#define BPOLY 0x1b - -/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */ - -#define gf_c1 0x80808080 -#define gf_c2 0x7f7f7f7f -#define gf_mulx(x) ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY)) - -/* The following defines provide alternative definitions of gf_mulx that might - give improved performance if a fast 32-bit multiply is not available. Note - that a temporary variable u needs to be defined where gf_mulx is used. - -#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6)) -#define gf_c4 (0x01010101 * BPOLY) -#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4) -*/ - -/* Work out which tables are needed for the different options */ - -#if defined( ASM_X86_V1C ) -# if defined( ENC_ROUND ) -# undef ENC_ROUND -# endif -# define ENC_ROUND FOUR_TABLES -# if defined( LAST_ENC_ROUND ) -# undef LAST_ENC_ROUND -# endif -# define LAST_ENC_ROUND FOUR_TABLES -# if defined( DEC_ROUND ) -# undef DEC_ROUND -# endif -# define DEC_ROUND FOUR_TABLES -# if defined( LAST_DEC_ROUND ) -# undef LAST_DEC_ROUND -# endif -# define LAST_DEC_ROUND FOUR_TABLES -# if defined( KEY_SCHED ) -# undef KEY_SCHED -# define KEY_SCHED FOUR_TABLES -# endif -#endif - -#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C ) -# if ENC_ROUND == ONE_TABLE -# define FT1_SET -# elif ENC_ROUND == FOUR_TABLES -# define FT4_SET -# else -# define SBX_SET -# endif -# if LAST_ENC_ROUND == ONE_TABLE -# define FL1_SET -# elif LAST_ENC_ROUND == FOUR_TABLES -# define FL4_SET -# elif !defined( SBX_SET ) -# define SBX_SET -# endif -#endif - -#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C ) -# if DEC_ROUND == ONE_TABLE -# define IT1_SET -# elif DEC_ROUND == FOUR_TABLES -# define IT4_SET -# else -# define ISB_SET -# endif -# if LAST_DEC_ROUND == ONE_TABLE -# define IL1_SET -# elif LAST_DEC_ROUND == FOUR_TABLES -# define IL4_SET -# elif !defined(ISB_SET) -# define ISB_SET -# endif -#endif - -#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) -# if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C)) -# if KEY_SCHED == ONE_TABLE -# if !defined( FL1_SET ) && !defined( FL4_SET ) -# define LS1_SET -# endif -# elif KEY_SCHED == FOUR_TABLES -# if !defined( FL4_SET ) -# define LS4_SET -# endif -# elif !defined( SBX_SET ) -# define SBX_SET -# endif -# endif -# if (FUNCS_IN_C & DEC_KEYING_IN_C) -# if KEY_SCHED == ONE_TABLE -# define IM1_SET -# elif KEY_SCHED == FOUR_TABLES -# define IM4_SET -# elif !defined( SBX_SET ) -# define SBX_SET -# endif -# endif -#endif - -/* generic definitions of Rijndael macros that use tables */ - -#define no_table(x,box,vf,rf,c) bytes2word( \ - box[bval(vf(x,0,c),rf(0,c))], \ - box[bval(vf(x,1,c),rf(1,c))], \ - box[bval(vf(x,2,c),rf(2,c))], \ - box[bval(vf(x,3,c),rf(3,c))]) - -#define one_table(x,op,tab,vf,rf,c) \ - ( tab[bval(vf(x,0,c),rf(0,c))] \ - ^ op(tab[bval(vf(x,1,c),rf(1,c))],1) \ - ^ op(tab[bval(vf(x,2,c),rf(2,c))],2) \ - ^ op(tab[bval(vf(x,3,c),rf(3,c))],3)) - -#define four_tables(x,tab,vf,rf,c) \ - ( tab[0][bval(vf(x,0,c),rf(0,c))] \ - ^ tab[1][bval(vf(x,1,c),rf(1,c))] \ - ^ tab[2][bval(vf(x,2,c),rf(2,c))] \ - ^ tab[3][bval(vf(x,3,c),rf(3,c))]) - -#define vf1(x,r,c) (x) -#define rf1(r,c) (r) -#define rf2(r,c) ((8+r-c)&3) - -/* perform forward and inverse column mix operation on four bytes in long word x in */ -/* parallel. NOTE: x must be a simple variable, NOT an expression in these macros. */ - -#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))) - -#if defined( FM4_SET ) /* not currently used */ -# define fwd_mcol(x) four_tables(x,t_use(f,m),vf1,rf1,0) -#elif defined( FM1_SET ) /* not currently used */ -# define fwd_mcol(x) one_table(x,upr,t_use(f,m),vf1,rf1,0) -#else -# define dec_fmvars uint32_t g2 -# define fwd_mcol(x) (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1)) -#endif - -#if defined( IM4_SET ) -# define inv_mcol(x) four_tables(x,t_use(i,m),vf1,rf1,0) -#elif defined( IM1_SET ) -# define inv_mcol(x) one_table(x,upr,t_use(i,m),vf1,rf1,0) -#else -# define dec_imvars uint32_t g2, g4, g9 -# define inv_mcol(x) (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \ - (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1)) -#endif - -#if defined( FL4_SET ) -# define ls_box(x,c) four_tables(x,t_use(f,l),vf1,rf2,c) -#elif defined( LS4_SET ) -# define ls_box(x,c) four_tables(x,t_use(l,s),vf1,rf2,c) -#elif defined( FL1_SET ) -# define ls_box(x,c) one_table(x,upr,t_use(f,l),vf1,rf2,c) -#elif defined( LS1_SET ) -# define ls_box(x,c) one_table(x,upr,t_use(l,s),vf1,rf2,c) -#else -# define ls_box(x,c) no_table(x,t_use(s,box),vf1,rf2,c) -#endif - -#endif - -#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET ) -# define ISB_SET -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/aestab.c b/game/client/third/minizip/lib/aes/aestab.c deleted file mode 100755 index 3d48edf3..00000000 --- a/game/client/third/minizip/lib/aes/aestab.c +++ /dev/null @@ -1,418 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 -*/ - -#define DO_TABLES - -#include "aes.h" -#include "aesopt.h" - -#if defined(STATIC_TABLES) - -#define sb_data(w) {\ - w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\ - w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\ - w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\ - w(0xad), w(0xd4), w(0xa2), w(0xaf), w(0x9c), w(0xa4), w(0x72), w(0xc0),\ - w(0xb7), w(0xfd), w(0x93), w(0x26), w(0x36), w(0x3f), w(0xf7), w(0xcc),\ - w(0x34), w(0xa5), w(0xe5), w(0xf1), w(0x71), w(0xd8), w(0x31), w(0x15),\ - w(0x04), w(0xc7), w(0x23), w(0xc3), w(0x18), w(0x96), w(0x05), w(0x9a),\ - w(0x07), w(0x12), w(0x80), w(0xe2), w(0xeb), w(0x27), w(0xb2), w(0x75),\ - w(0x09), w(0x83), w(0x2c), w(0x1a), w(0x1b), w(0x6e), w(0x5a), w(0xa0),\ - w(0x52), w(0x3b), w(0xd6), w(0xb3), w(0x29), w(0xe3), w(0x2f), w(0x84),\ - w(0x53), w(0xd1), w(0x00), w(0xed), w(0x20), w(0xfc), w(0xb1), w(0x5b),\ - w(0x6a), w(0xcb), w(0xbe), w(0x39), w(0x4a), w(0x4c), w(0x58), w(0xcf),\ - w(0xd0), w(0xef), w(0xaa), w(0xfb), w(0x43), w(0x4d), w(0x33), w(0x85),\ - w(0x45), w(0xf9), w(0x02), w(0x7f), w(0x50), w(0x3c), w(0x9f), w(0xa8),\ - w(0x51), w(0xa3), w(0x40), w(0x8f), w(0x92), w(0x9d), w(0x38), w(0xf5),\ - w(0xbc), w(0xb6), w(0xda), w(0x21), w(0x10), w(0xff), w(0xf3), w(0xd2),\ - w(0xcd), w(0x0c), w(0x13), w(0xec), w(0x5f), w(0x97), w(0x44), w(0x17),\ - w(0xc4), w(0xa7), w(0x7e), w(0x3d), w(0x64), w(0x5d), w(0x19), w(0x73),\ - w(0x60), w(0x81), w(0x4f), w(0xdc), w(0x22), w(0x2a), w(0x90), w(0x88),\ - w(0x46), w(0xee), w(0xb8), w(0x14), w(0xde), w(0x5e), w(0x0b), w(0xdb),\ - w(0xe0), w(0x32), w(0x3a), w(0x0a), w(0x49), w(0x06), w(0x24), w(0x5c),\ - w(0xc2), w(0xd3), w(0xac), w(0x62), w(0x91), w(0x95), w(0xe4), w(0x79),\ - w(0xe7), w(0xc8), w(0x37), w(0x6d), w(0x8d), w(0xd5), w(0x4e), w(0xa9),\ - w(0x6c), w(0x56), w(0xf4), w(0xea), w(0x65), w(0x7a), w(0xae), w(0x08),\ - w(0xba), w(0x78), w(0x25), w(0x2e), w(0x1c), w(0xa6), w(0xb4), w(0xc6),\ - w(0xe8), w(0xdd), w(0x74), w(0x1f), w(0x4b), w(0xbd), w(0x8b), w(0x8a),\ - w(0x70), w(0x3e), w(0xb5), w(0x66), w(0x48), w(0x03), w(0xf6), w(0x0e),\ - w(0x61), w(0x35), w(0x57), w(0xb9), w(0x86), w(0xc1), w(0x1d), w(0x9e),\ - w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\ - w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\ - w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\ - w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) } - -#define isb_data(w) {\ - w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\ - w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\ - w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\ - w(0x34), w(0x8e), w(0x43), w(0x44), w(0xc4), w(0xde), w(0xe9), w(0xcb),\ - w(0x54), w(0x7b), w(0x94), w(0x32), w(0xa6), w(0xc2), w(0x23), w(0x3d),\ - w(0xee), w(0x4c), w(0x95), w(0x0b), w(0x42), w(0xfa), w(0xc3), w(0x4e),\ - w(0x08), w(0x2e), w(0xa1), w(0x66), w(0x28), w(0xd9), w(0x24), w(0xb2),\ - w(0x76), w(0x5b), w(0xa2), w(0x49), w(0x6d), w(0x8b), w(0xd1), w(0x25),\ - w(0x72), w(0xf8), w(0xf6), w(0x64), w(0x86), w(0x68), w(0x98), w(0x16),\ - w(0xd4), w(0xa4), w(0x5c), w(0xcc), w(0x5d), w(0x65), w(0xb6), w(0x92),\ - w(0x6c), w(0x70), w(0x48), w(0x50), w(0xfd), w(0xed), w(0xb9), w(0xda),\ - w(0x5e), w(0x15), w(0x46), w(0x57), w(0xa7), w(0x8d), w(0x9d), w(0x84),\ - w(0x90), w(0xd8), w(0xab), w(0x00), w(0x8c), w(0xbc), w(0xd3), w(0x0a),\ - w(0xf7), w(0xe4), w(0x58), w(0x05), w(0xb8), w(0xb3), w(0x45), w(0x06),\ - w(0xd0), w(0x2c), w(0x1e), w(0x8f), w(0xca), w(0x3f), w(0x0f), w(0x02),\ - w(0xc1), w(0xaf), w(0xbd), w(0x03), w(0x01), w(0x13), w(0x8a), w(0x6b),\ - w(0x3a), w(0x91), w(0x11), w(0x41), w(0x4f), w(0x67), w(0xdc), w(0xea),\ - w(0x97), w(0xf2), w(0xcf), w(0xce), w(0xf0), w(0xb4), w(0xe6), w(0x73),\ - w(0x96), w(0xac), w(0x74), w(0x22), w(0xe7), w(0xad), w(0x35), w(0x85),\ - w(0xe2), w(0xf9), w(0x37), w(0xe8), w(0x1c), w(0x75), w(0xdf), w(0x6e),\ - w(0x47), w(0xf1), w(0x1a), w(0x71), w(0x1d), w(0x29), w(0xc5), w(0x89),\ - w(0x6f), w(0xb7), w(0x62), w(0x0e), w(0xaa), w(0x18), w(0xbe), w(0x1b),\ - w(0xfc), w(0x56), w(0x3e), w(0x4b), w(0xc6), w(0xd2), w(0x79), w(0x20),\ - w(0x9a), w(0xdb), w(0xc0), w(0xfe), w(0x78), w(0xcd), w(0x5a), w(0xf4),\ - w(0x1f), w(0xdd), w(0xa8), w(0x33), w(0x88), w(0x07), w(0xc7), w(0x31),\ - w(0xb1), w(0x12), w(0x10), w(0x59), w(0x27), w(0x80), w(0xec), w(0x5f),\ - w(0x60), w(0x51), w(0x7f), w(0xa9), w(0x19), w(0xb5), w(0x4a), w(0x0d),\ - w(0x2d), w(0xe5), w(0x7a), w(0x9f), w(0x93), w(0xc9), w(0x9c), w(0xef),\ - w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\ - w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\ - w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\ - w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) } - -#define mm_data(w) {\ - w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\ - w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\ - w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\ - w(0x18), w(0x19), w(0x1a), w(0x1b), w(0x1c), w(0x1d), w(0x1e), w(0x1f),\ - w(0x20), w(0x21), w(0x22), w(0x23), w(0x24), w(0x25), w(0x26), w(0x27),\ - w(0x28), w(0x29), w(0x2a), w(0x2b), w(0x2c), w(0x2d), w(0x2e), w(0x2f),\ - w(0x30), w(0x31), w(0x32), w(0x33), w(0x34), w(0x35), w(0x36), w(0x37),\ - w(0x38), w(0x39), w(0x3a), w(0x3b), w(0x3c), w(0x3d), w(0x3e), w(0x3f),\ - w(0x40), w(0x41), w(0x42), w(0x43), w(0x44), w(0x45), w(0x46), w(0x47),\ - w(0x48), w(0x49), w(0x4a), w(0x4b), w(0x4c), w(0x4d), w(0x4e), w(0x4f),\ - w(0x50), w(0x51), w(0x52), w(0x53), w(0x54), w(0x55), w(0x56), w(0x57),\ - w(0x58), w(0x59), w(0x5a), w(0x5b), w(0x5c), w(0x5d), w(0x5e), w(0x5f),\ - w(0x60), w(0x61), w(0x62), w(0x63), w(0x64), w(0x65), w(0x66), w(0x67),\ - w(0x68), w(0x69), w(0x6a), w(0x6b), w(0x6c), w(0x6d), w(0x6e), w(0x6f),\ - w(0x70), w(0x71), w(0x72), w(0x73), w(0x74), w(0x75), w(0x76), w(0x77),\ - w(0x78), w(0x79), w(0x7a), w(0x7b), w(0x7c), w(0x7d), w(0x7e), w(0x7f),\ - w(0x80), w(0x81), w(0x82), w(0x83), w(0x84), w(0x85), w(0x86), w(0x87),\ - w(0x88), w(0x89), w(0x8a), w(0x8b), w(0x8c), w(0x8d), w(0x8e), w(0x8f),\ - w(0x90), w(0x91), w(0x92), w(0x93), w(0x94), w(0x95), w(0x96), w(0x97),\ - w(0x98), w(0x99), w(0x9a), w(0x9b), w(0x9c), w(0x9d), w(0x9e), w(0x9f),\ - w(0xa0), w(0xa1), w(0xa2), w(0xa3), w(0xa4), w(0xa5), w(0xa6), w(0xa7),\ - w(0xa8), w(0xa9), w(0xaa), w(0xab), w(0xac), w(0xad), w(0xae), w(0xaf),\ - w(0xb0), w(0xb1), w(0xb2), w(0xb3), w(0xb4), w(0xb5), w(0xb6), w(0xb7),\ - w(0xb8), w(0xb9), w(0xba), w(0xbb), w(0xbc), w(0xbd), w(0xbe), w(0xbf),\ - w(0xc0), w(0xc1), w(0xc2), w(0xc3), w(0xc4), w(0xc5), w(0xc6), w(0xc7),\ - w(0xc8), w(0xc9), w(0xca), w(0xcb), w(0xcc), w(0xcd), w(0xce), w(0xcf),\ - w(0xd0), w(0xd1), w(0xd2), w(0xd3), w(0xd4), w(0xd5), w(0xd6), w(0xd7),\ - w(0xd8), w(0xd9), w(0xda), w(0xdb), w(0xdc), w(0xdd), w(0xde), w(0xdf),\ - w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\ - w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\ - w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\ - w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) } - -#define rc_data(w) {\ - w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\ - w(0x1b), w(0x36) } - -#define h0(x) (x) - -#define w0(p) bytes2word(p, 0, 0, 0) -#define w1(p) bytes2word(0, p, 0, 0) -#define w2(p) bytes2word(0, 0, p, 0) -#define w3(p) bytes2word(0, 0, 0, p) - -#define u0(p) bytes2word(f2(p), p, p, f3(p)) -#define u1(p) bytes2word(f3(p), f2(p), p, p) -#define u2(p) bytes2word(p, f3(p), f2(p), p) -#define u3(p) bytes2word(p, p, f3(p), f2(p)) - -#define v0(p) bytes2word(fe(p), f9(p), fd(p), fb(p)) -#define v1(p) bytes2word(fb(p), fe(p), f9(p), fd(p)) -#define v2(p) bytes2word(fd(p), fb(p), fe(p), f9(p)) -#define v3(p) bytes2word(f9(p), fd(p), fb(p), fe(p)) - -#endif - -#if defined(STATIC_TABLES) || !defined(FF_TABLES) - -#define f2(x) ((x<<1) ^ (((x>>7) & 1) * WPOLY)) -#define f4(x) ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY)) -#define f8(x) ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \ - ^ (((x>>5) & 4) * WPOLY)) -#define f3(x) (f2(x) ^ x) -#define f9(x) (f8(x) ^ x) -#define fb(x) (f8(x) ^ f2(x) ^ x) -#define fd(x) (f8(x) ^ f4(x) ^ x) -#define fe(x) (f8(x) ^ f4(x) ^ f2(x)) - -#else - -#define f2(x) ((x) ? pow[log[x] + 0x19] : 0) -#define f3(x) ((x) ? pow[log[x] + 0x01] : 0) -#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0) -#define fb(x) ((x) ? pow[log[x] + 0x68] : 0) -#define fd(x) ((x) ? pow[log[x] + 0xee] : 0) -#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0) - -#endif - -#include "aestab.h" - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#if defined(STATIC_TABLES) - -/* implemented in case of wrong call for fixed tables */ - -AES_RETURN aes_init(void) -{ - return EXIT_SUCCESS; -} - -#else /* Generate the tables for the dynamic table option */ - -#if defined(FF_TABLES) - -#define gf_inv(x) ((x) ? pow[ 255 - log[x]] : 0) - -#else - -/* It will generally be sensible to use tables to compute finite - field multiplies and inverses but where memory is scarse this - code might sometimes be better. But it only has effect during - initialisation so its pretty unimportant in overall terms. -*/ - -/* return 2 ^ (n - 1) where n is the bit number of the highest bit - set in x with x in the range 1 < x < 0x00000200. This form is - used so that locals within fi can be bytes rather than words -*/ - -static uint8_t hibit(const uint32_t x) -{ uint8_t r = (uint8_t)((x >> 1) | (x >> 2)); - - r |= (r >> 2); - r |= (r >> 4); - return (r + 1) >> 1; -} - -/* return the inverse of the finite field element x */ - -static uint8_t gf_inv(const uint8_t x) -{ uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0; - - if(x < 2) - return x; - - for( ; ; ) - { - if(n1) - while(n2 >= n1) /* divide polynomial p2 by p1 */ - { - n2 /= n1; /* shift smaller polynomial left */ - p2 ^= (p1 * n2) & 0xff; /* and remove from larger one */ - v2 ^= v1 * n2; /* shift accumulated value and */ - n2 = hibit(p2); /* add into result */ - } - else - return v1; - - if(n2) /* repeat with values swapped */ - while(n1 >= n2) - { - n1 /= n2; - p1 ^= p2 * n1; - v1 ^= v2 * n1; - n1 = hibit(p1); - } - else - return v2; - } -} - -#endif - -/* The forward and inverse affine transformations used in the S-box */ -uint8_t fwd_affine(const uint8_t x) -{ uint32_t w = x; - w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4); - return 0x63 ^ ((w ^ (w >> 8)) & 0xff); -} - -uint8_t inv_affine(const uint8_t x) -{ uint32_t w = x; - w = (w << 1) ^ (w << 3) ^ (w << 6); - return 0x05 ^ ((w ^ (w >> 8)) & 0xff); -} - -static int init = 0; - -AES_RETURN aes_init(void) -{ uint32_t i, w; - -#if defined(FF_TABLES) - - uint8_t pow[512], log[256]; - - if(init) - return EXIT_SUCCESS; - /* log and power tables for GF(2^8) finite field with - WPOLY as modular polynomial - the simplest primitive - root is 0x03, used here to generate the tables - */ - - i = 0; w = 1; - do - { - pow[i] = (uint8_t)w; - pow[i + 255] = (uint8_t)w; - log[w] = (uint8_t)i++; - w ^= (w << 1) ^ (w & 0x80 ? WPOLY : 0); - } - while (w != 1); - -#else - if(init) - return EXIT_SUCCESS; -#endif - - for(i = 0, w = 1; i < RC_LENGTH; ++i) - { - t_set(r,c)[i] = bytes2word(w, 0, 0, 0); - w = f2(w); - } - - for(i = 0; i < 256; ++i) - { uint8_t b; - - b = fwd_affine(gf_inv((uint8_t)i)); - w = bytes2word(f2(b), b, b, f3(b)); - -#if defined( SBX_SET ) - t_set(s,box)[i] = b; -#endif - -#if defined( FT1_SET ) /* tables for a normal encryption round */ - t_set(f,n)[i] = w; -#endif -#if defined( FT4_SET ) - t_set(f,n)[0][i] = w; - t_set(f,n)[1][i] = upr(w,1); - t_set(f,n)[2][i] = upr(w,2); - t_set(f,n)[3][i] = upr(w,3); -#endif - w = bytes2word(b, 0, 0, 0); - -#if defined( FL1_SET ) /* tables for last encryption round (may also */ - t_set(f,l)[i] = w; /* be used in the key schedule) */ -#endif -#if defined( FL4_SET ) - t_set(f,l)[0][i] = w; - t_set(f,l)[1][i] = upr(w,1); - t_set(f,l)[2][i] = upr(w,2); - t_set(f,l)[3][i] = upr(w,3); -#endif - -#if defined( LS1_SET ) /* table for key schedule if t_set(f,l) above is*/ - t_set(l,s)[i] = w; /* not of the required form */ -#endif -#if defined( LS4_SET ) - t_set(l,s)[0][i] = w; - t_set(l,s)[1][i] = upr(w,1); - t_set(l,s)[2][i] = upr(w,2); - t_set(l,s)[3][i] = upr(w,3); -#endif - - b = gf_inv(inv_affine((uint8_t)i)); - w = bytes2word(fe(b), f9(b), fd(b), fb(b)); - -#if defined( IM1_SET ) /* tables for the inverse mix column operation */ - t_set(i,m)[b] = w; -#endif -#if defined( IM4_SET ) - t_set(i,m)[0][b] = w; - t_set(i,m)[1][b] = upr(w,1); - t_set(i,m)[2][b] = upr(w,2); - t_set(i,m)[3][b] = upr(w,3); -#endif - -#if defined( ISB_SET ) - t_set(i,box)[i] = b; -#endif -#if defined( IT1_SET ) /* tables for a normal decryption round */ - t_set(i,n)[i] = w; -#endif -#if defined( IT4_SET ) - t_set(i,n)[0][i] = w; - t_set(i,n)[1][i] = upr(w,1); - t_set(i,n)[2][i] = upr(w,2); - t_set(i,n)[3][i] = upr(w,3); -#endif - w = bytes2word(b, 0, 0, 0); -#if defined( IL1_SET ) /* tables for last decryption round */ - t_set(i,l)[i] = w; -#endif -#if defined( IL4_SET ) - t_set(i,l)[0][i] = w; - t_set(i,l)[1][i] = upr(w,1); - t_set(i,l)[2][i] = upr(w,2); - t_set(i,l)[3][i] = upr(w,3); -#endif - } - init = 1; - return EXIT_SUCCESS; -} - -/* - Automatic code initialisation (suggested by by Henrik S. Gaßmann) - based on code provided by Joe Lowe and placed in the public domain at: - http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc -*/ - -#ifdef _MSC_VER - -#pragma section(".CRT$XCU", read) - -__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init; - -#elif defined(__GNUC__) - -static void aes_startup(void) __attribute__((constructor)); - -static void aes_startup(void) -{ - aes_init(); -} - -#else - -#pragma message( "dynamic tables must be initialised manually on your system" ) - -#endif - -#endif - -#if defined(__cplusplus) -} -#endif - diff --git a/game/client/third/minizip/lib/aes/aestab.h b/game/client/third/minizip/lib/aes/aestab.h deleted file mode 100755 index 8fe32d18..00000000 --- a/game/client/third/minizip/lib/aes/aestab.h +++ /dev/null @@ -1,173 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - - This file contains the code for declaring the tables needed to implement - AES. The file aesopt.h is assumed to be included before this header file. - If there are no global variables, the definitions here can be used to put - the AES tables in a structure so that a pointer can then be added to the - AES context to pass them to the AES routines that need them. If this - facility is used, the calling program has to ensure that this pointer is - managed appropriately. In particular, the value of the t_dec(in,it) item - in the table structure must be set to zero in order to ensure that the - tables are initialised. In practice the three code sequences in aeskey.c - that control the calls to aes_init() and the aes_init() routine itself will - have to be changed for a specific implementation. If global variables are - available it will generally be preferable to use them with the precomputed - STATIC_TABLES option that uses static global tables. - - The following defines can be used to control the way the tables - are defined, initialised and used in embedded environments that - require special features for these purposes - - the 't_dec' construction is used to declare fixed table arrays - the 't_set' construction is used to set fixed table values - the 't_use' construction is used to access fixed table values - - 256 byte tables: - - t_xxx(s,box) => forward S box - t_xxx(i,box) => inverse S box - - 256 32-bit word OR 4 x 256 32-bit word tables: - - t_xxx(f,n) => forward normal round - t_xxx(f,l) => forward last round - t_xxx(i,n) => inverse normal round - t_xxx(i,l) => inverse last round - t_xxx(l,s) => key schedule table - t_xxx(i,m) => key schedule table - - Other variables and tables: - - t_xxx(r,c) => the rcon table -*/ - -#if !defined( _AESTAB_H ) -#define _AESTAB_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#define t_dec(m,n) t_##m##n -#define t_set(m,n) t_##m##n -#define t_use(m,n) t_##m##n - -#if defined(STATIC_TABLES) -# if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ )) -/* make tables far data to avoid using too much DGROUP space (PG) */ -# define CONST const far -# else -# define CONST const -# endif -#else -# define CONST -#endif - -#if defined(DO_TABLES) -# define EXTERN -#else -# define EXTERN extern -#endif - -#if defined(_MSC_VER) && defined(TABLE_ALIGN) -#define ALIGN __declspec(align(TABLE_ALIGN)) -#else -#define ALIGN -#endif - -#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 ) -# define XP_DIR __cdecl -#else -# define XP_DIR -#endif - -#if defined(DO_TABLES) && defined(STATIC_TABLES) -#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] = b(e) -#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) } -EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0); -#else -#define d_1(t,n,b,e) EXTERN ALIGN CONST XP_DIR t n[256] -#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] -EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH]; -#endif - -#if defined( SBX_SET ) - d_1(uint8_t, t_dec(s,box), sb_data, h0); -#endif -#if defined( ISB_SET ) - d_1(uint8_t, t_dec(i,box), isb_data, h0); -#endif - -#if defined( FT1_SET ) - d_1(uint32_t, t_dec(f,n), sb_data, u0); -#endif -#if defined( FT4_SET ) - d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3); -#endif - -#if defined( FL1_SET ) - d_1(uint32_t, t_dec(f,l), sb_data, w0); -#endif -#if defined( FL4_SET ) - d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3); -#endif - -#if defined( IT1_SET ) - d_1(uint32_t, t_dec(i,n), isb_data, v0); -#endif -#if defined( IT4_SET ) - d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3); -#endif - -#if defined( IL1_SET ) - d_1(uint32_t, t_dec(i,l), isb_data, w0); -#endif -#if defined( IL4_SET ) - d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3); -#endif - -#if defined( LS1_SET ) -#if defined( FL1_SET ) -#undef LS1_SET -#else - d_1(uint32_t, t_dec(l,s), sb_data, w0); -#endif -#endif - -#if defined( LS4_SET ) -#if defined( FL4_SET ) -#undef LS4_SET -#else - d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3); -#endif -#endif - -#if defined( IM1_SET ) - d_1(uint32_t, t_dec(i,m), mm_data, v0); -#endif -#if defined( IM4_SET ) - d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3); -#endif - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/brg_endian.h b/game/client/third/minizip/lib/aes/brg_endian.h deleted file mode 100755 index 9ef4af58..00000000 --- a/game/client/third/minizip/lib/aes/brg_endian.h +++ /dev/null @@ -1,127 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 -*/ - -#ifndef _BRG_ENDIAN_H -#define _BRG_ENDIAN_H - -#define IS_BIG_ENDIAN 4321 /* byte 0 is most significant (mc68k) */ -#define IS_LITTLE_ENDIAN 1234 /* byte 0 is least significant (i386) */ - -/* Include files where endian defines and byteswap functions may reside */ -#if defined( __sun ) -# include -#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ ) -# include -#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \ - defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ ) || \ - defined(__pnacl__) -# include -#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ ) -# if !defined( __MINGW32__ ) && !defined( _AIX ) -# include -# if !defined( __BEOS__ ) -# include -# endif -# endif -#endif - -/* Now attempt to set the define for platform byte order using any */ -/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, which */ -/* seem to encompass most endian symbol definitions */ - -#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN ) -# if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN ) -# if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( _BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( _LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN ) -# if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( __BIG_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( __LITTLE_ENDIAN ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ ) -# if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__ -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -# elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -# endif -#elif defined( __BIG_ENDIAN__ ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#elif defined( __LITTLE_ENDIAN__ ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#endif - -/* if the platform byte order could not be determined, then try to */ -/* set this define using common machine defines */ -#if !defined(PLATFORM_BYTE_ORDER) - -#if defined( __alpha__ ) || defined( __alpha ) || defined( i386 ) || \ - defined( __i386__ ) || defined( _M_I86 ) || defined( _M_IX86 ) || \ - defined( __OS2__ ) || defined( sun386 ) || defined( __TURBOC__ ) || \ - defined( vax ) || defined( vms ) || defined( VMS ) || \ - defined( __VMS ) || defined( _M_X64 ) -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN - -#elif defined( AMIGA ) || defined( applec ) || defined( __AS400__ ) || \ - defined( _CRAY ) || defined( __hppa ) || defined( __hp9000 ) || \ - defined( ibm370 ) || defined( mc68000 ) || defined( m68k ) || \ - defined( __MRC__ ) || defined( __MVS__ ) || defined( __MWERKS__ ) || \ - defined( sparc ) || defined( __sparc) || defined( SYMANTEC_C ) || \ - defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM ) || \ - defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX ) -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN - -#elif 0 /* **** EDIT HERE IF NECESSARY **** */ -# define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN -#elif 0 /* **** EDIT HERE IF NECESSARY **** */ -# define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN -#else -# error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order -#endif - -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/brg_types.h b/game/client/third/minizip/lib/aes/brg_types.h deleted file mode 100755 index 307319bf..00000000 --- a/game/client/third/minizip/lib/aes/brg_types.h +++ /dev/null @@ -1,191 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - - The unsigned integer types defined here are of the form uint_t where - is the length of the type; for example, the unsigned 32-bit type is - 'uint32_t'. These are NOT the same as the 'C99 integer types' that are - defined in the inttypes.h and stdint.h headers since attempts to use these - types have shown that support for them is still highly variable. However, - since the latter are of the form uint_t, a regular expression search - and replace (in VC++ search on 'uint_{:z}t' and replace with 'uint\1_t') - can be used to convert the types used here to the C99 standard types. -*/ - -#ifndef _BRG_TYPES_H -#define _BRG_TYPES_H - -#if defined(__cplusplus) -extern "C" { -#endif - -#include -#include - -#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 ) -# include -# define ptrint_t intptr_t -#elif defined( __ECOS__ ) -# define intptr_t unsigned int -# define ptrint_t intptr_t -#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) -# define ptrint_t intptr_t -#else -# define ptrint_t int -#endif - -#ifndef BRG_UI32 -# define BRG_UI32 -# if UINT_MAX == 4294967295u -# define li_32(h) 0x##h##u -# elif ULONG_MAX == 4294967295u -# define li_32(h) 0x##h##ul -# elif defined( _CRAY ) -# error This code needs 32-bit data types, which Cray machines do not provide -# else -# error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h -# endif -#endif - -#ifndef BRG_UI64 -# if defined( __BORLANDC__ ) && !defined( __MSDOS__ ) -# define BRG_UI64 -# define li_64(h) 0x##h##ui64 -# elif defined( _MSC_VER ) && ( _MSC_VER < 1300 ) /* 1300 == VC++ 7.0 */ -# define BRG_UI64 -# define li_64(h) 0x##h##ui64 -# elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful -# define BRG_UI64 -# define li_64(h) 0x##h##ull -# elif defined( __MVS__ ) -# define BRG_UI64 -# define li_64(h) 0x##h##ull -# elif defined( UINT_MAX ) && UINT_MAX > 4294967295u -# if UINT_MAX == 18446744073709551615u -# define BRG_UI64 -# define li_64(h) 0x##h##u -# endif -# elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u -# if ULONG_MAX == 18446744073709551615ul -# define BRG_UI64 -# define li_64(h) 0x##h##ul -# endif -# elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u -# if ULLONG_MAX == 18446744073709551615ull -# define BRG_UI64 -# define li_64(h) 0x##h##ull -# endif -# elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u -# if ULONG_LONG_MAX == 18446744073709551615ull -# define BRG_UI64 -# define li_64(h) 0x##h##ull -# endif -# endif -#endif - -#if !defined( BRG_UI64 ) -# if defined( NEED_UINT_64T ) -# error Please define uint64_t as an unsigned 64 bit type in brg_types.h -# endif -#endif - -#ifndef RETURN_VALUES -# define RETURN_VALUES -# if defined( DLL_EXPORT ) -# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) -# define VOID_RETURN __declspec( dllexport ) void __stdcall -# define INT_RETURN __declspec( dllexport ) int __stdcall -# elif defined( __GNUC__ ) -# define VOID_RETURN __declspec( __dllexport__ ) void -# define INT_RETURN __declspec( __dllexport__ ) int -# else -# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers -# endif -# elif defined( DLL_IMPORT ) -# if defined( _MSC_VER ) || defined ( __INTEL_COMPILER ) -# define VOID_RETURN __declspec( dllimport ) void __stdcall -# define INT_RETURN __declspec( dllimport ) int __stdcall -# elif defined( __GNUC__ ) -# define VOID_RETURN __declspec( __dllimport__ ) void -# define INT_RETURN __declspec( __dllimport__ ) int -# else -# error Use of the DLL is only available on the Microsoft, Intel and GCC compilers -# endif -# elif defined( __WATCOMC__ ) -# define VOID_RETURN void __cdecl -# define INT_RETURN int __cdecl -# else -# define VOID_RETURN void -# define INT_RETURN int -# endif -#endif - -/* These defines are used to detect and set the memory alignment of pointers. - Note that offsets are in bytes. - - ALIGN_OFFSET(x,n) return the positive or zero offset of - the memory addressed by the pointer 'x' - from an address that is aligned on an - 'n' byte boundary ('n' is a power of 2) - - ALIGN_FLOOR(x,n) return a pointer that points to memory - that is aligned on an 'n' byte boundary - and is not higher than the memory address - pointed to by 'x' ('n' is a power of 2) - - ALIGN_CEIL(x,n) return a pointer that points to memory - that is aligned on an 'n' byte boundary - and is not lower than the memory address - pointed to by 'x' ('n' is a power of 2) -*/ - -#define ALIGN_OFFSET(x,n) (((ptrint_t)(x)) & ((n) - 1)) -#define ALIGN_FLOOR(x,n) ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1))) -#define ALIGN_CEIL(x,n) ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1))) - -/* These defines are used to declare buffers in a way that allows - faster operations on longer variables to be used. In all these - defines 'size' must be a power of 2 and >= 8. NOTE that the - buffer size is in bytes but the type length is in bits - - UNIT_TYPEDEF(x,size) declares a variable 'x' of length - 'size' bits - - BUFR_TYPEDEF(x,size,bsize) declares a buffer 'x' of length 'bsize' - bytes defined as an array of variables - each of 'size' bits (bsize must be a - multiple of size / 8) - - UNIT_CAST(x,size) casts a variable to a type of - length 'size' bits - - UPTR_CAST(x,size) casts a pointer to a pointer to a - varaiable of length 'size' bits -*/ - -#define UI_TYPE(size) uint##size##_t -#define UNIT_TYPEDEF(x,size) typedef UI_TYPE(size) x -#define BUFR_TYPEDEF(x,size,bsize) typedef UI_TYPE(size) x[bsize / (size >> 3)] -#define UNIT_CAST(x,size) ((UI_TYPE(size) )(x)) -#define UPTR_CAST(x,size) ((UI_TYPE(size)*)(x)) - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/hmac.c b/game/client/third/minizip/lib/aes/hmac.c deleted file mode 100755 index face1fbf..00000000 --- a/game/client/third/minizip/lib/aes/hmac.c +++ /dev/null @@ -1,209 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - -This is an implementation of HMAC, the FIPS standard keyed hash function -*/ - -#include "hmac.h" - -#if defined(__cplusplus) -extern "C" -{ -#endif - -/* initialise the HMAC context to zero */ -int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1]) -{ - memset(cx, 0, sizeof(hmac_ctx)); - switch(hash) - { -#ifdef SHA_1 - case HMAC_SHA1: - cx->f_begin = (hf_begin *)sha1_begin; - cx->f_hash = (hf_hash *)sha1_hash; - cx->f_end = (hf_end *)sha1_end; - cx->input_len = SHA1_BLOCK_SIZE; - cx->output_len = SHA1_DIGEST_SIZE; - break; -#endif -#ifdef SHA_224 - case HMAC_SHA224: - cx->f_begin = (hf_begin *)sha224_begin; - cx->f_hash = (hf_hash *)sha224_hash; - cx->f_end = (hf_end *)sha224_end; - cx->input_len = SHA224_BLOCK_SIZE; - cx->output_len = SHA224_DIGEST_SIZE; - break; -#endif -#ifdef SHA_256 - case HMAC_SHA256: - cx->f_begin = (hf_begin *)sha256_begin; - cx->f_hash = (hf_hash *)sha256_hash; - cx->f_end = (hf_end *)sha256_end; - cx->input_len = SHA256_BLOCK_SIZE; - cx->output_len = SHA256_DIGEST_SIZE; - break; -#endif -#ifdef SHA_384 - case HMAC_SHA384: - cx->f_begin = (hf_begin *)sha384_begin; - cx->f_hash = (hf_hash *)sha384_hash; - cx->f_end = (hf_end *)sha384_end; - cx->input_len = SHA384_BLOCK_SIZE; - cx->output_len = SHA384_DIGEST_SIZE; - break; -#endif -#ifdef SHA_512 - case HMAC_SHA512: - cx->f_begin = (hf_begin *)sha512_begin; - cx->f_hash = (hf_hash *)sha512_hash; - cx->f_end = (hf_end *)sha512_end; - cx->input_len = SHA512_BLOCK_SIZE; - cx->output_len = SHA512_DIGEST_SIZE; - break; - case HMAC_SHA512_256: - cx->f_begin = (hf_begin *)sha512_256_begin; - cx->f_hash = (hf_hash *)sha512_256_hash; - cx->f_end = (hf_end *)sha512_256_end; - cx->input_len = SHA512_256_BLOCK_SIZE; - cx->output_len = SHA512_256_DIGEST_SIZE; - break; - case HMAC_SHA512_224: - cx->f_begin = (hf_begin *)sha512_224_begin; - cx->f_hash = (hf_hash *)sha512_224_hash; - cx->f_end = (hf_end *)sha512_224_end; - cx->input_len = SHA512_224_BLOCK_SIZE; - cx->output_len = SHA512_224_DIGEST_SIZE; - break; - case HMAC_SHA512_192: - cx->f_begin = (hf_begin *)sha512_192_begin; - cx->f_hash = (hf_hash *)sha512_192_hash; - cx->f_end = (hf_end *)sha512_192_end; - cx->input_len = SHA512_192_BLOCK_SIZE; - cx->output_len = SHA512_192_DIGEST_SIZE; - break; - case HMAC_SHA512_128: - cx->f_begin = (hf_begin *)sha512_128_begin; - cx->f_hash = (hf_hash *)sha512_128_hash; - cx->f_end = (hf_begin *)sha512_128_end; - cx->input_len = SHA512_128_BLOCK_SIZE; - cx->output_len = SHA512_128_DIGEST_SIZE; - break; -#endif - } - return (int)cx->output_len; -} - -/* input the HMAC key (can be called multiple times) */ -int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]) -{ - if(cx->klen == HMAC_IN_DATA) /* error if further key input */ - return EXIT_FAILURE; /* is attempted in data mode */ - - if(cx->klen + key_len > cx->input_len) /* if the key has to be hashed */ - { - if(cx->klen <= cx->input_len) /* if the hash has not yet been */ - { /* started, initialise it and */ - cx->f_begin(cx->sha_ctx); /* hash stored key characters */ - cx->f_hash(cx->key, cx->klen, cx->sha_ctx); - } - - cx->f_hash(key, key_len, cx->sha_ctx); /* hash long key data into hash */ - } - else /* otherwise store key data */ - memcpy(cx->key + cx->klen, key, key_len); - - cx->klen += key_len; /* update the key length count */ - return EXIT_SUCCESS; -} - -/* input the HMAC data (can be called multiple times) - */ -/* note that this call terminates the key input phase */ -void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]) -{ unsigned int i; - - if(cx->klen != HMAC_IN_DATA) /* if not yet in data phase */ - { - if(cx->klen > cx->input_len) /* if key is being hashed */ - { /* complete the hash and */ - cx->f_end(cx->key, cx->sha_ctx); /* store the result as the */ - cx->klen = cx->output_len; /* key and set new length */ - } - - /* pad the key if necessary */ - memset(cx->key + cx->klen, 0, cx->input_len - cx->klen); - - /* xor ipad into key value */ - for(i = 0; i < (cx->input_len >> 2); ++i) - ((uint32_t*)cx->key)[i] ^= 0x36363636; - - /* and start hash operation */ - cx->f_begin(cx->sha_ctx); - cx->f_hash(cx->key, cx->input_len, cx->sha_ctx); - - /* mark as now in data mode */ - cx->klen = HMAC_IN_DATA; - } - - /* hash the data (if any) */ - if(data_len) - cx->f_hash(data, data_len, cx->sha_ctx); -} - -/* compute and output the MAC value */ -void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]) -{ unsigned char dig[HMAC_MAX_OUTPUT_SIZE]; - unsigned int i; - - /* if no data has been entered perform a null data phase */ - if(cx->klen != HMAC_IN_DATA) - hmac_sha_data((const unsigned char*)0, 0, cx); - - cx->f_end(dig, cx->sha_ctx); /* complete the inner hash */ - - /* set outer key value using opad and removing ipad */ - for(i = 0; i < (cx->input_len >> 2); ++i) - ((uint32_t*)cx->key)[i] ^= 0x36363636 ^ 0x5c5c5c5c; - - /* perform the outer hash operation */ - cx->f_begin(cx->sha_ctx); - cx->f_hash(cx->key, cx->input_len, cx->sha_ctx); - cx->f_hash(dig, cx->output_len, cx->sha_ctx); - cx->f_end(dig, cx->sha_ctx); - - /* output the hash value */ - for(i = 0; i < mac_len; ++i) - mac[i] = dig[i]; -} - -/* 'do it all in one go' subroutine */ -void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len, - const unsigned char data[], unsigned long data_len, - unsigned char mac[], unsigned long mac_len) -{ hmac_ctx cx[1]; - - hmac_sha_begin(hash, cx); - hmac_sha_key(key, key_len, cx); - hmac_sha_data(data, data_len, cx); - hmac_sha_end(mac, mac_len, cx); -} - -#if defined(__cplusplus) -} -#endif diff --git a/game/client/third/minizip/lib/aes/hmac.h b/game/client/third/minizip/lib/aes/hmac.h deleted file mode 100755 index 46956c45..00000000 --- a/game/client/third/minizip/lib/aes/hmac.h +++ /dev/null @@ -1,119 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - -This is an implementation of HMAC, the FIPS standard keyed hash function -*/ - -#ifndef _HMAC2_H -#define _HMAC2_H - -#include -#include - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#include "sha1.h" - -#if defined(SHA_224) || defined(SHA_256) || defined(SHA_384) || defined(SHA_512) -#define HMAC_MAX_OUTPUT_SIZE SHA2_MAX_DIGEST_SIZE -#define HMAC_MAX_BLOCK_SIZE SHA2_MAX_BLOCK_SIZE -#else -#define HMAC_MAX_OUTPUT_SIZE SHA1_DIGEST_SIZE -#define HMAC_MAX_BLOCK_SIZE SHA1_BLOCK_SIZE -#endif - -#define HMAC_IN_DATA 0xffffffff - -enum hmac_hash -{ -#ifdef SHA_1 - HMAC_SHA1, -#endif -#ifdef SHA_224 - HMAC_SHA224, -#endif -#ifdef SHA_256 - HMAC_SHA256, -#endif -#ifdef SHA_384 - HMAC_SHA384, -#endif -#ifdef SHA_512 - HMAC_SHA512, - HMAC_SHA512_256, - HMAC_SHA512_224, - HMAC_SHA512_192, - HMAC_SHA512_128 -#endif -}; - -typedef VOID_RETURN hf_begin(void*); -typedef VOID_RETURN hf_hash(const void*, unsigned long len, void*); -typedef VOID_RETURN hf_end(void*, void*); - -typedef struct -{ hf_begin *f_begin; - hf_hash *f_hash; - hf_end *f_end; - unsigned char key[HMAC_MAX_BLOCK_SIZE]; - union - { -#ifdef SHA_1 - sha1_ctx u_sha1; -#endif -#ifdef SHA_224 - sha224_ctx u_sha224; -#endif -#ifdef SHA_256 - sha256_ctx u_sha256; -#endif -#ifdef SHA_384 - sha384_ctx u_sha384; -#endif -#ifdef SHA_512 - sha512_ctx u_sha512; -#endif - } sha_ctx[1]; - unsigned long input_len; - unsigned long output_len; - unsigned long klen; -} hmac_ctx; - -/* returns the length of hash digest for the hash used */ -/* mac_len must not be greater than this */ -int hmac_sha_begin(enum hmac_hash hash, hmac_ctx cx[1]); - -int hmac_sha_key(const unsigned char key[], unsigned long key_len, hmac_ctx cx[1]); - -void hmac_sha_data(const unsigned char data[], unsigned long data_len, hmac_ctx cx[1]); - -void hmac_sha_end(unsigned char mac[], unsigned long mac_len, hmac_ctx cx[1]); - -void hmac_sha(enum hmac_hash hash, const unsigned char key[], unsigned long key_len, - const unsigned char data[], unsigned long data_len, - unsigned char mac[], unsigned long mac_len); - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/pwd2key.c b/game/client/third/minizip/lib/aes/pwd2key.c deleted file mode 100755 index e964759b..00000000 --- a/game/client/third/minizip/lib/aes/pwd2key.c +++ /dev/null @@ -1,182 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - -This is an implementation of RFC2898, which specifies key derivation from -a password and a salt value. -*/ - -#include -#include "hmac.h" -#include "pwd2key.h" - -#if defined(__cplusplus) -extern "C" -{ -#endif - -void derive_key(const unsigned char pwd[], /* the PASSWORD */ - unsigned int pwd_len, /* and its length */ - const unsigned char salt[], /* the SALT and its */ - unsigned int salt_len, /* length */ - unsigned int iter, /* the number of iterations */ - unsigned char key[], /* space for the output key */ - unsigned int key_len)/* and its required length */ -{ - unsigned int i, j, k, n_blk, h_size; - unsigned char uu[HMAC_MAX_OUTPUT_SIZE], ux[HMAC_MAX_OUTPUT_SIZE]; - hmac_ctx c1[1], c2[1], c3[1]; - - /* set HMAC context (c1) for password */ - h_size = hmac_sha_begin(HMAC_SHA1, c1); - hmac_sha_key(pwd, pwd_len, c1); - - /* set HMAC context (c2) for password and salt */ - memcpy(c2, c1, sizeof(hmac_ctx)); - hmac_sha_data(salt, salt_len, c2); - - /* find the number of SHA blocks in the key */ - n_blk = 1 + (key_len - 1) / h_size; - - for(i = 0; i < n_blk; ++i) /* for each block in key */ - { - /* ux[] holds the running xor value */ - memset(ux, 0, h_size); - - /* set HMAC context (c3) for password and salt */ - memcpy(c3, c2, sizeof(hmac_ctx)); - - /* enter additional data for 1st block into uu */ - uu[0] = (unsigned char)((i + 1) >> 24); - uu[1] = (unsigned char)((i + 1) >> 16); - uu[2] = (unsigned char)((i + 1) >> 8); - uu[3] = (unsigned char)(i + 1); - - /* this is the key mixing iteration */ - for(j = 0, k = 4; j < iter; ++j) - { - /* add previous round data to HMAC */ - hmac_sha_data(uu, k, c3); - - /* obtain HMAC for uu[] */ - hmac_sha_end(uu, h_size, c3); - - /* xor into the running xor block */ - for(k = 0; k < h_size; ++k) - ux[k] ^= uu[k]; - - /* set HMAC context (c3) for password */ - memcpy(c3, c1, sizeof(hmac_ctx)); - } - - /* compile key blocks into the key output */ - j = 0; k = i * h_size; - while(j < h_size && k < key_len) - key[k++] = ux[j++]; - } -} - -#ifdef TEST - -#include - -struct -{ unsigned int pwd_len; - unsigned int salt_len; - unsigned int it_count; - unsigned char *pwd; - unsigned char salt[32]; - unsigned char key[32]; -} tests[] = -{ - { 8, 4, 5, (unsigned char*)"password", - { - 0x12, 0x34, 0x56, 0x78 - }, - { - 0x5c, 0x75, 0xce, 0xf0, 0x1a, 0x96, 0x0d, 0xf7, - 0x4c, 0xb6, 0xb4, 0x9b, 0x9e, 0x38, 0xe6, 0xb5 - } - }, - { 8, 8, 5, (unsigned char*)"password", - { - 0x12, 0x34, 0x56, 0x78, 0x78, 0x56, 0x34, 0x12 - }, - { - 0xd1, 0xda, 0xa7, 0x86, 0x15, 0xf2, 0x87, 0xe6, - 0xa1, 0xc8, 0xb1, 0x20, 0xd7, 0x06, 0x2a, 0x49 - } - }, - { 8, 21, 1, (unsigned char*)"password", - { - "ATHENA.MIT.EDUraeburn" - }, - { - 0xcd, 0xed, 0xb5, 0x28, 0x1b, 0xb2, 0xf8, 0x01, - 0x56, 0x5a, 0x11, 0x22, 0xb2, 0x56, 0x35, 0x15 - } - }, - { 8, 21, 2, (unsigned char*)"password", - { - "ATHENA.MIT.EDUraeburn" - }, - { - 0x01, 0xdb, 0xee, 0x7f, 0x4a, 0x9e, 0x24, 0x3e, - 0x98, 0x8b, 0x62, 0xc7, 0x3c, 0xda, 0x93, 0x5d - } - }, - { 8, 21, 1200, (unsigned char*)"password", - { - "ATHENA.MIT.EDUraeburn" - }, - { - 0x5c, 0x08, 0xeb, 0x61, 0xfd, 0xf7, 0x1e, 0x4e, - 0x4e, 0xc3, 0xcf, 0x6b, 0xa1, 0xf5, 0x51, 0x2b - } - } -}; - -int main() -{ unsigned int i, j, key_len = 256; - unsigned char key[256]; - - printf("\nTest of RFC2898 Password Based Key Derivation"); - for(i = 0; i < 5; ++i) - { - derive_key(tests[i].pwd, tests[i].pwd_len, tests[i].salt, - tests[i].salt_len, tests[i].it_count, key, key_len); - - printf("\ntest %i: ", i + 1); - printf("key %s", memcmp(tests[i].key, key, 16) ? "is bad" : "is good"); - for(j = 0; j < key_len && j < 64; j += 4) - { - if(j % 16 == 0) - printf("\n"); - printf("0x%02x%02x%02x%02x ", key[j], key[j + 1], key[j + 2], key[j + 3]); - } - printf(j < key_len ? " ... \n" : "\n"); - } - printf("\n"); - return 0; -} - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/pwd2key.h b/game/client/third/minizip/lib/aes/pwd2key.h deleted file mode 100755 index b9ba4211..00000000 --- a/game/client/third/minizip/lib/aes/pwd2key.h +++ /dev/null @@ -1,45 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 - -This is an implementation of RFC2898, which specifies key derivation from -a password and a salt value. -*/ - -#ifndef PWD2KEY_H -#define PWD2KEY_H - -#if defined(__cplusplus) -extern "C" -{ -#endif - -void derive_key( - const unsigned char pwd[], /* the PASSWORD, and */ - unsigned int pwd_len, /* its length */ - const unsigned char salt[], /* the SALT and its */ - unsigned int salt_len, /* length */ - unsigned int iter, /* the number of iterations */ - unsigned char key[], /* space for the output key */ - unsigned int key_len); /* and its required length */ - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/game/client/third/minizip/lib/aes/sha1.c b/game/client/third/minizip/lib/aes/sha1.c deleted file mode 100755 index 33003632..00000000 --- a/game/client/third/minizip/lib/aes/sha1.c +++ /dev/null @@ -1,283 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 -*/ - -#include /* for memcpy() etc. */ - -#include "sha1.h" -#include "brg_endian.h" - -#if defined(__cplusplus) -extern "C" -{ -#endif - -#if defined( _MSC_VER ) && ( _MSC_VER > 800 ) -#pragma intrinsic(memcpy) -#pragma intrinsic(memset) -#endif - -#if 0 && defined(_MSC_VER) -#define rotl32 _lrotl -#define rotr32 _lrotr -#else -#define rotl32(x,n) (((x) << n) | ((x) >> (32 - n))) -#define rotr32(x,n) (((x) >> n) | ((x) << (32 - n))) -#endif - -#if !defined(bswap_32) -#define bswap_32(x) ((rotr32((x), 24) & 0x00ff00ff) | (rotr32((x), 8) & 0xff00ff00)) -#endif - -#if (PLATFORM_BYTE_ORDER == IS_LITTLE_ENDIAN) -#define SWAP_BYTES -#else -#undef SWAP_BYTES -#endif - -#if defined(SWAP_BYTES) -#define bsw_32(p,n) \ - { int _i = (n); while(_i--) ((uint32_t*)p)[_i] = bswap_32(((uint32_t*)p)[_i]); } -#else -#define bsw_32(p,n) -#endif - -#define SHA1_MASK (SHA1_BLOCK_SIZE - 1) - -#if 0 - -#define ch(x,y,z) (((x) & (y)) ^ (~(x) & (z))) -#define parity(x,y,z) ((x) ^ (y) ^ (z)) -#define maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) - -#else /* Discovered by Rich Schroeppel and Colin Plumb */ - -#define ch(x,y,z) ((z) ^ ((x) & ((y) ^ (z)))) -#define parity(x,y,z) ((x) ^ (y) ^ (z)) -#define maj(x,y,z) (((x) & (y)) | ((z) & ((x) ^ (y)))) - -#endif - -/* Compile 64 bytes of hash data into SHA1 context. Note */ -/* that this routine assumes that the byte order in the */ -/* ctx->wbuf[] at this point is in such an order that low */ -/* address bytes in the ORIGINAL byte stream will go in */ -/* this buffer to the high end of 32-bit words on BOTH big */ -/* and little endian systems */ - -#ifdef ARRAY -#define q(v,n) v[n] -#else -#define q(v,n) v##n -#endif - -#ifdef SHA_1 - -#define one_cycle(v,a,b,c,d,e,f,k,h) \ - q(v,e) += rotr32(q(v,a),27) + \ - f(q(v,b),q(v,c),q(v,d)) + k + h; \ - q(v,b) = rotr32(q(v,b), 2) - -#define five_cycle(v,f,k,i) \ - one_cycle(v, 0,1,2,3,4, f,k,hf(i )); \ - one_cycle(v, 4,0,1,2,3, f,k,hf(i+1)); \ - one_cycle(v, 3,4,0,1,2, f,k,hf(i+2)); \ - one_cycle(v, 2,3,4,0,1, f,k,hf(i+3)); \ - one_cycle(v, 1,2,3,4,0, f,k,hf(i+4)) - -VOID_RETURN sha1_compile(sha1_ctx ctx[1]) -{ uint32_t *w = ctx->wbuf; - -#ifdef ARRAY - uint32_t v[5]; - memcpy(v, ctx->hash, sizeof(ctx->hash)); -#else - uint32_t v0, v1, v2, v3, v4; - v0 = ctx->hash[0]; v1 = ctx->hash[1]; - v2 = ctx->hash[2]; v3 = ctx->hash[3]; - v4 = ctx->hash[4]; -#endif - -#define hf(i) w[i] - - five_cycle(v, ch, 0x5a827999, 0); - five_cycle(v, ch, 0x5a827999, 5); - five_cycle(v, ch, 0x5a827999, 10); - one_cycle(v,0,1,2,3,4, ch, 0x5a827999, hf(15)); \ - -#undef hf -#define hf(i) (w[(i) & 15] = rotl32( \ - w[((i) + 13) & 15] ^ w[((i) + 8) & 15] \ - ^ w[((i) + 2) & 15] ^ w[(i) & 15], 1)) - - one_cycle(v,4,0,1,2,3, ch, 0x5a827999, hf(16)); - one_cycle(v,3,4,0,1,2, ch, 0x5a827999, hf(17)); - one_cycle(v,2,3,4,0,1, ch, 0x5a827999, hf(18)); - one_cycle(v,1,2,3,4,0, ch, 0x5a827999, hf(19)); - - five_cycle(v, parity, 0x6ed9eba1, 20); - five_cycle(v, parity, 0x6ed9eba1, 25); - five_cycle(v, parity, 0x6ed9eba1, 30); - five_cycle(v, parity, 0x6ed9eba1, 35); - - five_cycle(v, maj, 0x8f1bbcdc, 40); - five_cycle(v, maj, 0x8f1bbcdc, 45); - five_cycle(v, maj, 0x8f1bbcdc, 50); - five_cycle(v, maj, 0x8f1bbcdc, 55); - - five_cycle(v, parity, 0xca62c1d6, 60); - five_cycle(v, parity, 0xca62c1d6, 65); - five_cycle(v, parity, 0xca62c1d6, 70); - five_cycle(v, parity, 0xca62c1d6, 75); - -#ifdef ARRAY - ctx->hash[0] += v[0]; ctx->hash[1] += v[1]; - ctx->hash[2] += v[2]; ctx->hash[3] += v[3]; - ctx->hash[4] += v[4]; -#else - ctx->hash[0] += v0; ctx->hash[1] += v1; - ctx->hash[2] += v2; ctx->hash[3] += v3; - ctx->hash[4] += v4; -#endif -} - -VOID_RETURN sha1_begin(sha1_ctx ctx[1]) -{ - memset(ctx, 0, sizeof(sha1_ctx)); - ctx->hash[0] = 0x67452301; - ctx->hash[1] = 0xefcdab89; - ctx->hash[2] = 0x98badcfe; - ctx->hash[3] = 0x10325476; - ctx->hash[4] = 0xc3d2e1f0; -} - -/* SHA1 hash data in an array of bytes into hash buffer and */ -/* call the hash_compile function as required. For both the */ -/* bit and byte orientated versions, the block length 'len' */ -/* must not be greater than 2^32 - 1 bits (2^29 - 1 bytes) */ - -VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]) -{ uint32_t pos = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK); - const unsigned char *sp = data; - unsigned char *w = (unsigned char*)ctx->wbuf; -#if SHA1_BITS == 1 - uint32_t ofs = (ctx->count[0] & 7); -#else - len <<= 3; -#endif - if((ctx->count[0] += len) < len) - ++(ctx->count[1]); -#if SHA1_BITS == 1 - if(ofs) /* if not on a byte boundary */ - { - if(ofs + len < 8) /* if no added bytes are needed */ - { - w[pos] |= (*sp >> ofs); - } - else /* otherwise and add bytes */ - { unsigned char part = w[pos]; - - while((int)(ofs + (len -= 8)) >= 0) - { - w[pos++] = part | (*sp >> ofs); - part = *sp++ << (8 - ofs); - if(pos == SHA1_BLOCK_SIZE) - { - bsw_32(w, SHA1_BLOCK_SIZE >> 2); - sha1_compile(ctx); pos = 0; - } - } - - w[pos] = part; - } - } - else /* data is byte aligned */ -#endif - { uint32_t space = SHA1_BLOCK_SIZE - pos; - - while(len >= (space << 3)) - { - memcpy(w + pos, sp, space); - bsw_32(w, SHA1_BLOCK_SIZE >> 2); - sha1_compile(ctx); - sp += space; len -= (space << 3); - space = SHA1_BLOCK_SIZE; pos = 0; - } - memcpy(w + pos, sp, (len + 7 * SHA1_BITS) >> 3); - } -} - -/* SHA1 final padding and digest calculation */ - -VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]) -{ uint32_t i = (uint32_t)((ctx->count[0] >> 3) & SHA1_MASK), m1; - - /* put bytes in the buffer in an order in which references to */ - /* 32-bit words will put bytes with lower addresses into the */ - /* top of 32 bit words on BOTH big and little endian machines */ - bsw_32(ctx->wbuf, (i + 3 + SHA1_BITS) >> 2); - - /* we now need to mask valid bytes and add the padding which is */ - /* a single 1 bit and as many zero bits as necessary. Note that */ - /* we can always add the first padding byte here because the */ - /* buffer always has at least one empty slot */ - m1 = (unsigned char)0x80 >> (ctx->count[0] & 7); - ctx->wbuf[i >> 2] &= ((0xffffff00 | (~m1 + 1)) << 8 * (~i & 3)); - ctx->wbuf[i >> 2] |= (m1 << 8 * (~i & 3)); - - /* we need 9 or more empty positions, one for the padding byte */ - /* (above) and eight for the length count. If there is not */ - /* enough space, pad and empty the buffer */ - if(i > SHA1_BLOCK_SIZE - 9) - { - if(i < 60) ctx->wbuf[15] = 0; - sha1_compile(ctx); - i = 0; - } - else /* compute a word index for the empty buffer positions */ - i = (i >> 2) + 1; - - while(i < 14) /* and zero pad all but last two positions */ - ctx->wbuf[i++] = 0; - - /* the following 32-bit length fields are assembled in the */ - /* wrong byte order on little endian machines but this is */ - /* corrected later since they are only ever used as 32-bit */ - /* word values. */ - ctx->wbuf[14] = ctx->count[1]; - ctx->wbuf[15] = ctx->count[0]; - sha1_compile(ctx); - - /* extract the hash value as bytes in case the hash buffer is */ - /* misaligned for 32-bit words */ - for(i = 0; i < SHA1_DIGEST_SIZE; ++i) - hval[i] = ((ctx->hash[i >> 2] >> (8 * (~i & 3))) & 0xff); -} - -VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len) -{ sha1_ctx cx[1]; - - sha1_begin(cx); sha1_hash(data, len, cx); sha1_end(hval, cx); -} - -#endif - -#if defined(__cplusplus) -} -#endif diff --git a/game/client/third/minizip/lib/aes/sha1.h b/game/client/third/minizip/lib/aes/sha1.h deleted file mode 100755 index e805ad92..00000000 --- a/game/client/third/minizip/lib/aes/sha1.h +++ /dev/null @@ -1,72 +0,0 @@ -/* ---------------------------------------------------------------------------- -Copyright (c) 1998-2010, Brian Gladman, Worcester, UK. All rights reserved. - -The redistribution and use of this software (with or without changes) -is allowed without the payment of fees or royalties provided that: - - source code distributions include the above copyright notice, this - list of conditions and the following disclaimer; - - binary distributions include the above copyright notice, this list - of conditions and the following disclaimer in their documentation. - -This software is provided 'as is' with no explicit or implied warranties -in respect of its operation, including, but not limited to, correctness -and fitness for purpose. ---------------------------------------------------------------------------- -Issue Date: 20/12/2007 -*/ - -#ifndef _SHA1_H -#define _SHA1_H - -#define SHA_1 - -/* define for bit or byte oriented SHA */ -#if 1 -# define SHA1_BITS 0 /* byte oriented */ -#else -# define SHA1_BITS 1 /* bit oriented */ -#endif - -#include -#include "brg_types.h" - -#define SHA1_BLOCK_SIZE 64 -#define SHA1_DIGEST_SIZE 20 - -#if defined(__cplusplus) -extern "C" -{ -#endif - -/* type to hold the SHA256 context */ - -typedef struct -{ uint32_t count[2]; - uint32_t hash[SHA1_DIGEST_SIZE >> 2]; - uint32_t wbuf[SHA1_BLOCK_SIZE >> 2]; -} sha1_ctx; - -/* Note that these prototypes are the same for both bit and */ -/* byte oriented implementations. However the length fields */ -/* are in bytes or bits as appropriate for the version used */ -/* and bit sequences are input as arrays of bytes in which */ -/* bit sequences run from the most to the least significant */ -/* end of each byte. The value 'len' in sha1_hash for the */ -/* byte oriented version of SHA1 is limited to 2^29 bytes, */ -/* but multiple calls will handle longer data blocks. */ - -VOID_RETURN sha1_compile(sha1_ctx ctx[1]); - -VOID_RETURN sha1_begin(sha1_ctx ctx[1]); -VOID_RETURN sha1_hash(const unsigned char data[], unsigned long len, sha1_ctx ctx[1]); -VOID_RETURN sha1_end(unsigned char hval[], sha1_ctx ctx[1]); -VOID_RETURN sha1(unsigned char hval[], const unsigned char data[], unsigned long len); - -#if defined(__cplusplus) -} -#endif - -#endif diff --git a/game/client/third/minizip/lib/bzip2/LICENSE b/game/client/third/minizip/lib/bzip2/LICENSE deleted file mode 100755 index cc614178..00000000 --- a/game/client/third/minizip/lib/bzip2/LICENSE +++ /dev/null @@ -1,42 +0,0 @@ - --------------------------------------------------------------------------- - -This program, "bzip2", the associated library "libbzip2", and all -documentation, are copyright (C) 1996-2010 Julian R Seward. All -rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions -are met: - -1. Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - -2. The origin of this software must not be misrepresented; you must - not claim that you wrote the original software. If you use this - software in a product, an acknowledgment in the product - documentation would be appreciated but is not required. - -3. Altered source versions must be plainly marked as such, and must - not be misrepresented as being the original software. - -4. The name of the author may not be used to endorse or promote - products derived from this software without specific prior written - permission. - -THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS -OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY -DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE -GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -Julian Seward, jseward@bzip.org -bzip2/libbzip2 version 1.0.6 of 6 September 2010 - --------------------------------------------------------------------------- diff --git a/game/client/third/minizip/lib/bzip2/blocksort.c b/game/client/third/minizip/lib/bzip2/blocksort.c deleted file mode 100755 index d0d662cd..00000000 --- a/game/client/third/minizip/lib/bzip2/blocksort.c +++ /dev/null @@ -1,1094 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Block sorting machinery ---*/ -/*--- blocksort.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------*/ -/*--- Fallback O(N log(N)^2) sorting ---*/ -/*--- algorithm, for repetitive blocks ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -void fallbackSimpleSort ( UInt32* fmap, - UInt32* eclass, - Int32 lo, - Int32 hi ) -{ - Int32 i, j, tmp; - UInt32 ec_tmp; - - if (lo == hi) return; - - if (hi - lo > 3) { - for ( i = hi-4; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+4; j <= hi && ec_tmp > eclass[fmap[j]]; j += 4 ) - fmap[j-4] = fmap[j]; - fmap[j-4] = tmp; - } - } - - for ( i = hi-1; i >= lo; i-- ) { - tmp = fmap[i]; - ec_tmp = eclass[tmp]; - for ( j = i+1; j <= hi && ec_tmp > eclass[fmap[j]]; j++ ) - fmap[j-1] = fmap[j]; - fmap[j-1] = tmp; - } -} - - -/*---------------------------------------------*/ -#define fswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define fvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - fswap(fmap[yyp1], fmap[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - - -#define fmin(a,b) ((a) < (b)) ? (a) : (b) - -#define fpush(lz,hz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - sp++; } - -#define fpop(lz,hz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; } - -#define FALLBACK_QSORT_SMALL_THRESH 10 -#define FALLBACK_QSORT_STACK_SIZE 100 - - -static -void fallbackQSort3 ( UInt32* fmap, - UInt32* eclass, - Int32 loSt, - Int32 hiSt ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m; - Int32 sp, lo, hi; - UInt32 med, r, r3; - Int32 stackLo[FALLBACK_QSORT_STACK_SIZE]; - Int32 stackHi[FALLBACK_QSORT_STACK_SIZE]; - - r = 0; - - sp = 0; - fpush ( loSt, hiSt ); - - while (sp > 0) { - - AssertH ( sp < FALLBACK_QSORT_STACK_SIZE - 1, 1004 ); - - fpop ( lo, hi ); - if (hi - lo < FALLBACK_QSORT_SMALL_THRESH) { - fallbackSimpleSort ( fmap, eclass, lo, hi ); - continue; - } - - /* Random partitioning. Median of 3 sometimes fails to - avoid bad cases. Median of 9 seems to help but - looks rather expensive. This too seems to work but - is cheaper. Guidance for the magic constants - 7621 and 32768 is taken from Sedgewick's algorithms - book, chapter 35. - */ - r = ((r * 7621) + 1) % 32768; - r3 = r % 3; - if (r3 == 0) med = eclass[fmap[lo]]; else - if (r3 == 1) med = eclass[fmap[(lo+hi)>>1]]; else - med = eclass[fmap[hi]]; - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (1) { - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unLo]] - (Int32)med; - if (n == 0) { - fswap(fmap[unLo], fmap[ltLo]); - ltLo++; unLo++; - continue; - }; - if (n > 0) break; - unLo++; - } - while (1) { - if (unLo > unHi) break; - n = (Int32)eclass[fmap[unHi]] - (Int32)med; - if (n == 0) { - fswap(fmap[unHi], fmap[gtHi]); - gtHi--; unHi--; - continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - fswap(fmap[unLo], fmap[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "fallbackQSort3(2)" ); - - if (gtHi < ltLo) continue; - - n = fmin(ltLo-lo, unLo-ltLo); fvswap(lo, unLo-n, n); - m = fmin(hi-gtHi, gtHi-unHi); fvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - if (n - lo > hi - m) { - fpush ( lo, n ); - fpush ( m, hi ); - } else { - fpush ( m, hi ); - fpush ( lo, n ); - } - } -} - -#undef fmin -#undef fpush -#undef fpop -#undef fswap -#undef fvswap -#undef FALLBACK_QSORT_SMALL_THRESH -#undef FALLBACK_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - eclass exists for [0 .. nblock-1] - ((UChar*)eclass) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)eclass) [0 .. nblock-1] holds block - All other areas of eclass destroyed - fmap [0 .. nblock-1] holds sorted order - bhtab [ 0 .. 2+(nblock/32) ] destroyed -*/ - -#define SET_BH(zz) bhtab[(zz) >> 5] |= (1 << ((zz) & 31)) -#define CLEAR_BH(zz) bhtab[(zz) >> 5] &= ~(1 << ((zz) & 31)) -#define ISSET_BH(zz) (bhtab[(zz) >> 5] & (1 << ((zz) & 31))) -#define WORD_BH(zz) bhtab[(zz) >> 5] -#define UNALIGNED_BH(zz) ((zz) & 0x01f) - -static -void fallbackSort ( UInt32* fmap, - UInt32* eclass, - UInt32* bhtab, - Int32 nblock, - Int32 verb ) -{ - Int32 ftab[257]; - Int32 ftabCopy[256]; - Int32 H, i, j, k, l, r, cc, cc1; - Int32 nNotDone; - Int32 nBhtab; - UChar* eclass8 = (UChar*)eclass; - - /*-- - Initial 1-char radix sort to generate - initial fmap and initial BH bits. - --*/ - if (verb >= 4) - VPrintf0 ( " bucket sorting ...\n" ); - for (i = 0; i < 257; i++) ftab[i] = 0; - for (i = 0; i < nblock; i++) ftab[eclass8[i]]++; - for (i = 0; i < 256; i++) ftabCopy[i] = ftab[i]; - for (i = 1; i < 257; i++) ftab[i] += ftab[i-1]; - - for (i = 0; i < nblock; i++) { - j = eclass8[i]; - k = ftab[j] - 1; - ftab[j] = k; - fmap[k] = i; - } - - nBhtab = 2 + (nblock / 32); - for (i = 0; i < nBhtab; i++) bhtab[i] = 0; - for (i = 0; i < 256; i++) SET_BH(ftab[i]); - - /*-- - Inductively refine the buckets. Kind-of an - "exponential radix sort" (!), inspired by the - Manber-Myers suffix array construction algorithm. - --*/ - - /*-- set sentinel bits for block-end detection --*/ - for (i = 0; i < 32; i++) { - SET_BH(nblock + 2*i); - CLEAR_BH(nblock + 2*i + 1); - } - - /*-- the log(N) loop --*/ - H = 1; - while (1) { - - if (verb >= 4) - VPrintf1 ( " depth %6d has ", H ); - - j = 0; - for (i = 0; i < nblock; i++) { - if (ISSET_BH(i)) j = i; - k = fmap[i] - H; if (k < 0) k += nblock; - eclass[k] = j; - } - - nNotDone = 0; - r = -1; - while (1) { - - /*-- find the next non-singleton bucket --*/ - k = r + 1; - while (ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (ISSET_BH(k)) { - while (WORD_BH(k) == 0xffffffff) k += 32; - while (ISSET_BH(k)) k++; - } - l = k - 1; - if (l >= nblock) break; - while (!ISSET_BH(k) && UNALIGNED_BH(k)) k++; - if (!ISSET_BH(k)) { - while (WORD_BH(k) == 0x00000000) k += 32; - while (!ISSET_BH(k)) k++; - } - r = k - 1; - if (r >= nblock) break; - - /*-- now [l, r] bracket current bucket --*/ - if (r > l) { - nNotDone += (r - l + 1); - fallbackQSort3 ( fmap, eclass, l, r ); - - /*-- scan bucket and generate header bits-- */ - cc = -1; - for (i = l; i <= r; i++) { - cc1 = eclass[fmap[i]]; - if (cc != cc1) { SET_BH(i); cc = cc1; }; - } - } - } - - if (verb >= 4) - VPrintf1 ( "%6d unresolved strings\n", nNotDone ); - - H *= 2; - if (H > nblock || nNotDone == 0) break; - } - - /*-- - Reconstruct the original block in - eclass8 [0 .. nblock-1], since the - previous phase destroyed it. - --*/ - if (verb >= 4) - VPrintf0 ( " reconstructing block ...\n" ); - j = 0; - for (i = 0; i < nblock; i++) { - while (ftabCopy[j] == 0) j++; - ftabCopy[j]--; - eclass8[fmap[i]] = (UChar)j; - } - AssertH ( j < 256, 1005 ); -} - -#undef SET_BH -#undef CLEAR_BH -#undef ISSET_BH -#undef WORD_BH -#undef UNALIGNED_BH - - -/*---------------------------------------------*/ -/*--- The main, O(N^2 log(N)) sorting ---*/ -/*--- algorithm. Faster for "normal" ---*/ -/*--- non-repetitive blocks. ---*/ -/*---------------------------------------------*/ - -/*---------------------------------------------*/ -static -__inline__ -Bool mainGtU ( UInt32 i1, - UInt32 i2, - UChar* block, - UInt16* quadrant, - UInt32 nblock, - Int32* budget ) -{ - Int32 k; - UChar c1, c2; - UInt16 s1, s2; - - AssertD ( i1 != i2, "mainGtU" ); - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 9 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 10 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 11 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - /* 12 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - i1++; i2++; - - k = nblock + 8; - - do { - /* 1 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 2 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 3 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 4 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 5 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 6 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 7 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - /* 8 */ - c1 = block[i1]; c2 = block[i2]; - if (c1 != c2) return (c1 > c2); - s1 = quadrant[i1]; s2 = quadrant[i2]; - if (s1 != s2) return (s1 > s2); - i1++; i2++; - - if (i1 >= nblock) i1 -= nblock; - if (i2 >= nblock) i2 -= nblock; - - k -= 8; - (*budget)--; - } - while (k >= 0); - - return False; -} - - -/*---------------------------------------------*/ -/*-- - Knuth's increments seem to work better - than Incerpi-Sedgewick here. Possibly - because the number of elems to sort is - usually small, typically <= 20. ---*/ -static -Int32 incs[14] = { 1, 4, 13, 40, 121, 364, 1093, 3280, - 9841, 29524, 88573, 265720, - 797161, 2391484 }; - -static -void mainSimpleSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 lo, - Int32 hi, - Int32 d, - Int32* budget ) -{ - Int32 i, j, h, bigN, hp; - UInt32 v; - - bigN = hi - lo + 1; - if (bigN < 2) return; - - hp = 0; - while (incs[hp] < bigN) hp++; - hp--; - - for (; hp >= 0; hp--) { - h = incs[hp]; - - i = lo + h; - while (True) { - - /*-- copy 1 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 2 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - /*-- copy 3 --*/ - if (i > hi) break; - v = ptr[i]; - j = i; - while ( mainGtU ( - ptr[j-h]+d, v+d, block, quadrant, nblock, budget - ) ) { - ptr[j] = ptr[j-h]; - j = j - h; - if (j <= (lo + h - 1)) break; - } - ptr[j] = v; - i++; - - if (*budget < 0) return; - } - } -} - - -/*---------------------------------------------*/ -/*-- - The following is an implementation of - an elegant 3-way quicksort for strings, - described in a paper "Fast Algorithms for - Sorting and Searching Strings", by Robert - Sedgewick and Jon L. Bentley. ---*/ - -#define mswap(zz1, zz2) \ - { Int32 zztmp = zz1; zz1 = zz2; zz2 = zztmp; } - -#define mvswap(zzp1, zzp2, zzn) \ -{ \ - Int32 yyp1 = (zzp1); \ - Int32 yyp2 = (zzp2); \ - Int32 yyn = (zzn); \ - while (yyn > 0) { \ - mswap(ptr[yyp1], ptr[yyp2]); \ - yyp1++; yyp2++; yyn--; \ - } \ -} - -static -__inline__ -UChar mmed3 ( UChar a, UChar b, UChar c ) -{ - UChar t; - if (a > b) { t = a; a = b; b = t; }; - if (b > c) { - b = c; - if (a > b) b = a; - } - return b; -} - -#define mmin(a,b) ((a) < (b)) ? (a) : (b) - -#define mpush(lz,hz,dz) { stackLo[sp] = lz; \ - stackHi[sp] = hz; \ - stackD [sp] = dz; \ - sp++; } - -#define mpop(lz,hz,dz) { sp--; \ - lz = stackLo[sp]; \ - hz = stackHi[sp]; \ - dz = stackD [sp]; } - - -#define mnextsize(az) (nextHi[az]-nextLo[az]) - -#define mnextswap(az,bz) \ - { Int32 tz; \ - tz = nextLo[az]; nextLo[az] = nextLo[bz]; nextLo[bz] = tz; \ - tz = nextHi[az]; nextHi[az] = nextHi[bz]; nextHi[bz] = tz; \ - tz = nextD [az]; nextD [az] = nextD [bz]; nextD [bz] = tz; } - - -#define MAIN_QSORT_SMALL_THRESH 20 -#define MAIN_QSORT_DEPTH_THRESH (BZ_N_RADIX + BZ_N_QSORT) -#define MAIN_QSORT_STACK_SIZE 100 - -static -void mainQSort3 ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - Int32 nblock, - Int32 loSt, - Int32 hiSt, - Int32 dSt, - Int32* budget ) -{ - Int32 unLo, unHi, ltLo, gtHi, n, m, med; - Int32 sp, lo, hi, d; - - Int32 stackLo[MAIN_QSORT_STACK_SIZE]; - Int32 stackHi[MAIN_QSORT_STACK_SIZE]; - Int32 stackD [MAIN_QSORT_STACK_SIZE]; - - Int32 nextLo[3]; - Int32 nextHi[3]; - Int32 nextD [3]; - - sp = 0; - mpush ( loSt, hiSt, dSt ); - - while (sp > 0) { - - AssertH ( sp < MAIN_QSORT_STACK_SIZE - 2, 1001 ); - - mpop ( lo, hi, d ); - if (hi - lo < MAIN_QSORT_SMALL_THRESH || - d > MAIN_QSORT_DEPTH_THRESH) { - mainSimpleSort ( ptr, block, quadrant, nblock, lo, hi, d, budget ); - if (*budget < 0) return; - continue; - } - - med = (Int32) - mmed3 ( block[ptr[ lo ]+d], - block[ptr[ hi ]+d], - block[ptr[ (lo+hi)>>1 ]+d] ); - - unLo = ltLo = lo; - unHi = gtHi = hi; - - while (True) { - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unLo]+d]) - med; - if (n == 0) { - mswap(ptr[unLo], ptr[ltLo]); - ltLo++; unLo++; continue; - }; - if (n > 0) break; - unLo++; - } - while (True) { - if (unLo > unHi) break; - n = ((Int32)block[ptr[unHi]+d]) - med; - if (n == 0) { - mswap(ptr[unHi], ptr[gtHi]); - gtHi--; unHi--; continue; - }; - if (n < 0) break; - unHi--; - } - if (unLo > unHi) break; - mswap(ptr[unLo], ptr[unHi]); unLo++; unHi--; - } - - AssertD ( unHi == unLo-1, "mainQSort3(2)" ); - - if (gtHi < ltLo) { - mpush(lo, hi, d+1 ); - continue; - } - - n = mmin(ltLo-lo, unLo-ltLo); mvswap(lo, unLo-n, n); - m = mmin(hi-gtHi, gtHi-unHi); mvswap(unLo, hi-m+1, m); - - n = lo + unLo - ltLo - 1; - m = hi - (gtHi - unHi) + 1; - - nextLo[0] = lo; nextHi[0] = n; nextD[0] = d; - nextLo[1] = m; nextHi[1] = hi; nextD[1] = d; - nextLo[2] = n+1; nextHi[2] = m-1; nextD[2] = d+1; - - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - if (mnextsize(1) < mnextsize(2)) mnextswap(1,2); - if (mnextsize(0) < mnextsize(1)) mnextswap(0,1); - - AssertD (mnextsize(0) >= mnextsize(1), "mainQSort3(8)" ); - AssertD (mnextsize(1) >= mnextsize(2), "mainQSort3(9)" ); - - mpush (nextLo[0], nextHi[0], nextD[0]); - mpush (nextLo[1], nextHi[1], nextD[1]); - mpush (nextLo[2], nextHi[2], nextD[2]); - } -} - -#undef mswap -#undef mvswap -#undef mpush -#undef mpop -#undef mmin -#undef mnextsize -#undef mnextswap -#undef MAIN_QSORT_SMALL_THRESH -#undef MAIN_QSORT_DEPTH_THRESH -#undef MAIN_QSORT_STACK_SIZE - - -/*---------------------------------------------*/ -/* Pre: - nblock > N_OVERSHOOT - block32 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)block32) [0 .. nblock-1] holds block - ptr exists for [0 .. nblock-1] - - Post: - ((UChar*)block32) [0 .. nblock-1] holds block - All other areas of block32 destroyed - ftab [0 .. 65536 ] destroyed - ptr [0 .. nblock-1] holds sorted order - if (*budget < 0), sorting was abandoned -*/ - -#define BIGFREQ(b) (ftab[((b)+1) << 8] - ftab[(b) << 8]) -#define SETMASK (1 << 21) -#define CLEARMASK (~(SETMASK)) - -static -void mainSort ( UInt32* ptr, - UChar* block, - UInt16* quadrant, - UInt32* ftab, - Int32 nblock, - Int32 verb, - Int32* budget ) -{ - Int32 i, j, k, ss, sb; - Int32 runningOrder[256]; - Bool bigDone[256]; - Int32 copyStart[256]; - Int32 copyEnd [256]; - UChar c1; - Int32 numQSorted; - UInt16 s; - if (verb >= 4) VPrintf0 ( " main sort initialise ...\n" ); - - /*-- set up the 2-byte frequency table --*/ - for (i = 65536; i >= 0; i--) ftab[i] = 0; - - j = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - quadrant[i-1] = 0; - j = (j >> 8) | ( ((UInt16)block[i-1]) << 8); - ftab[j]++; - quadrant[i-2] = 0; - j = (j >> 8) | ( ((UInt16)block[i-2]) << 8); - ftab[j]++; - quadrant[i-3] = 0; - j = (j >> 8) | ( ((UInt16)block[i-3]) << 8); - ftab[j]++; - } - for (; i >= 0; i--) { - quadrant[i] = 0; - j = (j >> 8) | ( ((UInt16)block[i]) << 8); - ftab[j]++; - } - - /*-- (emphasises close relationship of block & quadrant) --*/ - for (i = 0; i < BZ_N_OVERSHOOT; i++) { - block [nblock+i] = block[i]; - quadrant[nblock+i] = 0; - } - - if (verb >= 4) VPrintf0 ( " bucket sorting ...\n" ); - - /*-- Complete the initial radix sort --*/ - for (i = 1; i <= 65536; i++) ftab[i] += ftab[i-1]; - - s = block[0] << 8; - i = nblock-1; - for (; i >= 3; i -= 4) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - s = (s >> 8) | (block[i-1] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-1; - s = (s >> 8) | (block[i-2] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-2; - s = (s >> 8) | (block[i-3] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i-3; - } - for (; i >= 0; i--) { - s = (s >> 8) | (block[i] << 8); - j = ftab[s] -1; - ftab[s] = j; - ptr[j] = i; - } - - /*-- - Now ftab contains the first loc of every small bucket. - Calculate the running order, from smallest to largest - big bucket. - --*/ - for (i = 0; i <= 255; i++) { - bigDone [i] = False; - runningOrder[i] = i; - } - - { - Int32 vv; - Int32 h = 1; - do h = 3 * h + 1; while (h <= 256); - do { - h = h / 3; - for (i = h; i <= 255; i++) { - vv = runningOrder[i]; - j = i; - while ( BIGFREQ(runningOrder[j-h]) > BIGFREQ(vv) ) { - runningOrder[j] = runningOrder[j-h]; - j = j - h; - if (j <= (h - 1)) goto zero; - } - zero: - runningOrder[j] = vv; - } - } while (h != 1); - } - - /*-- - The main sorting loop. - --*/ - - numQSorted = 0; - - for (i = 0; i <= 255; i++) { - - /*-- - Process big buckets, starting with the least full. - Basically this is a 3-step process in which we call - mainQSort3 to sort the small buckets [ss, j], but - also make a big effort to avoid the calls if we can. - --*/ - ss = runningOrder[i]; - - /*-- - Step 1: - Complete the big bucket [ss] by quicksorting - any unsorted small buckets [ss, j], for j != ss. - Hopefully previous pointer-scanning phases have already - completed many of the small buckets [ss, j], so - we don't have to sort them at all. - --*/ - for (j = 0; j <= 255; j++) { - if (j != ss) { - sb = (ss << 8) + j; - if ( ! (ftab[sb] & SETMASK) ) { - Int32 lo = ftab[sb] & CLEARMASK; - Int32 hi = (ftab[sb+1] & CLEARMASK) - 1; - if (hi > lo) { - if (verb >= 4) - VPrintf4 ( " qsort [0x%x, 0x%x] " - "done %d this %d\n", - ss, j, numQSorted, hi - lo + 1 ); - mainQSort3 ( - ptr, block, quadrant, nblock, - lo, hi, BZ_N_RADIX, budget - ); - numQSorted += (hi - lo + 1); - if (*budget < 0) return; - } - } - ftab[sb] |= SETMASK; - } - } - - AssertH ( !bigDone[ss], 1006 ); - - /*-- - Step 2: - Now scan this big bucket [ss] so as to synthesise the - sorted order for small buckets [t, ss] for all t, - including, magically, the bucket [ss,ss] too. - This will avoid doing Real Work in subsequent Step 1's. - --*/ - { - for (j = 0; j <= 255; j++) { - copyStart[j] = ftab[(j << 8) + ss] & CLEARMASK; - copyEnd [j] = (ftab[(j << 8) + ss + 1] & CLEARMASK) - 1; - } - for (j = ftab[ss << 8] & CLEARMASK; j < copyStart[ss]; j++) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyStart[c1]++ ] = k; - } - for (j = (ftab[(ss+1) << 8] & CLEARMASK) - 1; j > copyEnd[ss]; j--) { - k = ptr[j]-1; if (k < 0) k += nblock; - c1 = block[k]; - if (!bigDone[c1]) - ptr[ copyEnd[c1]-- ] = k; - } - } - - AssertH ( (copyStart[ss]-1 == copyEnd[ss]) - || - /* Extremely rare case missing in bzip2-1.0.0 and 1.0.1. - Necessity for this case is demonstrated by compressing - a sequence of approximately 48.5 million of character - 251; 1.0.0/1.0.1 will then die here. */ - (copyStart[ss] == 0 && copyEnd[ss] == nblock-1), - 1007 ) - - for (j = 0; j <= 255; j++) ftab[(j << 8) + ss] |= SETMASK; - - /*-- - Step 3: - The [ss] big bucket is now done. Record this fact, - and update the quadrant descriptors. Remember to - update quadrants in the overshoot area too, if - necessary. The "if (i < 255)" test merely skips - this updating for the last bucket processed, since - updating for the last bucket is pointless. - - The quadrant array provides a way to incrementally - cache sort orderings, as they appear, so as to - make subsequent comparisons in fullGtU() complete - faster. For repetitive blocks this makes a big - difference (but not big enough to be able to avoid - the fallback sorting mechanism, exponential radix sort). - - The precise meaning is: at all times: - - for 0 <= i < nblock and 0 <= j <= nblock - - if block[i] != block[j], - - then the relative values of quadrant[i] and - quadrant[j] are meaningless. - - else { - if quadrant[i] < quadrant[j] - then the string starting at i lexicographically - precedes the string starting at j - - else if quadrant[i] > quadrant[j] - then the string starting at j lexicographically - precedes the string starting at i - - else - the relative ordering of the strings starting - at i and j has not yet been determined. - } - --*/ - bigDone[ss] = True; - - if (i < 255) { - Int32 bbStart = ftab[ss << 8] & CLEARMASK; - Int32 bbSize = (ftab[(ss+1) << 8] & CLEARMASK) - bbStart; - Int32 shifts = 0; - - while ((bbSize >> shifts) > 65534) shifts++; - - for (j = bbSize-1; j >= 0; j--) { - Int32 a2update = ptr[bbStart + j]; - UInt16 qVal = (UInt16)(j >> shifts); - quadrant[a2update] = qVal; - if (a2update < BZ_N_OVERSHOOT) - quadrant[a2update + nblock] = qVal; - } - AssertH ( ((bbSize-1) >> shifts) <= 65535, 1002 ); - } - - } - - if (verb >= 4) - VPrintf3 ( " %d pointers, %d sorted, %d scanned\n", - nblock, numQSorted, nblock - numQSorted ); -} - -#undef BIGFREQ -#undef SETMASK -#undef CLEARMASK - - -/*---------------------------------------------*/ -/* Pre: - nblock > 0 - arr2 exists for [0 .. nblock-1 +N_OVERSHOOT] - ((UChar*)arr2) [0 .. nblock-1] holds block - arr1 exists for [0 .. nblock-1] - - Post: - ((UChar*)arr2) [0 .. nblock-1] holds block - All other areas of block destroyed - ftab [ 0 .. 65536 ] destroyed - arr1 [0 .. nblock-1] holds sorted order -*/ -void BZ2_blockSort ( EState* s ) -{ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt32* ftab = s->ftab; - Int32 nblock = s->nblock; - Int32 verb = s->verbosity; - Int32 wfact = s->workFactor; - UInt16* quadrant; - Int32 budget; - Int32 budgetInit; - Int32 i; - - if (nblock < 10000) { - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } else { - /* Calculate the location for quadrant, remembering to get - the alignment right. Assumes that &(block[0]) is at least - 2-byte aligned -- this should be ok since block is really - the first section of arr2. - */ - i = nblock+BZ_N_OVERSHOOT; - if (i & 1) i++; - quadrant = (UInt16*)(&(block[i])); - - /* (wfact-1) / 3 puts the default-factor-30 - transition point at very roughly the same place as - with v0.1 and v0.9.0. - Not that it particularly matters any more, since the - resulting compressed stream is now the same regardless - of whether or not we use the main sort or fallback sort. - */ - if (wfact < 1 ) wfact = 1; - if (wfact > 100) wfact = 100; - budgetInit = nblock * ((wfact-1) / 3); - budget = budgetInit; - - mainSort ( ptr, block, quadrant, ftab, nblock, verb, &budget ); - if (verb >= 3) - VPrintf3 ( " %d work, %d block, ratio %5.2f\n", - budgetInit - budget, - nblock, - (float)(budgetInit - budget) / - (float)(nblock==0 ? 1 : nblock) ); - if (budget < 0) { - if (verb >= 2) - VPrintf0 ( " too repetitive; using fallback" - " sorting algorithm\n" ); - fallbackSort ( s->arr1, s->arr2, ftab, nblock, verb ); - } - } - - s->origPtr = -1; - for (i = 0; i < s->nblock; i++) - if (ptr[i] == 0) - { s->origPtr = i; break; }; - - AssertH( s->origPtr != -1, 1003 ); -} - - -/*-------------------------------------------------------------*/ -/*--- end blocksort.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/bzlib.c b/game/client/third/minizip/lib/bzip2/bzlib.c deleted file mode 100755 index bd358a79..00000000 --- a/game/client/third/minizip/lib/bzip2/bzlib.c +++ /dev/null @@ -1,1572 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Library top-level functions. ---*/ -/*--- bzlib.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- made zero-length BZ_FLUSH work correctly in bzCompress(). - fixed bzWrite/bzRead to ignore zero-length requests. - fixed bzread to correctly handle read requests after EOF. - wrong parameter order in call to bzDecompressInit in - bzBuffToBuffDecompress. Fixed. -*/ - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Compression stuff ---*/ -/*---------------------------------------------------*/ - - -/*---------------------------------------------------*/ -#ifndef BZ_NO_STDIO -void BZ2_bz__AssertH__fail ( int errcode ) -{ - fprintf(stderr, - "\n\nbzip2/libbzip2: internal error number %d.\n" - "This is a bug in bzip2/libbzip2, %s.\n" - "Please report it to me at: jseward@bzip.org. If this happened\n" - "when you were using some program which uses libbzip2 as a\n" - "component, you should also report this bug to the author(s)\n" - "of that program. Please make an effort to report this bug;\n" - "timely and accurate bug reports eventually lead to higher\n" - "quality software. Thanks. Julian Seward, 10 December 2007.\n\n", - errcode, - BZ2_bzlibVersion() - ); - - if (errcode == 1007) { - fprintf(stderr, - "\n*** A special note about internal error number 1007 ***\n" - "\n" - "Experience suggests that a common cause of i.e. 1007\n" - "is unreliable memory or other hardware. The 1007 assertion\n" - "just happens to cross-check the results of huge numbers of\n" - "memory reads/writes, and so acts (unintendedly) as a stress\n" - "test of your memory system.\n" - "\n" - "I suggest the following: try compressing the file again,\n" - "possibly monitoring progress in detail with the -vv flag.\n" - "\n" - "* If the error cannot be reproduced, and/or happens at different\n" - " points in compression, you may have a flaky memory system.\n" - " Try a memory-test program. I have used Memtest86\n" - " (www.memtest86.com). At the time of writing it is free (GPLd).\n" - " Memtest86 tests memory much more thorougly than your BIOSs\n" - " power-on test, and may find failures that the BIOS doesn't.\n" - "\n" - "* If the error can be repeatably reproduced, this is a bug in\n" - " bzip2, and I would very much like to hear about it. Please\n" - " let me know, and, ideally, save a copy of the file causing the\n" - " problem -- without which I will be unable to investigate it.\n" - "\n" - ); - } - - exit(3); -} -#endif - - -/*---------------------------------------------------*/ -static -int bz_config_ok ( void ) -{ - if (sizeof(int) != 4) return 0; - if (sizeof(short) != 2) return 0; - if (sizeof(char) != 1) return 0; - return 1; -} - - -/*---------------------------------------------------*/ -static -void* default_bzalloc ( void* opaque, Int32 items, Int32 size ) -{ - void* v = malloc ( items * size ); - return v; -} - -static -void default_bzfree ( void* opaque, void* addr ) -{ - if (addr != NULL) free ( addr ); -} - - -/*---------------------------------------------------*/ -static -void prepare_new_block ( EState* s ) -{ - Int32 i; - s->nblock = 0; - s->numZ = 0; - s->state_out_pos = 0; - BZ_INITIALISE_CRC ( s->blockCRC ); - for (i = 0; i < 256; i++) s->inUse[i] = False; - s->blockNo++; -} - - -/*---------------------------------------------------*/ -static -void init_RL ( EState* s ) -{ - s->state_in_ch = 256; - s->state_in_len = 0; -} - - -static -Bool isempty_RL ( EState* s ) -{ - if (s->state_in_ch < 256 && s->state_in_len > 0) - return False; else - return True; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressInit) - ( bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 n; - EState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL || - blockSize100k < 1 || blockSize100k > 9 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(EState) ); - if (s == NULL) return BZ_MEM_ERROR; - s->strm = strm; - - s->arr1 = NULL; - s->arr2 = NULL; - s->ftab = NULL; - - n = 100000 * blockSize100k; - s->arr1 = BZALLOC( n * sizeof(UInt32) ); - s->arr2 = BZALLOC( (n+BZ_N_OVERSHOOT) * sizeof(UInt32) ); - s->ftab = BZALLOC( 65537 * sizeof(UInt32) ); - - if (s->arr1 == NULL || s->arr2 == NULL || s->ftab == NULL) { - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - if (s != NULL) BZFREE(s); - return BZ_MEM_ERROR; - } - - s->blockNo = 0; - s->state = BZ_S_INPUT; - s->mode = BZ_M_RUNNING; - s->combinedCRC = 0; - s->blockSize100k = blockSize100k; - s->nblockMAX = 100000 * blockSize100k - 19; - s->verbosity = verbosity; - s->workFactor = workFactor; - - s->block = (UChar*)s->arr2; - s->mtfv = (UInt16*)s->arr1; - s->zbits = NULL; - s->ptr = (UInt32*)s->arr1; - - strm->state = s; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - init_RL ( s ); - prepare_new_block ( s ); - return BZ_OK; -} - - -/*---------------------------------------------------*/ -static -void add_pair_to_block ( EState* s ) -{ - Int32 i; - UChar ch = (UChar)(s->state_in_ch); - for (i = 0; i < s->state_in_len; i++) { - BZ_UPDATE_CRC( s->blockCRC, ch ); - } - s->inUse[s->state_in_ch] = True; - switch (s->state_in_len) { - case 1: - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 2: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - case 3: - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - break; - default: - s->inUse[s->state_in_len-4] = True; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = (UChar)ch; s->nblock++; - s->block[s->nblock] = ((UChar)(s->state_in_len-4)); - s->nblock++; - break; - } -} - - -/*---------------------------------------------------*/ -static -void flush_RL ( EState* s ) -{ - if (s->state_in_ch < 256) add_pair_to_block ( s ); - init_RL ( s ); -} - - -/*---------------------------------------------------*/ -#define ADD_CHAR_TO_BLOCK(zs,zchh0) \ -{ \ - UInt32 zchh = (UInt32)(zchh0); \ - /*-- fast track the common case --*/ \ - if (zchh != zs->state_in_ch && \ - zs->state_in_len == 1) { \ - UChar ch = (UChar)(zs->state_in_ch); \ - BZ_UPDATE_CRC( zs->blockCRC, ch ); \ - zs->inUse[zs->state_in_ch] = True; \ - zs->block[zs->nblock] = (UChar)ch; \ - zs->nblock++; \ - zs->state_in_ch = zchh; \ - } \ - else \ - /*-- general, uncommon cases --*/ \ - if (zchh != zs->state_in_ch || \ - zs->state_in_len == 255) { \ - if (zs->state_in_ch < 256) \ - add_pair_to_block ( zs ); \ - zs->state_in_ch = zchh; \ - zs->state_in_len = 1; \ - } else { \ - zs->state_in_len++; \ - } \ -} - - -/*---------------------------------------------------*/ -static -Bool copy_input_until_stop ( EState* s ) -{ - Bool progress_in = False; - - if (s->mode == BZ_M_RUNNING) { - - /*-- fast track the common case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - } - - } else { - - /*-- general, uncommon case --*/ - while (True) { - /*-- block full? --*/ - if (s->nblock >= s->nblockMAX) break; - /*-- no input? --*/ - if (s->strm->avail_in == 0) break; - /*-- flush/finish end? --*/ - if (s->avail_in_expect == 0) break; - progress_in = True; - ADD_CHAR_TO_BLOCK ( s, (UInt32)(*((UChar*)(s->strm->next_in))) ); - s->strm->next_in++; - s->strm->avail_in--; - s->strm->total_in_lo32++; - if (s->strm->total_in_lo32 == 0) s->strm->total_in_hi32++; - s->avail_in_expect--; - } - } - return progress_in; -} - - -/*---------------------------------------------------*/ -static -Bool copy_output_until_stop ( EState* s ) -{ - Bool progress_out = False; - - while (True) { - - /*-- no output space? --*/ - if (s->strm->avail_out == 0) break; - - /*-- block done? --*/ - if (s->state_out_pos >= s->numZ) break; - - progress_out = True; - *(s->strm->next_out) = s->zbits[s->state_out_pos]; - s->state_out_pos++; - s->strm->avail_out--; - s->strm->next_out++; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - return progress_out; -} - - -/*---------------------------------------------------*/ -static -Bool handle_compress ( bz_stream* strm ) -{ - Bool progress_in = False; - Bool progress_out = False; - EState* s = strm->state; - - while (True) { - - if (s->state == BZ_S_OUTPUT) { - progress_out |= copy_output_until_stop ( s ); - if (s->state_out_pos < s->numZ) break; - if (s->mode == BZ_M_FINISHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - prepare_new_block ( s ); - s->state = BZ_S_INPUT; - if (s->mode == BZ_M_FLUSHING && - s->avail_in_expect == 0 && - isempty_RL(s)) break; - } - - if (s->state == BZ_S_INPUT) { - progress_in |= copy_input_until_stop ( s ); - if (s->mode != BZ_M_RUNNING && s->avail_in_expect == 0) { - flush_RL ( s ); - BZ2_compressBlock ( s, (Bool)(s->mode == BZ_M_FINISHING) ); - s->state = BZ_S_OUTPUT; - } - else - if (s->nblock >= s->nblockMAX) { - BZ2_compressBlock ( s, False ); - s->state = BZ_S_OUTPUT; - } - else - if (s->strm->avail_in == 0) { - break; - } - } - - } - - return progress_in || progress_out; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompress) ( bz_stream *strm, int action ) -{ - Bool progress; - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - preswitch: - switch (s->mode) { - - case BZ_M_IDLE: - return BZ_SEQUENCE_ERROR; - - case BZ_M_RUNNING: - if (action == BZ_RUN) { - progress = handle_compress ( strm ); - return progress ? BZ_RUN_OK : BZ_PARAM_ERROR; - } - else - if (action == BZ_FLUSH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FLUSHING; - goto preswitch; - } - else - if (action == BZ_FINISH) { - s->avail_in_expect = strm->avail_in; - s->mode = BZ_M_FINISHING; - goto preswitch; - } - else - return BZ_PARAM_ERROR; - - case BZ_M_FLUSHING: - if (action != BZ_FLUSH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FLUSH_OK; - s->mode = BZ_M_RUNNING; - return BZ_RUN_OK; - - case BZ_M_FINISHING: - if (action != BZ_FINISH) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect != s->strm->avail_in) - return BZ_SEQUENCE_ERROR; - progress = handle_compress ( strm ); - if (!progress) return BZ_SEQUENCE_ERROR; - if (s->avail_in_expect > 0 || !isempty_RL(s) || - s->state_out_pos < s->numZ) return BZ_FINISH_OK; - s->mode = BZ_M_IDLE; - return BZ_STREAM_END; - } - return BZ_OK; /*--not reached--*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzCompressEnd) ( bz_stream *strm ) -{ - EState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->arr1 != NULL) BZFREE(s->arr1); - if (s->arr2 != NULL) BZFREE(s->arr2); - if (s->ftab != NULL) BZFREE(s->ftab); - BZFREE(strm->state); - - strm->state = NULL; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/*--- Decompression stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressInit) - ( bz_stream* strm, - int verbosity, - int small ) -{ - DState* s; - - if (!bz_config_ok()) return BZ_CONFIG_ERROR; - - if (strm == NULL) return BZ_PARAM_ERROR; - if (small != 0 && small != 1) return BZ_PARAM_ERROR; - if (verbosity < 0 || verbosity > 4) return BZ_PARAM_ERROR; - - if (strm->bzalloc == NULL) strm->bzalloc = default_bzalloc; - if (strm->bzfree == NULL) strm->bzfree = default_bzfree; - - s = BZALLOC( sizeof(DState) ); - if (s == NULL) return BZ_MEM_ERROR; - s->strm = strm; - strm->state = s; - s->state = BZ_X_MAGIC_1; - s->bsLive = 0; - s->bsBuff = 0; - s->calculatedCombinedCRC = 0; - strm->total_in_lo32 = 0; - strm->total_in_hi32 = 0; - strm->total_out_lo32 = 0; - strm->total_out_hi32 = 0; - s->smallDecompress = (Bool)small; - s->ll4 = NULL; - s->ll16 = NULL; - s->tt = NULL; - s->currBlockNo = 0; - s->verbosity = verbosity; - - return BZ_OK; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_FAST ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_FAST(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - /* restore */ - UInt32 c_calculatedBlockCRC = s->calculatedBlockCRC; - UChar c_state_out_ch = s->state_out_ch; - Int32 c_state_out_len = s->state_out_len; - Int32 c_nblock_used = s->nblock_used; - Int32 c_k0 = s->k0; - UInt32* c_tt = s->tt; - UInt32 c_tPos = s->tPos; - char* cs_next_out = s->strm->next_out; - unsigned int cs_avail_out = s->strm->avail_out; - Int32 ro_blockSize100k = s->blockSize100k; - /* end restore */ - - UInt32 avail_out_INIT = cs_avail_out; - Int32 s_save_nblockPP = s->save_nblock+1; - unsigned int total_out_lo32_old; - - while (True) { - - /* try to finish existing run */ - if (c_state_out_len > 0) { - while (True) { - if (cs_avail_out == 0) goto return_notr; - if (c_state_out_len == 1) break; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - c_state_out_len--; - cs_next_out++; - cs_avail_out--; - } - s_state_out_len_eq_one: - { - if (cs_avail_out == 0) { - c_state_out_len = 1; goto return_notr; - }; - *( (UChar*)(cs_next_out) ) = c_state_out_ch; - BZ_UPDATE_CRC ( c_calculatedBlockCRC, c_state_out_ch ); - cs_next_out++; - cs_avail_out--; - } - } - /* Only caused by corrupt data stream? */ - if (c_nblock_used > s_save_nblockPP) - return True; - - /* can a new run be started? */ - if (c_nblock_used == s_save_nblockPP) { - c_state_out_len = 0; goto return_notr; - }; - c_state_out_ch = c_k0; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (k1 != c_k0) { - c_k0 = k1; goto s_state_out_len_eq_one; - }; - if (c_nblock_used == s_save_nblockPP) - goto s_state_out_len_eq_one; - - c_state_out_len = 2; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - c_state_out_len = 3; - BZ_GET_FAST_C(k1); c_nblock_used++; - if (c_nblock_used == s_save_nblockPP) continue; - if (k1 != c_k0) { c_k0 = k1; continue; }; - - BZ_GET_FAST_C(k1); c_nblock_used++; - c_state_out_len = ((Int32)k1) + 4; - BZ_GET_FAST_C(c_k0); c_nblock_used++; - } - - return_notr: - total_out_lo32_old = s->strm->total_out_lo32; - s->strm->total_out_lo32 += (avail_out_INIT - cs_avail_out); - if (s->strm->total_out_lo32 < total_out_lo32_old) - s->strm->total_out_hi32++; - - /* save */ - s->calculatedBlockCRC = c_calculatedBlockCRC; - s->state_out_ch = c_state_out_ch; - s->state_out_len = c_state_out_len; - s->nblock_used = c_nblock_used; - s->k0 = c_k0; - s->tt = c_tt; - s->tPos = c_tPos; - s->strm->next_out = cs_next_out; - s->strm->avail_out = cs_avail_out; - /* end save */ - } - return False; -} - - - -/*---------------------------------------------------*/ -__inline__ Int32 BZ2_indexIntoF ( Int32 indx, Int32 *cftab ) -{ - Int32 nb, na, mid; - nb = 0; - na = 256; - do { - mid = (nb + na) >> 1; - if (indx >= cftab[mid]) nb = mid; else na = mid; - } - while (na - nb != 1); - return nb; -} - - -/*---------------------------------------------------*/ -/* Return True iff data corruption is discovered. - Returns False if there is no problem. -*/ -static -Bool unRLE_obuf_to_output_SMALL ( DState* s ) -{ - UChar k1; - - if (s->blockRandomised) { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); BZ_RAND_UPD_MASK; - k1 ^= BZ_RAND_MASK; s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); BZ_RAND_UPD_MASK; - s->k0 ^= BZ_RAND_MASK; s->nblock_used++; - } - - } else { - - while (True) { - /* try to finish existing run */ - while (True) { - if (s->strm->avail_out == 0) return False; - if (s->state_out_len == 0) break; - *( (UChar*)(s->strm->next_out) ) = s->state_out_ch; - BZ_UPDATE_CRC ( s->calculatedBlockCRC, s->state_out_ch ); - s->state_out_len--; - s->strm->next_out++; - s->strm->avail_out--; - s->strm->total_out_lo32++; - if (s->strm->total_out_lo32 == 0) s->strm->total_out_hi32++; - } - - /* can a new run be started? */ - if (s->nblock_used == s->save_nblock+1) return False; - - /* Only caused by corrupt data stream? */ - if (s->nblock_used > s->save_nblock+1) - return True; - - s->state_out_len = 1; - s->state_out_ch = s->k0; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 2; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - s->state_out_len = 3; - BZ_GET_SMALL(k1); s->nblock_used++; - if (s->nblock_used == s->save_nblock+1) continue; - if (k1 != s->k0) { s->k0 = k1; continue; }; - - BZ_GET_SMALL(k1); s->nblock_used++; - s->state_out_len = ((Int32)k1) + 4; - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompress) ( bz_stream *strm ) -{ - Bool corrupt; - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - while (True) { - if (s->state == BZ_X_IDLE) return BZ_SEQUENCE_ERROR; - if (s->state == BZ_X_OUTPUT) { - if (s->smallDecompress) - corrupt = unRLE_obuf_to_output_SMALL ( s ); else - corrupt = unRLE_obuf_to_output_FAST ( s ); - if (corrupt) return BZ_DATA_ERROR; - if (s->nblock_used == s->save_nblock+1 && s->state_out_len == 0) { - BZ_FINALISE_CRC ( s->calculatedBlockCRC ); - if (s->verbosity >= 3) - VPrintf2 ( " {0x%08x, 0x%08x}", s->storedBlockCRC, - s->calculatedBlockCRC ); - if (s->verbosity >= 2) VPrintf0 ( "]" ); - if (s->calculatedBlockCRC != s->storedBlockCRC) - return BZ_DATA_ERROR; - s->calculatedCombinedCRC - = (s->calculatedCombinedCRC << 1) | - (s->calculatedCombinedCRC >> 31); - s->calculatedCombinedCRC ^= s->calculatedBlockCRC; - s->state = BZ_X_BLKHDR_1; - } else { - return BZ_OK; - } - } - if (s->state >= BZ_X_MAGIC_1) { - Int32 r = BZ2_decompress ( s ); - if (r == BZ_STREAM_END) { - if (s->verbosity >= 3) - VPrintf2 ( "\n combined CRCs: stored = 0x%08x, computed = 0x%08x", - s->storedCombinedCRC, s->calculatedCombinedCRC ); - if (s->calculatedCombinedCRC != s->storedCombinedCRC) - return BZ_DATA_ERROR; - return r; - } - if (s->state != BZ_X_OUTPUT) return r; - } - } - - AssertH ( 0, 6001 ); - - return 0; /*NOTREACHED*/ -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzDecompressEnd) ( bz_stream *strm ) -{ - DState* s; - if (strm == NULL) return BZ_PARAM_ERROR; - s = strm->state; - if (s == NULL) return BZ_PARAM_ERROR; - if (s->strm != strm) return BZ_PARAM_ERROR; - - if (s->tt != NULL) BZFREE(s->tt); - if (s->ll16 != NULL) BZFREE(s->ll16); - if (s->ll4 != NULL) BZFREE(s->ll4); - - BZFREE(strm->state); - strm->state = NULL; - - return BZ_OK; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ -/*--- File I/O stuff ---*/ -/*---------------------------------------------------*/ - -#define BZ_SETERR(eee) \ -{ \ - if (bzerror != NULL) *bzerror = eee; \ - if (bzf != NULL) bzf->lastErr = eee; \ -} - -typedef - struct { - FILE* handle; - Char buf[BZ_MAX_UNUSED]; - Int32 bufN; - Bool writing; - bz_stream strm; - Int32 lastErr; - Bool initialisedOk; - } - bzFile; - - -/*---------------------------------------------*/ -static Bool myfeof ( FILE* f ) -{ - Int32 c = fgetc ( f ); - if (c == EOF) return True; - ungetc ( c, f ); - return False; -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzWriteOpen) - ( int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor ) -{ - Int32 ret; - bzFile* bzf = NULL; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (blockSize100k < 1 || blockSize100k > 9) || - (workFactor < 0 || workFactor > 250) || - (verbosity < 0 || verbosity > 4)) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - bzf->initialisedOk = False; - bzf->bufN = 0; - bzf->handle = f; - bzf->writing = True; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - if (workFactor == 0) workFactor = 30; - ret = BZ2_bzCompressInit ( &(bzf->strm), blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = 0; - bzf->initialisedOk = True; - return bzf; -} - - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWrite) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return; }; - - bzf->strm.avail_in = len; - bzf->strm.next_in = buf; - - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_RUN ); - if (ret != BZ_RUN_OK) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (bzf->strm.avail_in == 0) - { BZ_SETERR(BZ_OK); return; }; - } -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzWriteClose) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out ) -{ - BZ2_bzWriteClose64 ( bzerror, b, abandon, - nbytes_in, NULL, nbytes_out, NULL ); -} - - -void BZ_API(BZ2_bzWriteClose64) - ( int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 ) -{ - Int32 n, n2, ret; - bzFile* bzf = (bzFile*)b; - - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - if (!(bzf->writing)) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - - if (nbytes_in_lo32 != NULL) *nbytes_in_lo32 = 0; - if (nbytes_in_hi32 != NULL) *nbytes_in_hi32 = 0; - if (nbytes_out_lo32 != NULL) *nbytes_out_lo32 = 0; - if (nbytes_out_hi32 != NULL) *nbytes_out_hi32 = 0; - - if ((!abandon) && bzf->lastErr == BZ_OK) { - while (True) { - bzf->strm.avail_out = BZ_MAX_UNUSED; - bzf->strm.next_out = bzf->buf; - ret = BZ2_bzCompress ( &(bzf->strm), BZ_FINISH ); - if (ret != BZ_FINISH_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return; }; - - if (bzf->strm.avail_out < BZ_MAX_UNUSED) { - n = BZ_MAX_UNUSED - bzf->strm.avail_out; - n2 = fwrite ( (void*)(bzf->buf), sizeof(UChar), - n, bzf->handle ); - if (n != n2 || ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (ret == BZ_STREAM_END) break; - } - } - - if ( !abandon && !ferror ( bzf->handle ) ) { - fflush ( bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return; }; - } - - if (nbytes_in_lo32 != NULL) - *nbytes_in_lo32 = bzf->strm.total_in_lo32; - if (nbytes_in_hi32 != NULL) - *nbytes_in_hi32 = bzf->strm.total_in_hi32; - if (nbytes_out_lo32 != NULL) - *nbytes_out_lo32 = bzf->strm.total_out_lo32; - if (nbytes_out_hi32 != NULL) - *nbytes_out_hi32 = bzf->strm.total_out_hi32; - - BZ_SETERR(BZ_OK); - BZ2_bzCompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -BZFILE* BZ_API(BZ2_bzReadOpen) - ( int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused ) -{ - bzFile* bzf = NULL; - int ret; - - BZ_SETERR(BZ_OK); - - if (f == NULL || - (small != 0 && small != 1) || - (verbosity < 0 || verbosity > 4) || - (unused == NULL && nUnused != 0) || - (unused != NULL && (nUnused < 0 || nUnused > BZ_MAX_UNUSED))) - { BZ_SETERR(BZ_PARAM_ERROR); return NULL; }; - - if (ferror(f)) - { BZ_SETERR(BZ_IO_ERROR); return NULL; }; - - bzf = malloc ( sizeof(bzFile) ); - if (bzf == NULL) - { BZ_SETERR(BZ_MEM_ERROR); return NULL; }; - - BZ_SETERR(BZ_OK); - - bzf->initialisedOk = False; - bzf->handle = f; - bzf->bufN = 0; - bzf->writing = False; - bzf->strm.bzalloc = NULL; - bzf->strm.bzfree = NULL; - bzf->strm.opaque = NULL; - - while (nUnused > 0) { - bzf->buf[bzf->bufN] = *((UChar*)(unused)); bzf->bufN++; - unused = ((void*)( 1 + ((UChar*)(unused)) )); - nUnused--; - } - - ret = BZ2_bzDecompressInit ( &(bzf->strm), verbosity, small ); - if (ret != BZ_OK) - { BZ_SETERR(ret); free(bzf); return NULL; }; - - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - - bzf->initialisedOk = True; - return bzf; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadClose) ( int *bzerror, BZFILE *b ) -{ - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - if (bzf == NULL) - { BZ_SETERR(BZ_OK); return; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - - if (bzf->initialisedOk) - (void)BZ2_bzDecompressEnd ( &(bzf->strm) ); - free ( bzf ); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzRead) - ( int* bzerror, - BZFILE* b, - void* buf, - int len ) -{ - Int32 n, ret; - bzFile* bzf = (bzFile*)b; - - BZ_SETERR(BZ_OK); - - if (bzf == NULL || buf == NULL || len < 0) - { BZ_SETERR(BZ_PARAM_ERROR); return 0; }; - - if (bzf->writing) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return 0; }; - - if (len == 0) - { BZ_SETERR(BZ_OK); return 0; }; - - bzf->strm.avail_out = len; - bzf->strm.next_out = buf; - - while (True) { - - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - - if (bzf->strm.avail_in == 0 && !myfeof(bzf->handle)) { - n = fread ( bzf->buf, sizeof(UChar), - BZ_MAX_UNUSED, bzf->handle ); - if (ferror(bzf->handle)) - { BZ_SETERR(BZ_IO_ERROR); return 0; }; - bzf->bufN = n; - bzf->strm.avail_in = bzf->bufN; - bzf->strm.next_in = bzf->buf; - } - - ret = BZ2_bzDecompress ( &(bzf->strm) ); - - if (ret != BZ_OK && ret != BZ_STREAM_END) - { BZ_SETERR(ret); return 0; }; - - if (ret == BZ_OK && myfeof(bzf->handle) && - bzf->strm.avail_in == 0 && bzf->strm.avail_out > 0) - { BZ_SETERR(BZ_UNEXPECTED_EOF); return 0; }; - - if (ret == BZ_STREAM_END) - { BZ_SETERR(BZ_STREAM_END); - return len - bzf->strm.avail_out; }; - if (bzf->strm.avail_out == 0) - { BZ_SETERR(BZ_OK); return len; }; - - } - - return 0; /*not reached*/ -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzReadGetUnused) - ( int* bzerror, - BZFILE* b, - void** unused, - int* nUnused ) -{ - bzFile* bzf = (bzFile*)b; - if (bzf == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - if (bzf->lastErr != BZ_STREAM_END) - { BZ_SETERR(BZ_SEQUENCE_ERROR); return; }; - if (unused == NULL || nUnused == NULL) - { BZ_SETERR(BZ_PARAM_ERROR); return; }; - - BZ_SETERR(BZ_OK); - *nUnused = bzf->strm.avail_in; - *unused = bzf->strm.next_in; -} -#endif - - -/*---------------------------------------------------*/ -/*--- Misc convenience stuff ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffCompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - blockSize100k < 1 || blockSize100k > 9 || - verbosity < 0 || verbosity > 4 || - workFactor < 0 || workFactor > 250) - return BZ_PARAM_ERROR; - - if (workFactor == 0) workFactor = 30; - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzCompressInit ( &strm, blockSize100k, - verbosity, workFactor ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzCompress ( &strm, BZ_FINISH ); - if (ret == BZ_FINISH_OK) goto output_overflow; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzCompressEnd ( &strm ); - return BZ_OK; - - output_overflow: - BZ2_bzCompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - - errhandler: - BZ2_bzCompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzBuffToBuffDecompress) - ( char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity ) -{ - bz_stream strm; - int ret; - - if (dest == NULL || destLen == NULL || - source == NULL || - (small != 0 && small != 1) || - verbosity < 0 || verbosity > 4) - return BZ_PARAM_ERROR; - - strm.bzalloc = NULL; - strm.bzfree = NULL; - strm.opaque = NULL; - ret = BZ2_bzDecompressInit ( &strm, verbosity, small ); - if (ret != BZ_OK) return ret; - - strm.next_in = source; - strm.next_out = dest; - strm.avail_in = sourceLen; - strm.avail_out = *destLen; - - ret = BZ2_bzDecompress ( &strm ); - if (ret == BZ_OK) goto output_overflow_or_eof; - if (ret != BZ_STREAM_END) goto errhandler; - - /* normal termination */ - *destLen -= strm.avail_out; - BZ2_bzDecompressEnd ( &strm ); - return BZ_OK; - - output_overflow_or_eof: - if (strm.avail_out > 0) { - BZ2_bzDecompressEnd ( &strm ); - return BZ_UNEXPECTED_EOF; - } else { - BZ2_bzDecompressEnd ( &strm ); - return BZ_OUTBUFF_FULL; - }; - - errhandler: - BZ2_bzDecompressEnd ( &strm ); - return ret; -} - - -/*---------------------------------------------------*/ -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -/*-- - return version like "0.9.5d, 4-Sept-1999". ---*/ -const char * BZ_API(BZ2_bzlibVersion)(void) -{ - return BZ_VERSION; -} - - -#ifndef BZ_NO_STDIO -/*---------------------------------------------------*/ - -#if defined(_WIN32) || defined(OS2) || defined(MSDOS) -# include -# include -# define SET_BINARY_MODE(file) setmode(fileno(file),O_BINARY) -#else -# define SET_BINARY_MODE(file) -#endif -static -BZFILE * bzopen_or_bzdopen - ( const char *path, /* no use when bzdopen */ - int fd, /* no use when bzdopen */ - const char *mode, - int open_mode) /* bzopen: 0, bzdopen:1 */ -{ - int bzerr; - char unused[BZ_MAX_UNUSED]; - int blockSize100k = 9; - int writing = 0; - char mode2[10] = ""; - FILE *fp = NULL; - BZFILE *bzfp = NULL; - int verbosity = 0; - int workFactor = 30; - int smallMode = 0; - int nUnused = 0; - - if (mode == NULL) return NULL; - while (*mode) { - switch (*mode) { - case 'r': - writing = 0; break; - case 'w': - writing = 1; break; - case 's': - smallMode = 1; break; - default: - if (isdigit((int)(*mode))) { - blockSize100k = *mode-BZ_HDR_0; - } - } - mode++; - } - strcat(mode2, writing ? "w" : "r" ); - strcat(mode2,"b"); /* binary mode */ - - if (open_mode==0) { - if (path==NULL || strcmp(path,"")==0) { - fp = (writing ? stdout : stdin); - SET_BINARY_MODE(fp); - } else { - fp = fopen(path,mode2); - } - } else { -#ifdef BZ_STRICT_ANSI - fp = NULL; -#else - fp = fdopen(fd,mode2); -#endif - } - if (fp == NULL) return NULL; - - if (writing) { - /* Guard against total chaos and anarchy -- JRS */ - if (blockSize100k < 1) blockSize100k = 1; - if (blockSize100k > 9) blockSize100k = 9; - bzfp = BZ2_bzWriteOpen(&bzerr,fp,blockSize100k, - verbosity,workFactor); - } else { - bzfp = BZ2_bzReadOpen(&bzerr,fp,verbosity,smallMode, - unused,nUnused); - } - if (bzfp == NULL) { - if (fp != stdin && fp != stdout) fclose(fp); - return NULL; - } - return bzfp; -} - - -/*---------------------------------------------------*/ -/*-- - open file for read or write. - ex) bzopen("file","w9") - case path="" or NULL => use stdin or stdout. ---*/ -BZFILE * BZ_API(BZ2_bzopen) - ( const char *path, - const char *mode ) -{ - return bzopen_or_bzdopen(path,-1,mode,/*bzopen*/0); -} - - -/*---------------------------------------------------*/ -BZFILE * BZ_API(BZ2_bzdopen) - ( int fd, - const char *mode ) -{ - return bzopen_or_bzdopen(NULL,fd,mode,/*bzdopen*/1); -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzread) (BZFILE* b, void* buf, int len ) -{ - int bzerr, nread; - if (((bzFile*)b)->lastErr == BZ_STREAM_END) return 0; - nread = BZ2_bzRead(&bzerr,b,buf,len); - if (bzerr == BZ_OK || bzerr == BZ_STREAM_END) { - return nread; - } else { - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzwrite) (BZFILE* b, void* buf, int len ) -{ - int bzerr; - - BZ2_bzWrite(&bzerr,b,buf,len); - if(bzerr == BZ_OK){ - return len; - }else{ - return -1; - } -} - - -/*---------------------------------------------------*/ -int BZ_API(BZ2_bzflush) (BZFILE *b) -{ - /* do nothing now... */ - return 0; -} - - -/*---------------------------------------------------*/ -void BZ_API(BZ2_bzclose) (BZFILE* b) -{ - int bzerr; - FILE *fp; - - if (b==NULL) {return;} - fp = ((bzFile *)b)->handle; - if(((bzFile*)b)->writing){ - BZ2_bzWriteClose(&bzerr,b,0,NULL,NULL); - if(bzerr != BZ_OK){ - BZ2_bzWriteClose(NULL,b,1,NULL,NULL); - } - }else{ - BZ2_bzReadClose(&bzerr,b); - } - if(fp!=stdin && fp!=stdout){ - fclose(fp); - } -} - - -/*---------------------------------------------------*/ -/*-- - return last error code ---*/ -static const char *bzerrorstrings[] = { - "OK" - ,"SEQUENCE_ERROR" - ,"PARAM_ERROR" - ,"MEM_ERROR" - ,"DATA_ERROR" - ,"DATA_ERROR_MAGIC" - ,"IO_ERROR" - ,"UNEXPECTED_EOF" - ,"OUTBUFF_FULL" - ,"CONFIG_ERROR" - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ - ,"???" /* for future */ -}; - - -const char * BZ_API(BZ2_bzerror) (BZFILE *b, int *errnum) -{ - int err = ((bzFile *)b)->lastErr; - - if(err>0) err = 0; - *errnum = err; - return bzerrorstrings[err*-1]; -} -#endif - - -/*-------------------------------------------------------------*/ -/*--- end bzlib.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/bzlib.h b/game/client/third/minizip/lib/bzip2/bzlib.h deleted file mode 100755 index 8277123d..00000000 --- a/game/client/third/minizip/lib/bzip2/bzlib.h +++ /dev/null @@ -1,282 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Public header file for the library. ---*/ -/*--- bzlib.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_H -#define _BZLIB_H - -#ifdef __cplusplus -extern "C" { -#endif - -#define BZ_RUN 0 -#define BZ_FLUSH 1 -#define BZ_FINISH 2 - -#define BZ_OK 0 -#define BZ_RUN_OK 1 -#define BZ_FLUSH_OK 2 -#define BZ_FINISH_OK 3 -#define BZ_STREAM_END 4 -#define BZ_SEQUENCE_ERROR (-1) -#define BZ_PARAM_ERROR (-2) -#define BZ_MEM_ERROR (-3) -#define BZ_DATA_ERROR (-4) -#define BZ_DATA_ERROR_MAGIC (-5) -#define BZ_IO_ERROR (-6) -#define BZ_UNEXPECTED_EOF (-7) -#define BZ_OUTBUFF_FULL (-8) -#define BZ_CONFIG_ERROR (-9) - -typedef - struct { - char *next_in; - unsigned int avail_in; - unsigned int total_in_lo32; - unsigned int total_in_hi32; - - char *next_out; - unsigned int avail_out; - unsigned int total_out_lo32; - unsigned int total_out_hi32; - - void *state; - - void *(*bzalloc)(void *,int,int); - void (*bzfree)(void *,void *); - void *opaque; - } - bz_stream; - - -#ifndef BZ_IMPORT -#define BZ_EXPORT -#endif - -#ifndef BZ_NO_STDIO -/* Need a definitition for FILE */ -#include -#endif - -#ifdef _WIN32 -# include -# ifdef small - /* windows.h define small to char */ -# undef small -# endif -# ifdef BZ_EXPORT -# define BZ_API(func) WINAPI func -# define BZ_EXTERN extern -# else - /* import windows dll dynamically */ -# define BZ_API(func) (WINAPI * func) -# define BZ_EXTERN -# endif -#else -# define BZ_API(func) func -# define BZ_EXTERN extern -#endif - - -/*-- Core (low-level) library functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzCompressInit) ( - bz_stream* strm, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompress) ( - bz_stream* strm, - int action - ); - -BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) ( - bz_stream *strm, - int verbosity, - int small - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompress) ( - bz_stream* strm - ); - -BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) ( - bz_stream *strm - ); - - - -/*-- High(er) level library functions --*/ - -#ifndef BZ_NO_STDIO -#define BZ_MAX_UNUSED 5000 - -typedef void BZFILE; - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) ( - int* bzerror, - FILE* f, - int verbosity, - int small, - void* unused, - int nUnused - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadClose) ( - int* bzerror, - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) ( - int* bzerror, - BZFILE* b, - void** unused, - int* nUnused - ); - -BZ_EXTERN int BZ_API(BZ2_bzRead) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) ( - int* bzerror, - FILE* f, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN void BZ_API(BZ2_bzWrite) ( - int* bzerror, - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in, - unsigned int* nbytes_out - ); - -BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) ( - int* bzerror, - BZFILE* b, - int abandon, - unsigned int* nbytes_in_lo32, - unsigned int* nbytes_in_hi32, - unsigned int* nbytes_out_lo32, - unsigned int* nbytes_out_hi32 - ); -#endif - - -/*-- Utility functions --*/ - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int blockSize100k, - int verbosity, - int workFactor - ); - -BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) ( - char* dest, - unsigned int* destLen, - char* source, - unsigned int sourceLen, - int small, - int verbosity - ); - - -/*-- - Code contributed by Yoshioka Tsuneo (tsuneo@rr.iij4u.or.jp) - to support better zlib compatibility. - This code is not _officially_ part of libbzip2 (yet); - I haven't tested it, documented it, or considered the - threading-safeness of it. - If this code breaks, please contact both Yoshioka and me. ---*/ - -BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) ( - void - ); - -#ifndef BZ_NO_STDIO -BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) ( - const char *path, - const char *mode - ); - -BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) ( - int fd, - const char *mode - ); - -BZ_EXTERN int BZ_API(BZ2_bzread) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzwrite) ( - BZFILE* b, - void* buf, - int len - ); - -BZ_EXTERN int BZ_API(BZ2_bzflush) ( - BZFILE* b - ); - -BZ_EXTERN void BZ_API(BZ2_bzclose) ( - BZFILE* b - ); - -BZ_EXTERN const char * BZ_API(BZ2_bzerror) ( - BZFILE *b, - int *errnum - ); -#endif - -#ifdef __cplusplus -} -#endif - -#endif - -/*-------------------------------------------------------------*/ -/*--- end bzlib.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/bzlib_private.h b/game/client/third/minizip/lib/bzip2/bzlib_private.h deleted file mode 100755 index 5d0217f4..00000000 --- a/game/client/third/minizip/lib/bzip2/bzlib_private.h +++ /dev/null @@ -1,509 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Private header file for the library. ---*/ -/*--- bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#ifndef _BZLIB_PRIVATE_H -#define _BZLIB_PRIVATE_H - -#include - -#ifndef BZ_NO_STDIO -#include -#include -#include -#endif - -#include "bzlib.h" - - - -/*-- General stuff. --*/ - -#define BZ_VERSION "1.0.6, 6-Sept-2010" - -typedef char Char; -typedef unsigned char Bool; -typedef unsigned char UChar; -typedef int Int32; -typedef unsigned int UInt32; -typedef short Int16; -typedef unsigned short UInt16; - -#define True ((Bool)1) -#define False ((Bool)0) - -#ifndef __GNUC__ -#define __inline__ /* */ -#endif - -#ifndef BZ_NO_STDIO - -extern void BZ2_bz__AssertH__fail ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) BZ2_bz__AssertH__fail ( errcode ); } - -#if BZ_DEBUG -#define AssertD(cond,msg) \ - { if (!(cond)) { \ - fprintf ( stderr, \ - "\n\nlibbzip2(debug build): internal error\n\t%s\n", msg );\ - exit(1); \ - }} -#else -#define AssertD(cond,msg) /* */ -#endif - -#define VPrintf0(zf) \ - fprintf(stderr,zf) -#define VPrintf1(zf,za1) \ - fprintf(stderr,zf,za1) -#define VPrintf2(zf,za1,za2) \ - fprintf(stderr,zf,za1,za2) -#define VPrintf3(zf,za1,za2,za3) \ - fprintf(stderr,zf,za1,za2,za3) -#define VPrintf4(zf,za1,za2,za3,za4) \ - fprintf(stderr,zf,za1,za2,za3,za4) -#define VPrintf5(zf,za1,za2,za3,za4,za5) \ - fprintf(stderr,zf,za1,za2,za3,za4,za5) - -#else - -extern void bz_internal_error ( int errcode ); -#define AssertH(cond,errcode) \ - { if (!(cond)) bz_internal_error ( errcode ); } -#define AssertD(cond,msg) do { } while (0) -#define VPrintf0(zf) do { } while (0) -#define VPrintf1(zf,za1) do { } while (0) -#define VPrintf2(zf,za1,za2) do { } while (0) -#define VPrintf3(zf,za1,za2,za3) do { } while (0) -#define VPrintf4(zf,za1,za2,za3,za4) do { } while (0) -#define VPrintf5(zf,za1,za2,za3,za4,za5) do { } while (0) - -#endif - - -#define BZALLOC(nnn) (strm->bzalloc)(strm->opaque,(nnn),1) -#define BZFREE(ppp) (strm->bzfree)(strm->opaque,(ppp)) - - -/*-- Header bytes. --*/ - -#define BZ_HDR_B 0x42 /* 'B' */ -#define BZ_HDR_Z 0x5a /* 'Z' */ -#define BZ_HDR_h 0x68 /* 'h' */ -#define BZ_HDR_0 0x30 /* '0' */ - -/*-- Constants for the back end. --*/ - -#define BZ_MAX_ALPHA_SIZE 258 -#define BZ_MAX_CODE_LEN 23 - -#define BZ_RUNA 0 -#define BZ_RUNB 1 - -#define BZ_N_GROUPS 6 -#define BZ_G_SIZE 50 -#define BZ_N_ITERS 4 - -#define BZ_MAX_SELECTORS (2 + (900000 / BZ_G_SIZE)) - - - -/*-- Stuff for randomising repetitive blocks. --*/ - -extern Int32 BZ2_rNums[512]; - -#define BZ_RAND_DECLS \ - Int32 rNToGo; \ - Int32 rTPos \ - -#define BZ_RAND_INIT_MASK \ - s->rNToGo = 0; \ - s->rTPos = 0 \ - -#define BZ_RAND_MASK ((s->rNToGo == 1) ? 1 : 0) - -#define BZ_RAND_UPD_MASK \ - if (s->rNToGo == 0) { \ - s->rNToGo = BZ2_rNums[s->rTPos]; \ - s->rTPos++; \ - if (s->rTPos == 512) s->rTPos = 0; \ - } \ - s->rNToGo--; - - - -/*-- Stuff for doing CRCs. --*/ - -extern UInt32 BZ2_crc32Table[256]; - -#define BZ_INITIALISE_CRC(crcVar) \ -{ \ - crcVar = 0xffffffffL; \ -} - -#define BZ_FINALISE_CRC(crcVar) \ -{ \ - crcVar = ~(crcVar); \ -} - -#define BZ_UPDATE_CRC(crcVar,cha) \ -{ \ - crcVar = (crcVar << 8) ^ \ - BZ2_crc32Table[(crcVar >> 24) ^ \ - ((UChar)cha)]; \ -} - - - -/*-- States and modes for compression. --*/ - -#define BZ_M_IDLE 1 -#define BZ_M_RUNNING 2 -#define BZ_M_FLUSHING 3 -#define BZ_M_FINISHING 4 - -#define BZ_S_OUTPUT 1 -#define BZ_S_INPUT 2 - -#define BZ_N_RADIX 2 -#define BZ_N_QSORT 12 -#define BZ_N_SHELL 18 -#define BZ_N_OVERSHOOT (BZ_N_RADIX + BZ_N_QSORT + BZ_N_SHELL + 2) - - - - -/*-- Structure holding all the compression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* mode this stream is in, and whether inputting */ - /* or outputting data */ - Int32 mode; - Int32 state; - - /* remembers avail_in when flush/finish requested */ - UInt32 avail_in_expect; - - /* for doing the block sorting */ - UInt32* arr1; - UInt32* arr2; - UInt32* ftab; - Int32 origPtr; - - /* aliases for arr1 and arr2 */ - UInt32* ptr; - UChar* block; - UInt16* mtfv; - UChar* zbits; - - /* for deciding when to use the fallback sorting algorithm */ - Int32 workFactor; - - /* run-length-encoding of the input */ - UInt32 state_in_ch; - Int32 state_in_len; - BZ_RAND_DECLS; - - /* input and output limits and current posns */ - Int32 nblock; - Int32 nblockMAX; - Int32 numZ; - Int32 state_out_pos; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - UChar unseqToSeq[256]; - - /* the buffer for bit stream creation */ - UInt32 bsBuff; - Int32 bsLive; - - /* block and combined CRCs */ - UInt32 blockCRC; - UInt32 combinedCRC; - - /* misc administratium */ - Int32 verbosity; - Int32 blockNo; - Int32 blockSize100k; - - /* stuff for coding the MTF values */ - Int32 nMTF; - Int32 mtfFreq [BZ_MAX_ALPHA_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 code [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - /* second dimension: only 3 needed; 4 makes index calculations faster */ - UInt32 len_pack[BZ_MAX_ALPHA_SIZE][4]; - - } - EState; - - - -/*-- externs for compression. --*/ - -extern void -BZ2_blockSort ( EState* ); - -extern void -BZ2_compressBlock ( EState*, Bool ); - -extern void -BZ2_bsInitWrite ( EState* ); - -extern void -BZ2_hbAssignCodes ( Int32*, UChar*, Int32, Int32, Int32 ); - -extern void -BZ2_hbMakeCodeLengths ( UChar*, Int32*, Int32, Int32 ); - - - -/*-- states for decompression. --*/ - -#define BZ_X_IDLE 1 -#define BZ_X_OUTPUT 2 - -#define BZ_X_MAGIC_1 10 -#define BZ_X_MAGIC_2 11 -#define BZ_X_MAGIC_3 12 -#define BZ_X_MAGIC_4 13 -#define BZ_X_BLKHDR_1 14 -#define BZ_X_BLKHDR_2 15 -#define BZ_X_BLKHDR_3 16 -#define BZ_X_BLKHDR_4 17 -#define BZ_X_BLKHDR_5 18 -#define BZ_X_BLKHDR_6 19 -#define BZ_X_BCRC_1 20 -#define BZ_X_BCRC_2 21 -#define BZ_X_BCRC_3 22 -#define BZ_X_BCRC_4 23 -#define BZ_X_RANDBIT 24 -#define BZ_X_ORIGPTR_1 25 -#define BZ_X_ORIGPTR_2 26 -#define BZ_X_ORIGPTR_3 27 -#define BZ_X_MAPPING_1 28 -#define BZ_X_MAPPING_2 29 -#define BZ_X_SELECTOR_1 30 -#define BZ_X_SELECTOR_2 31 -#define BZ_X_SELECTOR_3 32 -#define BZ_X_CODING_1 33 -#define BZ_X_CODING_2 34 -#define BZ_X_CODING_3 35 -#define BZ_X_MTF_1 36 -#define BZ_X_MTF_2 37 -#define BZ_X_MTF_3 38 -#define BZ_X_MTF_4 39 -#define BZ_X_MTF_5 40 -#define BZ_X_MTF_6 41 -#define BZ_X_ENDHDR_2 42 -#define BZ_X_ENDHDR_3 43 -#define BZ_X_ENDHDR_4 44 -#define BZ_X_ENDHDR_5 45 -#define BZ_X_ENDHDR_6 46 -#define BZ_X_CCRC_1 47 -#define BZ_X_CCRC_2 48 -#define BZ_X_CCRC_3 49 -#define BZ_X_CCRC_4 50 - - - -/*-- Constants for the fast MTF decoder. --*/ - -#define MTFA_SIZE 4096 -#define MTFL_SIZE 16 - - - -/*-- Structure holding all the decompression-side stuff. --*/ - -typedef - struct { - /* pointer back to the struct bz_stream */ - bz_stream* strm; - - /* state indicator for this stream */ - Int32 state; - - /* for doing the final run-length decoding */ - UChar state_out_ch; - Int32 state_out_len; - Bool blockRandomised; - BZ_RAND_DECLS; - - /* the buffer for bit stream reading */ - UInt32 bsBuff; - Int32 bsLive; - - /* misc administratium */ - Int32 blockSize100k; - Bool smallDecompress; - Int32 currBlockNo; - Int32 verbosity; - - /* for undoing the Burrows-Wheeler transform */ - Int32 origPtr; - UInt32 tPos; - Int32 k0; - Int32 unzftab[256]; - Int32 nblock_used; - Int32 cftab[257]; - Int32 cftabCopy[257]; - - /* for undoing the Burrows-Wheeler transform (FAST) */ - UInt32 *tt; - - /* for undoing the Burrows-Wheeler transform (SMALL) */ - UInt16 *ll16; - UChar *ll4; - - /* stored and calculated CRCs */ - UInt32 storedBlockCRC; - UInt32 storedCombinedCRC; - UInt32 calculatedBlockCRC; - UInt32 calculatedCombinedCRC; - - /* map of bytes used in block */ - Int32 nInUse; - Bool inUse[256]; - Bool inUse16[16]; - UChar seqToUnseq[256]; - - /* for decoding the MTF values */ - UChar mtfa [MTFA_SIZE]; - Int32 mtfbase[256 / MTFL_SIZE]; - UChar selector [BZ_MAX_SELECTORS]; - UChar selectorMtf[BZ_MAX_SELECTORS]; - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - - Int32 limit [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 base [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 perm [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 minLens[BZ_N_GROUPS]; - - /* save area for scalars in the main decompress code */ - Int32 save_i; - Int32 save_j; - Int32 save_t; - Int32 save_alphaSize; - Int32 save_nGroups; - Int32 save_nSelectors; - Int32 save_EOB; - Int32 save_groupNo; - Int32 save_groupPos; - Int32 save_nextSym; - Int32 save_nblockMAX; - Int32 save_nblock; - Int32 save_es; - Int32 save_N; - Int32 save_curr; - Int32 save_zt; - Int32 save_zn; - Int32 save_zvec; - Int32 save_zj; - Int32 save_gSel; - Int32 save_gMinlen; - Int32* save_gLimit; - Int32* save_gBase; - Int32* save_gPerm; - - } - DState; - - - -/*-- Macros for decompression. --*/ - -#define BZ_GET_FAST(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - s->tPos = s->tt[s->tPos]; \ - cccc = (UChar)(s->tPos & 0xff); \ - s->tPos >>= 8; - -#define BZ_GET_FAST_C(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (c_tPos >= (UInt32)100000 * (UInt32)ro_blockSize100k) return True; \ - c_tPos = c_tt[c_tPos]; \ - cccc = (UChar)(c_tPos & 0xff); \ - c_tPos >>= 8; - -#define SET_LL4(i,n) \ - { if (((i) & 0x1) == 0) \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0xf0) | (n); else \ - s->ll4[(i) >> 1] = (s->ll4[(i) >> 1] & 0x0f) | ((n) << 4); \ - } - -#define GET_LL4(i) \ - ((((UInt32)(s->ll4[(i) >> 1])) >> (((i) << 2) & 0x4)) & 0xF) - -#define SET_LL(i,n) \ - { s->ll16[i] = (UInt16)(n & 0x0000ffff); \ - SET_LL4(i, n >> 16); \ - } - -#define GET_LL(i) \ - (((UInt32)s->ll16[i]) | (GET_LL4(i) << 16)) - -#define BZ_GET_SMALL(cccc) \ - /* c_tPos is unsigned, hence test < 0 is pointless. */ \ - if (s->tPos >= (UInt32)100000 * (UInt32)s->blockSize100k) return True; \ - cccc = BZ2_indexIntoF ( s->tPos, s->cftab ); \ - s->tPos = GET_LL(s->tPos); - - -/*-- externs for decompression. --*/ - -extern Int32 -BZ2_indexIntoF ( Int32, Int32* ); - -extern Int32 -BZ2_decompress ( DState* ); - -extern void -BZ2_hbCreateDecodeTables ( Int32*, Int32*, Int32*, UChar*, - Int32, Int32, Int32 ); - - -#endif - - -/*-- BZ_NO_STDIO seems to make NULL disappear on some platforms. --*/ - -#ifdef BZ_NO_STDIO -#ifndef NULL -#define NULL 0 -#endif -#endif - - -/*-------------------------------------------------------------*/ -/*--- end bzlib_private.h ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/compress.c b/game/client/third/minizip/lib/bzip2/compress.c deleted file mode 100755 index 62f377b5..00000000 --- a/game/client/third/minizip/lib/bzip2/compress.c +++ /dev/null @@ -1,672 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Compression machinery (not incl block sorting) ---*/ -/*--- compress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -/* CHANGES - 0.9.0 -- original version. - 0.9.0a/b -- no changes in this file. - 0.9.0c -- changed setting of nGroups in sendMTFValues() - so as to do a bit better on small files -*/ - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -/*--- Bit stream I/O ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -void BZ2_bsInitWrite ( EState* s ) -{ - s->bsLive = 0; - s->bsBuff = 0; -} - - -/*---------------------------------------------------*/ -static -void bsFinishWrite ( EState* s ) -{ - while (s->bsLive > 0) { - s->zbits[s->numZ] = (UChar)(s->bsBuff >> 24); - s->numZ++; - s->bsBuff <<= 8; - s->bsLive -= 8; - } -} - - -/*---------------------------------------------------*/ -#define bsNEEDW(nz) \ -{ \ - while (s->bsLive >= 8) { \ - s->zbits[s->numZ] \ - = (UChar)(s->bsBuff >> 24); \ - s->numZ++; \ - s->bsBuff <<= 8; \ - s->bsLive -= 8; \ - } \ -} - - -/*---------------------------------------------------*/ -static -__inline__ -void bsW ( EState* s, Int32 n, UInt32 v ) -{ - bsNEEDW ( n ); - s->bsBuff |= (v << (32 - s->bsLive - n)); - s->bsLive += n; -} - - -/*---------------------------------------------------*/ -static -void bsPutUInt32 ( EState* s, UInt32 u ) -{ - bsW ( s, 8, (u >> 24) & 0xffL ); - bsW ( s, 8, (u >> 16) & 0xffL ); - bsW ( s, 8, (u >> 8) & 0xffL ); - bsW ( s, 8, u & 0xffL ); -} - - -/*---------------------------------------------------*/ -static -void bsPutUChar ( EState* s, UChar c ) -{ - bsW( s, 8, (UInt32)c ); -} - - -/*---------------------------------------------------*/ -/*--- The back end proper ---*/ -/*---------------------------------------------------*/ - -/*---------------------------------------------------*/ -static -void makeMaps_e ( EState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->unseqToSeq[i] = s->nInUse; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -static -void generateMTFValues ( EState* s ) -{ - UChar yy[256]; - Int32 i, j; - Int32 zPend; - Int32 wr; - Int32 EOB; - - /* - After sorting (eg, here), - s->arr1 [ 0 .. s->nblock-1 ] holds sorted order, - and - ((UChar*)s->arr2) [ 0 .. s->nblock-1 ] - holds the original block data. - - The first thing to do is generate the MTF values, - and put them in - ((UInt16*)s->arr1) [ 0 .. s->nblock-1 ]. - Because there are strictly fewer or equal MTF values - than block values, ptr values in this area are overwritten - with MTF values only when they are no longer needed. - - The final compressed bitstream is generated into the - area starting at - (UChar*) (&((UChar*)s->arr2)[s->nblock]) - - These storage aliases are set up in bzCompressInit(), - except for the last one, which is arranged in - compressBlock(). - */ - UInt32* ptr = s->ptr; - UChar* block = s->block; - UInt16* mtfv = s->mtfv; - - makeMaps_e ( s ); - EOB = s->nInUse+1; - - for (i = 0; i <= EOB; i++) s->mtfFreq[i] = 0; - - wr = 0; - zPend = 0; - for (i = 0; i < s->nInUse; i++) yy[i] = (UChar) i; - - for (i = 0; i < s->nblock; i++) { - UChar ll_i; - AssertD ( wr <= i, "generateMTFValues(1)" ); - j = ptr[i]-1; if (j < 0) j += s->nblock; - ll_i = s->unseqToSeq[block[j]]; - AssertD ( ll_i < s->nInUse, "generateMTFValues(2a)" ); - - if (yy[0] == ll_i) { - zPend++; - } else { - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - { - register UChar rtmp; - register UChar* ryy_j; - register UChar rll_i; - rtmp = yy[1]; - yy[1] = yy[0]; - ryy_j = &(yy[1]); - rll_i = ll_i; - while ( rll_i != rtmp ) { - register UChar rtmp2; - ryy_j++; - rtmp2 = rtmp; - rtmp = *ryy_j; - *ryy_j = rtmp2; - }; - yy[0] = rtmp; - j = ryy_j - &(yy[0]); - mtfv[wr] = j+1; wr++; s->mtfFreq[j+1]++; - } - - } - } - - if (zPend > 0) { - zPend--; - while (True) { - if (zPend & 1) { - mtfv[wr] = BZ_RUNB; wr++; - s->mtfFreq[BZ_RUNB]++; - } else { - mtfv[wr] = BZ_RUNA; wr++; - s->mtfFreq[BZ_RUNA]++; - } - if (zPend < 2) break; - zPend = (zPend - 2) / 2; - }; - zPend = 0; - } - - mtfv[wr] = EOB; wr++; s->mtfFreq[EOB]++; - - s->nMTF = wr; -} - - -/*---------------------------------------------------*/ -#define BZ_LESSER_ICOST 0 -#define BZ_GREATER_ICOST 15 - -static -void sendMTFValues ( EState* s ) -{ - Int32 v, t, i, j, gs, ge, totc, bt, bc, iter; - Int32 nSelectors, alphaSize, minLen, maxLen, selCtr; - Int32 nGroups, nBytes; - - /*-- - UChar len [BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - is a global since the decoder also needs it. - - Int32 code[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - Int32 rfreq[BZ_N_GROUPS][BZ_MAX_ALPHA_SIZE]; - are also globals only used in this proc. - Made global to keep stack frame size small. - --*/ - - - UInt16 cost[BZ_N_GROUPS]; - Int32 fave[BZ_N_GROUPS]; - - UInt16* mtfv = s->mtfv; - - if (s->verbosity >= 3) - VPrintf3( " %d in block, %d after MTF & 1-2 coding, " - "%d+2 syms in use\n", - s->nblock, s->nMTF, s->nInUse ); - - alphaSize = s->nInUse+2; - for (t = 0; t < BZ_N_GROUPS; t++) - for (v = 0; v < alphaSize; v++) - s->len[t][v] = BZ_GREATER_ICOST; - - /*--- Decide how many coding tables to use ---*/ - AssertH ( s->nMTF > 0, 3001 ); - if (s->nMTF < 200) nGroups = 2; else - if (s->nMTF < 600) nGroups = 3; else - if (s->nMTF < 1200) nGroups = 4; else - if (s->nMTF < 2400) nGroups = 5; else - nGroups = 6; - - /*--- Generate an initial set of coding tables ---*/ - { - Int32 nPart, remF, tFreq, aFreq; - - nPart = nGroups; - remF = s->nMTF; - gs = 0; - while (nPart > 0) { - tFreq = remF / nPart; - ge = gs-1; - aFreq = 0; - while (aFreq < tFreq && ge < alphaSize-1) { - ge++; - aFreq += s->mtfFreq[ge]; - } - - if (ge > gs - && nPart != nGroups && nPart != 1 - && ((nGroups-nPart) % 2 == 1)) { - aFreq -= s->mtfFreq[ge]; - ge--; - } - - if (s->verbosity >= 3) - VPrintf5( " initial group %d, [%d .. %d], " - "has %d syms (%4.1f%%)\n", - nPart, gs, ge, aFreq, - (100.0 * (float)aFreq) / (float)(s->nMTF) ); - - for (v = 0; v < alphaSize; v++) - if (v >= gs && v <= ge) - s->len[nPart-1][v] = BZ_LESSER_ICOST; else - s->len[nPart-1][v] = BZ_GREATER_ICOST; - - nPart--; - gs = ge+1; - remF -= aFreq; - } - } - - /*--- - Iterate up to BZ_N_ITERS times to improve the tables. - ---*/ - for (iter = 0; iter < BZ_N_ITERS; iter++) { - - for (t = 0; t < nGroups; t++) fave[t] = 0; - - for (t = 0; t < nGroups; t++) - for (v = 0; v < alphaSize; v++) - s->rfreq[t][v] = 0; - - /*--- - Set up an auxiliary length table which is used to fast-track - the common case (nGroups == 6). - ---*/ - if (nGroups == 6) { - for (v = 0; v < alphaSize; v++) { - s->len_pack[v][0] = (s->len[1][v] << 16) | s->len[0][v]; - s->len_pack[v][1] = (s->len[3][v] << 16) | s->len[2][v]; - s->len_pack[v][2] = (s->len[5][v] << 16) | s->len[4][v]; - } - } - - nSelectors = 0; - totc = 0; - gs = 0; - while (True) { - - /*--- Set group start & end marks. --*/ - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - - /*-- - Calculate the cost of this group as coded - by each of the coding tables. - --*/ - for (t = 0; t < nGroups; t++) cost[t] = 0; - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - register UInt32 cost01, cost23, cost45; - register UInt16 icv; - cost01 = cost23 = cost45 = 0; - -# define BZ_ITER(nn) \ - icv = mtfv[gs+(nn)]; \ - cost01 += s->len_pack[icv][0]; \ - cost23 += s->len_pack[icv][1]; \ - cost45 += s->len_pack[icv][2]; \ - - BZ_ITER(0); BZ_ITER(1); BZ_ITER(2); BZ_ITER(3); BZ_ITER(4); - BZ_ITER(5); BZ_ITER(6); BZ_ITER(7); BZ_ITER(8); BZ_ITER(9); - BZ_ITER(10); BZ_ITER(11); BZ_ITER(12); BZ_ITER(13); BZ_ITER(14); - BZ_ITER(15); BZ_ITER(16); BZ_ITER(17); BZ_ITER(18); BZ_ITER(19); - BZ_ITER(20); BZ_ITER(21); BZ_ITER(22); BZ_ITER(23); BZ_ITER(24); - BZ_ITER(25); BZ_ITER(26); BZ_ITER(27); BZ_ITER(28); BZ_ITER(29); - BZ_ITER(30); BZ_ITER(31); BZ_ITER(32); BZ_ITER(33); BZ_ITER(34); - BZ_ITER(35); BZ_ITER(36); BZ_ITER(37); BZ_ITER(38); BZ_ITER(39); - BZ_ITER(40); BZ_ITER(41); BZ_ITER(42); BZ_ITER(43); BZ_ITER(44); - BZ_ITER(45); BZ_ITER(46); BZ_ITER(47); BZ_ITER(48); BZ_ITER(49); - -# undef BZ_ITER - - cost[0] = cost01 & 0xffff; cost[1] = cost01 >> 16; - cost[2] = cost23 & 0xffff; cost[3] = cost23 >> 16; - cost[4] = cost45 & 0xffff; cost[5] = cost45 >> 16; - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - UInt16 icv = mtfv[i]; - for (t = 0; t < nGroups; t++) cost[t] += s->len[t][icv]; - } - } - - /*-- - Find the coding table which is best for this group, - and record its identity in the selector table. - --*/ - bc = 999999999; bt = -1; - for (t = 0; t < nGroups; t++) - if (cost[t] < bc) { bc = cost[t]; bt = t; }; - totc += bc; - fave[bt]++; - s->selector[nSelectors] = bt; - nSelectors++; - - /*-- - Increment the symbol frequencies for the selected table. - --*/ - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - -# define BZ_ITUR(nn) s->rfreq[bt][ mtfv[gs+(nn)] ]++ - - BZ_ITUR(0); BZ_ITUR(1); BZ_ITUR(2); BZ_ITUR(3); BZ_ITUR(4); - BZ_ITUR(5); BZ_ITUR(6); BZ_ITUR(7); BZ_ITUR(8); BZ_ITUR(9); - BZ_ITUR(10); BZ_ITUR(11); BZ_ITUR(12); BZ_ITUR(13); BZ_ITUR(14); - BZ_ITUR(15); BZ_ITUR(16); BZ_ITUR(17); BZ_ITUR(18); BZ_ITUR(19); - BZ_ITUR(20); BZ_ITUR(21); BZ_ITUR(22); BZ_ITUR(23); BZ_ITUR(24); - BZ_ITUR(25); BZ_ITUR(26); BZ_ITUR(27); BZ_ITUR(28); BZ_ITUR(29); - BZ_ITUR(30); BZ_ITUR(31); BZ_ITUR(32); BZ_ITUR(33); BZ_ITUR(34); - BZ_ITUR(35); BZ_ITUR(36); BZ_ITUR(37); BZ_ITUR(38); BZ_ITUR(39); - BZ_ITUR(40); BZ_ITUR(41); BZ_ITUR(42); BZ_ITUR(43); BZ_ITUR(44); - BZ_ITUR(45); BZ_ITUR(46); BZ_ITUR(47); BZ_ITUR(48); BZ_ITUR(49); - -# undef BZ_ITUR - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) - s->rfreq[bt][ mtfv[i] ]++; - } - - gs = ge+1; - } - if (s->verbosity >= 3) { - VPrintf2 ( " pass %d: size is %d, grp uses are ", - iter+1, totc/8 ); - for (t = 0; t < nGroups; t++) - VPrintf1 ( "%d ", fave[t] ); - VPrintf0 ( "\n" ); - } - - /*-- - Recompute the tables based on the accumulated frequencies. - --*/ - /* maxLen was changed from 20 to 17 in bzip2-1.0.3. See - comment in huffman.c for details. */ - for (t = 0; t < nGroups; t++) - BZ2_hbMakeCodeLengths ( &(s->len[t][0]), &(s->rfreq[t][0]), - alphaSize, 17 /*20*/ ); - } - - - AssertH( nGroups < 8, 3002 ); - AssertH( nSelectors < 32768 && - nSelectors <= (2 + (900000 / BZ_G_SIZE)), - 3003 ); - - - /*--- Compute MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], ll_i, tmp2, tmp; - for (i = 0; i < nGroups; i++) pos[i] = i; - for (i = 0; i < nSelectors; i++) { - ll_i = s->selector[i]; - j = 0; - tmp = pos[j]; - while ( ll_i != tmp ) { - j++; - tmp2 = tmp; - tmp = pos[j]; - pos[j] = tmp2; - }; - pos[0] = tmp; - s->selectorMtf[i] = j; - } - }; - - /*--- Assign actual codes for the tables. --*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - AssertH ( !(maxLen > 17 /*20*/ ), 3004 ); - AssertH ( !(minLen < 1), 3005 ); - BZ2_hbAssignCodes ( &(s->code[t][0]), &(s->len[t][0]), - minLen, maxLen, alphaSize ); - } - - /*--- Transmit the mapping table. ---*/ - { - Bool inUse16[16]; - for (i = 0; i < 16; i++) { - inUse16[i] = False; - for (j = 0; j < 16; j++) - if (s->inUse[i * 16 + j]) inUse16[i] = True; - } - - nBytes = s->numZ; - for (i = 0; i < 16; i++) - if (inUse16[i]) bsW(s,1,1); else bsW(s,1,0); - - for (i = 0; i < 16; i++) - if (inUse16[i]) - for (j = 0; j < 16; j++) { - if (s->inUse[i * 16 + j]) bsW(s,1,1); else bsW(s,1,0); - } - - if (s->verbosity >= 3) - VPrintf1( " bytes: mapping %d, ", s->numZ-nBytes ); - } - - /*--- Now the selectors. ---*/ - nBytes = s->numZ; - bsW ( s, 3, nGroups ); - bsW ( s, 15, nSelectors ); - for (i = 0; i < nSelectors; i++) { - for (j = 0; j < s->selectorMtf[i]; j++) bsW(s,1,1); - bsW(s,1,0); - } - if (s->verbosity >= 3) - VPrintf1( "selectors %d, ", s->numZ-nBytes ); - - /*--- Now the coding tables. ---*/ - nBytes = s->numZ; - - for (t = 0; t < nGroups; t++) { - Int32 curr = s->len[t][0]; - bsW ( s, 5, curr ); - for (i = 0; i < alphaSize; i++) { - while (curr < s->len[t][i]) { bsW(s,2,2); curr++; /* 10 */ }; - while (curr > s->len[t][i]) { bsW(s,2,3); curr--; /* 11 */ }; - bsW ( s, 1, 0 ); - } - } - - if (s->verbosity >= 3) - VPrintf1 ( "code lengths %d, ", s->numZ-nBytes ); - - /*--- And finally, the block data proper ---*/ - nBytes = s->numZ; - selCtr = 0; - gs = 0; - while (True) { - if (gs >= s->nMTF) break; - ge = gs + BZ_G_SIZE - 1; - if (ge >= s->nMTF) ge = s->nMTF-1; - AssertH ( s->selector[selCtr] < nGroups, 3006 ); - - if (nGroups == 6 && 50 == ge-gs+1) { - /*--- fast track the common case ---*/ - UInt16 mtfv_i; - UChar* s_len_sel_selCtr - = &(s->len[s->selector[selCtr]][0]); - Int32* s_code_sel_selCtr - = &(s->code[s->selector[selCtr]][0]); - -# define BZ_ITAH(nn) \ - mtfv_i = mtfv[gs+(nn)]; \ - bsW ( s, \ - s_len_sel_selCtr[mtfv_i], \ - s_code_sel_selCtr[mtfv_i] ) - - BZ_ITAH(0); BZ_ITAH(1); BZ_ITAH(2); BZ_ITAH(3); BZ_ITAH(4); - BZ_ITAH(5); BZ_ITAH(6); BZ_ITAH(7); BZ_ITAH(8); BZ_ITAH(9); - BZ_ITAH(10); BZ_ITAH(11); BZ_ITAH(12); BZ_ITAH(13); BZ_ITAH(14); - BZ_ITAH(15); BZ_ITAH(16); BZ_ITAH(17); BZ_ITAH(18); BZ_ITAH(19); - BZ_ITAH(20); BZ_ITAH(21); BZ_ITAH(22); BZ_ITAH(23); BZ_ITAH(24); - BZ_ITAH(25); BZ_ITAH(26); BZ_ITAH(27); BZ_ITAH(28); BZ_ITAH(29); - BZ_ITAH(30); BZ_ITAH(31); BZ_ITAH(32); BZ_ITAH(33); BZ_ITAH(34); - BZ_ITAH(35); BZ_ITAH(36); BZ_ITAH(37); BZ_ITAH(38); BZ_ITAH(39); - BZ_ITAH(40); BZ_ITAH(41); BZ_ITAH(42); BZ_ITAH(43); BZ_ITAH(44); - BZ_ITAH(45); BZ_ITAH(46); BZ_ITAH(47); BZ_ITAH(48); BZ_ITAH(49); - -# undef BZ_ITAH - - } else { - /*--- slow version which correctly handles all situations ---*/ - for (i = gs; i <= ge; i++) { - bsW ( s, - s->len [s->selector[selCtr]] [mtfv[i]], - s->code [s->selector[selCtr]] [mtfv[i]] ); - } - } - - - gs = ge+1; - selCtr++; - } - AssertH( selCtr == nSelectors, 3007 ); - - if (s->verbosity >= 3) - VPrintf1( "codes %d\n", s->numZ-nBytes ); -} - - -/*---------------------------------------------------*/ -extern void BZ2_compressBlock ( EState* s, Bool is_last_block ) -{ - if (s->nblock > 0) { - - BZ_FINALISE_CRC ( s->blockCRC ); - s->combinedCRC = (s->combinedCRC << 1) | (s->combinedCRC >> 31); - s->combinedCRC ^= s->blockCRC; - if (s->blockNo > 1) s->numZ = 0; - - if (s->verbosity >= 2) - VPrintf4( " block %d: crc = 0x%08x, " - "combined CRC = 0x%08x, size = %d\n", - s->blockNo, s->blockCRC, s->combinedCRC, s->nblock ); - - BZ2_blockSort ( s ); - } - - s->zbits = (UChar*) (&((UChar*)s->arr2)[s->nblock]); - - /*-- If this is the first block, create the stream header. --*/ - if (s->blockNo == 1) { - BZ2_bsInitWrite ( s ); - bsPutUChar ( s, BZ_HDR_B ); - bsPutUChar ( s, BZ_HDR_Z ); - bsPutUChar ( s, BZ_HDR_h ); - bsPutUChar ( s, (UChar)(BZ_HDR_0 + s->blockSize100k) ); - } - - if (s->nblock > 0) { - - bsPutUChar ( s, 0x31 ); bsPutUChar ( s, 0x41 ); - bsPutUChar ( s, 0x59 ); bsPutUChar ( s, 0x26 ); - bsPutUChar ( s, 0x53 ); bsPutUChar ( s, 0x59 ); - - /*-- Now the block's CRC, so it is in a known place. --*/ - bsPutUInt32 ( s, s->blockCRC ); - - /*-- - Now a single bit indicating (non-)randomisation. - As of version 0.9.5, we use a better sorting algorithm - which makes randomisation unnecessary. So always set - the randomised bit to 'no'. Of course, the decoder - still needs to be able to handle randomised blocks - so as to maintain backwards compatibility with - older versions of bzip2. - --*/ - bsW(s,1,0); - - bsW ( s, 24, s->origPtr ); - generateMTFValues ( s ); - sendMTFValues ( s ); - } - - - /*-- If this is the last block, add the stream trailer. --*/ - if (is_last_block) { - - bsPutUChar ( s, 0x17 ); bsPutUChar ( s, 0x72 ); - bsPutUChar ( s, 0x45 ); bsPutUChar ( s, 0x38 ); - bsPutUChar ( s, 0x50 ); bsPutUChar ( s, 0x90 ); - bsPutUInt32 ( s, s->combinedCRC ); - if (s->verbosity >= 2) - VPrintf1( " final combined CRC = 0x%08x\n ", s->combinedCRC ); - bsFinishWrite ( s ); - } -} - - -/*-------------------------------------------------------------*/ -/*--- end compress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/crctable.c b/game/client/third/minizip/lib/bzip2/crctable.c deleted file mode 100755 index 1fea7e94..00000000 --- a/game/client/third/minizip/lib/bzip2/crctable.c +++ /dev/null @@ -1,104 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for doing CRCs ---*/ -/*--- crctable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*-- - I think this is an implementation of the AUTODIN-II, - Ethernet & FDDI 32-bit CRC standard. Vaguely derived - from code by Rob Warnock, in Section 51 of the - comp.compression FAQ. ---*/ - -UInt32 BZ2_crc32Table[256] = { - - /*-- Ugly, innit? --*/ - - 0x00000000L, 0x04c11db7L, 0x09823b6eL, 0x0d4326d9L, - 0x130476dcL, 0x17c56b6bL, 0x1a864db2L, 0x1e475005L, - 0x2608edb8L, 0x22c9f00fL, 0x2f8ad6d6L, 0x2b4bcb61L, - 0x350c9b64L, 0x31cd86d3L, 0x3c8ea00aL, 0x384fbdbdL, - 0x4c11db70L, 0x48d0c6c7L, 0x4593e01eL, 0x4152fda9L, - 0x5f15adacL, 0x5bd4b01bL, 0x569796c2L, 0x52568b75L, - 0x6a1936c8L, 0x6ed82b7fL, 0x639b0da6L, 0x675a1011L, - 0x791d4014L, 0x7ddc5da3L, 0x709f7b7aL, 0x745e66cdL, - 0x9823b6e0L, 0x9ce2ab57L, 0x91a18d8eL, 0x95609039L, - 0x8b27c03cL, 0x8fe6dd8bL, 0x82a5fb52L, 0x8664e6e5L, - 0xbe2b5b58L, 0xbaea46efL, 0xb7a96036L, 0xb3687d81L, - 0xad2f2d84L, 0xa9ee3033L, 0xa4ad16eaL, 0xa06c0b5dL, - 0xd4326d90L, 0xd0f37027L, 0xddb056feL, 0xd9714b49L, - 0xc7361b4cL, 0xc3f706fbL, 0xceb42022L, 0xca753d95L, - 0xf23a8028L, 0xf6fb9d9fL, 0xfbb8bb46L, 0xff79a6f1L, - 0xe13ef6f4L, 0xe5ffeb43L, 0xe8bccd9aL, 0xec7dd02dL, - 0x34867077L, 0x30476dc0L, 0x3d044b19L, 0x39c556aeL, - 0x278206abL, 0x23431b1cL, 0x2e003dc5L, 0x2ac12072L, - 0x128e9dcfL, 0x164f8078L, 0x1b0ca6a1L, 0x1fcdbb16L, - 0x018aeb13L, 0x054bf6a4L, 0x0808d07dL, 0x0cc9cdcaL, - 0x7897ab07L, 0x7c56b6b0L, 0x71159069L, 0x75d48ddeL, - 0x6b93dddbL, 0x6f52c06cL, 0x6211e6b5L, 0x66d0fb02L, - 0x5e9f46bfL, 0x5a5e5b08L, 0x571d7dd1L, 0x53dc6066L, - 0x4d9b3063L, 0x495a2dd4L, 0x44190b0dL, 0x40d816baL, - 0xaca5c697L, 0xa864db20L, 0xa527fdf9L, 0xa1e6e04eL, - 0xbfa1b04bL, 0xbb60adfcL, 0xb6238b25L, 0xb2e29692L, - 0x8aad2b2fL, 0x8e6c3698L, 0x832f1041L, 0x87ee0df6L, - 0x99a95df3L, 0x9d684044L, 0x902b669dL, 0x94ea7b2aL, - 0xe0b41de7L, 0xe4750050L, 0xe9362689L, 0xedf73b3eL, - 0xf3b06b3bL, 0xf771768cL, 0xfa325055L, 0xfef34de2L, - 0xc6bcf05fL, 0xc27dede8L, 0xcf3ecb31L, 0xcbffd686L, - 0xd5b88683L, 0xd1799b34L, 0xdc3abdedL, 0xd8fba05aL, - 0x690ce0eeL, 0x6dcdfd59L, 0x608edb80L, 0x644fc637L, - 0x7a089632L, 0x7ec98b85L, 0x738aad5cL, 0x774bb0ebL, - 0x4f040d56L, 0x4bc510e1L, 0x46863638L, 0x42472b8fL, - 0x5c007b8aL, 0x58c1663dL, 0x558240e4L, 0x51435d53L, - 0x251d3b9eL, 0x21dc2629L, 0x2c9f00f0L, 0x285e1d47L, - 0x36194d42L, 0x32d850f5L, 0x3f9b762cL, 0x3b5a6b9bL, - 0x0315d626L, 0x07d4cb91L, 0x0a97ed48L, 0x0e56f0ffL, - 0x1011a0faL, 0x14d0bd4dL, 0x19939b94L, 0x1d528623L, - 0xf12f560eL, 0xf5ee4bb9L, 0xf8ad6d60L, 0xfc6c70d7L, - 0xe22b20d2L, 0xe6ea3d65L, 0xeba91bbcL, 0xef68060bL, - 0xd727bbb6L, 0xd3e6a601L, 0xdea580d8L, 0xda649d6fL, - 0xc423cd6aL, 0xc0e2d0ddL, 0xcda1f604L, 0xc960ebb3L, - 0xbd3e8d7eL, 0xb9ff90c9L, 0xb4bcb610L, 0xb07daba7L, - 0xae3afba2L, 0xaafbe615L, 0xa7b8c0ccL, 0xa379dd7bL, - 0x9b3660c6L, 0x9ff77d71L, 0x92b45ba8L, 0x9675461fL, - 0x8832161aL, 0x8cf30badL, 0x81b02d74L, 0x857130c3L, - 0x5d8a9099L, 0x594b8d2eL, 0x5408abf7L, 0x50c9b640L, - 0x4e8ee645L, 0x4a4ffbf2L, 0x470cdd2bL, 0x43cdc09cL, - 0x7b827d21L, 0x7f436096L, 0x7200464fL, 0x76c15bf8L, - 0x68860bfdL, 0x6c47164aL, 0x61043093L, 0x65c52d24L, - 0x119b4be9L, 0x155a565eL, 0x18197087L, 0x1cd86d30L, - 0x029f3d35L, 0x065e2082L, 0x0b1d065bL, 0x0fdc1becL, - 0x3793a651L, 0x3352bbe6L, 0x3e119d3fL, 0x3ad08088L, - 0x2497d08dL, 0x2056cd3aL, 0x2d15ebe3L, 0x29d4f654L, - 0xc5a92679L, 0xc1683bceL, 0xcc2b1d17L, 0xc8ea00a0L, - 0xd6ad50a5L, 0xd26c4d12L, 0xdf2f6bcbL, 0xdbee767cL, - 0xe3a1cbc1L, 0xe760d676L, 0xea23f0afL, 0xeee2ed18L, - 0xf0a5bd1dL, 0xf464a0aaL, 0xf9278673L, 0xfde69bc4L, - 0x89b8fd09L, 0x8d79e0beL, 0x803ac667L, 0x84fbdbd0L, - 0x9abc8bd5L, 0x9e7d9662L, 0x933eb0bbL, 0x97ffad0cL, - 0xafb010b1L, 0xab710d06L, 0xa6322bdfL, 0xa2f33668L, - 0xbcb4666dL, 0xb8757bdaL, 0xb5365d03L, 0xb1f740b4L -}; - - -/*-------------------------------------------------------------*/ -/*--- end crctable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/decompress.c b/game/client/third/minizip/lib/bzip2/decompress.c deleted file mode 100755 index 311f5668..00000000 --- a/game/client/third/minizip/lib/bzip2/decompress.c +++ /dev/null @@ -1,646 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Decompression machinery ---*/ -/*--- decompress.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------------*/ -static -void makeMaps_d ( DState* s ) -{ - Int32 i; - s->nInUse = 0; - for (i = 0; i < 256; i++) - if (s->inUse[i]) { - s->seqToUnseq[s->nInUse] = i; - s->nInUse++; - } -} - - -/*---------------------------------------------------*/ -#define RETURN(rrr) \ - { retVal = rrr; goto save_state_and_return; }; - -#define GET_BITS(lll,vvv,nnn) \ - case lll: s->state = lll; \ - while (True) { \ - if (s->bsLive >= nnn) { \ - UInt32 v; \ - v = (s->bsBuff >> \ - (s->bsLive-nnn)) & ((1 << nnn)-1); \ - s->bsLive -= nnn; \ - vvv = v; \ - break; \ - } \ - if (s->strm->avail_in == 0) RETURN(BZ_OK); \ - s->bsBuff \ - = (s->bsBuff << 8) | \ - ((UInt32) \ - (*((UChar*)(s->strm->next_in)))); \ - s->bsLive += 8; \ - s->strm->next_in++; \ - s->strm->avail_in--; \ - s->strm->total_in_lo32++; \ - if (s->strm->total_in_lo32 == 0) \ - s->strm->total_in_hi32++; \ - } - -#define GET_UCHAR(lll,uuu) \ - GET_BITS(lll,uuu,8) - -#define GET_BIT(lll,uuu) \ - GET_BITS(lll,uuu,1) - -/*---------------------------------------------------*/ -#define GET_MTF_VAL(label1,label2,lval) \ -{ \ - if (groupPos == 0) { \ - groupNo++; \ - if (groupNo >= nSelectors) \ - RETURN(BZ_DATA_ERROR); \ - groupPos = BZ_G_SIZE; \ - gSel = s->selector[groupNo]; \ - gMinlen = s->minLens[gSel]; \ - gLimit = &(s->limit[gSel][0]); \ - gPerm = &(s->perm[gSel][0]); \ - gBase = &(s->base[gSel][0]); \ - } \ - groupPos--; \ - zn = gMinlen; \ - GET_BITS(label1, zvec, zn); \ - while (1) { \ - if (zn > 20 /* the longest code */) \ - RETURN(BZ_DATA_ERROR); \ - if (zvec <= gLimit[zn]) break; \ - zn++; \ - GET_BIT(label2, zj); \ - zvec = (zvec << 1) | zj; \ - }; \ - if (zvec - gBase[zn] < 0 \ - || zvec - gBase[zn] >= BZ_MAX_ALPHA_SIZE) \ - RETURN(BZ_DATA_ERROR); \ - lval = gPerm[zvec - gBase[zn]]; \ -} - - -/*---------------------------------------------------*/ -Int32 BZ2_decompress ( DState* s ) -{ - UChar uc; - Int32 retVal; - Int32 minLen, maxLen; - bz_stream* strm = s->strm; - - /* stuff that needs to be saved/restored */ - Int32 i; - Int32 j; - Int32 t; - Int32 alphaSize; - Int32 nGroups; - Int32 nSelectors; - Int32 EOB; - Int32 groupNo; - Int32 groupPos; - Int32 nextSym; - Int32 nblockMAX; - Int32 nblock; - Int32 es; - Int32 N; - Int32 curr; - Int32 zt; - Int32 zn; - Int32 zvec; - Int32 zj; - Int32 gSel; - Int32 gMinlen; - Int32* gLimit; - Int32* gBase; - Int32* gPerm; - - if (s->state == BZ_X_MAGIC_1) { - /*initialise the save area*/ - s->save_i = 0; - s->save_j = 0; - s->save_t = 0; - s->save_alphaSize = 0; - s->save_nGroups = 0; - s->save_nSelectors = 0; - s->save_EOB = 0; - s->save_groupNo = 0; - s->save_groupPos = 0; - s->save_nextSym = 0; - s->save_nblockMAX = 0; - s->save_nblock = 0; - s->save_es = 0; - s->save_N = 0; - s->save_curr = 0; - s->save_zt = 0; - s->save_zn = 0; - s->save_zvec = 0; - s->save_zj = 0; - s->save_gSel = 0; - s->save_gMinlen = 0; - s->save_gLimit = NULL; - s->save_gBase = NULL; - s->save_gPerm = NULL; - } - - /*restore from the save area*/ - i = s->save_i; - j = s->save_j; - t = s->save_t; - alphaSize = s->save_alphaSize; - nGroups = s->save_nGroups; - nSelectors = s->save_nSelectors; - EOB = s->save_EOB; - groupNo = s->save_groupNo; - groupPos = s->save_groupPos; - nextSym = s->save_nextSym; - nblockMAX = s->save_nblockMAX; - nblock = s->save_nblock; - es = s->save_es; - N = s->save_N; - curr = s->save_curr; - zt = s->save_zt; - zn = s->save_zn; - zvec = s->save_zvec; - zj = s->save_zj; - gSel = s->save_gSel; - gMinlen = s->save_gMinlen; - gLimit = s->save_gLimit; - gBase = s->save_gBase; - gPerm = s->save_gPerm; - - retVal = BZ_OK; - - switch (s->state) { - - GET_UCHAR(BZ_X_MAGIC_1, uc); - if (uc != BZ_HDR_B) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_2, uc); - if (uc != BZ_HDR_Z) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_UCHAR(BZ_X_MAGIC_3, uc) - if (uc != BZ_HDR_h) RETURN(BZ_DATA_ERROR_MAGIC); - - GET_BITS(BZ_X_MAGIC_4, s->blockSize100k, 8) - if (s->blockSize100k < (BZ_HDR_0 + 1) || - s->blockSize100k > (BZ_HDR_0 + 9)) RETURN(BZ_DATA_ERROR_MAGIC); - s->blockSize100k -= BZ_HDR_0; - - if (s->smallDecompress) { - s->ll16 = BZALLOC( s->blockSize100k * 100000 * sizeof(UInt16) ); - s->ll4 = BZALLOC( - ((1 + s->blockSize100k * 100000) >> 1) * sizeof(UChar) - ); - if (s->ll16 == NULL || s->ll4 == NULL) RETURN(BZ_MEM_ERROR); - } else { - s->tt = BZALLOC( s->blockSize100k * 100000 * sizeof(Int32) ); - if (s->tt == NULL) RETURN(BZ_MEM_ERROR); - } - - GET_UCHAR(BZ_X_BLKHDR_1, uc); - - if (uc == 0x17) goto endhdr_2; - if (uc != 0x31) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_2, uc); - if (uc != 0x41) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_3, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_4, uc); - if (uc != 0x26) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_5, uc); - if (uc != 0x53) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_BLKHDR_6, uc); - if (uc != 0x59) RETURN(BZ_DATA_ERROR); - - s->currBlockNo++; - if (s->verbosity >= 2) - VPrintf1 ( "\n [%d: huff+mtf ", s->currBlockNo ); - - s->storedBlockCRC = 0; - GET_UCHAR(BZ_X_BCRC_1, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_2, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_3, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_BCRC_4, uc); - s->storedBlockCRC = (s->storedBlockCRC << 8) | ((UInt32)uc); - - GET_BITS(BZ_X_RANDBIT, s->blockRandomised, 1); - - s->origPtr = 0; - GET_UCHAR(BZ_X_ORIGPTR_1, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_2, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - GET_UCHAR(BZ_X_ORIGPTR_3, uc); - s->origPtr = (s->origPtr << 8) | ((Int32)uc); - - if (s->origPtr < 0) - RETURN(BZ_DATA_ERROR); - if (s->origPtr > 10 + 100000*s->blockSize100k) - RETURN(BZ_DATA_ERROR); - - /*--- Receive the mapping table ---*/ - for (i = 0; i < 16; i++) { - GET_BIT(BZ_X_MAPPING_1, uc); - if (uc == 1) - s->inUse16[i] = True; else - s->inUse16[i] = False; - } - - for (i = 0; i < 256; i++) s->inUse[i] = False; - - for (i = 0; i < 16; i++) - if (s->inUse16[i]) - for (j = 0; j < 16; j++) { - GET_BIT(BZ_X_MAPPING_2, uc); - if (uc == 1) s->inUse[i * 16 + j] = True; - } - makeMaps_d ( s ); - if (s->nInUse == 0) RETURN(BZ_DATA_ERROR); - alphaSize = s->nInUse+2; - - /*--- Now the selectors ---*/ - GET_BITS(BZ_X_SELECTOR_1, nGroups, 3); - if (nGroups < 2 || nGroups > 6) RETURN(BZ_DATA_ERROR); - GET_BITS(BZ_X_SELECTOR_2, nSelectors, 15); - if (nSelectors < 1) RETURN(BZ_DATA_ERROR); - for (i = 0; i < nSelectors; i++) { - j = 0; - while (True) { - GET_BIT(BZ_X_SELECTOR_3, uc); - if (uc == 0) break; - j++; - if (j >= nGroups) RETURN(BZ_DATA_ERROR); - } - s->selectorMtf[i] = j; - } - - /*--- Undo the MTF values for the selectors. ---*/ - { - UChar pos[BZ_N_GROUPS], tmp, v; - for (v = 0; v < nGroups; v++) pos[v] = v; - - for (i = 0; i < nSelectors; i++) { - v = s->selectorMtf[i]; - tmp = pos[v]; - while (v > 0) { pos[v] = pos[v-1]; v--; } - pos[0] = tmp; - s->selector[i] = tmp; - } - } - - /*--- Now the coding tables ---*/ - for (t = 0; t < nGroups; t++) { - GET_BITS(BZ_X_CODING_1, curr, 5); - for (i = 0; i < alphaSize; i++) { - while (True) { - if (curr < 1 || curr > 20) RETURN(BZ_DATA_ERROR); - GET_BIT(BZ_X_CODING_2, uc); - if (uc == 0) break; - GET_BIT(BZ_X_CODING_3, uc); - if (uc == 0) curr++; else curr--; - } - s->len[t][i] = curr; - } - } - - /*--- Create the Huffman decoding tables ---*/ - for (t = 0; t < nGroups; t++) { - minLen = 32; - maxLen = 0; - for (i = 0; i < alphaSize; i++) { - if (s->len[t][i] > maxLen) maxLen = s->len[t][i]; - if (s->len[t][i] < minLen) minLen = s->len[t][i]; - } - BZ2_hbCreateDecodeTables ( - &(s->limit[t][0]), - &(s->base[t][0]), - &(s->perm[t][0]), - &(s->len[t][0]), - minLen, maxLen, alphaSize - ); - s->minLens[t] = minLen; - } - - /*--- Now the MTF values ---*/ - - EOB = s->nInUse+1; - nblockMAX = 100000 * s->blockSize100k; - groupNo = -1; - groupPos = 0; - - for (i = 0; i <= 255; i++) s->unzftab[i] = 0; - - /*-- MTF init --*/ - { - Int32 ii, jj, kk; - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE - 1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = (UChar)(ii * MTFL_SIZE + jj); - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - /*-- end MTF init --*/ - - nblock = 0; - GET_MTF_VAL(BZ_X_MTF_1, BZ_X_MTF_2, nextSym); - - while (True) { - - if (nextSym == EOB) break; - - if (nextSym == BZ_RUNA || nextSym == BZ_RUNB) { - - es = -1; - N = 1; - do { - /* Check that N doesn't get too big, so that es doesn't - go negative. The maximum value that can be - RUNA/RUNB encoded is equal to the block size (post - the initial RLE), viz, 900k, so bounding N at 2 - million should guard against overflow without - rejecting any legitimate inputs. */ - if (N >= 2*1024*1024) RETURN(BZ_DATA_ERROR); - if (nextSym == BZ_RUNA) es = es + (0+1) * N; else - if (nextSym == BZ_RUNB) es = es + (1+1) * N; - N = N * 2; - GET_MTF_VAL(BZ_X_MTF_3, BZ_X_MTF_4, nextSym); - } - while (nextSym == BZ_RUNA || nextSym == BZ_RUNB); - - es++; - uc = s->seqToUnseq[ s->mtfa[s->mtfbase[0]] ]; - s->unzftab[uc] += es; - - if (s->smallDecompress) - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->ll16[nblock] = (UInt16)uc; - nblock++; - es--; - } - else - while (es > 0) { - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - s->tt[nblock] = (UInt32)uc; - nblock++; - es--; - }; - - continue; - - } else { - - if (nblock >= nblockMAX) RETURN(BZ_DATA_ERROR); - - /*-- uc = MTF ( nextSym-1 ) --*/ - { - Int32 ii, jj, kk, pp, lno, off; - UInt32 nn; - nn = (UInt32)(nextSym - 1); - - if (nn < MTFL_SIZE) { - /* avoid general-case expense */ - pp = s->mtfbase[0]; - uc = s->mtfa[pp+nn]; - while (nn > 3) { - Int32 z = pp+nn; - s->mtfa[(z) ] = s->mtfa[(z)-1]; - s->mtfa[(z)-1] = s->mtfa[(z)-2]; - s->mtfa[(z)-2] = s->mtfa[(z)-3]; - s->mtfa[(z)-3] = s->mtfa[(z)-4]; - nn -= 4; - } - while (nn > 0) { - s->mtfa[(pp+nn)] = s->mtfa[(pp+nn)-1]; nn--; - }; - s->mtfa[pp] = uc; - } else { - /* general case */ - lno = nn / MTFL_SIZE; - off = nn % MTFL_SIZE; - pp = s->mtfbase[lno] + off; - uc = s->mtfa[pp]; - while (pp > s->mtfbase[lno]) { - s->mtfa[pp] = s->mtfa[pp-1]; pp--; - }; - s->mtfbase[lno]++; - while (lno > 0) { - s->mtfbase[lno]--; - s->mtfa[s->mtfbase[lno]] - = s->mtfa[s->mtfbase[lno-1] + MTFL_SIZE - 1]; - lno--; - } - s->mtfbase[0]--; - s->mtfa[s->mtfbase[0]] = uc; - if (s->mtfbase[0] == 0) { - kk = MTFA_SIZE-1; - for (ii = 256 / MTFL_SIZE-1; ii >= 0; ii--) { - for (jj = MTFL_SIZE-1; jj >= 0; jj--) { - s->mtfa[kk] = s->mtfa[s->mtfbase[ii] + jj]; - kk--; - } - s->mtfbase[ii] = kk + 1; - } - } - } - } - /*-- end uc = MTF ( nextSym-1 ) --*/ - - s->unzftab[s->seqToUnseq[uc]]++; - if (s->smallDecompress) - s->ll16[nblock] = (UInt16)(s->seqToUnseq[uc]); else - s->tt[nblock] = (UInt32)(s->seqToUnseq[uc]); - nblock++; - - GET_MTF_VAL(BZ_X_MTF_5, BZ_X_MTF_6, nextSym); - continue; - } - } - - /* Now we know what nblock is, we can do a better sanity - check on s->origPtr. - */ - if (s->origPtr < 0 || s->origPtr >= nblock) - RETURN(BZ_DATA_ERROR); - - /*-- Set up cftab to facilitate generation of T^(-1) --*/ - /* Check: unzftab entries in range. */ - for (i = 0; i <= 255; i++) { - if (s->unzftab[i] < 0 || s->unzftab[i] > nblock) - RETURN(BZ_DATA_ERROR); - } - /* Actually generate cftab. */ - s->cftab[0] = 0; - for (i = 1; i <= 256; i++) s->cftab[i] = s->unzftab[i-1]; - for (i = 1; i <= 256; i++) s->cftab[i] += s->cftab[i-1]; - /* Check: cftab entries in range. */ - for (i = 0; i <= 256; i++) { - if (s->cftab[i] < 0 || s->cftab[i] > nblock) { - /* s->cftab[i] can legitimately be == nblock */ - RETURN(BZ_DATA_ERROR); - } - } - /* Check: cftab entries non-descending. */ - for (i = 1; i <= 256; i++) { - if (s->cftab[i-1] > s->cftab[i]) { - RETURN(BZ_DATA_ERROR); - } - } - - s->state_out_len = 0; - s->state_out_ch = 0; - BZ_INITIALISE_CRC ( s->calculatedBlockCRC ); - s->state = BZ_X_OUTPUT; - if (s->verbosity >= 2) VPrintf0 ( "rt+rld" ); - - if (s->smallDecompress) { - - /*-- Make a copy of cftab, used in generation of T --*/ - for (i = 0; i <= 256; i++) s->cftabCopy[i] = s->cftab[i]; - - /*-- compute the T vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->ll16[i]); - SET_LL(i, s->cftabCopy[uc]); - s->cftabCopy[uc]++; - } - - /*-- Compute T^(-1) by pointer reversal on T --*/ - i = s->origPtr; - j = GET_LL(i); - do { - Int32 tmp = GET_LL(j); - SET_LL(j, i); - i = j; - j = tmp; - } - while (i != s->origPtr); - - s->tPos = s->origPtr; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_SMALL(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_SMALL(s->k0); s->nblock_used++; - } - - } else { - - /*-- compute the T^(-1) vector --*/ - for (i = 0; i < nblock; i++) { - uc = (UChar)(s->tt[i] & 0xff); - s->tt[s->cftab[uc]] |= (i << 8); - s->cftab[uc]++; - } - - s->tPos = s->tt[s->origPtr] >> 8; - s->nblock_used = 0; - if (s->blockRandomised) { - BZ_RAND_INIT_MASK; - BZ_GET_FAST(s->k0); s->nblock_used++; - BZ_RAND_UPD_MASK; s->k0 ^= BZ_RAND_MASK; - } else { - BZ_GET_FAST(s->k0); s->nblock_used++; - } - - } - - RETURN(BZ_OK); - - - - endhdr_2: - - GET_UCHAR(BZ_X_ENDHDR_2, uc); - if (uc != 0x72) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_3, uc); - if (uc != 0x45) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_4, uc); - if (uc != 0x38) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_5, uc); - if (uc != 0x50) RETURN(BZ_DATA_ERROR); - GET_UCHAR(BZ_X_ENDHDR_6, uc); - if (uc != 0x90) RETURN(BZ_DATA_ERROR); - - s->storedCombinedCRC = 0; - GET_UCHAR(BZ_X_CCRC_1, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_2, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_3, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - GET_UCHAR(BZ_X_CCRC_4, uc); - s->storedCombinedCRC = (s->storedCombinedCRC << 8) | ((UInt32)uc); - - s->state = BZ_X_IDLE; - RETURN(BZ_STREAM_END); - - default: AssertH ( False, 4001 ); - } - - AssertH ( False, 4002 ); - - save_state_and_return: - - s->save_i = i; - s->save_j = j; - s->save_t = t; - s->save_alphaSize = alphaSize; - s->save_nGroups = nGroups; - s->save_nSelectors = nSelectors; - s->save_EOB = EOB; - s->save_groupNo = groupNo; - s->save_groupPos = groupPos; - s->save_nextSym = nextSym; - s->save_nblockMAX = nblockMAX; - s->save_nblock = nblock; - s->save_es = es; - s->save_N = N; - s->save_curr = curr; - s->save_zt = zt; - s->save_zn = zn; - s->save_zvec = zvec; - s->save_zj = zj; - s->save_gSel = gSel; - s->save_gMinlen = gMinlen; - s->save_gLimit = gLimit; - s->save_gBase = gBase; - s->save_gPerm = gPerm; - - return retVal; -} - - -/*-------------------------------------------------------------*/ -/*--- end decompress.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/huffman.c b/game/client/third/minizip/lib/bzip2/huffman.c deleted file mode 100755 index 2283fdbc..00000000 --- a/game/client/third/minizip/lib/bzip2/huffman.c +++ /dev/null @@ -1,205 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Huffman coding low-level stuff ---*/ -/*--- huffman.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - -/*---------------------------------------------------*/ -#define WEIGHTOF(zz0) ((zz0) & 0xffffff00) -#define DEPTHOF(zz1) ((zz1) & 0x000000ff) -#define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3)) - -#define ADDWEIGHTS(zw1,zw2) \ - (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \ - (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2))) - -#define UPHEAP(z) \ -{ \ - Int32 zz, tmp; \ - zz = z; tmp = heap[zz]; \ - while (weight[tmp] < weight[heap[zz >> 1]]) { \ - heap[zz] = heap[zz >> 1]; \ - zz >>= 1; \ - } \ - heap[zz] = tmp; \ -} - -#define DOWNHEAP(z) \ -{ \ - Int32 zz, yy, tmp; \ - zz = z; tmp = heap[zz]; \ - while (True) { \ - yy = zz << 1; \ - if (yy > nHeap) break; \ - if (yy < nHeap && \ - weight[heap[yy+1]] < weight[heap[yy]]) \ - yy++; \ - if (weight[tmp] < weight[heap[yy]]) break; \ - heap[zz] = heap[yy]; \ - zz = yy; \ - } \ - heap[zz] = tmp; \ -} - - -/*---------------------------------------------------*/ -void BZ2_hbMakeCodeLengths ( UChar *len, - Int32 *freq, - Int32 alphaSize, - Int32 maxLen ) -{ - /*-- - Nodes and heap entries run from 1. Entry 0 - for both the heap and nodes is a sentinel. - --*/ - Int32 nNodes, nHeap, n1, n2, i, j, k; - Bool tooLong; - - Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ]; - Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ]; - Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ]; - - for (i = 0; i < alphaSize; i++) - weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8; - - while (True) { - - nNodes = alphaSize; - nHeap = 0; - - heap[0] = 0; - weight[0] = 0; - parent[0] = -2; - - for (i = 1; i <= alphaSize; i++) { - parent[i] = -1; - nHeap++; - heap[nHeap] = i; - UPHEAP(nHeap); - } - - AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 ); - - while (nHeap > 1) { - n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1); - nNodes++; - parent[n1] = parent[n2] = nNodes; - weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]); - parent[nNodes] = -1; - nHeap++; - heap[nHeap] = nNodes; - UPHEAP(nHeap); - } - - AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 ); - - tooLong = False; - for (i = 1; i <= alphaSize; i++) { - j = 0; - k = i; - while (parent[k] >= 0) { k = parent[k]; j++; } - len[i-1] = j; - if (j > maxLen) tooLong = True; - } - - if (! tooLong) break; - - /* 17 Oct 04: keep-going condition for the following loop used - to be 'i < alphaSize', which missed the last element, - theoretically leading to the possibility of the compressor - looping. However, this count-scaling step is only needed if - one of the generated Huffman code words is longer than - maxLen, which up to and including version 1.0.2 was 20 bits, - which is extremely unlikely. In version 1.0.3 maxLen was - changed to 17 bits, which has minimal effect on compression - ratio, but does mean this scaling step is used from time to - time, enough to verify that it works. - - This means that bzip2-1.0.3 and later will only produce - Huffman codes with a maximum length of 17 bits. However, in - order to preserve backwards compatibility with bitstreams - produced by versions pre-1.0.3, the decompressor must still - handle lengths of up to 20. */ - - for (i = 1; i <= alphaSize; i++) { - j = weight[i] >> 8; - j = 1 + (j / 2); - weight[i] = j << 8; - } - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbAssignCodes ( Int32 *code, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 n, vec, i; - - vec = 0; - for (n = minLen; n <= maxLen; n++) { - for (i = 0; i < alphaSize; i++) - if (length[i] == n) { code[i] = vec; vec++; }; - vec <<= 1; - } -} - - -/*---------------------------------------------------*/ -void BZ2_hbCreateDecodeTables ( Int32 *limit, - Int32 *base, - Int32 *perm, - UChar *length, - Int32 minLen, - Int32 maxLen, - Int32 alphaSize ) -{ - Int32 pp, i, j, vec; - - pp = 0; - for (i = minLen; i <= maxLen; i++) - for (j = 0; j < alphaSize; j++) - if (length[j] == i) { perm[pp] = j; pp++; }; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0; - for (i = 0; i < alphaSize; i++) base[length[i]+1]++; - - for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1]; - - for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0; - vec = 0; - - for (i = minLen; i <= maxLen; i++) { - vec += (base[i+1] - base[i]); - limit[i] = vec-1; - vec <<= 1; - } - for (i = minLen + 1; i <= maxLen; i++) - base[i] = ((limit[i-1] + 1) << 1) - base[i]; -} - - -/*-------------------------------------------------------------*/ -/*--- end huffman.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/bzip2/randtable.c b/game/client/third/minizip/lib/bzip2/randtable.c deleted file mode 100755 index 6d624599..00000000 --- a/game/client/third/minizip/lib/bzip2/randtable.c +++ /dev/null @@ -1,84 +0,0 @@ - -/*-------------------------------------------------------------*/ -/*--- Table for randomising repetitive blocks ---*/ -/*--- randtable.c ---*/ -/*-------------------------------------------------------------*/ - -/* ------------------------------------------------------------------ - This file is part of bzip2/libbzip2, a program and library for - lossless, block-sorting data compression. - - bzip2/libbzip2 version 1.0.6 of 6 September 2010 - Copyright (C) 1996-2010 Julian Seward - - Please read the WARNING, DISCLAIMER and PATENTS sections in the - README file. - - This program is released under the terms of the license contained - in the file LICENSE. - ------------------------------------------------------------------ */ - - -#include "bzlib_private.h" - - -/*---------------------------------------------*/ -Int32 BZ2_rNums[512] = { - 619, 720, 127, 481, 931, 816, 813, 233, 566, 247, - 985, 724, 205, 454, 863, 491, 741, 242, 949, 214, - 733, 859, 335, 708, 621, 574, 73, 654, 730, 472, - 419, 436, 278, 496, 867, 210, 399, 680, 480, 51, - 878, 465, 811, 169, 869, 675, 611, 697, 867, 561, - 862, 687, 507, 283, 482, 129, 807, 591, 733, 623, - 150, 238, 59, 379, 684, 877, 625, 169, 643, 105, - 170, 607, 520, 932, 727, 476, 693, 425, 174, 647, - 73, 122, 335, 530, 442, 853, 695, 249, 445, 515, - 909, 545, 703, 919, 874, 474, 882, 500, 594, 612, - 641, 801, 220, 162, 819, 984, 589, 513, 495, 799, - 161, 604, 958, 533, 221, 400, 386, 867, 600, 782, - 382, 596, 414, 171, 516, 375, 682, 485, 911, 276, - 98, 553, 163, 354, 666, 933, 424, 341, 533, 870, - 227, 730, 475, 186, 263, 647, 537, 686, 600, 224, - 469, 68, 770, 919, 190, 373, 294, 822, 808, 206, - 184, 943, 795, 384, 383, 461, 404, 758, 839, 887, - 715, 67, 618, 276, 204, 918, 873, 777, 604, 560, - 951, 160, 578, 722, 79, 804, 96, 409, 713, 940, - 652, 934, 970, 447, 318, 353, 859, 672, 112, 785, - 645, 863, 803, 350, 139, 93, 354, 99, 820, 908, - 609, 772, 154, 274, 580, 184, 79, 626, 630, 742, - 653, 282, 762, 623, 680, 81, 927, 626, 789, 125, - 411, 521, 938, 300, 821, 78, 343, 175, 128, 250, - 170, 774, 972, 275, 999, 639, 495, 78, 352, 126, - 857, 956, 358, 619, 580, 124, 737, 594, 701, 612, - 669, 112, 134, 694, 363, 992, 809, 743, 168, 974, - 944, 375, 748, 52, 600, 747, 642, 182, 862, 81, - 344, 805, 988, 739, 511, 655, 814, 334, 249, 515, - 897, 955, 664, 981, 649, 113, 974, 459, 893, 228, - 433, 837, 553, 268, 926, 240, 102, 654, 459, 51, - 686, 754, 806, 760, 493, 403, 415, 394, 687, 700, - 946, 670, 656, 610, 738, 392, 760, 799, 887, 653, - 978, 321, 576, 617, 626, 502, 894, 679, 243, 440, - 680, 879, 194, 572, 640, 724, 926, 56, 204, 700, - 707, 151, 457, 449, 797, 195, 791, 558, 945, 679, - 297, 59, 87, 824, 713, 663, 412, 693, 342, 606, - 134, 108, 571, 364, 631, 212, 174, 643, 304, 329, - 343, 97, 430, 751, 497, 314, 983, 374, 822, 928, - 140, 206, 73, 263, 980, 736, 876, 478, 430, 305, - 170, 514, 364, 692, 829, 82, 855, 953, 676, 246, - 369, 970, 294, 750, 807, 827, 150, 790, 288, 923, - 804, 378, 215, 828, 592, 281, 565, 555, 710, 82, - 896, 831, 547, 261, 524, 462, 293, 465, 502, 56, - 661, 821, 976, 991, 658, 869, 905, 758, 745, 193, - 768, 550, 608, 933, 378, 286, 215, 979, 792, 961, - 61, 688, 793, 644, 986, 403, 106, 366, 905, 644, - 372, 567, 466, 434, 645, 210, 389, 550, 919, 135, - 780, 773, 635, 389, 707, 100, 626, 958, 165, 504, - 920, 176, 193, 713, 857, 265, 203, 50, 668, 108, - 645, 990, 626, 197, 510, 357, 358, 850, 858, 364, - 936, 638 -}; - - -/*-------------------------------------------------------------*/ -/*--- end randtable.c ---*/ -/*-------------------------------------------------------------*/ diff --git a/game/client/third/minizip/lib/liblzma/api/lzma.h b/game/client/third/minizip/lib/liblzma/api/lzma.h deleted file mode 100755 index e4fed3d0..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma.h +++ /dev/null @@ -1,321 +0,0 @@ -/** - * \file api/lzma.h - * \brief The public API of liblzma data compression library - * - * liblzma is a public domain general-purpose data compression library with - * a zlib-like API. The native file format is .xz, but also the old .lzma - * format and raw (no headers) streams are supported. Multiple compression - * algorithms (filters) are supported. Currently LZMA2 is the primary filter. - * - * liblzma is part of XZ Utils . XZ Utils includes - * a gzip-like command line tool named xz and some other tools. XZ Utils - * is developed and maintained by Lasse Collin. - * - * Major parts of liblzma are based on Igor Pavlov's public domain LZMA SDK - * . - * - * The SHA-256 implementation is based on the public domain code found from - * 7-Zip , which has a modified version of the public - * domain SHA-256 code found from Crypto++ . - * The SHA-256 code in Crypto++ was written by Kevin Springle and Wei Dai. - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - */ - -#ifndef LZMA_H -#define LZMA_H - -/***************************** - * Required standard headers * - *****************************/ - -/* - * liblzma API headers need some standard types and macros. To allow - * including lzma.h without requiring the application to include other - * headers first, lzma.h includes the required standard headers unless - * they already seem to be included already or if LZMA_MANUAL_HEADERS - * has been defined. - * - * Here's what types and macros are needed and from which headers: - * - stddef.h: size_t, NULL - * - stdint.h: uint8_t, uint32_t, uint64_t, UINT32_C(n), uint64_C(n), - * UINT32_MAX, UINT64_MAX - * - * However, inttypes.h is a little more portable than stdint.h, although - * inttypes.h declares some unneeded things compared to plain stdint.h. - * - * The hacks below aren't perfect, specifically they assume that inttypes.h - * exists and that it typedefs at least uint8_t, uint32_t, and uint64_t, - * and that, in case of incomplete inttypes.h, unsigned int is 32-bit. - * If the application already takes care of setting up all the types and - * macros properly (for example by using gnulib's stdint.h or inttypes.h), - * we try to detect that the macros are already defined and don't include - * inttypes.h here again. However, you may define LZMA_MANUAL_HEADERS to - * force this file to never include any system headers. - * - * Some could argue that liblzma API should provide all the required types, - * for example lzma_uint64, LZMA_UINT64_C(n), and LZMA_UINT64_MAX. This was - * seen as an unnecessary mess, since most systems already provide all the - * necessary types and macros in the standard headers. - * - * Note that liblzma API still has lzma_bool, because using stdbool.h would - * break C89 and C++ programs on many systems. sizeof(bool) in C99 isn't - * necessarily the same as sizeof(bool) in C++. - */ - -#ifndef LZMA_MANUAL_HEADERS - /* - * I suppose this works portably also in C++. Note that in C++, - * we need to get size_t into the global namespace. - */ -# include - - /* - * Skip inttypes.h if we already have all the required macros. If we - * have the macros, we assume that we have the matching typedefs too. - */ -# if !defined(UINT32_C) || !defined(UINT64_C) \ - || !defined(UINT32_MAX) || !defined(UINT64_MAX) - /* - * MSVC versions older than 2013 have no C99 support, and - * thus they cannot be used to compile liblzma. Using an - * existing liblzma.dll with old MSVC can work though(*), - * but we need to define the required standard integer - * types here in a MSVC-specific way. - * - * (*) If you do this, the existing liblzma.dll probably uses - * a different runtime library than your MSVC-built - * application. Mixing runtimes is generally bad, but - * in this case it should work as long as you avoid - * the few rarely-needed liblzma functions that allocate - * memory and expect the caller to free it using free(). - */ -# if defined(_WIN32) && defined(_MSC_VER) && _MSC_VER < 1800 - typedef unsigned __int8 uint8_t; - typedef unsigned __int32 uint32_t; - typedef unsigned __int64 uint64_t; -# else - /* Use the standard inttypes.h. */ -# ifdef __cplusplus - /* - * C99 sections 7.18.2 and 7.18.4 specify - * that C++ implementations define the limit - * and constant macros only if specifically - * requested. Note that if you want the - * format macros (PRIu64 etc.) too, you need - * to define __STDC_FORMAT_MACROS before - * including lzma.h, since re-including - * inttypes.h with __STDC_FORMAT_MACROS - * defined doesn't necessarily work. - */ -# ifndef __STDC_LIMIT_MACROS -# define __STDC_LIMIT_MACROS 1 -# endif -# ifndef __STDC_CONSTANT_MACROS -# define __STDC_CONSTANT_MACROS 1 -# endif -# endif - -# include -# endif - - /* - * Some old systems have only the typedefs in inttypes.h, and - * lack all the macros. For those systems, we need a few more - * hacks. We assume that unsigned int is 32-bit and unsigned - * long is either 32-bit or 64-bit. If these hacks aren't - * enough, the application has to setup the types manually - * before including lzma.h. - */ -# ifndef UINT32_C -# if defined(_WIN32) && defined(_MSC_VER) -# define UINT32_C(n) n ## UI32 -# else -# define UINT32_C(n) n ## U -# endif -# endif - -# ifndef UINT64_C -# if defined(_WIN32) && defined(_MSC_VER) -# define UINT64_C(n) n ## UI64 -# else - /* Get ULONG_MAX. */ -# include -# if ULONG_MAX == 4294967295UL -# define UINT64_C(n) n ## ULL -# else -# define UINT64_C(n) n ## UL -# endif -# endif -# endif - -# ifndef UINT32_MAX -# define UINT32_MAX (UINT32_C(4294967295)) -# endif - -# ifndef UINT64_MAX -# define UINT64_MAX (UINT64_C(18446744073709551615)) -# endif -# endif -#endif /* ifdef LZMA_MANUAL_HEADERS */ - - -/****************** - * LZMA_API macro * - ******************/ - -/* - * Some systems require that the functions and function pointers are - * declared specially in the headers. LZMA_API_IMPORT is for importing - * symbols and LZMA_API_CALL is to specify the calling convention. - * - * By default it is assumed that the application will link dynamically - * against liblzma. #define LZMA_API_STATIC in your application if you - * want to link against static liblzma. If you don't care about portability - * to operating systems like Windows, or at least don't care about linking - * against static liblzma on them, don't worry about LZMA_API_STATIC. That - * is, most developers will never need to use LZMA_API_STATIC. - * - * The GCC variants are a special case on Windows (Cygwin and MinGW). - * We rely on GCC doing the right thing with its auto-import feature, - * and thus don't use __declspec(dllimport). This way developers don't - * need to worry about LZMA_API_STATIC. Also the calling convention is - * omitted on Cygwin but not on MinGW. - */ -#ifndef LZMA_API_IMPORT -# if !defined(LZMA_API_STATIC) && defined(_WIN32) && !defined(__GNUC__) -# define LZMA_API_IMPORT __declspec(dllimport) -# else -# define LZMA_API_IMPORT -# endif -#endif - -#ifndef LZMA_API_CALL -# if defined(_WIN32) && !defined(__CYGWIN__) -# define LZMA_API_CALL __cdecl -# else -# define LZMA_API_CALL -# endif -#endif - -#ifndef LZMA_API -# define LZMA_API(type) LZMA_API_IMPORT type LZMA_API_CALL -#endif - - -/*********** - * nothrow * - ***********/ - -/* - * None of the functions in liblzma may throw an exception. Even - * the functions that use callback functions won't throw exceptions, - * because liblzma would break if a callback function threw an exception. - */ -#ifndef lzma_nothrow -# if defined(__cplusplus) -# define lzma_nothrow throw() -# elif __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) -# define lzma_nothrow __attribute__((__nothrow__)) -# else -# define lzma_nothrow -# endif -#endif - - -/******************** - * GNU C extensions * - ********************/ - -/* - * GNU C extensions are used conditionally in the public API. It doesn't - * break anything if these are sometimes enabled and sometimes not, only - * affects warnings and optimizations. - */ -#if __GNUC__ >= 3 -# ifndef lzma_attribute -# define lzma_attribute(attr) __attribute__(attr) -# endif - - /* warn_unused_result was added in GCC 3.4. */ -# ifndef lzma_attr_warn_unused_result -# if __GNUC__ == 3 && __GNUC_MINOR__ < 4 -# define lzma_attr_warn_unused_result -# endif -# endif - -#else -# ifndef lzma_attribute -# define lzma_attribute(attr) -# endif -#endif - - -#ifndef lzma_attr_pure -# define lzma_attr_pure lzma_attribute((__pure__)) -#endif - -#ifndef lzma_attr_const -# define lzma_attr_const lzma_attribute((__const__)) -#endif - -#ifndef lzma_attr_warn_unused_result -# define lzma_attr_warn_unused_result \ - lzma_attribute((__warn_unused_result__)) -#endif - - -/************** - * Subheaders * - **************/ - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Subheaders check that this is defined. It is to prevent including - * them directly from applications. - */ -#define LZMA_H_INTERNAL 1 - -/* Basic features */ -#include "lzma/version.h" -#include "lzma/base.h" -#include "lzma/vli.h" -#include "lzma/check.h" - -/* Filters */ -#include "lzma/filter.h" -//#include "lzma/bcj.h" -//#include "lzma/delta.h" -#include "lzma/lzma12.h" - -/* Container formats */ -#include "lzma/container.h" - -/* Advanced features */ -//#include "lzma/stream_flags.h" -//#include "lzma/block.h" -//#include "lzma/index.h" -//#include "lzma/index_hash.h" - -/* Hardware information */ -//#include "lzma/hardware.h" - -/* - * All subheaders included. Undefine LZMA_H_INTERNAL to prevent applications - * re-including the subheaders. - */ -#undef LZMA_H_INTERNAL - -#ifdef __cplusplus -} -#endif - -#endif /* ifndef LZMA_H */ diff --git a/game/client/third/minizip/lib/liblzma/api/lzma/base.h b/game/client/third/minizip/lib/liblzma/api/lzma/base.h deleted file mode 100755 index 7a31a420..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma/base.h +++ /dev/null @@ -1,654 +0,0 @@ -/** - * \file lzma/base.h - * \brief Data types and functions used in many places in liblzma API - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - * - * See ../lzma.h for information about liblzma as a whole. - */ - -#ifndef LZMA_H_INTERNAL -# error Never include this file directly. Use instead. -#endif - - -/** - * \brief Boolean - * - * This is here because C89 doesn't have stdbool.h. To set a value for - * variables having type lzma_bool, you can use - * - C99's `true' and `false' from stdbool.h; - * - C++'s internal `true' and `false'; or - * - integers one (true) and zero (false). - */ -typedef unsigned char lzma_bool; - - -/** - * \brief Type of reserved enumeration variable in structures - * - * To avoid breaking library ABI when new features are added, several - * structures contain extra variables that may be used in future. Since - * sizeof(enum) can be different than sizeof(int), and sizeof(enum) may - * even vary depending on the range of enumeration constants, we specify - * a separate type to be used for reserved enumeration variables. All - * enumeration constants in liblzma API will be non-negative and less - * than 128, which should guarantee that the ABI won't break even when - * new constants are added to existing enumerations. - */ -typedef enum { - LZMA_RESERVED_ENUM = 0 -} lzma_reserved_enum; - - -/** - * \brief Return values used by several functions in liblzma - * - * Check the descriptions of specific functions to find out which return - * values they can return. With some functions the return values may have - * more specific meanings than described here; those differences are - * described per-function basis. - */ -typedef enum { - LZMA_OK = 0, - /**< - * \brief Operation completed successfully - */ - - LZMA_STREAM_END = 1, - /**< - * \brief End of stream was reached - * - * In encoder, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, or - * LZMA_FINISH was finished. In decoder, this indicates - * that all the data was successfully decoded. - * - * In all cases, when LZMA_STREAM_END is returned, the last - * output bytes should be picked from strm->next_out. - */ - - LZMA_NO_CHECK = 2, - /**< - * \brief Input stream has no integrity check - * - * This return value can be returned only if the - * LZMA_TELL_NO_CHECK flag was used when initializing - * the decoder. LZMA_NO_CHECK is just a warning, and - * the decoding can be continued normally. - * - * It is possible to call lzma_get_check() immediately after - * lzma_code has returned LZMA_NO_CHECK. The result will - * naturally be LZMA_CHECK_NONE, but the possibility to call - * lzma_get_check() may be convenient in some applications. - */ - - LZMA_UNSUPPORTED_CHECK = 3, - /**< - * \brief Cannot calculate the integrity check - * - * The usage of this return value is different in encoders - * and decoders. - * - * Encoders can return this value only from the initialization - * function. If initialization fails with this value, the - * encoding cannot be done, because there's no way to produce - * output with the correct integrity check. - * - * Decoders can return this value only from lzma_code() and - * only if the LZMA_TELL_UNSUPPORTED_CHECK flag was used when - * initializing the decoder. The decoding can still be - * continued normally even if the check type is unsupported, - * but naturally the check will not be validated, and possible - * errors may go undetected. - * - * With decoder, it is possible to call lzma_get_check() - * immediately after lzma_code() has returned - * LZMA_UNSUPPORTED_CHECK. This way it is possible to find - * out what the unsupported Check ID was. - */ - - LZMA_GET_CHECK = 4, - /**< - * \brief Integrity check type is now available - * - * This value can be returned only by the lzma_code() function - * and only if the decoder was initialized with the - * LZMA_TELL_ANY_CHECK flag. LZMA_GET_CHECK tells the - * application that it may now call lzma_get_check() to find - * out the Check ID. This can be used, for example, to - * implement a decoder that accepts only files that have - * strong enough integrity check. - */ - - LZMA_MEM_ERROR = 5, - /**< - * \brief Cannot allocate memory - * - * Memory allocation failed, or the size of the allocation - * would be greater than SIZE_MAX. - * - * Due to internal implementation reasons, the coding cannot - * be continued even if more memory were made available after - * LZMA_MEM_ERROR. - */ - - LZMA_MEMLIMIT_ERROR = 6, - /** - * \brief Memory usage limit was reached - * - * Decoder would need more memory than allowed by the - * specified memory usage limit. To continue decoding, - * the memory usage limit has to be increased with - * lzma_memlimit_set(). - */ - - LZMA_FORMAT_ERROR = 7, - /**< - * \brief File format not recognized - * - * The decoder did not recognize the input as supported file - * format. This error can occur, for example, when trying to - * decode .lzma format file with lzma_stream_decoder, - * because lzma_stream_decoder accepts only the .xz format. - */ - - LZMA_OPTIONS_ERROR = 8, - /**< - * \brief Invalid or unsupported options - * - * Invalid or unsupported options, for example - * - unsupported filter(s) or filter options; or - * - reserved bits set in headers (decoder only). - * - * Rebuilding liblzma with more features enabled, or - * upgrading to a newer version of liblzma may help. - */ - - LZMA_DATA_ERROR = 9, - /**< - * \brief Data is corrupt - * - * The usage of this return value is different in encoders - * and decoders. In both encoder and decoder, the coding - * cannot continue after this error. - * - * Encoders return this if size limits of the target file - * format would be exceeded. These limits are huge, thus - * getting this error from an encoder is mostly theoretical. - * For example, the maximum compressed and uncompressed - * size of a .xz Stream is roughly 8 EiB (2^63 bytes). - * - * Decoders return this error if the input data is corrupt. - * This can mean, for example, invalid CRC32 in headers - * or invalid check of uncompressed data. - */ - - LZMA_BUF_ERROR = 10, - /**< - * \brief No progress is possible - * - * This error code is returned when the coder cannot consume - * any new input and produce any new output. The most common - * reason for this error is that the input stream being - * decoded is truncated or corrupt. - * - * This error is not fatal. Coding can be continued normally - * by providing more input and/or more output space, if - * possible. - * - * Typically the first call to lzma_code() that can do no - * progress returns LZMA_OK instead of LZMA_BUF_ERROR. Only - * the second consecutive call doing no progress will return - * LZMA_BUF_ERROR. This is intentional. - * - * With zlib, Z_BUF_ERROR may be returned even if the - * application is doing nothing wrong, so apps will need - * to handle Z_BUF_ERROR specially. The above hack - * guarantees that liblzma never returns LZMA_BUF_ERROR - * to properly written applications unless the input file - * is truncated or corrupt. This should simplify the - * applications a little. - */ - - LZMA_PROG_ERROR = 11, - /**< - * \brief Programming error - * - * This indicates that the arguments given to the function are - * invalid or the internal state of the decoder is corrupt. - * - Function arguments are invalid or the structures - * pointed by the argument pointers are invalid - * e.g. if strm->next_out has been set to NULL and - * strm->avail_out > 0 when calling lzma_code(). - * - lzma_* functions have been called in wrong order - * e.g. lzma_code() was called right after lzma_end(). - * - If errors occur randomly, the reason might be flaky - * hardware. - * - * If you think that your code is correct, this error code - * can be a sign of a bug in liblzma. See the documentation - * how to report bugs. - */ -} lzma_ret; - - -/** - * \brief The `action' argument for lzma_code() - * - * After the first use of LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, LZMA_FULL_BARRIER, - * or LZMA_FINISH, the same `action' must is used until lzma_code() returns - * LZMA_STREAM_END. Also, the amount of input (that is, strm->avail_in) must - * not be modified by the application until lzma_code() returns - * LZMA_STREAM_END. Changing the `action' or modifying the amount of input - * will make lzma_code() return LZMA_PROG_ERROR. - */ -typedef enum { - LZMA_RUN = 0, - /**< - * \brief Continue coding - * - * Encoder: Encode as much input as possible. Some internal - * buffering will probably be done (depends on the filter - * chain in use), which causes latency: the input used won't - * usually be decodeable from the output of the same - * lzma_code() call. - * - * Decoder: Decode as much input as possible and produce as - * much output as possible. - */ - - LZMA_SYNC_FLUSH = 1, - /**< - * \brief Make all the input available at output - * - * Normally the encoder introduces some latency. - * LZMA_SYNC_FLUSH forces all the buffered data to be - * available at output without resetting the internal - * state of the encoder. This way it is possible to use - * compressed stream for example for communication over - * network. - * - * Only some filters support LZMA_SYNC_FLUSH. Trying to use - * LZMA_SYNC_FLUSH with filters that don't support it will - * make lzma_code() return LZMA_OPTIONS_ERROR. For example, - * LZMA1 doesn't support LZMA_SYNC_FLUSH but LZMA2 does. - * - * Using LZMA_SYNC_FLUSH very often can dramatically reduce - * the compression ratio. With some filters (for example, - * LZMA2), fine-tuning the compression options may help - * mitigate this problem significantly (for example, - * match finder with LZMA2). - * - * Decoders don't support LZMA_SYNC_FLUSH. - */ - - LZMA_FULL_FLUSH = 2, - /**< - * \brief Finish encoding of the current Block - * - * All the input data going to the current Block must have - * been given to the encoder (the last bytes can still be - * pending in *next_in). Call lzma_code() with LZMA_FULL_FLUSH - * until it returns LZMA_STREAM_END. Then continue normally - * with LZMA_RUN or finish the Stream with LZMA_FINISH. - * - * This action is currently supported only by Stream encoder - * and easy encoder (which uses Stream encoder). If there is - * no unfinished Block, no empty Block is created. - */ - - LZMA_FULL_BARRIER = 4, - /**< - * \brief Finish encoding of the current Block - * - * This is like LZMA_FULL_FLUSH except that this doesn't - * necessarily wait until all the input has been made - * available via the output buffer. That is, lzma_code() - * might return LZMA_STREAM_END as soon as all the input - * has been consumed (avail_in == 0). - * - * LZMA_FULL_BARRIER is useful with a threaded encoder if - * one wants to split the .xz Stream into Blocks at specific - * offsets but doesn't care if the output isn't flushed - * immediately. Using LZMA_FULL_BARRIER allows keeping - * the threads busy while LZMA_FULL_FLUSH would make - * lzma_code() wait until all the threads have finished - * until more data could be passed to the encoder. - * - * With a lzma_stream initialized with the single-threaded - * lzma_stream_encoder() or lzma_easy_encoder(), - * LZMA_FULL_BARRIER is an alias for LZMA_FULL_FLUSH. - */ - - LZMA_FINISH = 3 - /**< - * \brief Finish the coding operation - * - * All the input data must have been given to the encoder - * (the last bytes can still be pending in next_in). - * Call lzma_code() with LZMA_FINISH until it returns - * LZMA_STREAM_END. Once LZMA_FINISH has been used, - * the amount of input must no longer be changed by - * the application. - * - * When decoding, using LZMA_FINISH is optional unless the - * LZMA_CONCATENATED flag was used when the decoder was - * initialized. When LZMA_CONCATENATED was not used, the only - * effect of LZMA_FINISH is that the amount of input must not - * be changed just like in the encoder. - */ -} lzma_action; - - -/** - * \brief Custom functions for memory handling - * - * A pointer to lzma_allocator may be passed via lzma_stream structure - * to liblzma, and some advanced functions take a pointer to lzma_allocator - * as a separate function argument. The library will use the functions - * specified in lzma_allocator for memory handling instead of the default - * malloc() and free(). C++ users should note that the custom memory - * handling functions must not throw exceptions. - * - * Single-threaded mode only: liblzma doesn't make an internal copy of - * lzma_allocator. Thus, it is OK to change these function pointers in - * the middle of the coding process, but obviously it must be done - * carefully to make sure that the replacement `free' can deallocate - * memory allocated by the earlier `alloc' function(s). - * - * Multithreaded mode: liblzma might internally store pointers to the - * lzma_allocator given via the lzma_stream structure. The application - * must not change the allocator pointer in lzma_stream or the contents - * of the pointed lzma_allocator structure until lzma_end() has been used - * to free the memory associated with that lzma_stream. The allocation - * functions might be called simultaneously from multiple threads, and - * thus they must be thread safe. - */ -typedef struct { - /** - * \brief Pointer to a custom memory allocation function - * - * If you don't want a custom allocator, but still want - * custom free(), set this to NULL and liblzma will use - * the standard malloc(). - * - * \param opaque lzma_allocator.opaque (see below) - * \param nmemb Number of elements like in calloc(). liblzma - * will always set nmemb to 1, so it is safe to - * ignore nmemb in a custom allocator if you like. - * The nmemb argument exists only for - * compatibility with zlib and libbzip2. - * \param size Size of an element in bytes. - * liblzma never sets this to zero. - * - * \return Pointer to the beginning of a memory block of - * `size' bytes, or NULL if allocation fails - * for some reason. When allocation fails, functions - * of liblzma return LZMA_MEM_ERROR. - * - * The allocator should not waste time zeroing the allocated buffers. - * This is not only about speed, but also memory usage, since the - * operating system kernel doesn't necessarily allocate the requested - * memory in physical memory until it is actually used. With small - * input files, liblzma may actually need only a fraction of the - * memory that it requested for allocation. - * - * \note LZMA_MEM_ERROR is also used when the size of the - * allocation would be greater than SIZE_MAX. Thus, - * don't assume that the custom allocator must have - * returned NULL if some function from liblzma - * returns LZMA_MEM_ERROR. - */ - void *(LZMA_API_CALL *alloc)(void *opaque, size_t nmemb, size_t size); - - /** - * \brief Pointer to a custom memory freeing function - * - * If you don't want a custom freeing function, but still - * want a custom allocator, set this to NULL and liblzma - * will use the standard free(). - * - * \param opaque lzma_allocator.opaque (see below) - * \param ptr Pointer returned by lzma_allocator.alloc(), - * or when it is set to NULL, a pointer returned - * by the standard malloc(). - */ - void (LZMA_API_CALL *free)(void *opaque, void *ptr); - - /** - * \brief Pointer passed to .alloc() and .free() - * - * opaque is passed as the first argument to lzma_allocator.alloc() - * and lzma_allocator.free(). This intended to ease implementing - * custom memory allocation functions for use with liblzma. - * - * If you don't need this, you should set this to NULL. - */ - void *opaque; - -} lzma_allocator; - - -/** - * \brief Internal data structure - * - * The contents of this structure is not visible outside the library. - */ -typedef struct lzma_internal_s lzma_internal; - - -/** - * \brief Passing data to and from liblzma - * - * The lzma_stream structure is used for - * - passing pointers to input and output buffers to liblzma; - * - defining custom memory hander functions; and - * - holding a pointer to coder-specific internal data structures. - * - * Typical usage: - * - * - After allocating lzma_stream (on stack or with malloc()), it must be - * initialized to LZMA_STREAM_INIT (see LZMA_STREAM_INIT for details). - * - * - Initialize a coder to the lzma_stream, for example by using - * lzma_easy_encoder() or lzma_auto_decoder(). Some notes: - * - In contrast to zlib, strm->next_in and strm->next_out are - * ignored by all initialization functions, thus it is safe - * to not initialize them yet. - * - The initialization functions always set strm->total_in and - * strm->total_out to zero. - * - If the initialization function fails, no memory is left allocated - * that would require freeing with lzma_end() even if some memory was - * associated with the lzma_stream structure when the initialization - * function was called. - * - * - Use lzma_code() to do the actual work. - * - * - Once the coding has been finished, the existing lzma_stream can be - * reused. It is OK to reuse lzma_stream with different initialization - * function without calling lzma_end() first. Old allocations are - * automatically freed. - * - * - Finally, use lzma_end() to free the allocated memory. lzma_end() never - * frees the lzma_stream structure itself. - * - * Application may modify the values of total_in and total_out as it wants. - * They are updated by liblzma to match the amount of data read and - * written but aren't used for anything else except as a possible return - * values from lzma_get_progress(). - */ -typedef struct { - const uint8_t *next_in; /**< Pointer to the next input byte. */ - size_t avail_in; /**< Number of available input bytes in next_in. */ - uint64_t total_in; /**< Total number of bytes read by liblzma. */ - - uint8_t *next_out; /**< Pointer to the next output position. */ - size_t avail_out; /**< Amount of free space in next_out. */ - uint64_t total_out; /**< Total number of bytes written by liblzma. */ - - /** - * \brief Custom memory allocation functions - * - * In most cases this is NULL which makes liblzma use - * the standard malloc() and free(). - * - * \note In 5.0.x this is not a const pointer. - */ - const lzma_allocator *allocator; - - /** Internal state is not visible to applications. */ - lzma_internal *internal; - - /* - * Reserved space to allow possible future extensions without - * breaking the ABI. Excluding the initialization of this structure, - * you should not touch these, because the names of these variables - * may change. - */ - void *reserved_ptr1; - void *reserved_ptr2; - void *reserved_ptr3; - void *reserved_ptr4; - uint64_t reserved_int1; - uint64_t reserved_int2; - size_t reserved_int3; - size_t reserved_int4; - lzma_reserved_enum reserved_enum1; - lzma_reserved_enum reserved_enum2; - -} lzma_stream; - - -/** - * \brief Initialization for lzma_stream - * - * When you declare an instance of lzma_stream, you can immediately - * initialize it so that initialization functions know that no memory - * has been allocated yet: - * - * lzma_stream strm = LZMA_STREAM_INIT; - * - * If you need to initialize a dynamically allocated lzma_stream, you can use - * memset(strm_pointer, 0, sizeof(lzma_stream)). Strictly speaking, this - * violates the C standard since NULL may have different internal - * representation than zero, but it should be portable enough in practice. - * Anyway, for maximum portability, you can use something like this: - * - * lzma_stream tmp = LZMA_STREAM_INIT; - * *strm = tmp; - */ -#define LZMA_STREAM_INIT \ - { NULL, 0, 0, NULL, 0, 0, NULL, NULL, \ - NULL, NULL, NULL, NULL, 0, 0, 0, 0, \ - LZMA_RESERVED_ENUM, LZMA_RESERVED_ENUM } - - -/** - * \brief Encode or decode data - * - * Once the lzma_stream has been successfully initialized (e.g. with - * lzma_stream_encoder()), the actual encoding or decoding is done - * using this function. The application has to update strm->next_in, - * strm->avail_in, strm->next_out, and strm->avail_out to pass input - * to and get output from liblzma. - * - * See the description of the coder-specific initialization function to find - * out what `action' values are supported by the coder. - */ -extern LZMA_API(lzma_ret) lzma_code(lzma_stream *strm, lzma_action action) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Free memory allocated for the coder data structures - * - * \param strm Pointer to lzma_stream that is at least initialized - * with LZMA_STREAM_INIT. - * - * After lzma_end(strm), strm->internal is guaranteed to be NULL. No other - * members of the lzma_stream structure are touched. - * - * \note zlib indicates an error if application end()s unfinished - * stream structure. liblzma doesn't do this, and assumes that - * application knows what it is doing. - */ -extern LZMA_API(void) lzma_end(lzma_stream *strm) lzma_nothrow; - - -/** - * \brief Get progress information - * - * In single-threaded mode, applications can get progress information from - * strm->total_in and strm->total_out. In multi-threaded mode this is less - * useful because a significant amount of both input and output data gets - * buffered internally by liblzma. This makes total_in and total_out give - * misleading information and also makes the progress indicator updates - * non-smooth. - * - * This function gives realistic progress information also in multi-threaded - * mode by taking into account the progress made by each thread. In - * single-threaded mode *progress_in and *progress_out are set to - * strm->total_in and strm->total_out, respectively. - */ -extern LZMA_API(void) lzma_get_progress(lzma_stream *strm, - uint64_t *progress_in, uint64_t *progress_out) lzma_nothrow; - - -/** - * \brief Get the memory usage of decoder filter chain - * - * This function is currently supported only when *strm has been initialized - * with a function that takes a memlimit argument. With other functions, you - * should use e.g. lzma_raw_encoder_memusage() or lzma_raw_decoder_memusage() - * to estimate the memory requirements. - * - * This function is useful e.g. after LZMA_MEMLIMIT_ERROR to find out how big - * the memory usage limit should have been to decode the input. Note that - * this may give misleading information if decoding .xz Streams that have - * multiple Blocks, because each Block can have different memory requirements. - * - * \return How much memory is currently allocated for the filter - * decoders. If no filter chain is currently allocated, - * some non-zero value is still returned, which is less than - * or equal to what any filter chain would indicate as its - * memory requirement. - * - * If this function isn't supported by *strm or some other error - * occurs, zero is returned. - */ -extern LZMA_API(uint64_t) lzma_memusage(const lzma_stream *strm) - lzma_nothrow lzma_attr_pure; - - -/** - * \brief Get the current memory usage limit - * - * This function is supported only when *strm has been initialized with - * a function that takes a memlimit argument. - * - * \return On success, the current memory usage limit is returned - * (always non-zero). On error, zero is returned. - */ -extern LZMA_API(uint64_t) lzma_memlimit_get(const lzma_stream *strm) - lzma_nothrow lzma_attr_pure; - - -/** - * \brief Set the memory usage limit - * - * This function is supported only when *strm has been initialized with - * a function that takes a memlimit argument. - * - * \return - LZMA_OK: New memory usage limit successfully set. - * - LZMA_MEMLIMIT_ERROR: The new limit is too small. - * The limit was not changed. - * - LZMA_PROG_ERROR: Invalid arguments, e.g. *strm doesn't - * support memory usage limit or memlimit was zero. - */ -extern LZMA_API(lzma_ret) lzma_memlimit_set( - lzma_stream *strm, uint64_t memlimit) lzma_nothrow; diff --git a/game/client/third/minizip/lib/liblzma/api/lzma/check.h b/game/client/third/minizip/lib/liblzma/api/lzma/check.h deleted file mode 100755 index 6a243db0..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma/check.h +++ /dev/null @@ -1,150 +0,0 @@ -/** - * \file lzma/check.h - * \brief Integrity checks - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - * - * See ../lzma.h for information about liblzma as a whole. - */ - -#ifndef LZMA_H_INTERNAL -# error Never include this file directly. Use instead. -#endif - - -/** - * \brief Type of the integrity check (Check ID) - * - * The .xz format supports multiple types of checks that are calculated - * from the uncompressed data. They vary in both speed and ability to - * detect errors. - */ -typedef enum { - LZMA_CHECK_NONE = 0, - /**< - * No Check is calculated. - * - * Size of the Check field: 0 bytes - */ - - LZMA_CHECK_CRC32 = 1, - /**< - * CRC32 using the polynomial from the IEEE 802.3 standard - * - * Size of the Check field: 4 bytes - */ - - LZMA_CHECK_CRC64 = 4, - /**< - * CRC64 using the polynomial from the ECMA-182 standard - * - * Size of the Check field: 8 bytes - */ - - LZMA_CHECK_SHA256 = 10 - /**< - * SHA-256 - * - * Size of the Check field: 32 bytes - */ -} lzma_check; - - -/** - * \brief Maximum valid Check ID - * - * The .xz file format specification specifies 16 Check IDs (0-15). Some - * of them are only reserved, that is, no actual Check algorithm has been - * assigned. When decoding, liblzma still accepts unknown Check IDs for - * future compatibility. If a valid but unsupported Check ID is detected, - * liblzma can indicate a warning; see the flags LZMA_TELL_NO_CHECK, - * LZMA_TELL_UNSUPPORTED_CHECK, and LZMA_TELL_ANY_CHECK in container.h. - */ -#define LZMA_CHECK_ID_MAX 15 - - -/** - * \brief Test if the given Check ID is supported - * - * Return true if the given Check ID is supported by this liblzma build. - * Otherwise false is returned. It is safe to call this with a value that - * is not in the range [0, 15]; in that case the return value is always false. - * - * You can assume that LZMA_CHECK_NONE and LZMA_CHECK_CRC32 are always - * supported (even if liblzma is built with limited features). - */ -extern LZMA_API(lzma_bool) lzma_check_is_supported(lzma_check check) - lzma_nothrow lzma_attr_const; - - -/** - * \brief Get the size of the Check field with the given Check ID - * - * Although not all Check IDs have a check algorithm associated, the size of - * every Check is already frozen. This function returns the size (in bytes) of - * the Check field with the specified Check ID. The values are: - * { 0, 4, 4, 4, 8, 8, 8, 16, 16, 16, 32, 32, 32, 64, 64, 64 } - * - * If the argument is not in the range [0, 15], UINT32_MAX is returned. - */ -extern LZMA_API(uint32_t) lzma_check_size(lzma_check check) - lzma_nothrow lzma_attr_const; - - -/** - * \brief Maximum size of a Check field - */ -#define LZMA_CHECK_SIZE_MAX 64 - - -/** - * \brief Calculate CRC32 - * - * Calculate CRC32 using the polynomial from the IEEE 802.3 standard. - * - * \param buf Pointer to the input buffer - * \param size Size of the input buffer - * \param crc Previously returned CRC value. This is used to - * calculate the CRC of a big buffer in smaller chunks. - * Set to zero when starting a new calculation. - * - * \return Updated CRC value, which can be passed to this function - * again to continue CRC calculation. - */ -extern LZMA_API(uint32_t) lzma_crc32( - const uint8_t *buf, size_t size, uint32_t crc) - lzma_nothrow lzma_attr_pure; - - -/** - * \brief Calculate CRC64 - * - * Calculate CRC64 using the polynomial from the ECMA-182 standard. - * - * This function is used similarly to lzma_crc32(). See its documentation. - */ -extern LZMA_API(uint64_t) lzma_crc64( - const uint8_t *buf, size_t size, uint64_t crc) - lzma_nothrow lzma_attr_pure; - - -/* - * SHA-256 functions are currently not exported to public API. - * Contact Lasse Collin if you think it should be. - */ - - -/** - * \brief Get the type of the integrity check - * - * This function can be called only immediately after lzma_code() has - * returned LZMA_NO_CHECK, LZMA_UNSUPPORTED_CHECK, or LZMA_GET_CHECK. - * Calling this function in any other situation has undefined behavior. - */ -extern LZMA_API(lzma_check) lzma_get_check(const lzma_stream *strm) - lzma_nothrow; diff --git a/game/client/third/minizip/lib/liblzma/api/lzma/container.h b/game/client/third/minizip/lib/liblzma/api/lzma/container.h deleted file mode 100755 index 86991add..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma/container.h +++ /dev/null @@ -1,619 +0,0 @@ -/** - * \file lzma/container.h - * \brief File formats - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - * - * See ../lzma.h for information about liblzma as a whole. - */ - -#ifndef LZMA_H_INTERNAL -# error Never include this file directly. Use instead. -#endif - - -/************ - * Encoding * - ************/ - -/** - * \brief Default compression preset - * - * It's not straightforward to recommend a default preset, because in some - * cases keeping the resource usage relatively low is more important that - * getting the maximum compression ratio. - */ -#define LZMA_PRESET_DEFAULT UINT32_C(6) - - -/** - * \brief Mask for preset level - * - * This is useful only if you need to extract the level from the preset - * variable. That should be rare. - */ -#define LZMA_PRESET_LEVEL_MASK UINT32_C(0x1F) - - -/* - * Preset flags - * - * Currently only one flag is defined. - */ - -/** - * \brief Extreme compression preset - * - * This flag modifies the preset to make the encoding significantly slower - * while improving the compression ratio only marginally. This is useful - * when you don't mind wasting time to get as small result as possible. - * - * This flag doesn't affect the memory usage requirements of the decoder (at - * least not significantly). The memory usage of the encoder may be increased - * a little but only at the lowest preset levels (0-3). - */ -#define LZMA_PRESET_EXTREME (UINT32_C(1) << 31) - - -/** - * \brief Multithreading options - */ -typedef struct { - /** - * \brief Flags - * - * Set this to zero if no flags are wanted. - * - * No flags are currently supported. - */ - uint32_t flags; - - /** - * \brief Number of worker threads to use - */ - uint32_t threads; - - /** - * \brief Maximum uncompressed size of a Block - * - * The encoder will start a new .xz Block every block_size bytes. - * Using LZMA_FULL_FLUSH or LZMA_FULL_BARRIER with lzma_code() - * the caller may tell liblzma to start a new Block earlier. - * - * With LZMA2, a recommended block size is 2-4 times the LZMA2 - * dictionary size. With very small dictionaries, it is recommended - * to use at least 1 MiB block size for good compression ratio, even - * if this is more than four times the dictionary size. Note that - * these are only recommendations for typical use cases; feel free - * to use other values. Just keep in mind that using a block size - * less than the LZMA2 dictionary size is waste of RAM. - * - * Set this to 0 to let liblzma choose the block size depending - * on the compression options. For LZMA2 it will be 3*dict_size - * or 1 MiB, whichever is more. - * - * For each thread, about 3 * block_size bytes of memory will be - * allocated. This may change in later liblzma versions. If so, - * the memory usage will probably be reduced, not increased. - */ - uint64_t block_size; - - /** - * \brief Timeout to allow lzma_code() to return early - * - * Multithreading can make liblzma to consume input and produce - * output in a very bursty way: it may first read a lot of input - * to fill internal buffers, then no input or output occurs for - * a while. - * - * In single-threaded mode, lzma_code() won't return until it has - * either consumed all the input or filled the output buffer. If - * this is done in multithreaded mode, it may cause a call - * lzma_code() to take even tens of seconds, which isn't acceptable - * in all applications. - * - * To avoid very long blocking times in lzma_code(), a timeout - * (in milliseconds) may be set here. If lzma_code() would block - * longer than this number of milliseconds, it will return with - * LZMA_OK. Reasonable values are 100 ms or more. The xz command - * line tool uses 300 ms. - * - * If long blocking times are fine for you, set timeout to a special - * value of 0, which will disable the timeout mechanism and will make - * lzma_code() block until all the input is consumed or the output - * buffer has been filled. - * - * \note Even with a timeout, lzma_code() might sometimes take - * somewhat long time to return. No timing guarantees - * are made. - */ - uint32_t timeout; - - /** - * \brief Compression preset (level and possible flags) - * - * The preset is set just like with lzma_easy_encoder(). - * The preset is ignored if filters below is non-NULL. - */ - uint32_t preset; - - /** - * \brief Filter chain (alternative to a preset) - * - * If this is NULL, the preset above is used. Otherwise the preset - * is ignored and the filter chain specified here is used. - */ - const lzma_filter *filters; - - /** - * \brief Integrity check type - * - * See check.h for available checks. The xz command line tool - * defaults to LZMA_CHECK_CRC64, which is a good choice if you - * are unsure. - */ - lzma_check check; - - /* - * Reserved space to allow possible future extensions without - * breaking the ABI. You should not touch these, because the names - * of these variables may change. These are and will never be used - * with the currently supported options, so it is safe to leave these - * uninitialized. - */ - lzma_reserved_enum reserved_enum1; - lzma_reserved_enum reserved_enum2; - lzma_reserved_enum reserved_enum3; - uint32_t reserved_int1; - uint32_t reserved_int2; - uint32_t reserved_int3; - uint32_t reserved_int4; - uint64_t reserved_int5; - uint64_t reserved_int6; - uint64_t reserved_int7; - uint64_t reserved_int8; - void *reserved_ptr1; - void *reserved_ptr2; - void *reserved_ptr3; - void *reserved_ptr4; - -} lzma_mt; - - -/** - * \brief Calculate approximate memory usage of easy encoder - * - * This function is a wrapper for lzma_raw_encoder_memusage(). - * - * \param preset Compression preset (level and possible flags) - * - * \return Number of bytes of memory required for the given - * preset when encoding. If an error occurs, for example - * due to unsupported preset, UINT64_MAX is returned. - */ -extern LZMA_API(uint64_t) lzma_easy_encoder_memusage(uint32_t preset) - lzma_nothrow lzma_attr_pure; - - -/** - * \brief Calculate approximate decoder memory usage of a preset - * - * This function is a wrapper for lzma_raw_decoder_memusage(). - * - * \param preset Compression preset (level and possible flags) - * - * \return Number of bytes of memory required to decompress a file - * that was compressed using the given preset. If an error - * occurs, for example due to unsupported preset, UINT64_MAX - * is returned. - */ -extern LZMA_API(uint64_t) lzma_easy_decoder_memusage(uint32_t preset) - lzma_nothrow lzma_attr_pure; - - -/** - * \brief Initialize .xz Stream encoder using a preset number - * - * This function is intended for those who just want to use the basic features - * if liblzma (that is, most developers out there). - * - * \param strm Pointer to lzma_stream that is at least initialized - * with LZMA_STREAM_INIT. - * \param preset Compression preset to use. A preset consist of level - * number and zero or more flags. Usually flags aren't - * used, so preset is simply a number [0, 9] which match - * the options -0 ... -9 of the xz command line tool. - * Additional flags can be be set using bitwise-or with - * the preset level number, e.g. 6 | LZMA_PRESET_EXTREME. - * \param check Integrity check type to use. See check.h for available - * checks. The xz command line tool defaults to - * LZMA_CHECK_CRC64, which is a good choice if you are - * unsure. LZMA_CHECK_CRC32 is good too as long as the - * uncompressed file is not many gigabytes. - * - * \return - LZMA_OK: Initialization succeeded. Use lzma_code() to - * encode your data. - * - LZMA_MEM_ERROR: Memory allocation failed. - * - LZMA_OPTIONS_ERROR: The given compression preset is not - * supported by this build of liblzma. - * - LZMA_UNSUPPORTED_CHECK: The given check type is not - * supported by this liblzma build. - * - LZMA_PROG_ERROR: One or more of the parameters have values - * that will never be valid. For example, strm == NULL. - * - * If initialization fails (return value is not LZMA_OK), all the memory - * allocated for *strm by liblzma is always freed. Thus, there is no need - * to call lzma_end() after failed initialization. - * - * If initialization succeeds, use lzma_code() to do the actual encoding. - * Valid values for `action' (the second argument of lzma_code()) are - * LZMA_RUN, LZMA_SYNC_FLUSH, LZMA_FULL_FLUSH, and LZMA_FINISH. In future, - * there may be compression levels or flags that don't support LZMA_SYNC_FLUSH. - */ -extern LZMA_API(lzma_ret) lzma_easy_encoder( - lzma_stream *strm, uint32_t preset, lzma_check check) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Single-call .xz Stream encoding using a preset number - * - * The maximum required output buffer size can be calculated with - * lzma_stream_buffer_bound(). - * - * \param preset Compression preset to use. See the description - * in lzma_easy_encoder(). - * \param check Type of the integrity check to calculate from - * uncompressed data. - * \param allocator lzma_allocator for custom allocator functions. - * Set to NULL to use malloc() and free(). - * \param in Beginning of the input buffer - * \param in_size Size of the input buffer - * \param out Beginning of the output buffer - * \param out_pos The next byte will be written to out[*out_pos]. - * *out_pos is updated only if encoding succeeds. - * \param out_size Size of the out buffer; the first byte into - * which no data is written to is out[out_size]. - * - * \return - LZMA_OK: Encoding was successful. - * - LZMA_BUF_ERROR: Not enough output buffer space. - * - LZMA_UNSUPPORTED_CHECK - * - LZMA_OPTIONS_ERROR - * - LZMA_MEM_ERROR - * - LZMA_DATA_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_easy_buffer_encode( - uint32_t preset, lzma_check check, - const lzma_allocator *allocator, - const uint8_t *in, size_t in_size, - uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow; - - -/** - * \brief Initialize .xz Stream encoder using a custom filter chain - * - * \param strm Pointer to properly prepared lzma_stream - * \param filters Array of filters. This must be terminated with - * filters[n].id = LZMA_VLI_UNKNOWN. See filter.h for - * more information. - * \param check Type of the integrity check to calculate from - * uncompressed data. - * - * \return - LZMA_OK: Initialization was successful. - * - LZMA_MEM_ERROR - * - LZMA_UNSUPPORTED_CHECK - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_stream_encoder(lzma_stream *strm, - const lzma_filter *filters, lzma_check check) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Calculate approximate memory usage of multithreaded .xz encoder - * - * Since doing the encoding in threaded mode doesn't affect the memory - * requirements of single-threaded decompressor, you can use - * lzma_easy_decoder_memusage(options->preset) or - * lzma_raw_decoder_memusage(options->filters) to calculate - * the decompressor memory requirements. - * - * \param options Compression options - * - * \return Number of bytes of memory required for encoding with the - * given options. If an error occurs, for example due to - * unsupported preset or filter chain, UINT64_MAX is returned. - */ -extern LZMA_API(uint64_t) lzma_stream_encoder_mt_memusage( - const lzma_mt *options) lzma_nothrow lzma_attr_pure; - - -/** - * \brief Initialize multithreaded .xz Stream encoder - * - * This provides the functionality of lzma_easy_encoder() and - * lzma_stream_encoder() as a single function for multithreaded use. - * - * The supported actions for lzma_code() are LZMA_RUN, LZMA_FULL_FLUSH, - * LZMA_FULL_BARRIER, and LZMA_FINISH. Support for LZMA_SYNC_FLUSH might be - * added in the future. - * - * \param strm Pointer to properly prepared lzma_stream - * \param options Pointer to multithreaded compression options - * - * \return - LZMA_OK - * - LZMA_MEM_ERROR - * - LZMA_UNSUPPORTED_CHECK - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_stream_encoder_mt( - lzma_stream *strm, const lzma_mt *options) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Initialize .lzma encoder (legacy file format) - * - * The .lzma format is sometimes called the LZMA_Alone format, which is the - * reason for the name of this function. The .lzma format supports only the - * LZMA1 filter. There is no support for integrity checks like CRC32. - * - * Use this function if and only if you need to create files readable by - * legacy LZMA tools such as LZMA Utils 4.32.x. Moving to the .xz format - * is strongly recommended. - * - * The valid action values for lzma_code() are LZMA_RUN and LZMA_FINISH. - * No kind of flushing is supported, because the file format doesn't make - * it possible. - * - * \return - LZMA_OK - * - LZMA_MEM_ERROR - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_alone_encoder( - lzma_stream *strm, const lzma_options_lzma *options) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Calculate output buffer size for single-call Stream encoder - * - * When trying to compress uncompressible data, the encoded size will be - * slightly bigger than the input data. This function calculates how much - * output buffer space is required to be sure that lzma_stream_buffer_encode() - * doesn't return LZMA_BUF_ERROR. - * - * The calculated value is not exact, but it is guaranteed to be big enough. - * The actual maximum output space required may be slightly smaller (up to - * about 100 bytes). This should not be a problem in practice. - * - * If the calculated maximum size doesn't fit into size_t or would make the - * Stream grow past LZMA_VLI_MAX (which should never happen in practice), - * zero is returned to indicate the error. - * - * \note The limit calculated by this function applies only to - * single-call encoding. Multi-call encoding may (and probably - * will) have larger maximum expansion when encoding - * uncompressible data. Currently there is no function to - * calculate the maximum expansion of multi-call encoding. - */ -extern LZMA_API(size_t) lzma_stream_buffer_bound(size_t uncompressed_size) - lzma_nothrow; - - -/** - * \brief Single-call .xz Stream encoder - * - * \param filters Array of filters. This must be terminated with - * filters[n].id = LZMA_VLI_UNKNOWN. See filter.h - * for more information. - * \param check Type of the integrity check to calculate from - * uncompressed data. - * \param allocator lzma_allocator for custom allocator functions. - * Set to NULL to use malloc() and free(). - * \param in Beginning of the input buffer - * \param in_size Size of the input buffer - * \param out Beginning of the output buffer - * \param out_pos The next byte will be written to out[*out_pos]. - * *out_pos is updated only if encoding succeeds. - * \param out_size Size of the out buffer; the first byte into - * which no data is written to is out[out_size]. - * - * \return - LZMA_OK: Encoding was successful. - * - LZMA_BUF_ERROR: Not enough output buffer space. - * - LZMA_UNSUPPORTED_CHECK - * - LZMA_OPTIONS_ERROR - * - LZMA_MEM_ERROR - * - LZMA_DATA_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_stream_buffer_encode( - lzma_filter *filters, lzma_check check, - const lzma_allocator *allocator, - const uint8_t *in, size_t in_size, - uint8_t *out, size_t *out_pos, size_t out_size) - lzma_nothrow lzma_attr_warn_unused_result; - - -/************ - * Decoding * - ************/ - -/** - * This flag makes lzma_code() return LZMA_NO_CHECK if the input stream - * being decoded has no integrity check. Note that when used with - * lzma_auto_decoder(), all .lzma files will trigger LZMA_NO_CHECK - * if LZMA_TELL_NO_CHECK is used. - */ -#define LZMA_TELL_NO_CHECK UINT32_C(0x01) - - -/** - * This flag makes lzma_code() return LZMA_UNSUPPORTED_CHECK if the input - * stream has an integrity check, but the type of the integrity check is not - * supported by this liblzma version or build. Such files can still be - * decoded, but the integrity check cannot be verified. - */ -#define LZMA_TELL_UNSUPPORTED_CHECK UINT32_C(0x02) - - -/** - * This flag makes lzma_code() return LZMA_GET_CHECK as soon as the type - * of the integrity check is known. The type can then be got with - * lzma_get_check(). - */ -#define LZMA_TELL_ANY_CHECK UINT32_C(0x04) - - -/** - * This flag makes lzma_code() not calculate and verify the integrity check - * of the compressed data in .xz files. This means that invalid integrity - * check values won't be detected and LZMA_DATA_ERROR won't be returned in - * such cases. - * - * This flag only affects the checks of the compressed data itself; the CRC32 - * values in the .xz headers will still be verified normally. - * - * Don't use this flag unless you know what you are doing. Possible reasons - * to use this flag: - * - * - Trying to recover data from a corrupt .xz file. - * - * - Speeding up decompression, which matters mostly with SHA-256 - * or with files that have compressed extremely well. It's recommended - * to not use this flag for this purpose unless the file integrity is - * verified externally in some other way. - * - * Support for this flag was added in liblzma 5.1.4beta. - */ -#define LZMA_IGNORE_CHECK UINT32_C(0x10) - - -/** - * This flag enables decoding of concatenated files with file formats that - * allow concatenating compressed files as is. From the formats currently - * supported by liblzma, only the .xz format allows concatenated files. - * Concatenated files are not allowed with the legacy .lzma format. - * - * This flag also affects the usage of the `action' argument for lzma_code(). - * When LZMA_CONCATENATED is used, lzma_code() won't return LZMA_STREAM_END - * unless LZMA_FINISH is used as `action'. Thus, the application has to set - * LZMA_FINISH in the same way as it does when encoding. - * - * If LZMA_CONCATENATED is not used, the decoders still accept LZMA_FINISH - * as `action' for lzma_code(), but the usage of LZMA_FINISH isn't required. - */ -#define LZMA_CONCATENATED UINT32_C(0x08) - - -/** - * \brief Initialize .xz Stream decoder - * - * \param strm Pointer to properly prepared lzma_stream - * \param memlimit Memory usage limit as bytes. Use UINT64_MAX - * to effectively disable the limiter. - * \param flags Bitwise-or of zero or more of the decoder flags: - * LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK, - * LZMA_TELL_ANY_CHECK, LZMA_CONCATENATED - * - * \return - LZMA_OK: Initialization was successful. - * - LZMA_MEM_ERROR: Cannot allocate memory. - * - LZMA_OPTIONS_ERROR: Unsupported flags - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_stream_decoder( - lzma_stream *strm, uint64_t memlimit, uint32_t flags) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Decode .xz Streams and .lzma files with autodetection - * - * This decoder autodetects between the .xz and .lzma file formats, and - * calls lzma_stream_decoder() or lzma_alone_decoder() once the type - * of the input file has been detected. - * - * \param strm Pointer to properly prepared lzma_stream - * \param memlimit Memory usage limit as bytes. Use UINT64_MAX - * to effectively disable the limiter. - * \param flags Bitwise-or of flags, or zero for no flags. - * - * \return - LZMA_OK: Initialization was successful. - * - LZMA_MEM_ERROR: Cannot allocate memory. - * - LZMA_OPTIONS_ERROR: Unsupported flags - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_auto_decoder( - lzma_stream *strm, uint64_t memlimit, uint32_t flags) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Initialize .lzma decoder (legacy file format) - * - * Valid `action' arguments to lzma_code() are LZMA_RUN and LZMA_FINISH. - * There is no need to use LZMA_FINISH, but allowing it may simplify - * certain types of applications. - * - * \return - LZMA_OK - * - LZMA_MEM_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_alone_decoder( - lzma_stream *strm, uint64_t memlimit) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Single-call .xz Stream decoder - * - * \param memlimit Pointer to how much memory the decoder is allowed - * to allocate. The value pointed by this pointer is - * modified if and only if LZMA_MEMLIMIT_ERROR is - * returned. - * \param flags Bitwise-or of zero or more of the decoder flags: - * LZMA_TELL_NO_CHECK, LZMA_TELL_UNSUPPORTED_CHECK, - * LZMA_CONCATENATED. Note that LZMA_TELL_ANY_CHECK - * is not allowed and will return LZMA_PROG_ERROR. - * \param allocator lzma_allocator for custom allocator functions. - * Set to NULL to use malloc() and free(). - * \param in Beginning of the input buffer - * \param in_pos The next byte will be read from in[*in_pos]. - * *in_pos is updated only if decoding succeeds. - * \param in_size Size of the input buffer; the first byte that - * won't be read is in[in_size]. - * \param out Beginning of the output buffer - * \param out_pos The next byte will be written to out[*out_pos]. - * *out_pos is updated only if decoding succeeds. - * \param out_size Size of the out buffer; the first byte into - * which no data is written to is out[out_size]. - * - * \return - LZMA_OK: Decoding was successful. - * - LZMA_FORMAT_ERROR - * - LZMA_OPTIONS_ERROR - * - LZMA_DATA_ERROR - * - LZMA_NO_CHECK: This can be returned only if using - * the LZMA_TELL_NO_CHECK flag. - * - LZMA_UNSUPPORTED_CHECK: This can be returned only if using - * the LZMA_TELL_UNSUPPORTED_CHECK flag. - * - LZMA_MEM_ERROR - * - LZMA_MEMLIMIT_ERROR: Memory usage limit was reached. - * The minimum required memlimit value was stored to *memlimit. - * - LZMA_BUF_ERROR: Output buffer was too small. - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_stream_buffer_decode( - uint64_t *memlimit, uint32_t flags, - const lzma_allocator *allocator, - const uint8_t *in, size_t *in_pos, size_t in_size, - uint8_t *out, size_t *out_pos, size_t out_size) - lzma_nothrow lzma_attr_warn_unused_result; diff --git a/game/client/third/minizip/lib/liblzma/api/lzma/filter.h b/game/client/third/minizip/lib/liblzma/api/lzma/filter.h deleted file mode 100755 index 4e78752b..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma/filter.h +++ /dev/null @@ -1,425 +0,0 @@ -/** - * \file lzma/filter.h - * \brief Common filter related types and functions - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - * - * See ../lzma.h for information about liblzma as a whole. - */ - -#ifndef LZMA_H_INTERNAL -# error Never include this file directly. Use instead. -#endif - - -/** - * \brief Maximum number of filters in a chain - * - * A filter chain can have 1-4 filters, of which three are allowed to change - * the size of the data. Usually only one or two filters are needed. - */ -#define LZMA_FILTERS_MAX 4 - - -/** - * \brief Filter options - * - * This structure is used to pass Filter ID and a pointer filter's - * options to liblzma. A few functions work with a single lzma_filter - * structure, while most functions expect a filter chain. - * - * A filter chain is indicated with an array of lzma_filter structures. - * The array is terminated with .id = LZMA_VLI_UNKNOWN. Thus, the filter - * array must have LZMA_FILTERS_MAX + 1 elements (that is, five) to - * be able to hold any arbitrary filter chain. This is important when - * using lzma_block_header_decode() from block.h, because too small - * array would make liblzma write past the end of the filters array. - */ -typedef struct { - /** - * \brief Filter ID - * - * Use constants whose name begin with `LZMA_FILTER_' to specify - * different filters. In an array of lzma_filter structures, use - * LZMA_VLI_UNKNOWN to indicate end of filters. - * - * \note This is not an enum, because on some systems enums - * cannot be 64-bit. - */ - lzma_vli id; - - /** - * \brief Pointer to filter-specific options structure - * - * If the filter doesn't need options, set this to NULL. If id is - * set to LZMA_VLI_UNKNOWN, options is ignored, and thus - * doesn't need be initialized. - */ - void *options; - -} lzma_filter; - - -/** - * \brief Test if the given Filter ID is supported for encoding - * - * Return true if the give Filter ID is supported for encoding by this - * liblzma build. Otherwise false is returned. - * - * There is no way to list which filters are available in this particular - * liblzma version and build. It would be useless, because the application - * couldn't know what kind of options the filter would need. - */ -extern LZMA_API(lzma_bool) lzma_filter_encoder_is_supported(lzma_vli id) - lzma_nothrow lzma_attr_const; - - -/** - * \brief Test if the given Filter ID is supported for decoding - * - * Return true if the give Filter ID is supported for decoding by this - * liblzma build. Otherwise false is returned. - */ -extern LZMA_API(lzma_bool) lzma_filter_decoder_is_supported(lzma_vli id) - lzma_nothrow lzma_attr_const; - - -/** - * \brief Copy the filters array - * - * Copy the Filter IDs and filter-specific options from src to dest. - * Up to LZMA_FILTERS_MAX filters are copied, plus the terminating - * .id == LZMA_VLI_UNKNOWN. Thus, dest should have at least - * LZMA_FILTERS_MAX + 1 elements space unless the caller knows that - * src is smaller than that. - * - * Unless the filter-specific options is NULL, the Filter ID has to be - * supported by liblzma, because liblzma needs to know the size of every - * filter-specific options structure. The filter-specific options are not - * validated. If options is NULL, any unsupported Filter IDs are copied - * without returning an error. - * - * Old filter-specific options in dest are not freed, so dest doesn't - * need to be initialized by the caller in any way. - * - * If an error occurs, memory possibly already allocated by this function - * is always freed. - * - * \return - LZMA_OK - * - LZMA_MEM_ERROR - * - LZMA_OPTIONS_ERROR: Unsupported Filter ID and its options - * is not NULL. - * - LZMA_PROG_ERROR: src or dest is NULL. - */ -extern LZMA_API(lzma_ret) lzma_filters_copy( - const lzma_filter *src, lzma_filter *dest, - const lzma_allocator *allocator) lzma_nothrow; - - -/** - * \brief Calculate approximate memory requirements for raw encoder - * - * This function can be used to calculate the memory requirements for - * Block and Stream encoders too because Block and Stream encoders don't - * need significantly more memory than raw encoder. - * - * \param filters Array of filters terminated with - * .id == LZMA_VLI_UNKNOWN. - * - * \return Number of bytes of memory required for the given - * filter chain when encoding. If an error occurs, - * for example due to unsupported filter chain, - * UINT64_MAX is returned. - */ -extern LZMA_API(uint64_t) lzma_raw_encoder_memusage(const lzma_filter *filters) - lzma_nothrow lzma_attr_pure; - - -/** - * \brief Calculate approximate memory requirements for raw decoder - * - * This function can be used to calculate the memory requirements for - * Block and Stream decoders too because Block and Stream decoders don't - * need significantly more memory than raw decoder. - * - * \param filters Array of filters terminated with - * .id == LZMA_VLI_UNKNOWN. - * - * \return Number of bytes of memory required for the given - * filter chain when decoding. If an error occurs, - * for example due to unsupported filter chain, - * UINT64_MAX is returned. - */ -extern LZMA_API(uint64_t) lzma_raw_decoder_memusage(const lzma_filter *filters) - lzma_nothrow lzma_attr_pure; - - -/** - * \brief Initialize raw encoder - * - * This function may be useful when implementing custom file formats. - * - * \param strm Pointer to properly prepared lzma_stream - * \param filters Array of lzma_filter structures. The end of the - * array must be marked with .id = LZMA_VLI_UNKNOWN. - * - * The `action' with lzma_code() can be LZMA_RUN, LZMA_SYNC_FLUSH (if the - * filter chain supports it), or LZMA_FINISH. - * - * \return - LZMA_OK - * - LZMA_MEM_ERROR - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_raw_encoder( - lzma_stream *strm, const lzma_filter *filters) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Initialize raw decoder - * - * The initialization of raw decoder goes similarly to raw encoder. - * - * The `action' with lzma_code() can be LZMA_RUN or LZMA_FINISH. Using - * LZMA_FINISH is not required, it is supported just for convenience. - * - * \return - LZMA_OK - * - LZMA_MEM_ERROR - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_raw_decoder( - lzma_stream *strm, const lzma_filter *filters) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Update the filter chain in the encoder - * - * This function is for advanced users only. This function has two slightly - * different purposes: - * - * - After LZMA_FULL_FLUSH when using Stream encoder: Set a new filter - * chain, which will be used starting from the next Block. - * - * - After LZMA_SYNC_FLUSH using Raw, Block, or Stream encoder: Change - * the filter-specific options in the middle of encoding. The actual - * filters in the chain (Filter IDs) cannot be changed. In the future, - * it might become possible to change the filter options without - * using LZMA_SYNC_FLUSH. - * - * While rarely useful, this function may be called also when no data has - * been compressed yet. In that case, this function will behave as if - * LZMA_FULL_FLUSH (Stream encoder) or LZMA_SYNC_FLUSH (Raw or Block - * encoder) had been used right before calling this function. - * - * \return - LZMA_OK - * - LZMA_MEM_ERROR - * - LZMA_MEMLIMIT_ERROR - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_filters_update( - lzma_stream *strm, const lzma_filter *filters) lzma_nothrow; - - -/** - * \brief Single-call raw encoder - * - * \param filters Array of lzma_filter structures. The end of the - * array must be marked with .id = LZMA_VLI_UNKNOWN. - * \param allocator lzma_allocator for custom allocator functions. - * Set to NULL to use malloc() and free(). - * \param in Beginning of the input buffer - * \param in_size Size of the input buffer - * \param out Beginning of the output buffer - * \param out_pos The next byte will be written to out[*out_pos]. - * *out_pos is updated only if encoding succeeds. - * \param out_size Size of the out buffer; the first byte into - * which no data is written to is out[out_size]. - * - * \return - LZMA_OK: Encoding was successful. - * - LZMA_BUF_ERROR: Not enough output buffer space. - * - LZMA_OPTIONS_ERROR - * - LZMA_MEM_ERROR - * - LZMA_DATA_ERROR - * - LZMA_PROG_ERROR - * - * \note There is no function to calculate how big output buffer - * would surely be big enough. (lzma_stream_buffer_bound() - * works only for lzma_stream_buffer_encode(); raw encoder - * won't necessarily meet that bound.) - */ -extern LZMA_API(lzma_ret) lzma_raw_buffer_encode( - const lzma_filter *filters, const lzma_allocator *allocator, - const uint8_t *in, size_t in_size, uint8_t *out, - size_t *out_pos, size_t out_size) lzma_nothrow; - - -/** - * \brief Single-call raw decoder - * - * \param filters Array of lzma_filter structures. The end of the - * array must be marked with .id = LZMA_VLI_UNKNOWN. - * \param allocator lzma_allocator for custom allocator functions. - * Set to NULL to use malloc() and free(). - * \param in Beginning of the input buffer - * \param in_pos The next byte will be read from in[*in_pos]. - * *in_pos is updated only if decoding succeeds. - * \param in_size Size of the input buffer; the first byte that - * won't be read is in[in_size]. - * \param out Beginning of the output buffer - * \param out_pos The next byte will be written to out[*out_pos]. - * *out_pos is updated only if encoding succeeds. - * \param out_size Size of the out buffer; the first byte into - * which no data is written to is out[out_size]. - */ -extern LZMA_API(lzma_ret) lzma_raw_buffer_decode( - const lzma_filter *filters, const lzma_allocator *allocator, - const uint8_t *in, size_t *in_pos, size_t in_size, - uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow; - - -/** - * \brief Get the size of the Filter Properties field - * - * This function may be useful when implementing custom file formats - * using the raw encoder and decoder. - * - * \param size Pointer to uint32_t to hold the size of the properties - * \param filter Filter ID and options (the size of the properties may - * vary depending on the options) - * - * \return - LZMA_OK - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - * - * \note This function validates the Filter ID, but does not - * necessarily validate the options. Thus, it is possible - * that this returns LZMA_OK while the following call to - * lzma_properties_encode() returns LZMA_OPTIONS_ERROR. - */ -extern LZMA_API(lzma_ret) lzma_properties_size( - uint32_t *size, const lzma_filter *filter) lzma_nothrow; - - -/** - * \brief Encode the Filter Properties field - * - * \param filter Filter ID and options - * \param props Buffer to hold the encoded options. The size of - * buffer must have been already determined with - * lzma_properties_size(). - * - * \return - LZMA_OK - * - LZMA_OPTIONS_ERROR - * - LZMA_PROG_ERROR - * - * \note Even this function won't validate more options than actually - * necessary. Thus, it is possible that encoding the properties - * succeeds but using the same options to initialize the encoder - * will fail. - * - * \note If lzma_properties_size() indicated that the size - * of the Filter Properties field is zero, calling - * lzma_properties_encode() is not required, but it - * won't do any harm either. - */ -extern LZMA_API(lzma_ret) lzma_properties_encode( - const lzma_filter *filter, uint8_t *props) lzma_nothrow; - - -/** - * \brief Decode the Filter Properties field - * - * \param filter filter->id must have been set to the correct - * Filter ID. filter->options doesn't need to be - * initialized (it's not freed by this function). The - * decoded options will be stored to filter->options. - * filter->options is set to NULL if there are no - * properties or if an error occurs. - * \param allocator Custom memory allocator used to allocate the - * options. Set to NULL to use the default malloc(), - * and in case of an error, also free(). - * \param props Input buffer containing the properties. - * \param props_size Size of the properties. This must be the exact - * size; giving too much or too little input will - * return LZMA_OPTIONS_ERROR. - * - * \return - LZMA_OK - * - LZMA_OPTIONS_ERROR - * - LZMA_MEM_ERROR - */ -extern LZMA_API(lzma_ret) lzma_properties_decode( - lzma_filter *filter, const lzma_allocator *allocator, - const uint8_t *props, size_t props_size) lzma_nothrow; - - -/** - * \brief Calculate encoded size of a Filter Flags field - * - * Knowing the size of Filter Flags is useful to know when allocating - * memory to hold the encoded Filter Flags. - * - * \param size Pointer to integer to hold the calculated size - * \param filter Filter ID and associated options whose encoded - * size is to be calculated - * - * \return - LZMA_OK: *size set successfully. Note that this doesn't - * guarantee that filter->options is valid, thus - * lzma_filter_flags_encode() may still fail. - * - LZMA_OPTIONS_ERROR: Unknown Filter ID or unsupported options. - * - LZMA_PROG_ERROR: Invalid options - * - * \note If you need to calculate size of List of Filter Flags, - * you need to loop over every lzma_filter entry. - */ -extern LZMA_API(lzma_ret) lzma_filter_flags_size( - uint32_t *size, const lzma_filter *filter) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Encode Filter Flags into given buffer - * - * In contrast to some functions, this doesn't allocate the needed buffer. - * This is due to how this function is used internally by liblzma. - * - * \param filter Filter ID and options to be encoded - * \param out Beginning of the output buffer - * \param out_pos out[*out_pos] is the next write position. This - * is updated by the encoder. - * \param out_size out[out_size] is the first byte to not write. - * - * \return - LZMA_OK: Encoding was successful. - * - LZMA_OPTIONS_ERROR: Invalid or unsupported options. - * - LZMA_PROG_ERROR: Invalid options or not enough output - * buffer space (you should have checked it with - * lzma_filter_flags_size()). - */ -extern LZMA_API(lzma_ret) lzma_filter_flags_encode(const lzma_filter *filter, - uint8_t *out, size_t *out_pos, size_t out_size) - lzma_nothrow lzma_attr_warn_unused_result; - - -/** - * \brief Decode Filter Flags from given buffer - * - * The decoded result is stored into *filter. The old value of - * filter->options is not free()d. - * - * \return - LZMA_OK - * - LZMA_OPTIONS_ERROR - * - LZMA_MEM_ERROR - * - LZMA_PROG_ERROR - */ -extern LZMA_API(lzma_ret) lzma_filter_flags_decode( - lzma_filter *filter, const lzma_allocator *allocator, - const uint8_t *in, size_t *in_pos, size_t in_size) - lzma_nothrow lzma_attr_warn_unused_result; diff --git a/game/client/third/minizip/lib/liblzma/api/lzma/lzma12.h b/game/client/third/minizip/lib/liblzma/api/lzma/lzma12.h deleted file mode 100755 index 4e32fa3a..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma/lzma12.h +++ /dev/null @@ -1,420 +0,0 @@ -/** - * \file lzma/lzma12.h - * \brief LZMA1 and LZMA2 filters - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - * - * See ../lzma.h for information about liblzma as a whole. - */ - -#ifndef LZMA_H_INTERNAL -# error Never include this file directly. Use instead. -#endif - - -/** - * \brief LZMA1 Filter ID - * - * LZMA1 is the very same thing as what was called just LZMA in LZMA Utils, - * 7-Zip, and LZMA SDK. It's called LZMA1 here to prevent developers from - * accidentally using LZMA when they actually want LZMA2. - * - * LZMA1 shouldn't be used for new applications unless you _really_ know - * what you are doing. LZMA2 is almost always a better choice. - */ -#define LZMA_FILTER_LZMA1 LZMA_VLI_C(0x4000000000000001) - -/** - * \brief LZMA2 Filter ID - * - * Usually you want this instead of LZMA1. Compared to LZMA1, LZMA2 adds - * support for LZMA_SYNC_FLUSH, uncompressed chunks (smaller expansion - * when trying to compress uncompressible data), possibility to change - * lc/lp/pb in the middle of encoding, and some other internal improvements. - */ -#define LZMA_FILTER_LZMA2 LZMA_VLI_C(0x21) - - -/** - * \brief Match finders - * - * Match finder has major effect on both speed and compression ratio. - * Usually hash chains are faster than binary trees. - * - * If you will use LZMA_SYNC_FLUSH often, the hash chains may be a better - * choice, because binary trees get much higher compression ratio penalty - * with LZMA_SYNC_FLUSH. - * - * The memory usage formulas are only rough estimates, which are closest to - * reality when dict_size is a power of two. The formulas are more complex - * in reality, and can also change a little between liblzma versions. Use - * lzma_raw_encoder_memusage() to get more accurate estimate of memory usage. - */ -typedef enum { - LZMA_MF_HC3 = 0x03, - /**< - * \brief Hash Chain with 2- and 3-byte hashing - * - * Minimum nice_len: 3 - * - * Memory usage: - * - dict_size <= 16 MiB: dict_size * 7.5 - * - dict_size > 16 MiB: dict_size * 5.5 + 64 MiB - */ - - LZMA_MF_HC4 = 0x04, - /**< - * \brief Hash Chain with 2-, 3-, and 4-byte hashing - * - * Minimum nice_len: 4 - * - * Memory usage: - * - dict_size <= 32 MiB: dict_size * 7.5 - * - dict_size > 32 MiB: dict_size * 6.5 - */ - - LZMA_MF_BT2 = 0x12, - /**< - * \brief Binary Tree with 2-byte hashing - * - * Minimum nice_len: 2 - * - * Memory usage: dict_size * 9.5 - */ - - LZMA_MF_BT3 = 0x13, - /**< - * \brief Binary Tree with 2- and 3-byte hashing - * - * Minimum nice_len: 3 - * - * Memory usage: - * - dict_size <= 16 MiB: dict_size * 11.5 - * - dict_size > 16 MiB: dict_size * 9.5 + 64 MiB - */ - - LZMA_MF_BT4 = 0x14 - /**< - * \brief Binary Tree with 2-, 3-, and 4-byte hashing - * - * Minimum nice_len: 4 - * - * Memory usage: - * - dict_size <= 32 MiB: dict_size * 11.5 - * - dict_size > 32 MiB: dict_size * 10.5 - */ -} lzma_match_finder; - - -/** - * \brief Test if given match finder is supported - * - * Return true if the given match finder is supported by this liblzma build. - * Otherwise false is returned. It is safe to call this with a value that - * isn't listed in lzma_match_finder enumeration; the return value will be - * false. - * - * There is no way to list which match finders are available in this - * particular liblzma version and build. It would be useless, because - * a new match finder, which the application developer wasn't aware, - * could require giving additional options to the encoder that the older - * match finders don't need. - */ -extern LZMA_API(lzma_bool) lzma_mf_is_supported(lzma_match_finder match_finder) - lzma_nothrow lzma_attr_const; - - -/** - * \brief Compression modes - * - * This selects the function used to analyze the data produced by the match - * finder. - */ -typedef enum { - LZMA_MODE_FAST = 1, - /**< - * \brief Fast compression - * - * Fast mode is usually at its best when combined with - * a hash chain match finder. - */ - - LZMA_MODE_NORMAL = 2 - /**< - * \brief Normal compression - * - * This is usually notably slower than fast mode. Use this - * together with binary tree match finders to expose the - * full potential of the LZMA1 or LZMA2 encoder. - */ -} lzma_mode; - - -/** - * \brief Test if given compression mode is supported - * - * Return true if the given compression mode is supported by this liblzma - * build. Otherwise false is returned. It is safe to call this with a value - * that isn't listed in lzma_mode enumeration; the return value will be false. - * - * There is no way to list which modes are available in this particular - * liblzma version and build. It would be useless, because a new compression - * mode, which the application developer wasn't aware, could require giving - * additional options to the encoder that the older modes don't need. - */ -extern LZMA_API(lzma_bool) lzma_mode_is_supported(lzma_mode mode) - lzma_nothrow lzma_attr_const; - - -/** - * \brief Options specific to the LZMA1 and LZMA2 filters - * - * Since LZMA1 and LZMA2 share most of the code, it's simplest to share - * the options structure too. For encoding, all but the reserved variables - * need to be initialized unless specifically mentioned otherwise. - * lzma_lzma_preset() can be used to get a good starting point. - * - * For raw decoding, both LZMA1 and LZMA2 need dict_size, preset_dict, and - * preset_dict_size (if preset_dict != NULL). LZMA1 needs also lc, lp, and pb. - */ -typedef struct { - /** - * \brief Dictionary size in bytes - * - * Dictionary size indicates how many bytes of the recently processed - * uncompressed data is kept in memory. One method to reduce size of - * the uncompressed data is to store distance-length pairs, which - * indicate what data to repeat from the dictionary buffer. Thus, - * the bigger the dictionary, the better the compression ratio - * usually is. - * - * Maximum size of the dictionary depends on multiple things: - * - Memory usage limit - * - Available address space (not a problem on 64-bit systems) - * - Selected match finder (encoder only) - * - * Currently the maximum dictionary size for encoding is 1.5 GiB - * (i.e. (UINT32_C(1) << 30) + (UINT32_C(1) << 29)) even on 64-bit - * systems for certain match finder implementation reasons. In the - * future, there may be match finders that support bigger - * dictionaries. - * - * Decoder already supports dictionaries up to 4 GiB - 1 B (i.e. - * UINT32_MAX), so increasing the maximum dictionary size of the - * encoder won't cause problems for old decoders. - * - * Because extremely small dictionaries sizes would have unneeded - * overhead in the decoder, the minimum dictionary size is 4096 bytes. - * - * \note When decoding, too big dictionary does no other harm - * than wasting memory. - */ - uint32_t dict_size; -# define LZMA_DICT_SIZE_MIN UINT32_C(4096) -# define LZMA_DICT_SIZE_DEFAULT (UINT32_C(1) << 23) - - /** - * \brief Pointer to an initial dictionary - * - * It is possible to initialize the LZ77 history window using - * a preset dictionary. It is useful when compressing many - * similar, relatively small chunks of data independently from - * each other. The preset dictionary should contain typical - * strings that occur in the files being compressed. The most - * probable strings should be near the end of the preset dictionary. - * - * This feature should be used only in special situations. For - * now, it works correctly only with raw encoding and decoding. - * Currently none of the container formats supported by - * liblzma allow preset dictionary when decoding, thus if - * you create a .xz or .lzma file with preset dictionary, it - * cannot be decoded with the regular decoder functions. In the - * future, the .xz format will likely get support for preset - * dictionary though. - */ - const uint8_t *preset_dict; - - /** - * \brief Size of the preset dictionary - * - * Specifies the size of the preset dictionary. If the size is - * bigger than dict_size, only the last dict_size bytes are - * processed. - * - * This variable is read only when preset_dict is not NULL. - * If preset_dict is not NULL but preset_dict_size is zero, - * no preset dictionary is used (identical to only setting - * preset_dict to NULL). - */ - uint32_t preset_dict_size; - - /** - * \brief Number of literal context bits - * - * How many of the highest bits of the previous uncompressed - * eight-bit byte (also known as `literal') are taken into - * account when predicting the bits of the next literal. - * - * E.g. in typical English text, an upper-case letter is - * often followed by a lower-case letter, and a lower-case - * letter is usually followed by another lower-case letter. - * In the US-ASCII character set, the highest three bits are 010 - * for upper-case letters and 011 for lower-case letters. - * When lc is at least 3, the literal coding can take advantage of - * this property in the uncompressed data. - * - * There is a limit that applies to literal context bits and literal - * position bits together: lc + lp <= 4. Without this limit the - * decoding could become very slow, which could have security related - * results in some cases like email servers doing virus scanning. - * This limit also simplifies the internal implementation in liblzma. - * - * There may be LZMA1 streams that have lc + lp > 4 (maximum possible - * lc would be 8). It is not possible to decode such streams with - * liblzma. - */ - uint32_t lc; -# define LZMA_LCLP_MIN 0 -# define LZMA_LCLP_MAX 4 -# define LZMA_LC_DEFAULT 3 - - /** - * \brief Number of literal position bits - * - * lp affects what kind of alignment in the uncompressed data is - * assumed when encoding literals. A literal is a single 8-bit byte. - * See pb below for more information about alignment. - */ - uint32_t lp; -# define LZMA_LP_DEFAULT 0 - - /** - * \brief Number of position bits - * - * pb affects what kind of alignment in the uncompressed data is - * assumed in general. The default means four-byte alignment - * (2^ pb =2^2=4), which is often a good choice when there's - * no better guess. - * - * When the aligment is known, setting pb accordingly may reduce - * the file size a little. E.g. with text files having one-byte - * alignment (US-ASCII, ISO-8859-*, UTF-8), setting pb=0 can - * improve compression slightly. For UTF-16 text, pb=1 is a good - * choice. If the alignment is an odd number like 3 bytes, pb=0 - * might be the best choice. - * - * Even though the assumed alignment can be adjusted with pb and - * lp, LZMA1 and LZMA2 still slightly favor 16-byte alignment. - * It might be worth taking into account when designing file formats - * that are likely to be often compressed with LZMA1 or LZMA2. - */ - uint32_t pb; -# define LZMA_PB_MIN 0 -# define LZMA_PB_MAX 4 -# define LZMA_PB_DEFAULT 2 - - /** Compression mode */ - lzma_mode mode; - - /** - * \brief Nice length of a match - * - * This determines how many bytes the encoder compares from the match - * candidates when looking for the best match. Once a match of at - * least nice_len bytes long is found, the encoder stops looking for - * better candidates and encodes the match. (Naturally, if the found - * match is actually longer than nice_len, the actual length is - * encoded; it's not truncated to nice_len.) - * - * Bigger values usually increase the compression ratio and - * compression time. For most files, 32 to 128 is a good value, - * which gives very good compression ratio at good speed. - * - * The exact minimum value depends on the match finder. The maximum - * is 273, which is the maximum length of a match that LZMA1 and - * LZMA2 can encode. - */ - uint32_t nice_len; - - /** Match finder ID */ - lzma_match_finder mf; - - /** - * \brief Maximum search depth in the match finder - * - * For every input byte, match finder searches through the hash chain - * or binary tree in a loop, each iteration going one step deeper in - * the chain or tree. The searching stops if - * - a match of at least nice_len bytes long is found; - * - all match candidates from the hash chain or binary tree have - * been checked; or - * - maximum search depth is reached. - * - * Maximum search depth is needed to prevent the match finder from - * wasting too much time in case there are lots of short match - * candidates. On the other hand, stopping the search before all - * candidates have been checked can reduce compression ratio. - * - * Setting depth to zero tells liblzma to use an automatic default - * value, that depends on the selected match finder and nice_len. - * The default is in the range [4, 200] or so (it may vary between - * liblzma versions). - * - * Using a bigger depth value than the default can increase - * compression ratio in some cases. There is no strict maximum value, - * but high values (thousands or millions) should be used with care: - * the encoder could remain fast enough with typical input, but - * malicious input could cause the match finder to slow down - * dramatically, possibly creating a denial of service attack. - */ - uint32_t depth; - - /* - * Reserved space to allow possible future extensions without - * breaking the ABI. You should not touch these, because the names - * of these variables may change. These are and will never be used - * with the currently supported options, so it is safe to leave these - * uninitialized. - */ - uint32_t reserved_int1; - uint32_t reserved_int2; - uint32_t reserved_int3; - uint32_t reserved_int4; - uint32_t reserved_int5; - uint32_t reserved_int6; - uint32_t reserved_int7; - uint32_t reserved_int8; - lzma_reserved_enum reserved_enum1; - lzma_reserved_enum reserved_enum2; - lzma_reserved_enum reserved_enum3; - lzma_reserved_enum reserved_enum4; - void *reserved_ptr1; - void *reserved_ptr2; - -} lzma_options_lzma; - - -/** - * \brief Set a compression preset to lzma_options_lzma structure - * - * 0 is the fastest and 9 is the slowest. These match the switches -0 .. -9 - * of the xz command line tool. In addition, it is possible to bitwise-or - * flags to the preset. Currently only LZMA_PRESET_EXTREME is supported. - * The flags are defined in container.h, because the flags are used also - * with lzma_easy_encoder(). - * - * The preset values are subject to changes between liblzma versions. - * - * This function is available only if LZMA1 or LZMA2 encoder has been enabled - * when building liblzma. - * - * \return On success, false is returned. If the preset is not - * supported, true is returned. - */ -extern LZMA_API(lzma_bool) lzma_lzma_preset( - lzma_options_lzma *options, uint32_t preset) lzma_nothrow; diff --git a/game/client/third/minizip/lib/liblzma/api/lzma/version.h b/game/client/third/minizip/lib/liblzma/api/lzma/version.h deleted file mode 100755 index b5e061c2..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma/version.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * \file lzma/version.h - * \brief Version number - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - * - * See ../lzma.h for information about liblzma as a whole. - */ - -#ifndef LZMA_H_INTERNAL -# error Never include this file directly. Use instead. -#endif - - -/* - * Version number split into components - */ -#define LZMA_VERSION_MAJOR 5 -#define LZMA_VERSION_MINOR 2 -#define LZMA_VERSION_PATCH 3 -#define LZMA_VERSION_STABILITY LZMA_VERSION_STABILITY_STABLE - -#ifndef LZMA_VERSION_COMMIT -# define LZMA_VERSION_COMMIT "" -#endif - - -/* - * Map symbolic stability levels to integers. - */ -#define LZMA_VERSION_STABILITY_ALPHA 0 -#define LZMA_VERSION_STABILITY_BETA 1 -#define LZMA_VERSION_STABILITY_STABLE 2 - - -/** - * \brief Compile-time version number - * - * The version number is of format xyyyzzzs where - * - x = major - * - yyy = minor - * - zzz = revision - * - s indicates stability: 0 = alpha, 1 = beta, 2 = stable - * - * The same xyyyzzz triplet is never reused with different stability levels. - * For example, if 5.1.0alpha has been released, there will never be 5.1.0beta - * or 5.1.0 stable. - * - * \note The version number of liblzma has nothing to with - * the version number of Igor Pavlov's LZMA SDK. - */ -#define LZMA_VERSION (LZMA_VERSION_MAJOR * UINT32_C(10000000) \ - + LZMA_VERSION_MINOR * UINT32_C(10000) \ - + LZMA_VERSION_PATCH * UINT32_C(10) \ - + LZMA_VERSION_STABILITY) - - -/* - * Macros to construct the compile-time version string - */ -#if LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_ALPHA -# define LZMA_VERSION_STABILITY_STRING "alpha" -#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_BETA -# define LZMA_VERSION_STABILITY_STRING "beta" -#elif LZMA_VERSION_STABILITY == LZMA_VERSION_STABILITY_STABLE -# define LZMA_VERSION_STABILITY_STRING "" -#else -# error Incorrect LZMA_VERSION_STABILITY -#endif - -#define LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit) \ - #major "." #minor "." #patch stability commit - -#define LZMA_VERSION_STRING_C(major, minor, patch, stability, commit) \ - LZMA_VERSION_STRING_C_(major, minor, patch, stability, commit) - - -/** - * \brief Compile-time version as a string - * - * This can be for example "4.999.5alpha", "4.999.8beta", or "5.0.0" (stable - * versions don't have any "stable" suffix). In future, a snapshot built - * from source code repository may include an additional suffix, for example - * "4.999.8beta-21-g1d92". The commit ID won't be available in numeric form - * in LZMA_VERSION macro. - */ -#define LZMA_VERSION_STRING LZMA_VERSION_STRING_C( \ - LZMA_VERSION_MAJOR, LZMA_VERSION_MINOR, \ - LZMA_VERSION_PATCH, LZMA_VERSION_STABILITY_STRING, \ - LZMA_VERSION_COMMIT) - - -/* #ifndef is needed for use with windres (MinGW or Cygwin). */ -#ifndef LZMA_H_INTERNAL_RC - -/** - * \brief Run-time version number as an integer - * - * Return the value of LZMA_VERSION macro at the compile time of liblzma. - * This allows the application to compare if it was built against the same, - * older, or newer version of liblzma that is currently running. - */ -extern LZMA_API(uint32_t) lzma_version_number(void) - lzma_nothrow lzma_attr_const; - - -/** - * \brief Run-time version as a string - * - * This function may be useful if you want to display which version of - * liblzma your application is currently using. - */ -extern LZMA_API(const char *) lzma_version_string(void) - lzma_nothrow lzma_attr_const; - -#endif diff --git a/game/client/third/minizip/lib/liblzma/api/lzma/vli.h b/game/client/third/minizip/lib/liblzma/api/lzma/vli.h deleted file mode 100755 index 9ad13f2e..00000000 --- a/game/client/third/minizip/lib/liblzma/api/lzma/vli.h +++ /dev/null @@ -1,166 +0,0 @@ -/** - * \file lzma/vli.h - * \brief Variable-length integer handling - * - * In the .xz format, most integers are encoded in a variable-length - * representation, which is sometimes called little endian base-128 encoding. - * This saves space when smaller values are more likely than bigger values. - * - * The encoding scheme encodes seven bits to every byte, using minimum - * number of bytes required to represent the given value. Encodings that use - * non-minimum number of bytes are invalid, thus every integer has exactly - * one encoded representation. The maximum number of bits in a VLI is 63, - * thus the vli argument must be less than or equal to UINT64_MAX / 2. You - * should use LZMA_VLI_MAX for clarity. - */ - -/* - * Author: Lasse Collin - * - * This file has been put into the public domain. - * You can do whatever you want with this file. - * - * See ../lzma.h for information about liblzma as a whole. - */ - -#ifndef LZMA_H_INTERNAL -# error Never include this file directly. Use instead. -#endif - - -/** - * \brief Maximum supported value of a variable-length integer - */ -#define LZMA_VLI_MAX (UINT64_MAX / 2) - -/** - * \brief VLI value to denote that the value is unknown - */ -#define LZMA_VLI_UNKNOWN UINT64_MAX - -/** - * \brief Maximum supported encoded length of variable length integers - */ -#define LZMA_VLI_BYTES_MAX 9 - -/** - * \brief VLI constant suffix - */ -#define LZMA_VLI_C(n) UINT64_C(n) - - -/** - * \brief Variable-length integer type - * - * Valid VLI values are in the range [0, LZMA_VLI_MAX]. Unknown value is - * indicated with LZMA_VLI_UNKNOWN, which is the maximum value of the - * underlaying integer type. - * - * lzma_vli will be uint64_t for the foreseeable future. If a bigger size - * is needed in the future, it is guaranteed that 2 * LZMA_VLI_MAX will - * not overflow lzma_vli. This simplifies integer overflow detection. - */ -typedef uint64_t lzma_vli; - - -/** - * \brief Validate a variable-length integer - * - * This is useful to test that application has given acceptable values - * for example in the uncompressed_size and compressed_size variables. - * - * \return True if the integer is representable as VLI or if it - * indicates unknown value. - */ -#define lzma_vli_is_valid(vli) \ - ((vli) <= LZMA_VLI_MAX || (vli) == LZMA_VLI_UNKNOWN) - - -/** - * \brief Encode a variable-length integer - * - * This function has two modes: single-call and multi-call. Single-call mode - * encodes the whole integer at once; it is an error if the output buffer is - * too small. Multi-call mode saves the position in *vli_pos, and thus it is - * possible to continue encoding if the buffer becomes full before the whole - * integer has been encoded. - * - * \param vli Integer to be encoded - * \param vli_pos How many VLI-encoded bytes have already been written - * out. When starting to encode a new integer in - * multi-call mode, *vli_pos must be set to zero. - * To use single-call encoding, set vli_pos to NULL. - * \param out Beginning of the output buffer - * \param out_pos The next byte will be written to out[*out_pos]. - * \param out_size Size of the out buffer; the first byte into - * which no data is written to is out[out_size]. - * - * \return Slightly different return values are used in multi-call and - * single-call modes. - * - * Single-call (vli_pos == NULL): - * - LZMA_OK: Integer successfully encoded. - * - LZMA_PROG_ERROR: Arguments are not sane. This can be due - * to too little output space; single-call mode doesn't use - * LZMA_BUF_ERROR, since the application should have checked - * the encoded size with lzma_vli_size(). - * - * Multi-call (vli_pos != NULL): - * - LZMA_OK: So far all OK, but the integer is not - * completely written out yet. - * - LZMA_STREAM_END: Integer successfully encoded. - * - LZMA_BUF_ERROR: No output space was provided. - * - LZMA_PROG_ERROR: Arguments are not sane. - */ -extern LZMA_API(lzma_ret) lzma_vli_encode(lzma_vli vli, size_t *vli_pos, - uint8_t *out, size_t *out_pos, size_t out_size) lzma_nothrow; - - -/** - * \brief Decode a variable-length integer - * - * Like lzma_vli_encode(), this function has single-call and multi-call modes. - * - * \param vli Pointer to decoded integer. The decoder will - * initialize it to zero when *vli_pos == 0, so - * application isn't required to initialize *vli. - * \param vli_pos How many bytes have already been decoded. When - * starting to decode a new integer in multi-call - * mode, *vli_pos must be initialized to zero. To - * use single-call decoding, set vli_pos to NULL. - * \param in Beginning of the input buffer - * \param in_pos The next byte will be read from in[*in_pos]. - * \param in_size Size of the input buffer; the first byte that - * won't be read is in[in_size]. - * - * \return Slightly different return values are used in multi-call and - * single-call modes. - * - * Single-call (vli_pos == NULL): - * - LZMA_OK: Integer successfully decoded. - * - LZMA_DATA_ERROR: Integer is corrupt. This includes hitting - * the end of the input buffer before the whole integer was - * decoded; providing no input at all will use LZMA_DATA_ERROR. - * - LZMA_PROG_ERROR: Arguments are not sane. - * - * Multi-call (vli_pos != NULL): - * - LZMA_OK: So far all OK, but the integer is not - * completely decoded yet. - * - LZMA_STREAM_END: Integer successfully decoded. - * - LZMA_DATA_ERROR: Integer is corrupt. - * - LZMA_BUF_ERROR: No input was provided. - * - LZMA_PROG_ERROR: Arguments are not sane. - */ -extern LZMA_API(lzma_ret) lzma_vli_decode(lzma_vli *vli, size_t *vli_pos, - const uint8_t *in, size_t *in_pos, size_t in_size) - lzma_nothrow; - - -/** - * \brief Get the number of bytes required to encode a VLI - * - * \return Number of bytes on success (1-9). If vli isn't valid, - * zero is returned. - */ -extern LZMA_API(uint32_t) lzma_vli_size(lzma_vli vli) - lzma_nothrow lzma_attr_pure; diff --git a/game/client/third/minizip/lib/liblzma/check/check.c b/game/client/third/minizip/lib/liblzma/check/check.c deleted file mode 100755 index 428ddaeb..00000000 --- a/game/client/third/minizip/lib/liblzma/check/check.c +++ /dev/null @@ -1,174 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file check.c -/// \brief Single API to access different integrity checks -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "check.h" - - -extern LZMA_API(lzma_bool) -lzma_check_is_supported(lzma_check type) -{ - if ((unsigned int)(type) > LZMA_CHECK_ID_MAX) - return false; - - static const lzma_bool available_checks[LZMA_CHECK_ID_MAX + 1] = { - true, // LZMA_CHECK_NONE - -#ifdef HAVE_CHECK_CRC32 - true, -#else - false, -#endif - - false, // Reserved - false, // Reserved - -#ifdef HAVE_CHECK_CRC64 - true, -#else - false, -#endif - - false, // Reserved - false, // Reserved - false, // Reserved - false, // Reserved - false, // Reserved - -#ifdef HAVE_CHECK_SHA256 - true, -#else - false, -#endif - - false, // Reserved - false, // Reserved - false, // Reserved - false, // Reserved - false, // Reserved - }; - - return available_checks[(unsigned int)(type)]; -} - - -extern LZMA_API(uint32_t) -lzma_check_size(lzma_check type) -{ - if ((unsigned int)(type) > LZMA_CHECK_ID_MAX) - return UINT32_MAX; - - // See file-format.txt section 2.1.1.2. - static const uint8_t check_sizes[LZMA_CHECK_ID_MAX + 1] = { - 0, - 4, 4, 4, - 8, 8, 8, - 16, 16, 16, - 32, 32, 32, - 64, 64, 64 - }; - - return check_sizes[(unsigned int)(type)]; -} - - -extern void -lzma_check_init(lzma_check_state *check, lzma_check type) -{ - switch (type) { - case LZMA_CHECK_NONE: - break; - -#ifdef HAVE_CHECK_CRC32 - case LZMA_CHECK_CRC32: - check->state.crc32 = 0; - break; -#endif - -#ifdef HAVE_CHECK_CRC64 - case LZMA_CHECK_CRC64: - check->state.crc64 = 0; - break; -#endif - -#ifdef HAVE_CHECK_SHA256 - case LZMA_CHECK_SHA256: - lzma_sha256_init(check); - break; -#endif - - default: - break; - } - - return; -} - - -extern void -lzma_check_update(lzma_check_state *check, lzma_check type, - const uint8_t *buf, size_t size) -{ - switch (type) { -#ifdef HAVE_CHECK_CRC32 - case LZMA_CHECK_CRC32: - check->state.crc32 = lzma_crc32(buf, size, check->state.crc32); - break; -#endif - -#ifdef HAVE_CHECK_CRC64 - case LZMA_CHECK_CRC64: - check->state.crc64 = lzma_crc64(buf, size, check->state.crc64); - break; -#endif - -#ifdef HAVE_CHECK_SHA256 - case LZMA_CHECK_SHA256: - lzma_sha256_update(buf, size, check); - break; -#endif - - default: - break; - } - - return; -} - - -extern void -lzma_check_finish(lzma_check_state *check, lzma_check type) -{ - switch (type) { -#ifdef HAVE_CHECK_CRC32 - case LZMA_CHECK_CRC32: - check->buffer.u32[0] = conv32le(check->state.crc32); - break; -#endif - -#ifdef HAVE_CHECK_CRC64 - case LZMA_CHECK_CRC64: - check->buffer.u64[0] = conv64le(check->state.crc64); - break; -#endif - -#ifdef HAVE_CHECK_SHA256 - case LZMA_CHECK_SHA256: - lzma_sha256_finish(check); - break; -#endif - - default: - break; - } - - return; -} diff --git a/game/client/third/minizip/lib/liblzma/check/check.h b/game/client/third/minizip/lib/liblzma/check/check.h deleted file mode 100755 index 554a7417..00000000 --- a/game/client/third/minizip/lib/liblzma/check/check.h +++ /dev/null @@ -1,172 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file check.h -/// \brief Internal API to different integrity check functions -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_CHECK_H -#define LZMA_CHECK_H - -#include "common.h" - -// If the function for external SHA-256 is missing, use the internal SHA-256 -// code. Due to how configure works, these defines can only get defined when -// both a usable header and a type have already been found. -#if !(defined(HAVE_CC_SHA256_INIT) \ - || defined(HAVE_SHA256_INIT) \ - || defined(HAVE_SHA256INIT)) -# define HAVE_INTERNAL_SHA256 1 -#endif - -#if defined(HAVE_INTERNAL_SHA256) -// Nothing -#elif defined(HAVE_COMMONCRYPTO_COMMONDIGEST_H) -# include -#elif defined(HAVE_SHA256_H) -# include -# include -#elif defined(HAVE_SHA2_H) -# include -# include -#endif - -#if defined(HAVE_INTERNAL_SHA256) -/// State for the internal SHA-256 implementation -typedef struct { - /// Internal state - uint32_t state[8]; - - /// Size of the message excluding padding - uint64_t size; -} lzma_sha256_state; -#elif defined(HAVE_CC_SHA256_CTX) -typedef CC_SHA256_CTX lzma_sha256_state; -#elif defined(HAVE_SHA256_CTX) -typedef SHA256_CTX lzma_sha256_state; -#elif defined(HAVE_SHA2_CTX) -typedef SHA2_CTX lzma_sha256_state; -#endif - -#if defined(HAVE_INTERNAL_SHA256) -// Nothing -#elif defined(HAVE_CC_SHA256_INIT) -# define LZMA_SHA256FUNC(x) CC_SHA256_ ## x -#elif defined(HAVE_SHA256_INIT) -# define LZMA_SHA256FUNC(x) SHA256_ ## x -#elif defined(HAVE_SHA256INIT) -# define LZMA_SHA256FUNC(x) SHA256 ## x -#endif - -// Index hashing needs the best possible hash function (preferably -// a cryptographic hash) for maximum reliability. -#if defined(HAVE_CHECK_SHA256) -# define LZMA_CHECK_BEST LZMA_CHECK_SHA256 -#elif defined(HAVE_CHECK_CRC64) -# define LZMA_CHECK_BEST LZMA_CHECK_CRC64 -#else -# define LZMA_CHECK_BEST LZMA_CHECK_CRC32 -#endif - - -/// \brief Structure to hold internal state of the check being calculated -/// -/// \note This is not in the public API because this structure may -/// change in future if new integrity check algorithms are added. -typedef struct { - /// Buffer to hold the final result and a temporary buffer for SHA256. - union { - uint8_t u8[64]; - uint32_t u32[16]; - uint64_t u64[8]; - } buffer; - - /// Check-specific data - union { - uint32_t crc32; - uint64_t crc64; - lzma_sha256_state sha256; - } state; - -} lzma_check_state; - - -/// lzma_crc32_table[0] is needed by LZ encoder so we need to keep -/// the array two-dimensional. -#ifdef HAVE_SMALL -extern uint32_t lzma_crc32_table[1][256]; -extern void lzma_crc32_init(void); -#else -extern const uint32_t lzma_crc32_table[8][256]; -extern const uint64_t lzma_crc64_table[4][256]; -#endif - - -/// \brief Initialize *check depending on type -/// -/// \param check LZMA_OK on success. LZMA_UNSUPPORTED_CHECK if the type -/// is not supported by the current version or build of -/// liblzma. LZMA_PROG_ERROR if type > LZMA_CHECK_ID_MAX. -extern void lzma_check_init(lzma_check_state *check, lzma_check type); - -/// Update the check state -extern void lzma_check_update(lzma_check_state *check, lzma_check type, - const uint8_t *buf, size_t size); - -/// Finish the check calculation and store the result to check->buffer.u8. -extern void lzma_check_finish(lzma_check_state *check, lzma_check type); - - -#ifndef LZMA_SHA256FUNC - -/// Prepare SHA-256 state for new input. -extern void lzma_sha256_init(lzma_check_state *check); - -/// Update the SHA-256 hash state -extern void lzma_sha256_update( - const uint8_t *buf, size_t size, lzma_check_state *check); - -/// Finish the SHA-256 calculation and store the result to check->buffer.u8. -extern void lzma_sha256_finish(lzma_check_state *check); - - -#else - -static inline void -lzma_sha256_init(lzma_check_state *check) -{ - LZMA_SHA256FUNC(Init)(&check->state.sha256); -} - - -static inline void -lzma_sha256_update(const uint8_t *buf, size_t size, lzma_check_state *check) -{ -#if defined(HAVE_CC_SHA256_INIT) && SIZE_MAX > UINT32_MAX - // Darwin's CC_SHA256_Update takes uint32_t as the buffer size, - // so use a loop to support size_t. - while (size > UINT32_MAX) { - LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, UINT32_MAX); - buf += UINT32_MAX; - size -= UINT32_MAX; - } -#endif - - LZMA_SHA256FUNC(Update)(&check->state.sha256, buf, size); -} - - -static inline void -lzma_sha256_finish(lzma_check_state *check) -{ - LZMA_SHA256FUNC(Final)(check->buffer.u8, &check->state.sha256); -} - -#endif - -#endif diff --git a/game/client/third/minizip/lib/liblzma/check/crc32_fast.c b/game/client/third/minizip/lib/liblzma/check/crc32_fast.c deleted file mode 100755 index 94da8559..00000000 --- a/game/client/third/minizip/lib/liblzma/check/crc32_fast.c +++ /dev/null @@ -1,82 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file crc32.c -/// \brief CRC32 calculation -/// -/// Calculate the CRC32 using the slice-by-eight algorithm. -/// It is explained in this document: -/// http://www.intel.com/technology/comms/perfnet/download/CRC_generators.pdf -/// The code in this file is not the same as in Intel's paper, but -/// the basic principle is identical. -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "check.h" -#include "crc_macros.h" - - -// If you make any changes, do some bench marking! Seemingly unrelated -// changes can very easily ruin the performance (and very probably is -// very compiler dependent). -extern LZMA_API(uint32_t) -lzma_crc32(const uint8_t *buf, size_t size, uint32_t crc) -{ - crc = ~crc; - -#ifdef WORDS_BIGENDIAN - crc = bswap32(crc); -#endif - - if (size > 8) { - // Fix the alignment, if needed. The if statement above - // ensures that this won't read past the end of buf[]. - while ((uintptr_t)(buf) & 7) { - crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc); - --size; - } - - // Calculate the position where to stop. - const uint8_t *const limit = buf + (size & ~(size_t)(7)); - - // Calculate how many bytes must be calculated separately - // before returning the result. - size &= (size_t)(7); - - // Calculate the CRC32 using the slice-by-eight algorithm. - while (buf < limit) { - crc ^= *(const uint32_t *)(buf); - buf += 4; - - crc = lzma_crc32_table[7][A(crc)] - ^ lzma_crc32_table[6][B(crc)] - ^ lzma_crc32_table[5][C(crc)] - ^ lzma_crc32_table[4][D(crc)]; - - const uint32_t tmp = *(const uint32_t *)(buf); - buf += 4; - - // At least with some compilers, it is critical for - // performance, that the crc variable is XORed - // between the two table-lookup pairs. - crc = lzma_crc32_table[3][A(tmp)] - ^ lzma_crc32_table[2][B(tmp)] - ^ crc - ^ lzma_crc32_table[1][C(tmp)] - ^ lzma_crc32_table[0][D(tmp)]; - } - } - - while (size-- != 0) - crc = lzma_crc32_table[0][*buf++ ^ A(crc)] ^ S8(crc); - -#ifdef WORDS_BIGENDIAN - crc = bswap32(crc); -#endif - - return ~crc; -} diff --git a/game/client/third/minizip/lib/liblzma/check/crc32_table.c b/game/client/third/minizip/lib/liblzma/check/crc32_table.c deleted file mode 100755 index 368874eb..00000000 --- a/game/client/third/minizip/lib/liblzma/check/crc32_table.c +++ /dev/null @@ -1,19 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file crc32_table.c -/// \brief Precalculated CRC32 table with correct endianness -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "common.h" - -#ifdef WORDS_BIGENDIAN -# include "crc32_table_be.h" -#else -# include "crc32_table_le.h" -#endif diff --git a/game/client/third/minizip/lib/liblzma/check/crc32_table_be.h b/game/client/third/minizip/lib/liblzma/check/crc32_table_be.h deleted file mode 100755 index c483cb67..00000000 --- a/game/client/third/minizip/lib/liblzma/check/crc32_table_be.h +++ /dev/null @@ -1,525 +0,0 @@ -/* This file has been automatically generated by crc32_tablegen.c. */ - -const uint32_t lzma_crc32_table[8][256] = { - { - 0x00000000, 0x96300777, 0x2C610EEE, 0xBA510999, - 0x19C46D07, 0x8FF46A70, 0x35A563E9, 0xA395649E, - 0x3288DB0E, 0xA4B8DC79, 0x1EE9D5E0, 0x88D9D297, - 0x2B4CB609, 0xBD7CB17E, 0x072DB8E7, 0x911DBF90, - 0x6410B71D, 0xF220B06A, 0x4871B9F3, 0xDE41BE84, - 0x7DD4DA1A, 0xEBE4DD6D, 0x51B5D4F4, 0xC785D383, - 0x56986C13, 0xC0A86B64, 0x7AF962FD, 0xECC9658A, - 0x4F5C0114, 0xD96C0663, 0x633D0FFA, 0xF50D088D, - 0xC8206E3B, 0x5E10694C, 0xE44160D5, 0x727167A2, - 0xD1E4033C, 0x47D4044B, 0xFD850DD2, 0x6BB50AA5, - 0xFAA8B535, 0x6C98B242, 0xD6C9BBDB, 0x40F9BCAC, - 0xE36CD832, 0x755CDF45, 0xCF0DD6DC, 0x593DD1AB, - 0xAC30D926, 0x3A00DE51, 0x8051D7C8, 0x1661D0BF, - 0xB5F4B421, 0x23C4B356, 0x9995BACF, 0x0FA5BDB8, - 0x9EB80228, 0x0888055F, 0xB2D90CC6, 0x24E90BB1, - 0x877C6F2F, 0x114C6858, 0xAB1D61C1, 0x3D2D66B6, - 0x9041DC76, 0x0671DB01, 0xBC20D298, 0x2A10D5EF, - 0x8985B171, 0x1FB5B606, 0xA5E4BF9F, 0x33D4B8E8, - 0xA2C90778, 0x34F9000F, 0x8EA80996, 0x18980EE1, - 0xBB0D6A7F, 0x2D3D6D08, 0x976C6491, 0x015C63E6, - 0xF4516B6B, 0x62616C1C, 0xD8306585, 0x4E0062F2, - 0xED95066C, 0x7BA5011B, 0xC1F40882, 0x57C40FF5, - 0xC6D9B065, 0x50E9B712, 0xEAB8BE8B, 0x7C88B9FC, - 0xDF1DDD62, 0x492DDA15, 0xF37CD38C, 0x654CD4FB, - 0x5861B24D, 0xCE51B53A, 0x7400BCA3, 0xE230BBD4, - 0x41A5DF4A, 0xD795D83D, 0x6DC4D1A4, 0xFBF4D6D3, - 0x6AE96943, 0xFCD96E34, 0x468867AD, 0xD0B860DA, - 0x732D0444, 0xE51D0333, 0x5F4C0AAA, 0xC97C0DDD, - 0x3C710550, 0xAA410227, 0x10100BBE, 0x86200CC9, - 0x25B56857, 0xB3856F20, 0x09D466B9, 0x9FE461CE, - 0x0EF9DE5E, 0x98C9D929, 0x2298D0B0, 0xB4A8D7C7, - 0x173DB359, 0x810DB42E, 0x3B5CBDB7, 0xAD6CBAC0, - 0x2083B8ED, 0xB6B3BF9A, 0x0CE2B603, 0x9AD2B174, - 0x3947D5EA, 0xAF77D29D, 0x1526DB04, 0x8316DC73, - 0x120B63E3, 0x843B6494, 0x3E6A6D0D, 0xA85A6A7A, - 0x0BCF0EE4, 0x9DFF0993, 0x27AE000A, 0xB19E077D, - 0x44930FF0, 0xD2A30887, 0x68F2011E, 0xFEC20669, - 0x5D5762F7, 0xCB676580, 0x71366C19, 0xE7066B6E, - 0x761BD4FE, 0xE02BD389, 0x5A7ADA10, 0xCC4ADD67, - 0x6FDFB9F9, 0xF9EFBE8E, 0x43BEB717, 0xD58EB060, - 0xE8A3D6D6, 0x7E93D1A1, 0xC4C2D838, 0x52F2DF4F, - 0xF167BBD1, 0x6757BCA6, 0xDD06B53F, 0x4B36B248, - 0xDA2B0DD8, 0x4C1B0AAF, 0xF64A0336, 0x607A0441, - 0xC3EF60DF, 0x55DF67A8, 0xEF8E6E31, 0x79BE6946, - 0x8CB361CB, 0x1A8366BC, 0xA0D26F25, 0x36E26852, - 0x95770CCC, 0x03470BBB, 0xB9160222, 0x2F260555, - 0xBE3BBAC5, 0x280BBDB2, 0x925AB42B, 0x046AB35C, - 0xA7FFD7C2, 0x31CFD0B5, 0x8B9ED92C, 0x1DAEDE5B, - 0xB0C2649B, 0x26F263EC, 0x9CA36A75, 0x0A936D02, - 0xA906099C, 0x3F360EEB, 0x85670772, 0x13570005, - 0x824ABF95, 0x147AB8E2, 0xAE2BB17B, 0x381BB60C, - 0x9B8ED292, 0x0DBED5E5, 0xB7EFDC7C, 0x21DFDB0B, - 0xD4D2D386, 0x42E2D4F1, 0xF8B3DD68, 0x6E83DA1F, - 0xCD16BE81, 0x5B26B9F6, 0xE177B06F, 0x7747B718, - 0xE65A0888, 0x706A0FFF, 0xCA3B0666, 0x5C0B0111, - 0xFF9E658F, 0x69AE62F8, 0xD3FF6B61, 0x45CF6C16, - 0x78E20AA0, 0xEED20DD7, 0x5483044E, 0xC2B30339, - 0x612667A7, 0xF71660D0, 0x4D476949, 0xDB776E3E, - 0x4A6AD1AE, 0xDC5AD6D9, 0x660BDF40, 0xF03BD837, - 0x53AEBCA9, 0xC59EBBDE, 0x7FCFB247, 0xE9FFB530, - 0x1CF2BDBD, 0x8AC2BACA, 0x3093B353, 0xA6A3B424, - 0x0536D0BA, 0x9306D7CD, 0x2957DE54, 0xBF67D923, - 0x2E7A66B3, 0xB84A61C4, 0x021B685D, 0x942B6F2A, - 0x37BE0BB4, 0xA18E0CC3, 0x1BDF055A, 0x8DEF022D - }, { - 0x00000000, 0x41311B19, 0x82623632, 0xC3532D2B, - 0x04C56C64, 0x45F4777D, 0x86A75A56, 0xC796414F, - 0x088AD9C8, 0x49BBC2D1, 0x8AE8EFFA, 0xCBD9F4E3, - 0x0C4FB5AC, 0x4D7EAEB5, 0x8E2D839E, 0xCF1C9887, - 0x5112C24A, 0x1023D953, 0xD370F478, 0x9241EF61, - 0x55D7AE2E, 0x14E6B537, 0xD7B5981C, 0x96848305, - 0x59981B82, 0x18A9009B, 0xDBFA2DB0, 0x9ACB36A9, - 0x5D5D77E6, 0x1C6C6CFF, 0xDF3F41D4, 0x9E0E5ACD, - 0xA2248495, 0xE3159F8C, 0x2046B2A7, 0x6177A9BE, - 0xA6E1E8F1, 0xE7D0F3E8, 0x2483DEC3, 0x65B2C5DA, - 0xAAAE5D5D, 0xEB9F4644, 0x28CC6B6F, 0x69FD7076, - 0xAE6B3139, 0xEF5A2A20, 0x2C09070B, 0x6D381C12, - 0xF33646DF, 0xB2075DC6, 0x715470ED, 0x30656BF4, - 0xF7F32ABB, 0xB6C231A2, 0x75911C89, 0x34A00790, - 0xFBBC9F17, 0xBA8D840E, 0x79DEA925, 0x38EFB23C, - 0xFF79F373, 0xBE48E86A, 0x7D1BC541, 0x3C2ADE58, - 0x054F79F0, 0x447E62E9, 0x872D4FC2, 0xC61C54DB, - 0x018A1594, 0x40BB0E8D, 0x83E823A6, 0xC2D938BF, - 0x0DC5A038, 0x4CF4BB21, 0x8FA7960A, 0xCE968D13, - 0x0900CC5C, 0x4831D745, 0x8B62FA6E, 0xCA53E177, - 0x545DBBBA, 0x156CA0A3, 0xD63F8D88, 0x970E9691, - 0x5098D7DE, 0x11A9CCC7, 0xD2FAE1EC, 0x93CBFAF5, - 0x5CD76272, 0x1DE6796B, 0xDEB55440, 0x9F844F59, - 0x58120E16, 0x1923150F, 0xDA703824, 0x9B41233D, - 0xA76BFD65, 0xE65AE67C, 0x2509CB57, 0x6438D04E, - 0xA3AE9101, 0xE29F8A18, 0x21CCA733, 0x60FDBC2A, - 0xAFE124AD, 0xEED03FB4, 0x2D83129F, 0x6CB20986, - 0xAB2448C9, 0xEA1553D0, 0x29467EFB, 0x687765E2, - 0xF6793F2F, 0xB7482436, 0x741B091D, 0x352A1204, - 0xF2BC534B, 0xB38D4852, 0x70DE6579, 0x31EF7E60, - 0xFEF3E6E7, 0xBFC2FDFE, 0x7C91D0D5, 0x3DA0CBCC, - 0xFA368A83, 0xBB07919A, 0x7854BCB1, 0x3965A7A8, - 0x4B98833B, 0x0AA99822, 0xC9FAB509, 0x88CBAE10, - 0x4F5DEF5F, 0x0E6CF446, 0xCD3FD96D, 0x8C0EC274, - 0x43125AF3, 0x022341EA, 0xC1706CC1, 0x804177D8, - 0x47D73697, 0x06E62D8E, 0xC5B500A5, 0x84841BBC, - 0x1A8A4171, 0x5BBB5A68, 0x98E87743, 0xD9D96C5A, - 0x1E4F2D15, 0x5F7E360C, 0x9C2D1B27, 0xDD1C003E, - 0x120098B9, 0x533183A0, 0x9062AE8B, 0xD153B592, - 0x16C5F4DD, 0x57F4EFC4, 0x94A7C2EF, 0xD596D9F6, - 0xE9BC07AE, 0xA88D1CB7, 0x6BDE319C, 0x2AEF2A85, - 0xED796BCA, 0xAC4870D3, 0x6F1B5DF8, 0x2E2A46E1, - 0xE136DE66, 0xA007C57F, 0x6354E854, 0x2265F34D, - 0xE5F3B202, 0xA4C2A91B, 0x67918430, 0x26A09F29, - 0xB8AEC5E4, 0xF99FDEFD, 0x3ACCF3D6, 0x7BFDE8CF, - 0xBC6BA980, 0xFD5AB299, 0x3E099FB2, 0x7F3884AB, - 0xB0241C2C, 0xF1150735, 0x32462A1E, 0x73773107, - 0xB4E17048, 0xF5D06B51, 0x3683467A, 0x77B25D63, - 0x4ED7FACB, 0x0FE6E1D2, 0xCCB5CCF9, 0x8D84D7E0, - 0x4A1296AF, 0x0B238DB6, 0xC870A09D, 0x8941BB84, - 0x465D2303, 0x076C381A, 0xC43F1531, 0x850E0E28, - 0x42984F67, 0x03A9547E, 0xC0FA7955, 0x81CB624C, - 0x1FC53881, 0x5EF42398, 0x9DA70EB3, 0xDC9615AA, - 0x1B0054E5, 0x5A314FFC, 0x996262D7, 0xD85379CE, - 0x174FE149, 0x567EFA50, 0x952DD77B, 0xD41CCC62, - 0x138A8D2D, 0x52BB9634, 0x91E8BB1F, 0xD0D9A006, - 0xECF37E5E, 0xADC26547, 0x6E91486C, 0x2FA05375, - 0xE836123A, 0xA9070923, 0x6A542408, 0x2B653F11, - 0xE479A796, 0xA548BC8F, 0x661B91A4, 0x272A8ABD, - 0xE0BCCBF2, 0xA18DD0EB, 0x62DEFDC0, 0x23EFE6D9, - 0xBDE1BC14, 0xFCD0A70D, 0x3F838A26, 0x7EB2913F, - 0xB924D070, 0xF815CB69, 0x3B46E642, 0x7A77FD5B, - 0xB56B65DC, 0xF45A7EC5, 0x370953EE, 0x763848F7, - 0xB1AE09B8, 0xF09F12A1, 0x33CC3F8A, 0x72FD2493 - }, { - 0x00000000, 0x376AC201, 0x6ED48403, 0x59BE4602, - 0xDCA80907, 0xEBC2CB06, 0xB27C8D04, 0x85164F05, - 0xB851130E, 0x8F3BD10F, 0xD685970D, 0xE1EF550C, - 0x64F91A09, 0x5393D808, 0x0A2D9E0A, 0x3D475C0B, - 0x70A3261C, 0x47C9E41D, 0x1E77A21F, 0x291D601E, - 0xAC0B2F1B, 0x9B61ED1A, 0xC2DFAB18, 0xF5B56919, - 0xC8F23512, 0xFF98F713, 0xA626B111, 0x914C7310, - 0x145A3C15, 0x2330FE14, 0x7A8EB816, 0x4DE47A17, - 0xE0464D38, 0xD72C8F39, 0x8E92C93B, 0xB9F80B3A, - 0x3CEE443F, 0x0B84863E, 0x523AC03C, 0x6550023D, - 0x58175E36, 0x6F7D9C37, 0x36C3DA35, 0x01A91834, - 0x84BF5731, 0xB3D59530, 0xEA6BD332, 0xDD011133, - 0x90E56B24, 0xA78FA925, 0xFE31EF27, 0xC95B2D26, - 0x4C4D6223, 0x7B27A022, 0x2299E620, 0x15F32421, - 0x28B4782A, 0x1FDEBA2B, 0x4660FC29, 0x710A3E28, - 0xF41C712D, 0xC376B32C, 0x9AC8F52E, 0xADA2372F, - 0xC08D9A70, 0xF7E75871, 0xAE591E73, 0x9933DC72, - 0x1C259377, 0x2B4F5176, 0x72F11774, 0x459BD575, - 0x78DC897E, 0x4FB64B7F, 0x16080D7D, 0x2162CF7C, - 0xA4748079, 0x931E4278, 0xCAA0047A, 0xFDCAC67B, - 0xB02EBC6C, 0x87447E6D, 0xDEFA386F, 0xE990FA6E, - 0x6C86B56B, 0x5BEC776A, 0x02523168, 0x3538F369, - 0x087FAF62, 0x3F156D63, 0x66AB2B61, 0x51C1E960, - 0xD4D7A665, 0xE3BD6464, 0xBA032266, 0x8D69E067, - 0x20CBD748, 0x17A11549, 0x4E1F534B, 0x7975914A, - 0xFC63DE4F, 0xCB091C4E, 0x92B75A4C, 0xA5DD984D, - 0x989AC446, 0xAFF00647, 0xF64E4045, 0xC1248244, - 0x4432CD41, 0x73580F40, 0x2AE64942, 0x1D8C8B43, - 0x5068F154, 0x67023355, 0x3EBC7557, 0x09D6B756, - 0x8CC0F853, 0xBBAA3A52, 0xE2147C50, 0xD57EBE51, - 0xE839E25A, 0xDF53205B, 0x86ED6659, 0xB187A458, - 0x3491EB5D, 0x03FB295C, 0x5A456F5E, 0x6D2FAD5F, - 0x801B35E1, 0xB771F7E0, 0xEECFB1E2, 0xD9A573E3, - 0x5CB33CE6, 0x6BD9FEE7, 0x3267B8E5, 0x050D7AE4, - 0x384A26EF, 0x0F20E4EE, 0x569EA2EC, 0x61F460ED, - 0xE4E22FE8, 0xD388EDE9, 0x8A36ABEB, 0xBD5C69EA, - 0xF0B813FD, 0xC7D2D1FC, 0x9E6C97FE, 0xA90655FF, - 0x2C101AFA, 0x1B7AD8FB, 0x42C49EF9, 0x75AE5CF8, - 0x48E900F3, 0x7F83C2F2, 0x263D84F0, 0x115746F1, - 0x944109F4, 0xA32BCBF5, 0xFA958DF7, 0xCDFF4FF6, - 0x605D78D9, 0x5737BAD8, 0x0E89FCDA, 0x39E33EDB, - 0xBCF571DE, 0x8B9FB3DF, 0xD221F5DD, 0xE54B37DC, - 0xD80C6BD7, 0xEF66A9D6, 0xB6D8EFD4, 0x81B22DD5, - 0x04A462D0, 0x33CEA0D1, 0x6A70E6D3, 0x5D1A24D2, - 0x10FE5EC5, 0x27949CC4, 0x7E2ADAC6, 0x494018C7, - 0xCC5657C2, 0xFB3C95C3, 0xA282D3C1, 0x95E811C0, - 0xA8AF4DCB, 0x9FC58FCA, 0xC67BC9C8, 0xF1110BC9, - 0x740744CC, 0x436D86CD, 0x1AD3C0CF, 0x2DB902CE, - 0x4096AF91, 0x77FC6D90, 0x2E422B92, 0x1928E993, - 0x9C3EA696, 0xAB546497, 0xF2EA2295, 0xC580E094, - 0xF8C7BC9F, 0xCFAD7E9E, 0x9613389C, 0xA179FA9D, - 0x246FB598, 0x13057799, 0x4ABB319B, 0x7DD1F39A, - 0x3035898D, 0x075F4B8C, 0x5EE10D8E, 0x698BCF8F, - 0xEC9D808A, 0xDBF7428B, 0x82490489, 0xB523C688, - 0x88649A83, 0xBF0E5882, 0xE6B01E80, 0xD1DADC81, - 0x54CC9384, 0x63A65185, 0x3A181787, 0x0D72D586, - 0xA0D0E2A9, 0x97BA20A8, 0xCE0466AA, 0xF96EA4AB, - 0x7C78EBAE, 0x4B1229AF, 0x12AC6FAD, 0x25C6ADAC, - 0x1881F1A7, 0x2FEB33A6, 0x765575A4, 0x413FB7A5, - 0xC429F8A0, 0xF3433AA1, 0xAAFD7CA3, 0x9D97BEA2, - 0xD073C4B5, 0xE71906B4, 0xBEA740B6, 0x89CD82B7, - 0x0CDBCDB2, 0x3BB10FB3, 0x620F49B1, 0x55658BB0, - 0x6822D7BB, 0x5F4815BA, 0x06F653B8, 0x319C91B9, - 0xB48ADEBC, 0x83E01CBD, 0xDA5E5ABF, 0xED3498BE - }, { - 0x00000000, 0x6567BCB8, 0x8BC809AA, 0xEEAFB512, - 0x5797628F, 0x32F0DE37, 0xDC5F6B25, 0xB938D79D, - 0xEF28B4C5, 0x8A4F087D, 0x64E0BD6F, 0x018701D7, - 0xB8BFD64A, 0xDDD86AF2, 0x3377DFE0, 0x56106358, - 0x9F571950, 0xFA30A5E8, 0x149F10FA, 0x71F8AC42, - 0xC8C07BDF, 0xADA7C767, 0x43087275, 0x266FCECD, - 0x707FAD95, 0x1518112D, 0xFBB7A43F, 0x9ED01887, - 0x27E8CF1A, 0x428F73A2, 0xAC20C6B0, 0xC9477A08, - 0x3EAF32A0, 0x5BC88E18, 0xB5673B0A, 0xD00087B2, - 0x6938502F, 0x0C5FEC97, 0xE2F05985, 0x8797E53D, - 0xD1878665, 0xB4E03ADD, 0x5A4F8FCF, 0x3F283377, - 0x8610E4EA, 0xE3775852, 0x0DD8ED40, 0x68BF51F8, - 0xA1F82BF0, 0xC49F9748, 0x2A30225A, 0x4F579EE2, - 0xF66F497F, 0x9308F5C7, 0x7DA740D5, 0x18C0FC6D, - 0x4ED09F35, 0x2BB7238D, 0xC518969F, 0xA07F2A27, - 0x1947FDBA, 0x7C204102, 0x928FF410, 0xF7E848A8, - 0x3D58149B, 0x583FA823, 0xB6901D31, 0xD3F7A189, - 0x6ACF7614, 0x0FA8CAAC, 0xE1077FBE, 0x8460C306, - 0xD270A05E, 0xB7171CE6, 0x59B8A9F4, 0x3CDF154C, - 0x85E7C2D1, 0xE0807E69, 0x0E2FCB7B, 0x6B4877C3, - 0xA20F0DCB, 0xC768B173, 0x29C70461, 0x4CA0B8D9, - 0xF5986F44, 0x90FFD3FC, 0x7E5066EE, 0x1B37DA56, - 0x4D27B90E, 0x284005B6, 0xC6EFB0A4, 0xA3880C1C, - 0x1AB0DB81, 0x7FD76739, 0x9178D22B, 0xF41F6E93, - 0x03F7263B, 0x66909A83, 0x883F2F91, 0xED589329, - 0x546044B4, 0x3107F80C, 0xDFA84D1E, 0xBACFF1A6, - 0xECDF92FE, 0x89B82E46, 0x67179B54, 0x027027EC, - 0xBB48F071, 0xDE2F4CC9, 0x3080F9DB, 0x55E74563, - 0x9CA03F6B, 0xF9C783D3, 0x176836C1, 0x720F8A79, - 0xCB375DE4, 0xAE50E15C, 0x40FF544E, 0x2598E8F6, - 0x73888BAE, 0x16EF3716, 0xF8408204, 0x9D273EBC, - 0x241FE921, 0x41785599, 0xAFD7E08B, 0xCAB05C33, - 0x3BB659ED, 0x5ED1E555, 0xB07E5047, 0xD519ECFF, - 0x6C213B62, 0x094687DA, 0xE7E932C8, 0x828E8E70, - 0xD49EED28, 0xB1F95190, 0x5F56E482, 0x3A31583A, - 0x83098FA7, 0xE66E331F, 0x08C1860D, 0x6DA63AB5, - 0xA4E140BD, 0xC186FC05, 0x2F294917, 0x4A4EF5AF, - 0xF3762232, 0x96119E8A, 0x78BE2B98, 0x1DD99720, - 0x4BC9F478, 0x2EAE48C0, 0xC001FDD2, 0xA566416A, - 0x1C5E96F7, 0x79392A4F, 0x97969F5D, 0xF2F123E5, - 0x05196B4D, 0x607ED7F5, 0x8ED162E7, 0xEBB6DE5F, - 0x528E09C2, 0x37E9B57A, 0xD9460068, 0xBC21BCD0, - 0xEA31DF88, 0x8F566330, 0x61F9D622, 0x049E6A9A, - 0xBDA6BD07, 0xD8C101BF, 0x366EB4AD, 0x53090815, - 0x9A4E721D, 0xFF29CEA5, 0x11867BB7, 0x74E1C70F, - 0xCDD91092, 0xA8BEAC2A, 0x46111938, 0x2376A580, - 0x7566C6D8, 0x10017A60, 0xFEAECF72, 0x9BC973CA, - 0x22F1A457, 0x479618EF, 0xA939ADFD, 0xCC5E1145, - 0x06EE4D76, 0x6389F1CE, 0x8D2644DC, 0xE841F864, - 0x51792FF9, 0x341E9341, 0xDAB12653, 0xBFD69AEB, - 0xE9C6F9B3, 0x8CA1450B, 0x620EF019, 0x07694CA1, - 0xBE519B3C, 0xDB362784, 0x35999296, 0x50FE2E2E, - 0x99B95426, 0xFCDEE89E, 0x12715D8C, 0x7716E134, - 0xCE2E36A9, 0xAB498A11, 0x45E63F03, 0x208183BB, - 0x7691E0E3, 0x13F65C5B, 0xFD59E949, 0x983E55F1, - 0x2106826C, 0x44613ED4, 0xAACE8BC6, 0xCFA9377E, - 0x38417FD6, 0x5D26C36E, 0xB389767C, 0xD6EECAC4, - 0x6FD61D59, 0x0AB1A1E1, 0xE41E14F3, 0x8179A84B, - 0xD769CB13, 0xB20E77AB, 0x5CA1C2B9, 0x39C67E01, - 0x80FEA99C, 0xE5991524, 0x0B36A036, 0x6E511C8E, - 0xA7166686, 0xC271DA3E, 0x2CDE6F2C, 0x49B9D394, - 0xF0810409, 0x95E6B8B1, 0x7B490DA3, 0x1E2EB11B, - 0x483ED243, 0x2D596EFB, 0xC3F6DBE9, 0xA6916751, - 0x1FA9B0CC, 0x7ACE0C74, 0x9461B966, 0xF10605DE - }, { - 0x00000000, 0xB029603D, 0x6053C07A, 0xD07AA047, - 0xC0A680F5, 0x708FE0C8, 0xA0F5408F, 0x10DC20B2, - 0xC14B7030, 0x7162100D, 0xA118B04A, 0x1131D077, - 0x01EDF0C5, 0xB1C490F8, 0x61BE30BF, 0xD1975082, - 0x8297E060, 0x32BE805D, 0xE2C4201A, 0x52ED4027, - 0x42316095, 0xF21800A8, 0x2262A0EF, 0x924BC0D2, - 0x43DC9050, 0xF3F5F06D, 0x238F502A, 0x93A63017, - 0x837A10A5, 0x33537098, 0xE329D0DF, 0x5300B0E2, - 0x042FC1C1, 0xB406A1FC, 0x647C01BB, 0xD4556186, - 0xC4894134, 0x74A02109, 0xA4DA814E, 0x14F3E173, - 0xC564B1F1, 0x754DD1CC, 0xA537718B, 0x151E11B6, - 0x05C23104, 0xB5EB5139, 0x6591F17E, 0xD5B89143, - 0x86B821A1, 0x3691419C, 0xE6EBE1DB, 0x56C281E6, - 0x461EA154, 0xF637C169, 0x264D612E, 0x96640113, - 0x47F35191, 0xF7DA31AC, 0x27A091EB, 0x9789F1D6, - 0x8755D164, 0x377CB159, 0xE706111E, 0x572F7123, - 0x4958F358, 0xF9719365, 0x290B3322, 0x9922531F, - 0x89FE73AD, 0x39D71390, 0xE9ADB3D7, 0x5984D3EA, - 0x88138368, 0x383AE355, 0xE8404312, 0x5869232F, - 0x48B5039D, 0xF89C63A0, 0x28E6C3E7, 0x98CFA3DA, - 0xCBCF1338, 0x7BE67305, 0xAB9CD342, 0x1BB5B37F, - 0x0B6993CD, 0xBB40F3F0, 0x6B3A53B7, 0xDB13338A, - 0x0A846308, 0xBAAD0335, 0x6AD7A372, 0xDAFEC34F, - 0xCA22E3FD, 0x7A0B83C0, 0xAA712387, 0x1A5843BA, - 0x4D773299, 0xFD5E52A4, 0x2D24F2E3, 0x9D0D92DE, - 0x8DD1B26C, 0x3DF8D251, 0xED827216, 0x5DAB122B, - 0x8C3C42A9, 0x3C152294, 0xEC6F82D3, 0x5C46E2EE, - 0x4C9AC25C, 0xFCB3A261, 0x2CC90226, 0x9CE0621B, - 0xCFE0D2F9, 0x7FC9B2C4, 0xAFB31283, 0x1F9A72BE, - 0x0F46520C, 0xBF6F3231, 0x6F159276, 0xDF3CF24B, - 0x0EABA2C9, 0xBE82C2F4, 0x6EF862B3, 0xDED1028E, - 0xCE0D223C, 0x7E244201, 0xAE5EE246, 0x1E77827B, - 0x92B0E6B1, 0x2299868C, 0xF2E326CB, 0x42CA46F6, - 0x52166644, 0xE23F0679, 0x3245A63E, 0x826CC603, - 0x53FB9681, 0xE3D2F6BC, 0x33A856FB, 0x838136C6, - 0x935D1674, 0x23747649, 0xF30ED60E, 0x4327B633, - 0x102706D1, 0xA00E66EC, 0x7074C6AB, 0xC05DA696, - 0xD0818624, 0x60A8E619, 0xB0D2465E, 0x00FB2663, - 0xD16C76E1, 0x614516DC, 0xB13FB69B, 0x0116D6A6, - 0x11CAF614, 0xA1E39629, 0x7199366E, 0xC1B05653, - 0x969F2770, 0x26B6474D, 0xF6CCE70A, 0x46E58737, - 0x5639A785, 0xE610C7B8, 0x366A67FF, 0x864307C2, - 0x57D45740, 0xE7FD377D, 0x3787973A, 0x87AEF707, - 0x9772D7B5, 0x275BB788, 0xF72117CF, 0x470877F2, - 0x1408C710, 0xA421A72D, 0x745B076A, 0xC4726757, - 0xD4AE47E5, 0x648727D8, 0xB4FD879F, 0x04D4E7A2, - 0xD543B720, 0x656AD71D, 0xB510775A, 0x05391767, - 0x15E537D5, 0xA5CC57E8, 0x75B6F7AF, 0xC59F9792, - 0xDBE815E9, 0x6BC175D4, 0xBBBBD593, 0x0B92B5AE, - 0x1B4E951C, 0xAB67F521, 0x7B1D5566, 0xCB34355B, - 0x1AA365D9, 0xAA8A05E4, 0x7AF0A5A3, 0xCAD9C59E, - 0xDA05E52C, 0x6A2C8511, 0xBA562556, 0x0A7F456B, - 0x597FF589, 0xE95695B4, 0x392C35F3, 0x890555CE, - 0x99D9757C, 0x29F01541, 0xF98AB506, 0x49A3D53B, - 0x983485B9, 0x281DE584, 0xF86745C3, 0x484E25FE, - 0x5892054C, 0xE8BB6571, 0x38C1C536, 0x88E8A50B, - 0xDFC7D428, 0x6FEEB415, 0xBF941452, 0x0FBD746F, - 0x1F6154DD, 0xAF4834E0, 0x7F3294A7, 0xCF1BF49A, - 0x1E8CA418, 0xAEA5C425, 0x7EDF6462, 0xCEF6045F, - 0xDE2A24ED, 0x6E0344D0, 0xBE79E497, 0x0E5084AA, - 0x5D503448, 0xED795475, 0x3D03F432, 0x8D2A940F, - 0x9DF6B4BD, 0x2DDFD480, 0xFDA574C7, 0x4D8C14FA, - 0x9C1B4478, 0x2C322445, 0xFC488402, 0x4C61E43F, - 0x5CBDC48D, 0xEC94A4B0, 0x3CEE04F7, 0x8CC764CA - }, { - 0x00000000, 0xA5D35CCB, 0x0BA1C84D, 0xAE729486, - 0x1642919B, 0xB391CD50, 0x1DE359D6, 0xB830051D, - 0x6D8253EC, 0xC8510F27, 0x66239BA1, 0xC3F0C76A, - 0x7BC0C277, 0xDE139EBC, 0x70610A3A, 0xD5B256F1, - 0x9B02D603, 0x3ED18AC8, 0x90A31E4E, 0x35704285, - 0x8D404798, 0x28931B53, 0x86E18FD5, 0x2332D31E, - 0xF68085EF, 0x5353D924, 0xFD214DA2, 0x58F21169, - 0xE0C21474, 0x451148BF, 0xEB63DC39, 0x4EB080F2, - 0x3605AC07, 0x93D6F0CC, 0x3DA4644A, 0x98773881, - 0x20473D9C, 0x85946157, 0x2BE6F5D1, 0x8E35A91A, - 0x5B87FFEB, 0xFE54A320, 0x502637A6, 0xF5F56B6D, - 0x4DC56E70, 0xE81632BB, 0x4664A63D, 0xE3B7FAF6, - 0xAD077A04, 0x08D426CF, 0xA6A6B249, 0x0375EE82, - 0xBB45EB9F, 0x1E96B754, 0xB0E423D2, 0x15377F19, - 0xC08529E8, 0x65567523, 0xCB24E1A5, 0x6EF7BD6E, - 0xD6C7B873, 0x7314E4B8, 0xDD66703E, 0x78B52CF5, - 0x6C0A580F, 0xC9D904C4, 0x67AB9042, 0xC278CC89, - 0x7A48C994, 0xDF9B955F, 0x71E901D9, 0xD43A5D12, - 0x01880BE3, 0xA45B5728, 0x0A29C3AE, 0xAFFA9F65, - 0x17CA9A78, 0xB219C6B3, 0x1C6B5235, 0xB9B80EFE, - 0xF7088E0C, 0x52DBD2C7, 0xFCA94641, 0x597A1A8A, - 0xE14A1F97, 0x4499435C, 0xEAEBD7DA, 0x4F388B11, - 0x9A8ADDE0, 0x3F59812B, 0x912B15AD, 0x34F84966, - 0x8CC84C7B, 0x291B10B0, 0x87698436, 0x22BAD8FD, - 0x5A0FF408, 0xFFDCA8C3, 0x51AE3C45, 0xF47D608E, - 0x4C4D6593, 0xE99E3958, 0x47ECADDE, 0xE23FF115, - 0x378DA7E4, 0x925EFB2F, 0x3C2C6FA9, 0x99FF3362, - 0x21CF367F, 0x841C6AB4, 0x2A6EFE32, 0x8FBDA2F9, - 0xC10D220B, 0x64DE7EC0, 0xCAACEA46, 0x6F7FB68D, - 0xD74FB390, 0x729CEF5B, 0xDCEE7BDD, 0x793D2716, - 0xAC8F71E7, 0x095C2D2C, 0xA72EB9AA, 0x02FDE561, - 0xBACDE07C, 0x1F1EBCB7, 0xB16C2831, 0x14BF74FA, - 0xD814B01E, 0x7DC7ECD5, 0xD3B57853, 0x76662498, - 0xCE562185, 0x6B857D4E, 0xC5F7E9C8, 0x6024B503, - 0xB596E3F2, 0x1045BF39, 0xBE372BBF, 0x1BE47774, - 0xA3D47269, 0x06072EA2, 0xA875BA24, 0x0DA6E6EF, - 0x4316661D, 0xE6C53AD6, 0x48B7AE50, 0xED64F29B, - 0x5554F786, 0xF087AB4D, 0x5EF53FCB, 0xFB266300, - 0x2E9435F1, 0x8B47693A, 0x2535FDBC, 0x80E6A177, - 0x38D6A46A, 0x9D05F8A1, 0x33776C27, 0x96A430EC, - 0xEE111C19, 0x4BC240D2, 0xE5B0D454, 0x4063889F, - 0xF8538D82, 0x5D80D149, 0xF3F245CF, 0x56211904, - 0x83934FF5, 0x2640133E, 0x883287B8, 0x2DE1DB73, - 0x95D1DE6E, 0x300282A5, 0x9E701623, 0x3BA34AE8, - 0x7513CA1A, 0xD0C096D1, 0x7EB20257, 0xDB615E9C, - 0x63515B81, 0xC682074A, 0x68F093CC, 0xCD23CF07, - 0x189199F6, 0xBD42C53D, 0x133051BB, 0xB6E30D70, - 0x0ED3086D, 0xAB0054A6, 0x0572C020, 0xA0A19CEB, - 0xB41EE811, 0x11CDB4DA, 0xBFBF205C, 0x1A6C7C97, - 0xA25C798A, 0x078F2541, 0xA9FDB1C7, 0x0C2EED0C, - 0xD99CBBFD, 0x7C4FE736, 0xD23D73B0, 0x77EE2F7B, - 0xCFDE2A66, 0x6A0D76AD, 0xC47FE22B, 0x61ACBEE0, - 0x2F1C3E12, 0x8ACF62D9, 0x24BDF65F, 0x816EAA94, - 0x395EAF89, 0x9C8DF342, 0x32FF67C4, 0x972C3B0F, - 0x429E6DFE, 0xE74D3135, 0x493FA5B3, 0xECECF978, - 0x54DCFC65, 0xF10FA0AE, 0x5F7D3428, 0xFAAE68E3, - 0x821B4416, 0x27C818DD, 0x89BA8C5B, 0x2C69D090, - 0x9459D58D, 0x318A8946, 0x9FF81DC0, 0x3A2B410B, - 0xEF9917FA, 0x4A4A4B31, 0xE438DFB7, 0x41EB837C, - 0xF9DB8661, 0x5C08DAAA, 0xF27A4E2C, 0x57A912E7, - 0x19199215, 0xBCCACEDE, 0x12B85A58, 0xB76B0693, - 0x0F5B038E, 0xAA885F45, 0x04FACBC3, 0xA1299708, - 0x749BC1F9, 0xD1489D32, 0x7F3A09B4, 0xDAE9557F, - 0x62D95062, 0xC70A0CA9, 0x6978982F, 0xCCABC4E4 - }, { - 0x00000000, 0xB40B77A6, 0x29119F97, 0x9D1AE831, - 0x13244FF4, 0xA72F3852, 0x3A35D063, 0x8E3EA7C5, - 0x674EEF33, 0xD3459895, 0x4E5F70A4, 0xFA540702, - 0x746AA0C7, 0xC061D761, 0x5D7B3F50, 0xE97048F6, - 0xCE9CDE67, 0x7A97A9C1, 0xE78D41F0, 0x53863656, - 0xDDB89193, 0x69B3E635, 0xF4A90E04, 0x40A279A2, - 0xA9D23154, 0x1DD946F2, 0x80C3AEC3, 0x34C8D965, - 0xBAF67EA0, 0x0EFD0906, 0x93E7E137, 0x27EC9691, - 0x9C39BDCF, 0x2832CA69, 0xB5282258, 0x012355FE, - 0x8F1DF23B, 0x3B16859D, 0xA60C6DAC, 0x12071A0A, - 0xFB7752FC, 0x4F7C255A, 0xD266CD6B, 0x666DBACD, - 0xE8531D08, 0x5C586AAE, 0xC142829F, 0x7549F539, - 0x52A563A8, 0xE6AE140E, 0x7BB4FC3F, 0xCFBF8B99, - 0x41812C5C, 0xF58A5BFA, 0x6890B3CB, 0xDC9BC46D, - 0x35EB8C9B, 0x81E0FB3D, 0x1CFA130C, 0xA8F164AA, - 0x26CFC36F, 0x92C4B4C9, 0x0FDE5CF8, 0xBBD52B5E, - 0x79750B44, 0xCD7E7CE2, 0x506494D3, 0xE46FE375, - 0x6A5144B0, 0xDE5A3316, 0x4340DB27, 0xF74BAC81, - 0x1E3BE477, 0xAA3093D1, 0x372A7BE0, 0x83210C46, - 0x0D1FAB83, 0xB914DC25, 0x240E3414, 0x900543B2, - 0xB7E9D523, 0x03E2A285, 0x9EF84AB4, 0x2AF33D12, - 0xA4CD9AD7, 0x10C6ED71, 0x8DDC0540, 0x39D772E6, - 0xD0A73A10, 0x64AC4DB6, 0xF9B6A587, 0x4DBDD221, - 0xC38375E4, 0x77880242, 0xEA92EA73, 0x5E999DD5, - 0xE54CB68B, 0x5147C12D, 0xCC5D291C, 0x78565EBA, - 0xF668F97F, 0x42638ED9, 0xDF7966E8, 0x6B72114E, - 0x820259B8, 0x36092E1E, 0xAB13C62F, 0x1F18B189, - 0x9126164C, 0x252D61EA, 0xB83789DB, 0x0C3CFE7D, - 0x2BD068EC, 0x9FDB1F4A, 0x02C1F77B, 0xB6CA80DD, - 0x38F42718, 0x8CFF50BE, 0x11E5B88F, 0xA5EECF29, - 0x4C9E87DF, 0xF895F079, 0x658F1848, 0xD1846FEE, - 0x5FBAC82B, 0xEBB1BF8D, 0x76AB57BC, 0xC2A0201A, - 0xF2EA1688, 0x46E1612E, 0xDBFB891F, 0x6FF0FEB9, - 0xE1CE597C, 0x55C52EDA, 0xC8DFC6EB, 0x7CD4B14D, - 0x95A4F9BB, 0x21AF8E1D, 0xBCB5662C, 0x08BE118A, - 0x8680B64F, 0x328BC1E9, 0xAF9129D8, 0x1B9A5E7E, - 0x3C76C8EF, 0x887DBF49, 0x15675778, 0xA16C20DE, - 0x2F52871B, 0x9B59F0BD, 0x0643188C, 0xB2486F2A, - 0x5B3827DC, 0xEF33507A, 0x7229B84B, 0xC622CFED, - 0x481C6828, 0xFC171F8E, 0x610DF7BF, 0xD5068019, - 0x6ED3AB47, 0xDAD8DCE1, 0x47C234D0, 0xF3C94376, - 0x7DF7E4B3, 0xC9FC9315, 0x54E67B24, 0xE0ED0C82, - 0x099D4474, 0xBD9633D2, 0x208CDBE3, 0x9487AC45, - 0x1AB90B80, 0xAEB27C26, 0x33A89417, 0x87A3E3B1, - 0xA04F7520, 0x14440286, 0x895EEAB7, 0x3D559D11, - 0xB36B3AD4, 0x07604D72, 0x9A7AA543, 0x2E71D2E5, - 0xC7019A13, 0x730AEDB5, 0xEE100584, 0x5A1B7222, - 0xD425D5E7, 0x602EA241, 0xFD344A70, 0x493F3DD6, - 0x8B9F1DCC, 0x3F946A6A, 0xA28E825B, 0x1685F5FD, - 0x98BB5238, 0x2CB0259E, 0xB1AACDAF, 0x05A1BA09, - 0xECD1F2FF, 0x58DA8559, 0xC5C06D68, 0x71CB1ACE, - 0xFFF5BD0B, 0x4BFECAAD, 0xD6E4229C, 0x62EF553A, - 0x4503C3AB, 0xF108B40D, 0x6C125C3C, 0xD8192B9A, - 0x56278C5F, 0xE22CFBF9, 0x7F3613C8, 0xCB3D646E, - 0x224D2C98, 0x96465B3E, 0x0B5CB30F, 0xBF57C4A9, - 0x3169636C, 0x856214CA, 0x1878FCFB, 0xAC738B5D, - 0x17A6A003, 0xA3ADD7A5, 0x3EB73F94, 0x8ABC4832, - 0x0482EFF7, 0xB0899851, 0x2D937060, 0x999807C6, - 0x70E84F30, 0xC4E33896, 0x59F9D0A7, 0xEDF2A701, - 0x63CC00C4, 0xD7C77762, 0x4ADD9F53, 0xFED6E8F5, - 0xD93A7E64, 0x6D3109C2, 0xF02BE1F3, 0x44209655, - 0xCA1E3190, 0x7E154636, 0xE30FAE07, 0x5704D9A1, - 0xBE749157, 0x0A7FE6F1, 0x97650EC0, 0x236E7966, - 0xAD50DEA3, 0x195BA905, 0x84414134, 0x304A3692 - }, { - 0x00000000, 0x9E00AACC, 0x7D072542, 0xE3078F8E, - 0xFA0E4A84, 0x640EE048, 0x87096FC6, 0x1909C50A, - 0xB51BE5D3, 0x2B1B4F1F, 0xC81CC091, 0x561C6A5D, - 0x4F15AF57, 0xD115059B, 0x32128A15, 0xAC1220D9, - 0x2B31BB7C, 0xB53111B0, 0x56369E3E, 0xC83634F2, - 0xD13FF1F8, 0x4F3F5B34, 0xAC38D4BA, 0x32387E76, - 0x9E2A5EAF, 0x002AF463, 0xE32D7BED, 0x7D2DD121, - 0x6424142B, 0xFA24BEE7, 0x19233169, 0x87239BA5, - 0x566276F9, 0xC862DC35, 0x2B6553BB, 0xB565F977, - 0xAC6C3C7D, 0x326C96B1, 0xD16B193F, 0x4F6BB3F3, - 0xE379932A, 0x7D7939E6, 0x9E7EB668, 0x007E1CA4, - 0x1977D9AE, 0x87777362, 0x6470FCEC, 0xFA705620, - 0x7D53CD85, 0xE3536749, 0x0054E8C7, 0x9E54420B, - 0x875D8701, 0x195D2DCD, 0xFA5AA243, 0x645A088F, - 0xC8482856, 0x5648829A, 0xB54F0D14, 0x2B4FA7D8, - 0x324662D2, 0xAC46C81E, 0x4F414790, 0xD141ED5C, - 0xEDC29D29, 0x73C237E5, 0x90C5B86B, 0x0EC512A7, - 0x17CCD7AD, 0x89CC7D61, 0x6ACBF2EF, 0xF4CB5823, - 0x58D978FA, 0xC6D9D236, 0x25DE5DB8, 0xBBDEF774, - 0xA2D7327E, 0x3CD798B2, 0xDFD0173C, 0x41D0BDF0, - 0xC6F32655, 0x58F38C99, 0xBBF40317, 0x25F4A9DB, - 0x3CFD6CD1, 0xA2FDC61D, 0x41FA4993, 0xDFFAE35F, - 0x73E8C386, 0xEDE8694A, 0x0EEFE6C4, 0x90EF4C08, - 0x89E68902, 0x17E623CE, 0xF4E1AC40, 0x6AE1068C, - 0xBBA0EBD0, 0x25A0411C, 0xC6A7CE92, 0x58A7645E, - 0x41AEA154, 0xDFAE0B98, 0x3CA98416, 0xA2A92EDA, - 0x0EBB0E03, 0x90BBA4CF, 0x73BC2B41, 0xEDBC818D, - 0xF4B54487, 0x6AB5EE4B, 0x89B261C5, 0x17B2CB09, - 0x909150AC, 0x0E91FA60, 0xED9675EE, 0x7396DF22, - 0x6A9F1A28, 0xF49FB0E4, 0x17983F6A, 0x899895A6, - 0x258AB57F, 0xBB8A1FB3, 0x588D903D, 0xC68D3AF1, - 0xDF84FFFB, 0x41845537, 0xA283DAB9, 0x3C837075, - 0xDA853B53, 0x4485919F, 0xA7821E11, 0x3982B4DD, - 0x208B71D7, 0xBE8BDB1B, 0x5D8C5495, 0xC38CFE59, - 0x6F9EDE80, 0xF19E744C, 0x1299FBC2, 0x8C99510E, - 0x95909404, 0x0B903EC8, 0xE897B146, 0x76971B8A, - 0xF1B4802F, 0x6FB42AE3, 0x8CB3A56D, 0x12B30FA1, - 0x0BBACAAB, 0x95BA6067, 0x76BDEFE9, 0xE8BD4525, - 0x44AF65FC, 0xDAAFCF30, 0x39A840BE, 0xA7A8EA72, - 0xBEA12F78, 0x20A185B4, 0xC3A60A3A, 0x5DA6A0F6, - 0x8CE74DAA, 0x12E7E766, 0xF1E068E8, 0x6FE0C224, - 0x76E9072E, 0xE8E9ADE2, 0x0BEE226C, 0x95EE88A0, - 0x39FCA879, 0xA7FC02B5, 0x44FB8D3B, 0xDAFB27F7, - 0xC3F2E2FD, 0x5DF24831, 0xBEF5C7BF, 0x20F56D73, - 0xA7D6F6D6, 0x39D65C1A, 0xDAD1D394, 0x44D17958, - 0x5DD8BC52, 0xC3D8169E, 0x20DF9910, 0xBEDF33DC, - 0x12CD1305, 0x8CCDB9C9, 0x6FCA3647, 0xF1CA9C8B, - 0xE8C35981, 0x76C3F34D, 0x95C47CC3, 0x0BC4D60F, - 0x3747A67A, 0xA9470CB6, 0x4A408338, 0xD44029F4, - 0xCD49ECFE, 0x53494632, 0xB04EC9BC, 0x2E4E6370, - 0x825C43A9, 0x1C5CE965, 0xFF5B66EB, 0x615BCC27, - 0x7852092D, 0xE652A3E1, 0x05552C6F, 0x9B5586A3, - 0x1C761D06, 0x8276B7CA, 0x61713844, 0xFF719288, - 0xE6785782, 0x7878FD4E, 0x9B7F72C0, 0x057FD80C, - 0xA96DF8D5, 0x376D5219, 0xD46ADD97, 0x4A6A775B, - 0x5363B251, 0xCD63189D, 0x2E649713, 0xB0643DDF, - 0x6125D083, 0xFF257A4F, 0x1C22F5C1, 0x82225F0D, - 0x9B2B9A07, 0x052B30CB, 0xE62CBF45, 0x782C1589, - 0xD43E3550, 0x4A3E9F9C, 0xA9391012, 0x3739BADE, - 0x2E307FD4, 0xB030D518, 0x53375A96, 0xCD37F05A, - 0x4A146BFF, 0xD414C133, 0x37134EBD, 0xA913E471, - 0xB01A217B, 0x2E1A8BB7, 0xCD1D0439, 0x531DAEF5, - 0xFF0F8E2C, 0x610F24E0, 0x8208AB6E, 0x1C0801A2, - 0x0501C4A8, 0x9B016E64, 0x7806E1EA, 0xE6064B26 - } -}; diff --git a/game/client/third/minizip/lib/liblzma/check/crc32_table_le.h b/game/client/third/minizip/lib/liblzma/check/crc32_table_le.h deleted file mode 100755 index 25f4fc44..00000000 --- a/game/client/third/minizip/lib/liblzma/check/crc32_table_le.h +++ /dev/null @@ -1,525 +0,0 @@ -/* This file has been automatically generated by crc32_tablegen.c. */ - -const uint32_t lzma_crc32_table[8][256] = { - { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D - }, { - 0x00000000, 0x191B3141, 0x32366282, 0x2B2D53C3, - 0x646CC504, 0x7D77F445, 0x565AA786, 0x4F4196C7, - 0xC8D98A08, 0xD1C2BB49, 0xFAEFE88A, 0xE3F4D9CB, - 0xACB54F0C, 0xB5AE7E4D, 0x9E832D8E, 0x87981CCF, - 0x4AC21251, 0x53D92310, 0x78F470D3, 0x61EF4192, - 0x2EAED755, 0x37B5E614, 0x1C98B5D7, 0x05838496, - 0x821B9859, 0x9B00A918, 0xB02DFADB, 0xA936CB9A, - 0xE6775D5D, 0xFF6C6C1C, 0xD4413FDF, 0xCD5A0E9E, - 0x958424A2, 0x8C9F15E3, 0xA7B24620, 0xBEA97761, - 0xF1E8E1A6, 0xE8F3D0E7, 0xC3DE8324, 0xDAC5B265, - 0x5D5DAEAA, 0x44469FEB, 0x6F6BCC28, 0x7670FD69, - 0x39316BAE, 0x202A5AEF, 0x0B07092C, 0x121C386D, - 0xDF4636F3, 0xC65D07B2, 0xED705471, 0xF46B6530, - 0xBB2AF3F7, 0xA231C2B6, 0x891C9175, 0x9007A034, - 0x179FBCFB, 0x0E848DBA, 0x25A9DE79, 0x3CB2EF38, - 0x73F379FF, 0x6AE848BE, 0x41C51B7D, 0x58DE2A3C, - 0xF0794F05, 0xE9627E44, 0xC24F2D87, 0xDB541CC6, - 0x94158A01, 0x8D0EBB40, 0xA623E883, 0xBF38D9C2, - 0x38A0C50D, 0x21BBF44C, 0x0A96A78F, 0x138D96CE, - 0x5CCC0009, 0x45D73148, 0x6EFA628B, 0x77E153CA, - 0xBABB5D54, 0xA3A06C15, 0x888D3FD6, 0x91960E97, - 0xDED79850, 0xC7CCA911, 0xECE1FAD2, 0xF5FACB93, - 0x7262D75C, 0x6B79E61D, 0x4054B5DE, 0x594F849F, - 0x160E1258, 0x0F152319, 0x243870DA, 0x3D23419B, - 0x65FD6BA7, 0x7CE65AE6, 0x57CB0925, 0x4ED03864, - 0x0191AEA3, 0x188A9FE2, 0x33A7CC21, 0x2ABCFD60, - 0xAD24E1AF, 0xB43FD0EE, 0x9F12832D, 0x8609B26C, - 0xC94824AB, 0xD05315EA, 0xFB7E4629, 0xE2657768, - 0x2F3F79F6, 0x362448B7, 0x1D091B74, 0x04122A35, - 0x4B53BCF2, 0x52488DB3, 0x7965DE70, 0x607EEF31, - 0xE7E6F3FE, 0xFEFDC2BF, 0xD5D0917C, 0xCCCBA03D, - 0x838A36FA, 0x9A9107BB, 0xB1BC5478, 0xA8A76539, - 0x3B83984B, 0x2298A90A, 0x09B5FAC9, 0x10AECB88, - 0x5FEF5D4F, 0x46F46C0E, 0x6DD93FCD, 0x74C20E8C, - 0xF35A1243, 0xEA412302, 0xC16C70C1, 0xD8774180, - 0x9736D747, 0x8E2DE606, 0xA500B5C5, 0xBC1B8484, - 0x71418A1A, 0x685ABB5B, 0x4377E898, 0x5A6CD9D9, - 0x152D4F1E, 0x0C367E5F, 0x271B2D9C, 0x3E001CDD, - 0xB9980012, 0xA0833153, 0x8BAE6290, 0x92B553D1, - 0xDDF4C516, 0xC4EFF457, 0xEFC2A794, 0xF6D996D5, - 0xAE07BCE9, 0xB71C8DA8, 0x9C31DE6B, 0x852AEF2A, - 0xCA6B79ED, 0xD37048AC, 0xF85D1B6F, 0xE1462A2E, - 0x66DE36E1, 0x7FC507A0, 0x54E85463, 0x4DF36522, - 0x02B2F3E5, 0x1BA9C2A4, 0x30849167, 0x299FA026, - 0xE4C5AEB8, 0xFDDE9FF9, 0xD6F3CC3A, 0xCFE8FD7B, - 0x80A96BBC, 0x99B25AFD, 0xB29F093E, 0xAB84387F, - 0x2C1C24B0, 0x350715F1, 0x1E2A4632, 0x07317773, - 0x4870E1B4, 0x516BD0F5, 0x7A468336, 0x635DB277, - 0xCBFAD74E, 0xD2E1E60F, 0xF9CCB5CC, 0xE0D7848D, - 0xAF96124A, 0xB68D230B, 0x9DA070C8, 0x84BB4189, - 0x03235D46, 0x1A386C07, 0x31153FC4, 0x280E0E85, - 0x674F9842, 0x7E54A903, 0x5579FAC0, 0x4C62CB81, - 0x8138C51F, 0x9823F45E, 0xB30EA79D, 0xAA1596DC, - 0xE554001B, 0xFC4F315A, 0xD7626299, 0xCE7953D8, - 0x49E14F17, 0x50FA7E56, 0x7BD72D95, 0x62CC1CD4, - 0x2D8D8A13, 0x3496BB52, 0x1FBBE891, 0x06A0D9D0, - 0x5E7EF3EC, 0x4765C2AD, 0x6C48916E, 0x7553A02F, - 0x3A1236E8, 0x230907A9, 0x0824546A, 0x113F652B, - 0x96A779E4, 0x8FBC48A5, 0xA4911B66, 0xBD8A2A27, - 0xF2CBBCE0, 0xEBD08DA1, 0xC0FDDE62, 0xD9E6EF23, - 0x14BCE1BD, 0x0DA7D0FC, 0x268A833F, 0x3F91B27E, - 0x70D024B9, 0x69CB15F8, 0x42E6463B, 0x5BFD777A, - 0xDC656BB5, 0xC57E5AF4, 0xEE530937, 0xF7483876, - 0xB809AEB1, 0xA1129FF0, 0x8A3FCC33, 0x9324FD72 - }, { - 0x00000000, 0x01C26A37, 0x0384D46E, 0x0246BE59, - 0x0709A8DC, 0x06CBC2EB, 0x048D7CB2, 0x054F1685, - 0x0E1351B8, 0x0FD13B8F, 0x0D9785D6, 0x0C55EFE1, - 0x091AF964, 0x08D89353, 0x0A9E2D0A, 0x0B5C473D, - 0x1C26A370, 0x1DE4C947, 0x1FA2771E, 0x1E601D29, - 0x1B2F0BAC, 0x1AED619B, 0x18ABDFC2, 0x1969B5F5, - 0x1235F2C8, 0x13F798FF, 0x11B126A6, 0x10734C91, - 0x153C5A14, 0x14FE3023, 0x16B88E7A, 0x177AE44D, - 0x384D46E0, 0x398F2CD7, 0x3BC9928E, 0x3A0BF8B9, - 0x3F44EE3C, 0x3E86840B, 0x3CC03A52, 0x3D025065, - 0x365E1758, 0x379C7D6F, 0x35DAC336, 0x3418A901, - 0x3157BF84, 0x3095D5B3, 0x32D36BEA, 0x331101DD, - 0x246BE590, 0x25A98FA7, 0x27EF31FE, 0x262D5BC9, - 0x23624D4C, 0x22A0277B, 0x20E69922, 0x2124F315, - 0x2A78B428, 0x2BBADE1F, 0x29FC6046, 0x283E0A71, - 0x2D711CF4, 0x2CB376C3, 0x2EF5C89A, 0x2F37A2AD, - 0x709A8DC0, 0x7158E7F7, 0x731E59AE, 0x72DC3399, - 0x7793251C, 0x76514F2B, 0x7417F172, 0x75D59B45, - 0x7E89DC78, 0x7F4BB64F, 0x7D0D0816, 0x7CCF6221, - 0x798074A4, 0x78421E93, 0x7A04A0CA, 0x7BC6CAFD, - 0x6CBC2EB0, 0x6D7E4487, 0x6F38FADE, 0x6EFA90E9, - 0x6BB5866C, 0x6A77EC5B, 0x68315202, 0x69F33835, - 0x62AF7F08, 0x636D153F, 0x612BAB66, 0x60E9C151, - 0x65A6D7D4, 0x6464BDE3, 0x662203BA, 0x67E0698D, - 0x48D7CB20, 0x4915A117, 0x4B531F4E, 0x4A917579, - 0x4FDE63FC, 0x4E1C09CB, 0x4C5AB792, 0x4D98DDA5, - 0x46C49A98, 0x4706F0AF, 0x45404EF6, 0x448224C1, - 0x41CD3244, 0x400F5873, 0x4249E62A, 0x438B8C1D, - 0x54F16850, 0x55330267, 0x5775BC3E, 0x56B7D609, - 0x53F8C08C, 0x523AAABB, 0x507C14E2, 0x51BE7ED5, - 0x5AE239E8, 0x5B2053DF, 0x5966ED86, 0x58A487B1, - 0x5DEB9134, 0x5C29FB03, 0x5E6F455A, 0x5FAD2F6D, - 0xE1351B80, 0xE0F771B7, 0xE2B1CFEE, 0xE373A5D9, - 0xE63CB35C, 0xE7FED96B, 0xE5B86732, 0xE47A0D05, - 0xEF264A38, 0xEEE4200F, 0xECA29E56, 0xED60F461, - 0xE82FE2E4, 0xE9ED88D3, 0xEBAB368A, 0xEA695CBD, - 0xFD13B8F0, 0xFCD1D2C7, 0xFE976C9E, 0xFF5506A9, - 0xFA1A102C, 0xFBD87A1B, 0xF99EC442, 0xF85CAE75, - 0xF300E948, 0xF2C2837F, 0xF0843D26, 0xF1465711, - 0xF4094194, 0xF5CB2BA3, 0xF78D95FA, 0xF64FFFCD, - 0xD9785D60, 0xD8BA3757, 0xDAFC890E, 0xDB3EE339, - 0xDE71F5BC, 0xDFB39F8B, 0xDDF521D2, 0xDC374BE5, - 0xD76B0CD8, 0xD6A966EF, 0xD4EFD8B6, 0xD52DB281, - 0xD062A404, 0xD1A0CE33, 0xD3E6706A, 0xD2241A5D, - 0xC55EFE10, 0xC49C9427, 0xC6DA2A7E, 0xC7184049, - 0xC25756CC, 0xC3953CFB, 0xC1D382A2, 0xC011E895, - 0xCB4DAFA8, 0xCA8FC59F, 0xC8C97BC6, 0xC90B11F1, - 0xCC440774, 0xCD866D43, 0xCFC0D31A, 0xCE02B92D, - 0x91AF9640, 0x906DFC77, 0x922B422E, 0x93E92819, - 0x96A63E9C, 0x976454AB, 0x9522EAF2, 0x94E080C5, - 0x9FBCC7F8, 0x9E7EADCF, 0x9C381396, 0x9DFA79A1, - 0x98B56F24, 0x99770513, 0x9B31BB4A, 0x9AF3D17D, - 0x8D893530, 0x8C4B5F07, 0x8E0DE15E, 0x8FCF8B69, - 0x8A809DEC, 0x8B42F7DB, 0x89044982, 0x88C623B5, - 0x839A6488, 0x82580EBF, 0x801EB0E6, 0x81DCDAD1, - 0x8493CC54, 0x8551A663, 0x8717183A, 0x86D5720D, - 0xA9E2D0A0, 0xA820BA97, 0xAA6604CE, 0xABA46EF9, - 0xAEEB787C, 0xAF29124B, 0xAD6FAC12, 0xACADC625, - 0xA7F18118, 0xA633EB2F, 0xA4755576, 0xA5B73F41, - 0xA0F829C4, 0xA13A43F3, 0xA37CFDAA, 0xA2BE979D, - 0xB5C473D0, 0xB40619E7, 0xB640A7BE, 0xB782CD89, - 0xB2CDDB0C, 0xB30FB13B, 0xB1490F62, 0xB08B6555, - 0xBBD72268, 0xBA15485F, 0xB853F606, 0xB9919C31, - 0xBCDE8AB4, 0xBD1CE083, 0xBF5A5EDA, 0xBE9834ED - }, { - 0x00000000, 0xB8BC6765, 0xAA09C88B, 0x12B5AFEE, - 0x8F629757, 0x37DEF032, 0x256B5FDC, 0x9DD738B9, - 0xC5B428EF, 0x7D084F8A, 0x6FBDE064, 0xD7018701, - 0x4AD6BFB8, 0xF26AD8DD, 0xE0DF7733, 0x58631056, - 0x5019579F, 0xE8A530FA, 0xFA109F14, 0x42ACF871, - 0xDF7BC0C8, 0x67C7A7AD, 0x75720843, 0xCDCE6F26, - 0x95AD7F70, 0x2D111815, 0x3FA4B7FB, 0x8718D09E, - 0x1ACFE827, 0xA2738F42, 0xB0C620AC, 0x087A47C9, - 0xA032AF3E, 0x188EC85B, 0x0A3B67B5, 0xB28700D0, - 0x2F503869, 0x97EC5F0C, 0x8559F0E2, 0x3DE59787, - 0x658687D1, 0xDD3AE0B4, 0xCF8F4F5A, 0x7733283F, - 0xEAE41086, 0x525877E3, 0x40EDD80D, 0xF851BF68, - 0xF02BF8A1, 0x48979FC4, 0x5A22302A, 0xE29E574F, - 0x7F496FF6, 0xC7F50893, 0xD540A77D, 0x6DFCC018, - 0x359FD04E, 0x8D23B72B, 0x9F9618C5, 0x272A7FA0, - 0xBAFD4719, 0x0241207C, 0x10F48F92, 0xA848E8F7, - 0x9B14583D, 0x23A83F58, 0x311D90B6, 0x89A1F7D3, - 0x1476CF6A, 0xACCAA80F, 0xBE7F07E1, 0x06C36084, - 0x5EA070D2, 0xE61C17B7, 0xF4A9B859, 0x4C15DF3C, - 0xD1C2E785, 0x697E80E0, 0x7BCB2F0E, 0xC377486B, - 0xCB0D0FA2, 0x73B168C7, 0x6104C729, 0xD9B8A04C, - 0x446F98F5, 0xFCD3FF90, 0xEE66507E, 0x56DA371B, - 0x0EB9274D, 0xB6054028, 0xA4B0EFC6, 0x1C0C88A3, - 0x81DBB01A, 0x3967D77F, 0x2BD27891, 0x936E1FF4, - 0x3B26F703, 0x839A9066, 0x912F3F88, 0x299358ED, - 0xB4446054, 0x0CF80731, 0x1E4DA8DF, 0xA6F1CFBA, - 0xFE92DFEC, 0x462EB889, 0x549B1767, 0xEC277002, - 0x71F048BB, 0xC94C2FDE, 0xDBF98030, 0x6345E755, - 0x6B3FA09C, 0xD383C7F9, 0xC1366817, 0x798A0F72, - 0xE45D37CB, 0x5CE150AE, 0x4E54FF40, 0xF6E89825, - 0xAE8B8873, 0x1637EF16, 0x048240F8, 0xBC3E279D, - 0x21E91F24, 0x99557841, 0x8BE0D7AF, 0x335CB0CA, - 0xED59B63B, 0x55E5D15E, 0x47507EB0, 0xFFEC19D5, - 0x623B216C, 0xDA874609, 0xC832E9E7, 0x708E8E82, - 0x28ED9ED4, 0x9051F9B1, 0x82E4565F, 0x3A58313A, - 0xA78F0983, 0x1F336EE6, 0x0D86C108, 0xB53AA66D, - 0xBD40E1A4, 0x05FC86C1, 0x1749292F, 0xAFF54E4A, - 0x322276F3, 0x8A9E1196, 0x982BBE78, 0x2097D91D, - 0x78F4C94B, 0xC048AE2E, 0xD2FD01C0, 0x6A4166A5, - 0xF7965E1C, 0x4F2A3979, 0x5D9F9697, 0xE523F1F2, - 0x4D6B1905, 0xF5D77E60, 0xE762D18E, 0x5FDEB6EB, - 0xC2098E52, 0x7AB5E937, 0x680046D9, 0xD0BC21BC, - 0x88DF31EA, 0x3063568F, 0x22D6F961, 0x9A6A9E04, - 0x07BDA6BD, 0xBF01C1D8, 0xADB46E36, 0x15080953, - 0x1D724E9A, 0xA5CE29FF, 0xB77B8611, 0x0FC7E174, - 0x9210D9CD, 0x2AACBEA8, 0x38191146, 0x80A57623, - 0xD8C66675, 0x607A0110, 0x72CFAEFE, 0xCA73C99B, - 0x57A4F122, 0xEF189647, 0xFDAD39A9, 0x45115ECC, - 0x764DEE06, 0xCEF18963, 0xDC44268D, 0x64F841E8, - 0xF92F7951, 0x41931E34, 0x5326B1DA, 0xEB9AD6BF, - 0xB3F9C6E9, 0x0B45A18C, 0x19F00E62, 0xA14C6907, - 0x3C9B51BE, 0x842736DB, 0x96929935, 0x2E2EFE50, - 0x2654B999, 0x9EE8DEFC, 0x8C5D7112, 0x34E11677, - 0xA9362ECE, 0x118A49AB, 0x033FE645, 0xBB838120, - 0xE3E09176, 0x5B5CF613, 0x49E959FD, 0xF1553E98, - 0x6C820621, 0xD43E6144, 0xC68BCEAA, 0x7E37A9CF, - 0xD67F4138, 0x6EC3265D, 0x7C7689B3, 0xC4CAEED6, - 0x591DD66F, 0xE1A1B10A, 0xF3141EE4, 0x4BA87981, - 0x13CB69D7, 0xAB770EB2, 0xB9C2A15C, 0x017EC639, - 0x9CA9FE80, 0x241599E5, 0x36A0360B, 0x8E1C516E, - 0x866616A7, 0x3EDA71C2, 0x2C6FDE2C, 0x94D3B949, - 0x090481F0, 0xB1B8E695, 0xA30D497B, 0x1BB12E1E, - 0x43D23E48, 0xFB6E592D, 0xE9DBF6C3, 0x516791A6, - 0xCCB0A91F, 0x740CCE7A, 0x66B96194, 0xDE0506F1 - }, { - 0x00000000, 0x3D6029B0, 0x7AC05360, 0x47A07AD0, - 0xF580A6C0, 0xC8E08F70, 0x8F40F5A0, 0xB220DC10, - 0x30704BC1, 0x0D106271, 0x4AB018A1, 0x77D03111, - 0xC5F0ED01, 0xF890C4B1, 0xBF30BE61, 0x825097D1, - 0x60E09782, 0x5D80BE32, 0x1A20C4E2, 0x2740ED52, - 0x95603142, 0xA80018F2, 0xEFA06222, 0xD2C04B92, - 0x5090DC43, 0x6DF0F5F3, 0x2A508F23, 0x1730A693, - 0xA5107A83, 0x98705333, 0xDFD029E3, 0xE2B00053, - 0xC1C12F04, 0xFCA106B4, 0xBB017C64, 0x866155D4, - 0x344189C4, 0x0921A074, 0x4E81DAA4, 0x73E1F314, - 0xF1B164C5, 0xCCD14D75, 0x8B7137A5, 0xB6111E15, - 0x0431C205, 0x3951EBB5, 0x7EF19165, 0x4391B8D5, - 0xA121B886, 0x9C419136, 0xDBE1EBE6, 0xE681C256, - 0x54A11E46, 0x69C137F6, 0x2E614D26, 0x13016496, - 0x9151F347, 0xAC31DAF7, 0xEB91A027, 0xD6F18997, - 0x64D15587, 0x59B17C37, 0x1E1106E7, 0x23712F57, - 0x58F35849, 0x659371F9, 0x22330B29, 0x1F532299, - 0xAD73FE89, 0x9013D739, 0xD7B3ADE9, 0xEAD38459, - 0x68831388, 0x55E33A38, 0x124340E8, 0x2F236958, - 0x9D03B548, 0xA0639CF8, 0xE7C3E628, 0xDAA3CF98, - 0x3813CFCB, 0x0573E67B, 0x42D39CAB, 0x7FB3B51B, - 0xCD93690B, 0xF0F340BB, 0xB7533A6B, 0x8A3313DB, - 0x0863840A, 0x3503ADBA, 0x72A3D76A, 0x4FC3FEDA, - 0xFDE322CA, 0xC0830B7A, 0x872371AA, 0xBA43581A, - 0x9932774D, 0xA4525EFD, 0xE3F2242D, 0xDE920D9D, - 0x6CB2D18D, 0x51D2F83D, 0x167282ED, 0x2B12AB5D, - 0xA9423C8C, 0x9422153C, 0xD3826FEC, 0xEEE2465C, - 0x5CC29A4C, 0x61A2B3FC, 0x2602C92C, 0x1B62E09C, - 0xF9D2E0CF, 0xC4B2C97F, 0x8312B3AF, 0xBE729A1F, - 0x0C52460F, 0x31326FBF, 0x7692156F, 0x4BF23CDF, - 0xC9A2AB0E, 0xF4C282BE, 0xB362F86E, 0x8E02D1DE, - 0x3C220DCE, 0x0142247E, 0x46E25EAE, 0x7B82771E, - 0xB1E6B092, 0x8C869922, 0xCB26E3F2, 0xF646CA42, - 0x44661652, 0x79063FE2, 0x3EA64532, 0x03C66C82, - 0x8196FB53, 0xBCF6D2E3, 0xFB56A833, 0xC6368183, - 0x74165D93, 0x49767423, 0x0ED60EF3, 0x33B62743, - 0xD1062710, 0xEC660EA0, 0xABC67470, 0x96A65DC0, - 0x248681D0, 0x19E6A860, 0x5E46D2B0, 0x6326FB00, - 0xE1766CD1, 0xDC164561, 0x9BB63FB1, 0xA6D61601, - 0x14F6CA11, 0x2996E3A1, 0x6E369971, 0x5356B0C1, - 0x70279F96, 0x4D47B626, 0x0AE7CCF6, 0x3787E546, - 0x85A73956, 0xB8C710E6, 0xFF676A36, 0xC2074386, - 0x4057D457, 0x7D37FDE7, 0x3A978737, 0x07F7AE87, - 0xB5D77297, 0x88B75B27, 0xCF1721F7, 0xF2770847, - 0x10C70814, 0x2DA721A4, 0x6A075B74, 0x576772C4, - 0xE547AED4, 0xD8278764, 0x9F87FDB4, 0xA2E7D404, - 0x20B743D5, 0x1DD76A65, 0x5A7710B5, 0x67173905, - 0xD537E515, 0xE857CCA5, 0xAFF7B675, 0x92979FC5, - 0xE915E8DB, 0xD475C16B, 0x93D5BBBB, 0xAEB5920B, - 0x1C954E1B, 0x21F567AB, 0x66551D7B, 0x5B3534CB, - 0xD965A31A, 0xE4058AAA, 0xA3A5F07A, 0x9EC5D9CA, - 0x2CE505DA, 0x11852C6A, 0x562556BA, 0x6B457F0A, - 0x89F57F59, 0xB49556E9, 0xF3352C39, 0xCE550589, - 0x7C75D999, 0x4115F029, 0x06B58AF9, 0x3BD5A349, - 0xB9853498, 0x84E51D28, 0xC34567F8, 0xFE254E48, - 0x4C059258, 0x7165BBE8, 0x36C5C138, 0x0BA5E888, - 0x28D4C7DF, 0x15B4EE6F, 0x521494BF, 0x6F74BD0F, - 0xDD54611F, 0xE03448AF, 0xA794327F, 0x9AF41BCF, - 0x18A48C1E, 0x25C4A5AE, 0x6264DF7E, 0x5F04F6CE, - 0xED242ADE, 0xD044036E, 0x97E479BE, 0xAA84500E, - 0x4834505D, 0x755479ED, 0x32F4033D, 0x0F942A8D, - 0xBDB4F69D, 0x80D4DF2D, 0xC774A5FD, 0xFA148C4D, - 0x78441B9C, 0x4524322C, 0x028448FC, 0x3FE4614C, - 0x8DC4BD5C, 0xB0A494EC, 0xF704EE3C, 0xCA64C78C - }, { - 0x00000000, 0xCB5CD3A5, 0x4DC8A10B, 0x869472AE, - 0x9B914216, 0x50CD91B3, 0xD659E31D, 0x1D0530B8, - 0xEC53826D, 0x270F51C8, 0xA19B2366, 0x6AC7F0C3, - 0x77C2C07B, 0xBC9E13DE, 0x3A0A6170, 0xF156B2D5, - 0x03D6029B, 0xC88AD13E, 0x4E1EA390, 0x85427035, - 0x9847408D, 0x531B9328, 0xD58FE186, 0x1ED33223, - 0xEF8580F6, 0x24D95353, 0xA24D21FD, 0x6911F258, - 0x7414C2E0, 0xBF481145, 0x39DC63EB, 0xF280B04E, - 0x07AC0536, 0xCCF0D693, 0x4A64A43D, 0x81387798, - 0x9C3D4720, 0x57619485, 0xD1F5E62B, 0x1AA9358E, - 0xEBFF875B, 0x20A354FE, 0xA6372650, 0x6D6BF5F5, - 0x706EC54D, 0xBB3216E8, 0x3DA66446, 0xF6FAB7E3, - 0x047A07AD, 0xCF26D408, 0x49B2A6A6, 0x82EE7503, - 0x9FEB45BB, 0x54B7961E, 0xD223E4B0, 0x197F3715, - 0xE82985C0, 0x23755665, 0xA5E124CB, 0x6EBDF76E, - 0x73B8C7D6, 0xB8E41473, 0x3E7066DD, 0xF52CB578, - 0x0F580A6C, 0xC404D9C9, 0x4290AB67, 0x89CC78C2, - 0x94C9487A, 0x5F959BDF, 0xD901E971, 0x125D3AD4, - 0xE30B8801, 0x28575BA4, 0xAEC3290A, 0x659FFAAF, - 0x789ACA17, 0xB3C619B2, 0x35526B1C, 0xFE0EB8B9, - 0x0C8E08F7, 0xC7D2DB52, 0x4146A9FC, 0x8A1A7A59, - 0x971F4AE1, 0x5C439944, 0xDAD7EBEA, 0x118B384F, - 0xE0DD8A9A, 0x2B81593F, 0xAD152B91, 0x6649F834, - 0x7B4CC88C, 0xB0101B29, 0x36846987, 0xFDD8BA22, - 0x08F40F5A, 0xC3A8DCFF, 0x453CAE51, 0x8E607DF4, - 0x93654D4C, 0x58399EE9, 0xDEADEC47, 0x15F13FE2, - 0xE4A78D37, 0x2FFB5E92, 0xA96F2C3C, 0x6233FF99, - 0x7F36CF21, 0xB46A1C84, 0x32FE6E2A, 0xF9A2BD8F, - 0x0B220DC1, 0xC07EDE64, 0x46EAACCA, 0x8DB67F6F, - 0x90B34FD7, 0x5BEF9C72, 0xDD7BEEDC, 0x16273D79, - 0xE7718FAC, 0x2C2D5C09, 0xAAB92EA7, 0x61E5FD02, - 0x7CE0CDBA, 0xB7BC1E1F, 0x31286CB1, 0xFA74BF14, - 0x1EB014D8, 0xD5ECC77D, 0x5378B5D3, 0x98246676, - 0x852156CE, 0x4E7D856B, 0xC8E9F7C5, 0x03B52460, - 0xF2E396B5, 0x39BF4510, 0xBF2B37BE, 0x7477E41B, - 0x6972D4A3, 0xA22E0706, 0x24BA75A8, 0xEFE6A60D, - 0x1D661643, 0xD63AC5E6, 0x50AEB748, 0x9BF264ED, - 0x86F75455, 0x4DAB87F0, 0xCB3FF55E, 0x006326FB, - 0xF135942E, 0x3A69478B, 0xBCFD3525, 0x77A1E680, - 0x6AA4D638, 0xA1F8059D, 0x276C7733, 0xEC30A496, - 0x191C11EE, 0xD240C24B, 0x54D4B0E5, 0x9F886340, - 0x828D53F8, 0x49D1805D, 0xCF45F2F3, 0x04192156, - 0xF54F9383, 0x3E134026, 0xB8873288, 0x73DBE12D, - 0x6EDED195, 0xA5820230, 0x2316709E, 0xE84AA33B, - 0x1ACA1375, 0xD196C0D0, 0x5702B27E, 0x9C5E61DB, - 0x815B5163, 0x4A0782C6, 0xCC93F068, 0x07CF23CD, - 0xF6999118, 0x3DC542BD, 0xBB513013, 0x700DE3B6, - 0x6D08D30E, 0xA65400AB, 0x20C07205, 0xEB9CA1A0, - 0x11E81EB4, 0xDAB4CD11, 0x5C20BFBF, 0x977C6C1A, - 0x8A795CA2, 0x41258F07, 0xC7B1FDA9, 0x0CED2E0C, - 0xFDBB9CD9, 0x36E74F7C, 0xB0733DD2, 0x7B2FEE77, - 0x662ADECF, 0xAD760D6A, 0x2BE27FC4, 0xE0BEAC61, - 0x123E1C2F, 0xD962CF8A, 0x5FF6BD24, 0x94AA6E81, - 0x89AF5E39, 0x42F38D9C, 0xC467FF32, 0x0F3B2C97, - 0xFE6D9E42, 0x35314DE7, 0xB3A53F49, 0x78F9ECEC, - 0x65FCDC54, 0xAEA00FF1, 0x28347D5F, 0xE368AEFA, - 0x16441B82, 0xDD18C827, 0x5B8CBA89, 0x90D0692C, - 0x8DD55994, 0x46898A31, 0xC01DF89F, 0x0B412B3A, - 0xFA1799EF, 0x314B4A4A, 0xB7DF38E4, 0x7C83EB41, - 0x6186DBF9, 0xAADA085C, 0x2C4E7AF2, 0xE712A957, - 0x15921919, 0xDECECABC, 0x585AB812, 0x93066BB7, - 0x8E035B0F, 0x455F88AA, 0xC3CBFA04, 0x089729A1, - 0xF9C19B74, 0x329D48D1, 0xB4093A7F, 0x7F55E9DA, - 0x6250D962, 0xA90C0AC7, 0x2F987869, 0xE4C4ABCC - }, { - 0x00000000, 0xA6770BB4, 0x979F1129, 0x31E81A9D, - 0xF44F2413, 0x52382FA7, 0x63D0353A, 0xC5A73E8E, - 0x33EF4E67, 0x959845D3, 0xA4705F4E, 0x020754FA, - 0xC7A06A74, 0x61D761C0, 0x503F7B5D, 0xF64870E9, - 0x67DE9CCE, 0xC1A9977A, 0xF0418DE7, 0x56368653, - 0x9391B8DD, 0x35E6B369, 0x040EA9F4, 0xA279A240, - 0x5431D2A9, 0xF246D91D, 0xC3AEC380, 0x65D9C834, - 0xA07EF6BA, 0x0609FD0E, 0x37E1E793, 0x9196EC27, - 0xCFBD399C, 0x69CA3228, 0x582228B5, 0xFE552301, - 0x3BF21D8F, 0x9D85163B, 0xAC6D0CA6, 0x0A1A0712, - 0xFC5277FB, 0x5A257C4F, 0x6BCD66D2, 0xCDBA6D66, - 0x081D53E8, 0xAE6A585C, 0x9F8242C1, 0x39F54975, - 0xA863A552, 0x0E14AEE6, 0x3FFCB47B, 0x998BBFCF, - 0x5C2C8141, 0xFA5B8AF5, 0xCBB39068, 0x6DC49BDC, - 0x9B8CEB35, 0x3DFBE081, 0x0C13FA1C, 0xAA64F1A8, - 0x6FC3CF26, 0xC9B4C492, 0xF85CDE0F, 0x5E2BD5BB, - 0x440B7579, 0xE27C7ECD, 0xD3946450, 0x75E36FE4, - 0xB044516A, 0x16335ADE, 0x27DB4043, 0x81AC4BF7, - 0x77E43B1E, 0xD19330AA, 0xE07B2A37, 0x460C2183, - 0x83AB1F0D, 0x25DC14B9, 0x14340E24, 0xB2430590, - 0x23D5E9B7, 0x85A2E203, 0xB44AF89E, 0x123DF32A, - 0xD79ACDA4, 0x71EDC610, 0x4005DC8D, 0xE672D739, - 0x103AA7D0, 0xB64DAC64, 0x87A5B6F9, 0x21D2BD4D, - 0xE47583C3, 0x42028877, 0x73EA92EA, 0xD59D995E, - 0x8BB64CE5, 0x2DC14751, 0x1C295DCC, 0xBA5E5678, - 0x7FF968F6, 0xD98E6342, 0xE86679DF, 0x4E11726B, - 0xB8590282, 0x1E2E0936, 0x2FC613AB, 0x89B1181F, - 0x4C162691, 0xEA612D25, 0xDB8937B8, 0x7DFE3C0C, - 0xEC68D02B, 0x4A1FDB9F, 0x7BF7C102, 0xDD80CAB6, - 0x1827F438, 0xBE50FF8C, 0x8FB8E511, 0x29CFEEA5, - 0xDF879E4C, 0x79F095F8, 0x48188F65, 0xEE6F84D1, - 0x2BC8BA5F, 0x8DBFB1EB, 0xBC57AB76, 0x1A20A0C2, - 0x8816EAF2, 0x2E61E146, 0x1F89FBDB, 0xB9FEF06F, - 0x7C59CEE1, 0xDA2EC555, 0xEBC6DFC8, 0x4DB1D47C, - 0xBBF9A495, 0x1D8EAF21, 0x2C66B5BC, 0x8A11BE08, - 0x4FB68086, 0xE9C18B32, 0xD82991AF, 0x7E5E9A1B, - 0xEFC8763C, 0x49BF7D88, 0x78576715, 0xDE206CA1, - 0x1B87522F, 0xBDF0599B, 0x8C184306, 0x2A6F48B2, - 0xDC27385B, 0x7A5033EF, 0x4BB82972, 0xEDCF22C6, - 0x28681C48, 0x8E1F17FC, 0xBFF70D61, 0x198006D5, - 0x47ABD36E, 0xE1DCD8DA, 0xD034C247, 0x7643C9F3, - 0xB3E4F77D, 0x1593FCC9, 0x247BE654, 0x820CEDE0, - 0x74449D09, 0xD23396BD, 0xE3DB8C20, 0x45AC8794, - 0x800BB91A, 0x267CB2AE, 0x1794A833, 0xB1E3A387, - 0x20754FA0, 0x86024414, 0xB7EA5E89, 0x119D553D, - 0xD43A6BB3, 0x724D6007, 0x43A57A9A, 0xE5D2712E, - 0x139A01C7, 0xB5ED0A73, 0x840510EE, 0x22721B5A, - 0xE7D525D4, 0x41A22E60, 0x704A34FD, 0xD63D3F49, - 0xCC1D9F8B, 0x6A6A943F, 0x5B828EA2, 0xFDF58516, - 0x3852BB98, 0x9E25B02C, 0xAFCDAAB1, 0x09BAA105, - 0xFFF2D1EC, 0x5985DA58, 0x686DC0C5, 0xCE1ACB71, - 0x0BBDF5FF, 0xADCAFE4B, 0x9C22E4D6, 0x3A55EF62, - 0xABC30345, 0x0DB408F1, 0x3C5C126C, 0x9A2B19D8, - 0x5F8C2756, 0xF9FB2CE2, 0xC813367F, 0x6E643DCB, - 0x982C4D22, 0x3E5B4696, 0x0FB35C0B, 0xA9C457BF, - 0x6C636931, 0xCA146285, 0xFBFC7818, 0x5D8B73AC, - 0x03A0A617, 0xA5D7ADA3, 0x943FB73E, 0x3248BC8A, - 0xF7EF8204, 0x519889B0, 0x6070932D, 0xC6079899, - 0x304FE870, 0x9638E3C4, 0xA7D0F959, 0x01A7F2ED, - 0xC400CC63, 0x6277C7D7, 0x539FDD4A, 0xF5E8D6FE, - 0x647E3AD9, 0xC209316D, 0xF3E12BF0, 0x55962044, - 0x90311ECA, 0x3646157E, 0x07AE0FE3, 0xA1D90457, - 0x579174BE, 0xF1E67F0A, 0xC00E6597, 0x66796E23, - 0xA3DE50AD, 0x05A95B19, 0x34414184, 0x92364A30 - }, { - 0x00000000, 0xCCAA009E, 0x4225077D, 0x8E8F07E3, - 0x844A0EFA, 0x48E00E64, 0xC66F0987, 0x0AC50919, - 0xD3E51BB5, 0x1F4F1B2B, 0x91C01CC8, 0x5D6A1C56, - 0x57AF154F, 0x9B0515D1, 0x158A1232, 0xD92012AC, - 0x7CBB312B, 0xB01131B5, 0x3E9E3656, 0xF23436C8, - 0xF8F13FD1, 0x345B3F4F, 0xBAD438AC, 0x767E3832, - 0xAF5E2A9E, 0x63F42A00, 0xED7B2DE3, 0x21D12D7D, - 0x2B142464, 0xE7BE24FA, 0x69312319, 0xA59B2387, - 0xF9766256, 0x35DC62C8, 0xBB53652B, 0x77F965B5, - 0x7D3C6CAC, 0xB1966C32, 0x3F196BD1, 0xF3B36B4F, - 0x2A9379E3, 0xE639797D, 0x68B67E9E, 0xA41C7E00, - 0xAED97719, 0x62737787, 0xECFC7064, 0x205670FA, - 0x85CD537D, 0x496753E3, 0xC7E85400, 0x0B42549E, - 0x01875D87, 0xCD2D5D19, 0x43A25AFA, 0x8F085A64, - 0x562848C8, 0x9A824856, 0x140D4FB5, 0xD8A74F2B, - 0xD2624632, 0x1EC846AC, 0x9047414F, 0x5CED41D1, - 0x299DC2ED, 0xE537C273, 0x6BB8C590, 0xA712C50E, - 0xADD7CC17, 0x617DCC89, 0xEFF2CB6A, 0x2358CBF4, - 0xFA78D958, 0x36D2D9C6, 0xB85DDE25, 0x74F7DEBB, - 0x7E32D7A2, 0xB298D73C, 0x3C17D0DF, 0xF0BDD041, - 0x5526F3C6, 0x998CF358, 0x1703F4BB, 0xDBA9F425, - 0xD16CFD3C, 0x1DC6FDA2, 0x9349FA41, 0x5FE3FADF, - 0x86C3E873, 0x4A69E8ED, 0xC4E6EF0E, 0x084CEF90, - 0x0289E689, 0xCE23E617, 0x40ACE1F4, 0x8C06E16A, - 0xD0EBA0BB, 0x1C41A025, 0x92CEA7C6, 0x5E64A758, - 0x54A1AE41, 0x980BAEDF, 0x1684A93C, 0xDA2EA9A2, - 0x030EBB0E, 0xCFA4BB90, 0x412BBC73, 0x8D81BCED, - 0x8744B5F4, 0x4BEEB56A, 0xC561B289, 0x09CBB217, - 0xAC509190, 0x60FA910E, 0xEE7596ED, 0x22DF9673, - 0x281A9F6A, 0xE4B09FF4, 0x6A3F9817, 0xA6959889, - 0x7FB58A25, 0xB31F8ABB, 0x3D908D58, 0xF13A8DC6, - 0xFBFF84DF, 0x37558441, 0xB9DA83A2, 0x7570833C, - 0x533B85DA, 0x9F918544, 0x111E82A7, 0xDDB48239, - 0xD7718B20, 0x1BDB8BBE, 0x95548C5D, 0x59FE8CC3, - 0x80DE9E6F, 0x4C749EF1, 0xC2FB9912, 0x0E51998C, - 0x04949095, 0xC83E900B, 0x46B197E8, 0x8A1B9776, - 0x2F80B4F1, 0xE32AB46F, 0x6DA5B38C, 0xA10FB312, - 0xABCABA0B, 0x6760BA95, 0xE9EFBD76, 0x2545BDE8, - 0xFC65AF44, 0x30CFAFDA, 0xBE40A839, 0x72EAA8A7, - 0x782FA1BE, 0xB485A120, 0x3A0AA6C3, 0xF6A0A65D, - 0xAA4DE78C, 0x66E7E712, 0xE868E0F1, 0x24C2E06F, - 0x2E07E976, 0xE2ADE9E8, 0x6C22EE0B, 0xA088EE95, - 0x79A8FC39, 0xB502FCA7, 0x3B8DFB44, 0xF727FBDA, - 0xFDE2F2C3, 0x3148F25D, 0xBFC7F5BE, 0x736DF520, - 0xD6F6D6A7, 0x1A5CD639, 0x94D3D1DA, 0x5879D144, - 0x52BCD85D, 0x9E16D8C3, 0x1099DF20, 0xDC33DFBE, - 0x0513CD12, 0xC9B9CD8C, 0x4736CA6F, 0x8B9CCAF1, - 0x8159C3E8, 0x4DF3C376, 0xC37CC495, 0x0FD6C40B, - 0x7AA64737, 0xB60C47A9, 0x3883404A, 0xF42940D4, - 0xFEEC49CD, 0x32464953, 0xBCC94EB0, 0x70634E2E, - 0xA9435C82, 0x65E95C1C, 0xEB665BFF, 0x27CC5B61, - 0x2D095278, 0xE1A352E6, 0x6F2C5505, 0xA386559B, - 0x061D761C, 0xCAB77682, 0x44387161, 0x889271FF, - 0x825778E6, 0x4EFD7878, 0xC0727F9B, 0x0CD87F05, - 0xD5F86DA9, 0x19526D37, 0x97DD6AD4, 0x5B776A4A, - 0x51B26353, 0x9D1863CD, 0x1397642E, 0xDF3D64B0, - 0x83D02561, 0x4F7A25FF, 0xC1F5221C, 0x0D5F2282, - 0x079A2B9B, 0xCB302B05, 0x45BF2CE6, 0x89152C78, - 0x50353ED4, 0x9C9F3E4A, 0x121039A9, 0xDEBA3937, - 0xD47F302E, 0x18D530B0, 0x965A3753, 0x5AF037CD, - 0xFF6B144A, 0x33C114D4, 0xBD4E1337, 0x71E413A9, - 0x7B211AB0, 0xB78B1A2E, 0x39041DCD, 0xF5AE1D53, - 0x2C8E0FFF, 0xE0240F61, 0x6EAB0882, 0xA201081C, - 0xA8C40105, 0x646E019B, 0xEAE10678, 0x264B06E6 - } -}; diff --git a/game/client/third/minizip/lib/liblzma/check/crc_macros.h b/game/client/third/minizip/lib/liblzma/check/crc_macros.h deleted file mode 100755 index a7c21b76..00000000 --- a/game/client/third/minizip/lib/liblzma/check/crc_macros.h +++ /dev/null @@ -1,30 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file crc_macros.h -/// \brief Some endian-dependent macros for CRC32 and CRC64 -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifdef WORDS_BIGENDIAN -# define A(x) ((x) >> 24) -# define B(x) (((x) >> 16) & 0xFF) -# define C(x) (((x) >> 8) & 0xFF) -# define D(x) ((x) & 0xFF) - -# define S8(x) ((x) << 8) -# define S32(x) ((x) << 32) - -#else -# define A(x) ((x) & 0xFF) -# define B(x) (((x) >> 8) & 0xFF) -# define C(x) (((x) >> 16) & 0xFF) -# define D(x) ((x) >> 24) - -# define S8(x) ((x) >> 8) -# define S32(x) ((x) >> 32) -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/alone_decoder.c b/game/client/third/minizip/lib/liblzma/common/alone_decoder.c deleted file mode 100755 index 1345d300..00000000 --- a/game/client/third/minizip/lib/liblzma/common/alone_decoder.c +++ /dev/null @@ -1,227 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file alone_decoder.c -/// \brief Decoder for LZMA_Alone files -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "alone_decoder.h" -#include "lzma_decoder.h" -#include "lz_decoder.h" - - -typedef struct { - lzma_next_coder next; - - enum { - SEQ_PROPERTIES, - SEQ_DICTIONARY_SIZE, - SEQ_UNCOMPRESSED_SIZE, - SEQ_CODER_INIT, - SEQ_CODE, - } sequence; - - /// If true, reject files that are unlikely to be .lzma files. - /// If false, more non-.lzma files get accepted and will give - /// LZMA_DATA_ERROR either immediately or after a few output bytes. - bool picky; - - /// Position in the header fields - size_t pos; - - /// Uncompressed size decoded from the header - lzma_vli uncompressed_size; - - /// Memory usage limit - uint64_t memlimit; - - /// Amount of memory actually needed (only an estimate) - uint64_t memusage; - - /// Options decoded from the header needed to initialize - /// the LZMA decoder - lzma_options_lzma options; -} lzma_alone_coder; - - -static lzma_ret -alone_decode(void *coder_ptr, - const lzma_allocator *allocator lzma_attribute((__unused__)), - const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size, - lzma_action action) -{ - lzma_alone_coder *coder = coder_ptr; - - while (*out_pos < out_size - && (coder->sequence == SEQ_CODE || *in_pos < in_size)) - switch (coder->sequence) { - case SEQ_PROPERTIES: - if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos])) - return LZMA_FORMAT_ERROR; - - coder->sequence = SEQ_DICTIONARY_SIZE; - ++*in_pos; - break; - - case SEQ_DICTIONARY_SIZE: - coder->options.dict_size - |= (size_t)(in[*in_pos]) << (coder->pos * 8); - ++*in_pos; - if (++coder->pos < 4) - break; - - if (coder->picky && coder->options.dict_size - != UINT32_MAX) { - // A hack to ditch tons of false positives: - // We allow only dictionary sizes that are - // 2^n or 2^n + 2^(n-1). LZMA_Alone created - // only files with 2^n, but accepts any - // dictionary size. - uint32_t d = coder->options.dict_size - 1; - d |= d >> 2; - d |= d >> 3; - d |= d >> 4; - d |= d >> 8; - d |= d >> 16; - ++d; - - if (d != coder->options.dict_size) - return LZMA_FORMAT_ERROR; - } - - coder->uncompressed_size = LZMA_VLI_UNKNOWN; - - // Calculate the memory usage so that it is ready - // for SEQ_CODER_INIT. - coder->memusage = lzma_lzma_decoder_memusage(&coder->options) - + LZMA_MEMUSAGE_BASE; - - coder->pos = 0; - coder->sequence = SEQ_CODER_INIT; - - // Fall through - - case SEQ_CODER_INIT: { - if (coder->memusage > coder->memlimit) - return LZMA_MEMLIMIT_ERROR; - - lzma_filter_info filters[2] = { - { - .init = &lzma_lzma_decoder_init, - .options = &coder->options, - }, { - .init = NULL, - } - }; - - const lzma_ret ret = lzma_next_filter_init(&coder->next, - allocator, filters); - if (ret != LZMA_OK) - return ret; - - // Use a hack to set the uncompressed size. - lzma_lz_decoder_uncompressed(coder->next.coder, - coder->uncompressed_size); - - coder->sequence = SEQ_CODE; - break; - } - - case SEQ_CODE: { - return coder->next.code(coder->next.coder, - allocator, in, in_pos, in_size, - out, out_pos, out_size, action); - } - - default: - return LZMA_PROG_ERROR; - } - - return LZMA_OK; -} - - -static void -alone_decoder_end(void *coder_ptr, const lzma_allocator *allocator) -{ - lzma_alone_coder *coder = coder_ptr; - lzma_next_end(&coder->next, allocator); - lzma_free(coder, allocator); - return; -} - - -static lzma_ret -alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage, - uint64_t *old_memlimit, uint64_t new_memlimit) -{ - lzma_alone_coder *coder = coder_ptr; - - *memusage = coder->memusage; - *old_memlimit = coder->memlimit; - - if (new_memlimit != 0) { - if (new_memlimit < coder->memusage) - return LZMA_MEMLIMIT_ERROR; - - coder->memlimit = new_memlimit; - } - - return LZMA_OK; -} - - -extern lzma_ret -lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, - uint64_t memlimit, bool picky) -{ - lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator); - - if (memlimit == 0) - return LZMA_PROG_ERROR; - - lzma_alone_coder *coder = next->coder; - - if (coder == NULL) { - coder = lzma_alloc(sizeof(lzma_alone_coder), allocator); - if (coder == NULL) - return LZMA_MEM_ERROR; - - next->coder = coder; - next->code = &alone_decode; - next->end = &alone_decoder_end; - next->memconfig = &alone_decoder_memconfig; - coder->next = LZMA_NEXT_CODER_INIT; - } - - coder->sequence = SEQ_PROPERTIES; - coder->picky = picky; - coder->pos = 0; - coder->options.dict_size = 0; - coder->options.preset_dict = NULL; - coder->options.preset_dict_size = 0; - coder->uncompressed_size = 0; - coder->memlimit = memlimit; - coder->memusage = LZMA_MEMUSAGE_BASE; - - return LZMA_OK; -} - - -extern LZMA_API(lzma_ret) -lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit) -{ - lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit, false); - - strm->internal->supported_actions[LZMA_RUN] = true; - strm->internal->supported_actions[LZMA_FINISH] = true; - - return LZMA_OK; -} diff --git a/game/client/third/minizip/lib/liblzma/common/alone_decoder.h b/game/client/third/minizip/lib/liblzma/common/alone_decoder.h deleted file mode 100755 index dfa031aa..00000000 --- a/game/client/third/minizip/lib/liblzma/common/alone_decoder.h +++ /dev/null @@ -1,23 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file alone_decoder.h -/// \brief Decoder for LZMA_Alone files -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_ALONE_DECODER_H -#define LZMA_ALONE_DECODER_H - -#include "common.h" - - -extern lzma_ret lzma_alone_decoder_init( - lzma_next_coder *next, const lzma_allocator *allocator, - uint64_t memlimit, bool picky); - -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/alone_encoder.c b/game/client/third/minizip/lib/liblzma/common/alone_encoder.c deleted file mode 100755 index d2f413fe..00000000 --- a/game/client/third/minizip/lib/liblzma/common/alone_encoder.c +++ /dev/null @@ -1,160 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file alone_decoder.c -/// \brief Decoder for LZMA_Alone files -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "common.h" -#include "lzma_encoder.h" - - -#define ALONE_HEADER_SIZE (1 + 4) - - -typedef struct { - lzma_next_coder next; - - enum { - SEQ_HEADER, - SEQ_CODE, - } sequence; - - size_t header_pos; - uint8_t header[ALONE_HEADER_SIZE]; -} lzma_alone_coder; - - -static lzma_ret -alone_encode(void *coder_ptr, - const lzma_allocator *allocator lzma_attribute((__unused__)), - const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size, - lzma_action action) -{ - lzma_alone_coder *coder = coder_ptr; - - while (*out_pos < out_size) - switch (coder->sequence) { - case SEQ_HEADER: - lzma_bufcpy(coder->header, &coder->header_pos, - ALONE_HEADER_SIZE, - out, out_pos, out_size); - if (coder->header_pos < ALONE_HEADER_SIZE) - return LZMA_OK; - - coder->sequence = SEQ_CODE; - break; - - case SEQ_CODE: - return coder->next.code(coder->next.coder, - allocator, in, in_pos, in_size, - out, out_pos, out_size, action); - - default: - assert(0); - return LZMA_PROG_ERROR; - } - - return LZMA_OK; -} - - -static void -alone_encoder_end(void *coder_ptr, const lzma_allocator *allocator) -{ - lzma_alone_coder *coder = coder_ptr; - lzma_next_end(&coder->next, allocator); - lzma_free(coder, allocator); - return; -} - - -// At least for now, this is not used by any internal function. -static lzma_ret -alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_options_lzma *options) -{ - lzma_next_coder_init(&alone_encoder_init, next, allocator); - - lzma_alone_coder *coder = next->coder; - - if (coder == NULL) { - coder = lzma_alloc(sizeof(lzma_alone_coder), allocator); - if (coder == NULL) - return LZMA_MEM_ERROR; - - next->coder = coder; - next->code = &alone_encode; - next->end = &alone_encoder_end; - coder->next = LZMA_NEXT_CODER_INIT; - } - - // Basic initializations - coder->sequence = SEQ_HEADER; - coder->header_pos = 0; - - // Encode the header: - // - Properties (1 byte) - if (lzma_lzma_lclppb_encode(options, coder->header)) - return LZMA_OPTIONS_ERROR; - - // - Dictionary size (4 bytes) - if (options->dict_size < LZMA_DICT_SIZE_MIN) - return LZMA_OPTIONS_ERROR; - - // Round up to the next 2^n or 2^n + 2^(n - 1) depending on which - // one is the next unless it is UINT32_MAX. While the header would - // allow any 32-bit integer, we do this to keep the decoder of liblzma - // accepting the resulting files. - uint32_t d = options->dict_size - 1; - d |= d >> 2; - d |= d >> 3; - d |= d >> 4; - d |= d >> 8; - d |= d >> 16; - if (d != UINT32_MAX) - ++d; - - unaligned_write32le(coder->header + 1, d); - - // Initialize the LZMA encoder. - const lzma_filter_info filters[2] = { - { - .init = &lzma_lzma_encoder_init, - .options = (void *)(options), - }, { - .init = NULL, - } - }; - - return lzma_next_filter_init(&coder->next, allocator, filters); -} - - -/* -extern lzma_ret -lzma_alone_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_options_alone *options) -{ - lzma_next_coder_init(&alone_encoder_init, next, allocator, options); -} -*/ - - -extern LZMA_API(lzma_ret) -lzma_alone_encoder(lzma_stream *strm, const lzma_options_lzma *options) -{ - lzma_next_strm_init(alone_encoder_init, strm, options); - - strm->internal->supported_actions[LZMA_RUN] = true; - strm->internal->supported_actions[LZMA_FINISH] = true; - - return LZMA_OK; -} diff --git a/game/client/third/minizip/lib/liblzma/common/common.c b/game/client/third/minizip/lib/liblzma/common/common.c deleted file mode 100755 index 28aa2b71..00000000 --- a/game/client/third/minizip/lib/liblzma/common/common.c +++ /dev/null @@ -1,443 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file common.h -/// \brief Common functions needed in many places in liblzma -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "common.h" - - -///////////// -// Version // -///////////// - -extern LZMA_API(uint32_t) -lzma_version_number(void) -{ - return LZMA_VERSION; -} - - -extern LZMA_API(const char *) -lzma_version_string(void) -{ - return LZMA_VERSION_STRING; -} - - -/////////////////////// -// Memory allocation // -/////////////////////// - -extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1) -lzma_alloc(size_t size, const lzma_allocator *allocator) -{ - // Some malloc() variants return NULL if called with size == 0. - if (size == 0) - size = 1; - - void *ptr; - - if (allocator != NULL && allocator->alloc != NULL) - ptr = allocator->alloc(allocator->opaque, 1, size); - else - ptr = malloc(size); - - return ptr; -} - - -extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1) -lzma_alloc_zero(size_t size, const lzma_allocator *allocator) -{ - // Some calloc() variants return NULL if called with size == 0. - if (size == 0) - size = 1; - - void *ptr; - - if (allocator != NULL && allocator->alloc != NULL) { - ptr = allocator->alloc(allocator->opaque, 1, size); - if (ptr != NULL) - memzero(ptr, size); - } else { - ptr = calloc(1, size); - } - - return ptr; -} - - -extern void -lzma_free(void *ptr, const lzma_allocator *allocator) -{ - if (allocator != NULL && allocator->free != NULL) - allocator->free(allocator->opaque, ptr); - else - free(ptr); - - return; -} - - -////////// -// Misc // -////////// - -extern size_t -lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size) -{ - const size_t in_avail = in_size - *in_pos; - const size_t out_avail = out_size - *out_pos; - const size_t copy_size = my_min(in_avail, out_avail); - - memcpy(out + *out_pos, in + *in_pos, copy_size); - - *in_pos += copy_size; - *out_pos += copy_size; - - return copy_size; -} - - -extern lzma_ret -lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters) -{ - lzma_next_coder_init(filters[0].init, next, allocator); - next->id = filters[0].id; - return filters[0].init == NULL - ? LZMA_OK : filters[0].init(next, allocator, filters); -} - - -extern lzma_ret -lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter *reversed_filters) -{ - // Check that the application isn't trying to change the Filter ID. - // End of filters is indicated with LZMA_VLI_UNKNOWN in both - // reversed_filters[0].id and next->id. - if (reversed_filters[0].id != next->id) - return LZMA_PROG_ERROR; - - if (reversed_filters[0].id == LZMA_VLI_UNKNOWN) - return LZMA_OK; - - assert(next->update != NULL); - return next->update(next->coder, allocator, NULL, reversed_filters); -} - - -extern void -lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator) -{ - if (next->init != (uintptr_t)(NULL)) { - // To avoid tiny end functions that simply call - // lzma_free(coder, allocator), we allow leaving next->end - // NULL and call lzma_free() here. - if (next->end != NULL) - next->end(next->coder, allocator); - else - lzma_free(next->coder, allocator); - - // Reset the variables so the we don't accidentally think - // that it is an already initialized coder. - *next = LZMA_NEXT_CODER_INIT; - } - - return; -} - - -////////////////////////////////////// -// External to internal API wrapper // -////////////////////////////////////// - -extern lzma_ret -lzma_strm_init(lzma_stream *strm) -{ - if (strm == NULL) - return LZMA_PROG_ERROR; - - if (strm->internal == NULL) { - strm->internal = lzma_alloc(sizeof(lzma_internal), - strm->allocator); - if (strm->internal == NULL) - return LZMA_MEM_ERROR; - - strm->internal->next = LZMA_NEXT_CODER_INIT; - } - - memzero(strm->internal->supported_actions, - sizeof(strm->internal->supported_actions)); - strm->internal->sequence = ISEQ_RUN; - strm->internal->allow_buf_error = false; - - strm->total_in = 0; - strm->total_out = 0; - - return LZMA_OK; -} - - -extern LZMA_API(lzma_ret) -lzma_code(lzma_stream *strm, lzma_action action) -{ - // Sanity checks - if ((strm->next_in == NULL && strm->avail_in != 0) - || (strm->next_out == NULL && strm->avail_out != 0) - || strm->internal == NULL - || strm->internal->next.code == NULL - || (unsigned int)(action) > LZMA_ACTION_MAX - || !strm->internal->supported_actions[action]) - return LZMA_PROG_ERROR; - - // Check if unsupported members have been set to non-zero or non-NULL, - // which would indicate that some new feature is wanted. - if (strm->reserved_ptr1 != NULL - || strm->reserved_ptr2 != NULL - || strm->reserved_ptr3 != NULL - || strm->reserved_ptr4 != NULL - || strm->reserved_int1 != 0 - || strm->reserved_int2 != 0 - || strm->reserved_int3 != 0 - || strm->reserved_int4 != 0 - || strm->reserved_enum1 != LZMA_RESERVED_ENUM - || strm->reserved_enum2 != LZMA_RESERVED_ENUM) - return LZMA_OPTIONS_ERROR; - - switch (strm->internal->sequence) { - case ISEQ_RUN: - switch (action) { - case LZMA_RUN: - break; - - case LZMA_SYNC_FLUSH: - strm->internal->sequence = ISEQ_SYNC_FLUSH; - break; - - case LZMA_FULL_FLUSH: - strm->internal->sequence = ISEQ_FULL_FLUSH; - break; - - case LZMA_FINISH: - strm->internal->sequence = ISEQ_FINISH; - break; - - case LZMA_FULL_BARRIER: - strm->internal->sequence = ISEQ_FULL_BARRIER; - break; - } - - break; - - case ISEQ_SYNC_FLUSH: - // The same action must be used until we return - // LZMA_STREAM_END, and the amount of input must not change. - if (action != LZMA_SYNC_FLUSH - || strm->internal->avail_in != strm->avail_in) - return LZMA_PROG_ERROR; - - break; - - case ISEQ_FULL_FLUSH: - if (action != LZMA_FULL_FLUSH - || strm->internal->avail_in != strm->avail_in) - return LZMA_PROG_ERROR; - - break; - - case ISEQ_FINISH: - if (action != LZMA_FINISH - || strm->internal->avail_in != strm->avail_in) - return LZMA_PROG_ERROR; - - break; - - case ISEQ_FULL_BARRIER: - if (action != LZMA_FULL_BARRIER - || strm->internal->avail_in != strm->avail_in) - return LZMA_PROG_ERROR; - - break; - - case ISEQ_END: - return LZMA_STREAM_END; - - case ISEQ_ERROR: - default: - return LZMA_PROG_ERROR; - } - - size_t in_pos = 0; - size_t out_pos = 0; - lzma_ret ret = strm->internal->next.code( - strm->internal->next.coder, strm->allocator, - strm->next_in, &in_pos, strm->avail_in, - strm->next_out, &out_pos, strm->avail_out, action); - - strm->next_in += in_pos; - strm->avail_in -= in_pos; - strm->total_in += in_pos; - - strm->next_out += out_pos; - strm->avail_out -= out_pos; - strm->total_out += out_pos; - - strm->internal->avail_in = strm->avail_in; - - // Cast is needed to silence a warning about LZMA_TIMED_OUT, which - // isn't part of lzma_ret enumeration. - switch ((unsigned int)(ret)) { - case LZMA_OK: - // Don't return LZMA_BUF_ERROR when it happens the first time. - // This is to avoid returning LZMA_BUF_ERROR when avail_out - // was zero but still there was no more data left to written - // to next_out. - if (out_pos == 0 && in_pos == 0) { - if (strm->internal->allow_buf_error) - ret = LZMA_BUF_ERROR; - else - strm->internal->allow_buf_error = true; - } else { - strm->internal->allow_buf_error = false; - } - break; - - case LZMA_TIMED_OUT: - strm->internal->allow_buf_error = false; - ret = LZMA_OK; - break; - - case LZMA_STREAM_END: - if (strm->internal->sequence == ISEQ_SYNC_FLUSH - || strm->internal->sequence == ISEQ_FULL_FLUSH - || strm->internal->sequence - == ISEQ_FULL_BARRIER) - strm->internal->sequence = ISEQ_RUN; - else - strm->internal->sequence = ISEQ_END; - - // Fall through - - case LZMA_NO_CHECK: - case LZMA_UNSUPPORTED_CHECK: - case LZMA_GET_CHECK: - case LZMA_MEMLIMIT_ERROR: - // Something else than LZMA_OK, but not a fatal error, - // that is, coding may be continued (except if ISEQ_END). - strm->internal->allow_buf_error = false; - break; - - default: - // All the other errors are fatal; coding cannot be continued. - assert(ret != LZMA_BUF_ERROR); - strm->internal->sequence = ISEQ_ERROR; - break; - } - - return ret; -} - - -extern LZMA_API(void) -lzma_end(lzma_stream *strm) -{ - if (strm != NULL && strm->internal != NULL) { - lzma_next_end(&strm->internal->next, strm->allocator); - lzma_free(strm->internal, strm->allocator); - strm->internal = NULL; - } - - return; -} - - -extern LZMA_API(void) -lzma_get_progress(lzma_stream *strm, - uint64_t *progress_in, uint64_t *progress_out) -{ - if (strm->internal->next.get_progress != NULL) { - strm->internal->next.get_progress(strm->internal->next.coder, - progress_in, progress_out); - } else { - *progress_in = strm->total_in; - *progress_out = strm->total_out; - } - - return; -} - - -extern LZMA_API(lzma_check) -lzma_get_check(const lzma_stream *strm) -{ - // Return LZMA_CHECK_NONE if we cannot know the check type. - // It's a bug in the application if this happens. - if (strm->internal->next.get_check == NULL) - return LZMA_CHECK_NONE; - - return strm->internal->next.get_check(strm->internal->next.coder); -} - - -extern LZMA_API(uint64_t) -lzma_memusage(const lzma_stream *strm) -{ - uint64_t memusage; - uint64_t old_memlimit; - - if (strm == NULL || strm->internal == NULL - || strm->internal->next.memconfig == NULL - || strm->internal->next.memconfig( - strm->internal->next.coder, - &memusage, &old_memlimit, 0) != LZMA_OK) - return 0; - - return memusage; -} - - -extern LZMA_API(uint64_t) -lzma_memlimit_get(const lzma_stream *strm) -{ - uint64_t old_memlimit; - uint64_t memusage; - - if (strm == NULL || strm->internal == NULL - || strm->internal->next.memconfig == NULL - || strm->internal->next.memconfig( - strm->internal->next.coder, - &memusage, &old_memlimit, 0) != LZMA_OK) - return 0; - - return old_memlimit; -} - - -extern LZMA_API(lzma_ret) -lzma_memlimit_set(lzma_stream *strm, uint64_t new_memlimit) -{ - // Dummy variables to simplify memconfig functions - uint64_t old_memlimit; - uint64_t memusage; - - if (strm == NULL || strm->internal == NULL - || strm->internal->next.memconfig == NULL) - return LZMA_PROG_ERROR; - - if (new_memlimit != 0 && new_memlimit < LZMA_MEMUSAGE_BASE) - return LZMA_MEMLIMIT_ERROR; - - return strm->internal->next.memconfig(strm->internal->next.coder, - &memusage, &old_memlimit, new_memlimit); -} diff --git a/game/client/third/minizip/lib/liblzma/common/common.h b/game/client/third/minizip/lib/liblzma/common/common.h deleted file mode 100755 index dde3ae0e..00000000 --- a/game/client/third/minizip/lib/liblzma/common/common.h +++ /dev/null @@ -1,313 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file common.h -/// \brief Definitions common to the whole liblzma library -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_COMMON_H -#define LZMA_COMMON_H - -#include "sysdefs.h" -#include "tuklib_integer.h" - -#if defined(_WIN32) || defined(__CYGWIN__) -# ifdef DLL_EXPORT -# define LZMA_API_EXPORT __declspec(dllexport) -# else -# define LZMA_API_EXPORT -# endif -// Don't use ifdef or defined() below. -#elif HAVE_VISIBILITY -# define LZMA_API_EXPORT __attribute__((__visibility__("default"))) -#else -# define LZMA_API_EXPORT -#endif - -#define LZMA_API(type) LZMA_API_EXPORT type LZMA_API_CALL - -#include "lzma.h" - -// These allow helping the compiler in some often-executed branches, whose -// result is almost always the same. -#ifdef __GNUC__ -# define likely(expr) __builtin_expect(expr, true) -# define unlikely(expr) __builtin_expect(expr, false) -#else -# define likely(expr) (expr) -# define unlikely(expr) (expr) -#endif - - -/// Size of temporary buffers needed in some filters -#define LZMA_BUFFER_SIZE 4096 - - -/// Maximum number of worker threads within one multithreaded component. -/// The limit exists solely to make it simpler to prevent integer overflows -/// when allocating structures etc. This should be big enough for now... -/// the code won't scale anywhere close to this number anyway. -#define LZMA_THREADS_MAX 16384 - - -/// Starting value for memory usage estimates. Instead of calculating size -/// of _every_ structure and taking into account malloc() overhead etc., we -/// add a base size to all memory usage estimates. It's not very accurate -/// but should be easily good enough. -#define LZMA_MEMUSAGE_BASE (UINT64_C(1) << 15) - -/// Start of internal Filter ID space. These IDs must never be used -/// in Streams. -#define LZMA_FILTER_RESERVED_START (LZMA_VLI_C(1) << 62) - - -/// Supported flags that can be passed to lzma_stream_decoder() -/// or lzma_auto_decoder(). -#define LZMA_SUPPORTED_FLAGS \ - ( LZMA_TELL_NO_CHECK \ - | LZMA_TELL_UNSUPPORTED_CHECK \ - | LZMA_TELL_ANY_CHECK \ - | LZMA_IGNORE_CHECK \ - | LZMA_CONCATENATED ) - - -/// Largest valid lzma_action value as unsigned integer. -#define LZMA_ACTION_MAX ((unsigned int)(LZMA_FULL_BARRIER)) - - -/// Special return value (lzma_ret) to indicate that a timeout was reached -/// and lzma_code() must not return LZMA_BUF_ERROR. This is converted to -/// LZMA_OK in lzma_code(). This is not in the lzma_ret enumeration because -/// there's no need to have it in the public API. -#define LZMA_TIMED_OUT 32 - - -typedef struct lzma_next_coder_s lzma_next_coder; - -typedef struct lzma_filter_info_s lzma_filter_info; - - -/// Type of a function used to initialize a filter encoder or decoder -typedef lzma_ret (*lzma_init_function)( - lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters); - -/// Type of a function to do some kind of coding work (filters, Stream, -/// Block encoders/decoders etc.). Some special coders use don't use both -/// input and output buffers, but for simplicity they still use this same -/// function prototype. -typedef lzma_ret (*lzma_code_function)( - void *coder, const lzma_allocator *allocator, - const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size, - lzma_action action); - -/// Type of a function to free the memory allocated for the coder -typedef void (*lzma_end_function)( - void *coder, const lzma_allocator *allocator); - - -/// Raw coder validates and converts an array of lzma_filter structures to -/// an array of lzma_filter_info structures. This array is used with -/// lzma_next_filter_init to initialize the filter chain. -struct lzma_filter_info_s { - /// Filter ID. This is used only by the encoder - /// with lzma_filters_update(). - lzma_vli id; - - /// Pointer to function used to initialize the filter. - /// This is NULL to indicate end of array. - lzma_init_function init; - - /// Pointer to filter's options structure - void *options; -}; - - -/// Hold data and function pointers of the next filter in the chain. -struct lzma_next_coder_s { - /// Pointer to coder-specific data - void *coder; - - /// Filter ID. This is LZMA_VLI_UNKNOWN when this structure doesn't - /// point to a filter coder. - lzma_vli id; - - /// "Pointer" to init function. This is never called here. - /// We need only to detect if we are initializing a coder - /// that was allocated earlier. See lzma_next_coder_init and - /// lzma_next_strm_init macros in this file. - uintptr_t init; - - /// Pointer to function to do the actual coding - lzma_code_function code; - - /// Pointer to function to free lzma_next_coder.coder. This can - /// be NULL; in that case, lzma_free is called to free - /// lzma_next_coder.coder. - lzma_end_function end; - - /// Pointer to a function to get progress information. If this is NULL, - /// lzma_stream.total_in and .total_out are used instead. - void (*get_progress)(void *coder, - uint64_t *progress_in, uint64_t *progress_out); - - /// Pointer to function to return the type of the integrity check. - /// Most coders won't support this. - lzma_check (*get_check)(const void *coder); - - /// Pointer to function to get and/or change the memory usage limit. - /// If new_memlimit == 0, the limit is not changed. - lzma_ret (*memconfig)(void *coder, uint64_t *memusage, - uint64_t *old_memlimit, uint64_t new_memlimit); - - /// Update the filter-specific options or the whole filter chain - /// in the encoder. - lzma_ret (*update)(void *coder, const lzma_allocator *allocator, - const lzma_filter *filters, - const lzma_filter *reversed_filters); -}; - - -/// Macro to initialize lzma_next_coder structure -#define LZMA_NEXT_CODER_INIT \ - (lzma_next_coder){ \ - .coder = NULL, \ - .init = (uintptr_t)(NULL), \ - .id = LZMA_VLI_UNKNOWN, \ - .code = NULL, \ - .end = NULL, \ - .get_progress = NULL, \ - .get_check = NULL, \ - .memconfig = NULL, \ - .update = NULL, \ - } - - -/// Internal data for lzma_strm_init, lzma_code, and lzma_end. A pointer to -/// this is stored in lzma_stream. -struct lzma_internal_s { - /// The actual coder that should do something useful - lzma_next_coder next; - - /// Track the state of the coder. This is used to validate arguments - /// so that the actual coders can rely on e.g. that LZMA_SYNC_FLUSH - /// is used on every call to lzma_code until next.code has returned - /// LZMA_STREAM_END. - enum { - ISEQ_RUN, - ISEQ_SYNC_FLUSH, - ISEQ_FULL_FLUSH, - ISEQ_FINISH, - ISEQ_FULL_BARRIER, - ISEQ_END, - ISEQ_ERROR, - } sequence; - - /// A copy of lzma_stream avail_in. This is used to verify that the - /// amount of input doesn't change once e.g. LZMA_FINISH has been - /// used. - size_t avail_in; - - /// Indicates which lzma_action values are allowed by next.code. - bool supported_actions[LZMA_ACTION_MAX + 1]; - - /// If true, lzma_code will return LZMA_BUF_ERROR if no progress was - /// made (no input consumed and no output produced by next.code). - bool allow_buf_error; -}; - - -/// Allocates memory -extern void *lzma_alloc(size_t size, const lzma_allocator *allocator) - lzma_attribute((__malloc__)) lzma_attr_alloc_size(1); - -/// Allocates memory and zeroes it (like calloc()). This can be faster -/// than lzma_alloc() + memzero() while being backward compatible with -/// custom allocators. -extern void * lzma_attribute((__malloc__)) lzma_attr_alloc_size(1) - lzma_alloc_zero(size_t size, const lzma_allocator *allocator); - -/// Frees memory -extern void lzma_free(void *ptr, const lzma_allocator *allocator); - - -/// Allocates strm->internal if it is NULL, and initializes *strm and -/// strm->internal. This function is only called via lzma_next_strm_init macro. -extern lzma_ret lzma_strm_init(lzma_stream *strm); - -/// Initializes the next filter in the chain, if any. This takes care of -/// freeing the memory of previously initialized filter if it is different -/// than the filter being initialized now. This way the actual filter -/// initialization functions don't need to use lzma_next_coder_init macro. -extern lzma_ret lzma_next_filter_init(lzma_next_coder *next, - const lzma_allocator *allocator, - const lzma_filter_info *filters); - -/// Update the next filter in the chain, if any. This checks that -/// the application is not trying to change the Filter IDs. -extern lzma_ret lzma_next_filter_update( - lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter *reversed_filters); - -/// Frees the memory allocated for next->coder either using next->end or, -/// if next->end is NULL, using lzma_free. -extern void lzma_next_end(lzma_next_coder *next, - const lzma_allocator *allocator); - - -/// Copy as much data as possible from in[] to out[] and update *in_pos -/// and *out_pos accordingly. Returns the number of bytes copied. -extern size_t lzma_bufcpy(const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size); - - -/// \brief Return if expression doesn't evaluate to LZMA_OK -/// -/// There are several situations where we want to return immediately -/// with the value of expr if it isn't LZMA_OK. This macro shortens -/// the code a little. -#define return_if_error(expr) \ -do { \ - const lzma_ret ret_ = (expr); \ - if (ret_ != LZMA_OK) \ - return ret_; \ -} while (0) - - -/// If next isn't already initialized, free the previous coder. Then mark -/// that next is _possibly_ initialized for the coder using this macro. -/// "Possibly" means that if e.g. allocation of next->coder fails, the -/// structure isn't actually initialized for this coder, but leaving -/// next->init to func is still OK. -#define lzma_next_coder_init(func, next, allocator) \ -do { \ - if ((uintptr_t)(func) != (next)->init) \ - lzma_next_end(next, allocator); \ - (next)->init = (uintptr_t)(func); \ -} while (0) - - -/// Initializes lzma_strm and calls func() to initialize strm->internal->next. -/// (The function being called will use lzma_next_coder_init()). If -/// initialization fails, memory that wasn't freed by func() is freed -/// along strm->internal. -#define lzma_next_strm_init(func, strm, ...) \ -do { \ - return_if_error(lzma_strm_init(strm)); \ - const lzma_ret ret_ = func(&(strm)->internal->next, \ - (strm)->allocator, __VA_ARGS__); \ - if (ret_ != LZMA_OK) { \ - lzma_end(strm); \ - return ret_; \ - } \ -} while (0) - -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/filter_encoder.c b/game/client/third/minizip/lib/liblzma/common/filter_encoder.c deleted file mode 100755 index 438e17e9..00000000 --- a/game/client/third/minizip/lib/liblzma/common/filter_encoder.c +++ /dev/null @@ -1,238 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file filter_decoder.c -/// \brief Filter ID mapping to filter-specific functions -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "filter_encoder.h" -#include "lzma_encoder.h" -#ifdef HAVE_DECODER_LZMA2 -#include "lzma2_encoder.h" -#endif -#if defined(HAVE_DECODER_X86) || \ - defined(HAVE_DECODER_POWERPC) || \ - defined(HAVE_DECODER_IA64) || \ - defined(HAVE_DECODER_ARM) || \ - defined(HAVE_DECODER_ARMTHUMB) || \ - defined(HAVE_DECODER_SPARC) -#include "simple_encoder.h" -#endif -#ifdef HAVE_DECODER_DELTA -#include "delta_encoder.h" -#endif - - -typedef struct { - /// Filter ID - lzma_vli id; - - /// Initializes the filter encoder and calls lzma_next_filter_init() - /// for filters + 1. - lzma_init_function init; - - /// Calculates memory usage of the encoder. If the options are - /// invalid, UINT64_MAX is returned. - uint64_t (*memusage)(const void *options); - - /// Calculates the recommended Uncompressed Size for .xz Blocks to - /// which the input data can be split to make multithreaded - /// encoding possible. If this is NULL, it is assumed that - /// the encoder is fast enough with single thread. - uint64_t (*block_size)(const void *options); - - /// Tells the size of the Filter Properties field. If options are - /// invalid, UINT32_MAX is returned. If this is NULL, props_size_fixed - /// is used. - lzma_ret (*props_size_get)(uint32_t *size, const void *options); - uint32_t props_size_fixed; - - /// Encodes Filter Properties. - /// - /// \return - LZMA_OK: Properties encoded successfully. - /// - LZMA_OPTIONS_ERROR: Unsupported options - /// - LZMA_PROG_ERROR: Invalid options or not enough - /// output space - lzma_ret (*props_encode)(const void *options, uint8_t *out); - -} lzma_filter_encoder; - - -static const lzma_filter_encoder encoders[] = { -#ifdef HAVE_ENCODER_LZMA1 - { - .id = LZMA_FILTER_LZMA1, - .init = &lzma_lzma_encoder_init, - .memusage = &lzma_lzma_encoder_memusage, - .block_size = NULL, // FIXME - .props_size_get = NULL, - .props_size_fixed = 5, - .props_encode = &lzma_lzma_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_LZMA2 - { - .id = LZMA_FILTER_LZMA2, - .init = &lzma_lzma2_encoder_init, - .memusage = &lzma_lzma2_encoder_memusage, - .block_size = &lzma_lzma2_block_size, // FIXME - .props_size_get = NULL, - .props_size_fixed = 1, - .props_encode = &lzma_lzma2_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_X86 - { - .id = LZMA_FILTER_X86, - .init = &lzma_simple_x86_encoder_init, - .memusage = NULL, - .block_size = NULL, - .props_size_get = &lzma_simple_props_size, - .props_encode = &lzma_simple_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_POWERPC - { - .id = LZMA_FILTER_POWERPC, - .init = &lzma_simple_powerpc_encoder_init, - .memusage = NULL, - .block_size = NULL, - .props_size_get = &lzma_simple_props_size, - .props_encode = &lzma_simple_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_IA64 - { - .id = LZMA_FILTER_IA64, - .init = &lzma_simple_ia64_encoder_init, - .memusage = NULL, - .block_size = NULL, - .props_size_get = &lzma_simple_props_size, - .props_encode = &lzma_simple_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_ARM - { - .id = LZMA_FILTER_ARM, - .init = &lzma_simple_arm_encoder_init, - .memusage = NULL, - .block_size = NULL, - .props_size_get = &lzma_simple_props_size, - .props_encode = &lzma_simple_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_ARMTHUMB - { - .id = LZMA_FILTER_ARMTHUMB, - .init = &lzma_simple_armthumb_encoder_init, - .memusage = NULL, - .block_size = NULL, - .props_size_get = &lzma_simple_props_size, - .props_encode = &lzma_simple_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_SPARC - { - .id = LZMA_FILTER_SPARC, - .init = &lzma_simple_sparc_encoder_init, - .memusage = NULL, - .block_size = NULL, - .props_size_get = &lzma_simple_props_size, - .props_encode = &lzma_simple_props_encode, - }, -#endif -#ifdef HAVE_ENCODER_DELTA - { - .id = LZMA_FILTER_DELTA, - .init = &lzma_delta_encoder_init, - .memusage = &lzma_delta_coder_memusage, - .block_size = NULL, - .props_size_get = NULL, - .props_size_fixed = 1, - .props_encode = &lzma_delta_props_encode, - }, -#endif -}; - - -static const lzma_filter_encoder * -encoder_find(lzma_vli id) -{ - for (size_t i = 0; i < ARRAY_SIZE(encoders); ++i) - if (encoders[i].id == id) - return encoders + i; - - return NULL; -} - - -extern LZMA_API(lzma_bool) -lzma_filter_encoder_is_supported(lzma_vli id) -{ - return encoder_find(id) != NULL; -} - - -extern uint64_t -lzma_mt_block_size(const lzma_filter *filters) -{ - uint64_t max = 0; - - for (size_t i = 0; filters[i].id != LZMA_VLI_UNKNOWN; ++i) { - const lzma_filter_encoder *const fe - = encoder_find(filters[i].id); - if (fe->block_size != NULL) { - const uint64_t size - = fe->block_size(filters[i].options); - if (size == 0) - return 0; - - if (size > max) - max = size; - } - } - - return max; -} - - -extern LZMA_API(lzma_ret) -lzma_properties_size(uint32_t *size, const lzma_filter *filter) -{ - const lzma_filter_encoder *const fe = encoder_find(filter->id); - if (fe == NULL) { - // Unknown filter - if the Filter ID is a proper VLI, - // return LZMA_OPTIONS_ERROR instead of LZMA_PROG_ERROR, - // because it's possible that we just don't have support - // compiled in for the requested filter. - return filter->id <= LZMA_VLI_MAX - ? LZMA_OPTIONS_ERROR : LZMA_PROG_ERROR; - } - - if (fe->props_size_get == NULL) { - // No props_size_get() function, use props_size_fixed. - *size = fe->props_size_fixed; - return LZMA_OK; - } - - return fe->props_size_get(size, filter->options); -} - - -extern LZMA_API(lzma_ret) -lzma_properties_encode(const lzma_filter *filter, uint8_t *props) -{ - const lzma_filter_encoder *const fe = encoder_find(filter->id); - if (fe == NULL) - return LZMA_PROG_ERROR; - - if (fe->props_encode == NULL) - return LZMA_OK; - - return fe->props_encode(filter->options, props); -} diff --git a/game/client/third/minizip/lib/liblzma/common/filter_encoder.h b/game/client/third/minizip/lib/liblzma/common/filter_encoder.h deleted file mode 100755 index f1d5683f..00000000 --- a/game/client/third/minizip/lib/liblzma/common/filter_encoder.h +++ /dev/null @@ -1,27 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file filter_encoder.c -/// \brief Filter ID mapping to filter-specific functions -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_FILTER_ENCODER_H -#define LZMA_FILTER_ENCODER_H - -#include "common.h" - - -// FIXME: Might become a part of the public API. -extern uint64_t lzma_mt_block_size(const lzma_filter *filters); - - -extern lzma_ret lzma_raw_encoder_init( - lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter *filters); - -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/index.h b/game/client/third/minizip/lib/liblzma/common/index.h deleted file mode 100755 index 64e97247..00000000 --- a/game/client/third/minizip/lib/liblzma/common/index.h +++ /dev/null @@ -1,73 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file index.h -/// \brief Handling of Index -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_INDEX_H -#define LZMA_INDEX_H - -#include "common.h" - - -/// Minimum Unpadded Size -#define UNPADDED_SIZE_MIN LZMA_VLI_C(5) - -/// Maximum Unpadded Size -#define UNPADDED_SIZE_MAX (LZMA_VLI_MAX & ~LZMA_VLI_C(3)) - - -/// Get the size of the Index Padding field. This is needed by Index encoder -/// and decoder, but applications should have no use for this. -extern uint32_t lzma_index_padding_size(const lzma_index *i); - - -/// Set for how many Records to allocate memory the next time -/// lzma_index_append() needs to allocate space for a new Record. -/// This is used only by the Index decoder. -extern void lzma_index_prealloc(lzma_index *i, lzma_vli records); - - -/// Round the variable-length integer to the next multiple of four. -static inline lzma_vli -vli_ceil4(lzma_vli vli) -{ - assert(vli <= LZMA_VLI_MAX); - return (vli + 3) & ~LZMA_VLI_C(3); -} - - -/// Calculate the size of the Index field excluding Index Padding -static inline lzma_vli -index_size_unpadded(lzma_vli count, lzma_vli index_list_size) -{ - // Index Indicator + Number of Records + List of Records + CRC32 - return 1 + lzma_vli_size(count) + index_list_size + 4; -} - - -/// Calculate the size of the Index field including Index Padding -static inline lzma_vli -index_size(lzma_vli count, lzma_vli index_list_size) -{ - return vli_ceil4(index_size_unpadded(count, index_list_size)); -} - - -/// Calculate the total size of the Stream -static inline lzma_vli -index_stream_size(lzma_vli blocks_size, - lzma_vli count, lzma_vli index_list_size) -{ - return LZMA_STREAM_HEADER_SIZE + blocks_size - + index_size(count, index_list_size) - + LZMA_STREAM_HEADER_SIZE; -} - -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/memcmplen.h b/game/client/third/minizip/lib/liblzma/common/memcmplen.h deleted file mode 100755 index c1efc9e2..00000000 --- a/game/client/third/minizip/lib/liblzma/common/memcmplen.h +++ /dev/null @@ -1,175 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file memcmplen.h -/// \brief Optimized comparison of two buffers -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_MEMCMPLEN_H -#define LZMA_MEMCMPLEN_H - -#include "common.h" - -#ifdef HAVE_IMMINTRIN_H -# include -#endif - - -/// Find out how many equal bytes the two buffers have. -/// -/// \param buf1 First buffer -/// \param buf2 Second buffer -/// \param len How many bytes have already been compared and will -/// be assumed to match -/// \param limit How many bytes to compare at most, including the -/// already-compared bytes. This must be significantly -/// smaller than UINT32_MAX to avoid integer overflows. -/// Up to LZMA_MEMCMPLEN_EXTRA bytes may be read past -/// the specified limit from both buf1 and buf2. -/// -/// \return Number of equal bytes in the buffers is returned. -/// This is always at least len and at most limit. -/// -/// \note LZMA_MEMCMPLEN_EXTRA defines how many extra bytes may be read. -/// It's rounded up to 2^n. This extra amount needs to be -/// allocated in the buffers being used. It needs to be -/// initialized too to keep Valgrind quiet. -static inline uint32_t lzma_attribute((__always_inline__)) -lzma_memcmplen(const uint8_t *buf1, const uint8_t *buf2, - uint32_t len, uint32_t limit) -{ - assert(len <= limit); - assert(limit <= UINT32_MAX / 2); - -#if defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ - && ((TUKLIB_GNUC_REQ(3, 4) && defined(__x86_64__)) \ - || (defined(__INTEL_COMPILER) && defined(__x86_64__)) \ - || (defined(__INTEL_COMPILER) && defined(_M_X64)) \ - || (defined(_MSC_VER) && defined(_M_X64))) - // NOTE: This will use 64-bit unaligned access which - // TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit, but - // it's convenient here at least as long as it's x86-64 only. - // - // I keep this x86-64 only for now since that's where I know this - // to be a good method. This may be fine on other 64-bit CPUs too. - // On big endian one should use xor instead of subtraction and switch - // to __builtin_clzll(). -#define LZMA_MEMCMPLEN_EXTRA 8 - while (len < limit) { - const uint64_t x = *(const uint64_t *)(buf1 + len) - - *(const uint64_t *)(buf2 + len); - if (x != 0) { -# if defined(_M_X64) // MSVC or Intel C compiler on Windows - unsigned long tmp; - _BitScanForward64(&tmp, x); - len += (uint32_t)tmp >> 3; -# else // GCC, clang, or Intel C compiler - len += (uint32_t)__builtin_ctzll(x) >> 3; -# endif - return my_min(len, limit); - } - - len += 8; - } - - return limit; - -#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) \ - && defined(HAVE__MM_MOVEMASK_EPI8) \ - && ((defined(__GNUC__) && defined(__SSE2_MATH__)) \ - || (defined(__INTEL_COMPILER) && defined(__SSE2__)) \ - || (defined(_MSC_VER) && defined(_M_IX86_FP) \ - && _M_IX86_FP >= 2)) - // NOTE: Like above, this will use 128-bit unaligned access which - // TUKLIB_FAST_UNALIGNED_ACCESS wasn't meant to permit. - // - // SSE2 version for 32-bit and 64-bit x86. On x86-64 the above - // version is sometimes significantly faster and sometimes - // slightly slower than this SSE2 version, so this SSE2 - // version isn't used on x86-64. -# define LZMA_MEMCMPLEN_EXTRA 16 - while (len < limit) { - const uint32_t x = 0xFFFF ^ _mm_movemask_epi8(_mm_cmpeq_epi8( - _mm_loadu_si128((const __m128i *)(buf1 + len)), - _mm_loadu_si128((const __m128i *)(buf2 + len)))); - - if (x != 0) { -# if defined(__INTEL_COMPILER) - len += _bit_scan_forward(x); -# elif defined(_MSC_VER) - unsigned long tmp; - _BitScanForward(&tmp, x); - len += tmp; -# else - len += __builtin_ctz(x); -# endif - return my_min(len, limit); - } - - len += 16; - } - - return limit; - -#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && !defined(WORDS_BIGENDIAN) - // Generic 32-bit little endian method -# define LZMA_MEMCMPLEN_EXTRA 4 - while (len < limit) { - uint32_t x = *(const uint32_t *)(buf1 + len) - - *(const uint32_t *)(buf2 + len); - if (x != 0) { - if ((x & 0xFFFF) == 0) { - len += 2; - x >>= 16; - } - - if ((x & 0xFF) == 0) - ++len; - - return my_min(len, limit); - } - - len += 4; - } - - return limit; - -#elif defined(TUKLIB_FAST_UNALIGNED_ACCESS) && defined(WORDS_BIGENDIAN) - // Generic 32-bit big endian method -# define LZMA_MEMCMPLEN_EXTRA 4 - while (len < limit) { - uint32_t x = *(const uint32_t *)(buf1 + len) - ^ *(const uint32_t *)(buf2 + len); - if (x != 0) { - if ((x & 0xFFFF0000) == 0) { - len += 2; - x <<= 16; - } - - if ((x & 0xFF000000) == 0) - ++len; - - return my_min(len, limit); - } - - len += 4; - } - - return limit; - -#else - // Simple portable version that doesn't use unaligned access. -# define LZMA_MEMCMPLEN_EXTRA 0 - while (len < limit && buf1[len] == buf2[len]) - ++len; - - return len; -#endif -} - -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/sysdefs.h b/game/client/third/minizip/lib/liblzma/common/sysdefs.h deleted file mode 100755 index 4fe47ee2..00000000 --- a/game/client/third/minizip/lib/liblzma/common/sysdefs.h +++ /dev/null @@ -1,204 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file sysdefs.h -/// \brief Common includes, definitions, system-specific things etc. -/// -/// This file is used also by the lzma command line tool, that's why this -/// file is separate from common.h. -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_SYSDEFS_H -#define LZMA_SYSDEFS_H - -////////////// -// Includes // -////////////// - -#ifdef HAVE_CONFIG_H -# include -#endif - -// Get standard-compliant stdio functions under MinGW and MinGW-w64. -#ifdef __MINGW32__ -# define __USE_MINGW_ANSI_STDIO 1 -#endif - -// size_t and NULL -#include - -#ifdef HAVE_INTTYPES_H -# include -#endif - -// C99 says that inttypes.h always includes stdint.h, but some systems -// don't do that, and require including stdint.h separately. -#ifdef HAVE_STDINT_H -# include -#endif - -// Some pre-C99 systems have SIZE_MAX in limits.h instead of stdint.h. The -// limits are also used to figure out some macros missing from pre-C99 systems. -#ifdef HAVE_LIMITS_H -# include -#endif - -// Be more compatible with systems that have non-conforming inttypes.h. -// We assume that int is 32-bit and that long is either 32-bit or 64-bit. -// Full Autoconf test could be more correct, but this should work well enough. -// Note that this duplicates some code from lzma.h, but this is better since -// we can work without inttypes.h thanks to Autoconf tests. -#ifndef UINT32_C -# if UINT_MAX != 4294967295U -# error UINT32_C is not defined and unsigned int is not 32-bit. -# endif -# define UINT32_C(n) n ## U -#endif -#ifndef UINT32_MAX -# define UINT32_MAX UINT32_C(4294967295) -#endif -#ifndef PRIu32 -# define PRIu32 "u" -#endif -#ifndef PRIx32 -# define PRIx32 "x" -#endif -#ifndef PRIX32 -# define PRIX32 "X" -#endif - -#if ULONG_MAX == 4294967295UL -# ifndef UINT64_C -# define UINT64_C(n) n ## ULL -# endif -# ifndef PRIu64 -# define PRIu64 "llu" -# endif -# ifndef PRIx64 -# define PRIx64 "llx" -# endif -# ifndef PRIX64 -# define PRIX64 "llX" -# endif -#else -# ifndef UINT64_C -# define UINT64_C(n) n ## UL -# endif -# ifndef PRIu64 -# define PRIu64 "lu" -# endif -# ifndef PRIx64 -# define PRIx64 "lx" -# endif -# ifndef PRIX64 -# define PRIX64 "lX" -# endif -#endif -#ifndef UINT64_MAX -# define UINT64_MAX UINT64_C(18446744073709551615) -#endif - -// Incorrect(?) SIZE_MAX: -// - Interix headers typedef size_t to unsigned long, -// but a few lines later define SIZE_MAX to INT32_MAX. -// - SCO OpenServer (x86) headers typedef size_t to unsigned int -// but define SIZE_MAX to INT32_MAX. -#if defined(__INTERIX) || defined(_SCO_DS) -# undef SIZE_MAX -#endif - -// The code currently assumes that size_t is either 32-bit or 64-bit. -#ifndef SIZE_MAX -# if SIZEOF_SIZE_T == 4 -# define SIZE_MAX UINT32_MAX -# elif SIZEOF_SIZE_T == 8 -# define SIZE_MAX UINT64_MAX -# else -# error size_t is not 32-bit or 64-bit -# endif -#endif -#if SIZE_MAX != UINT32_MAX && SIZE_MAX != UINT64_MAX -# error size_t is not 32-bit or 64-bit -#endif - -#include -#include - -// Pre-C99 systems lack stdbool.h. All the code in LZMA Utils must be written -// so that it works with fake bool type, for example: -// -// bool foo = (flags & 0x100) != 0; -// bool bar = !!(flags & 0x100); -// -// This works with the real C99 bool but breaks with fake bool: -// -// bool baz = (flags & 0x100); -// -#ifdef HAVE_STDBOOL_H -# include -#else -# if ! HAVE__BOOL -typedef unsigned char _Bool; -# endif -# define bool _Bool -# define false 0 -# define true 1 -# define __bool_true_false_are_defined 1 -#endif - -// string.h should be enough but let's include strings.h and memory.h too if -// they exists, since that shouldn't do any harm, but may improve portability. -#ifdef HAVE_STRING_H -# include -#endif - -#ifdef HAVE_STRINGS_H -# include -#endif - -#ifdef HAVE_MEMORY_H -# include -#endif - -// As of MSVC 2013, inline and restrict are supported with -// non-standard keywords. -#if defined(_WIN32) && defined(_MSC_VER) -# ifndef inline -# define inline __inline -# endif -# ifndef restrict -# define restrict __restrict -# endif -#elif __STDC_VERSION__ < 199901L -# define restrict // nothing -#endif - -//////////// -// Macros // -//////////// - -#undef memzero -#define memzero(s, n) memset(s, 0, n) - -// NOTE: Avoid using MIN() and MAX(), because even conditionally defining -// those macros can cause some portability trouble, since on some systems -// the system headers insist defining their own versions. -#define my_min(x, y) ((x) < (y) ? (x) : (y)) -#define my_max(x, y) ((x) > (y) ? (x) : (y)) - -#ifndef ARRAY_SIZE -# define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) -#endif - -#if (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) || __GNUC__ > 4 -# define lzma_attr_alloc_size(x) __attribute__((__alloc_size__(x))) -#else -# define lzma_attr_alloc_size(x) -#endif - -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/tuklib_common.h b/game/client/third/minizip/lib/liblzma/common/tuklib_common.h deleted file mode 100755 index 31fbab58..00000000 --- a/game/client/third/minizip/lib/liblzma/common/tuklib_common.h +++ /dev/null @@ -1,71 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file tuklib_common.h -/// \brief Common definitions for tuklib modules -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef TUKLIB_COMMON_H -#define TUKLIB_COMMON_H - -// The config file may be replaced by a package-specific file. -// It should include at least stddef.h, inttypes.h, and limits.h. -#include "tuklib_config.h" - -// TUKLIB_SYMBOL_PREFIX is prefixed to all symbols exported by -// the tuklib modules. If you use a tuklib module in a library, -// you should use TUKLIB_SYMBOL_PREFIX to make sure that there -// are no symbol conflicts in case someone links your library -// into application that also uses the same tuklib module. -#ifndef TUKLIB_SYMBOL_PREFIX -# define TUKLIB_SYMBOL_PREFIX -#endif - -#define TUKLIB_CAT_X(a, b) a ## b -#define TUKLIB_CAT(a, b) TUKLIB_CAT_X(a, b) - -#ifndef TUKLIB_SYMBOL -# define TUKLIB_SYMBOL(sym) TUKLIB_CAT(TUKLIB_SYMBOL_PREFIX, sym) -#endif - -#ifndef TUKLIB_DECLS_BEGIN -# ifdef __cplusplus -# define TUKLIB_DECLS_BEGIN extern "C" { -# else -# define TUKLIB_DECLS_BEGIN -# endif -#endif - -#ifndef TUKLIB_DECLS_END -# ifdef __cplusplus -# define TUKLIB_DECLS_END } -# else -# define TUKLIB_DECLS_END -# endif -#endif - -#if defined(__GNUC__) && defined(__GNUC_MINOR__) -# define TUKLIB_GNUC_REQ(major, minor) \ - ((__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)) \ - || __GNUC__ > (major)) -#else -# define TUKLIB_GNUC_REQ(major, minor) 0 -#endif - -#if TUKLIB_GNUC_REQ(2, 5) -# define tuklib_attr_noreturn __attribute__((__noreturn__)) -#else -# define tuklib_attr_noreturn -#endif - -#if (defined(_WIN32) && !defined(__CYGWIN__)) \ - || defined(__OS2__) || defined(__MSDOS__) -# define TUKLIB_DOSLIKE 1 -#endif - -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/tuklib_config.h b/game/client/third/minizip/lib/liblzma/common/tuklib_config.h deleted file mode 100755 index 549cb24d..00000000 --- a/game/client/third/minizip/lib/liblzma/common/tuklib_config.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "sysdefs.h" -#else -# include -# include -# include -#endif diff --git a/game/client/third/minizip/lib/liblzma/common/tuklib_integer.h b/game/client/third/minizip/lib/liblzma/common/tuklib_integer.h deleted file mode 100755 index 738690d6..00000000 --- a/game/client/third/minizip/lib/liblzma/common/tuklib_integer.h +++ /dev/null @@ -1,523 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file tuklib_integer.h -/// \brief Various integer and bit operations -/// -/// This file provides macros or functions to do some basic integer and bit -/// operations. -/// -/// Endianness related integer operations (XX = 16, 32, or 64; Y = b or l): -/// - Byte swapping: bswapXX(num) -/// - Byte order conversions to/from native: convXXYe(num) -/// - Aligned reads: readXXYe(ptr) -/// - Aligned writes: writeXXYe(ptr, num) -/// - Unaligned reads (16/32-bit only): unaligned_readXXYe(ptr) -/// - Unaligned writes (16/32-bit only): unaligned_writeXXYe(ptr, num) -/// -/// Since they can macros, the arguments should have no side effects since -/// they may be evaluated more than once. -/// -/// \todo PowerPC and possibly some other architectures support -/// byte swapping load and store instructions. This file -/// doesn't take advantage of those instructions. -/// -/// Bit scan operations for non-zero 32-bit integers: -/// - Bit scan reverse (find highest non-zero bit): bsr32(num) -/// - Count leading zeros: clz32(num) -/// - Count trailing zeros: ctz32(num) -/// - Bit scan forward (simply an alias for ctz32()): bsf32(num) -/// -/// The above bit scan operations return 0-31. If num is zero, -/// the result is undefined. -// -// Authors: Lasse Collin -// Joachim Henke -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef TUKLIB_INTEGER_H -#define TUKLIB_INTEGER_H - -#include "tuklib_common.h" - - -//////////////////////////////////////// -// Operating system specific features // -//////////////////////////////////////// - -#if defined(HAVE_BYTESWAP_H) - // glibc, uClibc, dietlibc -# include -# ifdef HAVE_BSWAP_16 -# define bswap16(num) bswap_16(num) -# endif -# ifdef HAVE_BSWAP_32 -# define bswap32(num) bswap_32(num) -# endif -# ifdef HAVE_BSWAP_64 -# define bswap64(num) bswap_64(num) -# endif - -#elif defined(HAVE_SYS_ENDIAN_H) - // *BSDs and Darwin -# include - -#elif defined(HAVE_SYS_BYTEORDER_H) - // Solaris -# include -# ifdef BSWAP_16 -# define bswap16(num) BSWAP_16(num) -# endif -# ifdef BSWAP_32 -# define bswap32(num) BSWAP_32(num) -# endif -# ifdef BSWAP_64 -# define bswap64(num) BSWAP_64(num) -# endif -# ifdef BE_16 -# define conv16be(num) BE_16(num) -# endif -# ifdef BE_32 -# define conv32be(num) BE_32(num) -# endif -# ifdef BE_64 -# define conv64be(num) BE_64(num) -# endif -# ifdef LE_16 -# define conv16le(num) LE_16(num) -# endif -# ifdef LE_32 -# define conv32le(num) LE_32(num) -# endif -# ifdef LE_64 -# define conv64le(num) LE_64(num) -# endif -#endif - - -/////////////////// -// Byte swapping // -/////////////////// - -#ifndef bswap16 -# define bswap16(num) \ - (((uint16_t)(num) << 8) | ((uint16_t)(num) >> 8)) -#endif - -#ifndef bswap32 -# define bswap32(num) \ - ( (((uint32_t)(num) << 24) ) \ - | (((uint32_t)(num) << 8) & UINT32_C(0x00FF0000)) \ - | (((uint32_t)(num) >> 8) & UINT32_C(0x0000FF00)) \ - | (((uint32_t)(num) >> 24) ) ) -#endif - -#ifndef bswap64 -# define bswap64(num) \ - ( (((uint64_t)(num) << 56) ) \ - | (((uint64_t)(num) << 40) & UINT64_C(0x00FF000000000000)) \ - | (((uint64_t)(num) << 24) & UINT64_C(0x0000FF0000000000)) \ - | (((uint64_t)(num) << 8) & UINT64_C(0x000000FF00000000)) \ - | (((uint64_t)(num) >> 8) & UINT64_C(0x00000000FF000000)) \ - | (((uint64_t)(num) >> 24) & UINT64_C(0x0000000000FF0000)) \ - | (((uint64_t)(num) >> 40) & UINT64_C(0x000000000000FF00)) \ - | (((uint64_t)(num) >> 56) ) ) -#endif - -// Define conversion macros using the basic byte swapping macros. -#ifdef WORDS_BIGENDIAN -# ifndef conv16be -# define conv16be(num) ((uint16_t)(num)) -# endif -# ifndef conv32be -# define conv32be(num) ((uint32_t)(num)) -# endif -# ifndef conv64be -# define conv64be(num) ((uint64_t)(num)) -# endif -# ifndef conv16le -# define conv16le(num) bswap16(num) -# endif -# ifndef conv32le -# define conv32le(num) bswap32(num) -# endif -# ifndef conv64le -# define conv64le(num) bswap64(num) -# endif -#else -# ifndef conv16be -# define conv16be(num) bswap16(num) -# endif -# ifndef conv32be -# define conv32be(num) bswap32(num) -# endif -# ifndef conv64be -# define conv64be(num) bswap64(num) -# endif -# ifndef conv16le -# define conv16le(num) ((uint16_t)(num)) -# endif -# ifndef conv32le -# define conv32le(num) ((uint32_t)(num)) -# endif -# ifndef conv64le -# define conv64le(num) ((uint64_t)(num)) -# endif -#endif - - -////////////////////////////// -// Aligned reads and writes // -////////////////////////////// - -static inline uint16_t -read16be(const uint8_t *buf) -{ - uint16_t num = *(const uint16_t *)buf; - return conv16be(num); -} - - -static inline uint16_t -read16le(const uint8_t *buf) -{ - uint16_t num = *(const uint16_t *)buf; - return conv16le(num); -} - - -static inline uint32_t -read32be(const uint8_t *buf) -{ - uint32_t num = *(const uint32_t *)buf; - return conv32be(num); -} - - -static inline uint32_t -read32le(const uint8_t *buf) -{ - uint32_t num = *(const uint32_t *)buf; - return conv32le(num); -} - - -static inline uint64_t -read64be(const uint8_t *buf) -{ - uint64_t num = *(const uint64_t *)buf; - return conv64be(num); -} - - -static inline uint64_t -read64le(const uint8_t *buf) -{ - uint64_t num = *(const uint64_t *)buf; - return conv64le(num); -} - - -// NOTE: Possible byte swapping must be done in a macro to allow GCC -// to optimize byte swapping of constants when using glibc's or *BSD's -// byte swapping macros. The actual write is done in an inline function -// to make type checking of the buf pointer possible similarly to readXXYe() -// functions. - -#define write16be(buf, num) write16ne((buf), conv16be(num)) -#define write16le(buf, num) write16ne((buf), conv16le(num)) -#define write32be(buf, num) write32ne((buf), conv32be(num)) -#define write32le(buf, num) write32ne((buf), conv32le(num)) -#define write64be(buf, num) write64ne((buf), conv64be(num)) -#define write64le(buf, num) write64ne((buf), conv64le(num)) - - -static inline void -write16ne(uint8_t *buf, uint16_t num) -{ - *(uint16_t *)buf = num; - return; -} - - -static inline void -write32ne(uint8_t *buf, uint32_t num) -{ - *(uint32_t *)buf = num; - return; -} - - -static inline void -write64ne(uint8_t *buf, uint64_t num) -{ - *(uint64_t *)buf = num; - return; -} - - -//////////////////////////////// -// Unaligned reads and writes // -//////////////////////////////// - -// NOTE: TUKLIB_FAST_UNALIGNED_ACCESS indicates only support for 16-bit and -// 32-bit unaligned integer loads and stores. It's possible that 64-bit -// unaligned access doesn't work or is slower than byte-by-byte access. -// Since unaligned 64-bit is probably not needed as often as 16-bit or -// 32-bit, we simply don't support 64-bit unaligned access for now. -#ifdef TUKLIB_FAST_UNALIGNED_ACCESS -# define unaligned_read16be read16be -# define unaligned_read16le read16le -# define unaligned_read32be read32be -# define unaligned_read32le read32le -# define unaligned_write16be write16be -# define unaligned_write16le write16le -# define unaligned_write32be write32be -# define unaligned_write32le write32le - -#else - -static inline uint16_t -unaligned_read16be(const uint8_t *buf) -{ - uint16_t num = ((uint16_t)buf[0] << 8) | (uint16_t)buf[1]; - return num; -} - - -static inline uint16_t -unaligned_read16le(const uint8_t *buf) -{ - uint16_t num = ((uint16_t)buf[0]) | ((uint16_t)buf[1] << 8); - return num; -} - - -static inline uint32_t -unaligned_read32be(const uint8_t *buf) -{ - uint32_t num = (uint32_t)buf[0] << 24; - num |= (uint32_t)buf[1] << 16; - num |= (uint32_t)buf[2] << 8; - num |= (uint32_t)buf[3]; - return num; -} - - -static inline uint32_t -unaligned_read32le(const uint8_t *buf) -{ - uint32_t num = (uint32_t)buf[0]; - num |= (uint32_t)buf[1] << 8; - num |= (uint32_t)buf[2] << 16; - num |= (uint32_t)buf[3] << 24; - return num; -} - - -static inline void -unaligned_write16be(uint8_t *buf, uint16_t num) -{ - buf[0] = (uint8_t)(num >> 8); - buf[1] = (uint8_t)num; - return; -} - - -static inline void -unaligned_write16le(uint8_t *buf, uint16_t num) -{ - buf[0] = (uint8_t)num; - buf[1] = (uint8_t)(num >> 8); - return; -} - - -static inline void -unaligned_write32be(uint8_t *buf, uint32_t num) -{ - buf[0] = (uint8_t)(num >> 24); - buf[1] = (uint8_t)(num >> 16); - buf[2] = (uint8_t)(num >> 8); - buf[3] = (uint8_t)num; - return; -} - - -static inline void -unaligned_write32le(uint8_t *buf, uint32_t num) -{ - buf[0] = (uint8_t)num; - buf[1] = (uint8_t)(num >> 8); - buf[2] = (uint8_t)(num >> 16); - buf[3] = (uint8_t)(num >> 24); - return; -} - -#endif - - -static inline uint32_t -bsr32(uint32_t n) -{ - // Check for ICC first, since it tends to define __GNUC__ too. -#if defined(__INTEL_COMPILER) - return _bit_scan_reverse(n); - -#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX - // GCC >= 3.4 has __builtin_clz(), which gives good results on - // multiple architectures. On x86, __builtin_clz() ^ 31U becomes - // either plain BSR (so the XOR gets optimized away) or LZCNT and - // XOR (if -march indicates that SSE4a instructions are supported). - return __builtin_clz(n) ^ 31U; - -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - uint32_t i; - __asm__("bsrl %1, %0" : "=r" (i) : "rm" (n)); - return i; - -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - // MSVC isn't supported by tuklib, but since this code exists, - // it doesn't hurt to have it here anyway. - uint32_t i; - _BitScanReverse(&i, n); - return i; - -#else - uint32_t i = 31; - - if ((n & UINT32_C(0xFFFF0000)) == 0) { - n <<= 16; - i = 15; - } - - if ((n & UINT32_C(0xFF000000)) == 0) { - n <<= 8; - i -= 8; - } - - if ((n & UINT32_C(0xF0000000)) == 0) { - n <<= 4; - i -= 4; - } - - if ((n & UINT32_C(0xC0000000)) == 0) { - n <<= 2; - i -= 2; - } - - if ((n & UINT32_C(0x80000000)) == 0) - --i; - - return i; -#endif -} - - -static inline uint32_t -clz32(uint32_t n) -{ -#if defined(__INTEL_COMPILER) - return _bit_scan_reverse(n) ^ 31U; - -#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX == UINT32_MAX - return __builtin_clz(n); - -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - uint32_t i; - __asm__("bsrl %1, %0\n\t" - "xorl $31, %0" - : "=r" (i) : "rm" (n)); - return i; - -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - uint32_t i; - _BitScanReverse(&i, n); - return i ^ 31U; - -#else - uint32_t i = 0; - - if ((n & UINT32_C(0xFFFF0000)) == 0) { - n <<= 16; - i = 16; - } - - if ((n & UINT32_C(0xFF000000)) == 0) { - n <<= 8; - i += 8; - } - - if ((n & UINT32_C(0xF0000000)) == 0) { - n <<= 4; - i += 4; - } - - if ((n & UINT32_C(0xC0000000)) == 0) { - n <<= 2; - i += 2; - } - - if ((n & UINT32_C(0x80000000)) == 0) - ++i; - - return i; -#endif -} - - -static inline uint32_t -ctz32(uint32_t n) -{ -#if defined(__INTEL_COMPILER) - return _bit_scan_forward(n); - -#elif TUKLIB_GNUC_REQ(3, 4) && UINT_MAX >= UINT32_MAX - return __builtin_ctz(n); - -#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) - uint32_t i; - __asm__("bsfl %1, %0" : "=r" (i) : "rm" (n)); - return i; - -#elif defined(_MSC_VER) && _MSC_VER >= 1400 - uint32_t i; - _BitScanForward(&i, n); - return i; - -#else - uint32_t i = 0; - - if ((n & UINT32_C(0x0000FFFF)) == 0) { - n >>= 16; - i = 16; - } - - if ((n & UINT32_C(0x000000FF)) == 0) { - n >>= 8; - i += 8; - } - - if ((n & UINT32_C(0x0000000F)) == 0) { - n >>= 4; - i += 4; - } - - if ((n & UINT32_C(0x00000003)) == 0) { - n >>= 2; - i += 2; - } - - if ((n & UINT32_C(0x00000001)) == 0) - ++i; - - return i; -#endif -} - -#define bsf32 ctz32 - -#endif diff --git a/game/client/third/minizip/lib/liblzma/config.h b/game/client/third/minizip/lib/liblzma/config.h deleted file mode 100755 index d7a294b1..00000000 --- a/game/client/third/minizip/lib/liblzma/config.h +++ /dev/null @@ -1,497 +0,0 @@ -/* config.h. Generated from config.h.in by configure. */ -/* config.h.in. Generated from configure.ac by autoheader. */ - -/* Define if building universal (internal helper macro) */ -/* #undef AC_APPLE_UNIVERSAL_BUILD */ - -/* How many MiB of RAM to assume if the real amount cannot be determined. */ -#define ASSUME_RAM 128 - -/* Define to 1 if translation of program messages to the user's native - language is requested. */ -/* #undef ENABLE_NLS */ - -/* Define to 1 if bswap_16 is available. */ -/* #undef HAVE_BSWAP_16 */ - -/* Define to 1 if bswap_32 is available. */ -/* #undef HAVE_BSWAP_32 */ - -/* Define to 1 if bswap_64 is available. */ -/* #undef HAVE_BSWAP_64 */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_BYTESWAP_H */ - -/* Define to 1 if the system has the type `CC_SHA256_CTX'. */ -/* #undef HAVE_CC_SHA256_CTX */ - -/* Define to 1 if you have the `CC_SHA256_Init' function. */ -/* #undef HAVE_CC_SHA256_INIT */ - -/* Define to 1 if you have the MacOS X function CFLocaleCopyCurrent in the - CoreFoundation framework. */ -/* #undef HAVE_CFLOCALECOPYCURRENT */ - -/* Define to 1 if you have the MacOS X function CFPreferencesCopyAppValue in - the CoreFoundation framework. */ -/* #undef HAVE_CFPREFERENCESCOPYAPPVALUE */ - -/* Define to 1 if crc32 integrity check is enabled. */ -/* #undef HAVE_CHECK_CRC32 */ - -/* Define to 1 if crc64 integrity check is enabled. */ -/* #undef HAVE_CHECK_CRC64 */ - -/* Define to 1 if sha256 integrity check is enabled. */ -/* #undef HAVE_CHECK_SHA256 */ - -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_COMMONCRYPTO_COMMONDIGEST_H */ - -/* Define if the GNU dcgettext() function is already present or preinstalled. - */ -/* #undef HAVE_DCGETTEXT */ - -/* Define to 1 if you have the declaration of `CLOCK_MONOTONIC', and to 0 if - you don't. */ -#define HAVE_DECL_CLOCK_MONOTONIC 1 - -/* Define to 1 if you have the declaration of `program_invocation_name', and - to 0 if you don't. */ -#define HAVE_DECL_PROGRAM_INVOCATION_NAME 0 - -/* Define to 1 if arm decoder is enabled. */ -/* #undef HAVE_DECODER_ARM */ - -/* Define to 1 if armthumb decoder is enabled. */ -/* #undef HAVE_DECODER_ARMTHUMB */ - -/* Define to 1 if delta decoder is enabled. */ -/* #undef HAVE_DECODER_DELTA */ - -/* Define to 1 if ia64 decoder is enabled. */ -/* #undef HAVE_DECODER_IA64 */ - -/* Define to 1 if lzma1 decoder is enabled. */ -#define HAVE_DECODER_LZMA1 1 - -/* Define to 1 if lzma2 decoder is enabled. */ -/* #undef HAVE_DECODER_LZMA2 */ - -/* Define to 1 if powerpc decoder is enabled. */ -/* #undef HAVE_DECODER_POWERPC */ - -/* Define to 1 if sparc decoder is enabled. */ -/* #undef HAVE_DECODER_SPARC */ - -/* Define to 1 if x86 decoder is enabled. */ -/* #undef HAVE_DECODER_X86 */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_DLFCN_H */ - -/* Define to 1 if arm encoder is enabled. */ -/* #undef HAVE_ENCODER_ARM */ - -/* Define to 1 if armthumb encoder is enabled. */ -/* #undef HAVE_ENCODER_ARMTHUMB */ - -/* Define to 1 if delta encoder is enabled. */ -/* #undef HAVE_ENCODER_DELTA */ - -/* Define to 1 if ia64 encoder is enabled. */ -/* #undef HAVE_ENCODER_IA64 */ - -/* Define to 1 if lzma1 encoder is enabled. */ -#define HAVE_ENCODER_LZMA1 1 - -/* Define to 1 if lzma2 encoder is enabled. */ -/* #undef HAVE_ENCODER_LZMA2 */ - -/* Define to 1 if powerpc encoder is enabled. */ -/* #undef HAVE_ENCODER_POWERPC */ - -/* Define to 1 if sparc encoder is enabled. */ -/* #undef HAVE_ENCODER_SPARC */ - -/* Define to 1 if x86 encoder is enabled. */ -/* #undef HAVE_ENCODER_X86 */ - -/* Define to 1 if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define to 1 if you have the `futimens' function. */ -/* #undef HAVE_FUTIMENS */ - -/* Define to 1 if you have the `futimes' function. */ -/* #undef HAVE_FUTIMES */ - -/* Define to 1 if you have the `futimesat' function. */ -/* #undef HAVE_FUTIMESAT */ - -/* Define to 1 if you have the header file. */ -#define HAVE_GETOPT_H 1 - -/* Define to 1 if you have the `getopt_long' function. */ -#define HAVE_GETOPT_LONG 1 - -/* Define if the GNU gettext() function is already present or preinstalled. */ -/* #undef HAVE_GETTEXT */ - -/* Define if you have the iconv() function and it works. */ -/* #undef HAVE_ICONV */ - -/* Define to 1 if you have the header file. */ -#define HAVE_IMMINTRIN_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_INTTYPES_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define to 1 if mbrtowc and mbstate_t are properly declared. */ -#define HAVE_MBRTOWC 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_MEMORY_H 1 - -/* Define to 1 to enable bt2 match finder. */ -#define HAVE_MF_BT2 1 - -/* Define to 1 to enable bt3 match finder. */ -#define HAVE_MF_BT3 1 - -/* Define to 1 to enable bt4 match finder. */ -#define HAVE_MF_BT4 1 - -/* Define to 1 to enable hc3 match finder. */ -#define HAVE_MF_HC3 1 - -/* Define to 1 to enable hc4 match finder. */ -#define HAVE_MF_HC4 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_MINIX_SHA2_H */ - -/* Define to 1 if getopt.h declares extern int optreset. */ -/* #undef HAVE_OPTRESET */ - -/* Define to 1 if you have the `pipe2' function. */ -/* #undef HAVE_PIPE2 */ - -/* Define to 1 if you have the `posix_fadvise' function. */ -/* #undef HAVE_POSIX_FADVISE */ - -/* Define to 1 if you have the `pthread_condattr_setclock' function. */ -/* #undef HAVE_PTHREAD_CONDATTR_SETCLOCK */ - -/* Have PTHREAD_PRIO_INHERIT. */ -/* #undef HAVE_PTHREAD_PRIO_INHERIT */ - -/* Define to 1 if you have the `SHA256Init' function. */ -/* #undef HAVE_SHA256INIT */ - -/* Define to 1 if the system has the type `SHA256_CTX'. */ -/* #undef HAVE_SHA256_CTX */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SHA256_H */ - -/* Define to 1 if you have the `SHA256_Init' function. */ -/* #undef HAVE_SHA256_INIT */ - -/* Define to 1 if the system has the type `SHA2_CTX'. */ -/* #undef HAVE_SHA2_CTX */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SHA2_H */ - -/* Define to 1 if optimizing for size. */ -/* #undef HAVE_SMALL */ - -/* Define to 1 if stdbool.h conforms to C99. */ -#define HAVE_STDBOOL_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDINT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_STDLIB_H 1 - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_STRINGS_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define to 1 if `st_atimensec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */ - -/* Define to 1 if `st_atimespec.tv_nsec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIMESPEC_TV_NSEC */ - -/* Define to 1 if `st_atim.st__tim.tv_nsec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIM_ST__TIM_TV_NSEC */ - -/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC */ - -/* Define to 1 if `st_uatime' is a member of `struct stat'. */ -/* #undef HAVE_STRUCT_STAT_ST_UATIME */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_BYTEORDER_H */ - -/* Define to 1 if you have the header file. */ -/* #undef HAVE_SYS_ENDIAN_H */ - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_PARAM_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_STAT_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TIME_H 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_SYS_TYPES_H 1 - -/* Define to 1 if the system has the type `uintptr_t'. */ -#define HAVE_UINTPTR_T 1 - -/* Define to 1 if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define to 1 if you have the `utime' function. */ -#define HAVE_UTIME 1 - -/* Define to 1 if you have the `utimes' function. */ -/* #undef HAVE_UTIMES */ - -/* Define to 1 or 0, depending whether the compiler supports simple visibility - declarations. */ -#define HAVE_VISIBILITY 1 - -/* Define to 1 if you have the `wcwidth' function. */ -/* #undef HAVE_WCWIDTH */ - -/* Define to 1 if the system has the type `_Bool'. */ -#define HAVE__BOOL 1 - -/* Define to 1 if _mm_movemask_epi8 is available. */ -#define HAVE__MM_MOVEMASK_EPI8 1 - -/* Define to the sub-directory where libtool stores uninstalled libraries. */ -#define LT_OBJDIR ".libs/" - -/* Define to 1 when using POSIX threads (pthreads). */ -/* #undef MYTHREAD_POSIX */ - -#ifdef _WIN64 -/* Define to 1 when using Windows Vista compatible threads. This uses features - that are not available on Windows XP. */ -# define MYTHREAD_VISTA 1 -#else -/* Define to 1 when using Windows 95 (and thus XP) compatible threads. This - avoids use of features that were added in Windows Vista. - This is used for 32-bit x86 builds for compatibility reasons since it - makes no measurable difference in performance compared to Vista threads. */ -# define MYTHREAD_WIN95 1 -#endif - -/* Define to 1 to disable debugging code. */ -#define NDEBUG 1 - -/* Name of package */ -#define PACKAGE "xz" - -/* Define to the address where bug reports for this package should be sent. */ -#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org" - -/* Define to the full name of this package. */ -#define PACKAGE_NAME "XZ Utils" - -/* Define to the full name and version of this package. */ -#define PACKAGE_STRING "XZ Utils 5.2.3" - -/* Define to the one symbol short name of this package. */ -#define PACKAGE_TARNAME "xz" - -/* Define to the home page for this package. */ -#define PACKAGE_URL "http://tukaani.org/xz/" - -/* Define to the version of this package. */ -#define PACKAGE_VERSION "5.2.3" - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -/* #undef PTHREAD_CREATE_JOINABLE */ - -/* The size of `size_t', as computed by sizeof. */ -#ifdef _WIN64 -# define SIZEOF_SIZE_T 8 -#else -# define SIZEOF_SIZE_T 4 -#endif - -/* Define to 1 if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define to 1 if the number of available CPU cores can be detected with - cpuset(2). */ -/* #undef TUKLIB_CPUCORES_CPUSET */ - -/* Define to 1 if the number of available CPU cores can be detected with - pstat_getdynamic(). */ -/* #undef TUKLIB_CPUCORES_PSTAT_GETDYNAMIC */ - -/* Define to 1 if the number of available CPU cores can be detected with - sysconf(_SC_NPROCESSORS_ONLN) or sysconf(_SC_NPROC_ONLN). */ -/* #undef TUKLIB_CPUCORES_SYSCONF */ - -/* Define to 1 if the number of available CPU cores can be detected with - sysctl(). */ -/* #undef TUKLIB_CPUCORES_SYSCTL */ - -/* Define to 1 if the system supports fast unaligned access to 16-bit and - 32-bit integers. */ -#define TUKLIB_FAST_UNALIGNED_ACCESS 1 - -/* Define to 1 if the amount of physical memory can be detected with - _system_configuration.physmem. */ -/* #undef TUKLIB_PHYSMEM_AIX */ - -/* Define to 1 if the amount of physical memory can be detected with - getinvent_r(). */ -/* #undef TUKLIB_PHYSMEM_GETINVENT_R */ - -/* Define to 1 if the amount of physical memory can be detected with - getsysinfo(). */ -/* #undef TUKLIB_PHYSMEM_GETSYSINFO */ - -/* Define to 1 if the amount of physical memory can be detected with - pstat_getstatic(). */ -/* #undef TUKLIB_PHYSMEM_PSTAT_GETSTATIC */ - -/* Define to 1 if the amount of physical memory can be detected with - sysconf(_SC_PAGESIZE) and sysconf(_SC_PHYS_PAGES). */ -/* #undef TUKLIB_PHYSMEM_SYSCONF */ - -/* Define to 1 if the amount of physical memory can be detected with sysctl(). - */ -/* #undef TUKLIB_PHYSMEM_SYSCTL */ - -/* Define to 1 if the amount of physical memory can be detected with Linux - sysinfo(). */ -/* #undef TUKLIB_PHYSMEM_SYSINFO */ - -/* Enable extensions on AIX 3, Interix. */ -#ifndef _ALL_SOURCE -# define _ALL_SOURCE 1 -#endif -/* Enable GNU extensions on systems that have them. */ -#ifndef _GNU_SOURCE -# define _GNU_SOURCE 1 -#endif -/* Enable threading extensions on Solaris. */ -#ifndef _POSIX_PTHREAD_SEMANTICS -# define _POSIX_PTHREAD_SEMANTICS 1 -#endif -/* Enable extensions on HP NonStop. */ -#ifndef _TANDEM_SOURCE -# define _TANDEM_SOURCE 1 -#endif -/* Enable general extensions on Solaris. */ -#ifndef __EXTENSIONS__ -# define __EXTENSIONS__ 1 -#endif - - -/* Version number of package */ -#define VERSION "5.2.3" - -/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most - significant byte first (like Motorola and SPARC, unlike Intel). */ -#if defined AC_APPLE_UNIVERSAL_BUILD -# if defined __BIG_ENDIAN__ -# define WORDS_BIGENDIAN 1 -# endif -#else -# ifndef WORDS_BIGENDIAN -/* # undef WORDS_BIGENDIAN */ -# endif -#endif - -/* Enable large inode numbers on Mac OS X 10.5. */ -#ifndef _DARWIN_USE_64_BIT_INODE -# define _DARWIN_USE_64_BIT_INODE 1 -#endif - -/* Number of bits in a file offset, on hosts where this is settable. */ -#define _FILE_OFFSET_BITS 64 - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define to 1 if on MINIX. */ -/* #undef _MINIX */ - -/* Define to 2 if the system does not provide POSIX.1 features except with - this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define to 1 if you need to in order for `stat' and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define for Solaris 2.5.1 so the uint32_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT32_T */ - -/* Define for Solaris 2.5.1 so the uint64_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT64_T */ - -/* Define for Solaris 2.5.1 so the uint8_t typedef from , - , or is not used. If the typedef were allowed, the - #define below would cause a syntax error. */ -/* #undef _UINT8_T */ - -/* Define to rpl_ if the getopt replacement functions and variables should be - used. */ -/* #undef __GETOPT_PREFIX */ - -/* Define to the type of a signed integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int32_t */ - -/* Define to the type of a signed integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef int64_t */ - -/* Define to the type of an unsigned integer type of width exactly 16 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint16_t */ - -/* Define to the type of an unsigned integer type of width exactly 32 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint32_t */ - -/* Define to the type of an unsigned integer type of width exactly 64 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint64_t */ - -/* Define to the type of an unsigned integer type of width exactly 8 bits if - such a type exists and the standard includes do not define it. */ -/* #undef uint8_t */ - -/* Define to the type of an unsigned integer type wide enough to hold a - pointer, if such a type exists, and if the system does not define it. */ -/* #undef uintptr_t */ diff --git a/game/client/third/minizip/lib/liblzma/lz/lz_decoder.c b/game/client/third/minizip/lib/liblzma/lz/lz_decoder.c deleted file mode 100755 index c7086440..00000000 --- a/game/client/third/minizip/lib/liblzma/lz/lz_decoder.c +++ /dev/null @@ -1,306 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lz_decoder.c -/// \brief LZ out window -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -// liblzma supports multiple LZ77-based filters. The LZ part is shared -// between these filters. The LZ code takes care of dictionary handling -// and passing the data between filters in the chain. The filter-specific -// part decodes from the input buffer to the dictionary. - - -#include "lz_decoder.h" - - -typedef struct { - /// Dictionary (history buffer) - lzma_dict dict; - - /// The actual LZ-based decoder e.g. LZMA - lzma_lz_decoder lz; - - /// Next filter in the chain, if any. Note that LZMA and LZMA2 are - /// only allowed as the last filter, but the long-range filter in - /// future can be in the middle of the chain. - lzma_next_coder next; - - /// True if the next filter in the chain has returned LZMA_STREAM_END. - bool next_finished; - - /// True if the LZ decoder (e.g. LZMA) has detected end of payload - /// marker. This may become true before next_finished becomes true. - bool this_finished; - - /// Temporary buffer needed when the LZ-based filter is not the last - /// filter in the chain. The output of the next filter is first - /// decoded into buffer[], which is then used as input for the actual - /// LZ-based decoder. - struct { - size_t pos; - size_t size; - uint8_t buffer[LZMA_BUFFER_SIZE]; - } temp; -} lzma_coder; - - -static void -lz_decoder_reset(lzma_coder *coder) -{ - coder->dict.pos = 0; - coder->dict.full = 0; - coder->dict.buf[coder->dict.size - 1] = '\0'; - coder->dict.need_reset = false; - return; -} - - -static lzma_ret -decode_buffer(lzma_coder *coder, - const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size) -{ - while (true) { - // Wrap the dictionary if needed. - if (coder->dict.pos == coder->dict.size) - coder->dict.pos = 0; - - // Store the current dictionary position. It is needed to know - // where to start copying to the out[] buffer. - const size_t dict_start = coder->dict.pos; - - // Calculate how much we allow coder->lz.code() to decode. - // It must not decode past the end of the dictionary - // buffer, and we don't want it to decode more than is - // actually needed to fill the out[] buffer. - coder->dict.limit = coder->dict.pos - + my_min(out_size - *out_pos, - coder->dict.size - coder->dict.pos); - - // Call the coder->lz.code() to do the actual decoding. - const lzma_ret ret = coder->lz.code( - coder->lz.coder, &coder->dict, - in, in_pos, in_size); - - // Copy the decoded data from the dictionary to the out[] - // buffer. - const size_t copy_size = coder->dict.pos - dict_start; - assert(copy_size <= out_size - *out_pos); - memcpy(out + *out_pos, coder->dict.buf + dict_start, - copy_size); - *out_pos += copy_size; - - // Reset the dictionary if so requested by coder->lz.code(). - if (coder->dict.need_reset) { - lz_decoder_reset(coder); - - // Since we reset dictionary, we don't check if - // dictionary became full. - if (ret != LZMA_OK || *out_pos == out_size) - return ret; - } else { - // Return if everything got decoded or an error - // occurred, or if there's no more data to decode. - // - // Note that detecting if there's something to decode - // is done by looking if dictionary become full - // instead of looking if *in_pos == in_size. This - // is because it is possible that all the input was - // consumed already but some data is pending to be - // written to the dictionary. - if (ret != LZMA_OK || *out_pos == out_size - || coder->dict.pos < coder->dict.size) - return ret; - } - } -} - - -static lzma_ret -lz_decode(void *coder_ptr, - const lzma_allocator *allocator lzma_attribute((__unused__)), - const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size, - lzma_action action) -{ - lzma_coder *coder = coder_ptr; - - if (coder->next.code == NULL) - return decode_buffer(coder, in, in_pos, in_size, - out, out_pos, out_size); - - // We aren't the last coder in the chain, we need to decode - // our input to a temporary buffer. - while (*out_pos < out_size) { - // Fill the temporary buffer if it is empty. - if (!coder->next_finished - && coder->temp.pos == coder->temp.size) { - coder->temp.pos = 0; - coder->temp.size = 0; - - const lzma_ret ret = coder->next.code( - coder->next.coder, - allocator, in, in_pos, in_size, - coder->temp.buffer, &coder->temp.size, - LZMA_BUFFER_SIZE, action); - - if (ret == LZMA_STREAM_END) - coder->next_finished = true; - else if (ret != LZMA_OK || coder->temp.size == 0) - return ret; - } - - if (coder->this_finished) { - if (coder->temp.size != 0) - return LZMA_DATA_ERROR; - - if (coder->next_finished) - return LZMA_STREAM_END; - - return LZMA_OK; - } - - const lzma_ret ret = decode_buffer(coder, coder->temp.buffer, - &coder->temp.pos, coder->temp.size, - out, out_pos, out_size); - - if (ret == LZMA_STREAM_END) - coder->this_finished = true; - else if (ret != LZMA_OK) - return ret; - else if (coder->next_finished && *out_pos < out_size) - return LZMA_DATA_ERROR; - } - - return LZMA_OK; -} - - -static void -lz_decoder_end(void *coder_ptr, const lzma_allocator *allocator) -{ - lzma_coder *coder = coder_ptr; - - lzma_next_end(&coder->next, allocator); - lzma_free(coder->dict.buf, allocator); - - if (coder->lz.end != NULL) - coder->lz.end(coder->lz.coder, allocator); - else - lzma_free(coder->lz.coder, allocator); - - lzma_free(coder, allocator); - return; -} - - -extern lzma_ret -lzma_lz_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters, - lzma_ret (*lz_init)(lzma_lz_decoder *lz, - const lzma_allocator *allocator, const void *options, - lzma_lz_options *lz_options)) -{ - // Allocate the base structure if it isn't already allocated. - lzma_coder *coder = next->coder; - if (coder == NULL) { - coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (coder == NULL) - return LZMA_MEM_ERROR; - - next->coder = coder; - next->code = &lz_decode; - next->end = &lz_decoder_end; - - coder->dict.buf = NULL; - coder->dict.size = 0; - coder->lz = LZMA_LZ_DECODER_INIT; - coder->next = LZMA_NEXT_CODER_INIT; - } - - // Allocate and initialize the LZ-based decoder. It will also give - // us the dictionary size. - lzma_lz_options lz_options; - return_if_error(lz_init(&coder->lz, allocator, - filters[0].options, &lz_options)); - - // If the dictionary size is very small, increase it to 4096 bytes. - // This is to prevent constant wrapping of the dictionary, which - // would slow things down. The downside is that since we don't check - // separately for the real dictionary size, we may happily accept - // corrupt files. - if (lz_options.dict_size < 4096) - lz_options.dict_size = 4096; - - // Make dictionary size a multipe of 16. Some LZ-based decoders like - // LZMA use the lowest bits lzma_dict.pos to know the alignment of the - // data. Aligned buffer is also good when memcpying from the - // dictionary to the output buffer, since applications are - // recommended to give aligned buffers to liblzma. - // - // Avoid integer overflow. - if (lz_options.dict_size > SIZE_MAX - 15) - return LZMA_MEM_ERROR; - - lz_options.dict_size = (lz_options.dict_size + 15) & ~((size_t)(15)); - - // Allocate and initialize the dictionary. - if (coder->dict.size != lz_options.dict_size) { - lzma_free(coder->dict.buf, allocator); - coder->dict.buf - = lzma_alloc(lz_options.dict_size, allocator); - if (coder->dict.buf == NULL) - return LZMA_MEM_ERROR; - - coder->dict.size = lz_options.dict_size; - } - - lz_decoder_reset(next->coder); - - // Use the preset dictionary if it was given to us. - if (lz_options.preset_dict != NULL - && lz_options.preset_dict_size > 0) { - // If the preset dictionary is bigger than the actual - // dictionary, copy only the tail. - const size_t copy_size = my_min(lz_options.preset_dict_size, - lz_options.dict_size); - const size_t offset = lz_options.preset_dict_size - copy_size; - memcpy(coder->dict.buf, lz_options.preset_dict + offset, - copy_size); - coder->dict.pos = copy_size; - coder->dict.full = copy_size; - } - - // Miscellaneous initializations - coder->next_finished = false; - coder->this_finished = false; - coder->temp.pos = 0; - coder->temp.size = 0; - - // Initialize the next filter in the chain, if any. - return lzma_next_filter_init(&coder->next, allocator, filters + 1); -} - - -extern uint64_t -lzma_lz_decoder_memusage(size_t dictionary_size) -{ - return sizeof(lzma_coder) + (uint64_t)(dictionary_size); -} - - -extern void -lzma_lz_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size) -{ - lzma_coder *coder = coder_ptr; - coder->lz.set_uncompressed(coder->lz.coder, uncompressed_size); -} diff --git a/game/client/third/minizip/lib/liblzma/lz/lz_decoder.h b/game/client/third/minizip/lib/liblzma/lz/lz_decoder.h deleted file mode 100755 index 754ccf37..00000000 --- a/game/client/third/minizip/lib/liblzma/lz/lz_decoder.h +++ /dev/null @@ -1,234 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lz_decoder.h -/// \brief LZ out window -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZ_DECODER_H -#define LZMA_LZ_DECODER_H - -#include "common.h" - - -typedef struct { - /// Pointer to the dictionary buffer. It can be an allocated buffer - /// internal to liblzma, or it can a be a buffer given by the - /// application when in single-call mode (not implemented yet). - uint8_t *buf; - - /// Write position in dictionary. The next byte will be written to - /// buf[pos]. - size_t pos; - - /// Indicates how full the dictionary is. This is used by - /// dict_is_distance_valid() to detect corrupt files that would - /// read beyond the beginning of the dictionary. - size_t full; - - /// Write limit - size_t limit; - - /// Size of the dictionary - size_t size; - - /// True when dictionary should be reset before decoding more data. - bool need_reset; - -} lzma_dict; - - -typedef struct { - size_t dict_size; - const uint8_t *preset_dict; - size_t preset_dict_size; -} lzma_lz_options; - - -typedef struct { - /// Data specific to the LZ-based decoder - void *coder; - - /// Function to decode from in[] to *dict - lzma_ret (*code)(void *coder, - lzma_dict *restrict dict, const uint8_t *restrict in, - size_t *restrict in_pos, size_t in_size); - - void (*reset)(void *coder, const void *options); - - /// Set the uncompressed size - void (*set_uncompressed)(void *coder, lzma_vli uncompressed_size); - - /// Free allocated resources - void (*end)(void *coder, const lzma_allocator *allocator); - -} lzma_lz_decoder; - - -#define LZMA_LZ_DECODER_INIT \ - (lzma_lz_decoder){ \ - .coder = NULL, \ - .code = NULL, \ - .reset = NULL, \ - .set_uncompressed = NULL, \ - .end = NULL, \ - } - - -extern lzma_ret lzma_lz_decoder_init(lzma_next_coder *next, - const lzma_allocator *allocator, - const lzma_filter_info *filters, - lzma_ret (*lz_init)(lzma_lz_decoder *lz, - const lzma_allocator *allocator, const void *options, - lzma_lz_options *lz_options)); - -extern uint64_t lzma_lz_decoder_memusage(size_t dictionary_size); - -extern void lzma_lz_decoder_uncompressed( - void *coder, lzma_vli uncompressed_size); - - -////////////////////// -// Inline functions // -////////////////////// - -/// Get a byte from the history buffer. -static inline uint8_t -dict_get(const lzma_dict *const dict, const uint32_t distance) -{ - return dict->buf[dict->pos - distance - 1 - + (distance < dict->pos ? 0 : dict->size)]; -} - - -/// Test if dictionary is empty. -static inline bool -dict_is_empty(const lzma_dict *const dict) -{ - return dict->full == 0; -} - - -/// Validate the match distance -static inline bool -dict_is_distance_valid(const lzma_dict *const dict, const size_t distance) -{ - return dict->full > distance; -} - - -/// Repeat *len bytes at distance. -static inline bool -dict_repeat(lzma_dict *dict, uint32_t distance, uint32_t *len) -{ - // Don't write past the end of the dictionary. - const size_t dict_avail = dict->limit - dict->pos; - uint32_t left = my_min(dict_avail, *len); - *len -= left; - - // Repeat a block of data from the history. Because memcpy() is faster - // than copying byte by byte in a loop, the copying process gets split - // into three cases. - if (distance < left) { - // Source and target areas overlap, thus we can't use - // memcpy() nor even memmove() safely. - do { - dict->buf[dict->pos] = dict_get(dict, distance); - ++dict->pos; - } while (--left > 0); - - } else if (distance < dict->pos) { - // The easiest and fastest case - memcpy(dict->buf + dict->pos, - dict->buf + dict->pos - distance - 1, - left); - dict->pos += left; - - } else { - // The bigger the dictionary, the more rare this - // case occurs. We need to "wrap" the dict, thus - // we might need two memcpy() to copy all the data. - assert(dict->full == dict->size); - const uint32_t copy_pos - = dict->pos - distance - 1 + dict->size; - uint32_t copy_size = dict->size - copy_pos; - - if (copy_size < left) { - memmove(dict->buf + dict->pos, dict->buf + copy_pos, - copy_size); - dict->pos += copy_size; - copy_size = left - copy_size; - memcpy(dict->buf + dict->pos, dict->buf, copy_size); - dict->pos += copy_size; - } else { - memmove(dict->buf + dict->pos, dict->buf + copy_pos, - left); - dict->pos += left; - } - } - - // Update how full the dictionary is. - if (dict->full < dict->pos) - dict->full = dict->pos; - - return unlikely(*len != 0); -} - - -/// Puts one byte into the dictionary. Returns true if the dictionary was -/// already full and the byte couldn't be added. -static inline bool -dict_put(lzma_dict *dict, uint8_t byte) -{ - if (unlikely(dict->pos == dict->limit)) - return true; - - dict->buf[dict->pos++] = byte; - - if (dict->pos > dict->full) - dict->full = dict->pos; - - return false; -} - - -/// Copies arbitrary amount of data into the dictionary. -static inline void -dict_write(lzma_dict *restrict dict, const uint8_t *restrict in, - size_t *restrict in_pos, size_t in_size, - size_t *restrict left) -{ - // NOTE: If we are being given more data than the size of the - // dictionary, it could be possible to optimize the LZ decoder - // so that not everything needs to go through the dictionary. - // This shouldn't be very common thing in practice though, and - // the slowdown of one extra memcpy() isn't bad compared to how - // much time it would have taken if the data were compressed. - - if (in_size - *in_pos > *left) - in_size = *in_pos + *left; - - *left -= lzma_bufcpy(in, in_pos, in_size, - dict->buf, &dict->pos, dict->limit); - - if (dict->pos > dict->full) - dict->full = dict->pos; - - return; -} - - -static inline void -dict_reset(lzma_dict *dict) -{ - dict->need_reset = true; - return; -} - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lz/lz_encoder.c b/game/client/third/minizip/lib/liblzma/lz/lz_encoder.c deleted file mode 100755 index 9a74b7c4..00000000 --- a/game/client/third/minizip/lib/liblzma/lz/lz_encoder.c +++ /dev/null @@ -1,616 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lz_encoder.c -/// \brief LZ in window -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "lz_encoder.h" -#include "lz_encoder_hash.h" - -// See lz_encoder_hash.h. This is a bit hackish but avoids making -// endianness a conditional in makefiles. -#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL) -# include "lz_encoder_hash_table.h" -#endif - -#include "memcmplen.h" - - -typedef struct { - /// LZ-based encoder e.g. LZMA - lzma_lz_encoder lz; - - /// History buffer and match finder - lzma_mf mf; - - /// Next coder in the chain - lzma_next_coder next; -} lzma_coder; - - -/// \brief Moves the data in the input window to free space for new data -/// -/// mf->buffer is a sliding input window, which keeps mf->keep_size_before -/// bytes of input history available all the time. Now and then we need to -/// "slide" the buffer to make space for the new data to the end of the -/// buffer. At the same time, data older than keep_size_before is dropped. -/// -static void -move_window(lzma_mf *mf) -{ - // Align the move to a multiple of 16 bytes. Some LZ-based encoders - // like LZMA use the lowest bits of mf->read_pos to know the - // alignment of the uncompressed data. We also get better speed - // for memmove() with aligned buffers. - assert(mf->read_pos > mf->keep_size_before); - const uint32_t move_offset - = (mf->read_pos - mf->keep_size_before) & ~UINT32_C(15); - - assert(mf->write_pos > move_offset); - const size_t move_size = mf->write_pos - move_offset; - - assert(move_offset + move_size <= mf->size); - - memmove(mf->buffer, mf->buffer + move_offset, move_size); - - mf->offset += move_offset; - mf->read_pos -= move_offset; - mf->read_limit -= move_offset; - mf->write_pos -= move_offset; - - return; -} - - -/// \brief Tries to fill the input window (mf->buffer) -/// -/// If we are the last encoder in the chain, our input data is in in[]. -/// Otherwise we call the next filter in the chain to process in[] and -/// write its output to mf->buffer. -/// -/// This function must not be called once it has returned LZMA_STREAM_END. -/// -static lzma_ret -fill_window(lzma_coder *coder, const lzma_allocator *allocator, - const uint8_t *in, size_t *in_pos, size_t in_size, - lzma_action action) -{ - assert(coder->mf.read_pos <= coder->mf.write_pos); - - // Move the sliding window if needed. - if (coder->mf.read_pos >= coder->mf.size - coder->mf.keep_size_after) - move_window(&coder->mf); - - // Maybe this is ugly, but lzma_mf uses uint32_t for most things - // (which I find cleanest), but we need size_t here when filling - // the history window. - size_t write_pos = coder->mf.write_pos; - lzma_ret ret; - if (coder->next.code == NULL) { - // Not using a filter, simply memcpy() as much as possible. - lzma_bufcpy(in, in_pos, in_size, coder->mf.buffer, - &write_pos, coder->mf.size); - - ret = action != LZMA_RUN && *in_pos == in_size - ? LZMA_STREAM_END : LZMA_OK; - - } else { - ret = coder->next.code(coder->next.coder, allocator, - in, in_pos, in_size, - coder->mf.buffer, &write_pos, - coder->mf.size, action); - } - - coder->mf.write_pos = write_pos; - - // Silence Valgrind. lzma_memcmplen() can read extra bytes - // and Valgrind will give warnings if those bytes are uninitialized - // because Valgrind cannot see that the values of the uninitialized - // bytes are eventually ignored. - memzero(coder->mf.buffer + write_pos, LZMA_MEMCMPLEN_EXTRA); - - // If end of stream has been reached or flushing completed, we allow - // the encoder to process all the input (that is, read_pos is allowed - // to reach write_pos). Otherwise we keep keep_size_after bytes - // available as prebuffer. - if (ret == LZMA_STREAM_END) { - assert(*in_pos == in_size); - ret = LZMA_OK; - coder->mf.action = action; - coder->mf.read_limit = coder->mf.write_pos; - - } else if (coder->mf.write_pos > coder->mf.keep_size_after) { - // This needs to be done conditionally, because if we got - // only little new input, there may be too little input - // to do any encoding yet. - coder->mf.read_limit = coder->mf.write_pos - - coder->mf.keep_size_after; - } - - // Restart the match finder after finished LZMA_SYNC_FLUSH. - if (coder->mf.pending > 0 - && coder->mf.read_pos < coder->mf.read_limit) { - // Match finder may update coder->pending and expects it to - // start from zero, so use a temporary variable. - const uint32_t pending = coder->mf.pending; - coder->mf.pending = 0; - - // Rewind read_pos so that the match finder can hash - // the pending bytes. - assert(coder->mf.read_pos >= pending); - coder->mf.read_pos -= pending; - - // Call the skip function directly instead of using - // mf_skip(), since we don't want to touch mf->read_ahead. - coder->mf.skip(&coder->mf, pending); - } - - return ret; -} - - -static lzma_ret -lz_encode(void *coder_ptr, const lzma_allocator *allocator, - const uint8_t *restrict in, size_t *restrict in_pos, - size_t in_size, - uint8_t *restrict out, size_t *restrict out_pos, - size_t out_size, lzma_action action) -{ - lzma_coder *coder = coder_ptr; - - while (*out_pos < out_size - && (*in_pos < in_size || action != LZMA_RUN)) { - // Read more data to coder->mf.buffer if needed. - if (coder->mf.action == LZMA_RUN && coder->mf.read_pos - >= coder->mf.read_limit) - return_if_error(fill_window(coder, allocator, - in, in_pos, in_size, action)); - - // Encode - const lzma_ret ret = coder->lz.code(coder->lz.coder, - &coder->mf, out, out_pos, out_size); - if (ret != LZMA_OK) { - // Setting this to LZMA_RUN for cases when we are - // flushing. It doesn't matter when finishing or if - // an error occurred. - coder->mf.action = LZMA_RUN; - return ret; - } - } - - return LZMA_OK; -} - - -static bool -lz_encoder_prepare(lzma_mf *mf, const lzma_allocator *allocator, - const lzma_lz_options *lz_options) -{ - // For now, the dictionary size is limited to 1.5 GiB. This may grow - // in the future if needed, but it needs a little more work than just - // changing this check. - if (lz_options->dict_size < LZMA_DICT_SIZE_MIN - || lz_options->dict_size - > (UINT32_C(1) << 30) + (UINT32_C(1) << 29) - || lz_options->nice_len > lz_options->match_len_max) - return true; - - mf->keep_size_before = lz_options->before_size + lz_options->dict_size; - - mf->keep_size_after = lz_options->after_size - + lz_options->match_len_max; - - // To avoid constant memmove()s, allocate some extra space. Since - // memmove()s become more expensive when the size of the buffer - // increases, we reserve more space when a large dictionary is - // used to make the memmove() calls rarer. - // - // This works with dictionaries up to about 3 GiB. If bigger - // dictionary is wanted, some extra work is needed: - // - Several variables in lzma_mf have to be changed from uint32_t - // to size_t. - // - Memory usage calculation needs something too, e.g. use uint64_t - // for mf->size. - uint32_t reserve = lz_options->dict_size / 2; - if (reserve > (UINT32_C(1) << 30)) - reserve /= 2; - - reserve += (lz_options->before_size + lz_options->match_len_max - + lz_options->after_size) / 2 + (UINT32_C(1) << 19); - - const uint32_t old_size = mf->size; - mf->size = mf->keep_size_before + reserve + mf->keep_size_after; - - // Deallocate the old history buffer if it exists but has different - // size than what is needed now. - if (mf->buffer != NULL && old_size != mf->size) { - lzma_free(mf->buffer, allocator); - mf->buffer = NULL; - } - - // Match finder options - mf->match_len_max = lz_options->match_len_max; - mf->nice_len = lz_options->nice_len; - - // cyclic_size has to stay smaller than 2 Gi. Note that this doesn't - // mean limiting dictionary size to less than 2 GiB. With a match - // finder that uses multibyte resolution (hashes start at e.g. every - // fourth byte), cyclic_size would stay below 2 Gi even when - // dictionary size is greater than 2 GiB. - // - // It would be possible to allow cyclic_size >= 2 Gi, but then we - // would need to be careful to use 64-bit types in various places - // (size_t could do since we would need bigger than 32-bit address - // space anyway). It would also require either zeroing a multigigabyte - // buffer at initialization (waste of time and RAM) or allow - // normalization in lz_encoder_mf.c to access uninitialized - // memory to keep the code simpler. The current way is simple and - // still allows pretty big dictionaries, so I don't expect these - // limits to change. - mf->cyclic_size = lz_options->dict_size + 1; - - // Validate the match finder ID and setup the function pointers. - switch (lz_options->match_finder) { -#ifdef HAVE_MF_HC3 - case LZMA_MF_HC3: - mf->find = &lzma_mf_hc3_find; - mf->skip = &lzma_mf_hc3_skip; - break; -#endif -#ifdef HAVE_MF_HC4 - case LZMA_MF_HC4: - mf->find = &lzma_mf_hc4_find; - mf->skip = &lzma_mf_hc4_skip; - break; -#endif -#ifdef HAVE_MF_BT2 - case LZMA_MF_BT2: - mf->find = &lzma_mf_bt2_find; - mf->skip = &lzma_mf_bt2_skip; - break; -#endif -#ifdef HAVE_MF_BT3 - case LZMA_MF_BT3: - mf->find = &lzma_mf_bt3_find; - mf->skip = &lzma_mf_bt3_skip; - break; -#endif -#ifdef HAVE_MF_BT4 - case LZMA_MF_BT4: - mf->find = &lzma_mf_bt4_find; - mf->skip = &lzma_mf_bt4_skip; - break; -#endif - - default: - return true; - } - - // Calculate the sizes of mf->hash and mf->son and check that - // nice_len is big enough for the selected match finder. - const uint32_t hash_bytes = lz_options->match_finder & 0x0F; - if (hash_bytes > mf->nice_len) - return true; - - const bool is_bt = (lz_options->match_finder & 0x10) != 0; - uint32_t hs; - - if (hash_bytes == 2) { - hs = 0xFFFF; - } else { - // Round dictionary size up to the next 2^n - 1 so it can - // be used as a hash mask. - hs = lz_options->dict_size - 1; - hs |= hs >> 1; - hs |= hs >> 2; - hs |= hs >> 4; - hs |= hs >> 8; - hs >>= 1; - hs |= 0xFFFF; - - if (hs > (UINT32_C(1) << 24)) { - if (hash_bytes == 3) - hs = (UINT32_C(1) << 24) - 1; - else - hs >>= 1; - } - } - - mf->hash_mask = hs; - - ++hs; - if (hash_bytes > 2) - hs += HASH_2_SIZE; - if (hash_bytes > 3) - hs += HASH_3_SIZE; -/* - No match finder uses this at the moment. - if (mf->hash_bytes > 4) - hs += HASH_4_SIZE; -*/ - - const uint32_t old_hash_count = mf->hash_count; - const uint32_t old_sons_count = mf->sons_count; - mf->hash_count = hs; - mf->sons_count = mf->cyclic_size; - if (is_bt) - mf->sons_count *= 2; - - // Deallocate the old hash array if it exists and has different size - // than what is needed now. - if (old_hash_count != mf->hash_count - || old_sons_count != mf->sons_count) { - lzma_free(mf->hash, allocator); - mf->hash = NULL; - - lzma_free(mf->son, allocator); - mf->son = NULL; - } - - // Maximum number of match finder cycles - mf->depth = lz_options->depth; - if (mf->depth == 0) { - if (is_bt) - mf->depth = 16 + mf->nice_len / 2; - else - mf->depth = 4 + mf->nice_len / 4; - } - - return false; -} - - -static bool -lz_encoder_init(lzma_mf *mf, const lzma_allocator *allocator, - const lzma_lz_options *lz_options) -{ - // Allocate the history buffer. - if (mf->buffer == NULL) { - // lzma_memcmplen() is used for the dictionary buffer - // so we need to allocate a few extra bytes to prevent - // it from reading past the end of the buffer. - mf->buffer = lzma_alloc(mf->size + LZMA_MEMCMPLEN_EXTRA, - allocator); - if (mf->buffer == NULL) - return true; - - // Keep Valgrind happy with lzma_memcmplen() and initialize - // the extra bytes whose value may get read but which will - // effectively get ignored. - memzero(mf->buffer + mf->size, LZMA_MEMCMPLEN_EXTRA); - } - - // Use cyclic_size as initial mf->offset. This allows - // avoiding a few branches in the match finders. The downside is - // that match finder needs to be normalized more often, which may - // hurt performance with huge dictionaries. - mf->offset = mf->cyclic_size; - mf->read_pos = 0; - mf->read_ahead = 0; - mf->read_limit = 0; - mf->write_pos = 0; - mf->pending = 0; - -#if UINT32_MAX >= SIZE_MAX / 4 - // Check for integer overflow. (Huge dictionaries are not - // possible on 32-bit CPU.) - if (mf->hash_count > SIZE_MAX / sizeof(uint32_t) - || mf->sons_count > SIZE_MAX / sizeof(uint32_t)) - return true; -#endif - - // Allocate and initialize the hash table. Since EMPTY_HASH_VALUE - // is zero, we can use lzma_alloc_zero() or memzero() for mf->hash. - // - // We don't need to initialize mf->son, but not doing that may - // make Valgrind complain in normalization (see normalize() in - // lz_encoder_mf.c). Skipping the initialization is *very* good - // when big dictionary is used but only small amount of data gets - // actually compressed: most of the mf->son won't get actually - // allocated by the kernel, so we avoid wasting RAM and improve - // initialization speed a lot. - if (mf->hash == NULL) { - mf->hash = lzma_alloc_zero(mf->hash_count * sizeof(uint32_t), - allocator); - mf->son = lzma_alloc(mf->sons_count * sizeof(uint32_t), - allocator); - - if (mf->hash == NULL || mf->son == NULL) { - lzma_free(mf->hash, allocator); - mf->hash = NULL; - - lzma_free(mf->son, allocator); - mf->son = NULL; - - return true; - } - } else { -/* - for (uint32_t i = 0; i < mf->hash_count; ++i) - mf->hash[i] = EMPTY_HASH_VALUE; -*/ - memzero(mf->hash, mf->hash_count * sizeof(uint32_t)); - } - - mf->cyclic_pos = 0; - - // Handle preset dictionary. - if (lz_options->preset_dict != NULL - && lz_options->preset_dict_size > 0) { - // If the preset dictionary is bigger than the actual - // dictionary, use only the tail. - mf->write_pos = my_min(lz_options->preset_dict_size, mf->size); - memcpy(mf->buffer, lz_options->preset_dict - + lz_options->preset_dict_size - mf->write_pos, - mf->write_pos); - mf->action = LZMA_SYNC_FLUSH; - mf->skip(mf, mf->write_pos); - } - - mf->action = LZMA_RUN; - - return false; -} - - -extern uint64_t -lzma_lz_encoder_memusage(const lzma_lz_options *lz_options) -{ - // Old buffers must not exist when calling lz_encoder_prepare(). - lzma_mf mf = { - .buffer = NULL, - .hash = NULL, - .son = NULL, - .hash_count = 0, - .sons_count = 0, - }; - - // Setup the size information into mf. - if (lz_encoder_prepare(&mf, NULL, lz_options)) - return UINT64_MAX; - - // Calculate the memory usage. - return ((uint64_t)(mf.hash_count) + mf.sons_count) * sizeof(uint32_t) - + mf.size + sizeof(lzma_coder); -} - - -static void -lz_encoder_end(void *coder_ptr, const lzma_allocator *allocator) -{ - lzma_coder *coder = coder_ptr; - - lzma_next_end(&coder->next, allocator); - - lzma_free(coder->mf.son, allocator); - lzma_free(coder->mf.hash, allocator); - lzma_free(coder->mf.buffer, allocator); - - if (coder->lz.end != NULL) - coder->lz.end(coder->lz.coder, allocator); - else - lzma_free(coder->lz.coder, allocator); - - lzma_free(coder, allocator); - return; -} - - -static lzma_ret -lz_encoder_update(void *coder_ptr, const lzma_allocator *allocator, - const lzma_filter *filters_null lzma_attribute((__unused__)), - const lzma_filter *reversed_filters) -{ - lzma_coder *coder = coder_ptr; - - if (coder->lz.options_update == NULL) - return LZMA_PROG_ERROR; - - return_if_error(coder->lz.options_update( - coder->lz.coder, reversed_filters)); - - return lzma_next_filter_update( - &coder->next, allocator, reversed_filters + 1); -} - - -extern lzma_ret -lzma_lz_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters, - lzma_ret (*lz_init)(lzma_lz_encoder *lz, - const lzma_allocator *allocator, const void *options, - lzma_lz_options *lz_options)) -{ -#ifdef HAVE_SMALL - // We need that the CRC32 table has been initialized. - lzma_crc32_init(); -#endif - - // Allocate and initialize the base data structure. - lzma_coder *coder = next->coder; - if (coder == NULL) { - coder = lzma_alloc(sizeof(lzma_coder), allocator); - if (coder == NULL) - return LZMA_MEM_ERROR; - - next->coder = coder; - next->code = &lz_encode; - next->end = &lz_encoder_end; - next->update = &lz_encoder_update; - - coder->lz.coder = NULL; - coder->lz.code = NULL; - coder->lz.end = NULL; - - // mf.size is initialized to silence Valgrind - // when used on optimized binaries (GCC may reorder - // code in a way that Valgrind gets unhappy). - coder->mf.buffer = NULL; - coder->mf.size = 0; - coder->mf.hash = NULL; - coder->mf.son = NULL; - coder->mf.hash_count = 0; - coder->mf.sons_count = 0; - - coder->next = LZMA_NEXT_CODER_INIT; - } - - // Initialize the LZ-based encoder. - lzma_lz_options lz_options; - return_if_error(lz_init(&coder->lz, allocator, - filters[0].options, &lz_options)); - - // Setup the size information into coder->mf and deallocate - // old buffers if they have wrong size. - if (lz_encoder_prepare(&coder->mf, allocator, &lz_options)) - return LZMA_OPTIONS_ERROR; - - // Allocate new buffers if needed, and do the rest of - // the initialization. - if (lz_encoder_init(&coder->mf, allocator, &lz_options)) - return LZMA_MEM_ERROR; - - // Initialize the next filter in the chain, if any. - return lzma_next_filter_init(&coder->next, allocator, filters + 1); -} - - -extern LZMA_API(lzma_bool) -lzma_mf_is_supported(lzma_match_finder mf) -{ - bool ret = false; - -#ifdef HAVE_MF_HC3 - if (mf == LZMA_MF_HC3) - ret = true; -#endif - -#ifdef HAVE_MF_HC4 - if (mf == LZMA_MF_HC4) - ret = true; -#endif - -#ifdef HAVE_MF_BT2 - if (mf == LZMA_MF_BT2) - ret = true; -#endif - -#ifdef HAVE_MF_BT3 - if (mf == LZMA_MF_BT3) - ret = true; -#endif - -#ifdef HAVE_MF_BT4 - if (mf == LZMA_MF_BT4) - ret = true; -#endif - - return ret; -} diff --git a/game/client/third/minizip/lib/liblzma/lz/lz_encoder.h b/game/client/third/minizip/lib/liblzma/lz/lz_encoder.h deleted file mode 100755 index 426dcd8a..00000000 --- a/game/client/third/minizip/lib/liblzma/lz/lz_encoder.h +++ /dev/null @@ -1,327 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lz_encoder.h -/// \brief LZ in window and match finder API -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZ_ENCODER_H -#define LZMA_LZ_ENCODER_H - -#include "common.h" - - -/// A table of these is used by the LZ-based encoder to hold -/// the length-distance pairs found by the match finder. -typedef struct { - uint32_t len; - uint32_t dist; -} lzma_match; - - -typedef struct lzma_mf_s lzma_mf; -struct lzma_mf_s { - /////////////// - // In Window // - /////////////// - - /// Pointer to buffer with data to be compressed - uint8_t *buffer; - - /// Total size of the allocated buffer (that is, including all - /// the extra space) - uint32_t size; - - /// Number of bytes that must be kept available in our input history. - /// That is, once keep_size_before bytes have been processed, - /// buffer[read_pos - keep_size_before] is the oldest byte that - /// must be available for reading. - uint32_t keep_size_before; - - /// Number of bytes that must be kept in buffer after read_pos. - /// That is, read_pos <= write_pos - keep_size_after as long as - /// action is LZMA_RUN; when action != LZMA_RUN, read_pos is allowed - /// to reach write_pos so that the last bytes get encoded too. - uint32_t keep_size_after; - - /// Match finders store locations of matches using 32-bit integers. - /// To avoid adjusting several megabytes of integers every time the - /// input window is moved with move_window, we only adjust the - /// offset of the buffer. Thus, buffer[value_in_hash_table - offset] - /// is the byte pointed by value_in_hash_table. - uint32_t offset; - - /// buffer[read_pos] is the next byte to run through the match - /// finder. This is incremented in the match finder once the byte - /// has been processed. - uint32_t read_pos; - - /// Number of bytes that have been ran through the match finder, but - /// which haven't been encoded by the LZ-based encoder yet. - uint32_t read_ahead; - - /// As long as read_pos is less than read_limit, there is enough - /// input available in buffer for at least one encoding loop. - /// - /// Because of the stateful API, read_limit may and will get greater - /// than read_pos quite often. This is taken into account when - /// calculating the value for keep_size_after. - uint32_t read_limit; - - /// buffer[write_pos] is the first byte that doesn't contain valid - /// uncompressed data; that is, the next input byte will be copied - /// to buffer[write_pos]. - uint32_t write_pos; - - /// Number of bytes not hashed before read_pos. This is needed to - /// restart the match finder after LZMA_SYNC_FLUSH. - uint32_t pending; - - ////////////////// - // Match Finder // - ////////////////// - - /// Find matches. Returns the number of distance-length pairs written - /// to the matches array. This is called only via lzma_mf_find(). - uint32_t (*find)(lzma_mf *mf, lzma_match *matches); - - /// Skips num bytes. This is like find() but doesn't make the - /// distance-length pairs available, thus being a little faster. - /// This is called only via mf_skip(). - void (*skip)(lzma_mf *mf, uint32_t num); - - uint32_t *hash; - uint32_t *son; - uint32_t cyclic_pos; - uint32_t cyclic_size; // Must be dictionary size + 1. - uint32_t hash_mask; - - /// Maximum number of loops in the match finder - uint32_t depth; - - /// Maximum length of a match that the match finder will try to find. - uint32_t nice_len; - - /// Maximum length of a match supported by the LZ-based encoder. - /// If the longest match found by the match finder is nice_len, - /// mf_find() tries to expand it up to match_len_max bytes. - uint32_t match_len_max; - - /// When running out of input, binary tree match finders need to know - /// if it is due to flushing or finishing. The action is used also - /// by the LZ-based encoders themselves. - lzma_action action; - - /// Number of elements in hash[] - uint32_t hash_count; - - /// Number of elements in son[] - uint32_t sons_count; -}; - - -typedef struct { - /// Extra amount of data to keep available before the "actual" - /// dictionary. - size_t before_size; - - /// Size of the history buffer - size_t dict_size; - - /// Extra amount of data to keep available after the "actual" - /// dictionary. - size_t after_size; - - /// Maximum length of a match that the LZ-based encoder can accept. - /// This is used to extend matches of length nice_len to the - /// maximum possible length. - size_t match_len_max; - - /// Match finder will search matches up to this length. - /// This must be less than or equal to match_len_max. - size_t nice_len; - - /// Type of the match finder to use - lzma_match_finder match_finder; - - /// Maximum search depth - uint32_t depth; - - /// TODO: Comment - const uint8_t *preset_dict; - - uint32_t preset_dict_size; - -} lzma_lz_options; - - -// The total usable buffer space at any moment outside the match finder: -// before_size + dict_size + after_size + match_len_max -// -// In reality, there's some extra space allocated to prevent the number of -// memmove() calls reasonable. The bigger the dict_size is, the bigger -// this extra buffer will be since with bigger dictionaries memmove() would -// also take longer. -// -// A single encoder loop in the LZ-based encoder may call the match finder -// (mf_find() or mf_skip()) at most after_size times. In other words, -// a single encoder loop may increment lzma_mf.read_pos at most after_size -// times. Since matches are looked up to -// lzma_mf.buffer[lzma_mf.read_pos + match_len_max - 1], the total -// amount of extra buffer needed after dict_size becomes -// after_size + match_len_max. -// -// before_size has two uses. The first one is to keep literals available -// in cases when the LZ-based encoder has made some read ahead. -// TODO: Maybe this could be changed by making the LZ-based encoders to -// store the actual literals as they do with length-distance pairs. -// -// Algorithms such as LZMA2 first try to compress a chunk, and then check -// if the encoded result is smaller than the uncompressed one. If the chunk -// was uncompressible, it is better to store it in uncompressed form in -// the output stream. To do this, the whole uncompressed chunk has to be -// still available in the history buffer. before_size achieves that. - - -typedef struct { - /// Data specific to the LZ-based encoder - void *coder; - - /// Function to encode from *dict to out[] - lzma_ret (*code)(void *coder, - lzma_mf *restrict mf, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size); - - /// Free allocated resources - void (*end)(void *coder, const lzma_allocator *allocator); - - /// Update the options in the middle of the encoding. - lzma_ret (*options_update)(void *coder, const lzma_filter *filter); - -} lzma_lz_encoder; - - -// Basic steps: -// 1. Input gets copied into the dictionary. -// 2. Data in dictionary gets run through the match finder byte by byte. -// 3. The literals and matches are encoded using e.g. LZMA. -// -// The bytes that have been ran through the match finder, but not encoded yet, -// are called `read ahead'. - - -/// Get pointer to the first byte not ran through the match finder -static inline const uint8_t * -mf_ptr(const lzma_mf *mf) -{ - return mf->buffer + mf->read_pos; -} - - -/// Get the number of bytes that haven't been ran through the match finder yet. -static inline uint32_t -mf_avail(const lzma_mf *mf) -{ - return mf->write_pos - mf->read_pos; -} - - -/// Get the number of bytes that haven't been encoded yet (some of these -/// bytes may have been ran through the match finder though). -static inline uint32_t -mf_unencoded(const lzma_mf *mf) -{ - return mf->write_pos - mf->read_pos + mf->read_ahead; -} - - -/// Calculate the absolute offset from the beginning of the most recent -/// dictionary reset. Only the lowest four bits are important, so there's no -/// problem that we don't know the 64-bit size of the data encoded so far. -/// -/// NOTE: When moving the input window, we need to do it so that the lowest -/// bits of dict->read_pos are not modified to keep this macro working -/// as intended. -static inline uint32_t -mf_position(const lzma_mf *mf) -{ - return mf->read_pos - mf->read_ahead; -} - - -/// Since everything else begins with mf_, use it also for lzma_mf_find(). -#define mf_find lzma_mf_find - - -/// Skip the given number of bytes. This is used when a good match was found. -/// For example, if mf_find() finds a match of 200 bytes long, the first byte -/// of that match was already consumed by mf_find(), and the rest 199 bytes -/// have to be skipped with mf_skip(mf, 199). -static inline void -mf_skip(lzma_mf *mf, uint32_t amount) -{ - if (amount != 0) { - mf->skip(mf, amount); - mf->read_ahead += amount; - } -} - - -/// Copies at most *left number of bytes from the history buffer -/// to out[]. This is needed by LZMA2 to encode uncompressed chunks. -static inline void -mf_read(lzma_mf *mf, uint8_t *out, size_t *out_pos, size_t out_size, - size_t *left) -{ - const size_t out_avail = out_size - *out_pos; - const size_t copy_size = my_min(out_avail, *left); - - assert(mf->read_ahead == 0); - assert(mf->read_pos >= *left); - - memcpy(out + *out_pos, mf->buffer + mf->read_pos - *left, - copy_size); - - *out_pos += copy_size; - *left -= copy_size; - return; -} - - -extern lzma_ret lzma_lz_encoder_init( - lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters, - lzma_ret (*lz_init)(lzma_lz_encoder *lz, - const lzma_allocator *allocator, const void *options, - lzma_lz_options *lz_options)); - - -extern uint64_t lzma_lz_encoder_memusage(const lzma_lz_options *lz_options); - - -// These are only for LZ encoder's internal use. -extern uint32_t lzma_mf_find( - lzma_mf *mf, uint32_t *count, lzma_match *matches); - -extern uint32_t lzma_mf_hc3_find(lzma_mf *dict, lzma_match *matches); -extern void lzma_mf_hc3_skip(lzma_mf *dict, uint32_t amount); - -extern uint32_t lzma_mf_hc4_find(lzma_mf *dict, lzma_match *matches); -extern void lzma_mf_hc4_skip(lzma_mf *dict, uint32_t amount); - -extern uint32_t lzma_mf_bt2_find(lzma_mf *dict, lzma_match *matches); -extern void lzma_mf_bt2_skip(lzma_mf *dict, uint32_t amount); - -extern uint32_t lzma_mf_bt3_find(lzma_mf *dict, lzma_match *matches); -extern void lzma_mf_bt3_skip(lzma_mf *dict, uint32_t amount); - -extern uint32_t lzma_mf_bt4_find(lzma_mf *dict, lzma_match *matches); -extern void lzma_mf_bt4_skip(lzma_mf *dict, uint32_t amount); - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lz/lz_encoder_hash.h b/game/client/third/minizip/lib/liblzma/lz/lz_encoder_hash.h deleted file mode 100755 index 342a333d..00000000 --- a/game/client/third/minizip/lib/liblzma/lz/lz_encoder_hash.h +++ /dev/null @@ -1,108 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lz_encoder_hash.h -/// \brief Hash macros for match finders -// -// Author: Igor Pavlov -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZ_ENCODER_HASH_H -#define LZMA_LZ_ENCODER_HASH_H - -#if defined(WORDS_BIGENDIAN) && !defined(HAVE_SMALL) - // This is to make liblzma produce the same output on big endian - // systems that it does on little endian systems. lz_encoder.c - // takes care of including the actual table. - extern const uint32_t lzma_lz_hash_table[256]; -# define hash_table lzma_lz_hash_table -#else -# include "check.h" -# define hash_table lzma_crc32_table[0] -#endif - -#define HASH_2_SIZE (UINT32_C(1) << 10) -#define HASH_3_SIZE (UINT32_C(1) << 16) -#define HASH_4_SIZE (UINT32_C(1) << 20) - -#define HASH_2_MASK (HASH_2_SIZE - 1) -#define HASH_3_MASK (HASH_3_SIZE - 1) -#define HASH_4_MASK (HASH_4_SIZE - 1) - -#define FIX_3_HASH_SIZE (HASH_2_SIZE) -#define FIX_4_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE) -#define FIX_5_HASH_SIZE (HASH_2_SIZE + HASH_3_SIZE + HASH_4_SIZE) - -// Endianness doesn't matter in hash_2_calc() (no effect on the output). -#ifdef TUKLIB_FAST_UNALIGNED_ACCESS -# define hash_2_calc() \ - const uint32_t hash_value = *(const uint16_t *)(cur) -#else -# define hash_2_calc() \ - const uint32_t hash_value \ - = (uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8) -#endif - -#define hash_3_calc() \ - const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \ - const uint32_t hash_2_value = temp & HASH_2_MASK; \ - const uint32_t hash_value \ - = (temp ^ ((uint32_t)(cur[2]) << 8)) & mf->hash_mask - -#define hash_4_calc() \ - const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \ - const uint32_t hash_2_value = temp & HASH_2_MASK; \ - const uint32_t hash_3_value \ - = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \ - const uint32_t hash_value = (temp ^ ((uint32_t)(cur[2]) << 8) \ - ^ (hash_table[cur[3]] << 5)) & mf->hash_mask - - -// The following are not currently used. - -#define hash_5_calc() \ - const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \ - const uint32_t hash_2_value = temp & HASH_2_MASK; \ - const uint32_t hash_3_value \ - = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \ - uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \ - ^ hash_table[cur[3]] << 5); \ - const uint32_t hash_value \ - = (hash_4_value ^ (hash_table[cur[4]] << 3)) \ - & mf->hash_mask; \ - hash_4_value &= HASH_4_MASK - -/* -#define hash_zip_calc() \ - const uint32_t hash_value \ - = (((uint32_t)(cur[0]) | ((uint32_t)(cur[1]) << 8)) \ - ^ hash_table[cur[2]]) & 0xFFFF -*/ - -#define hash_zip_calc() \ - const uint32_t hash_value \ - = (((uint32_t)(cur[2]) | ((uint32_t)(cur[0]) << 8)) \ - ^ hash_table[cur[1]]) & 0xFFFF - -#define mt_hash_2_calc() \ - const uint32_t hash_2_value \ - = (hash_table[cur[0]] ^ cur[1]) & HASH_2_MASK - -#define mt_hash_3_calc() \ - const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \ - const uint32_t hash_2_value = temp & HASH_2_MASK; \ - const uint32_t hash_3_value \ - = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK - -#define mt_hash_4_calc() \ - const uint32_t temp = hash_table[cur[0]] ^ cur[1]; \ - const uint32_t hash_2_value = temp & HASH_2_MASK; \ - const uint32_t hash_3_value \ - = (temp ^ ((uint32_t)(cur[2]) << 8)) & HASH_3_MASK; \ - const uint32_t hash_4_value = (temp ^ ((uint32_t)(cur[2]) << 8) ^ \ - (hash_table[cur[3]] << 5)) & HASH_4_MASK - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lz/lz_encoder_hash_table.h b/game/client/third/minizip/lib/liblzma/lz/lz_encoder_hash_table.h deleted file mode 100755 index 8c51717d..00000000 --- a/game/client/third/minizip/lib/liblzma/lz/lz_encoder_hash_table.h +++ /dev/null @@ -1,68 +0,0 @@ -/* This file has been automatically generated by crc32_tablegen.c. */ - -const uint32_t lzma_lz_hash_table[256] = { - 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, - 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3, - 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, - 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, - 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, - 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, - 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, - 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5, - 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, - 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B, - 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, - 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, - 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, - 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, - 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, - 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D, - 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, - 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, - 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, - 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, - 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, - 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, - 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, - 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65, - 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, - 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, - 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, - 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, - 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, - 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F, - 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, - 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD, - 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, - 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, - 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, - 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, - 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, - 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7, - 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, - 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, - 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, - 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, - 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, - 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, - 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, - 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F, - 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, - 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, - 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, - 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, - 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, - 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, - 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, - 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777, - 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, - 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, - 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, - 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, - 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, - 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9, - 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, - 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, - 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, - 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D -}; diff --git a/game/client/third/minizip/lib/liblzma/lz/lz_encoder_mf.c b/game/client/third/minizip/lib/liblzma/lz/lz_encoder_mf.c deleted file mode 100755 index 78520779..00000000 --- a/game/client/third/minizip/lib/liblzma/lz/lz_encoder_mf.c +++ /dev/null @@ -1,744 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lz_encoder_mf.c -/// \brief Match finders -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "lz_encoder.h" -#include "lz_encoder_hash.h" -#include "memcmplen.h" - - -/// \brief Find matches starting from the current byte -/// -/// \return The length of the longest match found -extern uint32_t -lzma_mf_find(lzma_mf *mf, uint32_t *count_ptr, lzma_match *matches) -{ - // Call the match finder. It returns the number of length-distance - // pairs found. - // FIXME: Minimum count is zero, what _exactly_ is the maximum? - const uint32_t count = mf->find(mf, matches); - - // Length of the longest match; assume that no matches were found - // and thus the maximum length is zero. - uint32_t len_best = 0; - - if (count > 0) { -#ifndef NDEBUG - // Validate the matches. - for (uint32_t i = 0; i < count; ++i) { - assert(matches[i].len <= mf->nice_len); - assert(matches[i].dist < mf->read_pos); - assert(memcmp(mf_ptr(mf) - 1, - mf_ptr(mf) - matches[i].dist - 2, - matches[i].len) == 0); - } -#endif - - // The last used element in the array contains - // the longest match. - len_best = matches[count - 1].len; - - // If a match of maximum search length was found, try to - // extend the match to maximum possible length. - if (len_best == mf->nice_len) { - // The limit for the match length is either the - // maximum match length supported by the LZ-based - // encoder or the number of bytes left in the - // dictionary, whichever is smaller. - uint32_t limit = mf_avail(mf) + 1; - if (limit > mf->match_len_max) - limit = mf->match_len_max; - - // Pointer to the byte we just ran through - // the match finder. - const uint8_t *p1 = mf_ptr(mf) - 1; - - // Pointer to the beginning of the match. We need -1 - // here because the match distances are zero based. - const uint8_t *p2 = p1 - matches[count - 1].dist - 1; - - len_best = lzma_memcmplen(p1, p2, len_best, limit); - } - } - - *count_ptr = count; - - // Finally update the read position to indicate that match finder was - // run for this dictionary offset. - ++mf->read_ahead; - - return len_best; -} - - -/// Hash value to indicate unused element in the hash. Since we start the -/// positions from dict_size + 1, zero is always too far to qualify -/// as usable match position. -#define EMPTY_HASH_VALUE 0 - - -/// Normalization must be done when lzma_mf.offset + lzma_mf.read_pos -/// reaches MUST_NORMALIZE_POS. -#define MUST_NORMALIZE_POS UINT32_MAX - - -/// \brief Normalizes hash values -/// -/// The hash arrays store positions of match candidates. The positions are -/// relative to an arbitrary offset that is not the same as the absolute -/// offset in the input stream. The relative position of the current byte -/// is lzma_mf.offset + lzma_mf.read_pos. The distances of the matches are -/// the differences of the current read position and the position found from -/// the hash. -/// -/// To prevent integer overflows of the offsets stored in the hash arrays, -/// we need to "normalize" the stored values now and then. During the -/// normalization, we drop values that indicate distance greater than the -/// dictionary size, thus making space for new values. -static void -normalize(lzma_mf *mf) -{ - assert(mf->read_pos + mf->offset == MUST_NORMALIZE_POS); - - // In future we may not want to touch the lowest bits, because there - // may be match finders that use larger resolution than one byte. - const uint32_t subvalue - = (MUST_NORMALIZE_POS - mf->cyclic_size); - // & (~(UINT32_C(1) << 10) - 1); - - for (uint32_t i = 0; i < mf->hash_count; ++i) { - // If the distance is greater than the dictionary size, - // we can simply mark the hash element as empty. - if (mf->hash[i] <= subvalue) - mf->hash[i] = EMPTY_HASH_VALUE; - else - mf->hash[i] -= subvalue; - } - - for (uint32_t i = 0; i < mf->sons_count; ++i) { - // Do the same for mf->son. - // - // NOTE: There may be uninitialized elements in mf->son. - // Valgrind may complain that the "if" below depends on - // an uninitialized value. In this case it is safe to ignore - // the warning. See also the comments in lz_encoder_init() - // in lz_encoder.c. - if (mf->son[i] <= subvalue) - mf->son[i] = EMPTY_HASH_VALUE; - else - mf->son[i] -= subvalue; - } - - // Update offset to match the new locations. - mf->offset -= subvalue; - - return; -} - - -/// Mark the current byte as processed from point of view of the match finder. -static void -move_pos(lzma_mf *mf) -{ - if (++mf->cyclic_pos == mf->cyclic_size) - mf->cyclic_pos = 0; - - ++mf->read_pos; - assert(mf->read_pos <= mf->write_pos); - - if (unlikely(mf->read_pos + mf->offset == UINT32_MAX)) - normalize(mf); -} - - -/// When flushing, we cannot run the match finder unless there is nice_len -/// bytes available in the dictionary. Instead, we skip running the match -/// finder (indicating that no match was found), and count how many bytes we -/// have ignored this way. -/// -/// When new data is given after the flushing was completed, the match finder -/// is restarted by rewinding mf->read_pos backwards by mf->pending. Then -/// the missed bytes are added to the hash using the match finder's skip -/// function (with small amount of input, it may start using mf->pending -/// again if flushing). -/// -/// Due to this rewinding, we don't touch cyclic_pos or test for -/// normalization. It will be done when the match finder's skip function -/// catches up after a flush. -static void -move_pending(lzma_mf *mf) -{ - ++mf->read_pos; - assert(mf->read_pos <= mf->write_pos); - ++mf->pending; -} - - -/// Calculate len_limit and determine if there is enough input to run -/// the actual match finder code. Sets up "cur" and "pos". This macro -/// is used by all find functions and binary tree skip functions. Hash -/// chain skip function doesn't need len_limit so a simpler code is used -/// in them. -#define header(is_bt, len_min, ret_op) \ - uint32_t len_limit = mf_avail(mf); \ - if (mf->nice_len <= len_limit) { \ - len_limit = mf->nice_len; \ - } else if (len_limit < (len_min) \ - || (is_bt && mf->action == LZMA_SYNC_FLUSH)) { \ - assert(mf->action != LZMA_RUN); \ - move_pending(mf); \ - ret_op; \ - } \ - const uint8_t *cur = mf_ptr(mf); \ - const uint32_t pos = mf->read_pos + mf->offset - - -/// Header for find functions. "return 0" indicates that zero matches -/// were found. -#define header_find(is_bt, len_min) \ - header(is_bt, len_min, return 0); \ - uint32_t matches_count = 0 - - -/// Header for a loop in a skip function. "continue" tells to skip the rest -/// of the code in the loop. -#define header_skip(is_bt, len_min) \ - header(is_bt, len_min, continue) - - -/// Calls hc_find_func() or bt_find_func() and calculates the total number -/// of matches found. Updates the dictionary position and returns the number -/// of matches found. -#define call_find(func, len_best) \ -do { \ - matches_count = func(len_limit, pos, cur, cur_match, mf->depth, \ - mf->son, mf->cyclic_pos, mf->cyclic_size, \ - matches + matches_count, len_best) \ - - matches; \ - move_pos(mf); \ - return matches_count; \ -} while (0) - - -//////////////// -// Hash Chain // -//////////////// - -#if defined(HAVE_MF_HC3) || defined(HAVE_MF_HC4) -/// -/// -/// \param len_limit Don't look for matches longer than len_limit. -/// \param pos lzma_mf.read_pos + lzma_mf.offset -/// \param cur Pointer to current byte (mf_ptr(mf)) -/// \param cur_match Start position of the current match candidate -/// \param depth Maximum length of the hash chain -/// \param son lzma_mf.son (contains the hash chain) -/// \param cyclic_pos -/// \param cyclic_size -/// \param matches Array to hold the matches. -/// \param len_best The length of the longest match found so far. -static lzma_match * -hc_find_func( - const uint32_t len_limit, - const uint32_t pos, - const uint8_t *const cur, - uint32_t cur_match, - uint32_t depth, - uint32_t *const son, - const uint32_t cyclic_pos, - const uint32_t cyclic_size, - lzma_match *matches, - uint32_t len_best) -{ - son[cyclic_pos] = cur_match; - - while (true) { - const uint32_t delta = pos - cur_match; - if (depth-- == 0 || delta >= cyclic_size) - return matches; - - const uint8_t *const pb = cur - delta; - cur_match = son[cyclic_pos - delta - + (delta > cyclic_pos ? cyclic_size : 0)]; - - if (pb[len_best] == cur[len_best] && pb[0] == cur[0]) { - uint32_t len = lzma_memcmplen(pb, cur, 1, len_limit); - - if (len_best < len) { - len_best = len; - matches->len = len; - matches->dist = delta - 1; - ++matches; - - if (len == len_limit) - return matches; - } - } - } -} - - -#define hc_find(len_best) \ - call_find(hc_find_func, len_best) - - -#define hc_skip() \ -do { \ - mf->son[mf->cyclic_pos] = cur_match; \ - move_pos(mf); \ -} while (0) - -#endif - - -#ifdef HAVE_MF_HC3 -extern uint32_t -lzma_mf_hc3_find(lzma_mf *mf, lzma_match *matches) -{ - header_find(false, 3); - - hash_3_calc(); - - const uint32_t delta2 = pos - mf->hash[hash_2_value]; - const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; - - uint32_t len_best = 2; - - if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { - len_best = lzma_memcmplen(cur - delta2, cur, - len_best, len_limit); - - matches[0].len = len_best; - matches[0].dist = delta2 - 1; - matches_count = 1; - - if (len_best == len_limit) { - hc_skip(); - return 1; // matches_count - } - } - - hc_find(len_best); -} - - -extern void -lzma_mf_hc3_skip(lzma_mf *mf, uint32_t amount) -{ - do { - if (mf_avail(mf) < 3) { - move_pending(mf); - continue; - } - - const uint8_t *cur = mf_ptr(mf); - const uint32_t pos = mf->read_pos + mf->offset; - - hash_3_calc(); - - const uint32_t cur_match - = mf->hash[FIX_3_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; - - hc_skip(); - - } while (--amount != 0); -} -#endif - - -#ifdef HAVE_MF_HC4 -extern uint32_t -lzma_mf_hc4_find(lzma_mf *mf, lzma_match *matches) -{ - header_find(false, 4); - - hash_4_calc(); - - uint32_t delta2 = pos - mf->hash[hash_2_value]; - const uint32_t delta3 - = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value]; - const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value ] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; - mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; - - uint32_t len_best = 1; - - if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { - len_best = 2; - matches[0].len = 2; - matches[0].dist = delta2 - 1; - matches_count = 1; - } - - if (delta2 != delta3 && delta3 < mf->cyclic_size - && *(cur - delta3) == *cur) { - len_best = 3; - matches[matches_count++].dist = delta3 - 1; - delta2 = delta3; - } - - if (matches_count != 0) { - len_best = lzma_memcmplen(cur - delta2, cur, - len_best, len_limit); - - matches[matches_count - 1].len = len_best; - - if (len_best == len_limit) { - hc_skip(); - return matches_count; - } - } - - if (len_best < 3) - len_best = 3; - - hc_find(len_best); -} - - -extern void -lzma_mf_hc4_skip(lzma_mf *mf, uint32_t amount) -{ - do { - if (mf_avail(mf) < 4) { - move_pending(mf); - continue; - } - - const uint8_t *cur = mf_ptr(mf); - const uint32_t pos = mf->read_pos + mf->offset; - - hash_4_calc(); - - const uint32_t cur_match - = mf->hash[FIX_4_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; - mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; - - hc_skip(); - - } while (--amount != 0); -} -#endif - - -///////////////// -// Binary Tree // -///////////////// - -#if defined(HAVE_MF_BT2) || defined(HAVE_MF_BT3) || defined(HAVE_MF_BT4) -static lzma_match * -bt_find_func( - const uint32_t len_limit, - const uint32_t pos, - const uint8_t *const cur, - uint32_t cur_match, - uint32_t depth, - uint32_t *const son, - const uint32_t cyclic_pos, - const uint32_t cyclic_size, - lzma_match *matches, - uint32_t len_best) -{ - uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; - uint32_t *ptr1 = son + (cyclic_pos << 1); - - uint32_t len0 = 0; - uint32_t len1 = 0; - - while (true) { - const uint32_t delta = pos - cur_match; - if (depth-- == 0 || delta >= cyclic_size) { - *ptr0 = EMPTY_HASH_VALUE; - *ptr1 = EMPTY_HASH_VALUE; - return matches; - } - - uint32_t *const pair = son + ((cyclic_pos - delta - + (delta > cyclic_pos ? cyclic_size : 0)) - << 1); - - const uint8_t *const pb = cur - delta; - uint32_t len = my_min(len0, len1); - - if (pb[len] == cur[len]) { - len = lzma_memcmplen(pb, cur, len + 1, len_limit); - - if (len_best < len) { - len_best = len; - matches->len = len; - matches->dist = delta - 1; - ++matches; - - if (len == len_limit) { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return matches; - } - } - } - - if (pb[len] < cur[len]) { - *ptr1 = cur_match; - ptr1 = pair + 1; - cur_match = *ptr1; - len1 = len; - } else { - *ptr0 = cur_match; - ptr0 = pair; - cur_match = *ptr0; - len0 = len; - } - } -} - - -static void -bt_skip_func( - const uint32_t len_limit, - const uint32_t pos, - const uint8_t *const cur, - uint32_t cur_match, - uint32_t depth, - uint32_t *const son, - const uint32_t cyclic_pos, - const uint32_t cyclic_size) -{ - uint32_t *ptr0 = son + (cyclic_pos << 1) + 1; - uint32_t *ptr1 = son + (cyclic_pos << 1); - - uint32_t len0 = 0; - uint32_t len1 = 0; - - while (true) { - const uint32_t delta = pos - cur_match; - if (depth-- == 0 || delta >= cyclic_size) { - *ptr0 = EMPTY_HASH_VALUE; - *ptr1 = EMPTY_HASH_VALUE; - return; - } - - uint32_t *pair = son + ((cyclic_pos - delta - + (delta > cyclic_pos ? cyclic_size : 0)) - << 1); - const uint8_t *pb = cur - delta; - uint32_t len = my_min(len0, len1); - - if (pb[len] == cur[len]) { - len = lzma_memcmplen(pb, cur, len + 1, len_limit); - - if (len == len_limit) { - *ptr1 = pair[0]; - *ptr0 = pair[1]; - return; - } - } - - if (pb[len] < cur[len]) { - *ptr1 = cur_match; - ptr1 = pair + 1; - cur_match = *ptr1; - len1 = len; - } else { - *ptr0 = cur_match; - ptr0 = pair; - cur_match = *ptr0; - len0 = len; - } - } -} - - -#define bt_find(len_best) \ - call_find(bt_find_func, len_best) - -#define bt_skip() \ -do { \ - bt_skip_func(len_limit, pos, cur, cur_match, mf->depth, \ - mf->son, mf->cyclic_pos, \ - mf->cyclic_size); \ - move_pos(mf); \ -} while (0) - -#endif - - -#ifdef HAVE_MF_BT2 -extern uint32_t -lzma_mf_bt2_find(lzma_mf *mf, lzma_match *matches) -{ - header_find(true, 2); - - hash_2_calc(); - - const uint32_t cur_match = mf->hash[hash_value]; - mf->hash[hash_value] = pos; - - bt_find(1); -} - - -extern void -lzma_mf_bt2_skip(lzma_mf *mf, uint32_t amount) -{ - do { - header_skip(true, 2); - - hash_2_calc(); - - const uint32_t cur_match = mf->hash[hash_value]; - mf->hash[hash_value] = pos; - - bt_skip(); - - } while (--amount != 0); -} -#endif - - -#ifdef HAVE_MF_BT3 -extern uint32_t -lzma_mf_bt3_find(lzma_mf *mf, lzma_match *matches) -{ - header_find(true, 3); - - hash_3_calc(); - - const uint32_t delta2 = pos - mf->hash[hash_2_value]; - const uint32_t cur_match = mf->hash[FIX_3_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; - - uint32_t len_best = 2; - - if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { - len_best = lzma_memcmplen( - cur, cur - delta2, len_best, len_limit); - - matches[0].len = len_best; - matches[0].dist = delta2 - 1; - matches_count = 1; - - if (len_best == len_limit) { - bt_skip(); - return 1; // matches_count - } - } - - bt_find(len_best); -} - - -extern void -lzma_mf_bt3_skip(lzma_mf *mf, uint32_t amount) -{ - do { - header_skip(true, 3); - - hash_3_calc(); - - const uint32_t cur_match - = mf->hash[FIX_3_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_value] = pos; - - bt_skip(); - - } while (--amount != 0); -} -#endif - - -#ifdef HAVE_MF_BT4 -extern uint32_t -lzma_mf_bt4_find(lzma_mf *mf, lzma_match *matches) -{ - header_find(true, 4); - - hash_4_calc(); - - uint32_t delta2 = pos - mf->hash[hash_2_value]; - const uint32_t delta3 - = pos - mf->hash[FIX_3_HASH_SIZE + hash_3_value]; - const uint32_t cur_match = mf->hash[FIX_4_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; - mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; - - uint32_t len_best = 1; - - if (delta2 < mf->cyclic_size && *(cur - delta2) == *cur) { - len_best = 2; - matches[0].len = 2; - matches[0].dist = delta2 - 1; - matches_count = 1; - } - - if (delta2 != delta3 && delta3 < mf->cyclic_size - && *(cur - delta3) == *cur) { - len_best = 3; - matches[matches_count++].dist = delta3 - 1; - delta2 = delta3; - } - - if (matches_count != 0) { - len_best = lzma_memcmplen( - cur, cur - delta2, len_best, len_limit); - - matches[matches_count - 1].len = len_best; - - if (len_best == len_limit) { - bt_skip(); - return matches_count; - } - } - - if (len_best < 3) - len_best = 3; - - bt_find(len_best); -} - - -extern void -lzma_mf_bt4_skip(lzma_mf *mf, uint32_t amount) -{ - do { - header_skip(true, 4); - - hash_4_calc(); - - const uint32_t cur_match - = mf->hash[FIX_4_HASH_SIZE + hash_value]; - - mf->hash[hash_2_value] = pos; - mf->hash[FIX_3_HASH_SIZE + hash_3_value] = pos; - mf->hash[FIX_4_HASH_SIZE + hash_value] = pos; - - bt_skip(); - - } while (--amount != 0); -} -#endif diff --git a/game/client/third/minizip/lib/liblzma/lzma/fastpos.h b/game/client/third/minizip/lib/liblzma/lzma/fastpos.h deleted file mode 100755 index a3feea58..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/fastpos.h +++ /dev/null @@ -1,141 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file fastpos.h -/// \brief Kind of two-bit version of bit scan reverse -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_FASTPOS_H -#define LZMA_FASTPOS_H - -// LZMA encodes match distances by storing the highest two bits using -// a six-bit value [0, 63], and then the missing lower bits. -// Dictionary size is also stored using this encoding in the .xz -// file format header. -// -// fastpos.h provides a way to quickly find out the correct six-bit -// values. The following table gives some examples of this encoding: -// -// dist return -// 0 0 -// 1 1 -// 2 2 -// 3 3 -// 4 4 -// 5 4 -// 6 5 -// 7 5 -// 8 6 -// 11 6 -// 12 7 -// ... ... -// 15 7 -// 16 8 -// 17 8 -// ... ... -// 23 8 -// 24 9 -// 25 9 -// ... ... -// -// -// Provided functions or macros -// ---------------------------- -// -// get_dist_slot(dist) is the basic version. get_dist_slot_2(dist) -// assumes that dist >= FULL_DISTANCES, thus the result is at least -// FULL_DISTANCES_BITS * 2. Using get_dist_slot(dist) instead of -// get_dist_slot_2(dist) would give the same result, but get_dist_slot_2(dist) -// should be tiny bit faster due to the assumption being made. -// -// -// Size vs. speed -// -------------- -// -// With some CPUs that have fast BSR (bit scan reverse) instruction, the -// size optimized version is slightly faster than the bigger table based -// approach. Such CPUs include Intel Pentium Pro, Pentium II, Pentium III -// and Core 2 (possibly others). AMD K7 seems to have slower BSR, but that -// would still have speed roughly comparable to the table version. Older -// x86 CPUs like the original Pentium have very slow BSR; on those systems -// the table version is a lot faster. -// -// On some CPUs, the table version is a lot faster when using position -// dependent code, but with position independent code the size optimized -// version is slightly faster. This occurs at least on 32-bit SPARC (no -// ASM optimizations). -// -// I'm making the table version the default, because that has good speed -// on all systems I have tried. The size optimized version is sometimes -// slightly faster, but sometimes it is a lot slower. - -#ifdef HAVE_SMALL -# define get_dist_slot(dist) \ - ((dist) <= 4 ? (dist) : get_dist_slot_2(dist)) - -static inline uint32_t -get_dist_slot_2(uint32_t dist) -{ - const uint32_t i = bsr32(dist); - return (i + i) + ((dist >> (i - 1)) & 1); -} - - -#else - -#define FASTPOS_BITS 13 - -extern const uint8_t lzma_fastpos[1 << FASTPOS_BITS]; - - -#define fastpos_shift(extra, n) \ - ((extra) + (n) * (FASTPOS_BITS - 1)) - -#define fastpos_limit(extra, n) \ - (UINT32_C(1) << (FASTPOS_BITS + fastpos_shift(extra, n))) - -#define fastpos_result(dist, extra, n) \ - lzma_fastpos[(dist) >> fastpos_shift(extra, n)] \ - + 2 * fastpos_shift(extra, n) - - -static inline uint32_t -get_dist_slot(uint32_t dist) -{ - // If it is small enough, we can pick the result directly from - // the precalculated table. - if (dist < fastpos_limit(0, 0)) - return lzma_fastpos[dist]; - - if (dist < fastpos_limit(0, 1)) - return fastpos_result(dist, 0, 1); - - return fastpos_result(dist, 0, 2); -} - - -#ifdef FULL_DISTANCES_BITS -static inline uint32_t -get_dist_slot_2(uint32_t dist) -{ - assert(dist >= FULL_DISTANCES); - - if (dist < fastpos_limit(FULL_DISTANCES_BITS - 1, 0)) - return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 0); - - if (dist < fastpos_limit(FULL_DISTANCES_BITS - 1, 1)) - return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 1); - - return fastpos_result(dist, FULL_DISTANCES_BITS - 1, 2); -} -#endif - -#endif - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lzma/fastpos_table.c b/game/client/third/minizip/lib/liblzma/lzma/fastpos_table.c deleted file mode 100755 index 6a3ceac0..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/fastpos_table.c +++ /dev/null @@ -1,519 +0,0 @@ -/* This file has been automatically generated by fastpos_tablegen.c. */ - -#include "common.h" -#include "fastpos.h" - -const uint8_t lzma_fastpos[1 << FASTPOS_BITS] = { - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, - 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, - 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, - 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25 -}; diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma2_encoder.h b/game/client/third/minizip/lib/liblzma/lzma/lzma2_encoder.h deleted file mode 100755 index 515f1839..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma2_encoder.h +++ /dev/null @@ -1,43 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma2_encoder.h -/// \brief LZMA2 encoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZMA2_ENCODER_H -#define LZMA_LZMA2_ENCODER_H - -#include "common.h" - - -/// Maximum number of bytes of actual data per chunk (no headers) -#define LZMA2_CHUNK_MAX (UINT32_C(1) << 16) - -/// Maximum uncompressed size of LZMA chunk (no headers) -#define LZMA2_UNCOMPRESSED_MAX (UINT32_C(1) << 21) - -/// Maximum size of LZMA2 headers -#define LZMA2_HEADER_MAX 6 - -/// Size of a header for uncompressed chunk -#define LZMA2_HEADER_UNCOMPRESSED 3 - - -extern lzma_ret lzma_lzma2_encoder_init( - lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters); - -extern uint64_t lzma_lzma2_encoder_memusage(const void *options); - -extern lzma_ret lzma_lzma2_props_encode(const void *options, uint8_t *out); - -extern uint64_t lzma_lzma2_block_size(const void *options); - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_common.h b/game/client/third/minizip/lib/liblzma/lzma/lzma_common.h deleted file mode 100755 index 09efd387..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_common.h +++ /dev/null @@ -1,224 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_common.h -/// \brief Private definitions common to LZMA encoder and decoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZMA_COMMON_H -#define LZMA_LZMA_COMMON_H - -#include "common.h" -#include "range_common.h" - - -/////////////////// -// Miscellaneous // -/////////////////// - -/// Maximum number of position states. A position state is the lowest pos bits -/// number of bits of the current uncompressed offset. In some places there -/// are different sets of probabilities for different pos states. -#define POS_STATES_MAX (1 << LZMA_PB_MAX) - - -/// Validates lc, lp, and pb. -static inline bool -is_lclppb_valid(const lzma_options_lzma *options) -{ - return options->lc <= LZMA_LCLP_MAX && options->lp <= LZMA_LCLP_MAX - && options->lc + options->lp <= LZMA_LCLP_MAX - && options->pb <= LZMA_PB_MAX; -} - - -/////////// -// State // -/////////// - -/// This enum is used to track which events have occurred most recently and -/// in which order. This information is used to predict the next event. -/// -/// Events: -/// - Literal: One 8-bit byte -/// - Match: Repeat a chunk of data at some distance -/// - Long repeat: Multi-byte match at a recently seen distance -/// - Short repeat: One-byte repeat at a recently seen distance -/// -/// The event names are in from STATE_oldest_older_previous. REP means -/// either short or long repeated match, and NONLIT means any non-literal. -typedef enum { - STATE_LIT_LIT, - STATE_MATCH_LIT_LIT, - STATE_REP_LIT_LIT, - STATE_SHORTREP_LIT_LIT, - STATE_MATCH_LIT, - STATE_REP_LIT, - STATE_SHORTREP_LIT, - STATE_LIT_MATCH, - STATE_LIT_LONGREP, - STATE_LIT_SHORTREP, - STATE_NONLIT_MATCH, - STATE_NONLIT_REP, -} lzma_lzma_state; - - -/// Total number of states -#define STATES 12 - -/// The lowest 7 states indicate that the previous state was a literal. -#define LIT_STATES 7 - - -/// Indicate that the latest state was a literal. -#define update_literal(state) \ - state = ((state) <= STATE_SHORTREP_LIT_LIT \ - ? STATE_LIT_LIT \ - : ((state) <= STATE_LIT_SHORTREP \ - ? (state) - 3 \ - : (state) - 6)) - -/// Indicate that the latest state was a match. -#define update_match(state) \ - state = ((state) < LIT_STATES ? STATE_LIT_MATCH : STATE_NONLIT_MATCH) - -/// Indicate that the latest state was a long repeated match. -#define update_long_rep(state) \ - state = ((state) < LIT_STATES ? STATE_LIT_LONGREP : STATE_NONLIT_REP) - -/// Indicate that the latest state was a short match. -#define update_short_rep(state) \ - state = ((state) < LIT_STATES ? STATE_LIT_SHORTREP : STATE_NONLIT_REP) - -/// Test if the previous state was a literal. -#define is_literal_state(state) \ - ((state) < LIT_STATES) - - -///////////// -// Literal // -///////////// - -/// Each literal coder is divided in three sections: -/// - 0x001-0x0FF: Without match byte -/// - 0x101-0x1FF: With match byte; match bit is 0 -/// - 0x201-0x2FF: With match byte; match bit is 1 -/// -/// Match byte is used when the previous LZMA symbol was something else than -/// a literal (that is, it was some kind of match). -#define LITERAL_CODER_SIZE 0x300 - -/// Maximum number of literal coders -#define LITERAL_CODERS_MAX (1 << LZMA_LCLP_MAX) - -/// Locate the literal coder for the next literal byte. The choice depends on -/// - the lowest literal_pos_bits bits of the position of the current -/// byte; and -/// - the highest literal_context_bits bits of the previous byte. -#define literal_subcoder(probs, lc, lp_mask, pos, prev_byte) \ - ((probs)[(((pos) & lp_mask) << lc) + ((prev_byte) >> (8 - lc))]) - - -static inline void -literal_init(probability (*probs)[LITERAL_CODER_SIZE], - uint32_t lc, uint32_t lp) -{ - assert(lc + lp <= LZMA_LCLP_MAX); - - const uint32_t coders = 1U << (lc + lp); - - for (uint32_t i = 0; i < coders; ++i) - for (uint32_t j = 0; j < LITERAL_CODER_SIZE; ++j) - bit_reset(probs[i][j]); - - return; -} - - -////////////////// -// Match length // -////////////////// - -// Minimum length of a match is two bytes. -#define MATCH_LEN_MIN 2 - -// Match length is encoded with 4, 5, or 10 bits. -// -// Length Bits -// 2-9 4 = Choice=0 + 3 bits -// 10-17 5 = Choice=1 + Choice2=0 + 3 bits -// 18-273 10 = Choice=1 + Choice2=1 + 8 bits -#define LEN_LOW_BITS 3 -#define LEN_LOW_SYMBOLS (1 << LEN_LOW_BITS) -#define LEN_MID_BITS 3 -#define LEN_MID_SYMBOLS (1 << LEN_MID_BITS) -#define LEN_HIGH_BITS 8 -#define LEN_HIGH_SYMBOLS (1 << LEN_HIGH_BITS) -#define LEN_SYMBOLS (LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS + LEN_HIGH_SYMBOLS) - -// Maximum length of a match is 273 which is a result of the encoding -// described above. -#define MATCH_LEN_MAX (MATCH_LEN_MIN + LEN_SYMBOLS - 1) - - -//////////////////// -// Match distance // -//////////////////// - -// Different sets of probabilities are used for match distances that have very -// short match length: Lengths of 2, 3, and 4 bytes have a separate set of -// probabilities for each length. The matches with longer length use a shared -// set of probabilities. -#define DIST_STATES 4 - -// Macro to get the index of the appropriate probability array. -#define get_dist_state(len) \ - ((len) < DIST_STATES + MATCH_LEN_MIN \ - ? (len) - MATCH_LEN_MIN \ - : DIST_STATES - 1) - -// The highest two bits of a match distance (distance slot) are encoded -// using six bits. See fastpos.h for more explanation. -#define DIST_SLOT_BITS 6 -#define DIST_SLOTS (1 << DIST_SLOT_BITS) - -// Match distances up to 127 are fully encoded using probabilities. Since -// the highest two bits (distance slot) are always encoded using six bits, -// the distances 0-3 don't need any additional bits to encode, since the -// distance slot itself is the same as the actual distance. DIST_MODEL_START -// indicates the first distance slot where at least one additional bit is -// needed. -#define DIST_MODEL_START 4 - -// Match distances greater than 127 are encoded in three pieces: -// - distance slot: the highest two bits -// - direct bits: 2-26 bits below the highest two bits -// - alignment bits: four lowest bits -// -// Direct bits don't use any probabilities. -// -// The distance slot value of 14 is for distances 128-191 (see the table in -// fastpos.h to understand why). -#define DIST_MODEL_END 14 - -// Distance slots that indicate a distance <= 127. -#define FULL_DISTANCES_BITS (DIST_MODEL_END / 2) -#define FULL_DISTANCES (1 << FULL_DISTANCES_BITS) - -// For match distances greater than 127, only the highest two bits and the -// lowest four bits (alignment) is encoded using probabilities. -#define ALIGN_BITS 4 -#define ALIGN_SIZE (1 << ALIGN_BITS) -#define ALIGN_MASK (ALIGN_SIZE - 1) - -// LZMA remembers the four most recent match distances. Reusing these distances -// tends to take less space than re-encoding the actual distance value. -#define REPS 4 - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_decoder.c b/game/client/third/minizip/lib/liblzma/lzma/lzma_decoder.c deleted file mode 100755 index eedc0733..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_decoder.c +++ /dev/null @@ -1,1058 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_decoder.c -/// \brief LZMA decoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "lz_decoder.h" -#include "lzma_common.h" -#include "lzma_decoder.h" -#include "range_decoder.h" - - -#ifdef HAVE_SMALL - -// Macros for (somewhat) size-optimized code. -#define seq_4(seq) seq - -#define seq_6(seq) seq - -#define seq_8(seq) seq - -#define seq_len(seq) \ - seq ## _CHOICE, \ - seq ## _CHOICE2, \ - seq ## _BITTREE - -#define len_decode(target, ld, pos_state, seq) \ -do { \ -case seq ## _CHOICE: \ - rc_if_0(ld.choice, seq ## _CHOICE) { \ - rc_update_0(ld.choice); \ - probs = ld.low[pos_state];\ - limit = LEN_LOW_SYMBOLS; \ - target = MATCH_LEN_MIN; \ - } else { \ - rc_update_1(ld.choice); \ -case seq ## _CHOICE2: \ - rc_if_0(ld.choice2, seq ## _CHOICE2) { \ - rc_update_0(ld.choice2); \ - probs = ld.mid[pos_state]; \ - limit = LEN_MID_SYMBOLS; \ - target = MATCH_LEN_MIN + LEN_LOW_SYMBOLS; \ - } else { \ - rc_update_1(ld.choice2); \ - probs = ld.high; \ - limit = LEN_HIGH_SYMBOLS; \ - target = MATCH_LEN_MIN + LEN_LOW_SYMBOLS \ - + LEN_MID_SYMBOLS; \ - } \ - } \ - symbol = 1; \ -case seq ## _BITTREE: \ - do { \ - rc_bit(probs[symbol], , , seq ## _BITTREE); \ - } while (symbol < limit); \ - target += symbol - limit; \ -} while (0) - -#else // HAVE_SMALL - -// Unrolled versions -#define seq_4(seq) \ - seq ## 0, \ - seq ## 1, \ - seq ## 2, \ - seq ## 3 - -#define seq_6(seq) \ - seq ## 0, \ - seq ## 1, \ - seq ## 2, \ - seq ## 3, \ - seq ## 4, \ - seq ## 5 - -#define seq_8(seq) \ - seq ## 0, \ - seq ## 1, \ - seq ## 2, \ - seq ## 3, \ - seq ## 4, \ - seq ## 5, \ - seq ## 6, \ - seq ## 7 - -#define seq_len(seq) \ - seq ## _CHOICE, \ - seq ## _LOW0, \ - seq ## _LOW1, \ - seq ## _LOW2, \ - seq ## _CHOICE2, \ - seq ## _MID0, \ - seq ## _MID1, \ - seq ## _MID2, \ - seq ## _HIGH0, \ - seq ## _HIGH1, \ - seq ## _HIGH2, \ - seq ## _HIGH3, \ - seq ## _HIGH4, \ - seq ## _HIGH5, \ - seq ## _HIGH6, \ - seq ## _HIGH7 - -#define len_decode(target, ld, pos_state, seq) \ -do { \ - symbol = 1; \ -case seq ## _CHOICE: \ - rc_if_0(ld.choice, seq ## _CHOICE) { \ - rc_update_0(ld.choice); \ - rc_bit_case(ld.low[pos_state][symbol], , , seq ## _LOW0); \ - rc_bit_case(ld.low[pos_state][symbol], , , seq ## _LOW1); \ - rc_bit_case(ld.low[pos_state][symbol], , , seq ## _LOW2); \ - target = symbol - LEN_LOW_SYMBOLS + MATCH_LEN_MIN; \ - } else { \ - rc_update_1(ld.choice); \ -case seq ## _CHOICE2: \ - rc_if_0(ld.choice2, seq ## _CHOICE2) { \ - rc_update_0(ld.choice2); \ - rc_bit_case(ld.mid[pos_state][symbol], , , \ - seq ## _MID0); \ - rc_bit_case(ld.mid[pos_state][symbol], , , \ - seq ## _MID1); \ - rc_bit_case(ld.mid[pos_state][symbol], , , \ - seq ## _MID2); \ - target = symbol - LEN_MID_SYMBOLS \ - + MATCH_LEN_MIN + LEN_LOW_SYMBOLS; \ - } else { \ - rc_update_1(ld.choice2); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH0); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH1); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH2); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH3); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH4); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH5); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH6); \ - rc_bit_case(ld.high[symbol], , , seq ## _HIGH7); \ - target = symbol - LEN_HIGH_SYMBOLS \ - + MATCH_LEN_MIN \ - + LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; \ - } \ - } \ -} while (0) - -#endif // HAVE_SMALL - - -/// Length decoder probabilities; see comments in lzma_common.h. -typedef struct { - probability choice; - probability choice2; - probability low[POS_STATES_MAX][LEN_LOW_SYMBOLS]; - probability mid[POS_STATES_MAX][LEN_MID_SYMBOLS]; - probability high[LEN_HIGH_SYMBOLS]; -} lzma_length_decoder; - - -typedef struct { - /////////////////// - // Probabilities // - /////////////////// - - /// Literals; see comments in lzma_common.h. - probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; - - /// If 1, it's a match. Otherwise it's a single 8-bit literal. - probability is_match[STATES][POS_STATES_MAX]; - - /// If 1, it's a repeated match. The distance is one of rep0 .. rep3. - probability is_rep[STATES]; - - /// If 0, distance of a repeated match is rep0. - /// Otherwise check is_rep1. - probability is_rep0[STATES]; - - /// If 0, distance of a repeated match is rep1. - /// Otherwise check is_rep2. - probability is_rep1[STATES]; - - /// If 0, distance of a repeated match is rep2. Otherwise it is rep3. - probability is_rep2[STATES]; - - /// If 1, the repeated match has length of one byte. Otherwise - /// the length is decoded from rep_len_decoder. - probability is_rep0_long[STATES][POS_STATES_MAX]; - - /// Probability tree for the highest two bits of the match distance. - /// There is a separate probability tree for match lengths of - /// 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273]. - probability dist_slot[DIST_STATES][DIST_SLOTS]; - - /// Probability trees for additional bits for match distance when the - /// distance is in the range [4, 127]. - probability pos_special[FULL_DISTANCES - DIST_MODEL_END]; - - /// Probability tree for the lowest four bits of a match distance - /// that is equal to or greater than 128. - probability pos_align[ALIGN_SIZE]; - - /// Length of a normal match - lzma_length_decoder match_len_decoder; - - /// Length of a repeated match - lzma_length_decoder rep_len_decoder; - - /////////////////// - // Decoder state // - /////////////////// - - // Range coder - lzma_range_decoder rc; - - // Types of the most recently seen LZMA symbols - lzma_lzma_state state; - - uint32_t rep0; ///< Distance of the latest match - uint32_t rep1; ///< Distance of second latest match - uint32_t rep2; ///< Distance of third latest match - uint32_t rep3; ///< Distance of fourth latest match - - uint32_t pos_mask; // (1U << pb) - 1 - uint32_t literal_context_bits; - uint32_t literal_pos_mask; - - /// Uncompressed size as bytes, or LZMA_VLI_UNKNOWN if end of - /// payload marker is expected. - lzma_vli uncompressed_size; - - //////////////////////////////// - // State of incomplete symbol // - //////////////////////////////// - - /// Position where to continue the decoder loop - enum { - SEQ_NORMALIZE, - SEQ_IS_MATCH, - seq_8(SEQ_LITERAL), - seq_8(SEQ_LITERAL_MATCHED), - SEQ_LITERAL_WRITE, - SEQ_IS_REP, - seq_len(SEQ_MATCH_LEN), - seq_6(SEQ_DIST_SLOT), - SEQ_DIST_MODEL, - SEQ_DIRECT, - seq_4(SEQ_ALIGN), - SEQ_EOPM, - SEQ_IS_REP0, - SEQ_SHORTREP, - SEQ_IS_REP0_LONG, - SEQ_IS_REP1, - SEQ_IS_REP2, - seq_len(SEQ_REP_LEN), - SEQ_COPY, - } sequence; - - /// Base of the current probability tree - probability *probs; - - /// Symbol being decoded. This is also used as an index variable in - /// bittree decoders: probs[symbol] - uint32_t symbol; - - /// Used as a loop termination condition on bittree decoders and - /// direct bits decoder. - uint32_t limit; - - /// Matched literal decoder: 0x100 or 0 to help avoiding branches. - /// Bittree reverse decoders: Offset of the next bit: 1 << offset - uint32_t offset; - - /// If decoding a literal: match byte. - /// If decoding a match: length of the match. - uint32_t len; -} lzma_lzma1_decoder; - - -static lzma_ret -lzma_decode(void *coder_ptr, lzma_dict *restrict dictptr, - const uint8_t *restrict in, - size_t *restrict in_pos, size_t in_size) -{ - lzma_lzma1_decoder *restrict coder = coder_ptr; - - //////////////////// - // Initialization // - //////////////////// - - { - const lzma_ret ret = rc_read_init( - &coder->rc, in, in_pos, in_size); - if (ret != LZMA_STREAM_END) - return ret; - } - - /////////////// - // Variables // - /////////////// - - // Making local copies of often-used variables improves both - // speed and readability. - - lzma_dict dict = *dictptr; - - const size_t dict_start = dict.pos; - - // Range decoder - rc_to_local(coder->rc, *in_pos); - - // State - uint32_t state = coder->state; - uint32_t rep0 = coder->rep0; - uint32_t rep1 = coder->rep1; - uint32_t rep2 = coder->rep2; - uint32_t rep3 = coder->rep3; - - const uint32_t pos_mask = coder->pos_mask; - - // These variables are actually needed only if we last time ran - // out of input in the middle of the decoder loop. - probability *probs = coder->probs; - uint32_t symbol = coder->symbol; - uint32_t limit = coder->limit; - uint32_t offset = coder->offset; - uint32_t len = coder->len; - - const uint32_t literal_pos_mask = coder->literal_pos_mask; - const uint32_t literal_context_bits = coder->literal_context_bits; - - // Temporary variables - uint32_t pos_state = dict.pos & pos_mask; - - lzma_ret ret = LZMA_OK; - - // If uncompressed size is known, there must be no end of payload - // marker. - const bool no_eopm = coder->uncompressed_size - != LZMA_VLI_UNKNOWN; - if (no_eopm && coder->uncompressed_size < dict.limit - dict.pos) - dict.limit = dict.pos + (size_t)(coder->uncompressed_size); - - // The main decoder loop. The "switch" is used to restart the decoder at - // correct location. Once restarted, the "switch" is no longer used. - switch (coder->sequence) - while (true) { - // Calculate new pos_state. This is skipped on the first loop - // since we already calculated it when setting up the local - // variables. - pos_state = dict.pos & pos_mask; - - case SEQ_NORMALIZE: - case SEQ_IS_MATCH: - if (unlikely(no_eopm && dict.pos == dict.limit)) - break; - - rc_if_0(coder->is_match[state][pos_state], SEQ_IS_MATCH) { - rc_update_0(coder->is_match[state][pos_state]); - - // It's a literal i.e. a single 8-bit byte. - - probs = literal_subcoder(coder->literal, - literal_context_bits, literal_pos_mask, - dict.pos, dict_get(&dict, 0)); - symbol = 1; - - if (is_literal_state(state)) { - // Decode literal without match byte. -#ifdef HAVE_SMALL - case SEQ_LITERAL: - do { - rc_bit(probs[symbol], , , SEQ_LITERAL); - } while (symbol < (1 << 8)); -#else - rc_bit_case(probs[symbol], , , SEQ_LITERAL0); - rc_bit_case(probs[symbol], , , SEQ_LITERAL1); - rc_bit_case(probs[symbol], , , SEQ_LITERAL2); - rc_bit_case(probs[symbol], , , SEQ_LITERAL3); - rc_bit_case(probs[symbol], , , SEQ_LITERAL4); - rc_bit_case(probs[symbol], , , SEQ_LITERAL5); - rc_bit_case(probs[symbol], , , SEQ_LITERAL6); - rc_bit_case(probs[symbol], , , SEQ_LITERAL7); -#endif - } else { - // Decode literal with match byte. - // - // We store the byte we compare against - // ("match byte") to "len" to minimize the - // number of variables we need to store - // between decoder calls. - len = dict_get(&dict, rep0) << 1; - - // The usage of "offset" allows omitting some - // branches, which should give tiny speed - // improvement on some CPUs. "offset" gets - // set to zero if match_bit didn't match. - offset = 0x100; - -#ifdef HAVE_SMALL - case SEQ_LITERAL_MATCHED: - do { - const uint32_t match_bit - = len & offset; - const uint32_t subcoder_index - = offset + match_bit - + symbol; - - rc_bit(probs[subcoder_index], - offset &= ~match_bit, - offset &= match_bit, - SEQ_LITERAL_MATCHED); - - // It seems to be faster to do this - // here instead of putting it to the - // beginning of the loop and then - // putting the "case" in the middle - // of the loop. - len <<= 1; - - } while (symbol < (1 << 8)); -#else - // Unroll the loop. - uint32_t match_bit; - uint32_t subcoder_index; - -# define d(seq) \ - case seq: \ - match_bit = len & offset; \ - subcoder_index = offset + match_bit + symbol; \ - rc_bit(probs[subcoder_index], \ - offset &= ~match_bit, \ - offset &= match_bit, \ - seq) - - d(SEQ_LITERAL_MATCHED0); - len <<= 1; - d(SEQ_LITERAL_MATCHED1); - len <<= 1; - d(SEQ_LITERAL_MATCHED2); - len <<= 1; - d(SEQ_LITERAL_MATCHED3); - len <<= 1; - d(SEQ_LITERAL_MATCHED4); - len <<= 1; - d(SEQ_LITERAL_MATCHED5); - len <<= 1; - d(SEQ_LITERAL_MATCHED6); - len <<= 1; - d(SEQ_LITERAL_MATCHED7); -# undef d -#endif - } - - //update_literal(state); - // Use a lookup table to update to literal state, - // since compared to other state updates, this would - // need two branches. - static const lzma_lzma_state next_state[] = { - STATE_LIT_LIT, - STATE_LIT_LIT, - STATE_LIT_LIT, - STATE_LIT_LIT, - STATE_MATCH_LIT_LIT, - STATE_REP_LIT_LIT, - STATE_SHORTREP_LIT_LIT, - STATE_MATCH_LIT, - STATE_REP_LIT, - STATE_SHORTREP_LIT, - STATE_MATCH_LIT, - STATE_REP_LIT - }; - state = next_state[state]; - - case SEQ_LITERAL_WRITE: - if (unlikely(dict_put(&dict, symbol))) { - coder->sequence = SEQ_LITERAL_WRITE; - goto out; - } - - continue; - } - - // Instead of a new byte we are going to get a byte range - // (distance and length) which will be repeated from our - // output history. - - rc_update_1(coder->is_match[state][pos_state]); - - case SEQ_IS_REP: - rc_if_0(coder->is_rep[state], SEQ_IS_REP) { - // Not a repeated match - rc_update_0(coder->is_rep[state]); - update_match(state); - - // The latest three match distances are kept in - // memory in case there are repeated matches. - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - - // Decode the length of the match. - len_decode(len, coder->match_len_decoder, - pos_state, SEQ_MATCH_LEN); - - // Prepare to decode the highest two bits of the - // match distance. - probs = coder->dist_slot[get_dist_state(len)]; - symbol = 1; - -#ifdef HAVE_SMALL - case SEQ_DIST_SLOT: - do { - rc_bit(probs[symbol], , , SEQ_DIST_SLOT); - } while (symbol < DIST_SLOTS); -#else - rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT0); - rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT1); - rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT2); - rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT3); - rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT4); - rc_bit_case(probs[symbol], , , SEQ_DIST_SLOT5); -#endif - // Get rid of the highest bit that was needed for - // indexing of the probability array. - symbol -= DIST_SLOTS; - assert(symbol <= 63); - - if (symbol < DIST_MODEL_START) { - // Match distances [0, 3] have only two bits. - rep0 = symbol; - } else { - // Decode the lowest [1, 29] bits of - // the match distance. - limit = (symbol >> 1) - 1; - assert(limit >= 1 && limit <= 30); - rep0 = 2 + (symbol & 1); - - if (symbol < DIST_MODEL_END) { - // Prepare to decode the low bits for - // a distance of [4, 127]. - assert(limit <= 5); - rep0 <<= limit; - assert(rep0 <= 96); - // -1 is fine, because we start - // decoding at probs[1], not probs[0]. - // NOTE: This violates the C standard, - // since we are doing pointer - // arithmetic past the beginning of - // the array. - assert((int32_t)(rep0 - symbol - 1) - >= -1); - assert((int32_t)(rep0 - symbol - 1) - <= 82); - probs = coder->pos_special + rep0 - - symbol - 1; - symbol = 1; - offset = 0; - case SEQ_DIST_MODEL: -#ifdef HAVE_SMALL - do { - rc_bit(probs[symbol], , - rep0 += 1 << offset, - SEQ_DIST_MODEL); - } while (++offset < limit); -#else - switch (limit) { - case 5: - assert(offset == 0); - rc_bit(probs[symbol], , - rep0 += 1, - SEQ_DIST_MODEL); - ++offset; - --limit; - case 4: - rc_bit(probs[symbol], , - rep0 += 1 << offset, - SEQ_DIST_MODEL); - ++offset; - --limit; - case 3: - rc_bit(probs[symbol], , - rep0 += 1 << offset, - SEQ_DIST_MODEL); - ++offset; - --limit; - case 2: - rc_bit(probs[symbol], , - rep0 += 1 << offset, - SEQ_DIST_MODEL); - ++offset; - --limit; - case 1: - // We need "symbol" only for - // indexing the probability - // array, thus we can use - // rc_bit_last() here to omit - // the unneeded updating of - // "symbol". - rc_bit_last(probs[symbol], , - rep0 += 1 << offset, - SEQ_DIST_MODEL); - } -#endif - } else { - // The distance is >= 128. Decode the - // lower bits without probabilities - // except the lowest four bits. - assert(symbol >= 14); - assert(limit >= 6); - limit -= ALIGN_BITS; - assert(limit >= 2); - case SEQ_DIRECT: - // Not worth manual unrolling - do { - rc_direct(rep0, SEQ_DIRECT); - } while (--limit > 0); - - // Decode the lowest four bits using - // probabilities. - rep0 <<= ALIGN_BITS; - symbol = 1; -#ifdef HAVE_SMALL - offset = 0; - case SEQ_ALIGN: - do { - rc_bit(coder->pos_align[ - symbol], , - rep0 += 1 << offset, - SEQ_ALIGN); - } while (++offset < ALIGN_BITS); -#else - case SEQ_ALIGN0: - rc_bit(coder->pos_align[symbol], , - rep0 += 1, SEQ_ALIGN0); - case SEQ_ALIGN1: - rc_bit(coder->pos_align[symbol], , - rep0 += 2, SEQ_ALIGN1); - case SEQ_ALIGN2: - rc_bit(coder->pos_align[symbol], , - rep0 += 4, SEQ_ALIGN2); - case SEQ_ALIGN3: - // Like in SEQ_DIST_MODEL, we don't - // need "symbol" for anything else - // than indexing the probability array. - rc_bit_last(coder->pos_align[symbol], , - rep0 += 8, SEQ_ALIGN3); -#endif - - if (rep0 == UINT32_MAX) { - // End of payload marker was - // found. It must not be - // present if uncompressed - // size is known. - if (coder->uncompressed_size - != LZMA_VLI_UNKNOWN) { - ret = LZMA_DATA_ERROR; - goto out; - } - - case SEQ_EOPM: - // LZMA1 stream with - // end-of-payload marker. - rc_normalize(SEQ_EOPM); - ret = LZMA_STREAM_END; - goto out; - } - } - } - - // Validate the distance we just decoded. - if (unlikely(!dict_is_distance_valid(&dict, rep0))) { - ret = LZMA_DATA_ERROR; - goto out; - } - - } else { - rc_update_1(coder->is_rep[state]); - - // Repeated match - // - // The match distance is a value that we have had - // earlier. The latest four match distances are - // available as rep0, rep1, rep2 and rep3. We will - // now decode which of them is the new distance. - // - // There cannot be a match if we haven't produced - // any output, so check that first. - if (unlikely(!dict_is_distance_valid(&dict, 0))) { - ret = LZMA_DATA_ERROR; - goto out; - } - - case SEQ_IS_REP0: - rc_if_0(coder->is_rep0[state], SEQ_IS_REP0) { - rc_update_0(coder->is_rep0[state]); - // The distance is rep0. - - case SEQ_IS_REP0_LONG: - rc_if_0(coder->is_rep0_long[state][pos_state], - SEQ_IS_REP0_LONG) { - rc_update_0(coder->is_rep0_long[ - state][pos_state]); - - update_short_rep(state); - - case SEQ_SHORTREP: - if (unlikely(dict_put(&dict, dict_get( - &dict, rep0)))) { - coder->sequence = SEQ_SHORTREP; - goto out; - } - - continue; - } - - // Repeating more than one byte at - // distance of rep0. - rc_update_1(coder->is_rep0_long[ - state][pos_state]); - - } else { - rc_update_1(coder->is_rep0[state]); - - case SEQ_IS_REP1: - // The distance is rep1, rep2 or rep3. Once - // we find out which one of these three, it - // is stored to rep0 and rep1, rep2 and rep3 - // are updated accordingly. - rc_if_0(coder->is_rep1[state], SEQ_IS_REP1) { - rc_update_0(coder->is_rep1[state]); - - const uint32_t distance = rep1; - rep1 = rep0; - rep0 = distance; - - } else { - rc_update_1(coder->is_rep1[state]); - case SEQ_IS_REP2: - rc_if_0(coder->is_rep2[state], - SEQ_IS_REP2) { - rc_update_0(coder->is_rep2[ - state]); - - const uint32_t distance = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance; - - } else { - rc_update_1(coder->is_rep2[ - state]); - - const uint32_t distance = rep3; - rep3 = rep2; - rep2 = rep1; - rep1 = rep0; - rep0 = distance; - } - } - } - - update_long_rep(state); - - // Decode the length of the repeated match. - len_decode(len, coder->rep_len_decoder, - pos_state, SEQ_REP_LEN); - } - - ///////////////////////////////// - // Repeat from history buffer. // - ///////////////////////////////// - - // The length is always between these limits. There is no way - // to trigger the algorithm to set len outside this range. - assert(len >= MATCH_LEN_MIN); - assert(len <= MATCH_LEN_MAX); - - case SEQ_COPY: - // Repeat len bytes from distance of rep0. - if (unlikely(dict_repeat(&dict, rep0, &len))) { - coder->sequence = SEQ_COPY; - goto out; - } - } - - rc_normalize(SEQ_NORMALIZE); - coder->sequence = SEQ_IS_MATCH; - -out: - // Save state - - // NOTE: Must not copy dict.limit. - dictptr->pos = dict.pos; - dictptr->full = dict.full; - - rc_from_local(coder->rc, *in_pos); - - coder->state = state; - coder->rep0 = rep0; - coder->rep1 = rep1; - coder->rep2 = rep2; - coder->rep3 = rep3; - - coder->probs = probs; - coder->symbol = symbol; - coder->limit = limit; - coder->offset = offset; - coder->len = len; - - // Update the remaining amount of uncompressed data if uncompressed - // size was known. - if (coder->uncompressed_size != LZMA_VLI_UNKNOWN) { - coder->uncompressed_size -= dict.pos - dict_start; - - // Since there cannot be end of payload marker if the - // uncompressed size was known, we check here if we - // finished decoding. - if (coder->uncompressed_size == 0 && ret == LZMA_OK - && coder->sequence != SEQ_NORMALIZE) - ret = coder->sequence == SEQ_IS_MATCH - ? LZMA_STREAM_END : LZMA_DATA_ERROR; - } - - // We can do an additional check in the range decoder to catch some - // corrupted files. - if (ret == LZMA_STREAM_END) { - if (!rc_is_finished(coder->rc)) - ret = LZMA_DATA_ERROR; - - // Reset the range decoder so that it is ready to reinitialize - // for a new LZMA2 chunk. - rc_reset(coder->rc); - } - - return ret; -} - - - -static void -lzma_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size) -{ - lzma_lzma1_decoder *coder = coder_ptr; - coder->uncompressed_size = uncompressed_size; -} - - -static void -lzma_decoder_reset(void *coder_ptr, const void *opt) -{ - lzma_lzma1_decoder *coder = coder_ptr; - const lzma_options_lzma *options = opt; - - // NOTE: We assume that lc/lp/pb are valid since they were - // successfully decoded with lzma_lzma_decode_properties(). - - // Calculate pos_mask. We don't need pos_bits as is for anything. - coder->pos_mask = (1U << options->pb) - 1; - - // Initialize the literal decoder. - literal_init(coder->literal, options->lc, options->lp); - - coder->literal_context_bits = options->lc; - coder->literal_pos_mask = (1U << options->lp) - 1; - - // State - coder->state = STATE_LIT_LIT; - coder->rep0 = 0; - coder->rep1 = 0; - coder->rep2 = 0; - coder->rep3 = 0; - coder->pos_mask = (1U << options->pb) - 1; - - // Range decoder - rc_reset(coder->rc); - - // Bit and bittree decoders - for (uint32_t i = 0; i < STATES; ++i) { - for (uint32_t j = 0; j <= coder->pos_mask; ++j) { - bit_reset(coder->is_match[i][j]); - bit_reset(coder->is_rep0_long[i][j]); - } - - bit_reset(coder->is_rep[i]); - bit_reset(coder->is_rep0[i]); - bit_reset(coder->is_rep1[i]); - bit_reset(coder->is_rep2[i]); - } - - for (uint32_t i = 0; i < DIST_STATES; ++i) - bittree_reset(coder->dist_slot[i], DIST_SLOT_BITS); - - for (uint32_t i = 0; i < FULL_DISTANCES - DIST_MODEL_END; ++i) - bit_reset(coder->pos_special[i]); - - bittree_reset(coder->pos_align, ALIGN_BITS); - - // Len decoders (also bit/bittree) - const uint32_t num_pos_states = 1U << options->pb; - bit_reset(coder->match_len_decoder.choice); - bit_reset(coder->match_len_decoder.choice2); - bit_reset(coder->rep_len_decoder.choice); - bit_reset(coder->rep_len_decoder.choice2); - - for (uint32_t pos_state = 0; pos_state < num_pos_states; ++pos_state) { - bittree_reset(coder->match_len_decoder.low[pos_state], - LEN_LOW_BITS); - bittree_reset(coder->match_len_decoder.mid[pos_state], - LEN_MID_BITS); - - bittree_reset(coder->rep_len_decoder.low[pos_state], - LEN_LOW_BITS); - bittree_reset(coder->rep_len_decoder.mid[pos_state], - LEN_MID_BITS); - } - - bittree_reset(coder->match_len_decoder.high, LEN_HIGH_BITS); - bittree_reset(coder->rep_len_decoder.high, LEN_HIGH_BITS); - - coder->sequence = SEQ_IS_MATCH; - coder->probs = NULL; - coder->symbol = 0; - coder->limit = 0; - coder->offset = 0; - coder->len = 0; - - return; -} - - -extern lzma_ret -lzma_lzma_decoder_create(lzma_lz_decoder *lz, const lzma_allocator *allocator, - const void *opt, lzma_lz_options *lz_options) -{ - if (lz->coder == NULL) { - lz->coder = lzma_alloc(sizeof(lzma_lzma1_decoder), allocator); - if (lz->coder == NULL) - return LZMA_MEM_ERROR; - - lz->code = &lzma_decode; - lz->reset = &lzma_decoder_reset; - lz->set_uncompressed = &lzma_decoder_uncompressed; - } - - // All dictionary sizes are OK here. LZ decoder will take care of - // the special cases. - const lzma_options_lzma *options = opt; - lz_options->dict_size = options->dict_size; - lz_options->preset_dict = options->preset_dict; - lz_options->preset_dict_size = options->preset_dict_size; - - return LZMA_OK; -} - - -/// Allocate and initialize LZMA decoder. This is used only via LZ -/// initialization (lzma_lzma_decoder_init() passes function pointer to -/// the LZ initialization). -static lzma_ret -lzma_decoder_init(lzma_lz_decoder *lz, const lzma_allocator *allocator, - const void *options, lzma_lz_options *lz_options) -{ - if (!is_lclppb_valid(options)) - return LZMA_PROG_ERROR; - - return_if_error(lzma_lzma_decoder_create( - lz, allocator, options, lz_options)); - - lzma_decoder_reset(lz->coder, options); - lzma_decoder_uncompressed(lz->coder, LZMA_VLI_UNKNOWN); - - return LZMA_OK; -} - - -extern lzma_ret -lzma_lzma_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters) -{ - // LZMA can only be the last filter in the chain. This is enforced - // by the raw_decoder initialization. - assert(filters[1].init == NULL); - - return lzma_lz_decoder_init(next, allocator, filters, - &lzma_decoder_init); -} - - -extern bool -lzma_lzma_lclppb_decode(lzma_options_lzma *options, uint8_t byte) -{ - if (byte > (4 * 5 + 4) * 9 + 8) - return true; - - // See the file format specification to understand this. - options->pb = byte / (9 * 5); - byte -= options->pb * 9 * 5; - options->lp = byte / 9; - options->lc = byte - options->lp * 9; - - return options->lc + options->lp > LZMA_LCLP_MAX; -} - - -extern uint64_t -lzma_lzma_decoder_memusage_nocheck(const void *options) -{ - const lzma_options_lzma *const opt = options; - return sizeof(lzma_lzma1_decoder) - + lzma_lz_decoder_memusage(opt->dict_size); -} - - -extern uint64_t -lzma_lzma_decoder_memusage(const void *options) -{ - if (!is_lclppb_valid(options)) - return UINT64_MAX; - - return lzma_lzma_decoder_memusage_nocheck(options); -} - - -extern lzma_ret -lzma_lzma_props_decode(void **options, const lzma_allocator *allocator, - const uint8_t *props, size_t props_size) -{ - if (props_size != 5) - return LZMA_OPTIONS_ERROR; - - lzma_options_lzma *opt - = lzma_alloc(sizeof(lzma_options_lzma), allocator); - if (opt == NULL) - return LZMA_MEM_ERROR; - - if (lzma_lzma_lclppb_decode(opt, props[0])) - goto error; - - // All dictionary sizes are accepted, including zero. LZ decoder - // will automatically use a dictionary at least a few KiB even if - // a smaller dictionary is requested. - opt->dict_size = unaligned_read32le(props + 1); - - opt->preset_dict = NULL; - opt->preset_dict_size = 0; - - *options = opt; - - return LZMA_OK; - -error: - lzma_free(opt, allocator); - return LZMA_OPTIONS_ERROR; -} diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_decoder.h b/game/client/third/minizip/lib/liblzma/lzma/lzma_decoder.h deleted file mode 100755 index fa8ecb23..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_decoder.h +++ /dev/null @@ -1,53 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_decoder.h -/// \brief LZMA decoder API -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZMA_DECODER_H -#define LZMA_LZMA_DECODER_H - -#include "common.h" - - -/// Allocates and initializes LZMA decoder -extern lzma_ret lzma_lzma_decoder_init(lzma_next_coder *next, - const lzma_allocator *allocator, - const lzma_filter_info *filters); - -extern uint64_t lzma_lzma_decoder_memusage(const void *options); - -extern lzma_ret lzma_lzma_props_decode( - void **options, const lzma_allocator *allocator, - const uint8_t *props, size_t props_size); - - -/// \brief Decodes the LZMA Properties byte (lc/lp/pb) -/// -/// \return true if error occurred, false on success -/// -extern bool lzma_lzma_lclppb_decode( - lzma_options_lzma *options, uint8_t byte); - - -#ifdef LZMA_LZ_DECODER_H -/// Allocate and setup function pointers only. This is used by LZMA1 and -/// LZMA2 decoders. -extern lzma_ret lzma_lzma_decoder_create( - lzma_lz_decoder *lz, const lzma_allocator *allocator, - const void *opt, lzma_lz_options *lz_options); - -/// Gets memory usage without validating lc/lp/pb. This is used by LZMA2 -/// decoder, because raw LZMA2 decoding doesn't need lc/lp/pb. -extern uint64_t lzma_lzma_decoder_memusage_nocheck(const void *options); - -#endif - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder.c b/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder.c deleted file mode 100755 index ba9ce698..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder.c +++ /dev/null @@ -1,677 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_encoder.c -/// \brief LZMA encoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "lzma2_encoder.h" -#include "lzma_encoder_private.h" -#include "fastpos.h" - - -///////////// -// Literal // -///////////// - -static inline void -literal_matched(lzma_range_encoder *rc, probability *subcoder, - uint32_t match_byte, uint32_t symbol) -{ - uint32_t offset = 0x100; - symbol += UINT32_C(1) << 8; - - do { - match_byte <<= 1; - const uint32_t match_bit = match_byte & offset; - const uint32_t subcoder_index - = offset + match_bit + (symbol >> 8); - const uint32_t bit = (symbol >> 7) & 1; - rc_bit(rc, &subcoder[subcoder_index], bit); - - symbol <<= 1; - offset &= ~(match_byte ^ symbol); - - } while (symbol < (UINT32_C(1) << 16)); -} - - -static inline void -literal(lzma_lzma1_encoder *coder, lzma_mf *mf, uint32_t position) -{ - // Locate the literal byte to be encoded and the subcoder. - const uint8_t cur_byte = mf->buffer[ - mf->read_pos - mf->read_ahead]; - probability *subcoder = literal_subcoder(coder->literal, - coder->literal_context_bits, coder->literal_pos_mask, - position, mf->buffer[mf->read_pos - mf->read_ahead - 1]); - - if (is_literal_state(coder->state)) { - // Previous LZMA-symbol was a literal. Encode a normal - // literal without a match byte. - rc_bittree(&coder->rc, subcoder, 8, cur_byte); - } else { - // Previous LZMA-symbol was a match. Use the last byte of - // the match as a "match byte". That is, compare the bits - // of the current literal and the match byte. - const uint8_t match_byte = mf->buffer[ - mf->read_pos - coder->reps[0] - 1 - - mf->read_ahead]; - literal_matched(&coder->rc, subcoder, match_byte, cur_byte); - } - - update_literal(coder->state); -} - - -////////////////// -// Match length // -////////////////// - -static void -length_update_prices(lzma_length_encoder *lc, const uint32_t pos_state) -{ - const uint32_t table_size = lc->table_size; - lc->counters[pos_state] = table_size; - - const uint32_t a0 = rc_bit_0_price(lc->choice); - const uint32_t a1 = rc_bit_1_price(lc->choice); - const uint32_t b0 = a1 + rc_bit_0_price(lc->choice2); - const uint32_t b1 = a1 + rc_bit_1_price(lc->choice2); - uint32_t *const prices = lc->prices[pos_state]; - - uint32_t i; - for (i = 0; i < table_size && i < LEN_LOW_SYMBOLS; ++i) - prices[i] = a0 + rc_bittree_price(lc->low[pos_state], - LEN_LOW_BITS, i); - - for (; i < table_size && i < LEN_LOW_SYMBOLS + LEN_MID_SYMBOLS; ++i) - prices[i] = b0 + rc_bittree_price(lc->mid[pos_state], - LEN_MID_BITS, i - LEN_LOW_SYMBOLS); - - for (; i < table_size; ++i) - prices[i] = b1 + rc_bittree_price(lc->high, LEN_HIGH_BITS, - i - LEN_LOW_SYMBOLS - LEN_MID_SYMBOLS); - - return; -} - - -static inline void -length(lzma_range_encoder *rc, lzma_length_encoder *lc, - const uint32_t pos_state, uint32_t len, const bool fast_mode) -{ - assert(len <= MATCH_LEN_MAX); - len -= MATCH_LEN_MIN; - - if (len < LEN_LOW_SYMBOLS) { - rc_bit(rc, &lc->choice, 0); - rc_bittree(rc, lc->low[pos_state], LEN_LOW_BITS, len); - } else { - rc_bit(rc, &lc->choice, 1); - len -= LEN_LOW_SYMBOLS; - - if (len < LEN_MID_SYMBOLS) { - rc_bit(rc, &lc->choice2, 0); - rc_bittree(rc, lc->mid[pos_state], LEN_MID_BITS, len); - } else { - rc_bit(rc, &lc->choice2, 1); - len -= LEN_MID_SYMBOLS; - rc_bittree(rc, lc->high, LEN_HIGH_BITS, len); - } - } - - // Only getoptimum uses the prices so don't update the table when - // in fast mode. - if (!fast_mode) - if (--lc->counters[pos_state] == 0) - length_update_prices(lc, pos_state); -} - - -/////////// -// Match // -/////////// - -static inline void -match(lzma_lzma1_encoder *coder, const uint32_t pos_state, - const uint32_t distance, const uint32_t len) -{ - update_match(coder->state); - - length(&coder->rc, &coder->match_len_encoder, pos_state, len, - coder->fast_mode); - - const uint32_t dist_slot = get_dist_slot(distance); - const uint32_t dist_state = get_dist_state(len); - rc_bittree(&coder->rc, coder->dist_slot[dist_state], - DIST_SLOT_BITS, dist_slot); - - if (dist_slot >= DIST_MODEL_START) { - const uint32_t footer_bits = (dist_slot >> 1) - 1; - const uint32_t base = (2 | (dist_slot & 1)) << footer_bits; - const uint32_t dist_reduced = distance - base; - - if (dist_slot < DIST_MODEL_END) { - // Careful here: base - dist_slot - 1 can be -1, but - // rc_bittree_reverse starts at probs[1], not probs[0]. - rc_bittree_reverse(&coder->rc, - coder->dist_special + base - dist_slot - 1, - footer_bits, dist_reduced); - } else { - rc_direct(&coder->rc, dist_reduced >> ALIGN_BITS, - footer_bits - ALIGN_BITS); - rc_bittree_reverse( - &coder->rc, coder->dist_align, - ALIGN_BITS, dist_reduced & ALIGN_MASK); - ++coder->align_price_count; - } - } - - coder->reps[3] = coder->reps[2]; - coder->reps[2] = coder->reps[1]; - coder->reps[1] = coder->reps[0]; - coder->reps[0] = distance; - ++coder->match_price_count; -} - - -//////////////////// -// Repeated match // -//////////////////// - -static inline void -rep_match(lzma_lzma1_encoder *coder, const uint32_t pos_state, - const uint32_t rep, const uint32_t len) -{ - if (rep == 0) { - rc_bit(&coder->rc, &coder->is_rep0[coder->state], 0); - rc_bit(&coder->rc, - &coder->is_rep0_long[coder->state][pos_state], - len != 1); - } else { - const uint32_t distance = coder->reps[rep]; - rc_bit(&coder->rc, &coder->is_rep0[coder->state], 1); - - if (rep == 1) { - rc_bit(&coder->rc, &coder->is_rep1[coder->state], 0); - } else { - rc_bit(&coder->rc, &coder->is_rep1[coder->state], 1); - rc_bit(&coder->rc, &coder->is_rep2[coder->state], - rep - 2); - - if (rep == 3) - coder->reps[3] = coder->reps[2]; - - coder->reps[2] = coder->reps[1]; - } - - coder->reps[1] = coder->reps[0]; - coder->reps[0] = distance; - } - - if (len == 1) { - update_short_rep(coder->state); - } else { - length(&coder->rc, &coder->rep_len_encoder, pos_state, len, - coder->fast_mode); - update_long_rep(coder->state); - } -} - - -////////// -// Main // -////////// - -static void -encode_symbol(lzma_lzma1_encoder *coder, lzma_mf *mf, - uint32_t back, uint32_t len, uint32_t position) -{ - const uint32_t pos_state = position & coder->pos_mask; - - if (back == UINT32_MAX) { - // Literal i.e. eight-bit byte - assert(len == 1); - rc_bit(&coder->rc, - &coder->is_match[coder->state][pos_state], 0); - literal(coder, mf, position); - } else { - // Some type of match - rc_bit(&coder->rc, - &coder->is_match[coder->state][pos_state], 1); - - if (back < REPS) { - // It's a repeated match i.e. the same distance - // has been used earlier. - rc_bit(&coder->rc, &coder->is_rep[coder->state], 1); - rep_match(coder, pos_state, back, len); - } else { - // Normal match - rc_bit(&coder->rc, &coder->is_rep[coder->state], 0); - match(coder, pos_state, back - REPS, len); - } - } - - assert(mf->read_ahead >= len); - mf->read_ahead -= len; -} - - -static bool -encode_init(lzma_lzma1_encoder *coder, lzma_mf *mf) -{ - assert(mf_position(mf) == 0); - - if (mf->read_pos == mf->read_limit) { - if (mf->action == LZMA_RUN) - return false; // We cannot do anything. - - // We are finishing (we cannot get here when flushing). - assert(mf->write_pos == mf->read_pos); - assert(mf->action == LZMA_FINISH); - } else { - // Do the actual initialization. The first LZMA symbol must - // always be a literal. - mf_skip(mf, 1); - mf->read_ahead = 0; - rc_bit(&coder->rc, &coder->is_match[0][0], 0); - rc_bittree(&coder->rc, coder->literal[0], 8, mf->buffer[0]); - } - - // Initialization is done (except if empty file). - coder->is_initialized = true; - - return true; -} - - -static void -encode_eopm(lzma_lzma1_encoder *coder, uint32_t position) -{ - const uint32_t pos_state = position & coder->pos_mask; - rc_bit(&coder->rc, &coder->is_match[coder->state][pos_state], 1); - rc_bit(&coder->rc, &coder->is_rep[coder->state], 0); - match(coder, pos_state, UINT32_MAX, MATCH_LEN_MIN); -} - - -/// Number of bytes that a single encoding loop in lzma_lzma_encode() can -/// consume from the dictionary. This limit comes from lzma_lzma_optimum() -/// and may need to be updated if that function is significantly modified. -#define LOOP_INPUT_MAX (OPTS + 1) - - -extern lzma_ret -lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, - uint8_t *restrict out, size_t *restrict out_pos, - size_t out_size, uint32_t limit) -{ - // Initialize the stream if no data has been encoded yet. - if (!coder->is_initialized && !encode_init(coder, mf)) - return LZMA_OK; - - // Get the lowest bits of the uncompressed offset from the LZ layer. - uint32_t position = mf_position(mf); - - while (true) { - // Encode pending bits, if any. Calling this before encoding - // the next symbol is needed only with plain LZMA, since - // LZMA2 always provides big enough buffer to flush - // everything out from the range encoder. For the same reason, - // rc_encode() never returns true when this function is used - // as part of LZMA2 encoder. - if (rc_encode(&coder->rc, out, out_pos, out_size)) { - assert(limit == UINT32_MAX); - return LZMA_OK; - } - - // With LZMA2 we need to take care that compressed size of - // a chunk doesn't get too big. - // FIXME? Check if this could be improved. - if (limit != UINT32_MAX - && (mf->read_pos - mf->read_ahead >= limit - || *out_pos + rc_pending(&coder->rc) - >= LZMA2_CHUNK_MAX - - LOOP_INPUT_MAX)) - break; - - // Check that there is some input to process. - if (mf->read_pos >= mf->read_limit) { - if (mf->action == LZMA_RUN) - return LZMA_OK; - - if (mf->read_ahead == 0) - break; - } - - // Get optimal match (repeat position and length). - // Value ranges for pos: - // - [0, REPS): repeated match - // - [REPS, UINT32_MAX): - // match at (pos - REPS) - // - UINT32_MAX: not a match but a literal - // Value ranges for len: - // - [MATCH_LEN_MIN, MATCH_LEN_MAX] - uint32_t len; - uint32_t back; - - if (coder->fast_mode) - lzma_lzma_optimum_fast(coder, mf, &back, &len); - else - lzma_lzma_optimum_normal( - coder, mf, &back, &len, position); - - encode_symbol(coder, mf, back, len, position); - - position += len; - } - - if (!coder->is_flushed) { - coder->is_flushed = true; - - // We don't support encoding plain LZMA streams without EOPM, - // and LZMA2 doesn't use EOPM at LZMA level. - if (limit == UINT32_MAX) - encode_eopm(coder, position); - - // Flush the remaining bytes from the range encoder. - rc_flush(&coder->rc); - - // Copy the remaining bytes to the output buffer. If there - // isn't enough output space, we will copy out the remaining - // bytes on the next call to this function by using - // the rc_encode() call in the encoding loop above. - if (rc_encode(&coder->rc, out, out_pos, out_size)) { - assert(limit == UINT32_MAX); - return LZMA_OK; - } - } - - // Make it ready for the next LZMA2 chunk. - coder->is_flushed = false; - - return LZMA_STREAM_END; -} - - -static lzma_ret -lzma_encode(void *coder, lzma_mf *restrict mf, - uint8_t *restrict out, size_t *restrict out_pos, - size_t out_size) -{ - // Plain LZMA has no support for sync-flushing. - if (unlikely(mf->action == LZMA_SYNC_FLUSH)) - return LZMA_OPTIONS_ERROR; - - return lzma_lzma_encode(coder, mf, out, out_pos, out_size, UINT32_MAX); -} - - -//////////////////// -// Initialization // -//////////////////// - -static bool -is_options_valid(const lzma_options_lzma *options) -{ - // Validate some of the options. LZ encoder validates nice_len too - // but we need a valid value here earlier. - return is_lclppb_valid(options) - && options->nice_len >= MATCH_LEN_MIN - && options->nice_len <= MATCH_LEN_MAX - && (options->mode == LZMA_MODE_FAST - || options->mode == LZMA_MODE_NORMAL); -} - - -static void -set_lz_options(lzma_lz_options *lz_options, const lzma_options_lzma *options) -{ - // LZ encoder initialization does the validation for these so we - // don't need to validate here. - lz_options->before_size = OPTS; - lz_options->dict_size = options->dict_size; - lz_options->after_size = LOOP_INPUT_MAX; - lz_options->match_len_max = MATCH_LEN_MAX; - lz_options->nice_len = options->nice_len; - lz_options->match_finder = options->mf; - lz_options->depth = options->depth; - lz_options->preset_dict = options->preset_dict; - lz_options->preset_dict_size = options->preset_dict_size; - return; -} - - -static void -length_encoder_reset(lzma_length_encoder *lencoder, - const uint32_t num_pos_states, const bool fast_mode) -{ - bit_reset(lencoder->choice); - bit_reset(lencoder->choice2); - - for (size_t pos_state = 0; pos_state < num_pos_states; ++pos_state) { - bittree_reset(lencoder->low[pos_state], LEN_LOW_BITS); - bittree_reset(lencoder->mid[pos_state], LEN_MID_BITS); - } - - bittree_reset(lencoder->high, LEN_HIGH_BITS); - - if (!fast_mode) - for (uint32_t pos_state = 0; pos_state < num_pos_states; - ++pos_state) - length_update_prices(lencoder, pos_state); - - return; -} - - -extern lzma_ret -lzma_lzma_encoder_reset(lzma_lzma1_encoder *coder, - const lzma_options_lzma *options) -{ - if (!is_options_valid(options)) - return LZMA_OPTIONS_ERROR; - - coder->pos_mask = (1U << options->pb) - 1; - coder->literal_context_bits = options->lc; - coder->literal_pos_mask = (1U << options->lp) - 1; - - // Range coder - rc_reset(&coder->rc); - - // State - coder->state = STATE_LIT_LIT; - for (size_t i = 0; i < REPS; ++i) - coder->reps[i] = 0; - - literal_init(coder->literal, options->lc, options->lp); - - // Bit encoders - for (size_t i = 0; i < STATES; ++i) { - for (size_t j = 0; j <= coder->pos_mask; ++j) { - bit_reset(coder->is_match[i][j]); - bit_reset(coder->is_rep0_long[i][j]); - } - - bit_reset(coder->is_rep[i]); - bit_reset(coder->is_rep0[i]); - bit_reset(coder->is_rep1[i]); - bit_reset(coder->is_rep2[i]); - } - - for (size_t i = 0; i < FULL_DISTANCES - DIST_MODEL_END; ++i) - bit_reset(coder->dist_special[i]); - - // Bit tree encoders - for (size_t i = 0; i < DIST_STATES; ++i) - bittree_reset(coder->dist_slot[i], DIST_SLOT_BITS); - - bittree_reset(coder->dist_align, ALIGN_BITS); - - // Length encoders - length_encoder_reset(&coder->match_len_encoder, - 1U << options->pb, coder->fast_mode); - - length_encoder_reset(&coder->rep_len_encoder, - 1U << options->pb, coder->fast_mode); - - // Price counts are incremented every time appropriate probabilities - // are changed. price counts are set to zero when the price tables - // are updated, which is done when the appropriate price counts have - // big enough value, and lzma_mf.read_ahead == 0 which happens at - // least every OPTS (a few thousand) possible price count increments. - // - // By resetting price counts to UINT32_MAX / 2, we make sure that the - // price tables will be initialized before they will be used (since - // the value is definitely big enough), and that it is OK to increment - // price counts without risk of integer overflow (since UINT32_MAX / 2 - // is small enough). The current code doesn't increment price counts - // before initializing price tables, but it maybe done in future if - // we add support for saving the state between LZMA2 chunks. - coder->match_price_count = UINT32_MAX / 2; - coder->align_price_count = UINT32_MAX / 2; - - coder->opts_end_index = 0; - coder->opts_current_index = 0; - - return LZMA_OK; -} - - -extern lzma_ret -lzma_lzma_encoder_create(void **coder_ptr, - const lzma_allocator *allocator, - const lzma_options_lzma *options, lzma_lz_options *lz_options) -{ - // Allocate lzma_lzma1_encoder if it wasn't already allocated. - if (*coder_ptr == NULL) { - *coder_ptr = lzma_alloc(sizeof(lzma_lzma1_encoder), allocator); - if (*coder_ptr == NULL) - return LZMA_MEM_ERROR; - } - - lzma_lzma1_encoder *coder = *coder_ptr; - - // Set compression mode. We haven't validates the options yet, - // but it's OK here, since nothing bad happens with invalid - // options in the code below, and they will get rejected by - // lzma_lzma_encoder_reset() call at the end of this function. - switch (options->mode) { - case LZMA_MODE_FAST: - coder->fast_mode = true; - break; - - case LZMA_MODE_NORMAL: { - coder->fast_mode = false; - - // Set dist_table_size. - // Round the dictionary size up to next 2^n. - uint32_t log_size = 0; - while ((UINT32_C(1) << log_size) < options->dict_size) - ++log_size; - - coder->dist_table_size = log_size * 2; - - // Length encoders' price table size - coder->match_len_encoder.table_size - = options->nice_len + 1 - MATCH_LEN_MIN; - coder->rep_len_encoder.table_size - = options->nice_len + 1 - MATCH_LEN_MIN; - break; - } - - default: - return LZMA_OPTIONS_ERROR; - } - - // We don't need to write the first byte as literal if there is - // a non-empty preset dictionary. encode_init() wouldn't even work - // if there is a non-empty preset dictionary, because encode_init() - // assumes that position is zero and previous byte is also zero. - coder->is_initialized = options->preset_dict != NULL - && options->preset_dict_size > 0; - coder->is_flushed = false; - - set_lz_options(lz_options, options); - - return lzma_lzma_encoder_reset(coder, options); -} - - -static lzma_ret -lzma_encoder_init(lzma_lz_encoder *lz, const lzma_allocator *allocator, - const void *options, lzma_lz_options *lz_options) -{ - lz->code = &lzma_encode; - return lzma_lzma_encoder_create( - &lz->coder, allocator, options, lz_options); -} - - -extern lzma_ret -lzma_lzma_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, - const lzma_filter_info *filters) -{ - return lzma_lz_encoder_init( - next, allocator, filters, &lzma_encoder_init); -} - - -extern uint64_t -lzma_lzma_encoder_memusage(const void *options) -{ - if (!is_options_valid(options)) - return UINT64_MAX; - - lzma_lz_options lz_options; - set_lz_options(&lz_options, options); - - const uint64_t lz_memusage = lzma_lz_encoder_memusage(&lz_options); - if (lz_memusage == UINT64_MAX) - return UINT64_MAX; - - return (uint64_t)(sizeof(lzma_lzma1_encoder)) + lz_memusage; -} - - -extern bool -lzma_lzma_lclppb_encode(const lzma_options_lzma *options, uint8_t *byte) -{ - if (!is_lclppb_valid(options)) - return true; - - *byte = (options->pb * 5 + options->lp) * 9 + options->lc; - assert(*byte <= (4 * 5 + 4) * 9 + 8); - - return false; -} - - -#ifdef HAVE_ENCODER_LZMA1 -extern lzma_ret -lzma_lzma_props_encode(const void *options, uint8_t *out) -{ - const lzma_options_lzma *const opt = options; - - if (lzma_lzma_lclppb_encode(opt, out)) - return LZMA_PROG_ERROR; - - unaligned_write32le(out + 1, opt->dict_size); - - return LZMA_OK; -} -#endif - - -extern LZMA_API(lzma_bool) -lzma_mode_is_supported(lzma_mode mode) -{ - return mode == LZMA_MODE_FAST || mode == LZMA_MODE_NORMAL; -} diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder.h b/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder.h deleted file mode 100755 index 6cfdf228..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder.h +++ /dev/null @@ -1,58 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_encoder.h -/// \brief LZMA encoder API -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZMA_ENCODER_H -#define LZMA_LZMA_ENCODER_H - -#include "common.h" - - -typedef struct lzma_lzma1_encoder_s lzma_lzma1_encoder; - - -extern lzma_ret lzma_lzma_encoder_init(lzma_next_coder *next, - const lzma_allocator *allocator, - const lzma_filter_info *filters); - - -extern uint64_t lzma_lzma_encoder_memusage(const void *options); - -extern lzma_ret lzma_lzma_props_encode(const void *options, uint8_t *out); - - -/// Encodes lc/lp/pb into one byte. Returns false on success and true on error. -extern bool lzma_lzma_lclppb_encode( - const lzma_options_lzma *options, uint8_t *byte); - - -#ifdef LZMA_LZ_ENCODER_H - -/// Initializes raw LZMA encoder; this is used by LZMA2. -extern lzma_ret lzma_lzma_encoder_create( - void **coder_ptr, const lzma_allocator *allocator, - const lzma_options_lzma *options, lzma_lz_options *lz_options); - - -/// Resets an already initialized LZMA encoder; this is used by LZMA2. -extern lzma_ret lzma_lzma_encoder_reset( - lzma_lzma1_encoder *coder, const lzma_options_lzma *options); - - -extern lzma_ret lzma_lzma_encode(lzma_lzma1_encoder *restrict coder, - lzma_mf *restrict mf, uint8_t *restrict out, - size_t *restrict out_pos, size_t out_size, - uint32_t read_limit); - -#endif - -#endif diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_optimum_fast.c b/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_optimum_fast.c deleted file mode 100755 index 6c53d2bd..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_optimum_fast.c +++ /dev/null @@ -1,170 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_encoder_optimum_fast.c -// -// Author: Igor Pavlov -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "lzma_encoder_private.h" -#include "memcmplen.h" - - -#define change_pair(small_dist, big_dist) \ - (((big_dist) >> 7) > (small_dist)) - - -extern void -lzma_lzma_optimum_fast(lzma_lzma1_encoder *restrict coder, - lzma_mf *restrict mf, - uint32_t *restrict back_res, uint32_t *restrict len_res) -{ - const uint32_t nice_len = mf->nice_len; - - uint32_t len_main; - uint32_t matches_count; - if (mf->read_ahead == 0) { - len_main = mf_find(mf, &matches_count, coder->matches); - } else { - assert(mf->read_ahead == 1); - len_main = coder->longest_match_length; - matches_count = coder->matches_count; - } - - const uint8_t *buf = mf_ptr(mf) - 1; - const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX); - - if (buf_avail < 2) { - // There's not enough input left to encode a match. - *back_res = UINT32_MAX; - *len_res = 1; - return; - } - - // Look for repeated matches; scan the previous four match distances - uint32_t rep_len = 0; - uint32_t rep_index = 0; - - for (uint32_t i = 0; i < REPS; ++i) { - // Pointer to the beginning of the match candidate - const uint8_t *const buf_back = buf - coder->reps[i] - 1; - - // If the first two bytes (2 == MATCH_LEN_MIN) do not match, - // this rep is not useful. - if (not_equal_16(buf, buf_back)) - continue; - - // The first two bytes matched. - // Calculate the length of the match. - const uint32_t len = lzma_memcmplen( - buf, buf_back, 2, buf_avail); - - // If we have found a repeated match that is at least - // nice_len long, return it immediately. - if (len >= nice_len) { - *back_res = i; - *len_res = len; - mf_skip(mf, len - 1); - return; - } - - if (len > rep_len) { - rep_index = i; - rep_len = len; - } - } - - // We didn't find a long enough repeated match. Encode it as a normal - // match if the match length is at least nice_len. - if (len_main >= nice_len) { - *back_res = coder->matches[matches_count - 1].dist + REPS; - *len_res = len_main; - mf_skip(mf, len_main - 1); - return; - } - - uint32_t back_main = 0; - if (len_main >= 2) { - back_main = coder->matches[matches_count - 1].dist; - - while (matches_count > 1 && len_main == - coder->matches[matches_count - 2].len + 1) { - if (!change_pair(coder->matches[ - matches_count - 2].dist, - back_main)) - break; - - --matches_count; - len_main = coder->matches[matches_count - 1].len; - back_main = coder->matches[matches_count - 1].dist; - } - - if (len_main == 2 && back_main >= 0x80) - len_main = 1; - } - - if (rep_len >= 2) { - if (rep_len + 1 >= len_main - || (rep_len + 2 >= len_main - && back_main > (UINT32_C(1) << 9)) - || (rep_len + 3 >= len_main - && back_main > (UINT32_C(1) << 15))) { - *back_res = rep_index; - *len_res = rep_len; - mf_skip(mf, rep_len - 1); - return; - } - } - - if (len_main < 2 || buf_avail <= 2) { - *back_res = UINT32_MAX; - *len_res = 1; - return; - } - - // Get the matches for the next byte. If we find a better match, - // the current byte is encoded as a literal. - coder->longest_match_length = mf_find(mf, - &coder->matches_count, coder->matches); - - if (coder->longest_match_length >= 2) { - const uint32_t new_dist = coder->matches[ - coder->matches_count - 1].dist; - - if ((coder->longest_match_length >= len_main - && new_dist < back_main) - || (coder->longest_match_length == len_main + 1 - && !change_pair(back_main, new_dist)) - || (coder->longest_match_length > len_main + 1) - || (coder->longest_match_length + 1 >= len_main - && len_main >= 3 - && change_pair(new_dist, back_main))) { - *back_res = UINT32_MAX; - *len_res = 1; - return; - } - } - - // In contrast to LZMA SDK, dictionary could not have been moved - // between mf_find() calls, thus it is safe to just increment - // the old buf pointer instead of recalculating it with mf_ptr(). - ++buf; - - const uint32_t limit = my_max(2, len_main - 1); - - for (uint32_t i = 0; i < REPS; ++i) { - if (memcmp(buf, buf - coder->reps[i] - 1, limit) == 0) { - *back_res = UINT32_MAX; - *len_res = 1; - return; - } - } - - *back_res = back_main + REPS; - *len_res = len_main; - mf_skip(mf, len_main - 2); - return; -} diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_optimum_normal.c b/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_optimum_normal.c deleted file mode 100755 index 59f77343..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_optimum_normal.c +++ /dev/null @@ -1,855 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_encoder_optimum_normal.c -// -// Author: Igor Pavlov -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "lzma_encoder_private.h" -#include "fastpos.h" -#include "memcmplen.h" - - -//////////// -// Prices // -//////////// - -static uint32_t -get_literal_price(const lzma_lzma1_encoder *const coder, const uint32_t pos, - const uint32_t prev_byte, const bool match_mode, - uint32_t match_byte, uint32_t symbol) -{ - const probability *const subcoder = literal_subcoder(coder->literal, - coder->literal_context_bits, coder->literal_pos_mask, - pos, prev_byte); - - uint32_t price = 0; - - if (!match_mode) { - price = rc_bittree_price(subcoder, 8, symbol); - } else { - uint32_t offset = 0x100; - symbol += UINT32_C(1) << 8; - - do { - match_byte <<= 1; - - const uint32_t match_bit = match_byte & offset; - const uint32_t subcoder_index - = offset + match_bit + (symbol >> 8); - const uint32_t bit = (symbol >> 7) & 1; - price += rc_bit_price(subcoder[subcoder_index], bit); - - symbol <<= 1; - offset &= ~(match_byte ^ symbol); - - } while (symbol < (UINT32_C(1) << 16)); - } - - return price; -} - - -static inline uint32_t -get_len_price(const lzma_length_encoder *const lencoder, - const uint32_t len, const uint32_t pos_state) -{ - // NOTE: Unlike the other price tables, length prices are updated - // in lzma_encoder.c - return lencoder->prices[pos_state][len - MATCH_LEN_MIN]; -} - - -static inline uint32_t -get_short_rep_price(const lzma_lzma1_encoder *const coder, - const lzma_lzma_state state, const uint32_t pos_state) -{ - return rc_bit_0_price(coder->is_rep0[state]) - + rc_bit_0_price(coder->is_rep0_long[state][pos_state]); -} - - -static inline uint32_t -get_pure_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index, - const lzma_lzma_state state, uint32_t pos_state) -{ - uint32_t price; - - if (rep_index == 0) { - price = rc_bit_0_price(coder->is_rep0[state]); - price += rc_bit_1_price(coder->is_rep0_long[state][pos_state]); - } else { - price = rc_bit_1_price(coder->is_rep0[state]); - - if (rep_index == 1) { - price += rc_bit_0_price(coder->is_rep1[state]); - } else { - price += rc_bit_1_price(coder->is_rep1[state]); - price += rc_bit_price(coder->is_rep2[state], - rep_index - 2); - } - } - - return price; -} - - -static inline uint32_t -get_rep_price(const lzma_lzma1_encoder *const coder, const uint32_t rep_index, - const uint32_t len, const lzma_lzma_state state, - const uint32_t pos_state) -{ - return get_len_price(&coder->rep_len_encoder, len, pos_state) - + get_pure_rep_price(coder, rep_index, state, pos_state); -} - - -static inline uint32_t -get_dist_len_price(const lzma_lzma1_encoder *const coder, const uint32_t dist, - const uint32_t len, const uint32_t pos_state) -{ - const uint32_t dist_state = get_dist_state(len); - uint32_t price; - - if (dist < FULL_DISTANCES) { - price = coder->dist_prices[dist_state][dist]; - } else { - const uint32_t dist_slot = get_dist_slot_2(dist); - price = coder->dist_slot_prices[dist_state][dist_slot] - + coder->align_prices[dist & ALIGN_MASK]; - } - - price += get_len_price(&coder->match_len_encoder, len, pos_state); - - return price; -} - - -static void -fill_dist_prices(lzma_lzma1_encoder *coder) -{ - for (uint32_t dist_state = 0; dist_state < DIST_STATES; ++dist_state) { - - uint32_t *const dist_slot_prices - = coder->dist_slot_prices[dist_state]; - - // Price to encode the dist_slot. - for (uint32_t dist_slot = 0; - dist_slot < coder->dist_table_size; ++dist_slot) - dist_slot_prices[dist_slot] = rc_bittree_price( - coder->dist_slot[dist_state], - DIST_SLOT_BITS, dist_slot); - - // For matches with distance >= FULL_DISTANCES, add the price - // of the direct bits part of the match distance. (Align bits - // are handled by fill_align_prices()). - for (uint32_t dist_slot = DIST_MODEL_END; - dist_slot < coder->dist_table_size; - ++dist_slot) - dist_slot_prices[dist_slot] += rc_direct_price( - ((dist_slot >> 1) - 1) - ALIGN_BITS); - - // Distances in the range [0, 3] are fully encoded with - // dist_slot, so they are used for coder->dist_prices - // as is. - for (uint32_t i = 0; i < DIST_MODEL_START; ++i) - coder->dist_prices[dist_state][i] - = dist_slot_prices[i]; - } - - // Distances in the range [4, 127] depend on dist_slot and - // dist_special. We do this in a loop separate from the above - // loop to avoid redundant calls to get_dist_slot(). - for (uint32_t i = DIST_MODEL_START; i < FULL_DISTANCES; ++i) { - const uint32_t dist_slot = get_dist_slot(i); - const uint32_t footer_bits = ((dist_slot >> 1) - 1); - const uint32_t base = (2 | (dist_slot & 1)) << footer_bits; - const uint32_t price = rc_bittree_reverse_price( - coder->dist_special + base - dist_slot - 1, - footer_bits, i - base); - - for (uint32_t dist_state = 0; dist_state < DIST_STATES; - ++dist_state) - coder->dist_prices[dist_state][i] - = price + coder->dist_slot_prices[ - dist_state][dist_slot]; - } - - coder->match_price_count = 0; - return; -} - - -static void -fill_align_prices(lzma_lzma1_encoder *coder) -{ - for (uint32_t i = 0; i < ALIGN_SIZE; ++i) - coder->align_prices[i] = rc_bittree_reverse_price( - coder->dist_align, ALIGN_BITS, i); - - coder->align_price_count = 0; - return; -} - - -///////////// -// Optimal // -///////////// - -static inline void -make_literal(lzma_optimal *optimal) -{ - optimal->back_prev = UINT32_MAX; - optimal->prev_1_is_literal = false; -} - - -static inline void -make_short_rep(lzma_optimal *optimal) -{ - optimal->back_prev = 0; - optimal->prev_1_is_literal = false; -} - - -#define is_short_rep(optimal) \ - ((optimal).back_prev == 0) - - -static void -backward(lzma_lzma1_encoder *restrict coder, uint32_t *restrict len_res, - uint32_t *restrict back_res, uint32_t cur) -{ - coder->opts_end_index = cur; - - uint32_t pos_mem = coder->opts[cur].pos_prev; - uint32_t back_mem = coder->opts[cur].back_prev; - - do { - if (coder->opts[cur].prev_1_is_literal) { - make_literal(&coder->opts[pos_mem]); - coder->opts[pos_mem].pos_prev = pos_mem - 1; - - if (coder->opts[cur].prev_2) { - coder->opts[pos_mem - 1].prev_1_is_literal - = false; - coder->opts[pos_mem - 1].pos_prev - = coder->opts[cur].pos_prev_2; - coder->opts[pos_mem - 1].back_prev - = coder->opts[cur].back_prev_2; - } - } - - const uint32_t pos_prev = pos_mem; - const uint32_t back_cur = back_mem; - - back_mem = coder->opts[pos_prev].back_prev; - pos_mem = coder->opts[pos_prev].pos_prev; - - coder->opts[pos_prev].back_prev = back_cur; - coder->opts[pos_prev].pos_prev = cur; - cur = pos_prev; - - } while (cur != 0); - - coder->opts_current_index = coder->opts[0].pos_prev; - *len_res = coder->opts[0].pos_prev; - *back_res = coder->opts[0].back_prev; - - return; -} - - -////////// -// Main // -////////// - -static inline uint32_t -helper1(lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, - uint32_t *restrict back_res, uint32_t *restrict len_res, - uint32_t position) -{ - const uint32_t nice_len = mf->nice_len; - - uint32_t len_main; - uint32_t matches_count; - - if (mf->read_ahead == 0) { - len_main = mf_find(mf, &matches_count, coder->matches); - } else { - assert(mf->read_ahead == 1); - len_main = coder->longest_match_length; - matches_count = coder->matches_count; - } - - const uint32_t buf_avail = my_min(mf_avail(mf) + 1, MATCH_LEN_MAX); - if (buf_avail < 2) { - *back_res = UINT32_MAX; - *len_res = 1; - return UINT32_MAX; - } - - const uint8_t *const buf = mf_ptr(mf) - 1; - - uint32_t rep_lens[REPS]; - uint32_t rep_max_index = 0; - - for (uint32_t i = 0; i < REPS; ++i) { - const uint8_t *const buf_back = buf - coder->reps[i] - 1; - - if (not_equal_16(buf, buf_back)) { - rep_lens[i] = 0; - continue; - } - - rep_lens[i] = lzma_memcmplen(buf, buf_back, 2, buf_avail); - - if (rep_lens[i] > rep_lens[rep_max_index]) - rep_max_index = i; - } - - if (rep_lens[rep_max_index] >= nice_len) { - *back_res = rep_max_index; - *len_res = rep_lens[rep_max_index]; - mf_skip(mf, *len_res - 1); - return UINT32_MAX; - } - - - if (len_main >= nice_len) { - *back_res = coder->matches[matches_count - 1].dist + REPS; - *len_res = len_main; - mf_skip(mf, len_main - 1); - return UINT32_MAX; - } - - const uint8_t current_byte = *buf; - const uint8_t match_byte = *(buf - coder->reps[0] - 1); - - if (len_main < 2 && current_byte != match_byte - && rep_lens[rep_max_index] < 2) { - *back_res = UINT32_MAX; - *len_res = 1; - return UINT32_MAX; - } - - coder->opts[0].state = coder->state; - - const uint32_t pos_state = position & coder->pos_mask; - - coder->opts[1].price = rc_bit_0_price( - coder->is_match[coder->state][pos_state]) - + get_literal_price(coder, position, buf[-1], - !is_literal_state(coder->state), - match_byte, current_byte); - - make_literal(&coder->opts[1]); - - const uint32_t match_price = rc_bit_1_price( - coder->is_match[coder->state][pos_state]); - const uint32_t rep_match_price = match_price - + rc_bit_1_price(coder->is_rep[coder->state]); - - if (match_byte == current_byte) { - const uint32_t short_rep_price = rep_match_price - + get_short_rep_price( - coder, coder->state, pos_state); - - if (short_rep_price < coder->opts[1].price) { - coder->opts[1].price = short_rep_price; - make_short_rep(&coder->opts[1]); - } - } - - const uint32_t len_end = my_max(len_main, rep_lens[rep_max_index]); - - if (len_end < 2) { - *back_res = coder->opts[1].back_prev; - *len_res = 1; - return UINT32_MAX; - } - - coder->opts[1].pos_prev = 0; - - for (uint32_t i = 0; i < REPS; ++i) - coder->opts[0].backs[i] = coder->reps[i]; - - uint32_t len = len_end; - do { - coder->opts[len].price = RC_INFINITY_PRICE; - } while (--len >= 2); - - - for (uint32_t i = 0; i < REPS; ++i) { - uint32_t rep_len = rep_lens[i]; - if (rep_len < 2) - continue; - - const uint32_t price = rep_match_price + get_pure_rep_price( - coder, i, coder->state, pos_state); - - do { - const uint32_t cur_and_len_price = price - + get_len_price( - &coder->rep_len_encoder, - rep_len, pos_state); - - if (cur_and_len_price < coder->opts[rep_len].price) { - coder->opts[rep_len].price = cur_and_len_price; - coder->opts[rep_len].pos_prev = 0; - coder->opts[rep_len].back_prev = i; - coder->opts[rep_len].prev_1_is_literal = false; - } - } while (--rep_len >= 2); - } - - - const uint32_t normal_match_price = match_price - + rc_bit_0_price(coder->is_rep[coder->state]); - - len = rep_lens[0] >= 2 ? rep_lens[0] + 1 : 2; - if (len <= len_main) { - uint32_t i = 0; - while (len > coder->matches[i].len) - ++i; - - for(; ; ++len) { - const uint32_t dist = coder->matches[i].dist; - const uint32_t cur_and_len_price = normal_match_price - + get_dist_len_price(coder, - dist, len, pos_state); - - if (cur_and_len_price < coder->opts[len].price) { - coder->opts[len].price = cur_and_len_price; - coder->opts[len].pos_prev = 0; - coder->opts[len].back_prev = dist + REPS; - coder->opts[len].prev_1_is_literal = false; - } - - if (len == coder->matches[i].len) - if (++i == matches_count) - break; - } - } - - return len_end; -} - - -static inline uint32_t -helper2(lzma_lzma1_encoder *coder, uint32_t *reps, const uint8_t *buf, - uint32_t len_end, uint32_t position, const uint32_t cur, - const uint32_t nice_len, const uint32_t buf_avail_full) -{ - uint32_t matches_count = coder->matches_count; - uint32_t new_len = coder->longest_match_length; - uint32_t pos_prev = coder->opts[cur].pos_prev; - lzma_lzma_state state; - - if (coder->opts[cur].prev_1_is_literal) { - --pos_prev; - - if (coder->opts[cur].prev_2) { - state = coder->opts[coder->opts[cur].pos_prev_2].state; - - if (coder->opts[cur].back_prev_2 < REPS) - update_long_rep(state); - else - update_match(state); - - } else { - state = coder->opts[pos_prev].state; - } - - update_literal(state); - - } else { - state = coder->opts[pos_prev].state; - } - - if (pos_prev == cur - 1) { - if (is_short_rep(coder->opts[cur])) - update_short_rep(state); - else - update_literal(state); - } else { - uint32_t pos; - if (coder->opts[cur].prev_1_is_literal - && coder->opts[cur].prev_2) { - pos_prev = coder->opts[cur].pos_prev_2; - pos = coder->opts[cur].back_prev_2; - update_long_rep(state); - } else { - pos = coder->opts[cur].back_prev; - if (pos < REPS) - update_long_rep(state); - else - update_match(state); - } - - if (pos < REPS) { - reps[0] = coder->opts[pos_prev].backs[pos]; - - uint32_t i; - for (i = 1; i <= pos; ++i) - reps[i] = coder->opts[pos_prev].backs[i - 1]; - - for (; i < REPS; ++i) - reps[i] = coder->opts[pos_prev].backs[i]; - - } else { - reps[0] = pos - REPS; - - for (uint32_t i = 1; i < REPS; ++i) - reps[i] = coder->opts[pos_prev].backs[i - 1]; - } - } - - coder->opts[cur].state = state; - - for (uint32_t i = 0; i < REPS; ++i) - coder->opts[cur].backs[i] = reps[i]; - - const uint32_t cur_price = coder->opts[cur].price; - - const uint8_t current_byte = *buf; - const uint8_t match_byte = *(buf - reps[0] - 1); - - const uint32_t pos_state = position & coder->pos_mask; - - const uint32_t cur_and_1_price = cur_price - + rc_bit_0_price(coder->is_match[state][pos_state]) - + get_literal_price(coder, position, buf[-1], - !is_literal_state(state), match_byte, current_byte); - - bool next_is_literal = false; - - if (cur_and_1_price < coder->opts[cur + 1].price) { - coder->opts[cur + 1].price = cur_and_1_price; - coder->opts[cur + 1].pos_prev = cur; - make_literal(&coder->opts[cur + 1]); - next_is_literal = true; - } - - const uint32_t match_price = cur_price - + rc_bit_1_price(coder->is_match[state][pos_state]); - const uint32_t rep_match_price = match_price - + rc_bit_1_price(coder->is_rep[state]); - - if (match_byte == current_byte - && !(coder->opts[cur + 1].pos_prev < cur - && coder->opts[cur + 1].back_prev == 0)) { - - const uint32_t short_rep_price = rep_match_price - + get_short_rep_price(coder, state, pos_state); - - if (short_rep_price <= coder->opts[cur + 1].price) { - coder->opts[cur + 1].price = short_rep_price; - coder->opts[cur + 1].pos_prev = cur; - make_short_rep(&coder->opts[cur + 1]); - next_is_literal = true; - } - } - - if (buf_avail_full < 2) - return len_end; - - const uint32_t buf_avail = my_min(buf_avail_full, nice_len); - - if (!next_is_literal && match_byte != current_byte) { // speed optimization - // try literal + rep0 - const uint8_t *const buf_back = buf - reps[0] - 1; - const uint32_t limit = my_min(buf_avail_full, nice_len + 1); - - const uint32_t len_test = lzma_memcmplen(buf, buf_back, 1, limit) - 1; - - if (len_test >= 2) { - lzma_lzma_state state_2 = state; - update_literal(state_2); - - const uint32_t pos_state_next = (position + 1) & coder->pos_mask; - const uint32_t next_rep_match_price = cur_and_1_price - + rc_bit_1_price(coder->is_match[state_2][pos_state_next]) - + rc_bit_1_price(coder->is_rep[state_2]); - - //for (; len_test >= 2; --len_test) { - const uint32_t offset = cur + 1 + len_test; - - while (len_end < offset) - coder->opts[++len_end].price = RC_INFINITY_PRICE; - - const uint32_t cur_and_len_price = next_rep_match_price - + get_rep_price(coder, 0, len_test, - state_2, pos_state_next); - - if (cur_and_len_price < coder->opts[offset].price) { - coder->opts[offset].price = cur_and_len_price; - coder->opts[offset].pos_prev = cur + 1; - coder->opts[offset].back_prev = 0; - coder->opts[offset].prev_1_is_literal = true; - coder->opts[offset].prev_2 = false; - } - //} - } - } - - - uint32_t start_len = 2; // speed optimization - - for (uint32_t rep_index = 0; rep_index < REPS; ++rep_index) { - const uint8_t *const buf_back = buf - reps[rep_index] - 1; - if (not_equal_16(buf, buf_back)) - continue; - - uint32_t len_test = lzma_memcmplen(buf, buf_back, 2, buf_avail); - - while (len_end < cur + len_test) - coder->opts[++len_end].price = RC_INFINITY_PRICE; - - const uint32_t len_test_temp = len_test; - const uint32_t price = rep_match_price + get_pure_rep_price( - coder, rep_index, state, pos_state); - - do { - const uint32_t cur_and_len_price = price - + get_len_price(&coder->rep_len_encoder, - len_test, pos_state); - - if (cur_and_len_price < coder->opts[cur + len_test].price) { - coder->opts[cur + len_test].price = cur_and_len_price; - coder->opts[cur + len_test].pos_prev = cur; - coder->opts[cur + len_test].back_prev = rep_index; - coder->opts[cur + len_test].prev_1_is_literal = false; - } - } while (--len_test >= 2); - - len_test = len_test_temp; - - if (rep_index == 0) - start_len = len_test + 1; - - - uint32_t len_test_2 = len_test + 1; - const uint32_t limit = my_min(buf_avail_full, - len_test_2 + nice_len); - for (; len_test_2 < limit - && buf[len_test_2] == buf_back[len_test_2]; - ++len_test_2) ; - - len_test_2 -= len_test + 1; - - if (len_test_2 >= 2) { - lzma_lzma_state state_2 = state; - update_long_rep(state_2); - - uint32_t pos_state_next = (position + len_test) & coder->pos_mask; - - const uint32_t cur_and_len_literal_price = price - + get_len_price(&coder->rep_len_encoder, - len_test, pos_state) - + rc_bit_0_price(coder->is_match[state_2][pos_state_next]) - + get_literal_price(coder, position + len_test, - buf[len_test - 1], true, - buf_back[len_test], buf[len_test]); - - update_literal(state_2); - - pos_state_next = (position + len_test + 1) & coder->pos_mask; - - const uint32_t next_rep_match_price = cur_and_len_literal_price - + rc_bit_1_price(coder->is_match[state_2][pos_state_next]) - + rc_bit_1_price(coder->is_rep[state_2]); - - //for(; len_test_2 >= 2; len_test_2--) { - const uint32_t offset = cur + len_test + 1 + len_test_2; - - while (len_end < offset) - coder->opts[++len_end].price = RC_INFINITY_PRICE; - - const uint32_t cur_and_len_price = next_rep_match_price - + get_rep_price(coder, 0, len_test_2, - state_2, pos_state_next); - - if (cur_and_len_price < coder->opts[offset].price) { - coder->opts[offset].price = cur_and_len_price; - coder->opts[offset].pos_prev = cur + len_test + 1; - coder->opts[offset].back_prev = 0; - coder->opts[offset].prev_1_is_literal = true; - coder->opts[offset].prev_2 = true; - coder->opts[offset].pos_prev_2 = cur; - coder->opts[offset].back_prev_2 = rep_index; - } - //} - } - } - - - //for (uint32_t len_test = 2; len_test <= new_len; ++len_test) - if (new_len > buf_avail) { - new_len = buf_avail; - - matches_count = 0; - while (new_len > coder->matches[matches_count].len) - ++matches_count; - - coder->matches[matches_count++].len = new_len; - } - - - if (new_len >= start_len) { - const uint32_t normal_match_price = match_price - + rc_bit_0_price(coder->is_rep[state]); - - while (len_end < cur + new_len) - coder->opts[++len_end].price = RC_INFINITY_PRICE; - - uint32_t i = 0; - while (start_len > coder->matches[i].len) - ++i; - - for (uint32_t len_test = start_len; ; ++len_test) { - const uint32_t cur_back = coder->matches[i].dist; - uint32_t cur_and_len_price = normal_match_price - + get_dist_len_price(coder, - cur_back, len_test, pos_state); - - if (cur_and_len_price < coder->opts[cur + len_test].price) { - coder->opts[cur + len_test].price = cur_and_len_price; - coder->opts[cur + len_test].pos_prev = cur; - coder->opts[cur + len_test].back_prev - = cur_back + REPS; - coder->opts[cur + len_test].prev_1_is_literal = false; - } - - if (len_test == coder->matches[i].len) { - // Try Match + Literal + Rep0 - const uint8_t *const buf_back = buf - cur_back - 1; - uint32_t len_test_2 = len_test + 1; - const uint32_t limit = my_min(buf_avail_full, - len_test_2 + nice_len); - - for (; len_test_2 < limit && - buf[len_test_2] == buf_back[len_test_2]; - ++len_test_2) ; - - len_test_2 -= len_test + 1; - - if (len_test_2 >= 2) { - lzma_lzma_state state_2 = state; - update_match(state_2); - uint32_t pos_state_next - = (position + len_test) & coder->pos_mask; - - const uint32_t cur_and_len_literal_price = cur_and_len_price - + rc_bit_0_price( - coder->is_match[state_2][pos_state_next]) - + get_literal_price(coder, - position + len_test, - buf[len_test - 1], - true, - buf_back[len_test], - buf[len_test]); - - update_literal(state_2); - pos_state_next = (pos_state_next + 1) & coder->pos_mask; - - const uint32_t next_rep_match_price - = cur_and_len_literal_price - + rc_bit_1_price( - coder->is_match[state_2][pos_state_next]) - + rc_bit_1_price(coder->is_rep[state_2]); - - // for(; len_test_2 >= 2; --len_test_2) { - const uint32_t offset = cur + len_test + 1 + len_test_2; - - while (len_end < offset) - coder->opts[++len_end].price = RC_INFINITY_PRICE; - - cur_and_len_price = next_rep_match_price - + get_rep_price(coder, 0, len_test_2, - state_2, pos_state_next); - - if (cur_and_len_price < coder->opts[offset].price) { - coder->opts[offset].price = cur_and_len_price; - coder->opts[offset].pos_prev = cur + len_test + 1; - coder->opts[offset].back_prev = 0; - coder->opts[offset].prev_1_is_literal = true; - coder->opts[offset].prev_2 = true; - coder->opts[offset].pos_prev_2 = cur; - coder->opts[offset].back_prev_2 - = cur_back + REPS; - } - //} - } - - if (++i == matches_count) - break; - } - } - } - - return len_end; -} - - -extern void -lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder, - lzma_mf *restrict mf, - uint32_t *restrict back_res, uint32_t *restrict len_res, - uint32_t position) -{ - // If we have symbols pending, return the next pending symbol. - if (coder->opts_end_index != coder->opts_current_index) { - assert(mf->read_ahead > 0); - *len_res = coder->opts[coder->opts_current_index].pos_prev - - coder->opts_current_index; - *back_res = coder->opts[coder->opts_current_index].back_prev; - coder->opts_current_index = coder->opts[ - coder->opts_current_index].pos_prev; - return; - } - - // Update the price tables. In LZMA SDK <= 4.60 (and possibly later) - // this was done in both initialization function and in the main loop. - // In liblzma they were moved into this single place. - if (mf->read_ahead == 0) { - if (coder->match_price_count >= (1 << 7)) - fill_dist_prices(coder); - - if (coder->align_price_count >= ALIGN_SIZE) - fill_align_prices(coder); - } - - // TODO: This needs quite a bit of cleaning still. But splitting - // the original function into two pieces makes it at least a little - // more readable, since those two parts don't share many variables. - - uint32_t len_end = helper1(coder, mf, back_res, len_res, position); - if (len_end == UINT32_MAX) - return; - - uint32_t reps[REPS]; - memcpy(reps, coder->reps, sizeof(reps)); - - uint32_t cur; - for (cur = 1; cur < len_end; ++cur) { - assert(cur < OPTS); - - coder->longest_match_length = mf_find( - mf, &coder->matches_count, coder->matches); - - if (coder->longest_match_length >= mf->nice_len) - break; - - len_end = helper2(coder, reps, mf_ptr(mf) - 1, len_end, - position + cur, cur, mf->nice_len, - my_min(mf_avail(mf) + 1, OPTS - 1 - cur)); - } - - backward(coder, len_res, back_res, cur); - return; -} diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_presets.c b/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_presets.c deleted file mode 100755 index 711df025..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_presets.c +++ /dev/null @@ -1,64 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_encoder_presets.c -/// \brief Encoder presets -/// \note xz needs this even when only decoding is enabled. -// -// Author: Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#include "common.h" - - -extern LZMA_API(lzma_bool) -lzma_lzma_preset(lzma_options_lzma *options, uint32_t preset) -{ - const uint32_t level = preset & LZMA_PRESET_LEVEL_MASK; - const uint32_t flags = preset & ~LZMA_PRESET_LEVEL_MASK; - const uint32_t supported_flags = LZMA_PRESET_EXTREME; - - if (level > 9 || (flags & ~supported_flags)) - return true; - - options->preset_dict = NULL; - options->preset_dict_size = 0; - - options->lc = LZMA_LC_DEFAULT; - options->lp = LZMA_LP_DEFAULT; - options->pb = LZMA_PB_DEFAULT; - - static const uint8_t dict_pow2[] - = { 18, 20, 21, 22, 22, 23, 23, 24, 25, 26 }; - options->dict_size = UINT32_C(1) << dict_pow2[level]; - - if (level <= 3) { - options->mode = LZMA_MODE_FAST; - options->mf = level == 0 ? LZMA_MF_HC3 : LZMA_MF_HC4; - options->nice_len = level <= 1 ? 128 : 273; - static const uint8_t depths[] = { 4, 8, 24, 48 }; - options->depth = depths[level]; - } else { - options->mode = LZMA_MODE_NORMAL; - options->mf = LZMA_MF_BT4; - options->nice_len = level == 4 ? 16 : level == 5 ? 32 : 64; - options->depth = 0; - } - - if (flags & LZMA_PRESET_EXTREME) { - options->mode = LZMA_MODE_NORMAL; - options->mf = LZMA_MF_BT4; - if (level == 3 || level == 5) { - options->nice_len = 192; - options->depth = 0; - } else { - options->nice_len = 273; - options->depth = 512; - } - } - - return false; -} diff --git a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_private.h b/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_private.h deleted file mode 100755 index a2da969f..00000000 --- a/game/client/third/minizip/lib/liblzma/lzma/lzma_encoder_private.h +++ /dev/null @@ -1,148 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file lzma_encoder_private.h -/// \brief Private definitions for LZMA encoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_LZMA_ENCODER_PRIVATE_H -#define LZMA_LZMA_ENCODER_PRIVATE_H - -#include "lz_encoder.h" -#include "range_encoder.h" -#include "lzma_common.h" -#include "lzma_encoder.h" - - -// Macro to compare if the first two bytes in two buffers differ. This is -// needed in lzma_lzma_optimum_*() to test if the match is at least -// MATCH_LEN_MIN bytes. Unaligned access gives tiny gain so there's no -// reason to not use it when it is supported. -#ifdef TUKLIB_FAST_UNALIGNED_ACCESS -# define not_equal_16(a, b) \ - (*(const uint16_t *)(a) != *(const uint16_t *)(b)) -#else -# define not_equal_16(a, b) \ - ((a)[0] != (b)[0] || (a)[1] != (b)[1]) -#endif - - -// Optimal - Number of entries in the optimum array. -#define OPTS (1 << 12) - - -typedef struct { - probability choice; - probability choice2; - probability low[POS_STATES_MAX][LEN_LOW_SYMBOLS]; - probability mid[POS_STATES_MAX][LEN_MID_SYMBOLS]; - probability high[LEN_HIGH_SYMBOLS]; - - uint32_t prices[POS_STATES_MAX][LEN_SYMBOLS]; - uint32_t table_size; - uint32_t counters[POS_STATES_MAX]; - -} lzma_length_encoder; - - -typedef struct { - lzma_lzma_state state; - - bool prev_1_is_literal; - bool prev_2; - - uint32_t pos_prev_2; - uint32_t back_prev_2; - - uint32_t price; - uint32_t pos_prev; // pos_next; - uint32_t back_prev; - - uint32_t backs[REPS]; - -} lzma_optimal; - - -struct lzma_lzma1_encoder_s { - /// Range encoder - lzma_range_encoder rc; - - /// State - lzma_lzma_state state; - - /// The four most recent match distances - uint32_t reps[REPS]; - - /// Array of match candidates - lzma_match matches[MATCH_LEN_MAX + 1]; - - /// Number of match candidates in matches[] - uint32_t matches_count; - - /// Variable to hold the length of the longest match between calls - /// to lzma_lzma_optimum_*(). - uint32_t longest_match_length; - - /// True if using getoptimumfast - bool fast_mode; - - /// True if the encoder has been initialized by encoding the first - /// byte as a literal. - bool is_initialized; - - /// True if the range encoder has been flushed, but not all bytes - /// have been written to the output buffer yet. - bool is_flushed; - - uint32_t pos_mask; ///< (1 << pos_bits) - 1 - uint32_t literal_context_bits; - uint32_t literal_pos_mask; - - // These are the same as in lzma_decoder.c. See comments there. - probability literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; - probability is_match[STATES][POS_STATES_MAX]; - probability is_rep[STATES]; - probability is_rep0[STATES]; - probability is_rep1[STATES]; - probability is_rep2[STATES]; - probability is_rep0_long[STATES][POS_STATES_MAX]; - probability dist_slot[DIST_STATES][DIST_SLOTS]; - probability dist_special[FULL_DISTANCES - DIST_MODEL_END]; - probability dist_align[ALIGN_SIZE]; - - // These are the same as in lzma_decoder.c except that the encoders - // include also price tables. - lzma_length_encoder match_len_encoder; - lzma_length_encoder rep_len_encoder; - - // Price tables - uint32_t dist_slot_prices[DIST_STATES][DIST_SLOTS]; - uint32_t dist_prices[DIST_STATES][FULL_DISTANCES]; - uint32_t dist_table_size; - uint32_t match_price_count; - - uint32_t align_prices[ALIGN_SIZE]; - uint32_t align_price_count; - - // Optimal - uint32_t opts_end_index; - uint32_t opts_current_index; - lzma_optimal opts[OPTS]; -}; - - -extern void lzma_lzma_optimum_fast( - lzma_lzma1_encoder *restrict coder, lzma_mf *restrict mf, - uint32_t *restrict back_res, uint32_t *restrict len_res); - -extern void lzma_lzma_optimum_normal(lzma_lzma1_encoder *restrict coder, - lzma_mf *restrict mf, uint32_t *restrict back_res, - uint32_t *restrict len_res, uint32_t position); - -#endif diff --git a/game/client/third/minizip/lib/liblzma/rangecoder/price.h b/game/client/third/minizip/lib/liblzma/rangecoder/price.h deleted file mode 100755 index 8ae02ca7..00000000 --- a/game/client/third/minizip/lib/liblzma/rangecoder/price.h +++ /dev/null @@ -1,92 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file price.h -/// \brief Probability price calculation -// -// Author: Igor Pavlov -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_PRICE_H -#define LZMA_PRICE_H - - -#define RC_MOVE_REDUCING_BITS 4 -#define RC_BIT_PRICE_SHIFT_BITS 4 -#define RC_PRICE_TABLE_SIZE (RC_BIT_MODEL_TOTAL >> RC_MOVE_REDUCING_BITS) - -#define RC_INFINITY_PRICE (UINT32_C(1) << 30) - - -/// Lookup table for the inline functions defined in this file. -extern const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE]; - - -static inline uint32_t -rc_bit_price(const probability prob, const uint32_t bit) -{ - return lzma_rc_prices[(prob ^ ((UINT32_C(0) - bit) - & (RC_BIT_MODEL_TOTAL - 1))) >> RC_MOVE_REDUCING_BITS]; -} - - -static inline uint32_t -rc_bit_0_price(const probability prob) -{ - return lzma_rc_prices[prob >> RC_MOVE_REDUCING_BITS]; -} - - -static inline uint32_t -rc_bit_1_price(const probability prob) -{ - return lzma_rc_prices[(prob ^ (RC_BIT_MODEL_TOTAL - 1)) - >> RC_MOVE_REDUCING_BITS]; -} - - -static inline uint32_t -rc_bittree_price(const probability *const probs, - const uint32_t bit_levels, uint32_t symbol) -{ - uint32_t price = 0; - symbol += UINT32_C(1) << bit_levels; - - do { - const uint32_t bit = symbol & 1; - symbol >>= 1; - price += rc_bit_price(probs[symbol], bit); - } while (symbol != 1); - - return price; -} - - -static inline uint32_t -rc_bittree_reverse_price(const probability *const probs, - uint32_t bit_levels, uint32_t symbol) -{ - uint32_t price = 0; - uint32_t model_index = 1; - - do { - const uint32_t bit = symbol & 1; - symbol >>= 1; - price += rc_bit_price(probs[model_index], bit); - model_index = (model_index << 1) + bit; - } while (--bit_levels != 0); - - return price; -} - - -static inline uint32_t -rc_direct_price(const uint32_t bits) -{ - return bits << RC_BIT_PRICE_SHIFT_BITS; -} - -#endif diff --git a/game/client/third/minizip/lib/liblzma/rangecoder/price_table.c b/game/client/third/minizip/lib/liblzma/rangecoder/price_table.c deleted file mode 100755 index ac64bf62..00000000 --- a/game/client/third/minizip/lib/liblzma/rangecoder/price_table.c +++ /dev/null @@ -1,22 +0,0 @@ -/* This file has been automatically generated by price_tablegen.c. */ - -#include "range_encoder.h" - -const uint8_t lzma_rc_prices[RC_PRICE_TABLE_SIZE] = { - 128, 103, 91, 84, 78, 73, 69, 66, - 63, 61, 58, 56, 54, 52, 51, 49, - 48, 46, 45, 44, 43, 42, 41, 40, - 39, 38, 37, 36, 35, 34, 34, 33, - 32, 31, 31, 30, 29, 29, 28, 28, - 27, 26, 26, 25, 25, 24, 24, 23, - 23, 22, 22, 22, 21, 21, 20, 20, - 19, 19, 19, 18, 18, 17, 17, 17, - 16, 16, 16, 15, 15, 15, 14, 14, - 14, 13, 13, 13, 12, 12, 12, 11, - 11, 11, 11, 10, 10, 10, 10, 9, - 9, 9, 9, 8, 8, 8, 8, 7, - 7, 7, 7, 6, 6, 6, 6, 5, - 5, 5, 5, 5, 4, 4, 4, 4, - 3, 3, 3, 3, 3, 2, 2, 2, - 2, 2, 2, 1, 1, 1, 1, 1 -}; diff --git a/game/client/third/minizip/lib/liblzma/rangecoder/range_common.h b/game/client/third/minizip/lib/liblzma/rangecoder/range_common.h deleted file mode 100755 index 0e642419..00000000 --- a/game/client/third/minizip/lib/liblzma/rangecoder/range_common.h +++ /dev/null @@ -1,73 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file range_common.h -/// \brief Common things for range encoder and decoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_RANGE_COMMON_H -#define LZMA_RANGE_COMMON_H - -#ifdef HAVE_CONFIG_H -# include "common.h" -#endif - - -/////////////// -// Constants // -/////////////// - -#define RC_SHIFT_BITS 8 -#define RC_TOP_BITS 24 -#define RC_TOP_VALUE (UINT32_C(1) << RC_TOP_BITS) -#define RC_BIT_MODEL_TOTAL_BITS 11 -#define RC_BIT_MODEL_TOTAL (UINT32_C(1) << RC_BIT_MODEL_TOTAL_BITS) -#define RC_MOVE_BITS 5 - - -//////////// -// Macros // -//////////// - -// Resets the probability so that both 0 and 1 have probability of 50 % -#define bit_reset(prob) \ - prob = RC_BIT_MODEL_TOTAL >> 1 - -// This does the same for a complete bit tree. -// (A tree represented as an array.) -#define bittree_reset(probs, bit_levels) \ - for (uint32_t bt_i = 0; bt_i < (1 << (bit_levels)); ++bt_i) \ - bit_reset((probs)[bt_i]) - - -////////////////////// -// Type definitions // -////////////////////// - -/// \brief Type of probabilities used with range coder -/// -/// This needs to be at least 12-bit integer, so uint16_t is a logical choice. -/// However, on some architecture and compiler combinations, a bigger type -/// may give better speed, because the probability variables are accessed -/// a lot. On the other hand, bigger probability type increases cache -/// footprint, since there are 2 to 14 thousand probability variables in -/// LZMA (assuming the limit of lc + lp <= 4; with lc + lp <= 12 there -/// would be about 1.5 million variables). -/// -/// With malicious files, the initialization speed of the LZMA decoder can -/// become important. In that case, smaller probability variables mean that -/// there is less bytes to write to RAM, which makes initialization faster. -/// With big probability type, the initialization can become so slow that it -/// can be a problem e.g. for email servers doing virus scanning. -/// -/// I will be sticking to uint16_t unless some specific architectures -/// are *much* faster (20-50 %) with uint32_t. -typedef uint16_t probability; - -#endif diff --git a/game/client/third/minizip/lib/liblzma/rangecoder/range_decoder.h b/game/client/third/minizip/lib/liblzma/rangecoder/range_decoder.h deleted file mode 100755 index e0b051fa..00000000 --- a/game/client/third/minizip/lib/liblzma/rangecoder/range_decoder.h +++ /dev/null @@ -1,185 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file range_decoder.h -/// \brief Range Decoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_RANGE_DECODER_H -#define LZMA_RANGE_DECODER_H - -#include "range_common.h" - - -typedef struct { - uint32_t range; - uint32_t code; - uint32_t init_bytes_left; -} lzma_range_decoder; - - -/// Reads the first five bytes to initialize the range decoder. -static inline lzma_ret -rc_read_init(lzma_range_decoder *rc, const uint8_t *restrict in, - size_t *restrict in_pos, size_t in_size) -{ - while (rc->init_bytes_left > 0) { - if (*in_pos == in_size) - return LZMA_OK; - - // The first byte is always 0x00. It could have been omitted - // in LZMA2 but it wasn't, so one byte is wasted in every - // LZMA2 chunk. - if (rc->init_bytes_left == 5 && in[*in_pos] != 0x00) - return LZMA_DATA_ERROR; - - rc->code = (rc->code << 8) | in[*in_pos]; - ++*in_pos; - --rc->init_bytes_left; - } - - return LZMA_STREAM_END; -} - - -/// Makes local copies of range decoder and *in_pos variables. Doing this -/// improves speed significantly. The range decoder macros expect also -/// variables `in' and `in_size' to be defined. -#define rc_to_local(range_decoder, in_pos) \ - lzma_range_decoder rc = range_decoder; \ - size_t rc_in_pos = (in_pos); \ - uint32_t rc_bound - - -/// Stores the local copes back to the range decoder structure. -#define rc_from_local(range_decoder, in_pos) \ -do { \ - range_decoder = rc; \ - in_pos = rc_in_pos; \ -} while (0) - - -/// Resets the range decoder structure. -#define rc_reset(range_decoder) \ -do { \ - (range_decoder).range = UINT32_MAX; \ - (range_decoder).code = 0; \ - (range_decoder).init_bytes_left = 5; \ -} while (0) - - -/// When decoding has been properly finished, rc.code is always zero unless -/// the input stream is corrupt. So checking this can catch some corrupt -/// files especially if they don't have any other integrity check. -#define rc_is_finished(range_decoder) \ - ((range_decoder).code == 0) - - -/// Read the next input byte if needed. If more input is needed but there is -/// no more input available, "goto out" is used to jump out of the main -/// decoder loop. -#define rc_normalize(seq) \ -do { \ - if (rc.range < RC_TOP_VALUE) { \ - if (unlikely(rc_in_pos == in_size)) { \ - coder->sequence = seq; \ - goto out; \ - } \ - rc.range <<= RC_SHIFT_BITS; \ - rc.code = (rc.code << RC_SHIFT_BITS) | in[rc_in_pos++]; \ - } \ -} while (0) - - -/// Start decoding a bit. This must be used together with rc_update_0() -/// and rc_update_1(): -/// -/// rc_if_0(prob, seq) { -/// rc_update_0(prob); -/// // Do something -/// } else { -/// rc_update_1(prob); -/// // Do something else -/// } -/// -#define rc_if_0(prob, seq) \ - rc_normalize(seq); \ - rc_bound = (rc.range >> RC_BIT_MODEL_TOTAL_BITS) * (prob); \ - if (rc.code < rc_bound) - - -/// Update the range decoder state and the used probability variable to -/// match a decoded bit of 0. -#define rc_update_0(prob) \ -do { \ - rc.range = rc_bound; \ - prob += (RC_BIT_MODEL_TOTAL - (prob)) >> RC_MOVE_BITS; \ -} while (0) - - -/// Update the range decoder state and the used probability variable to -/// match a decoded bit of 1. -#define rc_update_1(prob) \ -do { \ - rc.range -= rc_bound; \ - rc.code -= rc_bound; \ - prob -= (prob) >> RC_MOVE_BITS; \ -} while (0) - - -/// Decodes one bit and runs action0 or action1 depending on the decoded bit. -/// This macro is used as the last step in bittree reverse decoders since -/// those don't use "symbol" for anything else than indexing the probability -/// arrays. -#define rc_bit_last(prob, action0, action1, seq) \ -do { \ - rc_if_0(prob, seq) { \ - rc_update_0(prob); \ - action0; \ - } else { \ - rc_update_1(prob); \ - action1; \ - } \ -} while (0) - - -/// Decodes one bit, updates "symbol", and runs action0 or action1 depending -/// on the decoded bit. -#define rc_bit(prob, action0, action1, seq) \ - rc_bit_last(prob, \ - symbol <<= 1; action0, \ - symbol = (symbol << 1) + 1; action1, \ - seq); - - -/// Like rc_bit() but add "case seq:" as a prefix. This makes the unrolled -/// loops more readable because the code isn't littered with "case" -/// statements. On the other hand this also makes it less readable, since -/// spotting the places where the decoder loop may be restarted is less -/// obvious. -#define rc_bit_case(prob, action0, action1, seq) \ - case seq: rc_bit(prob, action0, action1, seq) - - -/// Decode a bit without using a probability. -#define rc_direct(dest, seq) \ -do { \ - rc_normalize(seq); \ - rc.range >>= 1; \ - rc.code -= rc.range; \ - rc_bound = UINT32_C(0) - (rc.code >> 31); \ - rc.code += rc.range & rc_bound; \ - dest = (dest << 1) + (rc_bound + 1); \ -} while (0) - - -// NOTE: No macros are provided for bittree decoding. It seems to be simpler -// to just write them open in the code. - -#endif diff --git a/game/client/third/minizip/lib/liblzma/rangecoder/range_encoder.h b/game/client/third/minizip/lib/liblzma/rangecoder/range_encoder.h deleted file mode 100755 index 1e1c3699..00000000 --- a/game/client/third/minizip/lib/liblzma/rangecoder/range_encoder.h +++ /dev/null @@ -1,231 +0,0 @@ -/////////////////////////////////////////////////////////////////////////////// -// -/// \file range_encoder.h -/// \brief Range Encoder -/// -// Authors: Igor Pavlov -// Lasse Collin -// -// This file has been put into the public domain. -// You can do whatever you want with this file. -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef LZMA_RANGE_ENCODER_H -#define LZMA_RANGE_ENCODER_H - -#include "range_common.h" -#include "price.h" - - -/// Maximum number of symbols that can be put pending into lzma_range_encoder -/// structure between calls to lzma_rc_encode(). For LZMA, 52+5 is enough -/// (match with big distance and length followed by range encoder flush). -#define RC_SYMBOLS_MAX 58 - - -typedef struct { - uint64_t low; - uint64_t cache_size; - uint32_t range; - uint8_t cache; - - /// Number of symbols in the tables - size_t count; - - /// rc_encode()'s position in the tables - size_t pos; - - /// Symbols to encode - enum { - RC_BIT_0, - RC_BIT_1, - RC_DIRECT_0, - RC_DIRECT_1, - RC_FLUSH, - } symbols[RC_SYMBOLS_MAX]; - - /// Probabilities associated with RC_BIT_0 or RC_BIT_1 - probability *probs[RC_SYMBOLS_MAX]; - -} lzma_range_encoder; - - -static inline void -rc_reset(lzma_range_encoder *rc) -{ - rc->low = 0; - rc->cache_size = 1; - rc->range = UINT32_MAX; - rc->cache = 0; - rc->count = 0; - rc->pos = 0; -} - - -static inline void -rc_bit(lzma_range_encoder *rc, probability *prob, uint32_t bit) -{ - rc->symbols[rc->count] = bit; - rc->probs[rc->count] = prob; - ++rc->count; -} - - -static inline void -rc_bittree(lzma_range_encoder *rc, probability *probs, - uint32_t bit_count, uint32_t symbol) -{ - uint32_t model_index = 1; - - do { - const uint32_t bit = (symbol >> --bit_count) & 1; - rc_bit(rc, &probs[model_index], bit); - model_index = (model_index << 1) + bit; - } while (bit_count != 0); -} - - -static inline void -rc_bittree_reverse(lzma_range_encoder *rc, probability *probs, - uint32_t bit_count, uint32_t symbol) -{ - uint32_t model_index = 1; - - do { - const uint32_t bit = symbol & 1; - symbol >>= 1; - rc_bit(rc, &probs[model_index], bit); - model_index = (model_index << 1) + bit; - } while (--bit_count != 0); -} - - -static inline void -rc_direct(lzma_range_encoder *rc, - uint32_t value, uint32_t bit_count) -{ - do { - rc->symbols[rc->count++] - = RC_DIRECT_0 + ((value >> --bit_count) & 1); - } while (bit_count != 0); -} - - -static inline void -rc_flush(lzma_range_encoder *rc) -{ - for (size_t i = 0; i < 5; ++i) - rc->symbols[rc->count++] = RC_FLUSH; -} - - -static inline bool -rc_shift_low(lzma_range_encoder *rc, - uint8_t *out, size_t *out_pos, size_t out_size) -{ - if ((uint32_t)(rc->low) < (uint32_t)(0xFF000000) - || (uint32_t)(rc->low >> 32) != 0) { - do { - if (*out_pos == out_size) - return true; - - out[*out_pos] = rc->cache + (uint8_t)(rc->low >> 32); - ++*out_pos; - rc->cache = 0xFF; - - } while (--rc->cache_size != 0); - - rc->cache = (rc->low >> 24) & 0xFF; - } - - ++rc->cache_size; - rc->low = (rc->low & 0x00FFFFFF) << RC_SHIFT_BITS; - - return false; -} - - -static inline bool -rc_encode(lzma_range_encoder *rc, - uint8_t *out, size_t *out_pos, size_t out_size) -{ - assert(rc->count <= RC_SYMBOLS_MAX); - - while (rc->pos < rc->count) { - // Normalize - if (rc->range < RC_TOP_VALUE) { - if (rc_shift_low(rc, out, out_pos, out_size)) - return true; - - rc->range <<= RC_SHIFT_BITS; - } - - // Encode a bit - switch (rc->symbols[rc->pos]) { - case RC_BIT_0: { - probability prob = *rc->probs[rc->pos]; - rc->range = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) - * prob; - prob += (RC_BIT_MODEL_TOTAL - prob) >> RC_MOVE_BITS; - *rc->probs[rc->pos] = prob; - break; - } - - case RC_BIT_1: { - probability prob = *rc->probs[rc->pos]; - const uint32_t bound = prob * (rc->range - >> RC_BIT_MODEL_TOTAL_BITS); - rc->low += bound; - rc->range -= bound; - prob -= prob >> RC_MOVE_BITS; - *rc->probs[rc->pos] = prob; - break; - } - - case RC_DIRECT_0: - rc->range >>= 1; - break; - - case RC_DIRECT_1: - rc->range >>= 1; - rc->low += rc->range; - break; - - case RC_FLUSH: - // Prevent further normalizations. - rc->range = UINT32_MAX; - - // Flush the last five bytes (see rc_flush()). - do { - if (rc_shift_low(rc, out, out_pos, out_size)) - return true; - } while (++rc->pos < rc->count); - - // Reset the range encoder so we are ready to continue - // encoding if we weren't finishing the stream. - rc_reset(rc); - return false; - - default: - assert(0); - break; - } - - ++rc->pos; - } - - rc->count = 0; - rc->pos = 0; - - return false; -} - - -static inline uint64_t -rc_pending(const lzma_range_encoder *rc) -{ - return rc->cache_size + 5 - 1; -} - -#endif diff --git a/game/client/third/minizip/minizip.c b/game/client/third/minizip/minizip.c deleted file mode 100755 index a463a33d..00000000 --- a/game/client/third/minizip/minizip.c +++ /dev/null @@ -1,762 +0,0 @@ -/* minizip.c - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2009-2010 Mathias Svensson - Modifications for Zip64 support - http://result42.com - Copyright (C) 2007-2008 Even Rouault - Modifications of Unzip for Zip64 - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#include -#include -#include -#include -#include -#include - -#include "mz.h" -#include "mz_os.h" -#include "mz_strm.h" -#include "mz_strm_buf.h" -#include "mz_strm_split.h" -#include "mz_zip.h" - -/***************************************************************************/ - -void minizip_banner(void) -{ - printf("Minizip %s - https://github.com/nmoinvaz/minizip\n", MZ_VERSION); - printf("---------------------------------------------------\n"); -} - -void minizip_help(void) -{ - printf("Usage : minizip [-x -d dir|-l] [-o] [-a] [-j] [-0 to -9] [-b|-m] [-k 512] [-p pwd] [-s] file.zip [files]\n\n" \ - " -x Extract files\n" \ - " -l List files\n" \ - " -d Destination directory\n" \ - " -o Overwrite existing files\n" \ - " -a Append to existing zip file\n" \ - " -u Buffered reading and writing\n" \ - " -i Include full path of files\n" \ - " -0 Store only\n" \ - " -1 Compress faster\n" \ - " -9 Compress better\n" \ - " -k Disk size in KB\n" \ - " -p Encryption password\n"); -#ifdef HAVE_AES - printf(" -s AES encryption\n"); -#endif -#ifdef HAVE_BZIP2 - printf(" -b BZIP2 compression\n"); -#endif -#ifdef HAVE_LZMA - printf(" -m LZMA compression\n"); -#endif - printf("\n"); -} - -/***************************************************************************/ - -typedef struct minizip_opt_s { - int16_t include_path; - int16_t compress_level; - int16_t compress_method; - int16_t overwrite; -#ifdef HAVE_AES - int16_t aes; -#endif -} minizip_opt; - -/***************************************************************************/ - -int32_t minizip_add_path(void *handle, const char *path, const char *filenameinzip, const char *password, int16_t is_dir, minizip_opt *options) -{ - mz_zip_file file_info; - int32_t read = 0; - int32_t written = 0; - int32_t err = MZ_OK; - int32_t err_close = MZ_OK; - void *stream = NULL; - char buf[INT16_MAX]; - - - memset(&file_info, 0, sizeof(file_info)); - - // The path name saved, should not include a leading slash. - // If it did, windows/xp and dynazip couldn't read the zip file. - - if (filenameinzip == NULL) - filenameinzip = path; - while (filenameinzip[0] == '\\' || filenameinzip[0] == '/') - filenameinzip += 1; - - // Get information about the file on disk so we can store it in zip - printf("Adding: %s\n", filenameinzip); - - file_info.version_madeby = MZ_VERSION_MADEBY; - file_info.compression_method = options->compress_method; - file_info.filename = filenameinzip; - file_info.uncompressed_size = mz_os_get_file_size(path); - -#ifdef HAVE_AES - if (options->aes) - file_info.aes_version = MZ_AES_VERSION; -#endif - - mz_os_get_file_date(path, &file_info.modified_date, &file_info.accessed_date, - &file_info.creation_date); - mz_os_get_file_attribs(path, &file_info.external_fa); - - // Add to zip - err = mz_zip_entry_write_open(handle, &file_info, options->compress_level, password); - if (err != MZ_OK) - { - printf("Error in opening %s in zip file (%d)\n", filenameinzip, err); - return err; - } - - if (!is_dir) - { - mz_stream_os_create(&stream); - - err = mz_stream_os_open(stream, path, MZ_OPEN_MODE_READ); - - if (err == MZ_OK) - { - // Read contents of file and write it to zip - do - { - read = mz_stream_os_read(stream, buf, sizeof(buf)); - if (read < 0) - { - err = mz_stream_os_error(stream); - printf("Error %d in reading %s\n", err, filenameinzip); - break; - } - if (read == 0) - break; - - written = mz_zip_entry_write(handle, buf, read); - if (written != read) - { - err = mz_stream_os_error(stream); - printf("Error in writing %s in the zip file (%d)\n", filenameinzip, err); - break; - } - } while (err == MZ_OK); - - mz_stream_os_close(stream); - } - else - { - printf("Error in opening %s for reading\n", path); - } - - mz_stream_os_delete(&stream); - } - - err_close = mz_zip_entry_close(handle); - if (err_close != MZ_OK) - { - printf("Error in closing %s in the zip file (%d)\n", filenameinzip, err_close); - err = err_close; - } - - return err; -} - -int32_t minizip_add(void *handle, const char *path, const char *root_path, const char *password, minizip_opt *options, uint8_t recursive) -{ - DIR *dir = NULL; - struct dirent *entry = NULL; - int32_t err = MZ_OK; - int16_t is_dir = 0; - char full_path[320]; - const char *filename = NULL; - const char *filenameinzip = path; - - - if (mz_os_is_dir(path) == MZ_OK) - is_dir = 1; - - // Construct the filename that our file will be stored in the zip as - if (root_path == NULL) - root_path = path; - - // Should the file be stored with any path info at all? - if (!options->include_path) - { - if (!is_dir && root_path == path) - { - if (mz_path_get_filename(filenameinzip, &filename) == MZ_OK) - filenameinzip = filename; - } - else - { - filenameinzip += strlen(root_path); - } - } - - if (*filenameinzip != 0) - err = minizip_add_path(handle, path, filenameinzip, password, is_dir, options); - - if (!is_dir) - return err; - - dir = mz_os_open_dir(path); - - if (dir == NULL) - { - printf("Cannot enumerate directory %s\n", path); - return MZ_EXIST_ERROR; - } - - while ((entry = mz_os_read_dir(dir)) != NULL) - { - if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) - continue; - - full_path[0] = 0; - mz_path_combine(full_path, path, sizeof(full_path)); - mz_path_combine(full_path, entry->d_name, sizeof(full_path)); - - if (!recursive && mz_os_is_dir(full_path)) - continue; - - err = minizip_add(handle, full_path, root_path, password, options, recursive); - if (err != MZ_OK) - return err; - } - - mz_os_close_dir(dir); - return MZ_OK; -} - -/***************************************************************************/ - -int32_t minizip_list(void *handle) -{ - mz_zip_file *file_info = NULL; - uint32_t ratio = 0; - int16_t level = 0; - int32_t err = MZ_OK; - struct tm tmu_date; - const char *string_method = NULL; - char crypt = ' '; - - - err = mz_zip_goto_first_entry(handle); - - if (err != MZ_OK && err != MZ_END_OF_LIST) - { - printf("Error %d going to first entry in zip file\n", err); - return err; - } - - printf(" Length Method Size Attribs Ratio Date Time CRC-32 Name\n"); - printf(" ------ ------ ---- ------- ----- ---- ---- ------ ----\n"); - - while (err == MZ_OK) - { - err = mz_zip_entry_get_info(handle, &file_info); - - if (err != MZ_OK) - { - printf("Error %d getting entry info in zip file\n", err); - break; - } - - ratio = 0; - if (file_info->uncompressed_size > 0) - ratio = (uint32_t)((file_info->compressed_size * 100) / file_info->uncompressed_size); - - // Display a '*' if the file is encrypted - if (file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) - crypt = '*'; - - switch (file_info->compression_method) - { - case MZ_COMPRESS_METHOD_RAW: - string_method = "Stored"; - break; - case MZ_COMPRESS_METHOD_DEFLATE: - level = (int16_t)((file_info->flag & 0x6) / 2); - if (level == 0) - string_method = "Defl:N"; - else if (level == 1) - string_method = "Defl:X"; - else if ((level == 2) || (level == 3)) - string_method = "Defl:F"; // 2: fast , 3: extra fast - else - string_method = "Defl:?"; - break; - case MZ_COMPRESS_METHOD_BZIP2: - string_method = "BZip2"; - break; - case MZ_COMPRESS_METHOD_LZMA: - string_method = "LZMA"; - break; - default: - string_method = "Unknwn"; - } - - mz_zip_time_t_to_tm(file_info->modified_date, &tmu_date); - - printf(" %7"PRIu64" %6s%c %7"PRIu64" %8"PRIx32" %3"PRIu32"%% %2.2"PRIu32"-%2.2"PRIu32\ - "-%2.2"PRIu32" %2.2"PRIu32":%2.2"PRIu32" %8.8"PRIx32" %s\n", - file_info->uncompressed_size, string_method, crypt, - file_info->compressed_size, file_info->external_fa, ratio, - (uint32_t)tmu_date.tm_mon + 1, (uint32_t)tmu_date.tm_mday, - (uint32_t)tmu_date.tm_year % 100, - (uint32_t)tmu_date.tm_hour, (uint32_t)tmu_date.tm_min, - file_info->crc, file_info->filename); - - err = mz_zip_goto_next_entry(handle); - - if (err != MZ_OK && err != MZ_END_OF_LIST) - { - printf("Error %d going to next entry in zip file\n", err); - return err; - } - } - - if (err == MZ_END_OF_LIST) - return MZ_OK; - - return err; -} - -/***************************************************************************/ - -int32_t minizip_extract_currentfile(void *handle, const char *destination, const char *password, minizip_opt *options) -{ - mz_zip_file *file_info = NULL; - uint8_t buf[INT16_MAX]; - int32_t read = 0; - int32_t written = 0; - int32_t err = MZ_OK; - int32_t err_close = MZ_OK; - void *stream = NULL; - const char *filename = NULL; - char out_path[512]; - char directory[512]; - - - err = mz_zip_entry_get_info(handle, &file_info); - - if (err != MZ_OK) - { - printf("Error %d getting entry info in zip file\n", err); - return err; - } - - if (mz_path_get_filename(file_info->filename, &filename) != MZ_OK) - filename = file_info->filename; - - // Construct output path - out_path[0] = 0; - if ((*file_info->filename == '/') || (file_info->filename[1] == ':')) - { - strncpy(out_path, file_info->filename, sizeof(out_path)); - } - else - { - if (destination != NULL) - mz_path_combine(out_path, destination, sizeof(out_path)); - mz_path_combine(out_path, file_info->filename, sizeof(out_path)); - } - - // If zip entry is a directory then create it on disk - if (mz_zip_attrib_is_dir(file_info->external_fa, file_info->version_madeby) == MZ_OK) - { - printf("Creating directory: %s\n", out_path); - mz_make_dir(out_path); - return err; - } - - err = mz_zip_entry_read_open(handle, 0, password); - - if (err != MZ_OK) - { - printf("Error %d opening entry in zip file\n", err); - return err; - } - - // Determine if the file should be overwritten or not and ask the user if needed - if ((err == MZ_OK) && (options->overwrite == 0) && (mz_os_file_exists(out_path) == MZ_OK)) - { - char rep = 0; - do - { - char answer[128]; - printf("The file %s exists. Overwrite ? [y]es, [n]o, [A]ll: ", out_path); - if (scanf("%1s", answer) != 1) - exit(EXIT_FAILURE); - rep = answer[0]; - if ((rep >= 'a') && (rep <= 'z')) - rep -= 0x20; - } - while ((rep != 'Y') && (rep != 'N') && (rep != 'A')); - - if (rep == 'N') - return err; - if (rep == 'A') - options->overwrite = 1; - } - - mz_stream_os_create(&stream); - - // Create the file on disk so we can unzip to it - if (err == MZ_OK) - { - // Some zips don't contain directory alone before file - if ((mz_stream_os_open(stream, out_path, MZ_OPEN_MODE_CREATE) != MZ_OK) && - (filename != file_info->filename)) - { - // Create the directory of the output path - strncpy(directory, out_path, sizeof(directory)); - - mz_path_remove_filename(directory); - mz_make_dir(directory); - - mz_stream_os_open(stream, out_path, MZ_OPEN_MODE_CREATE); - } - } - - // Read from the zip, unzip to buffer, and write to disk - if (mz_stream_os_is_open(stream) == MZ_OK) - { - printf(" Extracting: %s\n", out_path); - while (1) - { - read = mz_zip_entry_read(handle, buf, sizeof(buf)); - if (read < 0) - { - err = read; - printf("Error %d reading entry in zip file\n", err); - break; - } - if (read == 0) - break; - written = mz_stream_os_write(stream, buf, read); - if (written != read) - { - err = mz_stream_os_error(stream); - printf("Error %d in writing extracted file\n", err); - break; - } - } - - mz_stream_os_close(stream); - - // Set the time of the file that has been unzipped - if (err == MZ_OK) - mz_os_set_file_date(out_path, file_info->modified_date, file_info->accessed_date, - file_info->creation_date); - } - else - { - printf("Error opening %s\n", out_path); - } - - mz_stream_os_delete(&stream); - - err_close = mz_zip_entry_close(handle); - if (err_close != MZ_OK) - { - printf("Error %d closing entry in zip file\n", err_close); - err = err_close; - } - - return err; -} - -int32_t minizip_extract_all(void *handle, const char *destination, const char *password, minizip_opt *options) -{ - int32_t err = MZ_OK; - - err = mz_zip_goto_first_entry(handle); - - if (err == MZ_END_OF_LIST) - return MZ_OK; - if (err != MZ_OK) - printf("Error %d going to first entry in zip file\n", err); - - while (err == MZ_OK) - { - err = minizip_extract_currentfile(handle, destination, password, options); - - if (err != MZ_OK) - break; - - err = mz_zip_goto_next_entry(handle); - - if (err == MZ_END_OF_LIST) - return MZ_OK; - if (err != MZ_OK) - printf("Error %d going to next entry in zip file\n", err); - } - - return err; -} - -int32_t minizip_extract_onefile(void *handle, const char *filename, const char *destination, const char *password, minizip_opt *options) -{ - int32_t err = mz_zip_locate_entry(handle, filename, NULL); - - if (err != MZ_OK) - { - printf("File %s not found in the zip file\n", filename); - return err; - } - - return minizip_extract_currentfile(handle, destination, password, options); -} - -/***************************************************************************/ - -#ifndef NOMAIN -int main(int argc, char *argv[]) -{ - void *handle = NULL; - void *file_stream = NULL; - void *split_stream = NULL; - void *buf_stream = NULL; - char *path = NULL; - char *password = NULL; - char *destination = NULL; - char *filename_to_extract = NULL; - minizip_opt options; - int64_t disk_size = 0; - int32_t path_arg = 0; - uint8_t do_list = 0; - uint8_t do_extract = 0; - uint8_t buffered = 0; - int16_t mode = 0; - uint8_t append = 0; - int32_t err_close = 0; - int32_t err = 0; - int32_t i = 0; - - minizip_banner(); - if (argc == 1) - { - minizip_help(); - return 0; - } - - memset(&options, 0, sizeof(options)); - - options.compress_method = MZ_COMPRESS_METHOD_DEFLATE; - options.compress_level = MZ_COMPRESS_LEVEL_DEFAULT; - - // Parse command line options - for (i = 1; i < argc; i += 1) - { - if ((*argv[i]) == '-') - { - const char *p = argv[i] + 1; - - while ((*p) != '\0') - { - char c = *(p++); - if ((c == 'l') || (c == 'L')) - do_list = 1; - if ((c == 'x') || (c == 'X')) - do_extract = 1; - if ((c == 'a') || (c == 'A')) - append = 1; - if ((c == 'u') || (c == 'U')) - buffered = 1; - if ((c == 'o') || (c == 'O')) - options.overwrite = 1; - if ((c == 'i') || (c == 'I')) - options.include_path = 1; - if ((c >= '0') && (c <= '9')) - { - options.compress_level = (c - '0'); - if (options.compress_level == 0) - options.compress_method = MZ_COMPRESS_METHOD_RAW; - } - -#ifdef HAVE_BZIP2 - if ((c == 'b') || (c == 'B')) - options.compress_method = MZ_COMPRESS_METHOD_BZIP2; -#endif -#ifdef HAVE_LZMA - if ((c == 'm') || (c == 'M')) - options.compress_method = MZ_COMPRESS_METHOD_LZMA; -#endif -#ifdef HAVE_AES - if ((c == 's') || (c == 'S')) - options.aes = 1; -#endif - if (((c == 'k') || (c == 'K')) && (i + 1 < argc)) - { - disk_size = atoi(argv[i + 1]) * 1024; - i += 1; - } - if (((c == 'd') || (c == 'D')) && (i + 1 < argc)) - { - destination = argv[i + 1]; - i += 1; - } - if (((c == 'p') || (c == 'P')) && (i + 1 < argc)) - { - password = argv[i + 1]; - i += 1; - } - } - - continue; - } - - if (path_arg == 0) - path_arg = i; - } - - if (path_arg == 0) - { - minizip_help(); - return 0; - } - - path = argv[path_arg]; - - mode = MZ_OPEN_MODE_READ; - - if ((do_list == 0) && (do_extract == 0)) - { - mode |= MZ_OPEN_MODE_WRITE; - - if (mz_os_file_exists(path) != MZ_OK) - { - // If the file doesn't exist, we don't append file - mode |= MZ_OPEN_MODE_CREATE; - } - else if (append == 1) - { - mode |= MZ_OPEN_MODE_APPEND; - } - else if (options.overwrite == 0) - { - // If ask the user what to do because append and overwrite args not set - char rep = 0; - do - { - char answer[128]; - printf("The file %s exists. Overwrite ? [y]es, [n]o, [a]ppend : ", path); - if (scanf("%1s", answer) != 1) - exit(EXIT_FAILURE); - rep = answer[0]; - - if ((rep >= 'a') && (rep <= 'z')) - rep -= 0x20; - } - while ((rep != 'Y') && (rep != 'N') && (rep != 'A')); - - if (rep == 'A') - { - mode |= MZ_OPEN_MODE_APPEND; - } - else if (rep == 'Y') - { - mode |= MZ_OPEN_MODE_CREATE; - } - else if (rep == 'N') - { - minizip_help(); - return 0; - } - } - } - - mz_stream_os_create(&file_stream); - mz_stream_buffered_create(&buf_stream); - mz_stream_split_create(&split_stream); - - if (buffered) - { - mz_stream_set_base(buf_stream, file_stream); - mz_stream_set_base(split_stream, buf_stream); - } - else - { - mz_stream_set_base(split_stream, file_stream); - } - - mz_stream_split_set_prop_int64(split_stream, MZ_STREAM_PROP_DISK_SIZE, disk_size); - - err = mz_stream_open(split_stream, path, mode); - - if (err != MZ_OK) - { - printf("Error opening file %s\n", path); - } - else - { - handle = mz_zip_open(split_stream, mode); - - if (handle == NULL) - { - printf("Error opening zip %s\n", path); - err = MZ_FORMAT_ERROR; - } - - if (do_list) - { - err = minizip_list(handle); - } - else if (do_extract) - { - // Create target directory if it doesn't exist - if (destination != NULL) - mz_make_dir(destination); - - if (argc > path_arg + 1) - filename_to_extract = argv[path_arg + 1]; - - if (filename_to_extract == NULL) - err = minizip_extract_all(handle, destination, password, &options); - else - err = minizip_extract_onefile(handle, filename_to_extract, destination, password, &options); - } - else - { - printf("Creating %s\n", path); - - // Go through command line args looking for files to add to zip - for (i = path_arg + 1; (i < argc) && (err == MZ_OK); i += 1) - err = minizip_add(handle, argv[i], NULL, password, &options, 1); - - mz_zip_set_version_madeby(handle, MZ_VERSION_MADEBY); - } - - err_close = mz_zip_close(handle); - - if (err_close != MZ_OK) - { - printf("Error in closing %s (%d)\n", path, err_close); - err = err_close; - } - - mz_stream_close(split_stream); - } - - mz_stream_split_delete(&split_stream); - mz_stream_buffered_delete(&buf_stream); - mz_stream_os_delete(&file_stream); - - return err; -} -#endif diff --git a/game/client/third/minizip/minizip.pc.cmakein b/game/client/third/minizip/minizip.pc.cmakein deleted file mode 100755 index bacb18ad..00000000 --- a/game/client/third/minizip/minizip.pc.cmakein +++ /dev/null @@ -1,13 +0,0 @@ -prefix=@CMAKE_INSTALL_PREFIX@ -exec_prefix=@CMAKE_INSTALL_PREFIX@ -libdir=@INSTALL_LIB_DIR@ -sharedlibdir=@INSTALL_LIB_DIR@ -includedir=@INSTALL_INC_DIR@ - -Name: minizip -Description: Minizip zip file manipulation library -Version: @VERSION@ - -Requires: zlib -Libs: -L${libdir} -L${sharedlibdir} -lminizip -Cflags: -I${includedir} diff --git a/game/client/third/minizip/mz.h b/game/client/third/minizip/mz.h deleted file mode 100755 index 5f1a1ebd..00000000 --- a/game/client/third/minizip/mz.h +++ /dev/null @@ -1,110 +0,0 @@ -/* mz.h -- Errors codes, zip flags and magic - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_H -#define MZ_H - -#ifdef __cplusplus -extern "C" { -#endif - -//mz_zip.c:1215:10: error: ZLIB or LZMA required for CRC32 -#define HAVE_ZLIB true - -/***************************************************************************/ - -// MZ_VERSION -#define MZ_VERSION ("2.3.3") - -// MZ_ERROR -#define MZ_OK (0) -#define MZ_STREAM_ERROR (-1) -#define MZ_DATA_ERROR (-3) -#define MZ_MEM_ERROR (-4) -#define MZ_END_OF_LIST (-100) -#define MZ_END_OF_STREAM (-101) -#define MZ_PARAM_ERROR (-102) -#define MZ_FORMAT_ERROR (-103) -#define MZ_INTERNAL_ERROR (-104) -#define MZ_CRC_ERROR (-105) -#define MZ_CRYPT_ERROR (-106) -#define MZ_EXIST_ERROR (-107) -#define MZ_PASSWORD_ERROR (-108) - -// MZ_OPEN -#define MZ_OPEN_MODE_READ (0x01) -#define MZ_OPEN_MODE_WRITE (0x02) -#define MZ_OPEN_MODE_READWRITE (MZ_OPEN_MODE_READ | MZ_OPEN_MODE_WRITE) -#define MZ_OPEN_MODE_APPEND (0x04) -#define MZ_OPEN_MODE_CREATE (0x08) -#define MZ_OPEN_MODE_EXISTING (0x10) - -// MZ_SEEK -#define MZ_SEEK_SET (0) -#define MZ_SEEK_CUR (1) -#define MZ_SEEK_END (2) - -// MZ_COMPRESS -#define MZ_COMPRESS_METHOD_RAW (0) -#define MZ_COMPRESS_METHOD_DEFLATE (8) -#define MZ_COMPRESS_METHOD_BZIP2 (12) -#define MZ_COMPRESS_METHOD_LZMA (14) -#define MZ_COMPRESS_METHOD_AES (99) - -#define MZ_COMPRESS_LEVEL_DEFAULT (-1) -#define MZ_COMPRESS_LEVEL_FAST (2) -#define MZ_COMPRESS_LEVEL_NORMAL (6) -#define MZ_COMPRESS_LEVEL_BEST (9) - -// MZ_ZIP -#define MZ_ZIP_FLAG_ENCRYPTED (1 << 0) -#define MZ_ZIP_FLAG_LZMA_EOS_MARKER (1 << 1) -#define MZ_ZIP_FLAG_DEFLATE_MAX (1 << 1) -#define MZ_ZIP_FLAG_DEFLATE_NORMAL (0) -#define MZ_ZIP_FLAG_DEFLATE_FAST (1 << 2) -#define MZ_ZIP_FLAG_DEFLATE_SUPER_FAST (MZ_ZIP_FLAG_DEFLATE_FAST | \ - MZ_ZIP_FLAG_DEFLATE_MAX) -#define MZ_ZIP_FLAG_DATA_DESCRIPTOR (1 << 3) - -// MZ_ZIP64 -#define MZ_ZIP64_AUTO (0) -#define MZ_ZIP64_FORCE (1) -#define MZ_ZIP64_DISABLE (2) - -// MZ_HOST_SYSTEM -#define MZ_HOST_SYSTEM_MSDOS (0) -#define MZ_HOST_SYSTEM_UNIX (3) -#define MZ_HOST_SYSTEM_WINDOWS_NTFS (10) -#define MZ_HOST_SYSTEM_OSX_DARWIN (19) - -// MZ_AES -#define MZ_AES_VERSION (1) -#define MZ_AES_ENCRYPTION_MODE_128 (0x01) -#define MZ_AES_ENCRYPTION_MODE_192 (0x02) -#define MZ_AES_ENCRYPTION_MODE_256 (0x03) - -// MZ_UTILITY -#define MZ_UNUSED(SYMBOL) ((void)SYMBOL) - -#ifndef MZ_CUSTOM_ALLOC -#define MZ_ALLOC(SIZE) (malloc(SIZE)) -#endif -#ifndef MZ_CUSTOM_FREE -#define MZ_FREE(PTR) (free(PTR)) -#endif - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_compat.c b/game/client/third/minizip/mz_compat.c deleted file mode 100755 index 811d24ac..00000000 --- a/game/client/third/minizip/mz_compat.c +++ /dev/null @@ -1,681 +0,0 @@ -/* mz_compat.c -- Backwards compatible interface for older versions - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#include -#include -#include - -#include "mz.h" -#include "mz_os.h" -#include "mz_strm.h" -#include "mz_strm_zlib.h" -#include "mz_zip.h" - -#include "mz_compat.h" - -/***************************************************************************/ - -typedef struct mz_compat_s { - void *stream; - void *handle; -} mz_compat; - -/***************************************************************************/ - -extern zipFile ZEXPORT zipOpen(const char *path, int append) -{ - zlib_filefunc64_def pzlib = mz_stream_os_get_interface(); - return zipOpen2(path, append, NULL, &pzlib); -} - -extern zipFile ZEXPORT zipOpen64(const void *path, int append) -{ - zlib_filefunc64_def pzlib = mz_stream_os_get_interface(); - return zipOpen2(path, append, NULL, &pzlib); -} - -extern zipFile ZEXPORT zipOpen2(const char *path, int append, const char **globalcomment, - zlib_filefunc_def *pzlib_filefunc_def) -{ - return zipOpen2_64(path, append, globalcomment, pzlib_filefunc_def); -} - -extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **globalcomment, - zlib_filefunc64_def *pzlib_filefunc_def) -{ - mz_compat *compat = NULL; - int32_t mode = MZ_OPEN_MODE_READWRITE; - void *handle = NULL; - void *stream = NULL; - - if (pzlib_filefunc_def) - { - if (mz_stream_create(&stream, (mz_stream_vtbl *)*pzlib_filefunc_def) == NULL) - return NULL; - } - else - { - if (mz_stream_os_create(&stream) == NULL) - return NULL; - } - - switch (append) - { - case APPEND_STATUS_CREATE: - mode |= MZ_OPEN_MODE_CREATE; - break; - case APPEND_STATUS_CREATEAFTER: - mode |= MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_APPEND; - break; - case APPEND_STATUS_ADDINZIP: - break; - } - - if (mz_stream_open(stream, path, mode) != MZ_OK) - { - mz_stream_delete(&stream); - return NULL; - } - - handle = mz_zip_open(stream, mode); - - if (handle == NULL) - { - mz_stream_delete(&stream); - return NULL; - } - - if (globalcomment != NULL) - mz_zip_get_comment(handle, globalcomment); - - compat = (mz_compat *)MZ_ALLOC(sizeof(mz_compat)); - compat->handle = handle; - compat->stream = stream; - - return (zipFile)compat; -} - -extern int ZEXPORT zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64) -{ - mz_compat *compat = (mz_compat *)file; - mz_zip_file file_info; - uint64_t dos_date = 0; - - - MZ_UNUSED(strategy); - MZ_UNUSED(memLevel); - MZ_UNUSED(windowBits); - MZ_UNUSED(size_extrafield_local); - MZ_UNUSED(extrafield_local); - MZ_UNUSED(crc_for_crypting); - - if (compat == NULL) - return ZIP_PARAMERROR; - - memset(&file_info, 0, sizeof(file_info)); - - if (zipfi != NULL) - { - if (zipfi->dosDate != 0) - dos_date = zipfi->dosDate; - else - dos_date = mz_zip_tm_to_dosdate(&zipfi->tmz_date); - - file_info.modified_date = mz_zip_dosdate_to_time_t(dos_date); - file_info.external_fa = zipfi->external_fa; - file_info.internal_fa = zipfi->internal_fa; - } - - if (filename == NULL) - filename = "-"; - - file_info.compression_method = compression_method; - file_info.filename = filename; - //file_info.extrafield_local = extrafield_local; - //file_info.extrafield_local_size = size_extrafield_local; - file_info.extrafield = extrafield_global; - file_info.extrafield_size = size_extrafield_global; - file_info.version_madeby = version_madeby; - file_info.comment = comment; - file_info.flag = flag_base; - if (zip64) - file_info.zip64 = MZ_ZIP64_FORCE; - else - file_info.zip64 = MZ_ZIP64_DISABLE; -#ifdef HAVE_AES - if (password) - file_info.aes_version = MZ_AES_VERSION; -#endif - - if (raw) - level = 0; - - return mz_zip_entry_write_open(compat->handle, &file_info, (int16_t)level, password); -} - -extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64) -{ - return zipOpenNewFileInZip5(file, filename, zipfi, extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, - memLevel, strategy, password, crc_for_crypting, version_madeby, flag_base, zip64); -} - -extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base) -{ - return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, - memLevel, strategy, password, crc_for_crypting, version_madeby, flag_base, 0); -} - -extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting) -{ - return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, - memLevel, strategy, password, crc_for_crypting, MZ_VERSION_MADEBY, 0, 0); -} - -extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, int zip64) -{ - return zipOpenNewFileInZip4_64(file, filename, zipfi, extrafield_local, size_extrafield_local, - extrafield_global, size_extrafield_global, comment, compression_method, level, raw, windowBits, - memLevel, strategy, password, crc_for_crypting, MZ_VERSION_MADEBY, 0, zip64); -} - -extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len) -{ - mz_compat *compat = (mz_compat *)file; - int32_t written = 0; - if (compat == NULL) - return ZIP_PARAMERROR; - written = mz_zip_entry_write(compat->handle, buf, len); - if ((written < 0) || ((uint32_t)written != len)) - return ZIP_ERRNO; - return ZIP_OK; -} - -extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32) -{ - return zipCloseFileInZipRaw64(file, uncompressed_size, crc32); -} - -extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, uint32_t crc32) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return ZIP_PARAMERROR; - return mz_zip_entry_close_raw(compat->handle, uncompressed_size, crc32); -} - -extern int ZEXPORT zipCloseFileInZip(zipFile file) -{ - return zipCloseFileInZipRaw(file, 0, 0); -} - -extern int ZEXPORT zipCloseFileInZip64(zipFile file) -{ - return zipCloseFileInZipRaw(file, 0, 0); -} - -extern int ZEXPORT zipClose(zipFile file, const char *global_comment) -{ - return zipClose_64(file, global_comment); -} - -extern int ZEXPORT zipClose_64(zipFile file, const char *global_comment) -{ - return zipClose2_64(file, global_comment, MZ_VERSION_MADEBY); -} - -extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby) -{ - mz_compat *compat = (mz_compat *)file; - int32_t err = MZ_OK; - - if (compat == NULL) - return ZIP_PARAMERROR; - - if (global_comment != NULL) - mz_zip_set_comment(compat->handle, global_comment); - - mz_zip_set_version_madeby(compat->handle, version_madeby); - err = mz_zip_close(compat->handle); - - if (compat->stream != NULL) - { - mz_stream_close(compat->stream); - mz_stream_delete(&compat->stream); - } - - MZ_FREE(compat); - - return err; -} - -/***************************************************************************/ - -extern unzFile ZEXPORT unzOpen(const char *path) -{ - return unzOpen64(path); -} - -extern unzFile ZEXPORT unzOpen64(const void *path) -{ - zlib_filefunc64_def pzlib = mz_stream_os_get_interface(); - return unzOpen2(path, &pzlib); -} - -extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def) -{ - return unzOpen2_64(path, pzlib_filefunc_def); -} - -extern unzFile ZEXPORT unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def) -{ - mz_compat *compat = NULL; - int32_t mode = MZ_OPEN_MODE_READ; - void *handle = NULL; - void *stream = NULL; - - if (pzlib_filefunc_def) - { - if (mz_stream_create(&stream, (mz_stream_vtbl *)*pzlib_filefunc_def) == NULL) - return NULL; - } - else - { - if (mz_stream_os_create(&stream) == NULL) - return NULL; - } - - if (mz_stream_open(stream, path, mode) != MZ_OK) - { - mz_stream_delete(&stream); - return NULL; - } - - handle = mz_zip_open(stream, mode); - - if (handle == NULL) - { - mz_stream_delete(&stream); - return NULL; - } - - compat = (mz_compat *)MZ_ALLOC(sizeof(mz_compat)); - compat->handle = handle; - compat->stream = stream; - - mz_zip_goto_first_entry(compat->handle); - return (unzFile)compat; -} - -extern int ZEXPORT unzClose(unzFile file) -{ - mz_compat *compat = (mz_compat *)file; - int32_t err = MZ_OK; - - if (compat == NULL) - return UNZ_PARAMERROR; - - err = mz_zip_close(compat->handle); - - if (compat->stream != NULL) - { - mz_stream_close(compat->stream); - mz_stream_delete(&compat->stream); - } - - MZ_FREE(compat); - - return err; -} - -extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32) -{ - mz_compat *compat = (mz_compat *)file; - unz_global_info64 global_info64; - int32_t err = MZ_OK; - - memset(pglobal_info32, 0, sizeof(unz_global_info)); - if (compat == NULL) - return UNZ_PARAMERROR; - - err = unzGetGlobalInfo64(file, &global_info64); - if (err == MZ_OK) - { - pglobal_info32->number_entry = (uint32_t)global_info64.number_entry; - pglobal_info32->size_comment = global_info64.size_comment; - pglobal_info32->number_disk_with_CD = global_info64.number_disk_with_CD; - } - return err; -} - -extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info) -{ - mz_compat *compat = (mz_compat *)file; - const char *comment_ptr = NULL; - int32_t err = MZ_OK; - - memset(pglobal_info, 0, sizeof(unz_global_info64)); - if (compat == NULL) - return UNZ_PARAMERROR; - err = mz_zip_get_comment(compat->handle, &comment_ptr); - if (err == MZ_OK) - pglobal_info->size_comment = (uint16_t)strlen(comment_ptr); - if ((err == MZ_OK) || (err == MZ_EXIST_ERROR)) - err = mz_zip_get_number_entry(compat->handle, (int64_t *)&pglobal_info->number_entry); - if (err == MZ_OK) - err = mz_zip_get_disk_number_with_cd(compat->handle, &pglobal_info->number_disk_with_CD); - return err; -} - -extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uint16_t comment_size) -{ - mz_compat *compat = (mz_compat *)file; - const char *comment_ptr = NULL; - int32_t err = MZ_OK; - - if (comment == NULL || comment_size == 0) - return UNZ_PARAMERROR; - err = mz_zip_get_comment(compat->handle, &comment_ptr); - if (err == MZ_OK) - strncpy(comment, comment_ptr, comment_size); - return err; -} - -extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - if (method != NULL) - *method = 0; - if (level != NULL) - *level = 0; - return mz_zip_entry_read_open(compat->handle, (int16_t)raw, password); -} - -extern int ZEXPORT unzOpenCurrentFile(unzFile file) -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, NULL); -} - -extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password) -{ - return unzOpenCurrentFile3(file, NULL, NULL, 0, password); -} - -extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw) -{ - return unzOpenCurrentFile3(file, method, level, raw, NULL); -} - -extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, uint32_t len) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - return mz_zip_entry_read(compat->handle, buf, len); -} - -extern int ZEXPORT unzCloseCurrentFile(unzFile file) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - return mz_zip_entry_close(compat->handle); -} - -extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename, - uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size) -{ - mz_compat *compat = (mz_compat *)file; - mz_zip_file *file_info = NULL; - int16_t bytes_to_copy = 0; - int32_t err = MZ_OK; - - if (compat == NULL) - return UNZ_PARAMERROR; - - err = mz_zip_entry_get_info(compat->handle, &file_info); - - if ((err == MZ_OK) && (pfile_info != NULL)) - { - pfile_info->version = file_info->version_madeby; - pfile_info->version_needed = file_info->version_needed; - pfile_info->flag = file_info->flag; - pfile_info->compression_method = file_info->compression_method; - pfile_info->dosDate = mz_zip_time_t_to_dos_date(file_info->modified_date); - mz_zip_time_t_to_tm(file_info->modified_date, &pfile_info->tmu_date); - pfile_info->tmu_date.tm_year += 1900; - pfile_info->crc = file_info->crc; - - pfile_info->size_filename = file_info->filename_size; - pfile_info->size_file_extra = file_info->extrafield_size; - pfile_info->size_file_comment = file_info->comment_size; - - pfile_info->disk_num_start = (uint16_t)file_info->disk_number; - pfile_info->internal_fa = file_info->internal_fa; - pfile_info->external_fa = file_info->external_fa; - - pfile_info->compressed_size = (uint32_t)file_info->compressed_size; - pfile_info->uncompressed_size = (uint32_t)file_info->uncompressed_size; - - if (filename_size > 0 && filename != NULL) - { - bytes_to_copy = filename_size; - if (bytes_to_copy > file_info->filename_size) - bytes_to_copy = file_info->filename_size; - memcpy(filename, file_info->filename, bytes_to_copy); - } - if (extrafield_size > 0 && extrafield != NULL) - { - bytes_to_copy = extrafield_size; - if (bytes_to_copy > file_info->extrafield_size) - bytes_to_copy = file_info->extrafield_size; - memcpy(extrafield, file_info->extrafield, bytes_to_copy); - } - if (comment_size > 0 && comment != NULL) - { - bytes_to_copy = comment_size; - if (bytes_to_copy > file_info->comment_size) - bytes_to_copy = file_info->comment_size; - memcpy(comment, file_info->comment, bytes_to_copy); - } - } - return err; -} - -extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 * pfile_info, char *filename, - uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size) -{ - mz_compat *compat = (mz_compat *)file; - mz_zip_file *file_info = NULL; - int16_t bytes_to_copy = 0; - int32_t err = MZ_OK; - - if (compat == NULL) - return UNZ_PARAMERROR; - - err = mz_zip_entry_get_info(compat->handle, &file_info); - - if ((err == MZ_OK) && (pfile_info != NULL)) - { - pfile_info->version = file_info->version_madeby; - pfile_info->version_needed = file_info->version_needed; - pfile_info->flag = file_info->flag; - pfile_info->compression_method = file_info->compression_method; - pfile_info->dosDate = mz_zip_time_t_to_dos_date(file_info->modified_date); - mz_zip_time_t_to_tm(file_info->modified_date, &pfile_info->tmu_date); - pfile_info->tmu_date.tm_year += 1900; - pfile_info->crc = file_info->crc; - - pfile_info->size_filename = file_info->filename_size; - pfile_info->size_file_extra = file_info->extrafield_size; - pfile_info->size_file_comment = file_info->comment_size; - - pfile_info->disk_num_start = file_info->disk_number; - pfile_info->internal_fa = file_info->internal_fa; - pfile_info->external_fa = file_info->external_fa; - - pfile_info->compressed_size = file_info->compressed_size; - pfile_info->uncompressed_size = file_info->uncompressed_size; - - if (filename_size > 0 && filename != NULL) - { - bytes_to_copy = filename_size; - if (bytes_to_copy > file_info->filename_size) - bytes_to_copy = file_info->filename_size; - memcpy(filename, file_info->filename, bytes_to_copy); - if (file_info->filename_size < filename_size) - filename[file_info->filename_size] = 0; - } - - if (extrafield_size > 0 && extrafield != NULL) - { - bytes_to_copy = extrafield_size; - if (bytes_to_copy > file_info->extrafield_size) - bytes_to_copy = file_info->extrafield_size; - memcpy(extrafield, file_info->extrafield, bytes_to_copy); - } - - if (comment_size > 0 && comment != NULL) - { - bytes_to_copy = comment_size; - if (bytes_to_copy > file_info->comment_size) - bytes_to_copy = file_info->comment_size; - memcpy(comment, file_info->comment, bytes_to_copy); - if (file_info->comment_size < comment_size) - comment[file_info->comment_size] = 0; - } - } - return err; -} - -extern int ZEXPORT unzGoToFirstFile(unzFile file) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - return mz_zip_goto_first_entry(compat->handle); -} - -extern int ZEXPORT unzGoToNextFile(unzFile file) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - return mz_zip_goto_next_entry(compat->handle); -} - -extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - return mz_zip_locate_entry(compat->handle, filename, filename_compare_func); -} - -extern int32_t ZEXPORT unzGetOffset(unzFile file) -{ - return (int32_t)unzGetOffset64(file); -} - -extern int64_t ZEXPORT unzGetOffset64(unzFile file) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - return mz_zip_get_entry(compat->handle); -} - -extern int ZEXPORT unzSetOffset(unzFile file, uint32_t pos) -{ - return unzSetOffset64(file, pos); -} - -extern int ZEXPORT unzSetOffset64(unzFile file, uint64_t pos) -{ - mz_compat *compat = (mz_compat *)file; - if (compat == NULL) - return UNZ_PARAMERROR; - return (int)mz_zip_goto_entry(compat->handle, pos); -} - -extern int ZEXPORT unzGetLocalExtrafield(unzFile file, void *buf, unsigned len) // TODO -{ - MZ_UNUSED(file); - MZ_UNUSED(buf); - MZ_UNUSED(len); - - return 0; -} - -/***************************************************************************/ - -void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def) -{ - if (pzlib_filefunc_def != NULL) - *pzlib_filefunc_def = mz_stream_os_get_interface(); -} - -void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def) -{ - if (pzlib_filefunc_def != NULL) - *pzlib_filefunc_def = mz_stream_os_get_interface(); -} - -void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def) -{ - if (pzlib_filefunc_def != NULL) - *pzlib_filefunc_def = mz_stream_os_get_interface(); -} - -void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def) -{ - if (pzlib_filefunc_def != NULL) - *pzlib_filefunc_def = mz_stream_os_get_interface(); -} - -void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def) -{ - if (pzlib_filefunc_def != NULL) - *pzlib_filefunc_def = mz_stream_os_get_interface(); -} - -void fill_win32_filefunc64W(zlib_filefunc64_def *pzlib_filefunc_def) -{ - // NOTE: You should no longer pass in widechar string to open function - if (pzlib_filefunc_def != NULL) - *pzlib_filefunc_def = mz_stream_os_get_interface(); -} diff --git a/game/client/third/minizip/mz_compat.h b/game/client/third/minizip/mz_compat.h deleted file mode 100755 index a3e57cba..00000000 --- a/game/client/third/minizip/mz_compat.h +++ /dev/null @@ -1,302 +0,0 @@ -/* mz_compat.h -- Backwards compatible interface for older versions - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_COMPAT_H -#define MZ_COMPAT_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef HAVE_ZLIB -#include "zlib.h" -#else -#define ZEXPORT -#define MAX_WBITS (15) -#define DEF_MEM_LEVEL (8) -#endif - -/***************************************************************************/ - -#if defined(USE_FILE32API) -# define MZ_USE_FILE32API -# define fopen64 fopen -# define ftello64 ftell -# define fseeko64 fseek -#else -# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ - defined(__OpenBSD__) || defined(__APPLE__) || defined(__ANDROID__) -# define fopen64 fopen -# define ftello64 ftello -# define fseeko64 fseeko -# endif -# ifdef _MSC_VER -# define fopen64 fopen -# if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) -# define ftello64 _ftelli64 -# define fseeko64 _fseeki64 -# else /* old MSC */ -# define ftello64 ftell -# define fseeko64 fseek -# endif -# endif -#endif - -/***************************************************************************/ - -#if defined(STRICTZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagzipFile__ { int unused; } zip_file__; -typedef zip_file__ *zipFile; -#else -typedef void *zipFile; -#endif - -/***************************************************************************/ - -typedef void *zlib_filefunc_def; -typedef void *zlib_filefunc64_def; -typedef const char *zipcharpc; - -typedef struct tm tm_unz; -typedef struct tm tm_zip; - -typedef uint64_t ZPOS64_T; - -/***************************************************************************/ - -typedef struct -{ - uint32_t dosDate; - struct tm tmz_date; - uint16_t internal_fa; // internal file attributes 2 bytes - uint32_t external_fa; // external file attributes 4 bytes -} zip_fileinfo; - -/***************************************************************************/ - -#define ZIP_OK (0) -#define ZIP_EOF (0) -#define ZIP_ERRNO (-1) -#define ZIP_PARAMERROR (-102) -#define ZIP_BADZIPFILE (-103) -#define ZIP_INTERNALERROR (-104) - -#define Z_BZIP2ED (12) - -#define APPEND_STATUS_CREATE (1) -#define APPEND_STATUS_CREATEAFTER (2) -#define APPEND_STATUS_ADDINZIP (3) - -/***************************************************************************/ - -extern zipFile ZEXPORT zipOpen(const char *path, int append); -extern zipFile ZEXPORT zipOpen64(const void *path, int append); -extern zipFile ZEXPORT zipOpen2(const char *path, int append, const char **globalcomment, - zlib_filefunc_def *pzlib_filefunc_def); -extern zipFile ZEXPORT zipOpen2_64(const void *path, int append, const char **globalcomment, - zlib_filefunc64_def *pzlib_filefunc_def); - -extern int ZEXPORT zipOpenNewFileInZip3(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting); -extern int ZEXPORT zipOpenNewFileInZip3_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, int zip64); -extern int ZEXPORT zipOpenNewFileInZip4(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base); -extern int ZEXPORT zipOpenNewFileInZip4_64(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64); -extern int ZEXPORT zipOpenNewFileInZip5(zipFile file, const char *filename, const zip_fileinfo *zipfi, - const void *extrafield_local, uint16_t size_extrafield_local, const void *extrafield_global, - uint16_t size_extrafield_global, const char *comment, uint16_t compression_method, int level, - int raw, int windowBits, int memLevel, int strategy, const char *password, - uint32_t crc_for_crypting, uint16_t version_madeby, uint16_t flag_base, int zip64); - -extern int ZEXPORT zipWriteInFileInZip(zipFile file, const void *buf, uint32_t len); - -extern int ZEXPORT zipCloseFileInZipRaw(zipFile file, uint32_t uncompressed_size, uint32_t crc32); -extern int ZEXPORT zipCloseFileInZipRaw64(zipFile file, uint64_t uncompressed_size, uint32_t crc32); -extern int ZEXPORT zipCloseFileInZip(zipFile file); -extern int ZEXPORT zipCloseFileInZip64(zipFile file); - -extern int ZEXPORT zipClose(zipFile file, const char *global_comment); -extern int ZEXPORT zipClose_64(zipFile file, const char *global_comment); -extern int ZEXPORT zipClose2_64(zipFile file, const char *global_comment, uint16_t version_madeby); - -/***************************************************************************/ - -#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP) -/* like the STRICT of WIN32, we define a pointer that cannot be converted - from (void*) without cast */ -typedef struct TagunzFile__ { int unused; } unz_file__; -typedef unz_file__ *unzFile; -#else -typedef void *unzFile; -#endif - -/***************************************************************************/ - -#define UNZ_OK (0) -#define UNZ_END_OF_LIST_OF_FILE (-100) -#define UNZ_ERRNO (-1) -#define UNZ_EOF (0) -#define UNZ_PARAMERROR (-102) -#define UNZ_BADZIPFILE (-103) -#define UNZ_INTERNALERROR (-104) -#define UNZ_CRCERROR (-105) -#define UNZ_BADPASSWORD (-106) - -/***************************************************************************/ - -typedef struct unz_global_info64_s -{ - uint64_t number_entry; // total number of entries in the central dir on this disk - uint32_t number_disk_with_CD; // number the the disk with central dir, used for spanning ZIP - uint16_t size_comment; // size of the global comment of the zipfile -} unz_global_info64; - -typedef struct unz_global_info_s -{ - uint32_t number_entry; // total number of entries in the central dir on this disk - uint32_t number_disk_with_CD; // number the the disk with central dir, used for spanning ZIP - uint16_t size_comment; // size of the global comment of the zipfile -} unz_global_info; - -typedef struct unz_file_info64_s -{ - uint16_t version; // version made by 2 bytes - uint16_t version_needed; // version needed to extract 2 bytes - uint16_t flag; // general purpose bit flag 2 bytes - uint16_t compression_method; // compression method 2 bytes - uint32_t dosDate; // last mod file date in Dos fmt 4 bytes - struct tm tmu_date; - uint32_t crc; // crc-32 4 bytes - uint64_t compressed_size; // compressed size 8 bytes - uint64_t uncompressed_size; // uncompressed size 8 bytes - uint16_t size_filename; // filename length 2 bytes - uint16_t size_file_extra; // extra field length 2 bytes - uint16_t size_file_comment; // file comment length 2 bytes - - uint32_t disk_num_start; // disk number start 4 bytes - uint16_t internal_fa; // internal file attributes 2 bytes - uint32_t external_fa; // external file attributes 4 bytes - - uint64_t disk_offset; - - uint16_t size_file_extra_internal; -} unz_file_info64; - -typedef struct unz_file_info_s -{ - uint16_t version; // version made by 2 bytes - uint16_t version_needed; // version needed to extract 2 bytes - uint16_t flag; // general purpose bit flag 2 bytes - uint16_t compression_method; // compression method 2 bytes - uint32_t dosDate; // last mod file date in Dos fmt 4 bytes - struct tm tmu_date; - uint32_t crc; // crc-32 4 bytes - uint32_t compressed_size; // compressed size 4 bytes - uint32_t uncompressed_size; // uncompressed size 4 bytes - uint16_t size_filename; // filename length 2 bytes - uint16_t size_file_extra; // extra field length 2 bytes - uint16_t size_file_comment; // file comment length 2 bytes - - uint16_t disk_num_start; // disk number start 2 bytes - uint16_t internal_fa; // internal file attributes 2 bytes - uint32_t external_fa; // external file attributes 4 bytes - - uint64_t disk_offset; -} unz_file_info; - -/***************************************************************************/ - -typedef int (*unzFileNameComparer)(unzFile file, const char *filename1, const char *filename2); -typedef int (*unzIteratorFunction)(unzFile file); -typedef int (*unzIteratorFunction2)(unzFile file, unz_file_info64 *pfile_info, char *filename, - uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size); - -/***************************************************************************/ - -extern unzFile ZEXPORT unzOpen(const char *path); -extern unzFile ZEXPORT unzOpen64(const void *path); -extern unzFile ZEXPORT unzOpen2(const char *path, zlib_filefunc_def *pzlib_filefunc_def); -extern unzFile ZEXPORT unzOpen2_64(const void *path, zlib_filefunc64_def *pzlib_filefunc_def); - -extern int ZEXPORT unzClose(unzFile file); -extern int ZEXPORT unzGetGlobalInfo(unzFile file, unz_global_info* pglobal_info32); -extern int ZEXPORT unzGetGlobalInfo64(unzFile file, unz_global_info64 *pglobal_info); -extern int ZEXPORT unzGetGlobalComment(unzFile file, char *comment, uint16_t comment_size); -extern int ZEXPORT unzOpenCurrentFile(unzFile file); -extern int ZEXPORT unzOpenCurrentFilePassword(unzFile file, const char *password); -extern int ZEXPORT unzOpenCurrentFile2(unzFile file, int *method, int *level, int raw); -extern int ZEXPORT unzOpenCurrentFile3(unzFile file, int *method, int *level, int raw, const char *password); -extern int ZEXPORT unzReadCurrentFile(unzFile file, void *buf, uint32_t len); -extern int ZEXPORT unzCloseCurrentFile(unzFile file); - -extern int ZEXPORT unzGetCurrentFileInfo(unzFile file, unz_file_info *pfile_info, char *filename, - uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size); -extern int ZEXPORT unzGetCurrentFileInfo64(unzFile file, unz_file_info64 * pfile_info, char *filename, - uint16_t filename_size, void *extrafield, uint16_t extrafield_size, char *comment, uint16_t comment_size); -extern int ZEXPORT unzGoToFirstFile(unzFile file); -extern int ZEXPORT unzGoToNextFile(unzFile file); -extern int ZEXPORT unzLocateFile(unzFile file, const char *filename, unzFileNameComparer filename_compare_func); - -extern int64_t ZEXPORT unzGetOffset64(unzFile file); -extern int32_t ZEXPORT unzGetOffset(unzFile file); -extern int ZEXPORT unzSetOffset64(unzFile file, uint64_t pos); -extern int ZEXPORT unzSetOffset(unzFile file, uint32_t pos); -extern int ZEXPORT unzGetLocalExtrafield(unzFile file, void *buf, unsigned len); - -/***************************************************************************/ - -void fill_fopen_filefunc(zlib_filefunc_def *pzlib_filefunc_def); -void fill_fopen64_filefunc(zlib_filefunc64_def *pzlib_filefunc_def); -void fill_win32_filefunc(zlib_filefunc_def *pzlib_filefunc_def); -void fill_win32_filefunc64(zlib_filefunc64_def *pzlib_filefunc_def); -void fill_win32_filefunc64A(zlib_filefunc64_def *pzlib_filefunc_def); -void fill_win32_filefunc64W(zlib_filefunc64_def *pzlib_filefunc_def); - -/***************************************************************************/ - -#define check_file_exists mz_os_file_exists -#define dosdate_to_tm mz_zip_dosdate_to_tm -#define change_file_date mz_os_set_file_date -#define get_file_date mz_os_get_file_date -#define is_large_file(x) (mz_os_get_file_size(x) >= UINT32_MAX) -#define makedir mz_make_dir -#define get_file_crc(p,b,bs,rc) mz_get_file_crc(p,rc) - -#define MKDIR mz_os_make_dir -#define CHDIR chdir - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_os.c b/game/client/third/minizip/mz_os.c deleted file mode 100755 index 8e73d632..00000000 --- a/game/client/third/minizip/mz_os.c +++ /dev/null @@ -1,195 +0,0 @@ -/* mz_os.c -- System functions - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#include -#include -#include - -#include "mz.h" -#include "mz_os.h" -#include "mz_strm.h" -#ifdef HAVE_LZMA -# include "mz_strm_lzma.h" -#endif -#ifdef HAVE_ZLIB -# include "mz_strm_zlib.h" -#endif - -/***************************************************************************/ - -int32_t mz_make_dir(const char *path) -{ - int32_t err = MZ_OK; - int16_t len = 0; - char *current_dir = NULL; - char *match = NULL; - char hold = 0; - - - len = (int16_t)strlen(path); - if (len <= 0) - return 0; - - current_dir = (char *)MZ_ALLOC(len + 1); - if (current_dir == NULL) - return MZ_MEM_ERROR; - - strcpy(current_dir, path); - - if (current_dir[len - 1] == '/') - current_dir[len - 1] = 0; - - err = mz_os_make_dir(current_dir); - if (err != MZ_OK) - { - match = current_dir + 1; - while (1) - { - while (*match != 0 && *match != '\\' && *match != '/') - match += 1; - hold = *match; - *match = 0; - - err = mz_os_make_dir(current_dir); - if (err != MZ_OK) - break; - if (hold == 0) - break; - - *match = hold; - match += 1; - } - } - - MZ_FREE(current_dir); - return err; -} - -int32_t mz_path_combine(char *path, const char *join, int32_t max_path) -{ - int32_t path_len = 0; - - if (path == NULL || join == NULL || max_path == 0) - return MZ_PARAM_ERROR; - - path_len = strlen(path); - - if (path_len == 0) - { - strncpy(path, join, max_path); - } - else - { - if (path[path_len - 1] != '\\' && path[path_len - 1] != '/') - strncat(path, "/", max_path - path_len - 1); - strncat(path, join, max_path - path_len); - } - - return MZ_OK; -} - -int32_t mz_path_remove_filename(const char *path) -{ - char *path_ptr = NULL; - - if (path == NULL) - return MZ_PARAM_ERROR; - - path_ptr = (char *)(path + strlen(path) - 1); - - while (path_ptr > path) - { - if ((*path_ptr == '/') || (*path_ptr == '\\')) - { - *path_ptr = 0; - break; - } - - path_ptr -= 1; - } - return MZ_OK; -} - -int32_t mz_path_get_filename(const char *path, const char **filename) -{ - const char *match = NULL; - - if (path == NULL || filename == NULL) - return MZ_PARAM_ERROR; - - *filename = NULL; - - for (match = path; *match != 0; match += 1) - { - if ((*match == '\\') || (*match == '/')) - *filename = match + 1; - } - - if (*filename == NULL) - return MZ_EXIST_ERROR; - - return MZ_OK; -} - -int32_t mz_get_file_crc(const char *path, uint32_t *result_crc) -{ - void *stream = NULL; - void *crc32_stream = NULL; - int32_t read = 0; - int32_t err = MZ_OK; - uint8_t buf[INT16_MAX]; - - mz_stream_os_create(&stream); - - err = mz_stream_os_open(stream, path, MZ_OPEN_MODE_READ); - - mz_stream_crc32_create(&crc32_stream); -#ifdef HAVE_ZLIB - mz_stream_crc32_set_update_func(crc32_stream, - (mz_stream_crc32_update)mz_stream_zlib_get_crc32_update()); -#elif defined(HAVE_LZMA) - mz_stream_crc32_set_update_func(crc32_stream, - (mz_stream_crc32_update)mz_stream_lzma_get_crc32_update()); -#else - #error ZLIB or LZMA required for CRC32 -#endif - - mz_stream_crc32_open(crc32_stream, NULL, MZ_OPEN_MODE_READ); - - mz_stream_set_base(crc32_stream, stream); - - if (err == MZ_OK) - { - do - { - read = mz_stream_crc32_read(crc32_stream, buf, sizeof(buf)); - - if (read < 0) - { - err = read; - break; - } - } - while ((err == MZ_OK) && (read > 0)); - - mz_stream_os_close(stream); - } - - mz_stream_crc32_close(crc32_stream); - *result_crc = mz_stream_crc32_get_value(crc32_stream); - mz_stream_crc32_delete(&crc32_stream); - - mz_stream_os_delete(&stream); - - return err; -} diff --git a/game/client/third/minizip/mz_os.h b/game/client/third/minizip/mz_os.h deleted file mode 100755 index ec73d07d..00000000 --- a/game/client/third/minizip/mz_os.h +++ /dev/null @@ -1,71 +0,0 @@ -/* mz_os.h -- System functions - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_OS_H -#define MZ_OS_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -#if !defined(_WIN32) && !defined(MZ_USE_WIN32_API) -#include "mz_os_posix.h" -#include "mz_strm_posix.h" -#else -#include "mz_os_win32.h" -#include "mz_strm_win32.h" -#endif - -/***************************************************************************/ - -#ifdef HAVE_LZMA -#define MZ_VERSION_MADEBY_ZIP_VERSION (63) -#elif HAVE_AES -#define MZ_VERSION_MADEBY_ZIP_VERSION (51) -#elif HAVE_BZIP2 -#define MZ_VERSION_MADEBY_ZIP_VERSION (46) -#else -#define MZ_VERSION_MADEBY_ZIP_VERSION (45) -#endif - -#define MZ_VERSION_MADEBY ((MZ_VERSION_MADEBY_HOST_SYSTEM << 8) | \ - (MZ_VERSION_MADEBY_ZIP_VERSION)) - -/***************************************************************************/ - -int32_t mz_make_dir(const char *path); -// Creates a directory recursively - -int32_t mz_path_combine(char *path, const char *join, int32_t max_path); -// Combines two paths - -int32_t mz_path_remove_filename(const char *path); -// Remove the filename from a path - -int32_t mz_path_get_filename(const char *path, const char **filename); -// Get the filename from a path - -int32_t mz_get_file_crc(const char *path, uint32_t *result_crc); -// Gets the crc32 hash of a file - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_os_posix.c b/game/client/third/minizip/mz_os_posix.c deleted file mode 100755 index 02edd1c0..00000000 --- a/game/client/third/minizip/mz_os_posix.c +++ /dev/null @@ -1,182 +0,0 @@ -/* mz_os_posix.c -- System functions for posix - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ -#undef strncpy -#include -#include -#include -#include - -#include -#include - -#if defined unix || defined __APPLE__ -# include -# include -#endif -#if defined __linux__ -# include -#else -# include -#endif - -#include "mz.h" -#include "mz_strm.h" -#include "mz_os.h" -#include "mz_os_posix.h" - -/***************************************************************************/ - -#if defined(HAVE_PKCRYPT) || defined(HAVE_AES) -int32_t mz_posix_rand(uint8_t *buf, int32_t size) -{ - arc4random_buf(buf, size); - return size; -} -#endif - -int32_t mz_posix_file_exists(const char *path) -{ - struct stat stat_info; - - memset(&stat_info, 0, sizeof(stat_info)); - if (stat(path, &stat_info) == 0) - return MZ_OK; - - return MZ_EXIST_ERROR; -} - -int64_t mz_posix_get_file_size(const char *path) -{ - struct stat stat_info; - - memset(&stat_info, 0, sizeof(stat_info)); - if (stat(path, &stat_info) == 0) - return stat_info.st_size; - - return 0; -} - -int32_t mz_posix_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date) -{ - struct stat stat_info; - char *name = NULL; - size_t len = 0; - int32_t err = MZ_INTERNAL_ERROR; - - memset(&stat_info, 0, sizeof(stat_info)); - - if (strcmp(path, "-") != 0) - { - // Not all systems allow stat'ing a file with / appended - len = strlen(path); - name = (char *)malloc(len + 1); - strncpy(name, path, len + 1); - name[len] = 0; - if (name[len - 1] == '/') - name[len - 1] = 0; - - if (stat(name, &stat_info) == 0) - { - if (modified_date != NULL) - *modified_date = stat_info.st_mtime; - if (accessed_date != NULL) - *accessed_date = stat_info.st_atime; - // Creation date not supported - if (creation_date != NULL) - *creation_date = 0; - - err = MZ_OK; - } - - free(name); - } - - return err; -} - -int32_t mz_posix_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date) -{ - struct utimbuf ut; - - ut.actime = accessed_date; - ut.modtime = modified_date; - // Creation date not supported - (void)creation_date; - - if (utime(path, &ut) != 0) - return MZ_INTERNAL_ERROR; - - return MZ_OK; -} - -int32_t mz_posix_get_file_attribs(const char *path, uint32_t *attributes) -{ - struct stat stat_info; - int32_t err = MZ_OK; - - memset(&stat_info, 0, sizeof(stat_info)); - if (stat(path, &stat_info) == -1) - err = MZ_INTERNAL_ERROR; - *attributes = stat_info.st_mode; - return err; -} - -int32_t mz_posix_set_file_attribs(const char *path, uint32_t attributes) -{ - int32_t err = MZ_OK; - - if (chmod(path, (mode_t)attributes) == -1) - err = MZ_INTERNAL_ERROR; - - return err; -} - -int32_t mz_posix_make_dir(const char *path) -{ - int32_t err = 0; - - err = mkdir(path, 0755); - - if (err != 0 && errno != EEXIST) - return MZ_INTERNAL_ERROR; - - return MZ_OK; -} - -DIR* mz_posix_open_dir(const char *path) -{ - return opendir(path); -} - -struct dirent* mz_posix_read_dir(DIR *dir) -{ - if (dir == NULL) - return NULL; - return readdir(dir); -} - -int32_t mz_posix_close_dir(DIR *dir) -{ - if (dir == NULL) - return MZ_PARAM_ERROR; - if (closedir(dir) == -1) - return MZ_INTERNAL_ERROR; - return MZ_OK; -} - -int32_t mz_posix_is_dir(const char *path) -{ - struct stat path_stat; - stat(path, &path_stat); - if (S_ISDIR(path_stat.st_mode)) - return MZ_OK; - return MZ_EXIST_ERROR; -} diff --git a/game/client/third/minizip/mz_os_posix.h b/game/client/third/minizip/mz_os_posix.h deleted file mode 100755 index 12727f0b..00000000 --- a/game/client/third/minizip/mz_os_posix.h +++ /dev/null @@ -1,68 +0,0 @@ -/* mz_os_posix.h -- System functions for posix - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_OS_POSIX_H -#define MZ_OS_POSIX_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -#if defined(__APPLE__) -#define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_OSX_DARWIN) -#elif defined(unix) -#define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_UNIX) -#endif - -/***************************************************************************/ - -int32_t mz_posix_rand(uint8_t *buf, int32_t size); -int32_t mz_posix_file_exists(const char *path); -int64_t mz_posix_get_file_size(const char *path); -int32_t mz_posix_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date); -int32_t mz_posix_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date); -int32_t mz_posix_get_file_attribs(const char *path, uint32_t *attributes); -int32_t mz_posix_set_file_attribs(const char *path, uint32_t attributes); -int32_t mz_posix_make_dir(const char *path); -DIR* mz_posix_open_dir(const char *path); -struct -dirent* mz_posix_read_dir(DIR *dir); -int32_t mz_posix_close_dir(DIR *dir); -int32_t mz_posix_is_dir(const char *path); - -/***************************************************************************/ - -#define mz_os_rand mz_posix_rand -#define mz_os_file_exists mz_posix_file_exists -#define mz_os_get_file_size mz_posix_get_file_size -#define mz_os_get_file_date mz_posix_get_file_date -#define mz_os_set_file_date mz_posix_set_file_date -#define mz_os_get_file_attribs mz_posix_get_file_attribs -#define mz_os_set_file_attribs mz_posix_set_file_attribs -#define mz_os_make_dir mz_posix_make_dir -#define mz_os_open_dir mz_posix_open_dir -#define mz_os_read_dir mz_posix_read_dir -#define mz_os_close_dir mz_posix_close_dir -#define mz_os_is_dir mz_posix_is_dir - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_os_win32.c b/game/client/third/minizip/mz_os_win32.c deleted file mode 100755 index 3f9e045f..00000000 --- a/game/client/third/minizip/mz_os_win32.c +++ /dev/null @@ -1,346 +0,0 @@ -/* mz_os_win32.c -- System functions for Windows - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "mz.h" - -#include "mz_os.h" -#include "mz_os_win32.h" - -/***************************************************************************/ - -#if defined(WINAPI_FAMILY_PARTITION) && (!(defined(MZ_USE_WINRT_API))) -# if !WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) -# define MZ_USE_WINRT_API 1 -# endif -#endif - -/***************************************************************************/ - -typedef struct DIR_int_s { - void *find_handle; - WIN32_FIND_DATAW find_data; - struct dirent entry; - uint8_t end; -} DIR_int; - -/***************************************************************************/ - -#if defined(HAVE_PKCRYPT) || defined(HAVE_AES) -int32_t mz_win32_rand(uint8_t *buf, int32_t size) -{ - HCRYPTPROV provider; - unsigned __int64 pentium_tsc[1]; - int32_t len = 0; - int32_t result = 0; - - - if (CryptAcquireContext(&provider, NULL, NULL, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) - { - result = CryptGenRandom(provider, size, buf); - CryptReleaseContext(provider, 0); - if (result) - return size; - } - - for (len = 0; len < (int)size; len += 1) - { - if (len % 8 == 0) - QueryPerformanceCounter((LARGE_INTEGER *)pentium_tsc); - buf[len] = ((unsigned char*)pentium_tsc)[len % 8]; - } - - return len; -} -#endif - -wchar_t *mz_win32_unicode_path_create(const char *path) -{ - wchar_t *path_wide = NULL; - uint32_t path_wide_size = 0; - - path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - path_wide = (wchar_t *)MZ_ALLOC((path_wide_size + 1) * sizeof(wchar_t)); - memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1)); - - MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size); - - return path_wide; -} - -void mz_win32_unicode_path_delete(wchar_t **path) -{ - if (path != NULL) - { - MZ_FREE(*path); - *path = NULL; - } -} - -int32_t mz_win32_file_exists(const char *path) -{ - wchar_t *path_wide = NULL; - DWORD attribs = 0; - - - path_wide = mz_win32_unicode_path_create(path); - attribs = GetFileAttributesW(path_wide); - mz_win32_unicode_path_delete(&path_wide); - - if (attribs == 0xFFFFFFFF) - return MZ_EXIST_ERROR; - - return MZ_OK; -} - -int64_t mz_win32_get_file_size(const char *path) -{ - HANDLE handle = NULL; - LARGE_INTEGER large_size; - wchar_t *path_wide = NULL; - - - path_wide = mz_win32_unicode_path_create(path); -#ifdef MZ_USE_WINRT_API - handle = CreateFile2W(path_wide, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#else - handle = CreateFileW(path_wide, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); -#endif - mz_win32_unicode_path_delete(&path_wide); - - large_size.QuadPart = 0; - - if (handle != INVALID_HANDLE_VALUE) - { - GetFileSizeEx(handle, &large_size); - CloseHandle(handle); - } - - return large_size.QuadPart; -} - -static void mz_win32_file_to_unix_time(FILETIME file_time, time_t *unix_time) -{ - uint64_t quad_file_time = 0; - quad_file_time = file_time.dwLowDateTime; - quad_file_time |= ((uint64_t)file_time.dwHighDateTime << 32); - *unix_time = (time_t)((quad_file_time - 116444736000000000LL) / 10000000); -} - -static void mz_win32_unix_to_file_time(time_t unix_time, FILETIME *file_time) -{ - uint64_t quad_file_time = 0; - quad_file_time = ((uint64_t)unix_time * 10000000) + 116444736000000000LL; - file_time->dwHighDateTime = (quad_file_time >> 32); - file_time->dwLowDateTime = (uint32_t)(quad_file_time); -} - -int32_t mz_win32_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date) -{ - WIN32_FIND_DATAW ff32; - HANDLE handle = NULL; - wchar_t *path_wide = NULL; - int32_t err = MZ_INTERNAL_ERROR; - - path_wide = mz_win32_unicode_path_create(path); - handle = FindFirstFileW(path_wide, &ff32); - MZ_FREE(path_wide); - - if (handle != INVALID_HANDLE_VALUE) - { - if (modified_date != NULL) - mz_win32_file_to_unix_time(ff32.ftLastWriteTime, modified_date); - if (accessed_date != NULL) - mz_win32_file_to_unix_time(ff32.ftLastAccessTime, accessed_date); - if (creation_date != NULL) - mz_win32_file_to_unix_time(ff32.ftCreationTime, creation_date); - - FindClose(handle); - err = MZ_OK; - } - - return err; -} - -int32_t mz_win32_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date) -{ - HANDLE handle = NULL; - FILETIME ftm_creation, ftm_accessed, ftm_modified; - wchar_t *path_wide = NULL; - int32_t err = MZ_OK; - - - path_wide = mz_win32_unicode_path_create(path); -#ifdef MZ_USE_WINRT_API - handle = CreateFile2W(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); -#else - handle = CreateFileW(path_wide, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); -#endif - mz_win32_unicode_path_delete(&path_wide); - - if (handle != INVALID_HANDLE_VALUE) - { - GetFileTime(handle, &ftm_creation, &ftm_accessed, &ftm_modified); - - if (modified_date != 0) - mz_win32_unix_to_file_time(modified_date, &ftm_modified); - if (accessed_date != 0) - mz_win32_unix_to_file_time(accessed_date, &ftm_accessed); - if (creation_date != 0) - mz_win32_unix_to_file_time(creation_date, &ftm_creation); - - if (SetFileTime(handle, &ftm_creation, &ftm_accessed, &ftm_modified) == 0) - err = MZ_INTERNAL_ERROR; - - CloseHandle(handle); - } - - return err; -} - -int32_t mz_win32_get_file_attribs(const char *path, uint32_t *attributes) -{ - wchar_t *path_wide = NULL; - int32_t err = MZ_OK; - - path_wide = mz_win32_unicode_path_create(path); - *attributes = GetFileAttributesW(path_wide); - MZ_FREE(path_wide); - - if (*attributes == INVALID_FILE_ATTRIBUTES) - err = MZ_INTERNAL_ERROR; - - return err; -} - -int32_t mz_win32_set_file_attribs(const char *path, uint32_t attributes) -{ - wchar_t *path_wide = NULL; - int32_t err = MZ_OK; - - path_wide = mz_win32_unicode_path_create(path); - if (SetFileAttributesW(path_wide, attributes) == 0) - err = MZ_INTERNAL_ERROR; - MZ_FREE(path_wide); - - return err; -} - -int32_t mz_win32_make_dir(const char *path) -{ - wchar_t *path_wide = NULL; - int32_t err = 0; - - - path_wide = mz_win32_unicode_path_create(path); - err = _wmkdir(path_wide); - mz_win32_unicode_path_delete(&path_wide); - - if (err != 0 && errno != EEXIST) - return MZ_INTERNAL_ERROR; - - return MZ_OK; -} - -DIR *mz_win32_open_dir(const char *path) -{ - WIN32_FIND_DATAW find_data; - DIR_int *dir_int = NULL; - wchar_t *path_wide = NULL; - char fixed_path[320]; - void *handle = NULL; - - - fixed_path[0] = 0; - mz_path_combine(fixed_path, path, sizeof(fixed_path)); - mz_path_combine(fixed_path, "*", sizeof(fixed_path)); - - path_wide = mz_win32_unicode_path_create(fixed_path); - handle = FindFirstFileW(path_wide, &find_data); - mz_win32_unicode_path_delete(&path_wide); - - if (handle == INVALID_HANDLE_VALUE) - return NULL; - - dir_int = (DIR_int *)MZ_ALLOC(sizeof(DIR_int)); - dir_int->find_handle = handle; - dir_int->end = 0; - - memcpy(&dir_int->find_data, &find_data, sizeof(dir_int->find_data)); - - return (DIR *)dir_int; -} - -struct dirent* mz_win32_read_dir(DIR *dir) -{ - DIR_int *dir_int; - - if (dir == NULL) - return NULL; - - dir_int = (DIR_int *)dir; - if (dir_int->end) - return NULL; - - WideCharToMultiByte(CP_UTF8, 0, dir_int->find_data.cFileName, -1, - dir_int->entry.d_name, sizeof(dir_int->entry.d_name), NULL, NULL); - - if (FindNextFileW(dir_int->find_handle, &dir_int->find_data) == 0) - { - if (GetLastError() != ERROR_NO_MORE_FILES) - return NULL; - - dir_int->end = 1; - } - - return &dir_int->entry; -} - -int32_t mz_win32_close_dir(DIR *dir) -{ - DIR_int *dir_int; - - if (dir == NULL) - return MZ_PARAM_ERROR; - - dir_int = (DIR_int *)dir; - if (dir_int->find_handle != INVALID_HANDLE_VALUE) - FindClose(dir_int->find_handle); - MZ_FREE(dir_int); - return MZ_OK; -} - -int32_t mz_win32_is_dir(const char *path) -{ - wchar_t *path_wide = NULL; - uint32_t attribs = 0; - - path_wide = mz_win32_unicode_path_create(path); - attribs = GetFileAttributesW(path_wide); - mz_win32_unicode_path_delete(&path_wide); - - if (attribs != 0xFFFFFFFF) - { - if (attribs & FILE_ATTRIBUTE_DIRECTORY) - return MZ_OK; - } - - return MZ_EXIST_ERROR; -} diff --git a/game/client/third/minizip/mz_os_win32.h b/game/client/third/minizip/mz_os_win32.h deleted file mode 100755 index 89cebe10..00000000 --- a/game/client/third/minizip/mz_os_win32.h +++ /dev/null @@ -1,69 +0,0 @@ -/* mz_os_win32.h -- System functions for Windows - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_OS_WIN32_H -#define MZ_OS_WIN32_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -#define MZ_VERSION_MADEBY_HOST_SYSTEM (MZ_HOST_SYSTEM_WINDOWS_NTFS) - -/***************************************************************************/ - -struct dirent { - char d_name[256]; -}; -typedef void* DIR; - -/***************************************************************************/ - -int32_t mz_win32_rand(uint8_t *buf, int32_t size); -int32_t mz_win32_file_exists(const char *path); -int64_t mz_win32_get_file_size(const char *path); -int32_t mz_win32_get_file_date(const char *path, time_t *modified_date, time_t *accessed_date, time_t *creation_date); -int32_t mz_win32_set_file_date(const char *path, time_t modified_date, time_t accessed_date, time_t creation_date); -int32_t mz_win32_get_file_attribs(const char *path, uint32_t *attributes); -int32_t mz_win32_set_file_attribs(const char *path, uint32_t attributes); -int32_t mz_win32_make_dir(const char *path); -DIR* mz_win32_open_dir(const char *path); -struct -dirent* mz_win32_read_dir(DIR *dir); -int32_t mz_win32_close_dir(DIR *dir); -int32_t mz_win32_is_dir(const char *path); - -/***************************************************************************/ - -#define mz_os_rand mz_win32_rand -#define mz_os_file_exists mz_win32_file_exists -#define mz_os_get_file_size mz_win32_get_file_size -#define mz_os_get_file_date mz_win32_get_file_date -#define mz_os_set_file_date mz_win32_set_file_date -#define mz_os_get_file_attribs mz_win32_get_file_attribs -#define mz_os_set_file_attribs mz_win32_set_file_attribs -#define mz_os_make_dir mz_win32_make_dir -#define mz_os_open_dir mz_win32_open_dir -#define mz_os_read_dir mz_win32_read_dir -#define mz_os_close_dir mz_win32_close_dir -#define mz_os_is_dir mz_win32_is_dir - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm.c b/game/client/third/minizip/mz_strm.c deleted file mode 100755 index e3ffdfdc..00000000 --- a/game/client/third/minizip/mz_strm.c +++ /dev/null @@ -1,580 +0,0 @@ -/* mz_strm.c -- Stream interface - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#include -#include -#include - -#include - -#include "mz.h" -#include "mz_strm.h" - -/***************************************************************************/ - -int32_t mz_stream_open(void *stream, const char *path, int32_t mode) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->open == NULL) - return MZ_STREAM_ERROR; - return strm->vtbl->open(strm, path, mode); -} - -int32_t mz_stream_is_open(void *stream) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->is_open == NULL) - return MZ_STREAM_ERROR; - return strm->vtbl->is_open(strm); -} - -int32_t mz_stream_read(void *stream, void *buf, int32_t size) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->read == NULL) - return MZ_PARAM_ERROR; - if (mz_stream_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - return strm->vtbl->read(strm, buf, size); -} - -static int32_t mz_stream_read_value(void *stream, uint64_t *value, int32_t len) -{ - uint8_t buf[8]; - int32_t n = 0; - int32_t i = 0; - - *value = 0; - if (mz_stream_read(stream, buf, len) == len) - { - for (n = 0; n < len; n += 1, i += 8) - *value += ((uint64_t)buf[n]) << i; - } - else if (mz_stream_error(stream)) - return MZ_STREAM_ERROR; - else - return MZ_END_OF_STREAM; - - return MZ_OK; -} - -int32_t mz_stream_read_uint8(void *stream, uint8_t *value) -{ - int32_t err = MZ_OK; - uint64_t value64 = 0; - - *value = 0; - err = mz_stream_read_value(stream, &value64, sizeof(uint8_t)); - if (err == MZ_OK) - *value = (uint8_t)value64; - return err; -} - -int32_t mz_stream_read_uint16(void *stream, uint16_t *value) -{ - int32_t err = MZ_OK; - uint64_t value64 = 0; - - *value = 0; - err = mz_stream_read_value(stream, &value64, sizeof(uint16_t)); - if (err == MZ_OK) - *value = (uint16_t)value64; - return err; -} - -int32_t mz_stream_read_uint32(void *stream, uint32_t *value) -{ - int32_t err = MZ_OK; - uint64_t value64 = 0; - - *value = 0; - err = mz_stream_read_value(stream, &value64, sizeof(uint32_t)); - if (err == MZ_OK) - *value = (uint32_t)value64; - return err; -} - -int32_t mz_stream_read_uint64(void *stream, uint64_t *value) -{ - return mz_stream_read_value(stream, value, sizeof(uint64_t)); -} - -int32_t mz_stream_write(void *stream, const void *buf, int32_t size) -{ - mz_stream *strm = (mz_stream *)stream; - if (size == 0) - return size; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->write == NULL) - return MZ_PARAM_ERROR; - if (mz_stream_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - return strm->vtbl->write(strm, buf, size); -} - -static int32_t mz_stream_write_value(void *stream, uint64_t value, int32_t len) -{ - uint8_t buf[8]; - int32_t n = 0; - - for (n = 0; n < len; n += 1) - { - buf[n] = (uint8_t)(value & 0xff); - value >>= 8; - } - - if (value != 0) - { - // Data overflow - hack for ZIP64 (X Roche) - for (n = 0; n < len; n += 1) - buf[n] = 0xff; - } - - if (mz_stream_write(stream, buf, len) != len) - return MZ_STREAM_ERROR; - - return MZ_OK; -} - -int32_t mz_stream_write_uint8(void *stream, uint8_t value) -{ - return mz_stream_write_value(stream, value, sizeof(uint8_t)); -} - -int32_t mz_stream_write_uint16(void *stream, uint16_t value) -{ - return mz_stream_write_value(stream, value, sizeof(uint16_t)); -} - -int32_t mz_stream_write_uint32(void *stream, uint32_t value) -{ - return mz_stream_write_value(stream, value, sizeof(uint32_t)); -} - -int32_t mz_stream_write_uint64(void *stream, uint64_t value) -{ - return mz_stream_write_value(stream, value, sizeof(uint64_t)); -} - -int32_t mz_stream_copy(void *target, void *source, int32_t len) -{ - uint8_t buf[INT16_MAX]; - int32_t bytes_to_copy = 0; - int32_t read = 0; - int32_t written = 0; - - while (len > 0) - { - bytes_to_copy = len; - if (bytes_to_copy > (int32_t)sizeof(buf)) - bytes_to_copy = sizeof(buf); - read = mz_stream_read(source, buf, bytes_to_copy); - if (read < 0) - return MZ_STREAM_ERROR; - written = mz_stream_write(target, buf, read); - if (written != read) - return MZ_STREAM_ERROR; - len -= read; - } - - return MZ_OK; -} - -int64_t mz_stream_tell(void *stream) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->tell == NULL) - return MZ_PARAM_ERROR; - if (mz_stream_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - return strm->vtbl->tell(strm); -} - -int32_t mz_stream_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->seek == NULL) - return MZ_PARAM_ERROR; - if (mz_stream_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - return strm->vtbl->seek(strm, offset, origin); -} - -int32_t mz_stream_close(void *stream) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->close == NULL) - return MZ_PARAM_ERROR; - if (mz_stream_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - return strm->vtbl->close(strm); -} - -int32_t mz_stream_error(void *stream) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->error == NULL) - return MZ_PARAM_ERROR; - return strm->vtbl->error(strm); -} - -int32_t mz_stream_set_base(void *stream, void *base) -{ - mz_stream *strm = (mz_stream *)stream; - strm->base = (mz_stream *)base; - return MZ_OK; -} - -int32_t mz_stream_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->get_prop_int64 == NULL) - return MZ_PARAM_ERROR; - return strm->vtbl->get_prop_int64(stream, prop, value); -} - -int32_t mz_stream_set_prop_int64(void *stream, int32_t prop, int64_t value) -{ - mz_stream *strm = (mz_stream *)stream; - if (strm == NULL || strm->vtbl == NULL || strm->vtbl->set_prop_int64 == NULL) - return MZ_PARAM_ERROR; - return strm->vtbl->set_prop_int64(stream, prop, value); -} - -void *mz_stream_create(void **stream, mz_stream_vtbl *vtbl) -{ - if (stream == NULL) - return NULL; - if (vtbl == NULL || vtbl->create == NULL) - return NULL; - return vtbl->create(stream); -} - -void mz_stream_delete(void **stream) -{ - mz_stream *strm = NULL; - if (stream == NULL) - return; - strm = (mz_stream *)*stream; - if (strm != NULL && strm->vtbl != NULL && strm->vtbl->destroy != NULL) - strm->vtbl->destroy(stream); - *stream = NULL; -} - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_crc32_vtbl = { - mz_stream_crc32_open, - mz_stream_crc32_is_open, - mz_stream_crc32_read, - mz_stream_crc32_write, - mz_stream_crc32_tell, - mz_stream_crc32_seek, - mz_stream_crc32_close, - mz_stream_crc32_error, - mz_stream_crc32_create, - mz_stream_crc32_delete, - mz_stream_crc32_get_prop_int64, - NULL -}; - -/***************************************************************************/ - -typedef struct mz_stream_crc32_s { - mz_stream stream; - int8_t initialized; - int64_t value; - int64_t total_in; - int64_t total_out; - - mz_stream_crc32_update update; -} mz_stream_crc32; - -/***************************************************************************/ - -int32_t mz_stream_crc32_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - - MZ_UNUSED(path); - MZ_UNUSED(mode); - - crc32->initialized = 1; - crc32->value = 0; - return MZ_OK; -} - -int32_t mz_stream_crc32_is_open(void *stream) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - if (crc32->initialized != 1) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_crc32_read(void *stream, void *buf, int32_t size) -{ - mz_stream_crc32 *crc32x = (mz_stream_crc32 *)stream; - int32_t read = 0; - read = mz_stream_read(crc32x->stream.base, buf, size); - if (read > 0) - crc32x->value = crc32x->update(crc32x->value, buf, read); - crc32x->total_in += read; - return read; -} - -int32_t mz_stream_crc32_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_crc32 *crc32x = (mz_stream_crc32 *)stream; - int32_t written = 0; - crc32x->value = crc32x->update(crc32x->value, buf, size); - written = mz_stream_write(crc32x->stream.base, buf, size); - crc32x->total_out += written; - return written; -} - -int64_t mz_stream_crc32_tell(void *stream) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - return mz_stream_tell(crc32->stream.base); -} - -int32_t mz_stream_crc32_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - crc32->value = 0; - return mz_stream_seek(crc32->stream.base, offset, origin); -} - -int32_t mz_stream_crc32_close(void *stream) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - crc32->initialized = 0; - return MZ_OK; -} - -int32_t mz_stream_crc32_error(void *stream) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - return mz_stream_error(crc32->stream.base); -} - -int32_t mz_stream_crc32_get_value(void *stream) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - return (int32_t)crc32->value; -} - -int32_t mz_stream_crc32_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN: - *value = crc32->total_in; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT: - *value = crc32->total_out; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -int32_t mz_stream_crc32_set_update_func(void *stream, mz_stream_crc32_update update) -{ - mz_stream_crc32 *crc32 = (mz_stream_crc32 *)stream; - crc32->update = update; - return MZ_OK; -} - -void *mz_stream_crc32_create(void **stream) -{ - mz_stream_crc32 *crc32 = NULL; - - crc32 = (mz_stream_crc32 *)MZ_ALLOC(sizeof(mz_stream_crc32)); - if (crc32 != NULL) - { - memset(crc32, 0, sizeof(mz_stream_crc32)); - crc32->stream.vtbl = &mz_stream_crc32_vtbl; - } - if (stream != NULL) - *stream = crc32; - - return crc32; -} - -void mz_stream_crc32_delete(void **stream) -{ - mz_stream_crc32 *crc32 = NULL; - if (stream == NULL) - return; - crc32 = (mz_stream_crc32 *)*stream; - if (crc32 != NULL) - MZ_FREE(crc32); - *stream = NULL; -} - -void *mz_stream_crc32_get_interface(void) -{ - return (void *)&mz_stream_crc32_vtbl; -} - -/***************************************************************************/ - -typedef struct mz_stream_raw_s { - mz_stream stream; - int64_t total_in; - int64_t total_out; - int64_t max_total_in; -} mz_stream_raw; - -/***************************************************************************/ - -int32_t mz_stream_raw_open(void *stream, const char *path, int32_t mode) -{ - MZ_UNUSED(stream); - MZ_UNUSED(path); - MZ_UNUSED(mode); - - return MZ_OK; -} - -int32_t mz_stream_raw_is_open(void *stream) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - return mz_stream_is_open(raw->stream.base); -} - -int32_t mz_stream_raw_read(void *stream, void *buf, int32_t size) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - int32_t bytes_to_read = size; - int32_t read = 0; - - if (raw->max_total_in > 0) - { - if ((raw->max_total_in - raw->total_in) < size) - bytes_to_read = (int32_t)(raw->max_total_in - raw->total_in); - } - - read = mz_stream_read(raw->stream.base, buf, bytes_to_read); - - if (read > 0) - raw->total_in += read; - - return read; -} - -int32_t mz_stream_raw_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - int32_t written = mz_stream_write(raw->stream.base, buf, size); - if (written > 0) - raw->total_out += written; - return written; -} - -int64_t mz_stream_raw_tell(void *stream) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - return mz_stream_tell(raw->stream.base); -} - -int32_t mz_stream_raw_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - return mz_stream_seek(raw->stream.base, offset, origin); -} - -int32_t mz_stream_raw_close(void *stream) -{ - MZ_UNUSED(stream); - - return MZ_OK; -} - -int32_t mz_stream_raw_error(void *stream) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - return mz_stream_error(raw->stream.base); -} - -int32_t mz_stream_raw_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN: - *value = raw->total_in; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT: - *value = raw->total_out; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -int32_t mz_stream_raw_set_prop_int64(void *stream, int32_t prop, int64_t value) -{ - mz_stream_raw *raw = (mz_stream_raw *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN_MAX: - raw->max_total_in = value; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_raw_vtbl = { - mz_stream_raw_open, - mz_stream_raw_is_open, - mz_stream_raw_read, - mz_stream_raw_write, - mz_stream_raw_tell, - mz_stream_raw_seek, - mz_stream_raw_close, - mz_stream_raw_error, - mz_stream_raw_create, - mz_stream_raw_delete, - mz_stream_raw_get_prop_int64, - mz_stream_raw_set_prop_int64 -}; - -/***************************************************************************/ - -void *mz_stream_raw_create(void **stream) -{ - mz_stream_raw *raw = NULL; - - raw = (mz_stream_raw *)MZ_ALLOC(sizeof(mz_stream_raw)); - if (raw != NULL) - { - memset(raw, 0, sizeof(mz_stream_raw)); - raw->stream.vtbl = &mz_stream_raw_vtbl; - } - if (stream != NULL) - *stream = raw; - - return raw; -} - -void mz_stream_raw_delete(void **stream) -{ - mz_stream_raw *raw = NULL; - if (stream == NULL) - return; - raw = (mz_stream_raw *)*stream; - if (raw != NULL) - MZ_FREE(raw); - *stream = NULL; -} diff --git a/game/client/third/minizip/mz_strm.h b/game/client/third/minizip/mz_strm.h deleted file mode 100755 index 1d9a30b3..00000000 --- a/game/client/third/minizip/mz_strm.h +++ /dev/null @@ -1,146 +0,0 @@ -/* mz_strm.h -- Stream interface - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_H -#define MZ_STREAM_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -#define MZ_STREAM_PROP_TOTAL_IN (1) -#define MZ_STREAM_PROP_TOTAL_IN_MAX (2) -#define MZ_STREAM_PROP_TOTAL_OUT (3) -#define MZ_STREAM_PROP_TOTAL_OUT_MAX (4) -#define MZ_STREAM_PROP_HEADER_SIZE (5) -#define MZ_STREAM_PROP_FOOTER_SIZE (6) -#define MZ_STREAM_PROP_DISK_SIZE (7) -#define MZ_STREAM_PROP_DISK_NUMBER (8) -#define MZ_STREAM_PROP_COMPRESS_LEVEL (9) - -/***************************************************************************/ - -typedef int32_t (*mz_stream_open_cb) (void *stream, const char *path, int32_t mode); -typedef int32_t (*mz_stream_is_open_cb) (void *stream); -typedef int32_t (*mz_stream_read_cb) (void *stream, void *buf, int32_t size); -typedef int32_t (*mz_stream_write_cb) (void *stream, const void *buf, int32_t size); -typedef int64_t (*mz_stream_tell_cb) (void *stream); -typedef int32_t (*mz_stream_seek_cb) (void *stream, int64_t offset, int32_t origin); -typedef int32_t (*mz_stream_close_cb) (void *stream); -typedef int32_t (*mz_stream_error_cb) (void *stream); -typedef void* (*mz_stream_create_cb) (void **stream); -typedef void (*mz_stream_destroy_cb) (void **stream); - -typedef int32_t (*mz_stream_get_prop_int64_cb) (void *stream, int32_t prop, int64_t *value); -typedef int32_t (*mz_stream_set_prop_int64_cb) (void *stream, int32_t prop, int64_t value); - -/***************************************************************************/ - -typedef struct mz_stream_vtbl_s -{ - mz_stream_open_cb open; - mz_stream_is_open_cb is_open; - mz_stream_read_cb read; - mz_stream_write_cb write; - mz_stream_tell_cb tell; - mz_stream_seek_cb seek; - mz_stream_close_cb close; - mz_stream_error_cb error; - mz_stream_create_cb create; - mz_stream_destroy_cb destroy; - - mz_stream_get_prop_int64_cb get_prop_int64; - mz_stream_set_prop_int64_cb set_prop_int64; -} mz_stream_vtbl; - -typedef struct mz_stream_s { - mz_stream_vtbl *vtbl; - struct mz_stream_s *base; -} mz_stream; - -/***************************************************************************/ - -int32_t mz_stream_open(void *stream, const char *path, int32_t mode); -int32_t mz_stream_is_open(void *stream); -int32_t mz_stream_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_read_uint8(void *stream, uint8_t *value); -int32_t mz_stream_read_uint16(void *stream, uint16_t *value); -int32_t mz_stream_read_uint32(void *stream, uint32_t *value); -int32_t mz_stream_read_uint64(void *stream, uint64_t *value); -int32_t mz_stream_write(void *stream, const void *buf, int32_t size); -int32_t mz_stream_write_uint8(void *stream, uint8_t value); -int32_t mz_stream_write_uint16(void *stream, uint16_t value); -int32_t mz_stream_write_uint32(void *stream, uint32_t value); -int32_t mz_stream_write_uint64(void *stream, uint64_t value); -int32_t mz_stream_copy(void *target, void *source, int32_t len); -int64_t mz_stream_tell(void *stream); -int32_t mz_stream_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_close(void *stream); -int32_t mz_stream_error(void *stream); - -int32_t mz_stream_set_base(void *stream, void *base); -int32_t mz_stream_get_prop_int64(void *stream, int32_t prop, int64_t *value); -int32_t mz_stream_set_prop_int64(void *stream, int32_t prop, int64_t value); - -void* mz_stream_create(void **stream, mz_stream_vtbl *vtbl); -void mz_stream_delete(void **stream); - -/***************************************************************************/ - -typedef int64_t (*mz_stream_crc32_update)(int64_t value, const void *buf, int32_t size); - -int32_t mz_stream_crc32_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_crc32_is_open(void *stream); -int32_t mz_stream_crc32_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_crc32_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_crc32_tell(void *stream); -int32_t mz_stream_crc32_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_crc32_close(void *stream); -int32_t mz_stream_crc32_error(void *stream); - -int32_t mz_stream_crc32_get_value(void *stream); - -int32_t mz_stream_crc32_get_prop_int64(void *stream, int32_t prop, int64_t *value); -int32_t mz_stream_crc32_set_update_func(void *stream, mz_stream_crc32_update update); - -void* mz_stream_crc32_create(void **stream); -void mz_stream_crc32_delete(void **stream); - -void* mz_stream_crc32_get_interface(void); - -/***************************************************************************/ - -int32_t mz_stream_raw_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_raw_is_open(void *stream); -int32_t mz_stream_raw_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_raw_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_raw_tell(void *stream); -int32_t mz_stream_raw_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_raw_close(void *stream); -int32_t mz_stream_raw_error(void *stream); - -int32_t mz_stream_raw_get_prop_int64(void *stream, int32_t prop, int64_t *value); -int32_t mz_stream_raw_set_prop_int64(void *stream, int32_t prop, int64_t value); - -void* mz_stream_raw_create(void **stream); -void mz_stream_raw_delete(void **stream); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_aes.c b/game/client/third/minizip/mz_strm_aes.c deleted file mode 100755 index 0128dfb0..00000000 --- a/game/client/third/minizip/mz_strm_aes.c +++ /dev/null @@ -1,350 +0,0 @@ -/* mz_strm_aes.c -- Stream for WinZip AES encryption - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 1998-2010 Brian Gladman, Worcester, UK - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - - -#include -#include -#include - -#include "aes.h" -#include "hmac.h" -#include "pwd2key.h" - -#include "mz.h" -#include "mz_os.h" -#include "mz_strm.h" -#include "mz_strm_aes.h" - -/***************************************************************************/ - -#define MZ_AES_KEY_LENGTH(mode) (8 * (mode & 3) + 8) -#define MZ_AES_KEY_LENGTH_MAX (32) -#define MZ_AES_KEYING_ITERATIONS (1000) -#define MZ_AES_SALT_LENGTH(mode) (4 * (mode & 3) + 4) -#define MZ_AES_SALT_LENGTH_MAX (16) -#define MZ_AES_MAC_LENGTH(mode) (10) -#define MZ_AES_PW_LENGTH_MAX (128) -#define MZ_AES_PW_VERIFY_SIZE (2) -#define MZ_AES_AUTHCODE_SIZE (10) - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_aes_vtbl = { - mz_stream_aes_open, - mz_stream_aes_is_open, - mz_stream_aes_read, - mz_stream_aes_write, - mz_stream_aes_tell, - mz_stream_aes_seek, - mz_stream_aes_close, - mz_stream_aes_error, - mz_stream_aes_create, - mz_stream_aes_delete, - mz_stream_aes_get_prop_int64, - NULL -}; - -/***************************************************************************/ - -typedef struct mz_stream_aes_s { - mz_stream stream; - int32_t mode; - int32_t error; - int16_t initialized; - uint8_t buffer[INT16_MAX]; - int64_t total_in; - int64_t total_out; - int16_t encryption_mode; - const char *password; - aes_encrypt_ctx encr_ctx[1]; - hmac_ctx auth_ctx[1]; - uint8_t nonce[AES_BLOCK_SIZE]; - uint8_t encr_bfr[AES_BLOCK_SIZE]; - uint32_t encr_pos; -} mz_stream_aes; - -/***************************************************************************/ - -int32_t mz_stream_aes_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - uint8_t kbuf[2 * MZ_AES_KEY_LENGTH_MAX + MZ_AES_PW_VERIFY_SIZE]; - uint8_t verify[MZ_AES_PW_VERIFY_SIZE]; - uint8_t verify_expected[MZ_AES_PW_VERIFY_SIZE]; - uint8_t salt_value[MZ_AES_SALT_LENGTH_MAX]; - int32_t salt_length = 0; - const char *password = path; - int32_t password_length = 0; - int32_t key_length = 0; - - aes->total_in = 0; - aes->total_out = 0; - aes->initialized = 0; - - if (mz_stream_is_open(aes->stream.base) != MZ_OK) - return MZ_STREAM_ERROR; - - if (password == NULL) - password = aes->password; - if (password == NULL) - return MZ_PARAM_ERROR; - password_length = (int32_t)strlen(password); - if (password_length > MZ_AES_PW_LENGTH_MAX) - return MZ_PARAM_ERROR; - - if (aes->encryption_mode < 1 || aes->encryption_mode > 3) - return MZ_PARAM_ERROR; - salt_length = MZ_AES_SALT_LENGTH(aes->encryption_mode); - - if (mode & MZ_OPEN_MODE_WRITE) - { - mz_os_rand(salt_value, salt_length); - } - else if (mode & MZ_OPEN_MODE_READ) - { - if (mz_stream_read(aes->stream.base, salt_value, salt_length) != salt_length) - return MZ_STREAM_ERROR; - } - - key_length = MZ_AES_KEY_LENGTH(aes->encryption_mode); - // Derive the encryption and authentication keys and the password verifier - derive_key((const uint8_t *)password, password_length, salt_value, salt_length, - MZ_AES_KEYING_ITERATIONS, kbuf, 2 * key_length + MZ_AES_PW_VERIFY_SIZE); - - // Initialize the encryption nonce and buffer pos - aes->encr_pos = AES_BLOCK_SIZE; - memset(aes->nonce, 0, AES_BLOCK_SIZE * sizeof(uint8_t)); - - // Initialize for encryption using key 1 - aes_encrypt_key(kbuf, key_length, aes->encr_ctx); - - // Initialize for authentication using key 2 - hmac_sha_begin(HMAC_SHA1, aes->auth_ctx); - hmac_sha_key(kbuf + key_length, key_length, aes->auth_ctx); - - memcpy(verify, kbuf + 2 * key_length, MZ_AES_PW_VERIFY_SIZE); - - if (mode & MZ_OPEN_MODE_WRITE) - { - if (mz_stream_write(aes->stream.base, salt_value, salt_length) != salt_length) - return MZ_STREAM_ERROR; - - aes->total_out += salt_length; - - if (mz_stream_write(aes->stream.base, verify, MZ_AES_PW_VERIFY_SIZE) != MZ_AES_PW_VERIFY_SIZE) - return MZ_STREAM_ERROR; - - aes->total_out += MZ_AES_PW_VERIFY_SIZE; - } - else if (mode & MZ_OPEN_MODE_READ) - { - aes->total_in += salt_length; - - if (mz_stream_read(aes->stream.base, verify_expected, MZ_AES_PW_VERIFY_SIZE) != MZ_AES_PW_VERIFY_SIZE) - return MZ_STREAM_ERROR; - - aes->total_in += MZ_AES_PW_VERIFY_SIZE; - - if (memcmp(verify_expected, verify, MZ_AES_PW_VERIFY_SIZE) != 0) - return MZ_PASSWORD_ERROR; - } - - aes->mode = mode; - aes->initialized = 1; - - return MZ_OK; -} - -int32_t mz_stream_aes_is_open(void *stream) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - if (aes->initialized == 0) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -static int32_t mz_stream_aes_encrypt_data(void *stream, uint8_t *buf, int32_t size) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - uint32_t pos = aes->encr_pos; - uint32_t i = 0; - - while (i < (uint32_t)size) - { - if (pos == AES_BLOCK_SIZE) - { - uint32_t j = 0; - - // Increment encryption nonce - while (j < 8 && !++aes->nonce[j]) - j += 1; - - // Encrypt the nonce to form next xor buffer - aes_encrypt(aes->nonce, aes->encr_bfr, aes->encr_ctx); - pos = 0; - } - - buf[i++] ^= aes->encr_bfr[pos++]; - } - - aes->encr_pos = pos; - return MZ_OK; -} - -int32_t mz_stream_aes_read(void *stream, void *buf, int32_t size) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - int32_t read = 0; - read = mz_stream_read(aes->stream.base, buf, size); - if (read > 0) - { - hmac_sha_data((uint8_t *)buf, read, aes->auth_ctx); - mz_stream_aes_encrypt_data(stream, (uint8_t *)buf, read); - } - - aes->total_in += read; - return read; -} - -int32_t mz_stream_aes_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - int32_t written = 0; - - if (size > (int32_t)sizeof(aes->buffer)) - return MZ_STREAM_ERROR; - - memcpy(aes->buffer, buf, size); - mz_stream_aes_encrypt_data(stream, (uint8_t *)aes->buffer, size); - hmac_sha_data((uint8_t *)aes->buffer, size, aes->auth_ctx); - - written = mz_stream_write(aes->stream.base, aes->buffer, size); - if (written > 0) - aes->total_out += written; - return written; -} - -int64_t mz_stream_aes_tell(void *stream) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - return mz_stream_tell(aes->stream.base); -} - -int32_t mz_stream_aes_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - return mz_stream_seek(aes->stream.base, offset, origin); -} - -int32_t mz_stream_aes_close(void *stream) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - uint8_t authcode[MZ_AES_AUTHCODE_SIZE]; - uint8_t verify_authcode[MZ_AES_AUTHCODE_SIZE]; - - if (MZ_AES_MAC_LENGTH(aes->encryption_mode) != MZ_AES_AUTHCODE_SIZE) - return MZ_STREAM_ERROR; - hmac_sha_end(authcode, MZ_AES_MAC_LENGTH(aes->encryption_mode), aes->auth_ctx); - - if (aes->mode & MZ_OPEN_MODE_WRITE) - { - if (mz_stream_write(aes->stream.base, authcode, MZ_AES_AUTHCODE_SIZE) != MZ_AES_AUTHCODE_SIZE) - return MZ_STREAM_ERROR; - - aes->total_out += MZ_AES_AUTHCODE_SIZE; - } - else if (aes->mode & MZ_OPEN_MODE_READ) - { - if (mz_stream_read(aes->stream.base, verify_authcode, MZ_AES_AUTHCODE_SIZE) != MZ_AES_AUTHCODE_SIZE) - return MZ_STREAM_ERROR; - - aes->total_in += MZ_AES_AUTHCODE_SIZE; - - if (memcmp(authcode, verify_authcode, MZ_AES_AUTHCODE_SIZE) != 0) - return MZ_CRC_ERROR; - } - - aes->initialized = 0; - return MZ_OK; -} - -int32_t mz_stream_aes_error(void *stream) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - return aes->error; -} - -void mz_stream_aes_set_password(void *stream, const char *password) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - aes->password = password; -} - -void mz_stream_aes_set_encryption_mode(void *stream, int16_t encryption_mode) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - aes->encryption_mode = encryption_mode; -} - -int32_t mz_stream_aes_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_aes *aes = (mz_stream_aes *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN: - *value = aes->total_in; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT: - *value = aes->total_out; - return MZ_OK; - case MZ_STREAM_PROP_HEADER_SIZE: - *value = MZ_AES_SALT_LENGTH(aes->encryption_mode) + MZ_AES_PW_VERIFY_SIZE; - return MZ_OK; - case MZ_STREAM_PROP_FOOTER_SIZE: - *value = MZ_AES_AUTHCODE_SIZE; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -void *mz_stream_aes_create(void **stream) -{ - mz_stream_aes *aes = NULL; - - aes = (mz_stream_aes *)MZ_ALLOC(sizeof(mz_stream_aes)); - if (aes != NULL) - { - memset(aes, 0, sizeof(mz_stream_aes)); - aes->stream.vtbl = &mz_stream_aes_vtbl; - aes->encryption_mode = MZ_AES_ENCRYPTION_MODE_256; - } - if (stream != NULL) - *stream = aes; - - return aes; -} - -void mz_stream_aes_delete(void **stream) -{ - mz_stream_aes *aes = NULL; - if (stream == NULL) - return; - aes = (mz_stream_aes *)*stream; - if (aes != NULL) - MZ_FREE(aes); - *stream = NULL; -} - -void *mz_stream_aes_get_interface(void) -{ - return (void *)&mz_stream_aes_vtbl; -} diff --git a/game/client/third/minizip/mz_strm_aes.h b/game/client/third/minizip/mz_strm_aes.h deleted file mode 100755 index 780d0249..00000000 --- a/game/client/third/minizip/mz_strm_aes.h +++ /dev/null @@ -1,48 +0,0 @@ -/* mz_strm_aes.h -- Stream for WinZIP AES encryption - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_AES_H -#define MZ_STREAM_AES_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_aes_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_aes_is_open(void *stream); -int32_t mz_stream_aes_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_aes_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_aes_tell(void *stream); -int32_t mz_stream_aes_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_aes_close(void *stream); -int32_t mz_stream_aes_error(void *stream); - -void mz_stream_aes_set_password(void *stream, const char *password); -void mz_stream_aes_set_encryption_mode(void *stream, int16_t encryption_mode); - -int32_t mz_stream_aes_get_prop_int64(void *stream, int32_t prop, int64_t *value); - -void* mz_stream_aes_create(void **stream); -void mz_stream_aes_delete(void **stream); - -void* mz_stream_aes_get_interface(void); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_buf.c b/game/client/third/minizip/mz_strm_buf.c deleted file mode 100755 index 55fe9bf7..00000000 --- a/game/client/third/minizip/mz_strm_buf.c +++ /dev/null @@ -1,397 +0,0 @@ -/* mz_strm_buf.c -- Stream for buffering reads/writes - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - This version of ioapi is designed to buffer IO. - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - - -#include -#include -#include -#include - -#include "mz.h" -#include "mz_strm.h" -#include "mz_strm_buf.h" - -/***************************************************************************/ - -#if 0 -# define mz_stream_buffered_print(s,f,...) printf(f,__VA_ARGS__); -#else -# define mz_stream_buffered_print(s,f,...) -#endif - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_buffered_vtbl = { - mz_stream_buffered_open, - mz_stream_buffered_is_open, - mz_stream_buffered_read, - mz_stream_buffered_write, - mz_stream_buffered_tell, - mz_stream_buffered_seek, - mz_stream_buffered_close, - mz_stream_buffered_error, - mz_stream_buffered_create, - mz_stream_buffered_delete, - NULL, - NULL -}; - -/***************************************************************************/ - -typedef struct mz_stream_buffered_s { - mz_stream stream; - int32_t error; - char readbuf[INT16_MAX]; - int32_t readbuf_len; - int32_t readbuf_pos; - int32_t readbuf_hits; - int32_t readbuf_misses; - char writebuf[INT16_MAX]; - int32_t writebuf_len; - int32_t writebuf_pos; - int32_t writebuf_hits; - int32_t writebuf_misses; - int64_t position; -} mz_stream_buffered; - -/***************************************************************************/ - -int32_t mz_stream_buffered_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - mz_stream_buffered_print(buffered, "open [mode %d]\n", mode); - return mz_stream_open(buffered->stream.base, path, mode); -} - -int32_t mz_stream_buffered_is_open(void *stream) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - return mz_stream_is_open(buffered->stream.base); -} - -static int32_t mz_stream_buffered_flush(void *stream, int32_t *written) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - int32_t total_bytes_written = 0; - int32_t bytes_to_write = buffered->writebuf_len; - int32_t bytes_left_to_write = buffered->writebuf_len; - int32_t bytes_written = 0; - - *written = 0; - - while (bytes_left_to_write > 0) - { - bytes_written = mz_stream_write(buffered->stream.base, - buffered->writebuf + (bytes_to_write - bytes_left_to_write), bytes_left_to_write); - - if (bytes_written != bytes_left_to_write) - return MZ_STREAM_ERROR; - - buffered->writebuf_misses += 1; - - mz_stream_buffered_print(stream, "write flush [%d:%d len %d]\n", - bytes_to_write, bytes_left_to_write, buffered->writebuf_len); - - total_bytes_written += bytes_written; - bytes_left_to_write -= bytes_written; - buffered->position += bytes_written; - } - - buffered->writebuf_len = 0; - buffered->writebuf_pos = 0; - - *written = total_bytes_written; - return MZ_OK; -} - -int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - int32_t buf_len = 0; - int32_t bytes_to_read = 0; - int32_t bytes_to_copy = 0; - int32_t bytes_left_to_read = size; - int32_t bytes_read = 0; - - mz_stream_buffered_print(stream, "read [size %ld pos %lld]\n", size, buffered->position); - - if (buffered->writebuf_len > 0) - mz_stream_buffered_print(stream, "switch from write to read, not yet supported [%lld]\n", - buffered->position); - - while (bytes_left_to_read > 0) - { - if ((buffered->readbuf_len == 0) || (buffered->readbuf_pos == buffered->readbuf_len)) - { - if (buffered->readbuf_len == sizeof(buffered->readbuf)) - { - buffered->readbuf_pos = 0; - buffered->readbuf_len = 0; - } - - bytes_to_read = sizeof(buffered->readbuf) - (buffered->readbuf_len - buffered->readbuf_pos); - bytes_read = mz_stream_read(buffered->stream.base, buffered->readbuf + buffered->readbuf_pos, bytes_to_read); - if (bytes_read < 0) - return bytes_read; - - buffered->readbuf_misses += 1; - buffered->readbuf_len += bytes_read; - buffered->position += bytes_read; - - mz_stream_buffered_print(stream, "filled [read %d/%d buf %d:%d pos %lld]\n", - bytes_read, bytes_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position); - - if (bytes_read == 0) - break; - } - - if ((buffered->readbuf_len - buffered->readbuf_pos) > 0) - { - bytes_to_copy = (uint32_t)(buffered->readbuf_len - buffered->readbuf_pos); - if (bytes_to_copy > bytes_left_to_read) - bytes_to_copy = bytes_left_to_read; - - memcpy((char *)buf + buf_len, buffered->readbuf + buffered->readbuf_pos, bytes_to_copy); - - buf_len += bytes_to_copy; - bytes_left_to_read -= bytes_to_copy; - - buffered->readbuf_hits += 1; - buffered->readbuf_pos += bytes_to_copy; - - mz_stream_buffered_print(stream, "emptied [copied %d remaining %d buf %d:%d pos %lld]\n", - bytes_to_copy, bytes_left_to_read, buffered->readbuf_pos, buffered->readbuf_len, buffered->position); - } - } - - return size - bytes_left_to_read; -} - -int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - int32_t bytes_to_write = size; - int32_t bytes_left_to_write = size; - int32_t bytes_to_copy = 0; - int32_t bytes_used = 0; - int32_t bytes_flushed = 0; - - - mz_stream_buffered_print(stream, "write [size %ld len %d pos %lld]\n", - size, buffered->writebuf_len, buffered->position); - - if (buffered->readbuf_len > 0) - { - buffered->position -= buffered->readbuf_len; - buffered->position += buffered->readbuf_pos; - - buffered->readbuf_len = 0; - buffered->readbuf_pos = 0; - - mz_stream_buffered_print(stream, "switch from read to write [%lld]\n", buffered->position); - - if (mz_stream_seek(buffered->stream.base, buffered->position, MZ_SEEK_SET) != MZ_OK) - return MZ_STREAM_ERROR; - } - - while (bytes_left_to_write > 0) - { - bytes_used = buffered->writebuf_len; - if (bytes_used > buffered->writebuf_pos) - bytes_used = buffered->writebuf_pos; - bytes_to_copy = (uint32_t)(sizeof(buffered->writebuf) - bytes_used); - if (bytes_to_copy > bytes_left_to_write) - bytes_to_copy = bytes_left_to_write; - - if (bytes_to_copy == 0) - { - if (mz_stream_buffered_flush(stream, &bytes_flushed) != MZ_OK) - return MZ_STREAM_ERROR; - if (bytes_flushed == 0) - return 0; - - continue; - } - - memcpy(buffered->writebuf + buffered->writebuf_pos, (const char *)buf + (bytes_to_write - bytes_left_to_write), bytes_to_copy); - - mz_stream_buffered_print(stream, "write copy [remaining %d write %d:%d len %d]\n", - bytes_to_copy, bytes_to_write, bytes_left_to_write, buffered->writebuf_len); - - bytes_left_to_write -= bytes_to_copy; - - buffered->writebuf_pos += bytes_to_copy; - buffered->writebuf_hits += 1; - if (buffered->writebuf_pos > buffered->writebuf_len) - buffered->writebuf_len += buffered->writebuf_pos - buffered->writebuf_len; - } - - return size - bytes_left_to_write; -} - -int64_t mz_stream_buffered_tell(void *stream) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - int64_t position = mz_stream_tell(buffered->stream.base); - - buffered->position = position; - - mz_stream_buffered_print(stream, "tell [pos %llu readpos %d writepos %d err %d]\n", - buffered->position, buffered->readbuf_pos, buffered->writebuf_pos, errno); - - if (buffered->readbuf_len > 0) - position -= (buffered->readbuf_len - buffered->readbuf_pos); - if (buffered->writebuf_len > 0) - position += buffered->writebuf_pos; - return position; -} - -int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - int32_t bytes_flushed = 0; - - mz_stream_buffered_print(stream, "seek [origin %d offset %llu pos %lld]\n", origin, offset, buffered->position); - - switch (origin) - { - case MZ_SEEK_SET: - - if (buffered->writebuf_len > 0) - { - if ((offset >= buffered->position) && (offset <= buffered->position + buffered->writebuf_len)) - { - buffered->writebuf_pos = (uint32_t)(offset - buffered->position); - return MZ_OK; - } - } - - if ((buffered->readbuf_len > 0) && (offset < buffered->position) && - (offset >= buffered->position - buffered->readbuf_len)) - { - buffered->readbuf_pos = (uint32_t)(offset - (buffered->position - buffered->readbuf_len)); - return MZ_OK; - } - - if (mz_stream_buffered_flush(stream, &bytes_flushed) != MZ_OK) - return MZ_STREAM_ERROR; - - buffered->position = offset; - break; - - case MZ_SEEK_CUR: - - if (buffered->readbuf_len > 0) - { - if (offset <= (buffered->readbuf_len - buffered->readbuf_pos)) - { - buffered->readbuf_pos += (uint32_t)offset; - return MZ_OK; - } - offset -= (buffered->readbuf_len - buffered->readbuf_pos); - buffered->position += offset; - } - if (buffered->writebuf_len > 0) - { - if (offset <= (buffered->writebuf_len - buffered->writebuf_pos)) - { - buffered->writebuf_pos += (uint32_t)offset; - return MZ_OK; - } - //offset -= (buffered->writebuf_len - buffered->writebuf_pos); - } - - if (mz_stream_buffered_flush(stream, &bytes_flushed) != MZ_OK) - return MZ_STREAM_ERROR; - - break; - - case MZ_SEEK_END: - - if (buffered->writebuf_len > 0) - { - buffered->writebuf_pos = buffered->writebuf_len; - return MZ_OK; - } - break; - } - - buffered->readbuf_len = 0; - buffered->readbuf_pos = 0; - buffered->writebuf_len = 0; - buffered->writebuf_pos = 0; - - return mz_stream_seek(buffered->stream.base, offset, origin); -} - -int32_t mz_stream_buffered_close(void *stream) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - int32_t bytes_flushed = 0; - - mz_stream_buffered_flush(stream, &bytes_flushed); - mz_stream_buffered_print(stream, "close [flushed %d]\n", bytes_flushed); - - if (buffered->readbuf_hits + buffered->readbuf_misses > 0) - mz_stream_buffered_print(stream, "read efficency %.02f%%\n", - (buffered->readbuf_hits / ((float)buffered->readbuf_hits + buffered->readbuf_misses)) * 100); - - if (buffered->writebuf_hits + buffered->writebuf_misses > 0) - mz_stream_buffered_print(stream, "write efficency %.02f%%\n", - (buffered->writebuf_hits / ((float)buffered->writebuf_hits + buffered->writebuf_misses)) * 100); - - buffered->readbuf_len = 0; - buffered->readbuf_pos = 0; - buffered->writebuf_len = 0; - buffered->writebuf_pos = 0; - - return mz_stream_close(buffered->stream.base); -} - -int32_t mz_stream_buffered_error(void *stream) -{ - mz_stream_buffered *buffered = (mz_stream_buffered *)stream; - return mz_stream_error(buffered->stream.base); -} - -void *mz_stream_buffered_create(void **stream) -{ - mz_stream_buffered *buffered = NULL; - - buffered = (mz_stream_buffered *)MZ_ALLOC(sizeof(mz_stream_buffered)); - if (buffered != NULL) - { - memset(buffered, 0, sizeof(mz_stream_buffered)); - buffered->stream.vtbl = &mz_stream_buffered_vtbl; - } - if (stream != NULL) - *stream = buffered; - - return buffered; -} - -void mz_stream_buffered_delete(void **stream) -{ - mz_stream_buffered *buffered = NULL; - if (stream == NULL) - return; - buffered = (mz_stream_buffered *)*stream; - if (buffered != NULL) - MZ_FREE(buffered); - *stream = NULL; -} - -void *mz_stream_buffered_get_interface(void) -{ - return (void *)&mz_stream_buffered_vtbl; -} diff --git a/game/client/third/minizip/mz_strm_buf.h b/game/client/third/minizip/mz_strm_buf.h deleted file mode 100755 index 422ef7be..00000000 --- a/game/client/third/minizip/mz_strm_buf.h +++ /dev/null @@ -1,45 +0,0 @@ -/* mz_strm_buf.h -- Stream for buffering reads/writes - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - This version of ioapi is designed to buffer IO. - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_BUFFERED_H -#define MZ_STREAM_BUFFERED_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_buffered_open(void *stream, const char *path, int32_t mode); -int32_t mz_stream_buffered_is_open(void *stream); -int32_t mz_stream_buffered_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_buffered_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_buffered_tell(void *stream); -int32_t mz_stream_buffered_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_buffered_close(void *stream); -int32_t mz_stream_buffered_error(void *stream); - -void* mz_stream_buffered_create(void **stream); -void mz_stream_buffered_delete(void **stream); - -void* mz_stream_buffered_get_interface(void); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_bzip.c b/game/client/third/minizip/mz_strm_bzip.c deleted file mode 100755 index 5a0c525a..00000000 --- a/game/client/third/minizip/mz_strm_bzip.c +++ /dev/null @@ -1,384 +0,0 @@ -/* mz_strm_bzip.c -- Stream for bzip inflate/deflate - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as bzip. - See the accompanying LICENSE file for the full text of the license. -*/ - - -#include -#include -#include -#include - -#include "bzlib.h" - -#include "mz.h" -#include "mz_strm.h" -#include "mz_strm_bzip.h" - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_bzip_vtbl = { - mz_stream_bzip_open, - mz_stream_bzip_is_open, - mz_stream_bzip_read, - mz_stream_bzip_write, - mz_stream_bzip_tell, - mz_stream_bzip_seek, - mz_stream_bzip_close, - mz_stream_bzip_error, - mz_stream_bzip_create, - mz_stream_bzip_delete, - mz_stream_bzip_get_prop_int64, - mz_stream_bzip_set_prop_int64 -}; - -/***************************************************************************/ - -typedef struct mz_stream_bzip_s { - mz_stream stream; - bz_stream bzstream; - int32_t mode; - int32_t error; - uint8_t buffer[INT16_MAX]; - int32_t buffer_len; - int16_t stream_end; - int64_t total_in; - int64_t total_out; - int64_t max_total_in; - int8_t initialized; - int16_t level; -} mz_stream_bzip; - -/***************************************************************************/ - -int32_t mz_stream_bzip_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - - MZ_UNUSED(path); - - bzip->bzstream.bzalloc = 0; - bzip->bzstream.bzfree = 0; - bzip->bzstream.opaque = 0; - bzip->bzstream.total_in_lo32 = 0; - bzip->bzstream.total_in_hi32 = 0; - bzip->bzstream.total_out_lo32 = 0; - bzip->bzstream.total_out_hi32 = 0; - - bzip->total_in = 0; - bzip->total_out = 0; - - if (mode & MZ_OPEN_MODE_WRITE) - { - bzip->bzstream.next_out = (char *)bzip->buffer; - bzip->bzstream.avail_out = sizeof(bzip->buffer); - - bzip->error = BZ2_bzCompressInit(&bzip->bzstream, bzip->level, 0, 0); - } - else if (mode & MZ_OPEN_MODE_READ) - { - bzip->bzstream.next_in = (char *)bzip->buffer; - bzip->bzstream.avail_in = 0; - - bzip->error = BZ2_bzDecompressInit(&bzip->bzstream, 0, 0); - } - - if (bzip->error != BZ_OK) - return MZ_STREAM_ERROR; - - bzip->initialized = 1; - bzip->stream_end = 0; - bzip->mode = mode; - return MZ_OK; -} - -int32_t mz_stream_bzip_is_open(void *stream) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - if (bzip->initialized != 1) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - uint64_t total_in_before = 0; - uint64_t total_out_before = 0; - uint64_t total_in_after = 0; - uint64_t total_out_after = 0; - uint32_t total_in = 0; - uint32_t total_out = 0; - uint32_t in_bytes = 0; - uint32_t out_bytes = 0; - int32_t bytes_to_read = 0; - int32_t read = 0; - int32_t err = BZ_OK; - - - if (bzip->stream_end) - return 0; - - bzip->bzstream.next_out = (char *)buf; - bzip->bzstream.avail_out = (unsigned int)size; - - do - { - if (bzip->bzstream.avail_in == 0) - { - bytes_to_read = sizeof(bzip->buffer); - if (bzip->max_total_in > 0) - { - if ((bzip->max_total_in - bzip->total_in) < (int64_t)sizeof(bzip->buffer)) - bytes_to_read = (int32_t)(bzip->max_total_in - bzip->total_in); - } - - read = mz_stream_read(bzip->stream.base, bzip->buffer, bytes_to_read); - - if (read < 0) - { - bzip->error = BZ_IO_ERROR; - break; - } - if (read == 0) - break; - - bzip->bzstream.next_in = (char *)bzip->buffer; - bzip->bzstream.avail_in = read; - } - - total_in_before = bzip->bzstream.avail_in; - total_out_before = bzip->bzstream.total_out_lo32 + - (((uint64_t)bzip->bzstream.total_out_hi32) << 32); - - err = BZ2_bzDecompress(&bzip->bzstream); - - total_in_after = bzip->bzstream.avail_in; - total_out_after = bzip->bzstream.total_out_lo32 + - (((uint64_t)bzip->bzstream.total_out_hi32) << 32); - - in_bytes = (uint32_t)(total_in_before - total_in_after); - out_bytes = (uint32_t)(total_out_after - total_out_before); - - total_in += in_bytes; - total_out += out_bytes; - - bzip->total_in += in_bytes; - bzip->total_out += out_bytes; - - if (err == BZ_STREAM_END) - { - bzip->stream_end = 1; - break; - } - if (err != BZ_OK && err != BZ_RUN_OK) - { - bzip->error = err; - break; - } - } - while (bzip->bzstream.avail_out > 0); - - if (bzip->error != 0) - return bzip->error; - - return total_out; -} - -static int32_t mz_stream_bzip_flush(void *stream) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - if (mz_stream_write(bzip->stream.base, bzip->buffer, bzip->buffer_len) != bzip->buffer_len) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -static int32_t mz_stream_bzip_compress(void *stream, int flush) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - uint64_t total_out_before = 0; - uint64_t total_out_after = 0; - uint32_t out_bytes = 0; - int32_t err = BZ_OK; - - do - { - if (bzip->bzstream.avail_out == 0) - { - if (mz_stream_bzip_flush(bzip) != MZ_OK) - { - bzip->error = BZ_DATA_ERROR; - return MZ_STREAM_ERROR; - } - - bzip->bzstream.avail_out = sizeof(bzip->buffer); - bzip->bzstream.next_out = (char *)bzip->buffer; - - bzip->buffer_len = 0; - } - - total_out_before = bzip->bzstream.total_out_lo32 + - (((uint64_t)bzip->bzstream.total_out_hi32) << 32); - - err = BZ2_bzCompress(&bzip->bzstream, flush); - - total_out_after = bzip->bzstream.total_out_lo32 + - (((uint64_t)bzip->bzstream.total_out_hi32) << 32); - - out_bytes = (uint32_t)(total_out_after - total_out_before); - - bzip->buffer_len += out_bytes; - bzip->total_out += out_bytes; - - if (err == BZ_STREAM_END) - break; - if (err < 0) - { - bzip->error = err; - return MZ_STREAM_ERROR; - } - } - while ((bzip->bzstream.avail_in > 0) || (flush == BZ_FINISH && err == BZ_FINISH_OK)); - - return MZ_OK; -} - -int32_t mz_stream_bzip_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - - - bzip->bzstream.next_in = (char *)(intptr_t)buf; - bzip->bzstream.avail_in = (unsigned int)size; - - mz_stream_bzip_compress(stream, BZ_RUN); - - bzip->total_in += size; - - return size; -} - -int64_t mz_stream_bzip_tell(void *stream) -{ - MZ_UNUSED(stream); - - return MZ_STREAM_ERROR; -} - -int32_t mz_stream_bzip_seek(void *stream, int64_t offset, int32_t origin) -{ - MZ_UNUSED(stream); - MZ_UNUSED(offset); - MZ_UNUSED(origin); - - return MZ_STREAM_ERROR; -} - -int32_t mz_stream_bzip_close(void *stream) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - - if (bzip->mode & MZ_OPEN_MODE_WRITE) - { - mz_stream_bzip_compress(stream, BZ_FINISH); - mz_stream_bzip_flush(stream); - - BZ2_bzCompressEnd(&bzip->bzstream); - } - else if (bzip->mode & MZ_OPEN_MODE_READ) - { - BZ2_bzDecompressEnd(&bzip->bzstream); - } - - bzip->initialized = 0; - - if (bzip->error != BZ_OK) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_bzip_error(void *stream) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - return bzip->error; -} - -int32_t mz_stream_bzip_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN: - *value = bzip->total_in; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT: - *value = bzip->total_out; - return MZ_OK; - case MZ_STREAM_PROP_HEADER_SIZE: - *value = 0; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -int32_t mz_stream_bzip_set_prop_int64(void *stream, int32_t prop, int64_t value) -{ - mz_stream_bzip *bzip = (mz_stream_bzip *)stream; - switch (prop) - { - case MZ_STREAM_PROP_COMPRESS_LEVEL: - if (value < 0) - bzip->level = 6; - else - bzip->level = (int16_t)value; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_IN_MAX: - bzip->max_total_in = value; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -void *mz_stream_bzip_create(void **stream) -{ - mz_stream_bzip *bzip = NULL; - - bzip = (mz_stream_bzip *)MZ_ALLOC(sizeof(mz_stream_bzip)); - if (bzip != NULL) - { - memset(bzip, 0, sizeof(mz_stream_bzip)); - bzip->stream.vtbl = &mz_stream_bzip_vtbl; - bzip->level = 6; - } - if (stream != NULL) - *stream = bzip; - - return bzip; -} - -void mz_stream_bzip_delete(void **stream) -{ - mz_stream_bzip *bzip = NULL; - if (stream == NULL) - return; - bzip = (mz_stream_bzip *)*stream; - if (bzip != NULL) - MZ_FREE(bzip); - *stream = NULL; -} - -void *mz_stream_bzip_get_interface(void) -{ - return (void *)&mz_stream_bzip_vtbl; -} - -extern void bz_internal_error(int errcode) -{ - MZ_UNUSED(errcode); -} diff --git a/game/client/third/minizip/mz_strm_bzip.h b/game/client/third/minizip/mz_strm_bzip.h deleted file mode 100755 index da0ba92d..00000000 --- a/game/client/third/minizip/mz_strm_bzip.h +++ /dev/null @@ -1,48 +0,0 @@ -/* mz_strm_bzip.h -- Stream for bzip inflate/deflate - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_BZIP_H -#define MZ_STREAM_BZIP_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_bzip_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_bzip_is_open(void *stream); -int32_t mz_stream_bzip_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_bzip_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_bzip_tell(void *stream); -int32_t mz_stream_bzip_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_bzip_close(void *stream); -int32_t mz_stream_bzip_error(void *stream); - -int32_t mz_stream_bzip_get_prop_int64(void *stream, int32_t prop, int64_t *value); -int32_t mz_stream_bzip_set_prop_int64(void *stream, int32_t prop, int64_t value); - -void* mz_stream_bzip_create(void **stream); -void mz_stream_bzip_delete(void **stream); - -void* mz_stream_bzip_get_interface(void); - -void bz_internal_error(int errcode); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_lzma.c b/game/client/third/minizip/mz_strm_lzma.c deleted file mode 100755 index 2c35cbaf..00000000 --- a/game/client/third/minizip/mz_strm_lzma.c +++ /dev/null @@ -1,419 +0,0 @@ -/* mz_strm_lzma.c -- Stream for lzma inflate/deflate - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as lzma. - See the accompanying LICENSE file for the full text of the license. -*/ - - -#include -#include -#include -#include -#include - -#include - -#include "mz.h" -#include "mz_strm.h" -#include "mz_strm_lzma.h" - -/***************************************************************************/ - -#define MZ_LZMA_HEADER_SIZE (4) - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_lzma_vtbl = { - mz_stream_lzma_open, - mz_stream_lzma_is_open, - mz_stream_lzma_read, - mz_stream_lzma_write, - mz_stream_lzma_tell, - mz_stream_lzma_seek, - mz_stream_lzma_close, - mz_stream_lzma_error, - mz_stream_lzma_create, - mz_stream_lzma_delete, - mz_stream_lzma_get_prop_int64, - mz_stream_lzma_set_prop_int64 -}; - -/***************************************************************************/ - -typedef struct mz_stream_lzma_s { - mz_stream stream; - lzma_stream lstream; - int32_t mode; - int32_t error; - uint8_t buffer[INT16_MAX]; - int32_t buffer_len; - int64_t total_in; - int64_t total_out; - int64_t max_total_in; - int64_t max_total_out; - int8_t initialized; - uint32_t preset; -} mz_stream_lzma; - -/***************************************************************************/ - -int32_t mz_stream_lzma_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_options_lzma opt_lzma; - uint32_t size = 0; - uint8_t major = 0; - uint8_t minor = 0; - - MZ_UNUSED(path); - - memset(&opt_lzma, 0, sizeof(opt_lzma)); - - lzma->lstream.total_in = 0; - lzma->lstream.total_out = 0; - - lzma->total_in = 0; - lzma->total_out = 0; - - if (mode & MZ_OPEN_MODE_WRITE) - { - lzma->lstream.next_out = lzma->buffer; - lzma->lstream.avail_out = sizeof(lzma->buffer); - - if (lzma_lzma_preset(&opt_lzma, lzma->preset)) - return MZ_STREAM_ERROR; - - memset(&filters, 0, sizeof(filters)); - - filters[0].id = LZMA_FILTER_LZMA1; - filters[0].options = &opt_lzma; - filters[1].id = LZMA_VLI_UNKNOWN; - - lzma_properties_size(&size, (lzma_filter *)&filters); - - mz_stream_write_uint8(lzma->stream.base, LZMA_VERSION_MAJOR); - mz_stream_write_uint8(lzma->stream.base, LZMA_VERSION_MINOR); - mz_stream_write_uint16(lzma->stream.base, (uint16_t)size); - - lzma->total_out += MZ_LZMA_HEADER_SIZE; - - lzma->error = lzma_alone_encoder(&lzma->lstream, &opt_lzma); - } - else if (mode & MZ_OPEN_MODE_READ) - { - lzma->lstream.next_in = lzma->buffer; - lzma->lstream.avail_in = 0; - - mz_stream_read_uint8(lzma->stream.base, &major); - mz_stream_read_uint8(lzma->stream.base, &minor); - mz_stream_read_uint16(lzma->stream.base, (uint16_t *)&size); - - lzma->total_in += MZ_LZMA_HEADER_SIZE; - - lzma->error = lzma_alone_decoder(&lzma->lstream, UINT64_MAX); - } - - if (lzma->error != LZMA_OK) - return MZ_STREAM_ERROR; - - lzma->initialized = 1; - lzma->mode = mode; - return MZ_OK; -} - -int32_t mz_stream_lzma_is_open(void *stream) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - if (lzma->initialized != 1) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - uint64_t total_in_before = 0; - uint64_t total_out_before = 0; - uint64_t total_in_after = 0; - uint64_t total_out_after = 0; - uint32_t total_in = 0; - uint32_t total_out = 0; - uint32_t in_bytes = 0; - uint32_t out_bytes = 0; - int32_t bytes_to_read = 0; - int32_t read = 0; - int32_t err = LZMA_OK; - - - lzma->lstream.next_out = (uint8_t*)buf; - lzma->lstream.avail_out = (size_t)size; - - do - { - if (lzma->lstream.avail_in == 0) - { - bytes_to_read = sizeof(lzma->buffer); - if (lzma->max_total_in > 0) - { - if ((lzma->max_total_in - lzma->total_in) < (int64_t)sizeof(lzma->buffer)) - bytes_to_read = (int32_t)(lzma->max_total_in - lzma->total_in); - } - - read = mz_stream_read(lzma->stream.base, lzma->buffer, bytes_to_read); - - if (read < 0) - { - lzma->error = MZ_STREAM_ERROR; - break; - } - if (read == 0) - break; - - lzma->lstream.next_in = lzma->buffer; - lzma->lstream.avail_in = read; - } - - total_in_before = lzma->lstream.avail_in; - total_out_before = lzma->lstream.total_out; - - err = lzma_code(&lzma->lstream, LZMA_RUN); - - total_in_after = lzma->lstream.avail_in; - total_out_after = lzma->lstream.total_out; - if ((lzma->max_total_out != -1) && (int64_t)total_out_after > lzma->max_total_out) - total_out_after = lzma->max_total_out; - - in_bytes = (uint32_t)(total_in_before - total_in_after); - out_bytes = (uint32_t)(total_out_after - total_out_before); - - total_in += in_bytes; - total_out += out_bytes; - - lzma->total_in += in_bytes; - lzma->total_out += out_bytes; - - if (err == LZMA_STREAM_END) - break; - if (err != LZMA_OK) - { - lzma->error = err; - break; - } - } - while (lzma->lstream.avail_out > 0); - - if (lzma->error != 0) - return lzma->error; - - return total_out; -} - -static int32_t mz_stream_lzma_flush(void *stream) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - if (mz_stream_write(lzma->stream.base, lzma->buffer, lzma->buffer_len) != lzma->buffer_len) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -static int32_t mz_stream_lzma_code(void *stream, int32_t flush) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - uint64_t total_out_before = 0; - uint64_t total_out_after = 0; - uint32_t out_bytes = 0; - int32_t err = LZMA_OK; - - - do - { - if (lzma->lstream.avail_out == 0) - { - if (mz_stream_lzma_flush(lzma) != MZ_OK) - { - lzma->error = MZ_STREAM_ERROR; - return MZ_STREAM_ERROR; - } - - lzma->lstream.avail_out = sizeof(lzma->buffer); - lzma->lstream.next_out = lzma->buffer; - - lzma->buffer_len = 0; - } - - total_out_before = lzma->lstream.total_out; - err = lzma_code(&lzma->lstream, flush); - total_out_after = lzma->lstream.total_out; - - out_bytes = (uint32_t)(total_out_after - total_out_before); - - if (err != LZMA_OK && err != LZMA_STREAM_END) - { - lzma->error = err; - return MZ_STREAM_ERROR; - } - - lzma->buffer_len += out_bytes; - lzma->total_out += out_bytes; - } - while (lzma->lstream.avail_in > 0); - - return MZ_OK; -} - -int32_t mz_stream_lzma_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - - - lzma->lstream.next_in = (uint8_t*)(intptr_t)buf; - lzma->lstream.avail_in = (size_t)size; - - mz_stream_lzma_code(stream, LZMA_RUN); - - lzma->total_in += size; - - return size; -} - -int64_t mz_stream_lzma_tell(void *stream) -{ - MZ_UNUSED(stream); - - return MZ_STREAM_ERROR; -} - -int32_t mz_stream_lzma_seek(void *stream, int64_t offset, int32_t origin) -{ - MZ_UNUSED(stream); - MZ_UNUSED(offset); - MZ_UNUSED(origin); - - return MZ_STREAM_ERROR; -} - -int32_t mz_stream_lzma_close(void *stream) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - - if (lzma->mode & MZ_OPEN_MODE_WRITE) - { - mz_stream_lzma_code(stream, LZMA_FINISH); - mz_stream_lzma_flush(stream); - - lzma_end(&lzma->lstream); - } - else if (lzma->mode & MZ_OPEN_MODE_READ) - { - lzma_end(&lzma->lstream); - } - - lzma->initialized = 0; - - if (lzma->error != LZMA_OK) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_lzma_error(void *stream) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - return lzma->error; -} - -int32_t mz_stream_lzma_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN: - *value = lzma->total_in; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT: - *value = lzma->total_out; - return MZ_OK; - case MZ_STREAM_PROP_HEADER_SIZE: - *value = MZ_LZMA_HEADER_SIZE; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -int32_t mz_stream_lzma_set_prop_int64(void *stream, int32_t prop, int64_t value) -{ - mz_stream_lzma *lzma = (mz_stream_lzma *)stream; - switch (prop) - { - case MZ_STREAM_PROP_COMPRESS_LEVEL: - if (value >= 9) - lzma->preset = LZMA_PRESET_EXTREME; - else - lzma->preset = LZMA_PRESET_DEFAULT; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_IN_MAX: - lzma->max_total_in = value; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT_MAX: - if (value < -1) - return MZ_PARAM_ERROR; - lzma->max_total_out = value; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -void *mz_stream_lzma_create(void **stream) -{ - mz_stream_lzma *lzma = NULL; - - lzma = (mz_stream_lzma *)MZ_ALLOC(sizeof(mz_stream_lzma)); - if (lzma != NULL) - { - memset(lzma, 0, sizeof(mz_stream_lzma)); - lzma->stream.vtbl = &mz_stream_lzma_vtbl; - lzma->preset = LZMA_PRESET_DEFAULT; - lzma->max_total_out = -1; - } - if (stream != NULL) - *stream = lzma; - - return lzma; -} - -void mz_stream_lzma_delete(void **stream) -{ - mz_stream_lzma *lzma = NULL; - if (stream == NULL) - return; - lzma = (mz_stream_lzma *)*stream; - if (lzma != NULL) - MZ_FREE(lzma); - *stream = NULL; -} - -void *mz_stream_lzma_get_interface(void) -{ - return (void *)&mz_stream_lzma_vtbl; -} - -static int64_t mz_stream_lzma_crc32(int64_t value, const void *buf, int32_t size) -{ - return (int32_t)lzma_crc32(buf, size, (int32_t)value); -} - -void *mz_stream_lzma_get_crc32_table(void) -{ - extern const uint32_t lzma_crc32_table; - return (void *)lzma_crc32_table; -} - -void *mz_stream_lzma_get_crc32_update(void) -{ - return (void *)mz_stream_lzma_crc32; -} diff --git a/game/client/third/minizip/mz_strm_lzma.h b/game/client/third/minizip/mz_strm_lzma.h deleted file mode 100755 index ed14df70..00000000 --- a/game/client/third/minizip/mz_strm_lzma.h +++ /dev/null @@ -1,48 +0,0 @@ -/* mz_strm_lzma.h -- Stream for lzma inflate/deflate - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as lzma. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_LZMA_H -#define MZ_STREAM_LZMA_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_lzma_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_lzma_is_open(void *stream); -int32_t mz_stream_lzma_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_lzma_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_lzma_tell(void *stream); -int32_t mz_stream_lzma_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_lzma_close(void *stream); -int32_t mz_stream_lzma_error(void *stream); - -int32_t mz_stream_lzma_get_prop_int64(void *stream, int32_t prop, int64_t *value); -int32_t mz_stream_lzma_set_prop_int64(void *stream, int32_t prop, int64_t value); - -void* mz_stream_lzma_create(void **stream); -void mz_stream_lzma_delete(void **stream); - -void* mz_stream_lzma_get_interface(void); -void* mz_stream_lzma_get_crc32_table(void); -void* mz_stream_lzma_get_crc32_update(void); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_mem.c b/game/client/third/minizip/mz_strm_mem.c deleted file mode 100755 index 7a13f28a..00000000 --- a/game/client/third/minizip/mz_strm_mem.c +++ /dev/null @@ -1,278 +0,0 @@ -/* mz_strm_mem.c -- Stream for memory access - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - This interface is designed to access memory rather than files. - We do use a region of memory to put data in to and take it out of. - - Based on Unzip ioapi.c version 0.22, May 19th, 2003 - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2003 Justin Fletcher - Copyright (C) 1998-2003 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - - -#include -#include -#include - -#include "mz.h" -#include "mz_strm.h" -#include "mz_strm_mem.h" - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_mem_vtbl = { - mz_stream_mem_open, - mz_stream_mem_is_open, - mz_stream_mem_read, - mz_stream_mem_write, - mz_stream_mem_tell, - mz_stream_mem_seek, - mz_stream_mem_close, - mz_stream_mem_error, - mz_stream_mem_create, - mz_stream_mem_delete, - NULL, - NULL -}; - -/***************************************************************************/ - -typedef struct mz_stream_mem_s { - mz_stream stream; - int32_t mode; - char *buffer; // Memory buffer pointer - int32_t size; // Size of the memory buffer - int32_t limit; // Furthest we've written - int32_t position; // Current position in the memory - int32_t grow_size; // Size to grow when full -} mz_stream_mem; - -/***************************************************************************/ - -static void mz_stream_mem_set_size(void *stream, int32_t size) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - int32_t new_size = size; - char *new_buf = NULL; - - - new_buf = (char *)MZ_ALLOC(new_size); - if (mem->buffer) - { - memcpy(new_buf, mem->buffer, mem->size); - MZ_FREE(mem->buffer); - } - - mem->buffer = new_buf; - mem->size = new_size; -} - -int32_t mz_stream_mem_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - - MZ_UNUSED(path); - - mem->mode = mode; - mem->limit = 0; - mem->position = 0; - - if (mem->mode & MZ_OPEN_MODE_CREATE) - mz_stream_mem_set_size(stream, mem->grow_size); - else - mem->limit = mem->size; - - return MZ_OK; -} - -int32_t mz_stream_mem_is_open(void *stream) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - if (mem->buffer == NULL) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_mem_read(void *stream, void *buf, int32_t size) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - - if (size > mem->size - mem->position) - size = mem->size - mem->position; - - if (mem->position + size > mem->limit) - return 0; - - memcpy(buf, mem->buffer + mem->position, size); - mem->position += size; - - return size; -} - -int32_t mz_stream_mem_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - int32_t new_size = 0; - - if (size == 0) - return size; - - if (size > mem->size - mem->position) - { - if (mem->mode & MZ_OPEN_MODE_CREATE) - { - new_size = mem->size; - if (size < mem->grow_size) - new_size += mem->grow_size; - else - new_size += size; - - mz_stream_mem_set_size(stream, new_size); - } - else - { - size = mem->size - mem->position; - } - } - - memcpy(mem->buffer + mem->position, buf, size); - - mem->position += size; - if (mem->position > mem->limit) - mem->limit = mem->position; - - return size; -} - -int64_t mz_stream_mem_tell(void *stream) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - return mem->position; -} - -int32_t mz_stream_mem_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - int64_t new_pos = 0; - - switch (origin) - { - case MZ_SEEK_CUR: - new_pos = mem->position + offset; - break; - case MZ_SEEK_END: - new_pos = mem->limit + offset; - break; - case MZ_SEEK_SET: - new_pos = offset; - break; - default: - return MZ_STREAM_ERROR; - } - - if (new_pos > mem->size) - { - if ((mem->mode & MZ_OPEN_MODE_CREATE) == 0) - return MZ_STREAM_ERROR; - - mz_stream_mem_set_size(stream, (int32_t)new_pos); - } - - mem->position = (uint32_t)new_pos; - return MZ_OK; -} - -int32_t mz_stream_mem_close(void *stream) -{ - MZ_UNUSED(stream); - - // We never return errors - return MZ_OK; -} - -int32_t mz_stream_mem_error(void *stream) -{ - MZ_UNUSED(stream); - - // We never return errors - return MZ_OK; -} - -void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - mem->buffer = buf; - mem->size = size; - mem->limit = size; -} - -int32_t mz_stream_mem_get_buffer(void *stream, const void **buf) -{ - return mz_stream_mem_get_buffer_at(stream, 0, buf); -} - -int32_t mz_stream_mem_get_buffer_at(void *stream, int64_t position, const void **buf) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - if (buf == NULL || position < 0 || mem->size < position || mem->buffer == NULL) - return MZ_STREAM_ERROR; - *buf = mem->buffer + position; - return MZ_OK; -} - -void mz_stream_mem_get_buffer_length(void *stream, int32_t *length) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - *length = mem->limit; -} - -void mz_stream_mem_set_grow_size(void *stream, int32_t grow_size) -{ - mz_stream_mem *mem = (mz_stream_mem *)stream; - mem->grow_size = grow_size; -} - -void *mz_stream_mem_create(void **stream) -{ - mz_stream_mem *mem = NULL; - - mem = (mz_stream_mem *)MZ_ALLOC(sizeof(mz_stream_mem)); - if (mem != NULL) - { - memset(mem, 0, sizeof(mz_stream_mem)); - mem->stream.vtbl = &mz_stream_mem_vtbl; - mem->grow_size = 4096; - } - if (stream != NULL) - *stream = mem; - - return mem; -} - -void mz_stream_mem_delete(void **stream) -{ - mz_stream_mem *mem = NULL; - if (stream == NULL) - return; - mem = (mz_stream_mem *)*stream; - if (mem != NULL) - { - if ((mem->mode & MZ_OPEN_MODE_CREATE) && (mem->buffer != NULL)) - MZ_FREE(mem->buffer); - MZ_FREE(mem); - } - *stream = NULL; -} - -void *mz_stream_mem_get_interface(void) -{ - return (void *)&mz_stream_mem_vtbl; -} diff --git a/game/client/third/minizip/mz_strm_mem.h b/game/client/third/minizip/mz_strm_mem.h deleted file mode 100755 index 8a3ce11b..00000000 --- a/game/client/third/minizip/mz_strm_mem.h +++ /dev/null @@ -1,51 +0,0 @@ -/* mz_strm_mem.h -- Stream for memory access - Version 2.3.3, June 10, 2018 - part of MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2003 Justin Fletcher - Copyright (C) 1998-2003 Gilles Vollant - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_MEM_H -#define MZ_STREAM_MEM_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_mem_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_mem_is_open(void *stream); -int32_t mz_stream_mem_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_mem_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_mem_tell(void *stream); -int32_t mz_stream_mem_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_mem_close(void *stream); -int32_t mz_stream_mem_error(void *stream); - -void mz_stream_mem_set_buffer(void *stream, void *buf, int32_t size); -int32_t mz_stream_mem_get_buffer(void *stream, const void **buf); -int32_t mz_stream_mem_get_buffer_at(void *stream, int64_t position, const void **buf); -void mz_stream_mem_get_buffer_length(void *stream, int32_t *length); -void mz_stream_mem_set_grow_size(void *stream, int32_t grow_size); - -void* mz_stream_mem_create(void **stream); -void mz_stream_mem_delete(void **stream); - -void* mz_stream_mem_get_interface(void); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_pkcrypt.c b/game/client/third/minizip/mz_strm_pkcrypt.c deleted file mode 100755 index a05b578b..00000000 --- a/game/client/third/minizip/mz_strm_pkcrypt.c +++ /dev/null @@ -1,352 +0,0 @@ -/* mz_strm_pkcrypt.c -- Code for traditional PKWARE encryption - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 1998-2005 Gilles Vollant - Modifications for Info-ZIP crypting - http://www.winimage.com/zLibDll/minizip.html - Copyright (C) 2003 Terry Thorsen - - This code is a modified version of crypting code in Info-ZIP distribution - - Copyright (C) 1990-2000 Info-ZIP. All rights reserved. - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. - - This encryption code is a direct transcription of the algorithm from - Roger Schlafly, described by Phil Katz in the file appnote.txt. This - file (appnote.txt) is distributed with the PKZIP program (even in the - version without encryption capabilities). -*/ - - -#include -#include -#include - -#ifdef HAVE_ZLIB -#include "zlib.h" -#endif - -#include "mz.h" -#include "mz_os.h" -#include "mz_strm.h" -#ifdef HAVE_LZMA -#include "mz_strm_lzma.h" -#endif -#include "mz_strm_pkcrypt.h" -#ifdef HAVE_ZLIB -#include "mz_strm_zlib.h" -#endif - -/***************************************************************************/ - -#define RAND_HEAD_LEN 12 - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_pkcrypt_vtbl = { - mz_stream_pkcrypt_open, - mz_stream_pkcrypt_is_open, - mz_stream_pkcrypt_read, - mz_stream_pkcrypt_write, - mz_stream_pkcrypt_tell, - mz_stream_pkcrypt_seek, - mz_stream_pkcrypt_close, - mz_stream_pkcrypt_error, - mz_stream_pkcrypt_create, - mz_stream_pkcrypt_delete, - mz_stream_pkcrypt_get_prop_int64, - NULL -}; - -/***************************************************************************/ - -// Define z_crc_t in zlib 1.2.5 and less or if using zlib-ng -#if (ZLIB_VERNUM < 0x1270) || defined(ZLIBNG_VERNUM) || !defined(HAVE_ZLIB) -#ifdef HAVE_ZLIB - typedef unsigned long z_crc_t; -#else - typedef uint32_t z_crc_t; -#endif -#endif - -/***************************************************************************/ - -typedef struct mz_stream_pkcrypt_s { - mz_stream stream; - int32_t error; - int16_t initialized; - uint8_t buffer[INT16_MAX]; - int64_t total_in; - int64_t total_out; - uint32_t keys[3]; // keys defining the pseudo-random sequence - const z_crc_t *crc_32_tab; - uint8_t verify1; - uint8_t verify2; - const char *password; -} mz_stream_pkcrypt; - -/***************************************************************************/ - -#define zdecode(keys,crc_32_tab,c) \ - (mz_stream_pkcrypt_update_keys(keys,crc_32_tab, c ^= mz_stream_pkcrypt_decrypt_byte(keys))) - -#define zencode(keys,crc_32_tab,c,t) \ - (t = mz_stream_pkcrypt_decrypt_byte(keys), mz_stream_pkcrypt_update_keys(keys,crc_32_tab,c), t^(c)) - -/***************************************************************************/ - -static uint8_t mz_stream_pkcrypt_decrypt_byte(uint32_t *keys) -{ - unsigned temp; /* POTENTIAL BUG: temp*(temp^1) may overflow in an - * unpredictable manner on 16-bit systems; not a problem - * with any known compiler so far, though */ - - temp = ((uint32_t)(*(keys+2)) & 0xffff) | 2; - return (uint8_t)(((temp * (temp ^ 1)) >> 8) & 0xff); -} - -static uint8_t mz_stream_pkcrypt_update_keys(uint32_t *keys, const z_crc_t *crc_32_tab, int32_t c) -{ - #define CRC32(c, b) ((*(crc_32_tab+(((uint32_t)(c) ^ (b)) & 0xff))) ^ ((c) >> 8)) - - (*(keys+0)) = (uint32_t)CRC32((*(keys+0)), c); - (*(keys+1)) += (*(keys+0)) & 0xff; - (*(keys+1)) = (*(keys+1)) * 134775813L + 1; - { - register int32_t keyshift = (int32_t)((*(keys + 1)) >> 24); - (*(keys+2)) = (uint32_t)CRC32((*(keys+2)), keyshift); - } - return (uint8_t)c; -} - -static void mz_stream_pkcrypt_init_keys(const char *password, uint32_t *keys, const z_crc_t *crc_32_tab) -{ - *(keys+0) = 305419896L; - *(keys+1) = 591751049L; - *(keys+2) = 878082192L; - - while (*password != 0) - { - mz_stream_pkcrypt_update_keys(keys, crc_32_tab, *password); - password += 1; - } -} - -/***************************************************************************/ - -int32_t mz_stream_pkcrypt_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - uint16_t t = 0; - int16_t i = 0; - //uint8_t verify1 = 0; - uint8_t verify2 = 0; - uint8_t header[RAND_HEAD_LEN]; - const char *password = path; - - pkcrypt->total_in = 0; - pkcrypt->total_out = 0; - pkcrypt->initialized = 0; - - if (mz_stream_is_open(pkcrypt->stream.base) != MZ_OK) - return MZ_STREAM_ERROR; - - if (password == NULL) - password = pkcrypt->password; - if (password == NULL) - return MZ_STREAM_ERROR; - -#ifdef HAVE_ZLIB - pkcrypt->crc_32_tab = (z_crc_t *)mz_stream_zlib_get_crc32_table(); -#elif defined(HAVE_LZMA) - pkcrypt->crc_32_tab = (z_crc_t *)mz_stream_lzma_get_crc32_table(); -#else -#error ZLIB or LZMA required for CRC32 -#endif - - if (pkcrypt->crc_32_tab == NULL) - return MZ_STREAM_ERROR; - - mz_stream_pkcrypt_init_keys(password, pkcrypt->keys, pkcrypt->crc_32_tab); - - if (mode & MZ_OPEN_MODE_WRITE) - { - // First generate RAND_HEAD_LEN - 2 random bytes. - mz_os_rand(header, RAND_HEAD_LEN - 2); - - // Encrypt random header (last two bytes is high word of crc) - for (i = 0; i < RAND_HEAD_LEN - 2; i++) - header[i] = (uint8_t)zencode(pkcrypt->keys, pkcrypt->crc_32_tab, header[i], t); - - header[i++] = (uint8_t)zencode(pkcrypt->keys, pkcrypt->crc_32_tab, pkcrypt->verify1, t); - header[i++] = (uint8_t)zencode(pkcrypt->keys, pkcrypt->crc_32_tab, pkcrypt->verify2, t); - - if (mz_stream_write(pkcrypt->stream.base, header, RAND_HEAD_LEN) != RAND_HEAD_LEN) - return MZ_STREAM_ERROR; - - pkcrypt->total_out += RAND_HEAD_LEN; - } - else if (mode & MZ_OPEN_MODE_READ) - { - if (mz_stream_read(pkcrypt->stream.base, header, RAND_HEAD_LEN) != RAND_HEAD_LEN) - return MZ_STREAM_ERROR; - - for (i = 0; i < RAND_HEAD_LEN - 2; i++) - header[i] = (uint8_t)zdecode(pkcrypt->keys, pkcrypt->crc_32_tab, header[i]); - - //verify1 = (uint8_t)zdecode(crypt->keys, crypt->crc_32_tab, header[i++]); - verify2 = (uint8_t)zdecode(pkcrypt->keys, pkcrypt->crc_32_tab, header[i++]); - - // Older versions used 2 byte check, newer versions use 1 byte check. - if ((verify2 != 0) && (verify2 != pkcrypt->verify2)) - return MZ_PASSWORD_ERROR; - - pkcrypt->total_in += RAND_HEAD_LEN; - } - - pkcrypt->initialized = 1; - return MZ_OK; -} - -int32_t mz_stream_pkcrypt_is_open(void *stream) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - if (pkcrypt->initialized == 0) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_pkcrypt_read(void *stream, void *buf, int32_t size) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - uint8_t *buf_ptr = (uint8_t *)buf; - int32_t read = 0; - int32_t i = 0; - - read = mz_stream_read(pkcrypt->stream.base, buf, size); - - for (i = 0; i < read; i++) - buf_ptr[i] = (uint8_t)zdecode(pkcrypt->keys, pkcrypt->crc_32_tab, buf_ptr[i]); - - pkcrypt->total_in += read; - return read; -} - -int32_t mz_stream_pkcrypt_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - const uint8_t *buf_ptr = (const uint8_t *)buf; - int32_t written = 0; - int32_t i = 0; - uint16_t t = 0; - - if (size > (int32_t)sizeof(pkcrypt->buffer)) - return MZ_STREAM_ERROR; - - for (i = 0; i < size; i++) - pkcrypt->buffer[i] = (uint8_t)zencode(pkcrypt->keys, pkcrypt->crc_32_tab, buf_ptr[i], t); - - written = mz_stream_write(pkcrypt->stream.base, pkcrypt->buffer, size); - - if (written > 0) - pkcrypt->total_out += written; - - return written; -} - -int64_t mz_stream_pkcrypt_tell(void *stream) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - return mz_stream_tell(pkcrypt->stream.base); -} - -int32_t mz_stream_pkcrypt_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - return mz_stream_seek(pkcrypt->stream.base, offset, origin); -} - -int32_t mz_stream_pkcrypt_close(void *stream) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - pkcrypt->initialized = 0; - return MZ_OK; -} - -int32_t mz_stream_pkcrypt_error(void *stream) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - return pkcrypt->error; -} - -void mz_stream_pkcrypt_set_password(void *stream, const char *password) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - pkcrypt->password = password; -} - -void mz_stream_pkcrypt_set_verify(void *stream, uint8_t verify1, uint8_t verify2) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - pkcrypt->verify1 = verify1; - pkcrypt->verify2 = verify2; -} - -void mz_stream_pkcrypt_get_verify(void *stream, uint8_t *verify1, uint8_t *verify2) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - *verify1 = pkcrypt->verify1; - *verify2 = pkcrypt->verify2; -} - -int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_pkcrypt *pkcrypt = (mz_stream_pkcrypt *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN: - *value = pkcrypt->total_in; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT: - *value = pkcrypt->total_out; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -void *mz_stream_pkcrypt_create(void **stream) -{ - mz_stream_pkcrypt *pkcrypt = NULL; - - pkcrypt = (mz_stream_pkcrypt *)MZ_ALLOC(sizeof(mz_stream_pkcrypt)); - if (pkcrypt != NULL) - { - memset(pkcrypt, 0, sizeof(mz_stream_pkcrypt)); - pkcrypt->stream.vtbl = &mz_stream_pkcrypt_vtbl; - } - - if (stream != NULL) - *stream = pkcrypt; - return pkcrypt; -} - -void mz_stream_pkcrypt_delete(void **stream) -{ - mz_stream_pkcrypt *pkcrypt = NULL; - if (stream == NULL) - return; - pkcrypt = (mz_stream_pkcrypt *)*stream; - if (pkcrypt != NULL) - MZ_FREE(pkcrypt); - *stream = NULL; -} - -void *mz_stream_pkcrypt_get_interface(void) -{ - return (void *)&mz_stream_pkcrypt_vtbl; -} diff --git a/game/client/third/minizip/mz_strm_pkcrypt.h b/game/client/third/minizip/mz_strm_pkcrypt.h deleted file mode 100755 index cff2d8fe..00000000 --- a/game/client/third/minizip/mz_strm_pkcrypt.h +++ /dev/null @@ -1,56 +0,0 @@ -/* mz_strm_pkcrypt.h -- Code for traditional PKWARE encryption - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 1998-2005 Gilles Vollant - Modifications for Info-ZIP crypting - http://www.winimage.com/zLibDll/minizip.html - Copyright (C) 2003 Terry Thorsen - - This code is a modified version of crypting code in Info-ZIP distribution - - Copyright (C) 1990-2000 Info-ZIP. All rights reserved. - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_PKCRYPT_H -#define MZ_STREAM_PKCRYPT_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_pkcrypt_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_pkcrypt_is_open(void *stream); -int32_t mz_stream_pkcrypt_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_pkcrypt_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_pkcrypt_tell(void *stream); -int32_t mz_stream_pkcrypt_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_pkcrypt_close(void *stream); -int32_t mz_stream_pkcrypt_error(void *stream); - -void mz_stream_pkcrypt_set_password(void *stream, const char *password); -void mz_stream_pkcrypt_set_verify(void *stream, uint8_t verify1, uint8_t verify2); -void mz_stream_pkcrypt_get_verify(void *stream, uint8_t *verify1, uint8_t *verify2); -int32_t mz_stream_pkcrypt_get_prop_int64(void *stream, int32_t prop, int64_t *value); - -void* mz_stream_pkcrypt_create(void **stream); -void mz_stream_pkcrypt_delete(void **stream); - -void* mz_stream_pkcrypt_get_interface(void); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_posix.c b/game/client/third/minizip/mz_strm_posix.c deleted file mode 100755 index 89991743..00000000 --- a/game/client/third/minizip/mz_strm_posix.c +++ /dev/null @@ -1,232 +0,0 @@ -/* mz_strm_posix.c -- Stream for filesystem access for posix/linux - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Modifications for Zip64 support - Copyright (C) 2009-2010 Mathias Svensson - http://result42.com - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#include -#include -#include -#include - -#include "mz.h" -#include "mz_strm.h" -#include "mz_strm_posix.h" - -/***************************************************************************/ - -#if defined(MZ_USE_FILE32API) -# define fopen64 fopen -# define ftello64 ftell -# define fseeko64 fseek -#else -# if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \ - defined(__OpenBSD__) || defined(__APPLE__) || defined(__ANDROID__) -# define fopen64 fopen -# define ftello64 ftello -# define fseeko64 fseeko -# endif -# ifdef _MSC_VER -# define fopen64 fopen -# if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC))) -# define ftello64 _ftelli64 -# define fseeko64 _fseeki64 -# else /* old MSC */ -# define ftello64 ftell -# define fseeko64 fseek -# endif -# endif -#endif - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_posix_vtbl = { - mz_stream_posix_open, - mz_stream_posix_is_open, - mz_stream_posix_read, - mz_stream_posix_write, - mz_stream_posix_tell, - mz_stream_posix_seek, - mz_stream_posix_close, - mz_stream_posix_error, - mz_stream_posix_create, - mz_stream_posix_delete, - NULL, - NULL -}; - -/***************************************************************************/ - -typedef struct mz_stream_posix_s -{ - mz_stream stream; - int32_t error; - FILE *handle; -} mz_stream_posix; - -/***************************************************************************/ - -int32_t mz_stream_posix_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_posix *posix = (mz_stream_posix *)stream; - const char *mode_fopen = NULL; - - if (path == NULL) - return MZ_STREAM_ERROR; - - if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ) - mode_fopen = "rb"; - else if (mode & MZ_OPEN_MODE_APPEND) - mode_fopen = "r+b"; - else if (mode & MZ_OPEN_MODE_CREATE) - mode_fopen = "wb"; - else - return MZ_STREAM_ERROR; - - posix->handle = fopen64(path, mode_fopen); - if (posix->handle == NULL) - { - posix->error = errno; - return MZ_STREAM_ERROR; - } - - return MZ_OK; -} - -int32_t mz_stream_posix_is_open(void *stream) -{ - mz_stream_posix *posix = (mz_stream_posix*)stream; - if (posix->handle == NULL) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_posix_read(void *stream, void *buf, int32_t size) -{ - mz_stream_posix *posix = (mz_stream_posix*)stream; - int32_t read = (int32_t)fread(buf, 1, (size_t)size, posix->handle); - if (read < size && ferror(posix->handle)) - { - posix->error = errno; - return MZ_STREAM_ERROR; - } - return read; -} - -int32_t mz_stream_posix_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_posix *posix = (mz_stream_posix*)stream; - int32_t written = (int32_t)fwrite(buf, 1, (size_t)size, posix->handle); - if (written < size && ferror(posix->handle)) - { - posix->error = errno; - return MZ_STREAM_ERROR; - } - return written; -} - -int64_t mz_stream_posix_tell(void *stream) -{ - mz_stream_posix *posix = (mz_stream_posix*)stream; - int64_t position = ftello64(posix->handle); - if (position == -1) - { - posix->error = errno; - return MZ_STREAM_ERROR; - } - return position; -} - -int32_t mz_stream_posix_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_posix *posix = (mz_stream_posix*)stream; - int32_t fseek_origin = 0; - - switch (origin) - { - case MZ_SEEK_CUR: - fseek_origin = SEEK_CUR; - break; - case MZ_SEEK_END: - fseek_origin = SEEK_END; - break; - case MZ_SEEK_SET: - fseek_origin = SEEK_SET; - break; - default: - return MZ_STREAM_ERROR; - } - - if (fseeko64(posix->handle, offset, fseek_origin) != 0) - { - posix->error = errno; - return MZ_STREAM_ERROR; - } - - return MZ_OK; -} - -int32_t mz_stream_posix_close(void *stream) -{ - mz_stream_posix *posix = (mz_stream_posix*)stream; - int32_t closed = 0; - if (posix->handle != NULL) - { - closed = fclose(posix->handle); - posix->handle = NULL; - } - if (closed != 0) - { - posix->error = errno; - return MZ_STREAM_ERROR; - } - return MZ_OK; -} - -int32_t mz_stream_posix_error(void *stream) -{ - mz_stream_posix *posix = (mz_stream_posix*)stream; - return posix->error; -} - -void *mz_stream_posix_create(void **stream) -{ - mz_stream_posix *posix = NULL; - - posix = (mz_stream_posix *)MZ_ALLOC(sizeof(mz_stream_posix)); - if (posix != NULL) - { - memset(posix, 0, sizeof(mz_stream_posix)); - posix->stream.vtbl = &mz_stream_posix_vtbl; - } - if (stream != NULL) - *stream = posix; - - return posix; -} - -void mz_stream_posix_delete(void **stream) -{ - mz_stream_posix *posix = NULL; - if (stream == NULL) - return; - posix = (mz_stream_posix *)*stream; - if (posix != NULL) - MZ_FREE(posix); - *stream = NULL; -} - -void *mz_stream_posix_get_interface(void) -{ - return (void *)&mz_stream_posix_vtbl; -} diff --git a/game/client/third/minizip/mz_strm_posix.h b/game/client/third/minizip/mz_strm_posix.h deleted file mode 100755 index f64c573d..00000000 --- a/game/client/third/minizip/mz_strm_posix.h +++ /dev/null @@ -1,67 +0,0 @@ -/* mz_strm_posix.h -- Stream for filesystem access for posix/linux - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2009-2010 Mathias Svensson - Modifications for Zip64 support - http://result42.com - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_POSIX_H -#define MZ_STREAM_POSIX_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_posix_open(void *stream, const char *path, int32_t mode); -int32_t mz_stream_posix_is_open(void *stream); -int32_t mz_stream_posix_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_posix_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_posix_tell(void *stream); -int32_t mz_stream_posix_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_posix_close(void *stream); -int32_t mz_stream_posix_error(void *stream); - -void* mz_stream_posix_create(void **stream); -void mz_stream_posix_delete(void **stream); - -void* mz_stream_posix_get_interface(void); - -/***************************************************************************/ - -#if !defined(_WIN32) && !defined(MZ_USE_WIN32_API) -#define mz_stream_os_open mz_stream_posix_open -#define mz_stream_os_is_open mz_stream_posix_is_open -#define mz_stream_os_read mz_stream_posix_read -#define mz_stream_os_write mz_stream_posix_write -#define mz_stream_os_tell mz_stream_posix_tell -#define mz_stream_os_seek mz_stream_posix_seek -#define mz_stream_os_close mz_stream_posix_close -#define mz_stream_os_error mz_stream_posix_error - -#define mz_stream_os_create mz_stream_posix_create -#define mz_stream_os_delete mz_stream_posix_delete - -#define mz_stream_os_get_interface \ - mz_stream_posix_get_interface -#endif - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_split.c b/game/client/third/minizip/mz_strm_split.c deleted file mode 100755 index 1274a681..00000000 --- a/game/client/third/minizip/mz_strm_split.c +++ /dev/null @@ -1,405 +0,0 @@ -/* mz_strm_split.c -- Stream for split files - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - - -#include -#include -#undef strncpy -#include - -#include "mz.h" -#include "mz_os.h" -#include "mz_strm.h" -#include "mz_strm_split.h" - -/***************************************************************************/ - -#define MZ_ZIP_MAGIC_DISKHEADER (0x08074b50) - -#if defined(_MSC_VER) && _MSC_VER < 1900 -# define snprintf _snprintf -#endif - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_split_vtbl = { - mz_stream_split_open, - mz_stream_split_is_open, - mz_stream_split_read, - mz_stream_split_write, - mz_stream_split_tell, - mz_stream_split_seek, - mz_stream_split_close, - mz_stream_split_error, - mz_stream_split_create, - mz_stream_split_delete, - mz_stream_split_get_prop_int64, - mz_stream_split_set_prop_int64 -}; - -/***************************************************************************/ - -typedef struct mz_stream_split_s { - mz_stream stream; - int32_t is_open; - int64_t disk_size; - int64_t total_in; - int64_t total_in_disk; - int64_t total_out; - int64_t total_out_disk; - int32_t mode; - char *path_cd; - int32_t path_cd_size; - char *path_disk; - int32_t path_disk_size; - int32_t number_disk; - int32_t current_disk; - int32_t reached_end; -} mz_stream_split; - -/***************************************************************************/ - -static int32_t mz_stream_split_open_disk(void *stream, int32_t number_disk) -{ - mz_stream_split *split = (mz_stream_split *)stream; - uint32_t magic = 0; - int32_t i = 0; - int32_t err = MZ_OK; - int16_t disk_part = 0; - - - // Check if we are reading or writing a disk part or the cd disk - if (number_disk >= 0) - { - if ((split->mode & MZ_OPEN_MODE_WRITE) == 0) - disk_part = MZ_OPEN_MODE_READ; - else if (split->disk_size > 0) - disk_part = MZ_OPEN_MODE_WRITE; - } - - // Construct disk path - if (disk_part > 0) - { - for (i = (int32_t)strlen(split->path_disk) - 1; i >= 0; i -= 1) - { - if (split->path_disk[i] != '.') - continue; - snprintf(&split->path_disk[i], split->path_disk_size - i, ".z%02d", number_disk + 1); - break; - } - } - else - { - strncpy(split->path_disk, split->path_cd, split->path_disk_size); - } - - // If disk part doesn't exist during reading then return MZ_EXIST_ERROR - if (disk_part == MZ_OPEN_MODE_READ) - err = mz_os_file_exists(split->path_disk); - - if (err == MZ_OK) - err = mz_stream_open(split->stream.base, split->path_disk, split->mode); - - if (err == MZ_OK) - { - split->total_in_disk = 0; - split->total_out_disk = 0; - split->current_disk = number_disk; - - if (split->mode & MZ_OPEN_MODE_WRITE) - { - if ((split->current_disk == 0) && (split->disk_size > 0)) - { - err = mz_stream_write_uint32(split->stream.base, MZ_ZIP_MAGIC_DISKHEADER); - split->total_out_disk += 4; - split->total_out += split->total_out_disk; - } - } - else if (split->mode & MZ_OPEN_MODE_READ) - { - if (split->current_disk == 0) - { - err = mz_stream_read_uint32(split->stream.base, &magic); - if (magic != MZ_ZIP_MAGIC_DISKHEADER) - err = MZ_FORMAT_ERROR; - } - } - } - - if (err == MZ_OK) - split->is_open = 1; - - return err; -} - -static int32_t mz_stream_split_close_disk(void *stream) -{ - mz_stream_split *split = (mz_stream_split *)stream; - - if (mz_stream_is_open(split->stream.base) != MZ_OK) - return MZ_OK; - - return mz_stream_close(split->stream.base); -} - -static int32_t mz_stream_split_goto_disk(void *stream, int32_t number_disk) -{ - mz_stream_split *split = (mz_stream_split *)stream; - int32_t err = MZ_OK; - - if ((split->disk_size == 0) && (split->mode & MZ_OPEN_MODE_WRITE)) - { - if (mz_stream_is_open(split->stream.base) != MZ_OK) - err = mz_stream_split_open_disk(stream, number_disk); - } - else if (number_disk != split->current_disk) - { - err = mz_stream_split_close_disk(stream); - if (err == MZ_OK) - { - err = mz_stream_split_open_disk(stream, number_disk); - if (err == MZ_OK) - split->number_disk = number_disk; - } - } - - return err; -} - -int32_t mz_stream_split_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_split *split = (mz_stream_split *)stream; - int32_t number_disk = 0; - - split->mode = mode; - - split->path_cd_size = (int32_t)strlen(path) + 1; - split->path_cd = (char *)MZ_ALLOC(split->path_cd_size); - strncpy(split->path_cd, path, split->path_cd_size); - - split->path_disk_size = (int32_t)strlen(path) + 10; - split->path_disk = (char *)MZ_ALLOC(split->path_disk_size); - strncpy(split->path_disk, path, split->path_disk_size); - - if (mode & MZ_OPEN_MODE_WRITE) - { - number_disk = 0; - split->current_disk = -1; - } - else if (mode & MZ_OPEN_MODE_READ) - { - number_disk = -1; - split->current_disk = 0; - } - - return mz_stream_split_goto_disk(stream, number_disk); -} - -int32_t mz_stream_split_is_open(void *stream) -{ - mz_stream_split *split = (mz_stream_split *)stream; - if (split->is_open == 1) - return MZ_OK; - return MZ_STREAM_ERROR; -} - -int32_t mz_stream_split_read(void *stream, void *buf, int32_t size) -{ - mz_stream_split *split = (mz_stream_split *)stream; - int32_t bytes_left = size; - int32_t read = 0; - int32_t err = MZ_OK; - uint8_t *buf_ptr = (uint8_t *)buf; - - err = mz_stream_split_goto_disk(stream, split->number_disk); - if (err != MZ_OK) - return err; - - while (bytes_left > 0) - { - read = mz_stream_read(split->stream.base, buf_ptr, bytes_left); - if (read < 0) - return read; - if (read == 0) - { - if (split->current_disk < 0) // No more disks to goto - break; - err = mz_stream_split_goto_disk(stream, split->current_disk + 1); - if (err == MZ_EXIST_ERROR) - break; - if (err != MZ_OK) - return err; - } - - bytes_left -= read; - buf_ptr += read; - split->total_in += read; - split->total_in_disk += read; - } - return size - bytes_left; -} - -int32_t mz_stream_split_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_split *split = (mz_stream_split *)stream; - int32_t written = 0; - int32_t bytes_left = size; - int32_t bytes_to_write = 0; - int32_t bytes_avail = 0; - int32_t number_disk = -1; - int32_t err = MZ_OK; - const uint8_t *buf_ptr = (const uint8_t *)buf; - - while (bytes_left > 0) - { - bytes_to_write = bytes_left; - - if (split->disk_size > 0) - { - if ((split->total_out_disk == split->disk_size && split->total_out > 0) || - (split->number_disk == -1 && split->number_disk != split->current_disk)) - { - if (split->number_disk != -1) - number_disk = split->current_disk + 1; - - err = mz_stream_split_goto_disk(stream, number_disk); - if (err != MZ_OK) - return err; - } - - if (split->number_disk != -1) - { - bytes_avail = (int32_t)(split->disk_size - split->total_out_disk); - if (bytes_to_write > bytes_avail) - bytes_to_write = bytes_avail; - } - } - - written = mz_stream_write(split->stream.base, buf_ptr, bytes_to_write); - if (written != bytes_to_write) - return MZ_STREAM_ERROR; - - bytes_left -= written; - buf_ptr += written; - split->total_out += written; - split->total_out_disk += written; - } - - return size - bytes_left; -} - -int64_t mz_stream_split_tell(void *stream) -{ - mz_stream_split *split = (mz_stream_split *)stream; - int32_t err = MZ_OK; - err = mz_stream_split_goto_disk(stream, split->number_disk); - if (err != MZ_OK) - return err; - return mz_stream_tell(split->stream.base); -} - -int32_t mz_stream_split_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_split *split = (mz_stream_split *)stream; - int32_t err = MZ_OK; - err = mz_stream_split_goto_disk(stream, split->number_disk); - if (err != MZ_OK) - return err; - return mz_stream_seek(split->stream.base, offset, origin); -} - -int32_t mz_stream_split_close(void *stream) -{ - mz_stream_split *split = (mz_stream_split *)stream; - int32_t err = MZ_OK; - - err = mz_stream_split_close_disk(stream); - split->is_open = 0; - return err; -} - -int32_t mz_stream_split_error(void *stream) -{ - mz_stream_split *split = (mz_stream_split *)stream; - return mz_stream_error(split->stream.base); -} - -int32_t mz_stream_split_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_split *split = (mz_stream_split *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_OUT: - *value = split->total_out; - return MZ_OK; - case MZ_STREAM_PROP_DISK_NUMBER: - *value = split->number_disk; - return MZ_OK; - case MZ_STREAM_PROP_DISK_SIZE: - *value = split->disk_size; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -int32_t mz_stream_split_set_prop_int64(void *stream, int32_t prop, int64_t value) -{ - mz_stream_split *split = (mz_stream_split *)stream; - switch (prop) - { - case MZ_STREAM_PROP_DISK_NUMBER: - split->number_disk = (int32_t)value; - return MZ_OK; - case MZ_STREAM_PROP_DISK_SIZE: - split->disk_size = value; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -void *mz_stream_split_create(void **stream) -{ - mz_stream_split *split = NULL; - - split = (mz_stream_split *)MZ_ALLOC(sizeof(mz_stream_split)); - if (split != NULL) - { - memset(split, 0, sizeof(mz_stream_split)); - split->stream.vtbl = &mz_stream_split_vtbl; - } - if (stream != NULL) - *stream = split; - - return split; -} - -void mz_stream_split_delete(void **stream) -{ - mz_stream_split *split = NULL; - if (stream == NULL) - return; - split = (mz_stream_split *)*stream; - if (split != NULL) - { - if (split->path_cd) - MZ_FREE(split->path_cd); - if (split->path_disk) - MZ_FREE(split->path_disk); - - MZ_FREE(split); - } - *stream = NULL; -} - -void *mz_stream_split_get_interface(void) -{ - return (void *)&mz_stream_split_vtbl; -} diff --git a/game/client/third/minizip/mz_strm_split.h b/game/client/third/minizip/mz_strm_split.h deleted file mode 100755 index 03cca248..00000000 --- a/game/client/third/minizip/mz_strm_split.h +++ /dev/null @@ -1,46 +0,0 @@ -/* mz_strm_split.h -- Stream for split files - Version 2.3.3, June 10, 2018 - part of MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_SPLIT_H -#define MZ_STREAM_SPLIT_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_split_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_split_is_open(void *stream); -int32_t mz_stream_split_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_split_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_split_tell(void *stream); -int32_t mz_stream_split_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_split_close(void *stream); -int32_t mz_stream_split_error(void *stream); - -int32_t mz_stream_split_get_prop_int64(void *stream, int32_t prop, int64_t *value); -int32_t mz_stream_split_set_prop_int64(void *stream, int32_t prop, int64_t value); - -void* mz_stream_split_create(void **stream); -void mz_stream_split_delete(void **stream); - -void* mz_stream_split_get_interface(void); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_win32.c b/game/client/third/minizip/mz_strm_win32.c deleted file mode 100755 index 5cf867ed..00000000 --- a/game/client/third/minizip/mz_strm_win32.c +++ /dev/null @@ -1,292 +0,0 @@ -/* mz_strm_win32.c -- Stream for filesystem access for windows - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2009-2010 Mathias Svensson - Modifications for Zip64 support - http://result42.com - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#include - -#include - -#include "mz.h" -#include "mz_strm.h" -#include "mz_strm_win32.h" - -/***************************************************************************/ - -#ifndef INVALID_HANDLE_VALUE -# define INVALID_HANDLE_VALUE (0xFFFFFFFF) -#endif - -#ifndef INVALID_SET_FILE_POINTER -# define INVALID_SET_FILE_POINTER ((DWORD)-1) -#endif - -#if defined(WINAPI_FAMILY_ONE_PARTITION) && !defined(MZ_USE_WINRT_API) -# if WINAPI_FAMILY_ONE_PARTITION(WINAPI_FAMILY, WINAPI_PARTITION_APP) -# define MZ_USE_WINRT_API 1 -# endif -#endif - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_win32_vtbl = { - mz_stream_win32_open, - mz_stream_win32_is_open, - mz_stream_win32_read, - mz_stream_win32_write, - mz_stream_win32_tell, - mz_stream_win32_seek, - mz_stream_win32_close, - mz_stream_win32_error, - mz_stream_win32_create, - mz_stream_win32_delete, - NULL, - NULL -}; - -/***************************************************************************/ - -typedef struct mz_stream_win32_s -{ - mz_stream stream; - HANDLE handle; - int32_t error; -} mz_stream_win32; - -/***************************************************************************/ - -int32_t mz_stream_win32_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - uint32_t desired_access = 0; - uint32_t creation_disposition = 0; - uint32_t share_mode = FILE_SHARE_READ; - uint32_t flags_attribs = FILE_ATTRIBUTE_NORMAL; - wchar_t *path_wide = NULL; - uint32_t path_wide_size = 0; - - - if (path == NULL) - return MZ_STREAM_ERROR; - - if ((mode & MZ_OPEN_MODE_READWRITE) == MZ_OPEN_MODE_READ) - { - desired_access = GENERIC_READ; - creation_disposition = OPEN_EXISTING; - } - else if (mode & MZ_OPEN_MODE_APPEND) - { - desired_access = GENERIC_WRITE | GENERIC_READ; - creation_disposition = OPEN_EXISTING; - } - else if (mode & MZ_OPEN_MODE_CREATE) - { - desired_access = GENERIC_WRITE | GENERIC_READ; - creation_disposition = CREATE_ALWAYS; - } - else - { - return MZ_STREAM_ERROR; - } - - path_wide_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0); - path_wide = (wchar_t *)MZ_ALLOC((path_wide_size + 1) * sizeof(wchar_t)); - memset(path_wide, 0, sizeof(wchar_t) * (path_wide_size + 1)); - - MultiByteToWideChar(CP_UTF8, 0, path, -1, path_wide, path_wide_size); - -#ifdef MZ_USE_WINRT_API - win32->handle = CreateFile2W(path_wide, desired_access, share_mode, creation_disposition, NULL); -#else - win32->handle = CreateFileW(path_wide, desired_access, share_mode, NULL, creation_disposition, flags_attribs, NULL); -#endif - - MZ_FREE(path_wide); - - if (mz_stream_win32_is_open(stream) != MZ_OK) - { - win32->error = GetLastError(); - return MZ_STREAM_ERROR; - } - - if (mode & MZ_OPEN_MODE_APPEND) - return mz_stream_win32_seek(stream, 0, MZ_SEEK_END); - - return MZ_OK; -} - -int32_t mz_stream_win32_is_open(void *stream) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - if (win32->handle == NULL || win32->handle == INVALID_HANDLE_VALUE) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_win32_read(void *stream, void *buf, int32_t size) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - uint32_t read = 0; - - if (mz_stream_win32_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - - if (!ReadFile(win32->handle, buf, size, (DWORD *)&read, NULL)) - { - win32->error = GetLastError(); - if (win32->error == ERROR_HANDLE_EOF) - win32->error = 0; - } - - return read; -} - -int32_t mz_stream_win32_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - uint32_t written = 0; - - if (mz_stream_win32_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - - if (!WriteFile(win32->handle, buf, size, (DWORD *)&written, NULL)) - { - win32->error = GetLastError(); - if (win32->error == ERROR_HANDLE_EOF) - win32->error = 0; - } - - return written; -} - -static int32_t mz_stream_win32_seekinternal(HANDLE handle, LARGE_INTEGER large_pos, LARGE_INTEGER *new_pos, uint32_t move_method) -{ -#ifdef MZ_USE_WINRT_API - return SetFilePointerEx(handle, pos, newPos, dwMoveMethod); -#else - LONG high_part = large_pos.HighPart; - uint32_t pos = SetFilePointer(handle, large_pos.LowPart, &high_part, move_method); - - if ((pos == INVALID_SET_FILE_POINTER) && (GetLastError() != NO_ERROR)) - return MZ_STREAM_ERROR; - - if (new_pos != NULL) - { - new_pos->LowPart = pos; - new_pos->HighPart = high_part; - } - - return MZ_OK; -#endif -} - -int64_t mz_stream_win32_tell(void *stream) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - LARGE_INTEGER large_pos; - - if (mz_stream_win32_is_open(stream) != MZ_OK) - return MZ_STREAM_ERROR; - - large_pos.QuadPart = 0; - - if (mz_stream_win32_seekinternal(win32->handle, large_pos, &large_pos, FILE_CURRENT) != MZ_OK) - win32->error = GetLastError(); - - return large_pos.QuadPart; -} - -int32_t mz_stream_win32_seek(void *stream, int64_t offset, int32_t origin) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - uint32_t move_method = 0xFFFFFFFF; - LARGE_INTEGER large_pos; - - - if (mz_stream_win32_is_open(stream) == MZ_STREAM_ERROR) - return MZ_STREAM_ERROR; - - switch (origin) - { - case MZ_SEEK_CUR: - move_method = FILE_CURRENT; - break; - case MZ_SEEK_END: - move_method = FILE_END; - break; - case MZ_SEEK_SET: - move_method = FILE_BEGIN; - break; - default: - return MZ_STREAM_ERROR; - } - - large_pos.QuadPart = offset; - - if (mz_stream_win32_seekinternal(win32->handle, large_pos, NULL, move_method) != MZ_OK) - { - win32->error = GetLastError(); - return MZ_STREAM_ERROR; - } - - return MZ_OK; -} - -int mz_stream_win32_close(void *stream) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - - if (win32->handle != NULL) - CloseHandle(win32->handle); - win32->handle = NULL; - return MZ_OK; -} - -int mz_stream_win32_error(void *stream) -{ - mz_stream_win32 *win32 = (mz_stream_win32 *)stream; - return win32->error; -} - -void *mz_stream_win32_create(void **stream) -{ - mz_stream_win32 *win32 = NULL; - - win32 = (mz_stream_win32 *)MZ_ALLOC(sizeof(mz_stream_win32)); - if (win32 != NULL) - { - memset(win32, 0, sizeof(mz_stream_win32)); - win32->stream.vtbl = &mz_stream_win32_vtbl; - } - if (stream != NULL) - *stream = win32; - - return win32; -} - -void mz_stream_win32_delete(void **stream) -{ - mz_stream_win32 *win32 = NULL; - if (stream == NULL) - return; - win32 = (mz_stream_win32 *)*stream; - if (win32 != NULL) - MZ_FREE(win32); - *stream = NULL; -} - -void *mz_stream_win32_get_interface(void) -{ - return (void *)&mz_stream_win32_vtbl; -} diff --git a/game/client/third/minizip/mz_strm_win32.h b/game/client/third/minizip/mz_strm_win32.h deleted file mode 100755 index 5679c657..00000000 --- a/game/client/third/minizip/mz_strm_win32.h +++ /dev/null @@ -1,67 +0,0 @@ -/* mz_sstrm_win32.h -- Stream for filesystem access for windows - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2009-2010 Mathias Svensson - Modifications for Zip64 support - http://result42.com - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_WIN32_H -#define MZ_STREAM_WIN32_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_win32_open(void *stream, const char *path, int32_t mode); -int32_t mz_stream_win32_is_open(void *stream); -int32_t mz_stream_win32_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_win32_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_win32_tell(void *stream); -int32_t mz_stream_win32_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_win32_close(void *stream); -int32_t mz_stream_win32_error(void *stream); - -void* mz_stream_win32_create(void **stream); -void mz_stream_win32_delete(void **stream); - -void* mz_stream_win32_get_interface(void); - -/***************************************************************************/ - -#if defined(_WIN32) || defined(MZ_USE_WIN32_API) -#define mz_stream_os_open mz_stream_win32_open -#define mz_stream_os_is_open mz_stream_win32_is_open -#define mz_stream_os_read mz_stream_win32_read -#define mz_stream_os_write mz_stream_win32_write -#define mz_stream_os_tell mz_stream_win32_tell -#define mz_stream_os_seek mz_stream_win32_seek -#define mz_stream_os_close mz_stream_win32_close -#define mz_stream_os_error mz_stream_win32_error - -#define mz_stream_os_create mz_stream_win32_create -#define mz_stream_os_delete mz_stream_win32_delete - -#define mz_stream_os_get_interface \ - mz_stream_win32_get_interface -#endif - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_strm_zlib.c b/game/client/third/minizip/mz_strm_zlib.c deleted file mode 100755 index db092980..00000000 --- a/game/client/third/minizip/mz_strm_zlib.c +++ /dev/null @@ -1,395 +0,0 @@ -/* mz_strm_zlib.c -- Stream for zlib inflate/deflate - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - - -#include -#include -#include -#include - -#include "zlib.h" - -#include "mz.h" -#include "mz_strm.h" -#include "mz_strm_zlib.h" - - -/***************************************************************************/ - -#ifndef DEF_MEM_LEVEL -# if MAX_MEM_LEVEL >= 8 -# define DEF_MEM_LEVEL 8 -# else -# define DEF_MEM_LEVEL MAX_MEM_LEVEL -# endif -#endif - -/***************************************************************************/ - -static mz_stream_vtbl mz_stream_zlib_vtbl = { - mz_stream_zlib_open, - mz_stream_zlib_is_open, - mz_stream_zlib_read, - mz_stream_zlib_write, - mz_stream_zlib_tell, - mz_stream_zlib_seek, - mz_stream_zlib_close, - mz_stream_zlib_error, - mz_stream_zlib_create, - mz_stream_zlib_delete, - mz_stream_zlib_get_prop_int64, - mz_stream_zlib_set_prop_int64 -}; - -/***************************************************************************/ - -typedef struct mz_stream_zlib_s { - mz_stream stream; - z_stream zstream; - uint8_t buffer[INT16_MAX]; - int32_t buffer_len; - int64_t total_in; - int64_t total_out; - int64_t max_total_in; - int8_t initialized; - int16_t level; - int32_t mode; - int32_t error; -} mz_stream_zlib; - -/***************************************************************************/ - -int32_t mz_stream_zlib_open(void *stream, const char *path, int32_t mode) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - - MZ_UNUSED(path); - - zlib->zstream.data_type = Z_BINARY; - zlib->zstream.zalloc = Z_NULL; - zlib->zstream.zfree = Z_NULL; - zlib->zstream.opaque = Z_NULL; - zlib->zstream.total_in = 0; - zlib->zstream.total_out = 0; - - zlib->total_in = 0; - zlib->total_out = 0; - - if (mode & MZ_OPEN_MODE_WRITE) - { - zlib->zstream.next_out = zlib->buffer; - zlib->zstream.avail_out = sizeof(zlib->buffer); - - zlib->error = deflateInit2(&zlib->zstream, (int8_t)zlib->level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); - } - else if (mode & MZ_OPEN_MODE_READ) - { - zlib->zstream.next_in = zlib->buffer; - zlib->zstream.avail_in = 0; - - zlib->error = inflateInit2(&zlib->zstream, -MAX_WBITS); - } - - if (zlib->error != Z_OK) - return MZ_STREAM_ERROR; - - zlib->initialized = 1; - zlib->mode = mode; - return MZ_OK; -} - -int32_t mz_stream_zlib_is_open(void *stream) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - if (zlib->initialized != 1) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_zlib_read(void *stream, void *buf, int32_t size) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - uint64_t total_in_before = 0; - uint64_t total_in_after = 0; - uint64_t total_out_before = 0; - uint64_t total_out_after = 0; - uint32_t total_in = 0; - uint32_t total_out = 0; - uint32_t in_bytes = 0; - uint32_t out_bytes = 0; - int32_t bytes_to_read = 0; - int32_t read = 0; - int32_t err = Z_OK; - - - zlib->zstream.next_out = (Bytef*)buf; - zlib->zstream.avail_out = (uInt)size; - - do - { - if (zlib->zstream.avail_in == 0) - { - bytes_to_read = sizeof(zlib->buffer); - if (zlib->max_total_in > 0) - { - if ((zlib->max_total_in - zlib->total_in) < (int64_t)sizeof(zlib->buffer)) - bytes_to_read = (int32_t)(zlib->max_total_in - zlib->total_in); - } - - read = mz_stream_read(zlib->stream.base, zlib->buffer, bytes_to_read); - - if (read < 0) - { - zlib->error = Z_STREAM_ERROR; - break; - } - if (read == 0) - break; - - zlib->zstream.next_in = zlib->buffer; - zlib->zstream.avail_in = read; - } - - total_in_before = zlib->zstream.avail_in; - total_out_before = zlib->zstream.total_out; - - err = inflate(&zlib->zstream, Z_SYNC_FLUSH); - if ((err >= Z_OK) && (zlib->zstream.msg != NULL)) - { - zlib->error = Z_DATA_ERROR; - break; - } - - total_in_after = zlib->zstream.avail_in; - total_out_after = zlib->zstream.total_out; - - in_bytes = (uint32_t)(total_in_before - total_in_after); - out_bytes = (uint32_t)(total_out_after - total_out_before); - - total_in += in_bytes; - total_out += out_bytes; - - zlib->total_in += in_bytes; - zlib->total_out += out_bytes; - - if (err == Z_STREAM_END) - break; - - if (err != Z_OK) - { - zlib->error = err; - break; - } - } - while (zlib->zstream.avail_out > 0); - - if (zlib->error != 0) - return zlib->error; - - return total_out; -} - -static int32_t mz_stream_zlib_flush(void *stream) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - if (mz_stream_write(zlib->stream.base, zlib->buffer, zlib->buffer_len) != zlib->buffer_len) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -static int32_t mz_stream_zlib_deflate(void *stream, int flush) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - uint64_t total_out_before = 0; - uint64_t total_out_after = 0; - int32_t out_bytes = 0; - int32_t err = Z_OK; - - - do - { - if (zlib->zstream.avail_out == 0) - { - if (mz_stream_zlib_flush(zlib) != MZ_OK) - { - zlib->error = Z_STREAM_ERROR; - return MZ_STREAM_ERROR; - } - - zlib->zstream.avail_out = sizeof(zlib->buffer); - zlib->zstream.next_out = zlib->buffer; - - zlib->buffer_len = 0; - } - - total_out_before = zlib->zstream.total_out; - err = deflate(&zlib->zstream, flush); - total_out_after = zlib->zstream.total_out; - - out_bytes = (uint32_t)(total_out_after - total_out_before); - - zlib->buffer_len += out_bytes; - zlib->total_out += out_bytes; - - if (err == Z_STREAM_END) - break; - if (err != Z_OK) - { - zlib->error = err; - return MZ_STREAM_ERROR; - } - } - while ((zlib->zstream.avail_in > 0) || (flush == Z_FINISH && err == Z_OK)); - - return MZ_OK; -} - -int32_t mz_stream_zlib_write(void *stream, const void *buf, int32_t size) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - - - zlib->zstream.next_in = (Bytef*)(intptr_t)buf; - zlib->zstream.avail_in = (uInt)size; - - mz_stream_zlib_deflate(stream, Z_NO_FLUSH); - - zlib->total_in += size; - - return size; -} - -int64_t mz_stream_zlib_tell(void *stream) -{ - MZ_UNUSED(stream); - - return MZ_STREAM_ERROR; -} - -int32_t mz_stream_zlib_seek(void *stream, int64_t offset, int32_t origin) -{ - MZ_UNUSED(stream); - MZ_UNUSED(offset); - MZ_UNUSED(origin); - - return MZ_STREAM_ERROR; -} - -int32_t mz_stream_zlib_close(void *stream) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - - - if (zlib->mode & MZ_OPEN_MODE_WRITE) - { - mz_stream_zlib_deflate(stream, Z_FINISH); - mz_stream_zlib_flush(stream); - - deflateEnd(&zlib->zstream); - } - else if (zlib->mode & MZ_OPEN_MODE_READ) - { - inflateEnd(&zlib->zstream); - } - - zlib->initialized = 0; - - if (zlib->error != Z_OK) - return MZ_STREAM_ERROR; - return MZ_OK; -} - -int32_t mz_stream_zlib_error(void *stream) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - return zlib->error; -} - -int32_t mz_stream_zlib_get_prop_int64(void *stream, int32_t prop, int64_t *value) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - switch (prop) - { - case MZ_STREAM_PROP_TOTAL_IN: - *value = zlib->total_in; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_OUT: - *value = zlib->total_out; - return MZ_OK; - case MZ_STREAM_PROP_HEADER_SIZE: - *value = 0; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -int32_t mz_stream_zlib_set_prop_int64(void *stream, int32_t prop, int64_t value) -{ - mz_stream_zlib *zlib = (mz_stream_zlib *)stream; - switch (prop) - { - case MZ_STREAM_PROP_COMPRESS_LEVEL: - zlib->level = (int16_t)value; - return MZ_OK; - case MZ_STREAM_PROP_TOTAL_IN_MAX: - zlib->max_total_in = value; - return MZ_OK; - } - return MZ_EXIST_ERROR; -} - -void *mz_stream_zlib_create(void **stream) -{ - mz_stream_zlib *zlib = NULL; - - zlib = (mz_stream_zlib *)MZ_ALLOC(sizeof(mz_stream_zlib)); - if (zlib != NULL) - { - memset(zlib, 0, sizeof(mz_stream_zlib)); - zlib->stream.vtbl = &mz_stream_zlib_vtbl; - zlib->level = Z_DEFAULT_COMPRESSION; - } - if (stream != NULL) - *stream = zlib; - - return zlib; -} - -void mz_stream_zlib_delete(void **stream) -{ - mz_stream_zlib *zlib = NULL; - if (stream == NULL) - return; - zlib = (mz_stream_zlib *)*stream; - if (zlib != NULL) - MZ_FREE(zlib); - *stream = NULL; -} - -void *mz_stream_zlib_get_interface(void) -{ - return (void *)&mz_stream_zlib_vtbl; -} - -static int64_t mz_stream_zlib_crc32(int64_t value, const void *buf, int32_t size) -{ - return crc32(/*(z_crc_t)*/value, buf, size); -} - -void *mz_stream_zlib_get_crc32_table(void) -{ - return (void *)get_crc_table(); -} - -void *mz_stream_zlib_get_crc32_update(void) -{ - return (void *)mz_stream_zlib_crc32; -} diff --git a/game/client/third/minizip/mz_strm_zlib.h b/game/client/third/minizip/mz_strm_zlib.h deleted file mode 100755 index 949fa0b0..00000000 --- a/game/client/third/minizip/mz_strm_zlib.h +++ /dev/null @@ -1,48 +0,0 @@ -/* mz_strm_zlib.h -- Stream for zlib inflate/deflate - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_STREAM_ZLIB_H -#define MZ_STREAM_ZLIB_H - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -int32_t mz_stream_zlib_open(void *stream, const char *filename, int32_t mode); -int32_t mz_stream_zlib_is_open(void *stream); -int32_t mz_stream_zlib_read(void *stream, void *buf, int32_t size); -int32_t mz_stream_zlib_write(void *stream, const void *buf, int32_t size); -int64_t mz_stream_zlib_tell(void *stream); -int32_t mz_stream_zlib_seek(void *stream, int64_t offset, int32_t origin); -int32_t mz_stream_zlib_close(void *stream); -int32_t mz_stream_zlib_error(void *stream); - -int32_t mz_stream_zlib_get_prop_int64(void *stream, int32_t prop, int64_t *value); -int32_t mz_stream_zlib_set_prop_int64(void *stream, int32_t prop, int64_t value); - -void* mz_stream_zlib_create(void **stream); -void mz_stream_zlib_delete(void **stream); - -void* mz_stream_zlib_get_interface(void); -void* mz_stream_zlib_get_crc32_table(void); -void* mz_stream_zlib_get_crc32_update(void); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/game/client/third/minizip/mz_zip.c b/game/client/third/minizip/mz_zip.c deleted file mode 100755 index 98b554b3..00000000 --- a/game/client/third/minizip/mz_zip.c +++ /dev/null @@ -1,1714 +0,0 @@ -/* zip.c -- Zip manipulation - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2009-2010 Mathias Svensson - Modifications for Zip64 support - http://result42.com - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#undef strncpy -#include -#include -#include -#include -#include -#include -#include - -#include "mz.h" -#include "mz_strm.h" -#ifdef HAVE_AES -# include "mz_strm_aes.h" -#endif -#ifdef HAVE_BZIP2 -# include "mz_strm_bzip.h" -#endif -#ifdef HAVE_LZMA -# include "mz_strm_lzma.h" -#endif -#ifdef HAVE_PKCRYPT -# include "mz_strm_pkcrypt.h" -#endif -#ifdef HAVE_ZLIB -# include "mz_strm_zlib.h" -#endif -#include "mz_strm_mem.h" - -#include "mz_zip.h" - -/***************************************************************************/ - -#define MZ_ZIP_MAGIC_LOCALHEADER (0x04034b50) -#define MZ_ZIP_MAGIC_CENTRALHEADER (0x02014b50) -#define MZ_ZIP_MAGIC_ENDHEADER (0x06054b50) -#define MZ_ZIP_MAGIC_ENDHEADER64 (0x06064b50) -#define MZ_ZIP_MAGIC_ENDLOCHEADER64 (0x07064b50) -#define MZ_ZIP_MAGIC_DATADESCRIPTOR (0x08074b50) - -#define MZ_ZIP_SIZE_CD_ITEM (0x2e) -#define MZ_ZIP_SIZE_CD_LOCATOR64 (0x14) - -#define MZ_ZIP_EXTENSION_ZIP64 (0x0001) -#define MZ_ZIP_EXTENSION_NTFS (0x000a) -#define MZ_ZIP_EXTENSION_AES (0x9901) - -/***************************************************************************/ - -typedef struct mz_zip_s -{ - mz_zip_file file_info; - mz_zip_file local_file_info; - - void *stream; // main stream - void *cd_stream; // pointer to the stream with the cd - void *cd_mem_stream; // memory stream for central directory - void *compress_stream; // compression stream - void *crc32_stream; // crc32 stream - void *crypt_stream; // encryption stream - void *file_info_stream; // memory stream for storing file info - void *local_file_info_stream; // memory stream for storing local file info - - int32_t open_mode; - - uint32_t disk_number_with_cd; // number of the disk with the central dir - - uint64_t cd_start_pos; // pos of the first file in the central dir stream - uint64_t cd_current_pos; // pos of the current file in the central dir - uint64_t cd_offset; // offset of start of central directory - uint64_t cd_size; // size of the central directory - - uint16_t entry_scanned; - uint16_t entry_opened; // 1 if a file in the zip is currently writ. - uint64_t entry_read; - - int64_t number_entry; - - int16_t compression_method; - - uint16_t version_madeby; - char *comment; -} mz_zip; - -/***************************************************************************/ - -// Locate the central directory of a zip file (at the end, just before the global comment) -static int32_t mz_zip_search_eocd(void *stream, uint64_t *central_pos) -{ - uint8_t buf[1024 + 4]; - int64_t file_size = 0; - int64_t back_read = 0; - int64_t max_back = UINT16_MAX; // maximum size of global comment - int32_t read_size = sizeof(buf); - int64_t read_pos = 0; - int32_t i = 0; - - *central_pos = 0; - - if (mz_stream_seek(stream, 0, MZ_SEEK_END) != MZ_OK) - return MZ_STREAM_ERROR; - - file_size = mz_stream_tell(stream); - - if (max_back > file_size) - max_back = file_size; - - while (back_read < max_back) - { - back_read += (sizeof(buf) - 4); - if (back_read > max_back) - back_read = max_back; - - read_pos = file_size - back_read; - if (read_size > (file_size - read_pos)) - read_size = (uint32_t)(file_size - read_pos); - - if (mz_stream_seek(stream, read_pos, MZ_SEEK_SET) != MZ_OK) - break; - if (mz_stream_read(stream, buf, read_size) != read_size) - break; - - for (i = read_size - 3; (i--) > 0;) - { - if (((*(buf + i)) == (MZ_ZIP_MAGIC_ENDHEADER & 0xff)) && - ((*(buf + i + 1)) == (MZ_ZIP_MAGIC_ENDHEADER >> 8 & 0xff)) && - ((*(buf + i + 2)) == (MZ_ZIP_MAGIC_ENDHEADER >> 16 & 0xff)) && - ((*(buf + i + 3)) == (MZ_ZIP_MAGIC_ENDHEADER >> 24 & 0xff))) - { - *central_pos = read_pos + i; - return MZ_OK; - } - } - - if (*central_pos != 0) - break; - } - - return MZ_EXIST_ERROR; -} - -// Locate the central directory 64 of a zip file (at the end, just before the global comment) -static int32_t mz_zip_search_zip64_eocd(void *stream, const uint64_t end_central_offset, uint64_t *central_pos) -{ - uint64_t offset = 0; - uint32_t value32 = 0; - int32_t err = MZ_OK; - - - *central_pos = 0; - - // Zip64 end of central directory locator - err = mz_stream_seek(stream, end_central_offset - MZ_ZIP_SIZE_CD_LOCATOR64, MZ_SEEK_SET); - // Read locator signature - if (err == MZ_OK) - { - err = mz_stream_read_uint32(stream, &value32); - if (value32 != MZ_ZIP_MAGIC_ENDLOCHEADER64) - err = MZ_FORMAT_ERROR; - } - // Number of the disk with the start of the zip64 end of central directory - if (err == MZ_OK) - err = mz_stream_read_uint32(stream, &value32); - // Relative offset of the zip64 end of central directory record8 - if (err == MZ_OK) - err = mz_stream_read_uint64(stream, &offset); - // Total number of disks - if (err == MZ_OK) - err = mz_stream_read_uint32(stream, &value32); - // Goto end of central directory record - if (err == MZ_OK) - err = mz_stream_seek(stream, offset, MZ_SEEK_SET); - // The signature - if (err == MZ_OK) - { - err = mz_stream_read_uint32(stream, &value32); - if (value32 != MZ_ZIP_MAGIC_ENDHEADER64) - err = MZ_FORMAT_ERROR; - } - - if (err == MZ_OK) - *central_pos = offset; - - return err; -} - -static int32_t mz_zip_read_cd(void *handle) -{ - mz_zip *zip = (mz_zip *)handle; - int64_t number_entry_cd = 0; - uint64_t number_entry_cd64 = 0; - uint64_t number_entry = 0; - uint64_t eocd_pos = 0; - uint64_t eocd_pos64 = 0; - uint16_t value16 = 0; - uint32_t value32 = 0; - uint64_t value64 = 0; - uint16_t comment_size = 0; - int32_t err = MZ_OK; - - - if (zip == NULL) - return MZ_PARAM_ERROR; - - // Read and cache central directory records - if (mz_zip_search_eocd(zip->stream, &eocd_pos) == MZ_OK) - { - // Read end of central directory info - err = mz_stream_seek(zip->stream, eocd_pos, MZ_SEEK_SET); - // The signature, already checked - if (err == MZ_OK) - err = mz_stream_read_uint32(zip->stream, &value32); - // Number of this disk - if (err == MZ_OK) - err = mz_stream_read_uint16(zip->stream, &value16); - // Number of the disk with the start of the central directory - if (err == MZ_OK) - err = mz_stream_read_uint16(zip->stream, &value16); - zip->disk_number_with_cd = value16; - // Total number of entries in the central dir on this disk - if (err == MZ_OK) - err = mz_stream_read_uint16(zip->stream, &value16); - zip->number_entry = value16; - // Total number of entries in the central dir - if (err == MZ_OK) - err = mz_stream_read_uint16(zip->stream, &value16); - number_entry_cd = value16; - if (number_entry_cd != zip->number_entry) - err = MZ_FORMAT_ERROR; - // Size of the central directory - if (err == MZ_OK) - err = mz_stream_read_uint32(zip->stream, &value32); - if (err == MZ_OK) - zip->cd_size = value32; - // Offset of start of central directory with respect to the starting disk number - if (err == MZ_OK) - err = mz_stream_read_uint32(zip->stream, &value32); - zip->cd_offset = value32; - // Zip file global comment length - if (err == MZ_OK) - err = mz_stream_read_uint16(zip->stream, &comment_size); - - if ((err == MZ_OK) && ((number_entry_cd == UINT16_MAX) || (zip->cd_offset == UINT32_MAX))) - { - // Format should be Zip64, as the central directory or file size is too large - if (mz_zip_search_zip64_eocd(zip->stream, eocd_pos, &eocd_pos64) == MZ_OK) - { - eocd_pos = eocd_pos64; - - err = mz_stream_seek(zip->stream, eocd_pos, MZ_SEEK_SET); - // The signature, already checked - if (err == MZ_OK) - err = mz_stream_read_uint32(zip->stream, &value32); - // Size of zip64 end of central directory record - if (err == MZ_OK) - err = mz_stream_read_uint64(zip->stream, &value64); - // Version made by - if (err == MZ_OK) - err = mz_stream_read_uint16(zip->stream, &zip->version_madeby); - // Version needed to extract - if (err == MZ_OK) - err = mz_stream_read_uint16(zip->stream, &value16); - // Number of this disk - if (err == MZ_OK) - err = mz_stream_read_uint32(zip->stream, &value32); - // Number of the disk with the start of the central directory - if (err == MZ_OK) - err = mz_stream_read_uint32(zip->stream, &zip->disk_number_with_cd); - // Total number of entries in the central directory on this disk - if (err == MZ_OK) - err = mz_stream_read_uint64(zip->stream, &number_entry); - // Total number of entries in the central directory - if (err == MZ_OK) - err = mz_stream_read_uint64(zip->stream, &number_entry_cd64); - if (number_entry == UINT32_MAX) - zip->number_entry = number_entry_cd64; - // Size of the central directory - if (err == MZ_OK) - err = mz_stream_read_uint64(zip->stream, &zip->cd_size); - // Offset of start of central directory with respect to the starting disk number - if (err == MZ_OK) - err = mz_stream_read_uint64(zip->stream, &zip->cd_offset); - } - else if ((zip->number_entry == UINT16_MAX) || (number_entry_cd != zip->number_entry) || - (zip->cd_size == UINT16_MAX) || (zip->cd_offset == UINT32_MAX)) - { - err = MZ_FORMAT_ERROR; - } - } - } - - if (err == MZ_OK) - { - if (eocd_pos < zip->cd_offset + zip->cd_size) - err = MZ_FORMAT_ERROR; - } - - if ((err == MZ_OK) && (comment_size > 0)) - { - zip->comment = (char *)MZ_ALLOC(comment_size + 1); - if (zip->comment) - { - if (mz_stream_read(zip->stream, zip->comment, comment_size) != comment_size) - err = MZ_STREAM_ERROR; - zip->comment[comment_size] = 0; - } - } - - return err; -} - -static int32_t mz_zip_write_cd(void *handle) -{ - mz_zip *zip = (mz_zip *)handle; - uint16_t comment_size = 0; - uint64_t zip64_eocd_pos_inzip = 0; - int64_t disk_number = 0; - int64_t disk_size = 0; - int32_t err = MZ_OK; - - - if (zip == NULL) - return MZ_PARAM_ERROR; - - if (mz_stream_get_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, &disk_number) == MZ_OK) - zip->disk_number_with_cd = (uint32_t)disk_number; - if (mz_stream_get_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_SIZE, &disk_size) == MZ_OK && disk_size > 0) - zip->disk_number_with_cd += 1; - mz_stream_set_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, -1); - - zip->cd_offset = mz_stream_tell(zip->stream); - mz_stream_seek(zip->cd_mem_stream, 0, MZ_SEEK_END); - zip->cd_size = (uint32_t)mz_stream_tell(zip->cd_mem_stream); - mz_stream_seek(zip->cd_mem_stream, 0, MZ_SEEK_SET); - - err = mz_stream_copy(zip->stream, zip->cd_mem_stream, (int32_t)zip->cd_size); - - // Write the ZIP64 central directory header - if (zip->cd_offset >= UINT32_MAX || zip->number_entry > UINT16_MAX) - { - zip64_eocd_pos_inzip = mz_stream_tell(zip->stream); - - err = mz_stream_write_uint32(zip->stream, MZ_ZIP_MAGIC_ENDHEADER64); - - // Size of this 'zip64 end of central directory' - if (err == MZ_OK) - err = mz_stream_write_uint64(zip->stream, (uint64_t)44); - // Version made by - if (err == MZ_OK) - err = mz_stream_write_uint16(zip->stream, zip->version_madeby); - // Version needed - if (err == MZ_OK) - err = mz_stream_write_uint16(zip->stream, (uint16_t)45); - // Number of this disk - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, zip->disk_number_with_cd); - // Number of the disk with the start of the central directory - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, zip->disk_number_with_cd); - // Total number of entries in the central dir on this disk - if (err == MZ_OK) - err = mz_stream_write_uint64(zip->stream, zip->number_entry); - // Total number of entries in the central dir - if (err == MZ_OK) - err = mz_stream_write_uint64(zip->stream, zip->number_entry); - // Size of the central directory - if (err == MZ_OK) - err = mz_stream_write_uint64(zip->stream, (uint64_t)zip->cd_size); - // Offset of start of central directory with respect to the starting disk number - if (err == MZ_OK) - err = mz_stream_write_uint64(zip->stream, zip->cd_offset); - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, MZ_ZIP_MAGIC_ENDLOCHEADER64); - - // Number of the disk with the start of the central directory - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, zip->disk_number_with_cd); - // Relative offset to the end of zip64 central directory - if (err == MZ_OK) - err = mz_stream_write_uint64(zip->stream, zip64_eocd_pos_inzip); - // Number of the disk with the start of the central directory - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, zip->disk_number_with_cd + 1); - } - - // Write the central directory header - - // Signature - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, MZ_ZIP_MAGIC_ENDHEADER); - // Number of this disk - if (err == MZ_OK) - err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->disk_number_with_cd); - // Number of the disk with the start of the central directory - if (err == MZ_OK) - err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->disk_number_with_cd); - // Total number of entries in the central dir on this disk - if (err == MZ_OK) - { - if (zip->number_entry >= UINT16_MAX) - err = mz_stream_write_uint16(zip->stream, UINT16_MAX); - else - err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->number_entry); - } - // Total number of entries in the central dir - if (err == MZ_OK) - { - if (zip->number_entry >= UINT16_MAX) - err = mz_stream_write_uint16(zip->stream, UINT16_MAX); - else - err = mz_stream_write_uint16(zip->stream, (uint16_t)zip->number_entry); - } - // Size of the central directory - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, (uint32_t)zip->cd_size); - // Offset of start of central directory with respect to the starting disk number - if (err == MZ_OK) - { - if (zip->cd_offset >= UINT32_MAX) - err = mz_stream_write_uint32(zip->stream, UINT32_MAX); - else - err = mz_stream_write_uint32(zip->stream, (uint32_t)zip->cd_offset); - } - - // Write global comment - if (zip->comment != NULL) - comment_size = (uint16_t)strlen(zip->comment); - if (err == MZ_OK) - err = mz_stream_write_uint16(zip->stream, comment_size); - if (err == MZ_OK) - { - if (mz_stream_write(zip->stream, zip->comment, comment_size) != comment_size) - err = MZ_STREAM_ERROR; - } - return err; -} - -extern void* mz_zip_open(void *stream, int32_t mode) -{ - mz_zip *zip = NULL; - int32_t err = MZ_OK; - - - zip = (mz_zip *)MZ_ALLOC(sizeof(mz_zip)); - if (zip == NULL) - return NULL; - - memset(zip, 0, sizeof(mz_zip)); - - zip->stream = stream; - - if (mode & MZ_OPEN_MODE_WRITE) - { - mz_stream_mem_create(&zip->cd_mem_stream); - mz_stream_mem_open(zip->cd_mem_stream, NULL, MZ_OPEN_MODE_CREATE); - - zip->cd_stream = zip->cd_mem_stream; - } - else - { - zip->cd_stream = stream; - } - - if ((mode & MZ_OPEN_MODE_READ) || (mode & MZ_OPEN_MODE_APPEND)) - { - err = mz_zip_read_cd(zip); - - if ((err == MZ_OK) && (mode & MZ_OPEN_MODE_APPEND)) - { - if (zip->cd_size > 0) - { - // Store central directory in memory - err = mz_stream_seek(zip->stream, zip->cd_offset, MZ_SEEK_SET); - if (err == MZ_OK) - err = mz_stream_copy(zip->cd_mem_stream, zip->stream, (uint32_t)zip->cd_size); - if (err == MZ_OK) - err = mz_stream_seek(zip->stream, zip->cd_offset, MZ_SEEK_SET); - } - else - { - // If no central directory, append new zip to end of file - err = mz_stream_seek(zip->stream, 0, MZ_SEEK_END); - } - } - else - { - zip->cd_start_pos = zip->cd_offset; - } - } - - if (err == MZ_OK) - { - mz_stream_mem_create(&zip->file_info_stream); - mz_stream_mem_open(zip->file_info_stream, NULL, MZ_OPEN_MODE_CREATE); - mz_stream_mem_create(&zip->local_file_info_stream); - mz_stream_mem_open(zip->local_file_info_stream, NULL, MZ_OPEN_MODE_CREATE); - } - - if (err != MZ_OK) - { - mz_zip_close(zip); - return NULL; - } - - zip->open_mode = mode; - - return zip; -} - -extern int32_t mz_zip_close(void *handle) -{ - mz_zip *zip = (mz_zip *)handle; - int32_t err = MZ_OK; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - if (zip->entry_opened == 1) - { - err = mz_zip_entry_close(handle); - if (err != MZ_OK) - return err; - } - - if (zip->open_mode & MZ_OPEN_MODE_WRITE) - err = mz_zip_write_cd(handle); - - if (zip->cd_mem_stream != NULL) - { - mz_stream_close(zip->cd_mem_stream); - mz_stream_delete(&zip->cd_mem_stream); - } - - if (zip->file_info_stream != NULL) - { - mz_stream_mem_close(zip->file_info_stream); - mz_stream_mem_delete(&zip->file_info_stream); - } - if (zip->local_file_info_stream != NULL) - { - mz_stream_mem_close(zip->local_file_info_stream); - mz_stream_mem_delete(&zip->local_file_info_stream); - } - - if (zip->comment) - MZ_FREE(zip->comment); - - MZ_FREE(zip); - - return err; -} - -extern int32_t mz_zip_get_comment(void *handle, const char **comment) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL || comment == NULL) - return MZ_PARAM_ERROR; - if (zip->comment == NULL) - return MZ_EXIST_ERROR; - *comment = zip->comment; - return MZ_OK; -} - -extern int32_t mz_zip_set_comment(void *handle, const char *comment) -{ - mz_zip *zip = (mz_zip *)handle; - uint16_t comment_size = 0; - if (zip == NULL || comment == NULL) - return MZ_PARAM_ERROR; - if (zip->comment != NULL) - MZ_FREE(zip->comment); - comment_size = (uint16_t)(strlen(comment) + 1); - zip->comment = (char *)MZ_ALLOC(comment_size); - strncpy(zip->comment, comment, comment_size); - return MZ_OK; -} - -extern int32_t mz_zip_get_version_madeby(void *handle, uint16_t *version_madeby) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL || version_madeby == NULL) - return MZ_PARAM_ERROR; - *version_madeby = zip->version_madeby; - return MZ_OK; -} - -extern int32_t mz_zip_set_version_madeby(void *handle, uint16_t version_madeby) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL) - return MZ_PARAM_ERROR; - zip->version_madeby = version_madeby; - return MZ_OK; -} - -// Get info about the current file in the zip file -static int32_t mz_zip_entry_read_header(void *stream, uint8_t local, mz_zip_file *file_info, void *file_info_stream) -{ - uint64_t ntfs_time = 0; - uint32_t reserved = 0; - uint32_t magic = 0; - uint32_t dos_date = 0; - uint32_t extra_pos = 0; - uint32_t extra_data_size_read = 0; - uint16_t extra_header_id = 0; - uint16_t extra_data_size = 0; - uint16_t ntfs_attrib_id = 0; - uint16_t ntfs_attrib_size = 0; - uint16_t value16 = 0; - uint32_t value32 = 0; - uint64_t value64 = 0; - int64_t max_seek = 0; - int64_t seek = 0; - int32_t err = MZ_OK; - - - memset(file_info, 0, sizeof(mz_zip_file)); - - // Check the magic - err = mz_stream_read_uint32(stream, &magic); - if (err == MZ_END_OF_STREAM) - err = MZ_END_OF_LIST; - else if (magic == MZ_ZIP_MAGIC_ENDHEADER || magic == MZ_ZIP_MAGIC_ENDHEADER64) - err = MZ_END_OF_LIST; - else if ((local) && (magic != MZ_ZIP_MAGIC_LOCALHEADER)) - err = MZ_FORMAT_ERROR; - else if ((!local) && (magic != MZ_ZIP_MAGIC_CENTRALHEADER)) - err = MZ_FORMAT_ERROR; - - // Read header fields - if (err == MZ_OK) - { - if (!local) - err = mz_stream_read_uint16(stream, &file_info->version_madeby); - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &file_info->version_needed); - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &file_info->flag); - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &file_info->compression_method); - if (err == MZ_OK) - { - err = mz_stream_read_uint32(stream, &dos_date); - file_info->modified_date = mz_zip_dosdate_to_time_t(dos_date); - } - if (err == MZ_OK) - err = mz_stream_read_uint32(stream, &file_info->crc); - if (err == MZ_OK) - err = mz_stream_read_uint32(stream, &value32); - file_info->compressed_size = value32; - if (err == MZ_OK) - err = mz_stream_read_uint32(stream, &value32); - file_info->uncompressed_size = value32; - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &file_info->filename_size); - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &file_info->extrafield_size); - if (!local) - { - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &file_info->comment_size); - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &value16); - file_info->disk_number = value16; - if (err == MZ_OK) - err = mz_stream_read_uint16(stream, &file_info->internal_fa); - if (err == MZ_OK) - err = mz_stream_read_uint32(stream, &file_info->external_fa); - if (err == MZ_OK) - err = mz_stream_read_uint32(stream, &value32); - file_info->disk_offset = value32; - } - } - - max_seek = file_info->filename_size + file_info->extrafield_size + file_info->comment_size + 3; - if (err == MZ_OK) - err = mz_stream_seek(file_info_stream, max_seek, MZ_SEEK_SET); - if (err == MZ_OK) - err = mz_stream_seek(file_info_stream, 0, MZ_SEEK_SET); - - if ((err == MZ_OK) && (file_info->filename_size > 0)) - { - mz_stream_mem_get_buffer(file_info_stream, (const void **)&file_info->filename); - - err = mz_stream_copy(file_info_stream, stream, file_info->filename_size); - if (err == MZ_OK) - err = mz_stream_write_uint8(file_info_stream, 0); - - seek += file_info->filename_size + 1; - } - - if ((err == MZ_OK) && (file_info->extrafield_size > 0)) - { - mz_stream_mem_get_buffer_at(file_info_stream, seek, (const void **)&file_info->extrafield); - - err = mz_stream_copy(file_info_stream, stream, file_info->extrafield_size); - if (err == MZ_OK) - err = mz_stream_write_uint8(file_info_stream, 0); - - // Seek back and parse the extra field - if (err == MZ_OK) - err = mz_stream_seek(file_info_stream, seek, MZ_SEEK_SET); - - seek += file_info->extrafield_size + 1; - - while ((err == MZ_OK) && (extra_pos < file_info->extrafield_size)) - { - err = mz_stream_read_uint16(file_info_stream, &extra_header_id); - if (err == MZ_OK) - err = mz_stream_read_uint16(file_info_stream, &extra_data_size); - - // ZIP64 extra field - if (extra_header_id == MZ_ZIP_EXTENSION_ZIP64) - { - if ((err == MZ_OK) && (file_info->uncompressed_size == UINT32_MAX)) - err = mz_stream_read_uint64(file_info_stream, &file_info->uncompressed_size); - if ((err == MZ_OK) && (file_info->compressed_size == UINT32_MAX)) - err = mz_stream_read_uint64(file_info_stream, &file_info->compressed_size); - if ((err == MZ_OK) && (file_info->disk_offset == UINT32_MAX)) - err = mz_stream_read_uint64(file_info_stream, &value64); - file_info->disk_offset = value64; - if ((err == MZ_OK) && (file_info->disk_number == UINT16_MAX)) - err = mz_stream_read_uint32(file_info_stream, &file_info->disk_number); - } - // NTFS extra field - else if (extra_header_id == MZ_ZIP_EXTENSION_NTFS) - { - if (err == MZ_OK) - err = mz_stream_read_uint32(file_info_stream, &reserved); - extra_data_size_read = 4; - - while ((err == MZ_OK) && (extra_data_size_read < extra_data_size)) - { - err = mz_stream_read_uint16(file_info_stream, &ntfs_attrib_id); - if (err == MZ_OK) - err = mz_stream_read_uint16(file_info_stream, &ntfs_attrib_size); - - if ((err == MZ_OK) && (ntfs_attrib_id == 0x01) && (ntfs_attrib_size == 24)) - { - err = mz_stream_read_uint64(file_info_stream, &ntfs_time); - mz_zip_ntfs_to_unix_time(ntfs_time, &file_info->modified_date); - - if (err == MZ_OK) - { - err = mz_stream_read_uint64(file_info_stream, &ntfs_time); - mz_zip_ntfs_to_unix_time(ntfs_time, &file_info->accessed_date); - } - if (err == MZ_OK) - { - err = mz_stream_read_uint64(file_info_stream, &ntfs_time); - mz_zip_ntfs_to_unix_time(ntfs_time, &file_info->creation_date); - } - } - else - { - if (err == MZ_OK) - err = mz_stream_seek(file_info_stream, ntfs_attrib_size, MZ_SEEK_CUR); - } - - extra_data_size_read += ntfs_attrib_size + 4; - } - } -#ifdef HAVE_AES - // AES extra field - else if (extra_header_id == MZ_ZIP_EXTENSION_AES) - { - uint8_t value8 = 0; - // Verify version info - err = mz_stream_read_uint16(file_info_stream, &value16); - // Support AE-1 and AE-2 - if (value16 != 1 && value16 != 2) - err = MZ_FORMAT_ERROR; - file_info->aes_version = value16; - if (err == MZ_OK) - err = mz_stream_read_uint8(file_info_stream, &value8); - if ((char)value8 != 'A') - err = MZ_FORMAT_ERROR; - if (err == MZ_OK) - err = mz_stream_read_uint8(file_info_stream, &value8); - if ((char)value8 != 'E') - err = MZ_FORMAT_ERROR; - // Get AES encryption strength and actual compression method - if (err == MZ_OK) - err = mz_stream_read_uint8(file_info_stream, &value8); - file_info->aes_encryption_mode = value8; - if (err == MZ_OK) - err = mz_stream_read_uint16(file_info_stream, &value16); - file_info->compression_method = value16; - } -#endif - else - { - err = mz_stream_seek(file_info_stream, extra_data_size, MZ_SEEK_CUR); - } - - extra_pos += 4 + extra_data_size; - } - } - - if ((err == MZ_OK) && (file_info->comment_size > 0)) - { - mz_stream_mem_get_buffer_at(file_info_stream, seek, (const void **)&file_info->comment); - - err = mz_stream_copy(file_info_stream, stream, file_info->comment_size); - if (err == MZ_OK) - err = mz_stream_write_uint8(file_info_stream, 0); - } - - return err; -} - -static int32_t mz_zip_entry_write_header(void *stream, uint8_t local, mz_zip_file *file_info) -{ - uint64_t ntfs_time = 0; - uint32_t reserved = 0; - uint32_t dos_date = 0; - uint16_t extrafield_size = 0; - uint16_t extrafield_zip64_size = 0; - uint16_t extrafield_ntfs_size = 0; - uint16_t filename_size = 0; - uint16_t filename_length = 0; - uint16_t comment_size = 0; - uint16_t version_needed = 0; - uint8_t zip64 = 0; - int32_t err = MZ_OK; - - if (file_info == NULL) - return MZ_PARAM_ERROR; - - // Calculate extra field sizes - extrafield_size = file_info->extrafield_size; - - if (file_info->uncompressed_size >= UINT32_MAX) - extrafield_zip64_size += 8; - if (file_info->compressed_size >= UINT32_MAX) - extrafield_zip64_size += 8; - if (file_info->disk_offset >= UINT32_MAX) - extrafield_zip64_size += 8; - - if (file_info->zip64 == MZ_ZIP64_AUTO) - { - // If uncompressed size is unknown, assume zip64 for 64-bit data descriptors - zip64 = (local && file_info->uncompressed_size == 0) || (extrafield_zip64_size > 0); - } - else if (file_info->zip64 == MZ_ZIP64_FORCE) - zip64 = 1; - else if (file_info->zip64 == MZ_ZIP64_DISABLE) - { - // Zip64 extension is required to zip file - if (extrafield_zip64_size > 0) - return MZ_PARAM_ERROR; - } - - if (zip64) - { - extrafield_size += 4; - extrafield_size += extrafield_zip64_size; - } -#ifdef HAVE_AES - if ((file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) && (file_info->aes_version)) - extrafield_size += 4 + 7; -#endif - // NTFS timestamps - if ((file_info->modified_date != 0) && - (file_info->accessed_date != 0) && - (file_info->creation_date != 0)) - { - extrafield_ntfs_size += 8 + 8 + 8 + 4 + 2 + 2; - extrafield_size += 4; - extrafield_size += extrafield_ntfs_size; - } - - if (local) - err = mz_stream_write_uint32(stream, MZ_ZIP_MAGIC_LOCALHEADER); - else - { - err = mz_stream_write_uint32(stream, MZ_ZIP_MAGIC_CENTRALHEADER); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, file_info->version_madeby); - } - - // Calculate version needed to extract - if (err == MZ_OK) - { - version_needed = file_info->version_needed; - if (version_needed == 0) - { - version_needed = 20; - if (zip64) - version_needed = 45; -#ifdef HAVE_AES - if ((file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) && (file_info->aes_version)) - version_needed = 51; -#endif -#ifdef HAVE_LZMA - if (file_info->compression_method == MZ_COMPRESS_METHOD_LZMA) - version_needed = 63; -#endif - } - err = mz_stream_write_uint16(stream, version_needed); - } - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, file_info->flag); - if (err == MZ_OK) - { -#ifdef HAVE_AES - if (file_info->aes_version) - err = mz_stream_write_uint16(stream, MZ_COMPRESS_METHOD_AES); - else -#endif - err = mz_stream_write_uint16(stream, file_info->compression_method); - } - if (err == MZ_OK) - { - if (file_info->modified_date != 0) - dos_date = mz_zip_time_t_to_dos_date(file_info->modified_date); - err = mz_stream_write_uint32(stream, dos_date); - } - - if (err == MZ_OK) - err = mz_stream_write_uint32(stream, file_info->crc); // crc - if (err == MZ_OK) - { - if (file_info->compressed_size >= UINT32_MAX) // compr size - err = mz_stream_write_uint32(stream, UINT32_MAX); - else - err = mz_stream_write_uint32(stream, (uint32_t)file_info->compressed_size); - } - if (err == MZ_OK) - { - if (file_info->uncompressed_size >= UINT32_MAX) // uncompr size - err = mz_stream_write_uint32(stream, UINT32_MAX); - else - err = mz_stream_write_uint32(stream, (uint32_t)file_info->uncompressed_size); - } - - filename_length = (uint16_t)strlen(file_info->filename); - if (err == MZ_OK) - { - filename_size = filename_length; - if (mz_zip_attrib_is_dir(file_info->external_fa, file_info->version_madeby) == MZ_OK) - { - if ((file_info->filename[filename_length - 1] == '/') || - (file_info->filename[filename_length - 1] == '\\')) - filename_length -= 1; - else - filename_size += 1; - } - err = mz_stream_write_uint16(stream, filename_size); - } - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, extrafield_size); - - if (!local) - { - if (file_info->comment != NULL) - comment_size = (uint16_t)strlen(file_info->comment); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, comment_size); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, (uint16_t)file_info->disk_number); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, file_info->internal_fa); - if (err == MZ_OK) - err = mz_stream_write_uint32(stream, file_info->external_fa); - if (err == MZ_OK) - { - if (file_info->disk_offset >= UINT32_MAX) - err = mz_stream_write_uint32(stream, UINT32_MAX); - else - err = mz_stream_write_uint32(stream, (uint32_t)file_info->disk_offset); - } - } - - if (err == MZ_OK) - { - if (mz_stream_write(stream, file_info->filename, filename_length) != filename_length) - err = MZ_STREAM_ERROR; - if (err == MZ_OK) - { - // Ensure that directories have a slash appended to them for compatibility - if (mz_zip_attrib_is_dir(file_info->external_fa, file_info->version_madeby) == MZ_OK) - err = mz_stream_write_uint8(stream, '/'); - } - } - if (err == MZ_OK) - { - if (mz_stream_write(stream, file_info->extrafield, file_info->extrafield_size) != file_info->extrafield_size) - err = MZ_STREAM_ERROR; - } - // Add ZIP64 extra info header to central directory - if ((err == MZ_OK) && (zip64)) - { - err = mz_stream_write_uint16(stream, MZ_ZIP_EXTENSION_ZIP64); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, extrafield_zip64_size); - if ((err == MZ_OK) && (file_info->uncompressed_size >= UINT32_MAX)) - err = mz_stream_write_uint64(stream, file_info->uncompressed_size); - if ((err == MZ_OK) && (file_info->compressed_size >= UINT32_MAX)) - err = mz_stream_write_uint64(stream, file_info->compressed_size); - if ((err == MZ_OK) && (file_info->disk_offset >= UINT32_MAX)) - err = mz_stream_write_uint64(stream, file_info->disk_offset); - } - // Write NTFS timestamps - if ((err == MZ_OK) && (extrafield_ntfs_size > 0)) - { - err = mz_stream_write_uint16(stream, MZ_ZIP_EXTENSION_NTFS); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, extrafield_ntfs_size); - if (err == MZ_OK) - err = mz_stream_write_uint32(stream, reserved); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, 0x01); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, extrafield_ntfs_size - 8); - if (err == MZ_OK) - { - mz_zip_unix_to_ntfs_time(file_info->modified_date, &ntfs_time); - err = mz_stream_write_uint64(stream, ntfs_time); - } - if (err == MZ_OK) - { - mz_zip_unix_to_ntfs_time(file_info->accessed_date, &ntfs_time); - err = mz_stream_write_uint64(stream, ntfs_time); - } - if (err == MZ_OK) - { - mz_zip_unix_to_ntfs_time(file_info->creation_date, &ntfs_time); - err = mz_stream_write_uint64(stream, ntfs_time); - } - } -#ifdef HAVE_AES - // Write AES extra info header to central directory - if ((err == MZ_OK) && (file_info->flag & MZ_ZIP_FLAG_ENCRYPTED) && (file_info->aes_version)) - { - err = mz_stream_write_uint16(stream, MZ_ZIP_EXTENSION_AES); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, 7); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, file_info->aes_version); - if (err == MZ_OK) - err = mz_stream_write_uint8(stream, 'A'); - if (err == MZ_OK) - err = mz_stream_write_uint8(stream, 'E'); - if (err == MZ_OK) - err = mz_stream_write_uint8(stream, file_info->aes_encryption_mode); - if (err == MZ_OK) - err = mz_stream_write_uint16(stream, file_info->compression_method); - } -#endif - if ((err == MZ_OK) && (file_info->comment != NULL)) - { - if (mz_stream_write(stream, file_info->comment, file_info->comment_size) != MZ_OK) - err = MZ_STREAM_ERROR; - } - - return err; -} - -static int32_t mz_zip_entry_open_int(void *handle, int16_t compression_method, int16_t compress_level, const char *password) -{ - mz_zip *zip = (mz_zip *)handle; - int64_t max_total_in = 0; - int64_t total_in = 0; - int64_t footer_size = 0; - int32_t err = MZ_OK; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - zip->compression_method = compression_method; - - switch (zip->compression_method) - { - case MZ_COMPRESS_METHOD_RAW: - case MZ_COMPRESS_METHOD_DEFLATE: -#ifdef HAVE_BZIP2 - case MZ_COMPRESS_METHOD_BZIP2: -#endif -#if HAVE_LZMA - case MZ_COMPRESS_METHOD_LZMA: -#endif - err = MZ_OK; - break; - default: - return MZ_PARAM_ERROR; - } - - if ((zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED) && (password == NULL) && (zip->compression_method != MZ_COMPRESS_METHOD_RAW)) - return MZ_PARAM_ERROR; - - if ((err == MZ_OK) && (zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED) && (zip->compression_method != MZ_COMPRESS_METHOD_RAW)) - { -#ifdef HAVE_AES - if (zip->file_info.aes_version) - { - mz_stream_aes_create(&zip->crypt_stream); - mz_stream_aes_set_password(zip->crypt_stream, password); - mz_stream_aes_set_encryption_mode(zip->crypt_stream, zip->file_info.aes_encryption_mode); - } - else -#endif - { -#ifdef HAVE_PKCRYPT - uint8_t verify1 = 0; - uint8_t verify2 = 0; - - // Info-ZIP modification to ZipCrypto format: - // If bit 3 of the general purpose bit flag is set, it uses high byte of 16-bit File Time. - - if (zip->file_info.flag & MZ_ZIP_FLAG_DATA_DESCRIPTOR) - { - uint32_t dos_date = 0; - - dos_date = mz_zip_time_t_to_dos_date(zip->file_info.modified_date); - - verify1 = (uint8_t)((dos_date >> 16) & 0xff); - verify2 = (uint8_t)((dos_date >> 8) & 0xff); - } - else - { - verify1 = (uint8_t)((zip->file_info.crc >> 16) & 0xff); - verify2 = (uint8_t)((zip->file_info.crc >> 24) & 0xff); - } - - mz_stream_pkcrypt_create(&zip->crypt_stream); - mz_stream_pkcrypt_set_password(zip->crypt_stream, password); - mz_stream_pkcrypt_set_verify(zip->crypt_stream, verify1, verify2); -#endif - } - } - - if (err == MZ_OK) - { - if (zip->crypt_stream == NULL) - mz_stream_raw_create(&zip->crypt_stream); - - mz_stream_set_base(zip->crypt_stream, zip->stream); - - err = mz_stream_open(zip->crypt_stream, NULL, zip->open_mode); - } - - if (err == MZ_OK) - { - if (zip->compression_method == MZ_COMPRESS_METHOD_RAW) - mz_stream_raw_create(&zip->compress_stream); -#ifdef HAVE_ZLIB - else if (zip->compression_method == MZ_COMPRESS_METHOD_DEFLATE) - mz_stream_zlib_create(&zip->compress_stream); -#endif -#ifdef HAVE_BZIP2 - else if (zip->compression_method == MZ_COMPRESS_METHOD_BZIP2) - mz_stream_bzip_create(&zip->compress_stream); -#endif -#ifdef HAVE_LZMA - else if (zip->compression_method == MZ_COMPRESS_METHOD_LZMA) - mz_stream_lzma_create(&zip->compress_stream); -#endif - else - err = MZ_PARAM_ERROR; - } - - if (err == MZ_OK) - { - if (zip->open_mode & MZ_OPEN_MODE_WRITE) - { - mz_stream_set_prop_int64(zip->compress_stream, MZ_STREAM_PROP_COMPRESS_LEVEL, compress_level); - } - else - { - if (zip->compression_method == MZ_COMPRESS_METHOD_RAW || zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED) - { - max_total_in = zip->file_info.compressed_size; - if (mz_stream_get_prop_int64(zip->crypt_stream, MZ_STREAM_PROP_FOOTER_SIZE, &footer_size) == MZ_OK) - max_total_in -= footer_size; - if (mz_stream_get_prop_int64(zip->crypt_stream, MZ_STREAM_PROP_TOTAL_IN, &total_in) == MZ_OK) - max_total_in -= total_in; - mz_stream_set_prop_int64(zip->compress_stream, MZ_STREAM_PROP_TOTAL_IN_MAX, max_total_in); - } - if (zip->compression_method == MZ_COMPRESS_METHOD_LZMA && (zip->file_info.flag & MZ_ZIP_FLAG_LZMA_EOS_MARKER) == 0) - { - mz_stream_set_prop_int64(zip->compress_stream, MZ_STREAM_PROP_TOTAL_IN_MAX, zip->file_info.compressed_size); - mz_stream_set_prop_int64(zip->compress_stream, MZ_STREAM_PROP_TOTAL_OUT_MAX, zip->file_info.uncompressed_size); - } - } - - mz_stream_set_base(zip->compress_stream, zip->crypt_stream); - - err = mz_stream_open(zip->compress_stream, NULL, zip->open_mode); - } - if (err == MZ_OK) - { - mz_stream_crc32_create(&zip->crc32_stream); -#ifdef HAVE_ZLIB - mz_stream_crc32_set_update_func(zip->crc32_stream, - (mz_stream_crc32_update)mz_stream_zlib_get_crc32_update()); -#elif defined(HAVE_LZMA) - mz_stream_crc32_set_update_func(zip->crc32_stream, - (mz_stream_crc32_update)mz_stream_lzma_get_crc32_update()); -#else - #error ZLIB or LZMA required for CRC32 -#endif - - mz_stream_set_base(zip->crc32_stream, zip->compress_stream); - - err = mz_stream_open(zip->crc32_stream, NULL, zip->open_mode); - } - - if (err == MZ_OK) - { - zip->entry_opened = 1; - } - - return err; -} - -extern int32_t mz_zip_entry_read_open(void *handle, int16_t raw, const char *password) -{ - mz_zip *zip = (mz_zip *)handle; - int16_t compression_method = 0; - int32_t err = MZ_OK; - -#if !defined(HAVE_PKCRYPT) && !defined(HAVE_AES) - if (password != NULL) - return MZ_PARAM_ERROR; -#endif - if (zip == NULL) - return MZ_PARAM_ERROR; - if ((zip->open_mode & MZ_OPEN_MODE_READ) == 0) - return MZ_PARAM_ERROR; - if (zip->entry_scanned == 0) - return MZ_PARAM_ERROR; - if ((zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED) && (password == NULL) && (!raw)) - return MZ_PARAM_ERROR; - - if (zip->file_info.disk_number == zip->disk_number_with_cd) - mz_stream_set_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, -1); - else - mz_stream_set_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, zip->file_info.disk_number); - - err = mz_stream_seek(zip->stream, zip->file_info.disk_offset, MZ_SEEK_SET); - if (err == MZ_OK) - err = mz_zip_entry_read_header(zip->stream, 1, &zip->local_file_info, zip->local_file_info_stream); - - compression_method = zip->file_info.compression_method; - if (raw) - compression_method = MZ_COMPRESS_METHOD_RAW; - - if (err == MZ_OK) - err = mz_zip_entry_open_int(handle, compression_method, 0, password); - - return err; -} - -extern int32_t mz_zip_entry_write_open(void *handle, const mz_zip_file *file_info, int16_t compress_level, const char *password) -{ - mz_zip *zip = (mz_zip *)handle; - int64_t disk_number = 0; - int32_t err = MZ_OK; - int16_t compression_method = 0; - - -#if !defined(HAVE_PKCRYPT) && !defined(HAVE_AES) - if (password != NULL) - return MZ_PARAM_ERROR; -#endif - if (zip == NULL || file_info == NULL || file_info->filename == NULL) - return MZ_PARAM_ERROR; - - if (zip->entry_opened == 1) - { - err = mz_zip_entry_close(handle); - if (err != MZ_OK) - return err; - } - - memcpy(&zip->file_info, file_info, sizeof(mz_zip_file)); - - compression_method = zip->file_info.compression_method; - - if (compression_method == MZ_COMPRESS_METHOD_DEFLATE) - { - if ((compress_level == 8) || (compress_level == 9)) - zip->file_info.flag |= MZ_ZIP_FLAG_DEFLATE_MAX; - if (compress_level == 2) - zip->file_info.flag |= MZ_ZIP_FLAG_DEFLATE_FAST; - if (compress_level == 1) - zip->file_info.flag |= MZ_ZIP_FLAG_DEFLATE_SUPER_FAST; - } -#ifdef HAVE_LZMA - else if (compression_method == MZ_COMPRESS_METHOD_LZMA) - zip->file_info.flag |= MZ_ZIP_FLAG_LZMA_EOS_MARKER; -#endif - - zip->file_info.flag |= MZ_ZIP_FLAG_DATA_DESCRIPTOR; - - if (password != NULL) - zip->file_info.flag |= MZ_ZIP_FLAG_ENCRYPTED; - else - zip->file_info.flag &= ~MZ_ZIP_FLAG_ENCRYPTED; - - mz_stream_get_prop_int64(zip->stream, MZ_STREAM_PROP_DISK_NUMBER, &disk_number); - zip->file_info.disk_number = (uint32_t)disk_number; - - zip->file_info.disk_offset = mz_stream_tell(zip->stream); - zip->file_info.crc = 0; - zip->file_info.compressed_size = 0; - -#ifdef HAVE_AES - if (zip->file_info.aes_version && zip->file_info.aes_encryption_mode == 0) - zip->file_info.aes_encryption_mode = MZ_AES_ENCRYPTION_MODE_256; -#endif - - if ((compress_level == 0) || (mz_zip_attrib_is_dir(zip->file_info.external_fa, zip->file_info.version_madeby) == MZ_OK)) - compression_method = MZ_COMPRESS_METHOD_RAW; - - if (err == MZ_OK) - err = mz_zip_entry_write_header(zip->stream, 1, &zip->file_info); - if (err == MZ_OK) - err = mz_zip_entry_open_int(handle, compression_method, compress_level, password); - - return err; -} - -extern int32_t mz_zip_entry_read(void *handle, void *buf, uint32_t len) -{ - mz_zip *zip = (mz_zip *)handle; - int32_t read = 0; - - if (zip == NULL || zip->entry_opened == 0) - return MZ_PARAM_ERROR; - if (UINT_MAX == UINT16_MAX && len > UINT16_MAX) // Zlib limitation - return MZ_PARAM_ERROR; - if (len == 0 || zip->file_info.uncompressed_size == 0) - return 0; - read = mz_stream_read(zip->crc32_stream, buf, len); - if (read > 0) - zip->entry_read += read; - return read; -} - -extern int32_t mz_zip_entry_write(void *handle, const void *buf, uint32_t len) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL || zip->entry_opened == 0) - return MZ_PARAM_ERROR; - return mz_stream_write(zip->crc32_stream, buf, len); -} - -extern int32_t mz_zip_entry_get_info(void *handle, mz_zip_file **file_info) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL || zip->entry_scanned == 0) - return MZ_PARAM_ERROR; - *file_info = &zip->file_info; - return MZ_OK; -} - -extern int32_t mz_zip_entry_get_local_info(void *handle, mz_zip_file **local_file_info) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL || zip->entry_scanned == 0 || zip->entry_opened == 0) - return MZ_PARAM_ERROR; - *local_file_info = &zip->local_file_info; - return MZ_OK; -} - -extern int32_t mz_zip_entry_close_raw(void *handle, uint64_t uncompressed_size, uint32_t crc32) -{ - mz_zip *zip = (mz_zip *)handle; - uint64_t compressed_size = 0; - int32_t err = MZ_OK; - - if (zip == NULL || zip->entry_opened == 0) - return MZ_PARAM_ERROR; - - mz_stream_close(zip->compress_stream); - if (crc32 == 0) - crc32 = mz_stream_crc32_get_value(zip->crc32_stream); - - if ((zip->open_mode & MZ_OPEN_MODE_WRITE) == 0) - { -#ifdef HAVE_AES - // AES zip version AE-1 will expect a valid crc as well - if (zip->file_info.aes_version <= 0x0001) -#endif - { - if ((zip->entry_read > 0) && (zip->compression_method != MZ_COMPRESS_METHOD_RAW)) - { - if (crc32 != zip->file_info.crc) - err = MZ_CRC_ERROR; - } - } - } - - mz_stream_get_prop_int64(zip->compress_stream, MZ_STREAM_PROP_TOTAL_OUT, (int64_t *)&compressed_size); - if ((zip->compression_method != MZ_COMPRESS_METHOD_RAW) || (uncompressed_size == 0)) - mz_stream_get_prop_int64(zip->crc32_stream, MZ_STREAM_PROP_TOTAL_OUT, (int64_t *)&uncompressed_size); - - if (zip->file_info.flag & MZ_ZIP_FLAG_ENCRYPTED) - { - mz_stream_set_base(zip->crypt_stream, zip->stream); - err = mz_stream_close(zip->crypt_stream); - - mz_stream_get_prop_int64(zip->crypt_stream, MZ_STREAM_PROP_TOTAL_OUT, (int64_t *)&compressed_size); - } - - mz_stream_delete(&zip->crypt_stream); - - mz_stream_delete(&zip->compress_stream); - mz_stream_crc32_delete(&zip->crc32_stream); - - if (zip->open_mode & MZ_OPEN_MODE_WRITE) - { - if (err == MZ_OK) - { - err = mz_stream_write_uint32(zip->stream, MZ_ZIP_MAGIC_DATADESCRIPTOR); - if (err == MZ_OK) - err = mz_stream_write_uint32(zip->stream, crc32); - if (err == MZ_OK) - { - if (zip->file_info.uncompressed_size <= UINT32_MAX) - err = mz_stream_write_uint32(zip->stream, (uint32_t)compressed_size); - else - err = mz_stream_write_uint64(zip->stream, compressed_size); - } - if (err == MZ_OK) - { - if (zip->file_info.uncompressed_size <= UINT32_MAX) - err = mz_stream_write_uint32(zip->stream, (uint32_t)uncompressed_size); - else - err = mz_stream_write_uint64(zip->stream, uncompressed_size); - } - } - - zip->file_info.crc = crc32; - zip->file_info.compressed_size = compressed_size; - zip->file_info.uncompressed_size = uncompressed_size; - - if (err == MZ_OK) - err = mz_zip_entry_write_header(zip->cd_mem_stream, 0, &zip->file_info); - - zip->number_entry += 1; - } - - zip->entry_opened = 0; - - return err; -} - -extern int32_t mz_zip_entry_close(void *handle) -{ - return mz_zip_entry_close_raw(handle, 0, 0); -} - -static int32_t mz_zip_goto_next_entry_int(void *handle) -{ - mz_zip *zip = (mz_zip *)handle; - int32_t err = MZ_OK; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - zip->entry_scanned = 0; - - mz_stream_set_prop_int64(zip->cd_stream, MZ_STREAM_PROP_DISK_NUMBER, -1); - - err = mz_stream_seek(zip->cd_stream, zip->cd_current_pos, MZ_SEEK_SET); - if (err == MZ_OK) - err = mz_zip_entry_read_header(zip->cd_stream, 0, &zip->file_info, zip->file_info_stream); - if (err == MZ_OK) - zip->entry_scanned = 1; - return err; -} - -extern int32_t mz_zip_get_number_entry(void *handle, int64_t *number_entry) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL || number_entry == NULL) - return MZ_PARAM_ERROR; - *number_entry = zip->number_entry; - return MZ_OK; -} - -extern int32_t mz_zip_get_disk_number_with_cd(void *handle, uint32_t *disk_number_with_cd) -{ - mz_zip *zip = (mz_zip *)handle; - if (zip == NULL || disk_number_with_cd == NULL) - return MZ_PARAM_ERROR; - *disk_number_with_cd = zip->disk_number_with_cd; - return MZ_OK; -} - -extern int64_t mz_zip_get_entry(void *handle) -{ - mz_zip *zip = (mz_zip *)handle; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - return zip->cd_current_pos; -} - -extern int32_t mz_zip_goto_entry(void *handle, uint64_t cd_pos) -{ - mz_zip *zip = (mz_zip *)handle; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - if (cd_pos < zip->cd_start_pos || cd_pos > zip->cd_start_pos + zip->cd_size) - return MZ_PARAM_ERROR; - - zip->cd_current_pos = cd_pos; - - return mz_zip_goto_next_entry_int(handle); -} - -extern int32_t mz_zip_goto_first_entry(void *handle) -{ - mz_zip *zip = (mz_zip *)handle; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - zip->cd_current_pos = zip->cd_start_pos; - - return mz_zip_goto_next_entry_int(handle); -} - -extern int32_t mz_zip_goto_next_entry(void *handle) -{ - mz_zip *zip = (mz_zip *)handle; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - zip->cd_current_pos += MZ_ZIP_SIZE_CD_ITEM + zip->file_info.filename_size + - zip->file_info.extrafield_size + zip->file_info.comment_size; - - return mz_zip_goto_next_entry_int(handle); -} - -extern int32_t mz_zip_locate_entry(void *handle, const char *filename, mz_filename_compare_cb filename_compare_cb) -{ - mz_zip *zip = (mz_zip *)handle; - int32_t err = MZ_OK; - int32_t result = 0; - - if (zip == NULL) - return MZ_PARAM_ERROR; - - err = mz_zip_goto_first_entry(handle); - while (err == MZ_OK) - { - if (filename_compare_cb != NULL) - result = filename_compare_cb(handle, zip->file_info.filename, filename); - else - result = strcmp(zip->file_info.filename, filename); - - if (result == 0) - return MZ_OK; - - err = mz_zip_goto_next_entry(handle); - } - - return err; -} - -/***************************************************************************/ - -int32_t mz_zip_attrib_is_dir(int32_t attributes, int32_t version_madeby) -{ - int32_t host_system = (uint8_t)(version_madeby >> 8); - - if (host_system == MZ_HOST_SYSTEM_MSDOS || host_system == MZ_HOST_SYSTEM_WINDOWS_NTFS) - { - if ((attributes & 0x10) == 0x10) // FILE_ATTRIBUTE_DIRECTORY - return MZ_OK; - } - else if (host_system == MZ_HOST_SYSTEM_UNIX || host_system == MZ_HOST_SYSTEM_OSX_DARWIN) - { - if ((attributes & 00170000) == 0040000) // S_ISDIR - return MZ_OK; - } - - return MZ_EXIST_ERROR; -} - -/***************************************************************************/ - -static int32_t mz_zip_invalid_date(const struct tm *ptm) -{ -#define datevalue_in_range(min, max, value) ((min) <= (value) && (value) <= (max)) - return (!datevalue_in_range(0, 127 + 80, ptm->tm_year) || // 1980-based year, allow 80 extra - !datevalue_in_range(0, 11, ptm->tm_mon) || - !datevalue_in_range(1, 31, ptm->tm_mday) || - !datevalue_in_range(0, 23, ptm->tm_hour) || - !datevalue_in_range(0, 59, ptm->tm_min) || - !datevalue_in_range(0, 59, ptm->tm_sec)); -#undef datevalue_in_range -} - -static void mz_zip_dosdate_to_raw_tm(uint64_t dos_date, struct tm *ptm) -{ - uint64_t date = (uint64_t)(dos_date >> 16); - - ptm->tm_mday = (uint16_t)(date & 0x1f); - ptm->tm_mon = (uint16_t)(((date & 0x1E0) / 0x20) - 1); - ptm->tm_year = (uint16_t)(((date & 0x0FE00) / 0x0200) + 80); - ptm->tm_hour = (uint16_t)((dos_date & 0xF800) / 0x800); - ptm->tm_min = (uint16_t)((dos_date & 0x7E0) / 0x20); - ptm->tm_sec = (uint16_t)(2 * (dos_date & 0x1f)); - ptm->tm_isdst = -1; -} - -int32_t mz_zip_dosdate_to_tm(uint64_t dos_date, struct tm *ptm) -{ - if (ptm == NULL) - return MZ_PARAM_ERROR; - - mz_zip_dosdate_to_raw_tm(dos_date, ptm); - - if (mz_zip_invalid_date(ptm)) - { - // Invalid date stored, so don't return it - memset(ptm, 0, sizeof(struct tm)); - return MZ_FORMAT_ERROR; - } - return MZ_OK; -} - -time_t mz_zip_dosdate_to_time_t(uint64_t dos_date) -{ - struct tm ptm; - mz_zip_dosdate_to_raw_tm(dos_date, &ptm); - return mktime(&ptm); -} - -int32_t mz_zip_time_t_to_tm(time_t unix_time, struct tm *ptm) -{ - struct tm *ltm = NULL; - if (ptm == NULL) - return MZ_PARAM_ERROR; - ltm = localtime(&unix_time); // Returns a 1900-based year - if (ltm == NULL) - { - // Invalid date stored, so don't return it - memset(ptm, 0, sizeof(struct tm)); - return MZ_INTERNAL_ERROR; - } - memcpy(ptm, ltm, sizeof(struct tm)); - return MZ_OK; -} - -uint32_t mz_zip_time_t_to_dos_date(time_t unix_time) -{ - struct tm ptm; - mz_zip_time_t_to_tm(unix_time, &ptm); - return mz_zip_tm_to_dosdate((const struct tm *)&ptm); -} - -uint32_t mz_zip_tm_to_dosdate(const struct tm *ptm) -{ - struct tm fixed_tm; - - // Years supported: - - // [00, 79] (assumed to be between 2000 and 2079) - // [80, 207] (assumed to be between 1980 and 2107, typical output of old - // software that does 'year-1900' to get a double digit year) - // [1980, 2107] (due to format limitations, only years 1980-2107 can be stored.) - - memcpy(&fixed_tm, ptm, sizeof(struct tm)); - if (fixed_tm.tm_year >= 1980) // range [1980, 2107] - fixed_tm.tm_year -= 1980; - else if (fixed_tm.tm_year >= 80) // range [80, 207] - fixed_tm.tm_year -= 80; - else // range [00, 79] - fixed_tm.tm_year += 20; - - if (mz_zip_invalid_date(&fixed_tm)) - return 0; - - return (uint32_t)(((fixed_tm.tm_mday) + (32 * (fixed_tm.tm_mon + 1)) + (512 * fixed_tm.tm_year)) << 16) | - ((fixed_tm.tm_sec / 2) + (32 * fixed_tm.tm_min) + (2048 * (uint32_t)fixed_tm.tm_hour)); -} - -int32_t mz_zip_ntfs_to_unix_time(uint64_t ntfs_time, time_t *unix_time) -{ - *unix_time = (time_t)((ntfs_time - 116444736000000000LL) / 10000000); - return MZ_OK; -} - -int32_t mz_zip_unix_to_ntfs_time(time_t unix_time, uint64_t *ntfs_time) -{ - *ntfs_time = ((uint64_t)unix_time * 10000000) + 116444736000000000LL; - return MZ_OK; -} diff --git a/game/client/third/minizip/mz_zip.h b/game/client/third/minizip/mz_zip.h deleted file mode 100755 index a2fe6c9b..00000000 --- a/game/client/third/minizip/mz_zip.h +++ /dev/null @@ -1,164 +0,0 @@ -/* mz_zip.h -- Zip manipulation - Version 2.3.3, June 10, 2018 - part of the MiniZip project - - Copyright (C) 2010-2018 Nathan Moinvaziri - https://github.com/nmoinvaz/minizip - Copyright (C) 2009-2010 Mathias Svensson - Modifications for Zip64 support - http://result42.com - Copyright (C) 1998-2010 Gilles Vollant - http://www.winimage.com/zLibDll/minizip.html - - This program is distributed under the terms of the same license as zlib. - See the accompanying LICENSE file for the full text of the license. -*/ - -#ifndef MZ_ZIP_H -#define MZ_ZIP_H - -#include -#include - -#include "mz_strm.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -typedef struct mz_zip_file_s -{ - uint16_t version_madeby; // version made by - uint16_t version_needed; // version needed to extract - uint16_t flag; // general purpose bit flag - uint16_t compression_method; // compression method - time_t modified_date; // last modified date in unix time - time_t accessed_date; // last accessed date in unix time - time_t creation_date; // creation date in unix time - uint32_t crc; // crc-32 - uint64_t compressed_size; // compressed size - uint64_t uncompressed_size; // uncompressed size - uint16_t filename_size; // filename length - uint16_t extrafield_size; // extra field length - uint16_t comment_size; // file comment length - uint32_t disk_number; // disk number start - uint64_t disk_offset; // relative offset of local header - uint16_t internal_fa; // internal file attributes - uint32_t external_fa; // external file attributes - uint16_t zip64; // zip64 extension mode - - const char *filename; // filename string - const uint8_t *extrafield; // extrafield data - const char *comment; // comment string - -#ifdef HAVE_AES - uint16_t aes_version; // winzip aes extension if not 0 - uint8_t aes_encryption_mode; // winzip aes encryption mode -#endif -} mz_zip_file; - -/***************************************************************************/ - -extern void * mz_zip_open(void *stream, int32_t mode); -// Create a zip file, no delete file in zip functionality - -extern int32_t mz_zip_close(void *handle); -// Close the zip file - -extern int32_t mz_zip_get_comment(void *handle, const char **comment); -// Get a pointer to the global comment - -extern int32_t mz_zip_set_comment(void *handle, const char *comment); -// Set the global comment used for writing zip file - -extern int32_t mz_zip_get_version_madeby(void *handle, uint16_t *version_madeby); -// Get the version made by - -extern int32_t mz_zip_set_version_madeby(void *handle, uint16_t version_madeby); -// Set the version made by used for writing zip file - -extern int32_t mz_zip_entry_write_open(void *handle, const mz_zip_file *file_info, - int16_t compress_level, const char *password); -// Open for writing the current file in the zip file - -extern int32_t mz_zip_entry_write(void *handle, const void *buf, uint32_t len); -// Write bytes from the current file in the zip file - -extern int32_t mz_zip_entry_read_open(void *handle, int16_t raw, const char *password); -// Open for reading the current file in the zip file - -extern int32_t mz_zip_entry_read(void *handle, void *buf, uint32_t len); -// Read bytes from the current file in the zip file - -extern int32_t mz_zip_entry_get_info(void *handle, mz_zip_file **file_info); -// Get info about the current file, only valid while current entry is open - -extern int32_t mz_zip_entry_get_local_info(void *handle, mz_zip_file **local_file_info); -// Get local info about the current file, only valid while current entry is being read - -extern int32_t mz_zip_entry_close_raw(void *handle, uint64_t uncompressed_size, uint32_t crc32); -// Close the current file in the zip file where raw is compressed data - -extern int32_t mz_zip_entry_close(void *handle); -// Close the current file in the zip file - -/***************************************************************************/ - -extern int32_t mz_zip_get_number_entry(void *handle, int64_t *number_entry); -// Get the total number of entries - -extern int32_t mz_zip_get_disk_number_with_cd(void *handle, uint32_t *disk_number_with_cd); -// Get the the disk number containing the central directory record - -extern int64_t mz_zip_get_entry(void *handle); -// Return offset of the current entry in the zip file - -extern int32_t mz_zip_goto_entry(void *handle, uint64_t cd_pos); -// Go to specified entry in the zip file - -extern int32_t mz_zip_goto_first_entry(void *handle); -// Go to the first entry in the zip file - -extern int32_t mz_zip_goto_next_entry(void *handle); -// Go to the next entry in the zip file or MZ_END_OF_LIST if reaching the end - -typedef int32_t (*mz_filename_compare_cb)(void *handle, const char *filename1, const char *filename2); -extern int32_t mz_zip_locate_entry(void *handle, const char *filename, - mz_filename_compare_cb filename_compare_cb); -// Locate the file with the specified name in the zip file or MZ_END_LIST if not found - -/***************************************************************************/ - -int32_t mz_zip_attrib_is_dir(int32_t attributes, int32_t version_madeby); -// Checks to see if the attribute is a directory based on platform - -int32_t mz_zip_dosdate_to_tm(uint64_t dos_date, struct tm *ptm); -// Convert dos date/time format to struct tm - -time_t mz_zip_dosdate_to_time_t(uint64_t dos_date); -// Convert dos date/time format to time_t - -int32_t mz_zip_time_t_to_tm(time_t unix_time, struct tm *ptm); -// Convert time_t to time struct - -uint32_t mz_zip_time_t_to_dos_date(time_t unix_time); -// Convert time_t to dos date/time format - -uint32_t mz_zip_tm_to_dosdate(const struct tm *ptm); -// Convert struct tm to dos date/time format - -int32_t mz_zip_ntfs_to_unix_time(uint64_t ntfs_time, time_t *unix_time); -// Convert ntfs time to unix time - -int32_t mz_zip_unix_to_ntfs_time(time_t unix_time, uint64_t *ntfs_time); -// Convert unix time to ntfs time - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif /* _ZIP_H */ diff --git a/game/client/third/minizip/test/empty.zip b/game/client/third/minizip/test/empty.zip deleted file mode 100755 index 15cb0ecb..00000000 Binary files a/game/client/third/minizip/test/empty.zip and /dev/null differ diff --git a/game/client/third/minizip/test/test.c b/game/client/third/minizip/test/test.c deleted file mode 100755 index 5b8bb1e7..00000000 --- a/game/client/third/minizip/test/test.c +++ /dev/null @@ -1,331 +0,0 @@ -#include -#include -#include -#include -#include -#include - -#include "mz.h" -#include "mz_os.h" -#include "mz_strm.h" -#include "mz_strm_mem.h" -#include "mz_strm_bzip.h" -#include "mz_strm_crypt.h" -#include "mz_strm_aes.h" -#include "mz_strm_zlib.h" -#include "mz_zip.h" - - -/***************************************************************************/ - -void test_encrypt(char *method, mz_stream_create_cb crypt_create, char *password) -{ - char buf[UINT16_MAX]; - int16_t read = 0; - int16_t written = 0; - void *out_stream = NULL; - void *in_stream = NULL; - void *crypt_out_stream = NULL; - char filename[120]; - - mz_stream_os_create(&in_stream); - - if (mz_stream_os_open(in_stream, "LICENSE", MZ_OPEN_MODE_READ) == MZ_OK) - { - read = mz_stream_os_read(in_stream, buf, UINT16_MAX); - mz_stream_os_close(in_stream); - } - - mz_stream_os_delete(&in_stream); - mz_stream_os_create(&out_stream); - - snprintf(filename, sizeof(filename), "LICENSE.encrypt.%s", method); - if (mz_stream_os_open(out_stream, filename, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE) == MZ_OK) - { - crypt_create(&crypt_out_stream); - - mz_stream_set_base(crypt_out_stream, out_stream); - - if (mz_stream_open(crypt_out_stream, password, MZ_OPEN_MODE_WRITE) == MZ_OK) - { - written = mz_stream_write(crypt_out_stream, buf, read); - mz_stream_close(crypt_out_stream); - } - - mz_stream_delete(&crypt_out_stream); - - mz_stream_os_close(out_stream); - - printf("%s encrypted %d\n", filename, written); - } - - mz_stream_os_delete(&out_stream); - mz_stream_os_create(&in_stream); - - if (mz_stream_os_open(in_stream, filename, MZ_OPEN_MODE_READ) == MZ_OK) - { - crypt_create(&crypt_out_stream); - - mz_stream_set_base(crypt_out_stream, in_stream); - - if (mz_stream_open(crypt_out_stream, password, MZ_OPEN_MODE_READ) == MZ_OK) - { - read = mz_stream_read(crypt_out_stream, buf, read); - mz_stream_close(crypt_out_stream); - } - - mz_stream_delete(&crypt_out_stream); - - mz_stream_os_close(in_stream); - - printf("%s decrypted %d\n", filename, read); - } - - mz_stream_os_delete(&in_stream); - mz_stream_os_create(&out_stream); - - snprintf(filename, sizeof(filename), "LICENSE.decrypt.%s", method); - if (mz_stream_os_open(out_stream, filename, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE) == MZ_OK) - { - mz_stream_os_write(out_stream, buf, read); - mz_stream_os_close(out_stream); - } - - mz_stream_os_delete(&out_stream); -} - -void test_compress(char *method, mz_stream_create_cb create_compress) -{ - char buf[UINT16_MAX]; - int16_t read = 0; - uint64_t total_in = 0; - uint64_t total_out = 0; - void *crc_in_stream = NULL; - void *in_stream = NULL; - void *out_stream = NULL; - void *deflate_stream = NULL; - void *inflate_stream = NULL; - uint32_t crc32 = 0; - char filename[120]; - - printf("Testing compress %s\n", method); - - mz_stream_os_create(&in_stream); - - if (mz_stream_os_open(in_stream, "LICENSE", MZ_OPEN_MODE_READ) == MZ_OK) - { - - mz_stream_crc32_create(&crc_in_stream); - mz_stream_set_base(crc_in_stream, in_stream); - mz_stream_crc32_open(crc_in_stream, NULL, MZ_OPEN_MODE_READ); - read = mz_stream_read(crc_in_stream, buf, UINT16_MAX); - crc32 = mz_stream_crc32_get_value(crc_in_stream); - mz_stream_close(crc_in_stream); - mz_stream_crc32_delete(&crc_in_stream); - - mz_stream_os_close(in_stream); - } - - mz_stream_os_delete(&in_stream); - - if (read < 0) - { - printf("Failed to read LICENSE\n"); - return; - } - - printf("LICENSE crc 0x%08x\n", crc32); - - mz_stream_os_create(&out_stream); - - snprintf(filename, sizeof(filename), "LICENSE.deflate.%s", method); - if (mz_stream_os_open(out_stream, filename, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE) == MZ_OK) - { - create_compress(&deflate_stream); - mz_stream_set_base(deflate_stream, out_stream); - - mz_stream_open(deflate_stream, NULL, MZ_OPEN_MODE_WRITE); - mz_stream_write(deflate_stream, buf, read); - mz_stream_close(deflate_stream); - - mz_stream_get_prop_int64(deflate_stream, MZ_STREAM_PROP_TOTAL_IN, &total_in); - mz_stream_get_prop_int64(deflate_stream, MZ_STREAM_PROP_TOTAL_OUT, &total_out); - - mz_stream_delete(&deflate_stream); - - printf("%s compressed from %u to %u\n", filename, (uint32_t)total_in, (uint32_t)total_out); - - mz_stream_os_close(out_stream); - } - - mz_stream_os_delete(&out_stream); - mz_stream_os_create(&in_stream); - - if (mz_stream_os_open(in_stream, filename, MZ_OPEN_MODE_READ) == MZ_OK) - { - create_compress(&inflate_stream); - mz_stream_set_base(inflate_stream, in_stream); - - mz_stream_open(inflate_stream, NULL, MZ_OPEN_MODE_READ); - read = mz_stream_read(inflate_stream, buf, UINT16_MAX); - mz_stream_close(inflate_stream); - - mz_stream_get_prop_int64(inflate_stream, MZ_STREAM_PROP_TOTAL_IN, &total_in); - mz_stream_get_prop_int64(inflate_stream, MZ_STREAM_PROP_TOTAL_OUT, &total_out); - - mz_stream_delete(&inflate_stream); - - mz_stream_os_close(in_stream); - - printf("%s uncompressed from %u to %u\n", filename, (uint32_t)total_in, (uint32_t)total_out); - } - - mz_stream_os_delete(&in_stream); - mz_stream_os_create(&out_stream); - - snprintf(filename, sizeof(filename), "LICENSE.inflate.%s", method); - if (mz_stream_os_open(out_stream, filename, MZ_OPEN_MODE_CREATE | MZ_OPEN_MODE_WRITE) == MZ_OK) - { - mz_stream_crc32_create(&crc_in_stream); - mz_stream_crc32_open(crc_in_stream, NULL, MZ_OPEN_MODE_WRITE); - - mz_stream_set_base(crc_in_stream, in_stream); - if (mz_stream_write(crc_in_stream, buf, read) != read) - printf("Failed to write %s\n", filename); - - crc32 = mz_stream_crc32_get_value(crc_in_stream); - - mz_stream_close(crc_in_stream); - mz_stream_delete(&crc_in_stream); - - mz_stream_os_close(out_stream); - - printf("%s crc 0x%08x\n", filename, crc32); - } - - mz_stream_os_delete(&out_stream); -} - -/***************************************************************************/ - -void test_aes() -{ - test_encrypt("aes", mz_stream_aes_create, "hello"); -} - -void test_crypt() -{ - test_encrypt("crypt", mz_stream_crypt_create, "hello"); -} - -void test_zlib() -{ - test_compress("zlib", mz_stream_zlib_create); -} - -void test_bzip() -{ - test_compress("bzip", mz_stream_bzip_create); -} - -/***************************************************************************/ - -void test_zip_mem() -{ - mz_zip_file file_info = { 0 }; - void *read_mem_stream = NULL; - void *write_mem_stream = NULL; - void *os_stream = NULL; - void *zip_handle = NULL; - int32_t written = 0; - int32_t read = 0; - int32_t text_size = 0; - int32_t buffer_size = 0; - int32_t err = MZ_OK; - char *buffer_ptr = NULL; - char *password = "1234"; - char *text_name = "test"; - char *text_ptr = "test string"; - char temp[120]; - - - text_size = (int32_t)strlen(text_ptr); - - // Write zip to memory stream - mz_stream_mem_create(&write_mem_stream); - mz_stream_mem_set_grow_size(write_mem_stream, 128 * 1024); - mz_stream_open(write_mem_stream, NULL, MZ_OPEN_MODE_CREATE); - - zip_handle = mz_zip_open(write_mem_stream, MZ_OPEN_MODE_READWRITE); - - if (zip_handle != NULL) - { - file_info.version_madeby = MZ_VERSION_MADEBY; - file_info.compression_method = MZ_COMPRESS_METHOD_DEFLATE; - file_info.filename = text_name; - file_info.uncompressed_size = text_size; - file_info.aes_version = MZ_AES_VERSION; - - err = mz_zip_entry_write_open(zip_handle, &file_info, MZ_COMPRESS_LEVEL_DEFAULT, password); - if (err == MZ_OK) - { - written = mz_zip_entry_write(zip_handle, text_ptr, text_size); - if (written < MZ_OK) - err = written; - mz_zip_entry_close(zip_handle); - } - - mz_zip_close(zip_handle); - } - else - { - err = MZ_INTERNAL_ERROR; - } - - mz_stream_mem_get_buffer(write_mem_stream, (void **)&buffer_ptr); - mz_stream_mem_seek(write_mem_stream, 0, MZ_SEEK_END); - buffer_size = (int32_t)mz_stream_mem_tell(write_mem_stream); - - if (err == MZ_OK) - { - // Create a zip file on disk for inspection - mz_stream_os_create(&os_stream); - mz_stream_os_open(os_stream, "mytest.zip", MZ_OPEN_MODE_WRITE | MZ_OPEN_MODE_CREATE); - mz_stream_os_write(os_stream, buffer_ptr, buffer_size); - mz_stream_os_close(os_stream); - mz_stream_os_delete(&os_stream); - } - - if (err == MZ_OK) - { - // Read from a memory stream - mz_stream_mem_create(&read_mem_stream); - mz_stream_mem_set_buffer(read_mem_stream, buffer_ptr, buffer_size); - mz_stream_open(read_mem_stream, NULL, MZ_OPEN_MODE_READ); - - zip_handle = mz_zip_open(read_mem_stream, MZ_OPEN_MODE_READ); - - if (zip_handle != NULL) - { - err = mz_zip_goto_first_entry(zip_handle); - if (err == MZ_OK) - err = mz_zip_entry_read_open(zip_handle, 0, password); - if (err == MZ_OK) - read = mz_zip_entry_read(zip_handle, temp, sizeof(temp)); - - mz_zip_entry_close(zip_handle); - mz_zip_close(zip_handle); - } - - mz_stream_mem_close(&read_mem_stream); - mz_stream_mem_delete(&read_mem_stream); - read_mem_stream = NULL; - } - - mz_stream_mem_close(write_mem_stream); - mz_stream_mem_delete(&write_mem_stream); - write_mem_stream = NULL; -} - - -/***************************************************************************/ diff --git a/game/client/third/minizip/test/test.h b/game/client/third/minizip/test/test.h deleted file mode 100755 index 8471aa3d..00000000 --- a/game/client/third/minizip/test/test.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _MZ_TEST_H -#define _MZ_TEST_H - -#ifdef __cplusplus -extern "C" { -#endif - -/***************************************************************************/ - -void test_aes(); -void test_crypt(); -void test_inflate(); -void test_deflate(); -void test_bzip(); -void test_zip_mem(); - -/***************************************************************************/ - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/game/client/third/minizip/test/test.py b/game/client/third/minizip/test/test.py deleted file mode 100755 index 160c067c..00000000 --- a/game/client/third/minizip/test/test.py +++ /dev/null @@ -1,202 +0,0 @@ -import os -import sys -import stat -import argparse -import glob -import shutil -import fnmatch -import time -import struct -import numpy -import random -import pprint -import hashlib -from sys import platform - -parser = argparse.ArgumentParser(description='Test script') -parser.add_argument('--exe_dir', help='Built exes directory', default=None, action='store', required=False) -args, unknown = parser.parse_known_args() - -def hash_file_sha1(path): - sha1 = hashlib.sha1() - with open(path, 'rb') as f: - while True: - data = f.read(8192) - if not data: - break - sha1.update(data) - return sha1.hexdigest() - -def find_files(directory, pattern, recursive = True): - if directory == '': - directory = os.getcwd() - if recursive: - items = os.walk(directory) - else: - items = [next(os.walk(directory))] - for root, dirs, files in items: - for basename in files: - if fnmatch.fnmatch(basename, pattern): - filename = os.path.join(root, basename) - yield filename - -def erase_file(path): - #print('Deleting {0}'.format(path)) - os.chmod(path, stat.S_IWUSR) - os.remove(path) - -def erase_files(search_pattern): - search_dir, match = os.path.split(search_pattern) - for path in find_files(search_dir, match): - erase_file(path) - -def erase_dir(path): - if not os.path.exists(path): - return - print('Erasing dir {0}'.format(path)) - # shutil.rmtree doesn't work well and sometimes can't delete - for root, dirs, files in os.walk(path, topdown=False): - for name in files: - filename = os.path.join(root, name) - success = False - while not success: - try: - erase_file(filename) - success = True - except: - time.sleep(4) - pass - for name in dirs: - os.rmdir(os.path.join(root, name)) - os.rmdir(path) - -def get_exec(name): - global args - if platform == 'win32': - name += '.exe' - if args.exe_dir is not None: - return os.path.join(args.exe_dir, name) - return name - -def get_files_info(path): - if os.path.isfile(path): - return { - path: { - 'hash': hash_file_sha1(path), - 'size': os.path.getsize(path) - } - } - info = {} - for root, dirs, files in os.walk(path): - path = root.split(os.sep) - for path in files: - info.update(get_files_info(path)) - return info - -def create_random_file(path, size): - if os.path.exists(path): - return - with open(path, 'wb') as fout: - i = 0 - while size > 0: - if i == 0 or i % 400000 == 0: - data = numpy.random.rand(100000) - floatlist = numpy.squeeze(numpy.asarray(data)) - buf = struct.pack('%sf' % len(floatlist), *floatlist) - fout.write(buf) - size -= len(buf) - i += 1 - -def zip(zip_file, zip_args, files): - cmd = '{0} {1} {2} {3}'.format(get_exec('minizip'), zip_args, zip_file, ' '.join(files)) - print cmd - err = os.system(cmd) - if (err != 0): - print('Zip returned error code {0}'.format(err)) - sys.exit(err) - -def list(zip_file): - cmd = '{0} -l {1}'.format(get_exec('minizip'), zip_file) - print cmd - err = os.system(cmd) - if (err != 0): - print('List returned error code {0}'.format(err)) - sys.exit(err) - -def unzip(zip_file, dest_dir, unzip_args = ''): - cmd = '{0} -x {1} -d {2} {3}'.format(get_exec('minizip'), unzip_args, dest_dir, zip_file) - print cmd - err = os.system(cmd) - if (err != 0): - print('Unzip returned error code {0}'.format(err)) - sys.exit(err) - -def zip_list_unzip(zip_file, dest_dir, zip_args, unzip_args, files): - # Single test run - original_infos = {} - for (i, path) in enumerate(files): - original_infos.update(get_files_info(path)) - print original_infos - - erase_files(zip_file[0:-2] + "*") - erase_dir(dest_dir) - - zip(zip_file, zip_args, files) - list(zip_file) - unzip(zip_file, dest_dir, unzip_args) - - new_infos = {} - for (i, path) in enumerate(files): - new_infos.update(get_files_info(path)) - - if (' '.join(original_infos) != ' '.join(new_infos)): - print('Infos do not match') - print('Original: ') - pprint(original_infos) - print('New: ') - print(new_infos) - -def file_tests(method, zip_arg = '', unzip_arg = ''): - print('Testing {0} on Single File'.format(method)) - zip_list_unzip('test.zip', 'out', zip_arg, unzip_arg, ['test.c']) - print('Testing {0} on Two Files'.format(method)) - zip_list_unzip('test.zip', 'out', zip_arg, unzip_arg, ['test.c', 'test.h']) - print('Testing {0} Directory'.format(method)) - zip_list_unzip('test.zip', 'out', zip_arg, unzip_arg, ['repo']) - print('Testing {0} 1MB file'.format(method)) - create_random_file('1MB.dat', 1 * 1024 * 1024) - zip_list_unzip('test.zip', 'out', zip_arg, unzip_arg, ['1MB.dat']) - print('Testing {0} 50MB file'.format(method)) - create_random_file('50MB.dat', 50 * 1024 * 1024) - zip_list_unzip('test.zip', 'out', zip_arg, unzip_arg, ['50MB.dat']) - -def compression_method_tests(method = '', zip_arg = '', unzip_arg = ''): - method = method + ' ' if method != '' else '' - file_tests(method + 'Deflate', zip_arg, unzip_arg) - file_tests(method + 'Raw', '-0 ' + zip_arg, unzip_arg) - file_tests(method + 'BZIP2', '-b ' + zip_arg, unzip_arg) - file_tests(method + 'LZMA', '-m ' + zip_arg, unzip_arg) - -def encryption_tests(): - compression_method_tests('Crypt', '-p 1234567890', '-p 1234567890') - compression_method_tests('AES', '-s -p 1234567890', '-p 1234567890') - -def empty_zip_test(): - unzip('empty.zip', 'out') - -def sfx_zip_test(): - org_exe = get_exec('minizip') - sfx_exe = org_exe.replace('.exe', '') + '_sfx.exe' - shutil.copyfile(org_exe, sfx_exe) - zip_list_unzip(sfx_exe, 'out', '-a', '', [ 'test.c', 'test.h' ]) - -if not os.path.exists('repo'): - os.system('git clone https://github.com/nmoinvaz/minizip repo') - -# Run tests -empty_zip_test() -sfx_zip_test() -compression_method_tests() -encryption_tests() -compression_method_tests('Disk Span', '-k 1024', '') -compression_method_tests('Buffered', '-u', '-u') diff --git a/game/client/touch.cpp b/game/client/touch.cpp index 586f616e..d45d616b 100644 --- a/game/client/touch.cpp +++ b/game/client/touch.cpp @@ -8,7 +8,9 @@ #include "cdll_int.h" #include "ienginevgui.h" #include "in_buttons.h" -#include "base_texture.h" +#include "filesystem.h" +#include "tier0/icommandline.h" +#include "vgui_controls/Button.h" extern ConVar cl_sidespeed; extern ConVar cl_forwardspeed; @@ -60,11 +62,36 @@ CTouchPanel::CTouchPanel( vgui::VPANEL parent ) : BaseClass( NULL, "TouchPanel" SetVisible( true ); } + void CTouchPanel::Paint() { gTouch.Frame(); } +void CTouchPanel::OnScreenSizeChanged(int iOldWide, int iOldTall) +{ + BaseClass::OnScreenSizeChanged(iOldWide, iOldTall); + + int w,h; + w = ScreenWidth(); + h = ScreenHeight(); + gTouch.screen_w = ScreenWidth(); gTouch.screen_h = h; + + SetBounds( 0, 0, w, h ); +} + +void CTouchPanel::ApplySchemeSettings(vgui::IScheme *pScheme) +{ + BaseClass::ApplySchemeSettings(pScheme); + + int w,h; + w = ScreenWidth(); + h = ScreenHeight(); + gTouch.screen_w = ScreenWidth(); gTouch.screen_h = h; + + SetBounds( 0, 0, w, h ); +} + CON_COMMAND( touch_addbutton, "add native touch button" ) { rgba_t color; @@ -129,7 +156,12 @@ CON_COMMAND( touch_settexture, "add native touch button" ) CON_COMMAND( touch_enableedit, "enable button editing mode" ) { - gTouch.EnableTouchEdit(); + gTouch.EnableTouchEdit(true); +} + +CON_COMMAND( touch_disableedit, "disable button editing mode" ) +{ + gTouch.EnableTouchEdit(false); } CON_COMMAND( touch_setcolor, "change button color" ) @@ -161,28 +193,40 @@ CON_COMMAND( touch_setflags, "change button flags" ) CON_COMMAND( touch_show, "show button" ) { - + if( args.ArgC() >= 2 ) + gTouch.ShowButton( args[1] ); + else + Msg( "Usage: touch_show \n" ); } CON_COMMAND( touch_hide, "hide button" ) { - + if( args.ArgC() >= 2 ) + gTouch.HideButton( args[1] ); + else + Msg( "Usage: touch_hide \n" ); } CON_COMMAND( touch_list, "list buttons" ) { - + gTouch.ListButtons(); } CON_COMMAND( touch_removeall, "remove all buttons" ) { - + gTouch.RemoveButtons(); } +CON_COMMAND( touch_writeconfig, "save current config" ) +{ + gTouch.WriteConfig(); +} + +/* CON_COMMAND( touch_loaddefaults, "generate config from defaults" ) { -} +} CON_COMMAND( touch_roundall, "round all buttons coordinates to grid" ) { @@ -198,12 +242,9 @@ CON_COMMAND( touch_reloadconfig, "load config, not saving changes" ) { } +*/ -CON_COMMAND( touch_writeconfig, "save current config" ) -{ - -} - +/* CON_COMMAND( touch_fade, "start fade animation for selected buttons" ) { @@ -212,21 +253,17 @@ CON_COMMAND( touch_fade, "start fade animation for selected buttons" ) CON_COMMAND( touch_toggleselection, "toggle visibility on selected button in editor" ) { -} +}*/ void CTouchControls::Init() { - m_bHaveAssets = true; - if( getAssets() == 0 ) - { - m_bHaveAssets = false; - base_textureID = vgui::surface()->CreateNewTextureID(true); - vgui::surface()->DrawSetTextureRGBA( base_textureID, base_img_rgba, 120, 96, 0, true ); - } + int w,h; + engine->GetScreenSize( w, h ); + screen_w = w; screen_h = h; - engine->GetScreenSize( screen_w, screen_h ); - - initialized = true; + Msg("grid_x: %f, grid_y: %x\n", GRID_X, GRID_Y); + configchanged = false; + config_loaded = false; btns.EnsureCapacity( 64 ); look_finger = move_finger = resize_finger = -1; forward = side = 0; @@ -243,10 +280,10 @@ void CTouchControls::Init() showtexture = hidetexture = resettexture = closetexture = joytexture = 0; configchanged = false; - rgba_t color(255, 255, 255, 255); + rgba_t color(255, 255, 255, 155); - AddButton( "_look", "", "", 0.5, 0, 1, 1, color, 0, 0, 0 ); - AddButton( "_move", "", "", 0, 0, 0.5, 1, color, 0, 0, 0 ); + AddButton( "look", "", "_look", 0.5, 0, 1, 1, color, 0, 0, 0 ); + AddButton( "move", "", "_move", 0, 0, 0.5, 1, color, 0, 0, 0 ); AddButton( "use", "vgui/touch/use", "+use", 0.880000, 0.213333, 1.000000, 0.426667, color ); AddButton( "jump", "vgui/touch/jump", "+jump", 0.880000, 0.462222, 1.000000, 0.675556, color ); @@ -254,7 +291,8 @@ void CTouchControls::Init() AddButton( "attack2", "vgui/touch/shoot_alt", "+attack2", 0.760000, 0.320000, 0.880000, 0.533333, color ); AddButton( "duck", "vgui/touch/crouch", "+duck", 0.880000, 0.746667, 1.000000, 0.960000, color ); AddButton( "tduck", "vgui/touch/tduck", ";+duck", 0.560000, 0.817778, 0.620000, 0.924444, color ); - AddButton( "zoom", "vgui/touch/zoom", "+scoreboard", 0.680000, 0.00000, 0.760000, 0.142222, color ); + AddButton( "zoom", "vgui/touch/zoom", "+zoom", 0.680000, 0.00000, 0.760000, 0.142222, color ); +// AddButton( "score", "vgui/touch/map", "+score", 0.680000, 0.00000, 0.760000, 0.142222, color ); AddButton( "speed", "vgui/touch/speed", "+speed", 0.180000, 0.568889, 0.280000, 0.746667, color ); AddButton( "loadquick", "vgui/touch/load", "load quick", 0.760000, 0.000000, 0.840000, 0.142222, color ); AddButton( "savequick", "vgui/touch/save", "save quick", 0.840000, 0.000000, 0.920000, 0.142222, color ); @@ -262,8 +300,19 @@ void CTouchControls::Init() AddButton( "flashlight", "vgui/touch/flash_light_filled", "impulse 100", 0.920000, 0.000000, 1.000000, 0.142222, color ); AddButton( "invnext", "vgui/touch/next_weap", "invnext", 0.000000, 0.533333, 0.120000, 0.746667, color ); AddButton( "invprev", "vgui/touch/prev_weap", "invprev", 0.000000, 0.071111, 0.120000, 0.284444, color ); - //AddButton( "edit", "vgui/touch/settings", "touch_enableedit", 0.420000, 0.000000, 0.500000, 0.151486, color ); + AddButton( "edit", "vgui/touch/settings", "touch_enableedit", 0.420000, 0.000000, 0.500000, 0.151486, color ); AddButton( "menu", "vgui/touch/menu", "gameui_activate", 0.000000, 0.00000, 0.080000, 0.142222, color ); +// AddButton( "lie", "vgui/touch/lie", "+alt1", 0.580000, 0.568889, 0.680000, 0.746667, color ); + + char buf[256]; + Q_snprintf(buf, sizeof buf, "exec %s\n", touch_config_file.GetString()); + engine->ClientCmd_Unrestricted(buf); + + Q_snprintf(buf, sizeof buf, "cfg/%s", touch_config_file.GetString()); + if( !filesystem->FileExists(buf) ) + WriteConfig(); + + initialized = true; } void CTouchControls::Shutdown( ) @@ -271,6 +320,25 @@ void CTouchControls::Shutdown( ) btns.PurgeAndDeleteElements(); } +void CTouchControls::RemoveButtons() +{ + btns.PurgeAndDeleteElements(); +} + +void CTouchControls::ListButtons() +{ + CUtlLinkedList::iterator it; + for( it = btns.begin(); it != btns.end(); it++ ) + { + CTouchButton *b = *it; + + Msg( "%s %s %s %f %f %f %f %d %d %d %d %d\n", + b->name, b->texturefile, b->command, + b->x1, b->y1, b->x2, b->y2, + b->color.r, b->color.g, b->color.b, b->color.a, b->flags ); + } +} + void CTouchControls::IN_CheckCoords( float *x1, float *y1, float *x2, float *y2 ) { /// TODO: grid check here @@ -322,15 +390,6 @@ void CTouchControls::Frame() IN_Look(); - if( !m_bHaveAssets ) - { - vgui::surface()->DrawSetColor(255,255,255,255); - vgui::surface()->DrawSetTexture(base_textureID); - - const int off = 50; - vgui::surface()->DrawTexturedRect( off, off, screen_w*0.3+off, 0.24f*screen_w+off ); - } - if( touch_enable.GetBool() && !enginevgui->IsGameUIVisible() ) Paint(); } @@ -339,16 +398,36 @@ void CTouchControls::Paint( ) if (!initialized) return; + + if( state == state_edit ) + { + vgui::surface()->DrawSetColor(255, 0, 0, 200); + float x,y; + + for( x = 0.0f; x < 1.0f; x += GRID_X ) + vgui::surface()->DrawLine( screen_w*x, 0, screen_w*x, screen_h ); + + for( y = 0.0f; y < 1.0f; y += GRID_Y ) + vgui::surface()->DrawLine( 0, screen_h*y, screen_w, screen_h*y ); + } + CUtlLinkedList::iterator it; for( it = btns.begin(); it != btns.end(); it++ ) { CTouchButton *btn = *it; - if( btn->type == touch_move || btn->type == touch_look ) - continue; - vgui::surface()->DrawSetColor(255, 255, 255, 155); - vgui::surface()->DrawSetTexture( btn->textureID ); - vgui::surface()->DrawTexturedRect( btn->x1*screen_w, btn->y1*screen_h, btn->x2*screen_w, btn->y2*screen_h ); + if( btn->type != touch_move && btn->type != touch_look && !(btn->flags & TOUCH_FL_HIDE) ) + { + vgui::surface()->DrawSetTexture( btn->textureID ); + vgui::surface()->DrawSetColor(btn->color.r, btn->color.g, btn->color.b, btn->color.a); + vgui::surface()->DrawTexturedRect( btn->x1*screen_w, btn->y1*screen_h, btn->x2*screen_w, btn->y2*screen_h ); + } + + if( state == state_edit && !(btn->flags & TOUCH_FL_NOEDIT) ) + { + vgui::surface()->DrawSetColor(255, 0, 0, 50); + vgui::surface()->DrawFilledRect( btn->x1*screen_w, btn->y1*screen_h, btn->x2*screen_w, btn->y2*screen_h ); + } } } @@ -361,21 +440,23 @@ void CTouchControls::AddButton( const char *name, const char *texturefile, const Q_strncpy( btn->texturefile, texturefile, sizeof(btn->texturefile) ); Q_strncpy( btn->command, command, sizeof(btn->command) ); - IN_CheckCoords(&x1, &y1, &x2, &y2); + if( round ) + IN_CheckCoords(&x1, &y1, &x2, &y2); if( round == round_aspect ) - y2 = y1 + ( x2 - x1 ) * (((float)screen_w)/screen_h); + y2 = y1 + ( x2 - x1 ) * (((float)screen_w)/screen_h) * aspect; btn->x1 = x1; btn->y1 = y1; btn->x2 = x2; btn->y2 = y2; + btn->flags = flags; - IN_CheckCoords(&btn->x1, &btn->y1, &btn->x2, &btn->y2); + //IN_CheckCoords(&btn->x1, &btn->y1, &btn->x2, &btn->y2); - if( Q_strcmp(name, "_look") == 0 ) + if( Q_strcmp(command, "_look") == 0 ) type = touch_look; - else if( Q_strcmp(name, "_move") == 0 ) + else if( Q_strcmp(command, "_move") == 0 ) type = touch_move; btn->color = color; @@ -390,12 +471,16 @@ void CTouchControls::AddButton( const char *name, const char *texturefile, const void CTouchControls::ShowButton( const char *name ) { - + CTouchButton *btn = FindButton( name ); + if( btn ) + btn->flags &= ~TOUCH_FL_HIDE; } void CTouchControls::HideButton(const char *name) { - + CTouchButton *btn = FindButton( name ); + if( btn ) + btn->flags |= TOUCH_FL_HIDE; } void CTouchControls::SetTexture(const char *name, const char *file) @@ -448,6 +533,7 @@ CTouchButton *CTouchControls::FindButton( const char *name ) if( Q_strncmp( button->name, name, sizeof(button->name)) == 0 ) return button; } + return NULL; } void CTouchControls::ProcessEvent(touch_event_t *ev) @@ -455,16 +541,91 @@ void CTouchControls::ProcessEvent(touch_event_t *ev) if( !touch_enable.GetBool() ) return; + if( state == state_edit ) + { + EditEvent(ev); + return; + } + if( ev->type == IE_FingerMotion ) FingerMotion( ev ); else FingerPress( ev ); } -void CTouchControls::FingerMotion(touch_event_t *ev) +void CTouchControls::EditEvent(touch_event_t *ev) { - float x = ev->x / (float)screen_w; - float y = ev->y / (float)screen_h; + const float x = ev->x; + const float y = ev->y; + + //CUtlLinkedList::iterator it; + + if( ev->type == IE_FingerDown ) + { + //for( it = btns.end(); it != btns.begin(); it-- ) unexpected, doesn't work + for( int i = btns.Count()-1; i >= 0; i-- ) + { + CTouchButton *btn = btns[i]; + if( x > btn->x1 && x < btn->x2 && y > btn->y1 && y < btn->y2 ) + { + if( btn->flags & TOUCH_FL_HIDE ) + continue; + + if( btn->flags & TOUCH_FL_NOEDIT ) + { + engine->ClientCmd_Unrestricted( btn->command ); + continue; + } + + if( move_finger == -1 ) + { + move_finger = ev->fingerid; + selection = btn; + break; + } + else if( resize_finger == -1 ) + { + resize_finger = ev->fingerid; + } + } + } + } + else if( ev->type == IE_FingerUp ) + { + if( ev->fingerid == move_finger ) + { + move_finger = -1; + IN_CheckCoords( &selection->x1, &selection->y1, &selection->x2, &selection->y2 ); + selection = nullptr; + } + else if( ev->fingerid == resize_finger ) + resize_finger = -1; + } + else // IE_FingerMotion + { + if( !selection ) + return; + + if( move_finger == ev->fingerid ) + { + selection->x1 += ev->dx; + selection->x2 += ev->dx; + selection->y1 += ev->dy; + selection->y2 += ev->dy; + } + else if( resize_finger == ev->fingerid ) + { + selection->x2 += ev->dx; + selection->y2 += ev->dy; + } + } +} + + +void CTouchControls::FingerMotion(touch_event_t *ev) // finger in my ass +{ + const float x = ev->x; + const float y = ev->y; float f, s; @@ -483,10 +644,8 @@ void CTouchControls::FingerMotion(touch_event_t *ev) } else if( btn->type == touch_look ) { - yaw += touch_yaw.GetFloat() * ( dx - x ) * sensitivity.GetFloat(); - pitch -= touch_pitch.GetFloat() * ( dy - y ) * sensitivity.GetFloat(); - dx = x; - dy = y; + yaw -= touch_yaw.GetFloat() * ev->dx * sensitivity.GetFloat(); + pitch += touch_pitch.GetFloat() * ev->dy * sensitivity.GetFloat(); } } } @@ -494,8 +653,8 @@ void CTouchControls::FingerMotion(touch_event_t *ev) void CTouchControls::FingerPress(touch_event_t *ev) { - float x = ev->x / (float)screen_w; - float y = ev->y / (float)screen_h; + const float x = ev->x; + const float y = ev->y; CUtlLinkedList::iterator it; @@ -506,6 +665,9 @@ void CTouchControls::FingerPress(touch_event_t *ev) CTouchButton *btn = *it; if( x > btn->x1 && x < btn->x2 && y > btn->y1 && y < btn->y2 ) { + if( btn->flags & TOUCH_FL_HIDE ) + continue; + btn->finger = ev->fingerid; if( btn->type == touch_move ) { @@ -521,11 +683,7 @@ void CTouchControls::FingerPress(touch_event_t *ev) else if( btn->type == touch_look ) { if( look_finger == -1 ) - { - dx = x; - dy = y; look_finger = ev->fingerid; - } else btn->finger = look_finger; } @@ -539,6 +697,10 @@ void CTouchControls::FingerPress(touch_event_t *ev) for( it = btns.begin(); it != btns.end(); it++ ) { CTouchButton *btn = *it; + + if( btn->flags & TOUCH_FL_HIDE ) + continue; + if( btn->finger == ev->fingerid ) { btn->finger = -1; @@ -563,10 +725,117 @@ void CTouchControls::FingerPress(touch_event_t *ev) } } -void CTouchControls::EnableTouchEdit() +void CTouchControls::EnableTouchEdit(bool enable) { - state = state_edit; - resize_finger = move_finger = look_finger = wheel_finger = -1; - move_button = NULL; - configchanged = true; + if( enable ) + { + state = state_edit; + resize_finger = move_finger = look_finger = wheel_finger = -1; + move_button = NULL; + configchanged = true; + AddButton( "close_edit", "vgui/touch/back", "touch_disableedit", 0.010000, 0.837778, 0.080000, 0.980000, rgba_t(255,255,255,255), 0, 1.f, TOUCH_FL_NOEDIT ); + } + else + { + state = state_none; + resize_finger = move_finger = look_finger = wheel_finger = -1; + move_button = NULL; + configchanged = false; + RemoveButton("close_edit"); + WriteConfig(); + } +} + +void CTouchControls::WriteConfig() +{ + FileHandle_t f; + char newconfigfile[128]; + char oldconfigfile[128]; + char configfile[128]; + + if( btns.IsEmpty() ) + return; + + if( CommandLine()->FindParm("-nowriteconfig") ) + return; + + DevMsg( "Touch_WriteConfig(): %s\n", touch_config_file.GetString() ); + + Q_snprintf( newconfigfile, 64, "cfg/%s.new", touch_config_file.GetString() ); + Q_snprintf( oldconfigfile, 64, "cfg/%s.bak", touch_config_file.GetString() ); + Q_snprintf( configfile, 64, "cfg/%s", touch_config_file.GetString() ); + + f = filesystem->Open( newconfigfile , "w+"); + + if( f ) + { + CTouchButton *button; + filesystem->FPrintf( f, "//=======================================================================\n"); + filesystem->FPrintf( f, "//\t\t\ttouchscreen config\n" ); + filesystem->FPrintf( f, "//=======================================================================\n" ); + filesystem->FPrintf( f, "\ntouch_config_file \"%s\"\n", touch_config_file.GetString() ); + filesystem->FPrintf( f, "\n// touch cvars\n" ); + filesystem->FPrintf( f, "\n// sensitivity settings\n" ); + filesystem->FPrintf( f, "touch_pitch \"%f\"\n", touch_pitch.GetFloat() ); + filesystem->FPrintf( f, "touch_yaw \"%f\"\n", touch_yaw.GetFloat() ); + filesystem->FPrintf( f, "touch_forwardzone \"%f\"\n", touch_forwardzone.GetFloat() ); + filesystem->FPrintf( f, "touch_sidezone \"%f\"\n", touch_sidezone.GetFloat() ); +/* filesystem->FPrintf( f, "touch_nonlinear_look \"%d\"\n",touch_nonlinear_look.GetBool() ); + filesystem->FPrintf( f, "touch_pow_factor \"%f\"\n", touch_pow_factor->value ); + filesystem->FPrintf( f, "touch_pow_mult \"%f\"\n", touch_pow_mult->value ); + filesystem->FPrintf( f, "touch_exp_mult \"%f\"\n", touch_exp_mult->value );*/ + filesystem->FPrintf( f, "\n// grid settings\n" ); + filesystem->FPrintf( f, "touch_grid_count \"%d\"\n", touch_grid_count.GetInt() ); + filesystem->FPrintf( f, "touch_grid_enable \"%d\"\n", touch_grid_enable.GetInt() ); +/* + filesystem->FPrintf( f, "\n// global overstroke (width, r, g, b, a)\n" ); + filesystem->FPrintf( f, "touch_set_stroke %d %d %d %d %d\n", touch.swidth, touch.scolor[0], touch.scolor[1], touch.scolor[2], touch.scolor[3] ); + filesystem->FPrintf( f, "\n// highlight when pressed\n" ); + filesystem->FPrintf( f, "touch_highlight_r \"%f\"\n", touch_highlight_r->value ); + filesystem->FPrintf( f, "touch_highlight_g \"%f\"\n", touch_highlight_g->value ); + filesystem->FPrintf( f, "touch_highlight_b \"%f\"\n", touch_highlight_b->value ); + filesystem->FPrintf( f, "touch_highlight_a \"%f\"\n", touch_highlight_a->value ); + filesystem->FPrintf( f, "\n// _joy and _dpad options\n" ); + filesystem->FPrintf( f, "touch_dpad_radius \"%f\"\n", touch_dpad_radius->value ); + filesystem->FPrintf( f, "touch_joy_radius \"%f\"\n", touch_joy_radius->value ); +*/ + filesystem->FPrintf( f, "\n// how much slowdown when Precise Look button pressed\n" ); + filesystem->FPrintf( f, "touch_precise_amount \"%f\"\n", touch_precise_amount.GetFloat() ); +// filesystem->FPrintf( f, "\n// enable/disable move indicator\n" ); +// filesystem->FPrintf( f, "touch_move_indicator \"%f\"\n", touch_move_indicator ); + + filesystem->FPrintf( f, "\n// reset menu state when execing config\n" ); + //filesystem->FPrintf( f, "touch_setclientonly 0\n" ); + filesystem->FPrintf( f, "\n// touch buttons\n" ); + filesystem->FPrintf( f, "touch_removeall\n" ); + + CUtlLinkedList::iterator it; + for( it = btns.begin(); it != btns.end(); it++ ) + { + CTouchButton *b = *it; + + if( b->flags & TOUCH_FL_CLIENT ) + continue; //skip temporary buttons + + if( b->flags & TOUCH_FL_DEF_SHOW ) + b->flags &= ~TOUCH_FL_HIDE; + + if( b->flags & TOUCH_FL_DEF_HIDE ) + b->flags |= TOUCH_FL_HIDE; + + float aspect = ( b->y2 - b->y1 ) / ( ( b->x2 - b->x1 )/(screen_h/screen_w) ); + + filesystem->FPrintf( f, "touch_addbutton \"%s\" \"%s\" \"%s\" %f %f %f %f %d %d %d %d %d %f\n", + b->name, b->texturefile, b->command, + b->x1, b->y1, b->x2, b->y2, + b->color.r, b->color.g, b->color.b, b->color.a, b->flags, aspect ); + } + + filesystem->Close(f); + + filesystem->RemoveFile(oldconfigfile); + filesystem->RenameFile(configfile, oldconfigfile ); + filesystem->RenameFile(newconfigfile, configfile); + } + else DevMsg( "Couldn't write %s.\n", configfile ); } diff --git a/game/client/touch.h b/game/client/touch.h index 1876fa22..5fe162c6 100644 --- a/game/client/touch.h +++ b/game/client/touch.h @@ -1,4 +1,5 @@ #include "utllinkedlist.h" +#include "vgui/ISurface.h" #include "vgui/VGUI.h" #include #include "cbase.h" @@ -6,12 +7,11 @@ #include "usercmd.h" extern ConVar touch_enable; -extern "C" int getAssets(); #define GRID_COUNT touch_grid_count.GetInt() #define GRID_COUNT_X (GRID_COUNT) #define GRID_COUNT_Y (GRID_COUNT * screen_h / screen_w) -#define GRID_X (1.0/GRID_COUNT_X) +#define GRID_X (1.0f/GRID_COUNT_X) #define GRID_Y (screen_w/screen_h/GRID_COUNT_X) #define GRID_ROUND_X(x) ((float)round( x * GRID_COUNT_X ) / GRID_COUNT_X) #define GRID_ROUND_Y(x) ((float)round( x * GRID_COUNT_Y ) / GRID_COUNT_Y) @@ -72,8 +72,7 @@ struct event_clientcmd_t struct event_s { int type; - int x; - int y; + float x,y,dx,dy; int fingerid; } typedef touch_event_t; @@ -110,8 +109,11 @@ class CTouchPanel : public vgui::Panel public: CTouchPanel( vgui::VPANEL parent ); virtual ~CTouchPanel( void ) {}; - virtual void Paint(); + virtual void ApplySchemeSettings(vgui::IScheme *pScheme); + +protected: + MESSAGE_FUNC_INT_INT( OnScreenSizeChanged, "OnScreenSizeChanged", oldwide, oldtall ); }; abstract_class ITouchPanel @@ -157,12 +159,13 @@ public: void Paint( ); void Frame( ); - void AddButton( const char *name, const char *texturefile, const char *command, float x1, float y1, float x2, float y2, rgba_t color = rgba_t(255, 255, 255, 255), int round = 2, float aspect = 1, int flags = 0 ); + void AddButton( const char *name, const char *texturefile, const char *command, float x1, float y1, float x2, float y2, rgba_t color = rgba_t(255, 255, 255, 255), int round = 2, float aspect = 1.f, int flags = 0 ); void RemoveButton( const char *name ); void HideButton( const char *name ); void ShowButton( const char *name ); - + void ListButtons(); + void RemoveButtons(); CTouchButton *FindButton( const char *name ); // bool FindNextButton( const char *name, CTouchButton &button ); @@ -170,9 +173,10 @@ public: void SetColor( const char *name, rgba_t color ); void SetCommand( const char *name, const char *cmd ); void SetFlags( const char *name, int flags ); - + void WriteConfig(); void IN_CheckCoords( float *x1, float *y1, float *x2, float *y2 ); + void InitGrid(); void Move( float frametime, CUserCmd *cmd ); @@ -182,11 +186,15 @@ public: void FingerPress( touch_event_t *ev ); void FingerMotion( touch_event_t *ev ); - void EnableTouchEdit(); + void EditEvent( touch_event_t *ev ); + + void EnableTouchEdit(bool enable); CTouchPanel *touchPanel; + float screen_h, screen_w; + private: - bool initialized; + bool initialized = false; ETouchState state; CUtlLinkedList btns; @@ -196,7 +204,6 @@ private: CTouchButton *move_button; float move_start_x, move_start_y; - float dx, dy; // editing CTouchButton *edit; @@ -214,13 +221,9 @@ private: int closetexture; int joytexture; // touch indicator bool configchanged; + bool config_loaded; vgui::HFont textfont; int mouse_events; - - int base_textureID; - - bool m_bHaveAssets; - int screen_h, screen_w; }; extern CTouchControls gTouch; diff --git a/game/client/wscript b/game/client/wscript index 3d8e1fe0..ca2ced3b 100755 --- a/game/client/wscript +++ b/game/client/wscript @@ -64,21 +64,9 @@ def build(bld): install_path = bld.env.PREFIX if bld.env.DEST_OS != 'android': - install_path += '/hl2/bin' + install_path += '/'+bld.env.GAMES+'/bin' - source = [ 'touch.cpp', 'arch.c' ] - - if bld.env.DEST_OS == 'android': - source += [ - 'third/minizip/mz_zip.c', - 'third/minizip/mz_strm.c', - 'third/minizip/mz_strm_mem.c', - 'third/minizip/mz_strm_buf.c', - 'third/minizip/mz_strm_split.c', - 'third/minizip/mz_strm_posix.c', - 'third/minizip/mz_strm_zlib.c', - 'third/minizip/mz_os_posix.c' - ] + source = [ 'touch.cpp' ] source += game["sources"] includes += game["includes"] diff --git a/game/server/wscript b/game/server/wscript index 92c37a03..a474c2f8 100755 --- a/game/server/wscript +++ b/game/server/wscript @@ -57,7 +57,7 @@ def build(bld): install_path = bld.env.PREFIX if bld.env.DEST_OS != 'android': - install_path += '/hl2/bin' + install_path += '/'+bld.env.GAMES+'/bin' source = game["sources"] includes += game["includes"] diff --git a/game/shared/achievementmgr.cpp b/game/shared/achievementmgr.cpp index ba1fab2b..606443bc 100644 --- a/game/shared/achievementmgr.cpp +++ b/game/shared/achievementmgr.cpp @@ -930,7 +930,7 @@ void CAchievementMgr::AwardAchievement( int iAchievementID ) pAchievement->OnAchieved(); // [tj] - IGameEvent * event = gameeventmanager->CreateEvent( "achievement_earned_local" ); + IGameEvent * event = gameeventmanager->CreateEvent( "achievement_earned" ); if ( event ) { event->SetInt( "achievement", pAchievement->GetAchievementID() ); @@ -1033,6 +1033,8 @@ extern bool IsInCommentaryMode( void ); //----------------------------------------------------------------------------- bool CAchievementMgr::CheckAchievementsEnabled() { + return true; + // if PC, Steam must be running and user logged in if ( IsPC() && !LoggedIntoSteam() ) { diff --git a/game/shared/saverestore.cpp b/game/shared/saverestore.cpp index cc8abfcf..bd1a7bef 100644 --- a/game/shared/saverestore.cpp +++ b/game/shared/saverestore.cpp @@ -112,7 +112,7 @@ static void Matrix3x4Offset( matrix3x4_t& dest, const matrix3x4_t& matrixIn, con // This does the necessary casting / extract to grab a pointer to a member function as a void * // UNDONE: Cast to BASEPTR or something else here? -#define EXTRACT_INPUTFUNC_FUNCTIONPTR(x) (*(inputfunc_t **)(&(x))) +//#define EXTRACT_INPUTFUNC_FUNCTIONPTR(x) (*(inputfunc_t **)(&(x))) //----------------------------------------------------------------------------- // Purpose: Search this datamap for the name of this member function @@ -120,7 +120,7 @@ static void Matrix3x4Offset( matrix3x4_t& dest, const matrix3x4_t& matrixIn, con // Input : *function - pointer to member function // Output : const char * - function name //----------------------------------------------------------------------------- -const char *UTIL_FunctionToName( datamap_t *pMap, inputfunc_t *function ) +const char *UTIL_FunctionToName( datamap_t *pMap, inputfunc_t function ) { while ( pMap ) { @@ -135,7 +135,7 @@ const char *UTIL_FunctionToName( datamap_t *pMap, inputfunc_t *function ) #else #error #endif - inputfunc_t *pTest = EXTRACT_INPUTFUNC_FUNCTIONPTR(pMap->dataDesc[i].inputFunc); + inputfunc_t pTest = pMap->dataDesc[i].inputFunc; if ( pTest == function ) return pMap->dataDesc[i].fieldName; @@ -152,7 +152,7 @@ const char *UTIL_FunctionToName( datamap_t *pMap, inputfunc_t *function ) // This is used to save/restore function pointers (convert text back to pointer) // Input : *pName - name of the member function //----------------------------------------------------------------------------- -inputfunc_t *UTIL_FunctionFromName( datamap_t *pMap, const char *pName ) +inputfunc_t UTIL_FunctionFromName( datamap_t *pMap, const char *pName ) { while ( pMap ) { @@ -170,7 +170,7 @@ inputfunc_t *UTIL_FunctionFromName( datamap_t *pMap, const char *pName ) { if ( FStrEq( pName, pMap->dataDesc[i].fieldName ) ) { - return EXTRACT_INPUTFUNC_FUNCTIONPTR(pMap->dataDesc[i].inputFunc); + return pMap->dataDesc[i].inputFunc; } } } @@ -1140,7 +1140,7 @@ void CSave::WritePositionVector( const Vector *value, int count ) void CSave::WriteFunction( datamap_t *pRootMap, const char *pname, inputfunc_t **data, int count ) { AssertMsg( count == 1, "Arrays of functions not presently supported" ); - const char *functionName = UTIL_FunctionToName( pRootMap, *data ); + const char *functionName = UTIL_FunctionToName( pRootMap, *(inputfunc_t*)data ); if ( !functionName ) { Warning( "Invalid function pointer in entity!\n" ); @@ -2240,8 +2240,14 @@ int CRestore::ReadFunction( datamap_t *pMap, inputfunc_t **pValue, int count, in if ( *pszFunctionName == 0 ) *pValue = NULL; else - *pValue = UTIL_FunctionFromName( pMap, pszFunctionName ); - + { + inputfunc_t func = UTIL_FunctionFromName( pMap, pszFunctionName ); +#ifdef GNUC + Q_memcpy( (void*)pValue, &func, sizeof(void*)*2 ); +#else + Q_memcpy( (void*)pValue, &func, sizeof(void*) ); +#endif + } return 0; } diff --git a/gameui/BasePanel.cpp b/gameui/BasePanel.cpp index eaabd91c..16e75081 100644 --- a/gameui/BasePanel.cpp +++ b/gameui/BasePanel.cpp @@ -1983,12 +1983,14 @@ void CBasePanel::RunMenuCommand(const char *command) { if ( IsPC() ) { +#ifndef NO_STEAM if ( !steamapicontext->SteamUser() || !steamapicontext->SteamUser()->BLoggedOn() ) { - vgui::MessageBox *pMessageBox = new vgui::MessageBox("#GameUI_Achievements_SteamRequired_Title", "#GameUI_Achievements_SteamRequired_Message"); + vgui::MessageBox *pMessageBox = new vgui::MessageBox("#GameUI_Achievements_SteamRequired_Title", "#GameUI_Achievements_SteamRequired_Message", this); pMessageBox->DoModal(); return; } +#endif OnOpenAchievementsDialog(); } else diff --git a/gameui/CreateMultiplayerGameDialog.cpp b/gameui/CreateMultiplayerGameDialog.cpp index a372255e..c8b2b52c 100644 --- a/gameui/CreateMultiplayerGameDialog.cpp +++ b/gameui/CreateMultiplayerGameDialog.cpp @@ -34,7 +34,16 @@ CCreateMultiplayerGameDialog::CCreateMultiplayerGameDialog(vgui::Panel *parent) { m_bBotsEnabled = false; SetDeleteSelfOnClose(true); - SetSize(348, 460); + + int w = 348; + int h = 460; + if (IsProportional()) + { + w = scheme()->GetProportionalScaledValueEx(GetScheme(), w); + h = scheme()->GetProportionalScaledValueEx(GetScheme(), h); + } + + SetSize(w, h); SetTitle("#GameUI_CreateServer", true); SetOKButtonText("#GameUI_Start"); diff --git a/gameui/GameConsole.cpp b/gameui/GameConsole.cpp index 5f1cb0c6..8bd55b72 100644 --- a/gameui/GameConsole.cpp +++ b/gameui/GameConsole.cpp @@ -148,6 +148,13 @@ void CGameConsole::SetParent( int parent ) return; m_pConsole->SetParent( static_cast( parent )); + + // apply proportionality from parent + if (vgui::ipanel()->IsProportional(static_cast(parent))) + { + m_pConsole->SetProportional(true); + m_pConsole->InvalidateLayout(true, true); + } #endif } diff --git a/gameui/NewGameDialog.cpp b/gameui/NewGameDialog.cpp index 2d768618..36325e3c 100644 --- a/gameui/NewGameDialog.cpp +++ b/gameui/NewGameDialog.cpp @@ -161,16 +161,6 @@ public: SetPaintBackgroundEnabled( false ); - // the image has the same name as the config file - char szMaterial[ MAX_PATH ]; - Q_snprintf( szMaterial, sizeof(szMaterial), "chapters/%s", chapterConfigFile ); - char *ext = strstr( szMaterial, "." ); - if ( ext ) - { - *ext = 0; - } - m_pLevelPic->SetImage( szMaterial ); - KeyValues *pKeys = NULL; if ( GameUI().IsConsoleUI() ) { @@ -178,6 +168,16 @@ public: } LoadControlSettings( "Resource/NewGameChapterPanel.res", NULL, pKeys ); + // the image has the same name as the config file + char szMaterial[MAX_PATH]; + Q_snprintf(szMaterial, sizeof(szMaterial), "chapters/%s", chapterConfigFile); + char* ext = strstr(szMaterial, "."); + if (ext) + { + *ext = 0; + } + m_pLevelPic->SetImage(szMaterial); + int px, py; m_pLevelPicBorder->GetPos( px, py ); SetSize( m_pLevelPicBorder->GetWide(), py + m_pLevelPicBorder->GetTall() ); @@ -525,11 +525,23 @@ CNewGameDialog::CNewGameDialog(vgui::Panel *parent, bool bCommentaryMode) : Base return; } + int indent = 8; + if ( IsProportional() ) + { + indent = scheme()->GetProportionalScaledValueEx( GetScheme(), indent ); + } + + int wide = 16; + if ( IsProportional() ) + { + wide = scheme()->GetProportionalScaledValueEx( GetScheme(), wide ); + } + // Layout panel positions relative to the dialog center. - int panelWidth = m_ChapterPanels[0]->GetWide() + 16; + int panelWidth = m_ChapterPanels[0]->GetWide() + wide; int dialogWidth = GetWide(); - m_PanelXPos[2] = ( dialogWidth - panelWidth ) / 2 + 8; + m_PanelXPos[2] = ( dialogWidth - panelWidth ) / 2 + indent; if (m_ChapterPanels.Count() > 1) { @@ -553,8 +565,8 @@ CNewGameDialog::CNewGameDialog(vgui::Panel *parent, bool bCommentaryMode) : Base int panelHeight; m_ChapterPanels[0]->GetSize( panelWidth, panelHeight ); - m_pCenterBg->SetWide( panelWidth + 16 ); - m_pCenterBg->SetPos( m_PanelXPos[2] - 8, m_PanelYPos[2] - (m_pCenterBg->GetTall() - panelHeight) + 8 ); + m_pCenterBg->SetWide( panelWidth + wide); + m_pCenterBg->SetPos( m_PanelXPos[2] - indent, m_PanelYPos[2] - (m_pCenterBg->GetTall() - panelHeight) + indent ); m_pCenterBg->SetBgColor( Color( 190, 115, 0, 255 ) ); // start the first item selected @@ -615,6 +627,11 @@ void CNewGameDialog::ApplySettings( KeyValues *inResourceData ) BaseClass::ApplySettings( inResourceData ); int ypos = inResourceData->GetInt( "chapterypos", 40 ); + if ( IsProportional() ) + { + ypos = scheme()->GetProportionalScaledValueEx( GetScheme(), ypos ); + } + for ( int i = 0; i < NUM_SLOTS; ++i ) { m_PanelYPos[i] = ypos; diff --git a/gameui/OptionsDialog.cpp b/gameui/OptionsDialog.cpp index b1dedfe8..c166a15b 100644 --- a/gameui/OptionsDialog.cpp +++ b/gameui/OptionsDialog.cpp @@ -45,7 +45,17 @@ using namespace vgui; COptionsDialog::COptionsDialog(vgui::Panel *parent) : PropertyDialog(parent, "OptionsDialog") { SetDeleteSelfOnClose(true); - SetBounds(0, 0, 512, 406); + + int w = 512; + int h = 406; + if (IsProportional()) + { + w = scheme()->GetProportionalScaledValueEx(GetScheme(), w); + h = scheme()->GetProportionalScaledValueEx(GetScheme(), h); + } + + SetBounds(0, 0, w, h); + SetSizeable( false ); SetTitle("#GameUI_Options", true); diff --git a/gameui/OptionsSubAudio.cpp b/gameui/OptionsSubAudio.cpp index 9a4d6aec..d1fffeba 100644 --- a/gameui/OptionsSubAudio.cpp +++ b/gameui/OptionsSubAudio.cpp @@ -383,39 +383,47 @@ void COptionsSubAudio::RunTestSpeakers() //----------------------------------------------------------------------------- class COptionsSubAudioThirdPartyCreditsDlg : public vgui::Frame { - DECLARE_CLASS_SIMPLE( COptionsSubAudioThirdPartyCreditsDlg, vgui::Frame ); + DECLARE_CLASS_SIMPLE(COptionsSubAudioThirdPartyCreditsDlg, vgui::Frame); public: - COptionsSubAudioThirdPartyCreditsDlg( vgui::VPANEL hParent ) : BaseClass( NULL, NULL ) - { - // parent is ignored, since we want look like we're steal focus from the parent (we'll become modal below) + COptionsSubAudioThirdPartyCreditsDlg(vgui::VPANEL hParent) : BaseClass(NULL, NULL) + { + // parent is ignored, since we want look like we're steal focus from the parent (we'll become modal below) + int w = 500; + int h = 200; + if (ipanel()->IsProportional(hParent)) + { + SetProportional(true); + w = scheme()->GetProportionalScaledValueEx(GetScheme(), w); + h = scheme()->GetProportionalScaledValueEx(GetScheme(), h); + } - SetTitle("#GameUI_ThirdPartyAudio_Title", true); - SetSize( 500, 200 ); - LoadControlSettings( "resource/OptionsSubAudioThirdPartyDlg.res" ); - MoveToCenterOfScreen(); - SetSizeable( false ); - SetDeleteSelfOnClose( true ); - } + SetTitle("#GameUI_ThirdPartyAudio_Title", true); + SetSize(w, h); + LoadControlSettings("resource/OptionsSubAudioThirdPartyDlg.res"); + MoveToCenterOfScreen(); + SetSizeable(false); + SetDeleteSelfOnClose(true); + } - virtual void Activate() - { - BaseClass::Activate(); + virtual void Activate() + { + BaseClass::Activate(); - input()->SetAppModalSurface(GetVPanel()); - } + input()->SetAppModalSurface(GetVPanel()); + } - void OnKeyCodeTyped(KeyCode code) - { - // force ourselves to be closed if the escape key it pressed - if (code == KEY_ESCAPE) - { - Close(); - } - else - { - BaseClass::OnKeyCodeTyped(code); - } - } + void OnKeyCodeTyped(KeyCode code) + { + // force ourselves to be closed if the escape key it pressed + if (code == KEY_ESCAPE) + { + Close(); + } + else + { + BaseClass::OnKeyCodeTyped(code); + } + } }; @@ -424,9 +432,9 @@ public: //----------------------------------------------------------------------------- void COptionsSubAudio::OpenThirdPartySoundCreditsDialog() { - if (!m_OptionsSubAudioThirdPartyCreditsDlg.Get()) - { - m_OptionsSubAudioThirdPartyCreditsDlg = new COptionsSubAudioThirdPartyCreditsDlg(GetVParent()); - } - m_OptionsSubAudioThirdPartyCreditsDlg->Activate(); + if (!m_OptionsSubAudioThirdPartyCreditsDlg.Get()) + { + m_OptionsSubAudioThirdPartyCreditsDlg = new COptionsSubAudioThirdPartyCreditsDlg(GetVParent()); + } + m_OptionsSubAudioThirdPartyCreditsDlg->Activate(); } diff --git a/gameui/OptionsSubVideo.cpp b/gameui/OptionsSubVideo.cpp index 57db4015..353f2d40 100644 --- a/gameui/OptionsSubVideo.cpp +++ b/gameui/OptionsSubVideo.cpp @@ -1041,6 +1041,7 @@ COptionsSubVideo::COptionsSubVideo(vgui::Panel *parent) : PropertyPage(parent, N unicodeText = g_pVGuiLocalize->Find("#GameUI_AspectWide16x10"); g_pVGuiLocalize->ConvertUnicodeToANSI(unicodeText, pszAspectName[2], 32); +#ifndef ANDROID int iNormalItemID = m_pAspectRatio->AddItem( pszAspectName[0], NULL ); int i16x9ItemID = m_pAspectRatio->AddItem( pszAspectName[1], NULL ); int i16x10ItemID = m_pAspectRatio->AddItem( pszAspectName[2], NULL ); @@ -1061,6 +1062,12 @@ COptionsSubVideo::COptionsSubVideo(vgui::Panel *parent) : PropertyPage(parent, N m_pAspectRatio->ActivateItem( i16x10ItemID ); break; } +#else + int iNormalItemID = m_pAspectRatio->AddItem( "lemonparty.org", NULL ); + m_pAspectRatio->ActivateItem( iNormalItemID ); + + m_pGammaButton->SetEnabled(false); +#endif char pszVRModeName[2][64]; unicodeText = g_pVGuiLocalize->Find("#GameUI_Disabled"); @@ -1110,6 +1117,10 @@ COptionsSubVideo::COptionsSubVideo(vgui::Panel *parent) : PropertyPage(parent, N m_pWindowed->AddItem( "#GameUI_Windowed", NULL ); #endif +#ifdef ANDROID + m_pWindowed->SetEnabled( false ); +#endif + LoadControlSettings("Resource\\OptionsSubVideo.res"); // Moved down here so we can set the Drop down's @@ -1160,9 +1171,10 @@ void COptionsSubVideo::PrepareResolutionList() // Clean up before filling the info again. m_pMode->DeleteAllItems(); +#ifndef ANDROID m_pAspectRatio->SetItemEnabled(1, false); m_pAspectRatio->SetItemEnabled(2, false); - +#endif // get full video mode list vmode_t *plist = NULL; int count = 0; @@ -1225,7 +1237,9 @@ void COptionsSubVideo::PrepareResolutionList() GetResolutionName( plist, sz, sizeof( sz ), desktopWidth, desktopHeight ); int itemID = -1; + int iAspectMode = GetScreenAspectMode( plist->width, plist->height ); +#ifndef ANDROID if ( iAspectMode > 0 ) { m_pAspectRatio->SetItemEnabled( iAspectMode, true ); @@ -1237,8 +1251,15 @@ void COptionsSubVideo::PrepareResolutionList() { itemID = m_pMode->AddItem( sz, NULL); } +#else + float aspect = (float)plist->width / plist->height; + float native_aspect = (float)desktopWidth / desktopHeight; - // try and find the best match for the resolution to be selected + if( fabs(native_aspect - aspect) < 0.01f ) + itemID = m_pMode->AddItem( sz, NULL); +#endif + + // try and find the bestplistplistplist match for the resolution to be selected if ( plist->width == currentWidth && plist->height == currentHeight ) { selectedItemID = itemID; @@ -1250,7 +1271,9 @@ void COptionsSubVideo::PrepareResolutionList() } // disable ratio selection if we can't display widescreen. +#ifndef ANDROID m_pAspectRatio->SetEnabled( bFoundWidescreen ); +#endif m_nSelectedMode = selectedItemID; @@ -1377,7 +1400,11 @@ void COptionsSubVideo::OnResetData() #endif // reset gamma control +#ifdef ANDROID + m_pGammaButton->SetEnabled( false ); +#else m_pGammaButton->SetEnabled( !config.Windowed() ); +#endif m_pHDContent->SetSelected( BUseHDContent() ); @@ -1577,8 +1604,12 @@ void COptionsSubVideo::PerformLayout() if ( m_pGammaButton ) { +#ifdef ANDROID + m_pGammaButton->SetEnabled( false ); +#else const MaterialSystem_Config_t &config = materials->GetCurrentConfigForVideoCard(); m_pGammaButton->SetEnabled( !config.Windowed() ); +#endif } } @@ -1600,10 +1631,12 @@ void COptionsSubVideo::OnTextChanged(Panel *pPanel, const char *pszText) OnDataChanged(); } } - else if (pPanel == m_pAspectRatio) - { +#ifndef ANDROID + else if (pPanel == m_pAspectRatio) + { PrepareResolutionList(); - } + } +#endif else if (pPanel == m_pWindowed) { PrepareResolutionList(); @@ -1645,7 +1678,11 @@ void COptionsSubVideo::EnableOrDisableWindowedForVR() } else { +#ifdef ANDROID + m_pWindowed->SetEnabled( false ); +#else m_pWindowed->SetEnabled( true ); +#endif } } @@ -1714,39 +1751,47 @@ void COptionsSubVideo::LaunchBenchmark() //----------------------------------------------------------------------------- class COptionsSubVideoThirdPartyCreditsDlg : public vgui::Frame { - DECLARE_CLASS_SIMPLE( COptionsSubVideoThirdPartyCreditsDlg, vgui::Frame ); + DECLARE_CLASS_SIMPLE(COptionsSubVideoThirdPartyCreditsDlg, vgui::Frame); public: - COptionsSubVideoThirdPartyCreditsDlg( vgui::VPANEL hParent ) : BaseClass( NULL, NULL ) - { - // parent is ignored, since we want look like we're steal focus from the parent (we'll become modal below) + COptionsSubVideoThirdPartyCreditsDlg(vgui::VPANEL hParent) : BaseClass(NULL, NULL) + { + // parent is ignored, since we want look like we're steal focus from the parent (we'll become modal below) + int w = 500; + int h = 200; + if (ipanel()->IsProportional(hParent)) + { + SetProportional(true); + w = scheme()->GetProportionalScaledValueEx(GetScheme(), w); + h = scheme()->GetProportionalScaledValueEx(GetScheme(), h); + } - SetTitle("#GameUI_ThirdPartyVideo_Title", true); - SetSize( 500, 200 ); - LoadControlSettings( "resource/OptionsSubVideoThirdPartyDlg.res" ); - MoveToCenterOfScreen(); - SetSizeable( false ); - SetDeleteSelfOnClose( true ); - } + SetTitle("#GameUI_ThirdPartyVideo_Title", true); + SetSize(w, h); + LoadControlSettings("resource/OptionsSubVideoThirdPartyDlg.res"); + MoveToCenterOfScreen(); + SetSizeable(false); + SetDeleteSelfOnClose(true); + } - virtual void Activate() - { - BaseClass::Activate(); + virtual void Activate() + { + BaseClass::Activate(); - input()->SetAppModalSurface(GetVPanel()); - } + input()->SetAppModalSurface(GetVPanel()); + } - void OnKeyCodeTyped(KeyCode code) - { - // force ourselves to be closed if the escape key it pressed - if (code == KEY_ESCAPE) - { - Close(); - } - else - { - BaseClass::OnKeyCodeTyped(code); - } - } + void OnKeyCodeTyped(KeyCode code) + { + // force ourselves to be closed if the escape key it pressed + if (code == KEY_ESCAPE) + { + Close(); + } + else + { + BaseClass::OnKeyCodeTyped(code); + } + } }; @@ -1755,9 +1800,9 @@ public: //----------------------------------------------------------------------------- void COptionsSubVideo::OpenThirdPartyVideoCreditsDialog() { - if (!m_OptionsSubVideoThirdPartyCreditsDlg.Get()) - { - m_OptionsSubVideoThirdPartyCreditsDlg = new COptionsSubVideoThirdPartyCreditsDlg(GetVParent()); - } - m_OptionsSubVideoThirdPartyCreditsDlg->Activate(); + if (!m_OptionsSubVideoThirdPartyCreditsDlg.Get()) + { + m_OptionsSubVideoThirdPartyCreditsDlg = new COptionsSubVideoThirdPartyCreditsDlg(GetVParent()); + } + m_OptionsSubVideoThirdPartyCreditsDlg->Activate(); } diff --git a/gameui/TGAImagePanel.cpp b/gameui/TGAImagePanel.cpp index 927b401e..94951c1c 100644 --- a/gameui/TGAImagePanel.cpp +++ b/gameui/TGAImagePanel.cpp @@ -19,6 +19,10 @@ CTGAImagePanel::CTGAImagePanel( vgui::Panel *parent, const char *name ) : BaseCl m_bHasValidTexture = false; m_bLoadedTexture = false; m_szTGAName[0] = 0; + m_iImageWidth = 0; + m_iImageHeight = 0; + m_iImageRealWidth = 0; + m_iImageRealHeight = 0; SetPaintBackgroundEnabled( false ); } @@ -63,8 +67,19 @@ void CTGAImagePanel::Paint() // set the textureID surface()->DrawSetTextureRGBA( m_iTextureID, tga.Base(), m_iImageWidth, m_iImageHeight, false, true ); m_bHasValidTexture = true; + + surface()->DrawGetTextureSize(m_iTextureID, m_iImageRealWidth, m_iImageRealHeight); + if (IsProportional()) + { + m_iImageRealWidth = scheme()->GetProportionalScaledValueEx(GetScheme(), m_iImageRealWidth); + m_iImageRealHeight = scheme()->GetProportionalScaledValueEx(GetScheme(), m_iImageRealHeight); + + m_iImageWidth = scheme()->GetProportionalScaledValueEx(GetScheme(), m_iImageWidth); + m_iImageHeight = scheme()->GetProportionalScaledValueEx(GetScheme(), m_iImageHeight); + } + // set our size to be the size of the tga - SetSize( m_iImageWidth, m_iImageHeight ); + SetSize(m_iImageWidth, m_iImageHeight); } else #endif @@ -77,10 +92,9 @@ void CTGAImagePanel::Paint() int wide, tall; if ( m_bHasValidTexture ) { - surface()->DrawGetTextureSize( m_iTextureID, wide, tall ); surface()->DrawSetTexture( m_iTextureID ); surface()->DrawSetColor( 255, 255, 255, 255 ); - surface()->DrawTexturedRect( 0, 0, wide, tall ); + surface()->DrawTexturedRect( 0, 0, m_iImageRealWidth, m_iImageRealHeight ); } else { diff --git a/gameui/TGAImagePanel.h b/gameui/TGAImagePanel.h index 1c8d36ef..c5b7a8ae 100644 --- a/gameui/TGAImagePanel.h +++ b/gameui/TGAImagePanel.h @@ -34,6 +34,7 @@ public: private: int m_iTextureID; int m_iImageWidth, m_iImageHeight; + int m_iImageRealWidth, m_iImageRealHeight; bool m_bHasValidTexture, m_bLoadedTexture; char m_szTGAName[256]; }; diff --git a/gameui/wscript b/gameui/wscript index 76473ce2..72e4221e 100755 --- a/gameui/wscript +++ b/gameui/wscript @@ -13,6 +13,7 @@ def options(opt): def configure(conf): conf.define('GAMEUI_EXPORTS',1) + conf.define('NO_STEAM',1) conf.define('VERSION_SAFE_STEAM_API_INTERFACES',1) def build(bld): diff --git a/inputsystem/inputsystem.h b/inputsystem/inputsystem.h index 0b113061..c369851e 100644 --- a/inputsystem/inputsystem.h +++ b/inputsystem/inputsystem.h @@ -333,10 +333,7 @@ public: void JoystickButtonRelease( int joystickId, int button ); // same as above. void JoystickAxisMotion( int joystickId, int axis, int value ); - void FingerDown( int fingerId, int x, int y ); - void FingerUp( int fingerId, int x, int y ); - void FingerMotion( int fingerId, int x, int y ); - + void FingerEvent( int eventType, int fingerId, float x, float y, float dx, float dy ); // Steam Controller void ReadSteamController( int iIndex ); diff --git a/inputsystem/touch_sdl.cpp b/inputsystem/touch_sdl.cpp index 086160c4..871e285b 100644 --- a/inputsystem/touch_sdl.cpp +++ b/inputsystem/touch_sdl.cpp @@ -24,19 +24,15 @@ int TouchSDLWatcher( void *userInfo, SDL_Event *event ) if( !window ) return 0; - int width, height; - width = height = 0; - SDL_GetWindowSize(window, &width, &height); - switch ( event->type ) { case SDL_FINGERDOWN: - pInputSystem->FingerDown( event->tfinger.fingerId, event->tfinger.x*width, event->tfinger.y*height ); + pInputSystem->FingerEvent( IE_FingerDown, event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, event->tfinger.dx, event->tfinger.dy ); break; case SDL_FINGERUP: - pInputSystem->FingerUp( event->tfinger.fingerId, event->tfinger.x*width, event->tfinger.y*height ); + pInputSystem->FingerEvent( IE_FingerUp, event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, event->tfinger.dx, event->tfinger.dy ); break; case SDL_FINGERMOTION: - pInputSystem->FingerMotion( event->tfinger.fingerId, event->tfinger.x*width, event->tfinger.y*height ); + pInputSystem->FingerEvent( IE_FingerMotion ,event->tfinger.fingerId, event->tfinger.x, event->tfinger.y, event->tfinger.dx, event->tfinger.dy ); break; } @@ -67,32 +63,20 @@ void CInputSystem::ShutdownTouch() m_bTouchInitialized = false; } -void CInputSystem::FingerDown(int fingerId, int x, int y) +void CInputSystem::FingerEvent(int eventType, int fingerId, float x, float y, float dx, float dy) { - m_touchAccumEvent = IE_FingerDown; - m_touchAccumFingerId = fingerId; - m_touchAccumX = x; - m_touchAccumY = y; + // Shit, but should work with arm/x86 - PostEvent(IE_FingerDown, m_nLastSampleTick, fingerId, x, y); -} - -void CInputSystem::FingerUp(int fingerId, int x, int y) -{ - m_touchAccumEvent = IE_FingerUp; - m_touchAccumFingerId = fingerId; - m_touchAccumX = x; - m_touchAccumY = y; - - PostEvent(IE_FingerUp, m_nLastSampleTick, fingerId, x, y); -} - -void CInputSystem::FingerMotion(int fingerId, int x, int y) -{ - m_touchAccumEvent = IE_FingerMotion; - m_touchAccumFingerId = fingerId; - m_touchAccumX = x; - m_touchAccumY = y; - - PostEvent(IE_FingerMotion, m_nLastSampleTick, fingerId, x, y); + int data0 = fingerId << 16 | eventType; + int _x = (int)((double)x*0xFFFF); + int _y = (int)((double)y*0xFFFF); + int data1 = _x << 16 | (_y & 0xFFFF); + + union{int i;float f;} ifconv; + ifconv.f = dx; + int _dx = ifconv.i; + ifconv.f = dy; + int _dy = ifconv.i; + + PostEvent(data0, m_nLastSampleTick, data1, _dx, _dy); } diff --git a/launcher/android.cpp b/launcher/android.cpp index 337952ea..226c05ca 100644 --- a/launcher/android.cpp +++ b/launcher/android.cpp @@ -114,12 +114,11 @@ void SetLauncherArgs() D(binPath); D("-console"); - A("-game", "hl2mp"); D("-nouserclip"); parseArgs(java_args); - D("-windowed"); + D("-fullscreen"); D("-nosteam"); D("-insecure"); } diff --git a/launcher/launcher.cpp b/launcher/launcher.cpp index 5ba0ab18..217db87c 100644 --- a/launcher/launcher.cpp +++ b/launcher/launcher.cpp @@ -1176,6 +1176,8 @@ static const char *BuildCommand() return (const char *)build.Base(); } +extern void InitGL4ES(); + //----------------------------------------------------------------------------- // Purpose: The real entry point for the application // Input : hInstance - @@ -1190,7 +1192,7 @@ extern "C" __declspec(DLL_EXPORT) int LauncherMain( HINSTANCE hInstance, HINSTAN DLL_EXPORT int LauncherMain( int argc, char **argv ) #endif { -#ifdef LINUX +#if defined LINUX && !defined ANDROID // Temporary fix to stop us from crashing in printf/sscanf functions that don't expect // localization to mess with your "." and "," float seperators. Mac OSX also sets LANG // to en_US.UTF-8 before starting up (in info.plist I believe). @@ -1206,10 +1208,15 @@ DLL_EXPORT int LauncherMain( int argc, char **argv ) const char *CurrentLocale = setlocale( LC_ALL, NULL ); if ( Q_stricmp( CurrentLocale, en_US ) ) { - Warning( "WARNING: setlocale('%s') failed, using locale:'%s'. International characters may not work.\n", en_US, CurrentLocale ); + Msg( "WARNING: setlocale('%s') failed, using locale:'%s'. International characters may not work.\n", en_US, CurrentLocale ); } + #endif // LINUX +#if defined LINUX && defined USE_SDL && defined TOGLES && !defined ANDROID + SDL_SetHint(SDL_HINT_VIDEO_X11_FORCE_EGL, "1"); +#endif + #ifdef WIN32 SetAppInstance( hInstance ); #elif defined( POSIX ) diff --git a/lib/android/armeabi-v7a/libandroid_support.a b/lib/android/armeabi-v7a/libandroid_support.a index 30a81d72..9f833a4d 100644 Binary files a/lib/android/armeabi-v7a/libandroid_support.a and b/lib/android/armeabi-v7a/libandroid_support.a differ diff --git a/lib/android/armeabi-v7a/libfreetype2.a b/lib/android/armeabi-v7a/libfreetype2.a index e27727e8..c83750bd 100755 Binary files a/lib/android/armeabi-v7a/libfreetype2.a and b/lib/android/armeabi-v7a/libfreetype2.a differ diff --git a/materialsystem/cmaterialsystem.cpp b/materialsystem/cmaterialsystem.cpp index 3d19a168..0618d0c0 100644 --- a/materialsystem/cmaterialsystem.cpp +++ b/materialsystem/cmaterialsystem.cpp @@ -1872,7 +1872,12 @@ void CMaterialSystem::ReadConfigFromConVars( MaterialSystem_Config_t *pConfig ) pConfig->m_fGammaTVExponent = mat_monitorgamma_tv_exp.GetFloat(); pConfig->m_bGammaTVEnabled = mat_monitorgamma_tv_enabled.GetBool(); +#ifdef TOGLES + pConfig->m_nAASamples = 0; +#else pConfig->m_nAASamples = mat_antialias.GetInt(); +#endif + pConfig->m_nAAQuality = mat_aaquality.GetInt(); pConfig->bShowDiffuse = mat_diffuse.GetInt() ? true : false; // pConfig->bAllowCheats = false; // hack diff --git a/materialsystem/shaderapidx9/shaderapidx8.cpp b/materialsystem/shaderapidx9/shaderapidx8.cpp index 7accc77c..21fd9586 100644 --- a/materialsystem/shaderapidx9/shaderapidx8.cpp +++ b/materialsystem/shaderapidx9/shaderapidx8.cpp @@ -3499,7 +3499,7 @@ void CShaderAPIDx8::ResetRenderState( bool bFullReset ) SetRenderState( D3DRS_CULLMODE, D3DCULL_CCW ); // No shade mode yet - m_DynamicState.m_ShadeMode = NULL; + m_DynamicState.m_ShadeMode = D3DSHADE_NONE; ShadeMode( SHADER_SMOOTH ); m_DynamicState.m_bHWMorphingEnabled = false; diff --git a/materialsystem/shaderapidx9/vertexshaderdx8.cpp b/materialsystem/shaderapidx9/vertexshaderdx8.cpp index b3f1063c..614d88f0 100644 --- a/materialsystem/shaderapidx9/vertexshaderdx8.cpp +++ b/materialsystem/shaderapidx9/vertexshaderdx8.cpp @@ -160,14 +160,12 @@ static FILE *GetDebugFileHandle( void ) #ifdef DX_TO_GL_ABSTRACTION // mat_autoload_glshaders instructs the engine to load a cached shader table at startup // it will try for glshaders.cfg first, then fall back to glbaseshaders.cfg if not found -ConVar mat_autoload_glshaders( "mat_autoload_glshaders", "1" ); - // mat_autosave_glshaders instructs the engine to save out the shader table at key points // to the filename glshaders.cfg // -ConVar mat_autosave_glshaders( "mat_autosave_glshaders", "1" ); - + ConVar mat_autosave_glshaders( "mat_autosave_glshaders", "1" ); + ConVar mat_autoload_glshaders( "mat_autoload_glshaders", "1" ); #endif //----------------------------------------------------------------------------- // Explicit instantiation of shader buffer implementation @@ -940,7 +938,8 @@ void CShaderManager::Shutdown() } #endif -#ifdef DX_TO_GL_ABSTRACTION +#if defined (DX_TO_GL_ABSTRACTION) && !defined (ANDROID) + if (mat_autosave_glshaders.GetInt()) { SaveShaderCache("glshaders.cfg"); @@ -3754,6 +3753,10 @@ CON_COMMAND( mat_shadercount, "display count of all shaders and reset that count #if defined( DX_TO_GL_ABSTRACTION ) void CShaderManager::DoStartupShaderPreloading() { +#ifdef ANDROID // Too slow + return; +#endif + if (mat_autoload_glshaders.GetInt()) { double flStartTime = Plat_FloatTime(); diff --git a/public/Color.h b/public/Color.h index 0d6d292d..d9ff9bfc 100644 --- a/public/Color.h +++ b/public/Color.h @@ -83,12 +83,12 @@ public: return _color[index]; } - bool operator == (const Color &rhs) + bool operator == (const Color &rhs) const { return Q_memcmp( this, &rhs, sizeof(Color) ) == 0; } - bool operator != (const Color &rhs) + bool operator != (const Color &rhs) const { return !(operator==(rhs)); } diff --git a/public/appframework/ilaunchermgr.h b/public/appframework/ilaunchermgr.h index 4b433ad8..bafa67cb 100644 --- a/public/appframework/ilaunchermgr.h +++ b/public/appframework/ilaunchermgr.h @@ -16,6 +16,7 @@ #include "appframework/IAppSystem.h" #if defined( DX_TO_GL_ABSTRACTION ) + #include "togl/linuxwin/glmgrbasics.h" #include "togl/linuxwin/glmdisplay.h" diff --git a/public/cdll_int.h b/public/cdll_int.h index d3e6dc44..85cd7617 100644 --- a/public/cdll_int.h +++ b/public/cdll_int.h @@ -790,7 +790,7 @@ public: virtual bool IsConnectedUserInfoChangeAllowed( IConVar *pCvar ) = 0; - virtual void IN_TouchEvent( int type, int fingerId, int x, int y ) = 0; + virtual void IN_TouchEvent( uint data, uint data2, uint data3, uint data4 ) = 0; }; #define CLIENT_DLL_INTERFACE_VERSION "VClient017" diff --git a/public/datamap.h b/public/datamap.h index 936f4436..d49a9871 100644 --- a/public/datamap.h +++ b/public/datamap.h @@ -113,9 +113,9 @@ DECLARE_FIELD_SIZE( FIELD_SOUNDNAME, sizeof(int)) DECLARE_FIELD_SIZE( FIELD_INPUT, sizeof(int)) #ifdef POSIX // pointer to members under gnuc are 8bytes if you have a virtual func -DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(uint64)) +DECLARE_FIELD_SIZE( FIELD_FUNCTION, 2 * sizeof(void *)) #else -DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(int *)) +DECLARE_FIELD_SIZE( FIELD_FUNCTION, sizeof(void *)) #endif DECLARE_FIELD_SIZE( FIELD_VMATRIX, 16 * sizeof(float)) DECLARE_FIELD_SIZE( FIELD_VMATRIX_WORLDSPACE, 16 * sizeof(float)) @@ -128,7 +128,7 @@ DECLARE_FIELD_SIZE( FIELD_MATERIALINDEX, sizeof(int) ) #define ARRAYSIZE2D(p) (sizeof(p)/sizeof(p[0][0])) #define SIZE_OF_ARRAY(p) _ARRAYSIZE(p) -#define _offsetof(s,m) ((size_t)&(((s *)0)->m)) +#define _offsetof(s,m) ((int)&(((s *)0)->m)) #define _FIELD(name,fieldtype,count,flags,mapname,tolerance) { fieldtype, #name, { _offsetof(classNameTypedef, name), 0 }, count, flags, mapname, NULL, NULL, NULL, sizeof( ((classNameTypedef *)0)->name ), NULL, 0, tolerance } #define DEFINE_FIELD_NULL { FIELD_VOID,0, {0,0},0,0,0,0,0,0} @@ -278,7 +278,7 @@ struct typedescription_t // Used to track exclusion of baseclass fields int override_count; - + // Tolerance for field errors for float fields float fieldTolerance; }; diff --git a/public/filesystem_init.cpp b/public/filesystem_init.cpp index 2b2c2ee6..ba30f129 100644 --- a/public/filesystem_init.cpp +++ b/public/filesystem_init.cpp @@ -581,6 +581,20 @@ FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo ) } } + const char *ExtraVpkPaths = getenv( "EXTRAS_VPK_PATH" ); + char szAbsSearchPath[MAX_PATH]; + + if( ExtraVpkPaths ) + { + CUtlStringList vecPaths; + V_SplitString( ExtraVpkPaths, ",", vecPaths ); + + FOR_EACH_VEC( vecPaths, idxExtraPath ) + { + FileSystem_AddLoadedSearchPath( initInfo, "GAME", vecPaths[idxExtraPath], false ); + } + } + bool bLowViolence = initInfo.m_bLowViolence; for ( KeyValues *pCur=pSearchPaths->GetFirstValue(); pCur; pCur=pCur->GetNextValue() ) { @@ -602,11 +616,12 @@ FSReturnCode_t FileSystem_LoadSearchPaths( CFSSearchPathsInit &initInfo ) // We need a special identifier in the gameinfo.txt here because the base hl2 folder exists in different places. // In the case of a game or a Steam-launched dedicated server, all the necessary prior engine content is mapped in with the Steam depots, // so we can just use the path as-is. + pLocation += strlen( BASESOURCEPATHS_TOKEN ); } + CUtlStringList vecFullLocationPaths; - char szAbsSearchPath[MAX_PATH]; V_MakeAbsolutePath( szAbsSearchPath, sizeof( szAbsSearchPath ), pLocation, pszBaseDir ); // Now resolve any ./'s. diff --git a/public/tier0/platform.h b/public/tier0/platform.h index a7e55f6f..69970444 100644 --- a/public/tier0/platform.h +++ b/public/tier0/platform.h @@ -245,6 +245,11 @@ typedef signed char int8; #define IsPlatform64Bits() false #endif +#ifdef _ANDROID + #define IsAndroid() true +#else + #define IsAndroid() false +#endif // From steam/steamtypes.h // RTime32 // We use this 32 bit time representing real world time. diff --git a/public/togl/linuxwin/dxabstract_types.h b/public/togl/linuxwin/dxabstract_types.h index 9713ec71..aa3013f3 100644 --- a/public/togl/linuxwin/dxabstract_types.h +++ b/public/togl/linuxwin/dxabstract_types.h @@ -993,6 +993,7 @@ typedef enum _D3DTEXTUREADDRESS typedef enum _D3DSHADEMODE { + D3DSHADE_NONE = 0, D3DSHADE_FLAT = 1, D3DSHADE_GOURAUD = 2, D3DSHADE_PHONG = 3, diff --git a/public/togl/rendermechanism.h b/public/togl/rendermechanism.h index 47be332d..374ccaa9 100644 --- a/public/togl/rendermechanism.h +++ b/public/togl/rendermechanism.h @@ -22,6 +22,11 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // + +#ifdef TOGLES +#include "togles/rendermechanism.h" +#else + #ifndef RENDERMECHANISM_H #define RENDERMECHANISM_H @@ -71,3 +76,5 @@ #endif // defined(DX_TO_GL_ABSTRACTION) #endif // RENDERMECHANISM_H + +#endif diff --git a/public/togles/glfuncs.inl b/public/togles/glfuncs.inl new file mode 100644 index 00000000..a542e211 --- /dev/null +++ b/public/togles/glfuncs.inl @@ -0,0 +1,2 @@ +#include "togles/linuxwin/glfuncs.h" + diff --git a/public/togles/linuxwin/cglmbuffer.h b/public/togles/linuxwin/cglmbuffer.h new file mode 100644 index 00000000..10782243 --- /dev/null +++ b/public/togles/linuxwin/cglmbuffer.h @@ -0,0 +1,262 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmprogram.h +// GLMgr buffers (index / vertex) +// ... maybe add PBO later as well +//=============================================================================== + +#ifndef CGLMBUFFER_H +#define CGLMBUFFER_H + +#pragma once + +//=============================================================================== + +extern bool g_bUsePseudoBufs; + +// forward declarations + +class GLMContext; + +enum EGLMBufferType +{ + kGLMVertexBuffer, + kGLMIndexBuffer, + kGLMUniformBuffer, // for bindable uniform + kGLMPixelBuffer, // for PBO + + kGLMNumBufferTypes +}; + +// pass this in "options" to constructor to make a dynamic buffer +#define GLMBufferOptionDynamic 0x00000001 + +struct GLMBuffLockParams +{ + uint m_nOffset; + uint m_nSize; + bool m_bNoOverwrite; + bool m_bDiscard; +}; + +#define GL_STATIC_BUFFER_SIZE ( 2048 * 1024 ) +#define GL_MAX_STATIC_BUFFERS 2 + +extern void glBufferSubDataMaxSize( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data, uint nMaxSizePerCall = 128 * 1024 ); + +//===========================================================================// + +// Creates an immutable storage for a buffer object +// https://www.opengl.org/registry/specs/ARB/buffer_storage.txt +class CPersistentBuffer +{ +public: + + CPersistentBuffer(); + ~CPersistentBuffer(); + + void Init( EGLMBufferType type,uint nSize ); + void Deinit(); + + void InsertFence(); + void BlockUntilNotBusy(); + + void Append( uint nSize ); + + inline uint GetBytesRemaining() const { return m_nSize - m_nOffset; } + inline uint GetOffset() const { return m_nOffset; } + inline void *GetPtr() const { return m_pImmutablePersistentBuf; } + inline GLuint GetHandle() const { return m_nHandle; } + +private: + + CPersistentBuffer( const CPersistentBuffer & ); + CPersistentBuffer & operator= (const CPersistentBuffer &); + + uint m_nSize; + + EGLMBufferType m_type; + GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB + GLuint m_nHandle; // handle of this program in the GL context + + // Holds a pointer to the persistently mapped buffer + void* m_pImmutablePersistentBuf; + + uint m_nOffset; + +#ifdef HAVE_GL_ARB_SYNC + GLsync m_nSyncObj; +#endif +}; + +//=============================================================================== + +#if GL_ENABLE_INDEX_VERIFICATION + +struct GLDynamicBuf_t +{ + GLenum m_nGLType; + uint m_nHandle; + uint m_nActualBufSize; + uint m_nSize; + + uint m_nLockOffset; + uint m_nLockSize; +}; + +class CGLMBufferSpanManager +{ + CGLMBufferSpanManager( const CGLMBufferSpanManager& ); + CGLMBufferSpanManager& operator= ( const CGLMBufferSpanManager& ); + +public: + CGLMBufferSpanManager(); + ~CGLMBufferSpanManager(); + + void Init( GLMContext *pContext, EGLMBufferType nBufType, uint nInitialCapacity, uint nBufSize, bool bDynamic ); + void Deinit(); + + inline GLMContext *GetContext() const { return m_pCtx; } + + inline GLenum GetGLBufType() const { return ( m_nBufType == kGLMVertexBuffer ) ? GL_ARRAY_BUFFER_ARB : GL_ELEMENT_ARRAY_BUFFER_ARB; } + + struct ActiveSpan_t + { + uint m_nStart; + uint m_nEnd; + + GLDynamicBuf_t m_buf; + bool m_bOriginalAlloc; + + inline ActiveSpan_t() { } + inline ActiveSpan_t( uint nStart, uint nEnd, GLDynamicBuf_t &buf, bool bOriginalAlloc ) : m_nStart( nStart ), m_nEnd( nEnd ), m_buf( buf ), m_bOriginalAlloc( bOriginalAlloc ) { Assert( nStart <= nEnd ); } + }; + + ActiveSpan_t *AddSpan( uint nOffset, uint nMaxSize, uint nActualSize, bool bDiscard, bool bNoOverwrite ); + + void DiscardAllSpans(); + + bool IsValid( uint nOffset, uint nSize ) const; + +private: + bool AllocDynamicBuf( uint nSize, GLDynamicBuf_t &buf ); + void ReleaseDynamicBuf( GLDynamicBuf_t &buf ); + + GLMContext *m_pCtx; + + EGLMBufferType m_nBufType; + + uint m_nBufSize; + bool m_bDynamic; + + CUtlVector m_ActiveSpans; + CUtlVector m_DeletedSpans; + + int m_nSpanEndMax; + + int m_nNumAllocatedBufs; + int m_nTotalBytesAllocated; +}; + +#endif // GL_ENABLE_INDEX_VERIFICATION + +class CGLMBuffer +{ +public: + void Lock( GLMBuffLockParams *pParams, char **pAddressOut ); + void Unlock( int nActualSize = -1, const void *pActualData = NULL ); + + GLuint GetHandle() const; + + friend class GLMContext; // only GLMContext can make CGLMBuffer objects + friend class GLMTester; + friend struct IDirect3D9; + friend struct IDirect3DDevice9; + + CGLMBuffer( GLMContext *pCtx, EGLMBufferType type, uint size, uint options ); + ~CGLMBuffer(); + + void SetModes( bool bAsyncMap, bool bExplicitFlush, bool bForce = false ); + void FlushRange( uint offset, uint size ); + +#if GL_ENABLE_INDEX_VERIFICATION + bool IsSpanValid( uint nOffset, uint nSize ) const; +#endif + + GLMContext *m_pCtx; // link back to parent context + EGLMBufferType m_type; + uint m_nSize; + uint m_nActualSize; + + bool m_bDynamic; + + GLenum m_buffGLTarget; // GL_ARRAY_BUFFER_ARB / GL_ELEMENT_BUFFER_ARB + GLuint m_nHandle; // name of this program in the context + + uint m_nRevision; // bump anytime the size changes or buffer is orphaned + + bool m_bEnableAsyncMap; // mirror of the buffer state + bool m_bEnableExplicitFlush; // mirror of the buffer state + + bool m_bMapped; // is it currently mapped + + uint m_dirtyMinOffset; // when equal, range is empty + uint m_dirtyMaxOffset; + + float *m_pLastMappedAddress; + + int m_nPinnedMemoryOfs; + + uint m_nPersistentBufferStartOffset; + bool m_bUsingPersistentBuffer; + + bool m_bPseudo; // true if the m_name is 0, and the backing is plain RAM + + // in pseudo mode, there is just one RAM buffer that acts as the backing. + // expectation is that this mode would only be used for dynamic indices. + // since indices have to be consumed (copied to command stream) prior to return from a drawing call, + // there's no need to do any fencing or multibuffering. orphaning in particular becomes a no-op. + + char *m_pActualPseudoBuf; // storage for pseudo buffer + char *m_pPseudoBuf; // storage for pseudo buffer + char *m_pStaticBuffer; + + GLMBuffLockParams m_LockParams; + + static char ALIGN16 m_StaticBuffers[ GL_MAX_STATIC_BUFFERS ][ GL_STATIC_BUFFER_SIZE ] ALIGN16_POST; + static bool m_bStaticBufferUsed[ GL_MAX_STATIC_BUFFERS ]; + +#if GL_ENABLE_INDEX_VERIFICATION + CGLMBufferSpanManager m_BufferSpanManager; +#endif + +#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION + uint m_nDirtyRangeStart; + uint m_nDirtyRangeEnd; +#endif +}; + +#endif // CGLMBUFFER_H + diff --git a/public/togles/linuxwin/cglmfbo.h b/public/togles/linuxwin/cglmfbo.h new file mode 100644 index 00000000..93ebb11f --- /dev/null +++ b/public/togles/linuxwin/cglmfbo.h @@ -0,0 +1,104 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmfbo.h +// GLMgr FBO's (render targets) +// +//=============================================================================== + +#ifndef CGLMFBO_H +#define CGLMFBO_H + +#pragma once + +// good FBO references / recaps +// http://www.songho.ca/opengl/gl_fbo.html +// http://www.gamedev.net/reference/articles/article2331.asp + +// ext links + +// http://www.opengl.org/registry/specs/EXT/framebuffer_object.txt +// http://www.opengl.org/registry/specs/EXT/framebuffer_multisample.txt + +//=============================================================================== + +// tokens not in the SDK headers + +#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT + #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9 +#endif + +//=============================================================================== + +// forward declarations + +class GLMContext; + +enum EGLMFBOAttachment +{ + kAttColor0, kAttColor1, kAttColor2, kAttColor3, + kAttDepth, kAttStencil, kAttDepthStencil, + kAttCount +}; + +struct GLMFBOTexAttachParams +{ + CGLMTex *m_tex; + int m_face; // keep zero if not cube map + int m_mip; // keep zero if notmip mapped + int m_zslice; // keep zero if not a 3D tex +}; + +class CGLMFBO +{ + friend class GLMContext; + friend class GLMTester; + friend class CGLMTex; + + friend struct IDirect3D9; + friend struct IDirect3DDevice9; + +public: + CGLMFBO( GLMContext *ctx ); + ~CGLMFBO( ); + +protected: + void TexAttach( GLMFBOTexAttachParams *params, EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT ); + void TexDetach( EGLMFBOAttachment attachIndex, GLenum fboBindPoint = GL_FRAMEBUFFER_EXT ); + // you can also pass GL_READ_FRAMEBUFFER_EXT or GL_DRAW_FRAMEBUFFER_EXT to selectively bind the receiving FBO to one or the other. + + void TexScrub( CGLMTex *tex ); + // search and destroy any attachment for the named texture + + bool IsReady( void ); // aka FBO completeness check - ready to draw + + GLMContext *m_ctx; // link back to parent context + + GLuint m_name; // name of this FBO in the context + + GLMFBOTexAttachParams m_attach[ kAttCount ]; // indexed by EGLMFBOAttachment +}; + + +#endif \ No newline at end of file diff --git a/public/togles/linuxwin/cglmprogram.h b/public/togles/linuxwin/cglmprogram.h new file mode 100644 index 00000000..63f74d68 --- /dev/null +++ b/public/togles/linuxwin/cglmprogram.h @@ -0,0 +1,459 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmprogram.h +// GLMgr programs (ARBVP/ARBfp) +// +//=============================================================================== + +#ifndef CGLMPROGRAM_H +#define CGLMPROGRAM_H + +#include + +#pragma once + +// good ARB program references +// http://petewarden.com/notes/archives/2005/05/fragment_progra_2.html +// http://petewarden.com/notes/archives/2005/06/fragment_progra_3.html + +// ext links + +// http://www.opengl.org/registry/specs/ARB/vertex_program.txt +// http://www.opengl.org/registry/specs/ARB/fragment_program.txt +// http://www.opengl.org/registry/specs/EXT/gpu_program_parameters.txt + + +//=============================================================================== + +// tokens not in the SDK headers + +//#ifndef GL_DEPTH_STENCIL_ATTACHMENT_EXT +// #define GL_DEPTH_STENCIL_ATTACHMENT_EXT 0x84F9 +//#endif + +//=============================================================================== + +// forward declarations + +class GLMContext; +class CGLMShaderPair; +class CGLMShaderPairCache; + +// CGLMProgram can contain two flavors of the same program, one in assembler, one in GLSL. +// these flavors are pretty different in terms of the API's that are used to activate them - +// for example, assembler programs can just get bound to the context, whereas GLSL programs +// have to be linked. To some extent we try to hide that detail inside GLM. + +// for now, make CGLMProgram a container, it does not set policy or hold a preference as to which +// flavor you want to use. GLMContext has to handle that. + +enum EGLMProgramType +{ + kGLMVertexProgram, + kGLMFragmentProgram, + + kGLMNumProgramTypes +}; + +enum EGLMProgramLang +{ + kGLMARB, + kGLMGLSL, + + kGLMNumProgramLangs +}; + +struct GLMShaderDesc +{ + union + { + GLuint arb; // ARB program object name + GLuint glsl; // GLSL shader object handle (void*) + } m_object; + + // these can change if shader text is edited + bool m_textPresent; // is this flavor(lang) of text present in the buffer? + int m_textOffset; // where is it + int m_textLength; // how big + + bool m_compiled; // has this text been through a compile attempt + bool m_valid; // and if so, was the compile successful + + int m_slowMark; // has it been flagged during a non native draw batch before. increment every time it's slow. + + int m_highWater; // count of vec4's in the major uniform array ("vc" on vs, "pc" on ps) + // written by dxabstract.... gross! + int m_VSHighWaterBone; // count of vec4's in the bone-specific uniform array (only valid for vertex shaders) +}; + +GLenum GLMProgTypeToARBEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target +GLenum GLMProgTypeToGLSLEnum( EGLMProgramType type ); // map vert/frag to ARB asm bind target + +#define GL_SHADER_PAIR_CACHE_STATS 0 + +class CGLMProgram +{ +public: + friend class CGLMShaderPairCache; + friend class CGLMShaderPair; + friend class GLMContext; // only GLMContext can make CGLMProgram objects + friend class GLMTester; + friend struct IDirect3D9; + friend struct IDirect3DDevice9; + + //=============================== + + // constructor is very light, it just makes one empty program object per flavor. + CGLMProgram( GLMContext *ctx, EGLMProgramType type ); + ~CGLMProgram( ); + + void SetProgramText ( char *text ); // import text to GLM object - invalidate any prev compiled program + void SetShaderName ( const char *name ); // only used for debugging/telemetry markup + + void CompileActiveSources ( void ); // compile only the flavors that were provided. + void Compile ( EGLMProgramLang lang ); + bool CheckValidity ( EGLMProgramLang lang ); + + void LogSlow ( EGLMProgramLang lang ); // detailed spew when called for first time; one liner or perhaps silence after that + + void GetLabelIndexCombo ( char *labelOut, int labelOutMaxChars, int *indexOut, int *comboOut ); + void GetComboIndexNameString ( char *stringOut, int stringOutMaxChars ); // mmmmmmmm-nnnnnnnn-filename + +#if GLMDEBUG + bool PollForChanges( void ); // check mirror for changes. + void ReloadStringFromEditable( void ); // populate m_string from editable item (react to change) + bool SyncWithEditable( void ); +#endif + + //=============================== + + // common stuff + + GLMContext *m_ctx; // link back to parent context + + EGLMProgramType m_type; // vertex or pixel + + unsigned long m_nHashTag; // serial number for hashing + + char *m_text; // copy of text passed into constructor. Can change if editable shaders is enabled. + // note - it can contain multiple flavors, so use CGLMTextSectioner to scan it and locate them +#if GLMDEBUG + CGLMEditableTextItem *m_editable; // editable text item for debugging +#endif + + GLMShaderDesc m_descs[ kGLMNumProgramLangs ]; + + uint m_samplerMask; // (1<> 16 ); + // Apply half pixel offset to output vertices to account for the pixel center difference between D3D9 and OpenGL. + // We output vertices in clip space, which ranges from [-1,1], so 1.0/width in clip space transforms into .5/width in screenspace, see: "Viewports and Clipping (Direct3D 9)" in the DXSDK + float v[4] = { 1.0f / fWidth, 1.0f / fHeight, fWidth, fHeight }; + if ( m_locVertexScreenParams >= 0 ) + gGL->glUniform4fv( m_locVertexScreenParams, 1, v ); + } + + //=============================== + + // common stuff + + GLMContext *m_ctx; // link back to parent context + + CGLMProgram *m_vertexProg; + CGLMProgram *m_fragmentProg; + + GLuint m_program; // linked program object + + // need meta data for attribs / samplers / params + // actually we only need it for samplers and params. + // attributes are hardwired. + + // vertex stage uniforms + GLint m_locVertexParams; // "vc" per dx9asmtogl2 convention + GLint m_locVertexBoneParams; // "vcbones" + GLint m_locVertexInteger0; // "i0" + GLint m_locAlphaRef; // "alpha_ref" + + enum { cMaxVertexShaderBoolUniforms = 4, cMaxFragmentShaderBoolUniforms = 1 }; + + GLint m_locVertexBool[cMaxVertexShaderBoolUniforms]; // "b0", etc. + GLint m_locFragmentBool[cMaxFragmentShaderBoolUniforms]; // "fb0", etc. + bool m_bHasBoolOrIntUniforms; + + // fragment stage uniforms + GLint m_locFragmentParams; // "pc" per dx9asmtogl2 convention + + int m_NumUniformBufferParams[kGLMNumProgramTypes]; + GLint m_UniformBufferParams[kGLMNumProgramTypes][256]; + + GLint m_locFragmentFakeSRGBEnable; // "flSRGBWrite" - set to 1.0 to effect sRGB encoding on output + float m_fakeSRGBEnableValue; // shadow to avoid redundant sets of the m_locFragmentFakeSRGBEnable uniform + // init it to -1.0 at link or relink, so it will trip on any legit incoming value (0.0 or 1.0) + + GLint m_locSamplers[ GLM_SAMPLER_COUNT ]; // "sampler0 ... sampler1..." + + // other stuff + bool m_valid; // true on successful link + bool m_bCheckLinkStatus; + uint m_revision; // if this pair is relinked, bump this number. + + GLint m_locVertexScreenParams; // vcscreen + uint m_nScreenWidthHeight; + +}; + +//=============================================================================== + +// N-row, M-way associative cache with LRU per row. +// still needs some metric dump ability and some parameter tuning. +// extra credit would be to make an auto-tuner. + +struct CGLMPairCacheEntry +{ + long long m_lastMark; // a mark of zero means an empty entry + CGLMProgram *m_vertexProg; + CGLMProgram *m_fragmentProg; + uint m_extraKeyBits; + CGLMShaderPair *m_pair; +}; + +class CGLMShaderPairCache // cache for linked GLSL shader pairs +{ + +public: + +protected: + friend class CGLMShaderPair; + friend class CGLMProgram; + friend class GLMContext; + + //=============================== + + CGLMShaderPairCache( GLMContext *ctx ); + ~CGLMShaderPairCache( ); + + FORCEINLINE CGLMShaderPair *SelectShaderPair ( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits ); + void QueryShaderPair ( int index, GLMShaderPairInfo *infoOut ); + + // shoot down linked pairs that use the program in the arg + // return true if any had to be skipped due to conflict with currently bound pair + bool PurgePairsWithShader( CGLMProgram *prog ); + + // purge everything (when would GLM know how to do this ? at context destroy time, but any other times?) + // return true if any had to be skipped due to conflict with currently bound pair + bool Purge ( void ); + + // stats + void DumpStats ( void ); + + //=============================== + + FORCEINLINE uint HashRowIndex( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits ) const; + FORCEINLINE CGLMPairCacheEntry* HashRowPtr( uint hashRowIndex ) const; + + FORCEINLINE void HashRowProbe( CGLMPairCacheEntry *row, CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int &hitway, int &emptyway, int &oldestway ); + + CGLMShaderPair *SelectShaderPairInternal( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int rowIndex ); + //=============================== + + // common stuff + + GLMContext *m_ctx; // link back to parent context + + long long m_mark; + + uint m_rowsLg2; + uint m_rows; + uint m_rowsMask; + + uint m_waysLg2; + uint m_ways; + + uint m_entryCount; + + CGLMPairCacheEntry *m_entries; // array[ m_rows ][ m_ways ] + + uint *m_evictions; // array[ m_rows ]; + +#if GL_SHADER_PAIR_CACHE_STATS + uint *m_hits; // array[ m_rows ]; +#endif +}; + +FORCEINLINE uint CGLMShaderPairCache::HashRowIndex( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits ) const +{ + return ( vp->m_nHashTag + fp->m_nHashTag + extraKeyBits * 7 ) & m_rowsMask; +} + +FORCEINLINE CGLMPairCacheEntry* CGLMShaderPairCache::HashRowPtr( uint hashRowIndex ) const +{ + return &m_entries[ hashRowIndex * m_ways ]; +} + +FORCEINLINE void CGLMShaderPairCache::HashRowProbe( CGLMPairCacheEntry *row, CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int& hitway, int& emptyway, int& oldestway ) +{ + hitway = -1; + emptyway = -1; + oldestway = -1; + + // scan this row to see if the desired pair is present + CGLMPairCacheEntry *cursor = row; + long long oldestmark = 0xFFFFFFFFFFFFFFFFLL; + + for( uint way = 0; way < m_ways; ++way ) + { + if ( cursor->m_lastMark != 0 ) // occupied slot + { + // check if this is the oldest one on the row - only occupied slots are checked + if ( cursor->m_lastMark < oldestmark ) + { + oldestway = way; + oldestmark = cursor->m_lastMark; + } + + if ( ( cursor->m_vertexProg == vp ) && ( cursor->m_fragmentProg == fp ) && ( cursor->m_extraKeyBits == extraKeyBits ) ) // match? + { + // found it + hitway = way; + break; + } + } + else + { + // empty way, log it if first one seen + if (emptyway<0) + { + emptyway = way; + } + } + cursor++; + } +} + +FORCEINLINE CGLMShaderPair *CGLMShaderPairCache::SelectShaderPair( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits ) +{ + // select row where pair would be found if it exists + uint rowIndex = HashRowIndex( vp, fp, extraKeyBits ); + + CGLMPairCacheEntry *pCursor = HashRowPtr( rowIndex ); + + if ( ( pCursor->m_fragmentProg != fp ) || ( pCursor->m_vertexProg != vp ) || ( pCursor->m_extraKeyBits != extraKeyBits ) ) + { + CGLMPairCacheEntry *pLastCursor = pCursor + m_ways; + + ++pCursor; + + while ( pCursor != pLastCursor ) + { + if ( ( pCursor->m_fragmentProg == fp ) && ( pCursor->m_vertexProg == vp ) && ( pCursor->m_extraKeyBits == extraKeyBits ) ) // match? + break; + ++pCursor; + }; + + if ( pCursor == pLastCursor ) + return SelectShaderPairInternal( vp, fp, extraKeyBits, rowIndex ); + } + + // found it. mark it and return + pCursor->m_lastMark = m_mark++; + +#if GL_SHADER_PAIR_CACHE_STATS + // count the hit + m_hits[ rowIndex ] ++; +#endif + + return pCursor->m_pair; +} + +#endif diff --git a/public/togles/linuxwin/cglmquery.h b/public/togles/linuxwin/cglmquery.h new file mode 100644 index 00000000..168e3f7c --- /dev/null +++ b/public/togles/linuxwin/cglmquery.h @@ -0,0 +1,108 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmquery.h +// GLMgr queries +// +//=============================================================================== + +#ifndef CGLMQUERY_H +#define CGLMQUERY_H + +#pragma once + +//=============================================================================== + +// forward declarations + +class GLMContext; +class CGLMQuery; + +//=============================================================================== + +enum EGLMQueryType +{ + EOcclusion, + EFence, + EGLMQueryCount +}; + +struct GLMQueryParams +{ + EGLMQueryType m_type; +}; + +class CGLMQuery +{ + // leave everything public til it's running +public: + friend class GLMContext; // only GLMContext can make CGLMTex objects + friend struct IDirect3DDevice9; + friend struct IDirect3DQuery9; + + GLMContext *m_ctx; // link back to parent context + GLMQueryParams m_params; // params created with + + GLuint m_name; // name of the query object per se - could be fence, could be query object ... NOT USED WITH GL_ARB_sync! +#ifdef HAVE_GL_ARB_SYNC + GLsync m_syncobj; // GL_ARB_sync object. NOT USED WITH GL_NV_fence or GL_APPLE_fence! +#else + GLuint m_syncobj; +#endif + + bool m_started; + bool m_stopped; + bool m_done; + + bool m_nullQuery; // was gl_nullqueries true at Start time - if so, continue to act like a null query through Stop/IsDone/Complete time + // restated - only Start should examine the convar. + static uint s_nTotalOcclusionQueryCreatesOrDeletes; + + CGLMQuery( GLMContext *ctx, GLMQueryParams *params ); + ~CGLMQuery( ); + + // for an occlusion query: + // Start = BeginQuery query-start goes into stream + // Stop = EndQuery query-end goes into stream - a fence is also set so we can probe for completion + // IsDone = TestFence use the added fence to ask if query-end has passed (i.e. will Complete block?) + // Complete = GetQueryObjectuivARB(uint id, enum pname, uint *params) - extract the sample count + + // for a fence query: + // Start = SetFence fence goes into command stream + // Stop = NOP fences are self finishing - no need to call Stop on a fence + // IsDone = TestFence ask if fence passed + // Complete = FinishFence + + void Start ( void ); + void Stop ( void ); + bool IsDone ( void ); + void Complete ( uint *result ); + + // accessors for the started/stopped state + bool IsStarted ( void ); + bool IsStopped ( void ); +}; + + +#endif diff --git a/public/togles/linuxwin/cglmtex.h b/public/togles/linuxwin/cglmtex.h new file mode 100644 index 00000000..3a312c67 --- /dev/null +++ b/public/togles/linuxwin/cglmtex.h @@ -0,0 +1,547 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmtex.h +// GLMgr textures +// +//=============================================================================== + +#ifndef CGLMTEX_H +#define CGLMTEX_H + +#pragma once + +#ifdef OSX +#include "glmgrbasics.h" +#endif +#include "tier1/utlhash.h" +#include "tier1/utlmap.h" + +//=============================================================================== + +// forward declarations + +class GLMContext; +class GLMTester; +class CGLMTexLayoutTable; +class CGLMTex; +class CGLMFBO; + +struct IDirect3DSurface9; + +#if GLMDEBUG +extern CGLMTex *g_pFirstCGMLTex; +#endif + +// For GL_EXT_texture_sRGB_decode +#ifndef GL_TEXTURE_SRGB_DECODE_EXT +#define GL_TEXTURE_SRGB_DECODE_EXT 0x8A48 +#endif + +#ifndef GL_DECODE_EXT +#define GL_DECODE_EXT 0x8A49 +#endif + +#ifndef GL_SKIP_DECODE_EXT +#define GL_SKIP_DECODE_EXT 0x8A4A +#endif + +//=============================================================================== + +struct GLMTexFormatDesc +{ + const char *m_formatSummary; // for debug visibility + + D3DFORMAT m_d3dFormat; // what D3D knows it as; see public/bitmap/imageformat.h + + GLenum m_glIntFormat; // GL internal format + GLenum m_glIntFormatSRGB; // internal format if SRGB flavor + GLenum m_glDataFormat; // GL data format + GLenum m_glDataType; // GL data type + + int m_chunkSize; // 1 or 4 - 4 is used for compressed textures + int m_bytesPerSquareChunk; // how many bytes for the smallest quantum (m_chunkSize x m_chunkSize) + // this description lets us calculate size cleanly without conditional logic for compression +}; +const GLMTexFormatDesc *GetFormatDesc( D3DFORMAT format ); + +//=============================================================================== + +// utility function for generating slabs of texels. mostly for test. +typedef struct +{ + // in + D3DFORMAT m_format; + void *m_dest; // dest address + int m_chunkCount; // square chunk count (single texels or compressed blocks) + int m_byteCountLimit; // caller expectation of max number of bytes to write out + float r,g,b,a; // color desired + + // out + int m_bytesWritten; +} GLMGenTexelParams; + +// return true if successful +bool GLMGenTexels( GLMGenTexelParams *params ); + + +//=============================================================================== + +struct GLMTexLayoutSlice +{ + int m_xSize,m_ySize,m_zSize; //texel dimensions of this slice + int m_storageOffset; //where in the storage slab does this slice live + int m_storageSize; //how much storage does this slice occupy +}; + +enum EGLMTexFlags +{ + kGLMTexMipped = 0x01, + kGLMTexMippedAuto = 0x02, + kGLMTexRenderable = 0x04, + kGLMTexIsStencil = 0x08, + kGLMTexIsDepth = 0x10, + kGLMTexSRGB = 0x20, + kGLMTexMultisampled = 0x40, // has an RBO backing it. Cannot combine with Mipped, MippedAuto. One slice maximum, only targeting GL_TEXTURE_2D. + // actually not 100% positive on the mipmapping, the RBO itself can't be mipped, but the resulting texture could + // have mipmaps generated. +}; + +//=============================================================================== + +struct GLMTexLayoutKey +{ + // input values: held const, these are the hash key for the form map + GLenum m_texGLTarget; // flavor of texture: GL_TEXTURE_2D, GL_TEXTURE_3D, GLTEXTURE_CUBE_MAP + D3DFORMAT m_texFormat; // D3D texel format + unsigned long m_texFlags; // mipped, autogen mips, render target, ... ? + unsigned long m_texSamples; // zero for a plain tex, 2/4/6/8 for "MSAA tex" (RBO backed) + int m_xSize,m_ySize,m_zSize; // size of base mip +}; + +bool LessFunc_GLMTexLayoutKey( const GLMTexLayoutKey &a, const GLMTexLayoutKey &b ); + +#define GLM_TEX_MAX_MIPS 14 +#define GLM_TEX_MAX_FACES 6 +#define GLM_TEX_MAX_SLICES (GLM_TEX_MAX_MIPS * GLM_TEX_MAX_FACES) + +#pragma warning( push ) +#pragma warning( disable : 4200 ) + +struct GLMTexLayout +{ + char *m_layoutSummary; // for debug visibility + + // const inputs used for hashing + GLMTexLayoutKey m_key; + + // refcount + int m_refCount; + + // derived values: + GLMTexFormatDesc *m_format; // format specific info + int m_mipCount; // derived by starying at base size and working down towards 1x1 + int m_faceCount; // 1 for 2d/3d, 6 for cubemap + int m_sliceCount; // product of faces and mips + int m_storageTotalSize; // size of storage slab required + + // slice array + GLMTexLayoutSlice m_slices[0]; // dynamically allocated 2-d array [faces][mips] +}; + +#pragma warning( pop ) + +class CGLMTexLayoutTable +{ +public: + CGLMTexLayoutTable(); + + GLMTexLayout *NewLayoutRef( GLMTexLayoutKey *pDesiredKey ); // pass in a pointer to layout key - receive ptr to completed layout + void DelLayoutRef( GLMTexLayout *layout ); // pass in pointer to completed layout. refcount is dropped. + + void DumpStats( void ); +protected: + CUtlMap< GLMTexLayoutKey, GLMTexLayout* > m_layoutMap; +}; + +//=============================================================================== + +// a sampler specifies desired state for drawing on a given sampler index +// this is the combination of a texture choice and a set of sampler parameters +// see http://msdn.microsoft.com/en-us/library/bb172602(VS.85).aspx + +struct GLMTexLockParams +{ + // input params which identify the slice of interest + CGLMTex *m_tex; + int m_face; + int m_mip; + + // identifies the region of the slice + GLMRegion m_region; + + // tells GLM to force re-read of the texels back from GL + // i.e. "I know I stepped on those texels with a draw or blit - the GLM copy is stale" + bool m_readback; +}; + +struct GLMTexLockDesc +{ + GLMTexLockParams m_req; // form of the lock request + + bool m_active; // set true at lock time. cleared at unlock time. + + int m_sliceIndex; // which slice in the layout + int m_sliceBaseOffset; // where is that in the texture data + int m_sliceRegionOffset; // offset to the start (lowest address corner) of the region requested +}; + +//=============================================================================== + +#define GLM_SAMPLER_COUNT 16 + +#define GLM_MAX_PIXEL_TEX_SAMPLERS 16 +#define GLM_MAX_VERTEX_TEX_SAMPLERS 0 +typedef CBitVec CTexBindMask; + +enum EGLMTexSliceFlag +{ + kSliceValid = 0x01, // slice has been teximage'd in whole at least once - set to 0 initially + kSliceStorageValid = 0x02, // if backing store is available, this slice's data is a valid copy - set to 0 initially + kSliceLocked = 0x04, // are one or more locks outstanding on this slice + kSliceFullyDirty = 0x08, // does the slice need to be fully downloaded at unlock time (disregard dirty rects) +}; + +//=============================================================================== + +#define GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS (2) +#define GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS (2) +#define GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS (2) +#define GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS (2) +#define GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS (4) +#define GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS (5) +#define GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS (1) +#define GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS (1) + +struct GLMTexPackedSamplingParams +{ + uint32 m_addressU : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS; + uint32 m_addressV : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS; + uint32 m_addressW : GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS; + + uint32 m_minFilter : GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS; + uint32 m_magFilter : GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS; + uint32 m_mipFilter : GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS; + + uint32 m_minLOD : GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS; + uint32 m_maxAniso : GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS; + uint32 m_compareMode : GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS; + uint32 m_srgb : GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS; + uint32 m_isValid : 1; +}; + +struct GLMTexSamplingParams +{ + union + { + GLMTexPackedSamplingParams m_packed; + uint32 m_bits; + }; + + uint32 m_borderColor; + float m_lodBias; + + FORCEINLINE bool operator== (const GLMTexSamplingParams& rhs ) const + { + return ( m_bits == rhs.m_bits ) && ( m_borderColor == rhs.m_borderColor ) && ( m_lodBias == rhs.m_lodBias ); + } + + FORCEINLINE void SetToDefaults() + { + m_bits = 0; + m_borderColor = 0; + m_lodBias = 0.0f; + m_packed.m_addressU = D3DTADDRESS_WRAP; + m_packed.m_addressV = D3DTADDRESS_WRAP; + m_packed.m_addressW = D3DTADDRESS_WRAP; + m_packed.m_minFilter = D3DTEXF_POINT; + m_packed.m_magFilter = D3DTEXF_POINT; + m_packed.m_mipFilter = D3DTEXF_NONE; + m_packed.m_maxAniso = 1; + m_packed.m_compareMode = 0; + m_packed.m_isValid = true; + } + +#ifndef OSX + FORCEINLINE void SetToSamplerObject( GLuint nSamplerObject ) const + { + static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 }; + static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR }; + static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter]. + { + /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT + /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, + /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, + /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling + }; + + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] ); + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] ); + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] ); + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] ); + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] ); + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso ); + + float flBorderColor[4] = { 0, 0, 0, 0 }; + if ( m_borderColor ) + { + flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R + flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G + flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B + flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A + } + gGL->glSamplerParameterfv( nSamplerObject, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD ); +// gGL->glSamplerParameterfv( nSamplerObject, GL_TEXTURE_LOD_BIAS, &m_lodBias ); + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE ); +// gGL->glSamplerParameterf( nSamplerObject, GL_TEXTURE_LOD_BIAS, m_lodBias ); + if ( m_packed.m_compareMode ) + { + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL ); + } + if ( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) + { + gGL->glSamplerParameteri( nSamplerObject, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT ); + } + } +#endif // !OSX + + inline void DeltaSetToTarget( GLenum target, const GLMTexSamplingParams &curState ) + { + static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 }; + static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR }; + static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter]. + { + /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT + /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, + /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, + /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling + }; + + if ( m_packed.m_addressU != curState.m_packed.m_addressU ) + { + gGL->glTexParameteri( target, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] ); + } + + if ( m_packed.m_addressV != curState.m_packed.m_addressV ) + { + gGL->glTexParameteri( target, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] ); + } + + if ( m_packed.m_addressW != curState.m_packed.m_addressW ) + { + gGL->glTexParameteri( target, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] ); + } + + if ( ( m_packed.m_minFilter != curState.m_packed.m_minFilter ) || + ( m_packed.m_magFilter != curState.m_packed.m_magFilter ) || + ( m_packed.m_mipFilter != curState.m_packed.m_mipFilter ) || + ( m_packed.m_maxAniso != curState.m_packed.m_maxAniso ) ) + { + gGL->glTexParameteri( target, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] ); + gGL->glTexParameteri( target, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] ); + gGL->glTexParameteri( target, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso ); + } + + if ( m_borderColor != curState.m_borderColor ) + { + float flBorderColor[4] = { 0, 0, 0, 0 }; + if ( m_borderColor ) + { + flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R + flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G + flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B + flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A + } + + gGL->glTexParameterfv( target, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out + } + + if ( m_packed.m_minLOD != curState.m_packed.m_minLOD ) + { + gGL->glTexParameteri( target, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD ); + } + + if ( m_lodBias != curState.m_lodBias ) + { + // Could use TexParameterf instead, but we don't currently grab it. This works fine, too. + gGL->glTexParameterfv( target, GL_TEXTURE_LOD_BIAS, &m_lodBias ); + } + + if ( m_packed.m_compareMode != curState.m_packed.m_compareMode ) + { + gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE ); + if ( m_packed.m_compareMode ) + { + gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL ); + } + } + + if ( ( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) && ( m_packed.m_srgb != curState.m_packed.m_srgb ) ) + { + gGL->glTexParameteri( target, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT ); + } + } + + inline void SetToTarget( GLenum target ) + { + static const GLenum dxtogl_addressMode[] = { GL_REPEAT, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER, (GLenum)-1 }; + static const GLenum dxtogl_magFilter[4] = { GL_NEAREST, GL_NEAREST, GL_LINEAR, GL_LINEAR }; + static const GLenum dxtogl_minFilter[4][4] = // indexed by _D3DTEXTUREFILTERTYPE on both axes: [row is min filter][col is mip filter]. + { + /* min = D3DTEXF_NONE */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, // D3DTEXF_NONE we just treat like POINT + /* min = D3DTEXF_POINT */ { GL_NEAREST, GL_NEAREST_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR, (GLenum)-1 }, + /* min = D3DTEXF_LINEAR */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, + /* min = D3DTEXF_ANISOTROPIC */ { GL_LINEAR, GL_LINEAR_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_LINEAR, (GLenum)-1 }, // no diff from prior row, set maxAniso to effect the sampling + }; + + gGL->glTexParameteri( target, GL_TEXTURE_WRAP_S, dxtogl_addressMode[m_packed.m_addressU] ); + gGL->glTexParameteri( target, GL_TEXTURE_WRAP_T, dxtogl_addressMode[m_packed.m_addressV] ); + gGL->glTexParameteri( target, GL_TEXTURE_WRAP_R, dxtogl_addressMode[m_packed.m_addressW] ); + gGL->glTexParameteri( target, GL_TEXTURE_MIN_FILTER, dxtogl_minFilter[m_packed.m_minFilter][m_packed.m_mipFilter] ); + gGL->glTexParameteri( target, GL_TEXTURE_MAG_FILTER, dxtogl_magFilter[m_packed.m_magFilter] ); + gGL->glTexParameteri( target, GL_TEXTURE_MAX_ANISOTROPY_EXT, m_packed.m_maxAniso ); + + float flBorderColor[4] = { 0, 0, 0, 0 }; + if ( m_borderColor ) + { + flBorderColor[0] = ((m_borderColor >> 16) & 0xFF) * (1.0f/255.0f); //R + flBorderColor[1] = ((m_borderColor >> 8) & 0xFF) * (1.0f/255.0f); //G + flBorderColor[2] = ((m_borderColor ) & 0xFF) * (1.0f/255.0f); //B + flBorderColor[3] = ((m_borderColor >> 24) & 0xFF) * (1.0f/255.0f); //A + } + gGL->glTexParameterfv( target, GL_TEXTURE_BORDER_COLOR, flBorderColor ); // <-- this crashes ATI's driver, remark it out + gGL->glTexParameteri( target, GL_TEXTURE_MIN_LOD, m_packed.m_minLOD ); +// gGL->glTexParameterfv( target, GL_TEXTURE_LOD_BIAS, &m_lodBias ); + gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_MODE_ARB, m_packed.m_compareMode ? GL_COMPARE_R_TO_TEXTURE_ARB : GL_NONE ); + if ( m_packed.m_compareMode ) + { + gGL->glTexParameteri( target, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL ); + } + if ( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) + { + gGL->glTexParameteri( target, GL_TEXTURE_SRGB_DECODE_EXT, m_packed.m_srgb ? GL_DECODE_EXT : GL_SKIP_DECODE_EXT ); + } + } +}; + +//=============================================================================== + +class CGLMTex +{ + +public: + + void Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut ); + void Unlock( GLMTexLockParams *params ); + GLuint GetTexName() { return m_texName; } + +protected: + friend class GLMContext; // only GLMContext can make CGLMTex objects + friend class GLMTester; + friend class CGLMFBO; + + friend struct IDirect3DDevice9; + friend struct IDirect3DBaseTexture9; + friend struct IDirect3DTexture9; + friend struct IDirect3DSurface9; + friend struct IDirect3DCubeTexture9; + friend struct IDirect3DVolumeTexture9; + + CGLMTex( GLMContext *ctx, GLMTexLayout *layout, uint levels, const char *debugLabel = NULL ); + ~CGLMTex( ); + + int CalcSliceIndex( int face, int mip ); + void CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut ); + + void ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice=true ); + void WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice=true, bool noDataWrite=false ); + // last param lets us send NULL data ptr (only legal with uncompressed formats, beware) + // this helps out ResetSRGB. + +#if defined( OSX ) + void HandleSRGBMismatch( bool srgb, int &srgbFlipCount ); + void ResetSRGB( bool srgb, bool noDataWrite ); + // re-specify texture format to match desired sRGB form + // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's +#endif + + bool IsRBODirty() const; + void ForceRBONonDirty(); + void ForceRBODirty(); + + // re-specify texture format to match desired sRGB form + // noWrite means send NULL for texel source addresses instead of actual data - ideal for RT's + + GLuint m_texName; // name of this texture in the context + GLenum m_texGLTarget; + uint m_nSamplerType; // SAMPLER_2D, etc. + + GLMTexSamplingParams m_SamplingParams; + + GLMTexLayout *m_layout; // layout of texture (shared across all tex with same layout) + + uint m_nLastResolvedBatchCounter; + + int m_minActiveMip;//index of lowest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL. + int m_maxActiveMip;//index of highest mip that has been written. used to drive setting of GL_TEXTURE_MAX_LEVEL. + + GLMContext *m_ctx; // link back to parent context + + + CGLMFBO *m_pBlitSrcFBO; + CGLMFBO *m_pBlitDstFBO; + GLuint m_rboName; // name of MSAA RBO backing the tex if MSAA enabled (or zero) + + int m_rtAttachCount; // how many RT's have this texture attached somewhere + + char *m_backing; // backing storage if available + + int m_lockCount; // lock reqs are stored in the GLMContext for tracking + + CUtlVector m_sliceFlags; + + char *m_debugLabel; // strdup() of debugLabel passed in, or NULL + + bool m_texClientStorage; // was CS selected for texture + bool m_texPreloaded; // has it been kicked into VRAM with GLMContext::PreloadTex yet + + int m_srgbFlipCount; +#if GLMDEBUG + CGLMTex *m_pPrevTex; + CGLMTex *m_pNextTex; +#endif +}; + +#endif diff --git a/public/togles/linuxwin/dxabstract.h b/public/togles/linuxwin/dxabstract.h new file mode 100644 index 00000000..a8e74590 --- /dev/null +++ b/public/togles/linuxwin/dxabstract.h @@ -0,0 +1,1444 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// dxabstract.h +// +//================================================================================================== +#ifndef DXABSTRACT_H +#define DXABSTRACT_H + +#ifdef DX_TO_GL_ABSTRACTION + +#include "togles/rendermechanism.h" + +#include "tier0/platform.h" +#include "tier0/dbg.h" +#include "tier1/utlmap.h" + +// turn this on to get refcount logging from IUnknown +#define IUNKNOWN_ALLOC_SPEW 0 +#define IUNKNOWN_ALLOC_SPEW_MARK_ALL 0 + + +TOGL_INTERFACE void toglGetClientRect( VD3DHWND hWnd, RECT *destRect ); + + +struct TOGL_CLASS IUnknown +{ + int m_refcount[2]; + bool m_mark; + + IUnknown() + { + m_refcount[0] = 1; + m_refcount[1] = 0; + m_mark = (IUNKNOWN_ALLOC_SPEW_MARK_ALL != 0); // either all are marked, or only the ones that have SetMark(true) called on them + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUnew (%08x) refc -> (%d,%d) ",this,m_refcount[0],m_refcount[1])); + } + #endif + }; + + virtual ~IUnknown() + { + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUdel (%08x) ",this )); + } + #endif + }; + + void AddRef( int which=0, char *comment = NULL ) + { + Assert( which >= 0 ); + Assert( which < 2 ); + m_refcount[which]++; + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IUAddRef (%08x,%d) refc -> (%d,%d) [%s]",this,which,m_refcount[0],m_refcount[1],comment?comment:"...")) ; + if (!comment) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + } + #endif + }; + + ULONG __stdcall Release( int which=0, char *comment = NULL ) + { + Assert( which >= 0 ); + Assert( which < 2 ); + + //int oldrefcs[2] = { m_refcount[0], m_refcount[1] }; + bool deleting = false; + + m_refcount[which]--; + if ( (!m_refcount[0]) && (!m_refcount[1]) ) + { + deleting = true; + } + + #if IUNKNOWN_ALLOC_SPEW + if (m_mark) + { + GLMPRINTF(("-A- IURelease (%08x,%d) refc -> (%d,%d) [%s] %s",this,which,m_refcount[0],m_refcount[1],comment?comment:"...",deleting?"->DELETING":"")); + if (!comment) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + } + #endif + + if (deleting) + { + if (m_mark) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + delete this; + return 0; + } + else + { + return m_refcount[0]; + } + }; + + void SetMark( bool markValue, char *comment=NULL ) + { + #if IUNKNOWN_ALLOC_SPEW + if (!m_mark && markValue) // leading edge detect + { + // print the same thing that the constructor would have printed if it had been marked from the beginning + // i.e. it's anticipated that callers asking for marking will do so right at create time + GLMPRINTF(("-A- IUSetMark (%08x) refc -> (%d,%d) (%s) ",this,m_refcount[0],m_refcount[1],comment?comment:"...")); + } + #endif + + m_mark = markValue; + } +}; + +// ------------------------------------------------------------------------------------------------------------------------------ // +// INTERFACES +// ------------------------------------------------------------------------------------------------------------------------------ // + +struct TOGL_CLASS IDirect3DResource9 : public IUnknown +{ + IDirect3DDevice9 *m_device; // parent device + D3DRESOURCETYPE m_restype; + + DWORD SetPriority(DWORD PriorityNew); +}; + +struct TOGL_CLASS IDirect3DBaseTexture9 : public IDirect3DResource9 // "A Texture.." +{ + D3DSURFACE_DESC m_descZero; // desc of top level. + CGLMTex *m_tex; // a CGLMTex can represent all forms of tex + + virtual ~IDirect3DBaseTexture9(); + D3DRESOURCETYPE TOGLMETHODCALLTYPE GetType(); + DWORD TOGLMETHODCALLTYPE GetLevelCount(); + HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DTexture9 : public IDirect3DBaseTexture9 // "Texture 2D" +{ + IDirect3DSurface9 *m_surfZero; // surf of top level. + virtual ~IDirect3DTexture9(); + HRESULT TOGLMETHODCALLTYPE LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags); + HRESULT TOGLMETHODCALLTYPE UnlockRect(UINT Level); + HRESULT TOGLMETHODCALLTYPE GetSurfaceLevel(UINT Level,IDirect3DSurface9** ppSurfaceLevel); +}; + +struct TOGL_CLASS IDirect3DCubeTexture9 : public IDirect3DBaseTexture9 // "Texture Cube Map" +{ + IDirect3DSurface9 *m_surfZero[6]; // surfs of top level. + virtual ~IDirect3DCubeTexture9(); + HRESULT TOGLMETHODCALLTYPE GetCubeMapSurface(D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface); + HRESULT TOGLMETHODCALLTYPE GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DVolumeTexture9 : public IDirect3DBaseTexture9 // "Texture 3D" +{ + IDirect3DSurface9 *m_surfZero; // surf of top level. + D3DVOLUME_DESC m_volDescZero; // volume desc top level + virtual ~IDirect3DVolumeTexture9(); + HRESULT TOGLMETHODCALLTYPE LockBox(UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags); + HRESULT TOGLMETHODCALLTYPE UnlockBox(UINT Level); + HRESULT TOGLMETHODCALLTYPE GetLevelDesc( UINT level, D3DVOLUME_DESC *pDesc ); +}; + + +// for the moment, a "D3D surface" is modeled as a GLM tex, a face, and a mip. +// no Create method, these are filled in by the various create surface methods. + +struct TOGL_CLASS IDirect3DSurface9 : public IDirect3DResource9 +{ + virtual ~IDirect3DSurface9(); + HRESULT TOGLMETHODCALLTYPE LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags); + HRESULT TOGLMETHODCALLTYPE UnlockRect(); + HRESULT TOGLMETHODCALLTYPE GetDesc(D3DSURFACE_DESC *pDesc); + + D3DSURFACE_DESC m_desc; + CGLMTex *m_tex; + int m_face; + int m_mip; +}; + +struct TOGL_CLASS IDirect3D9 : public IUnknown +{ + virtual ~IDirect3D9(); + + UINT TOGLMETHODCALLTYPE GetAdapterCount(); + + HRESULT TOGLMETHODCALLTYPE GetDeviceCaps (UINT Adapter,D3DDEVTYPE DeviceType,D3DCAPS9* pCaps); + HRESULT TOGLMETHODCALLTYPE GetAdapterIdentifier (UINT Adapter,DWORD Flags,D3DADAPTER_IDENTIFIER9* pIdentifier); + HRESULT TOGLMETHODCALLTYPE CheckDeviceFormat (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat); + UINT TOGLMETHODCALLTYPE GetAdapterModeCount (UINT Adapter,D3DFORMAT Format); + HRESULT TOGLMETHODCALLTYPE EnumAdapterModes (UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode); + HRESULT TOGLMETHODCALLTYPE CheckDeviceType (UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed); + HRESULT TOGLMETHODCALLTYPE GetAdapterDisplayMode (UINT Adapter,D3DDISPLAYMODE* pMode); + HRESULT TOGLMETHODCALLTYPE CheckDepthStencilMatch (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat); + HRESULT TOGLMETHODCALLTYPE CheckDeviceMultiSampleType (UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels); + + HRESULT TOGLMETHODCALLTYPE CreateDevice (UINT Adapter,D3DDEVTYPE DeviceType,VD3DHWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface); +}; + +struct TOGL_CLASS IDirect3DVertexDeclaration9 : public IUnknown +{ + IDirect3DDevice9 *m_device; + uint m_elemCount; + D3DVERTEXELEMENT9_GL m_elements[ MAX_D3DVERTEXELEMENTS ]; + + uint8 m_VertexAttribDescToStreamIndex[256]; + + virtual ~IDirect3DVertexDeclaration9(); +}; + +struct TOGL_CLASS IDirect3DQuery9 : public IDirect3DResource9 //was IUnknown +{ + D3DQUERYTYPE m_type; // D3DQUERYTYPE_OCCLUSION or D3DQUERYTYPE_EVENT + GLMContext *m_ctx; + CGLMQuery *m_query; + + uint m_nIssueStartThreadID, m_nIssueEndThreadID; + uint m_nIssueStartDrawCallIndex, m_nIssueEndDrawCallIndex; + uint m_nIssueStartFrameIndex, m_nIssueEndFrameIndex; + uint m_nIssueStartQueryCreationCounter, m_nIssueEndQueryCreationCounter; + + virtual ~IDirect3DQuery9(); + + HRESULT Issue(DWORD dwIssueFlags); + HRESULT GetData(void* pData,DWORD dwSize,DWORD dwGetDataFlags); +}; + +struct TOGL_CLASS IDirect3DVertexBuffer9 : public IDirect3DResource9 //was IUnknown +{ + GLMContext *m_ctx; + CGLMBuffer *m_vtxBuffer; + D3DVERTEXBUFFER_DESC m_vtxDesc; // to satisfy GetDesc + + virtual ~IDirect3DVertexBuffer9(); + HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags); + HRESULT Unlock(); + void UnlockActualSize( uint nActualSize, const void *pActualData = NULL ); +}; + +struct TOGL_CLASS IDirect3DIndexBuffer9 : public IDirect3DResource9 //was IUnknown +{ + GLMContext *m_ctx; + CGLMBuffer *m_idxBuffer; + D3DINDEXBUFFER_DESC m_idxDesc; // to satisfy GetDesc + + virtual ~IDirect3DIndexBuffer9(); + + HRESULT Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags); + HRESULT Unlock(); + void UnlockActualSize( uint nActualSize, const void *pActualData = NULL ); + + HRESULT GetDesc(D3DINDEXBUFFER_DESC *pDesc); +}; + +struct TOGL_CLASS IDirect3DPixelShader9 : public IDirect3DResource9 //was IUnknown +{ + CGLMProgram *m_pixProgram; + uint m_pixHighWater; // count of active constant slots referenced by shader. + uint m_pixSamplerMask; // (1< CD3DMATRIXAllocator; + typedef class TOGL_CLASS CUtlVector CD3DMATRIXStack; +#else + typedef class CUtlMemory CD3DMATRIXAllocator; + typedef class CUtlVector CD3DMATRIXStack; +#endif + +struct TOGL_CLASS ID3DXMatrixStack //: public IUnknown +{ + int m_refcount[2]; + bool m_mark; + CD3DMATRIXStack m_stack; + int m_stackTop; // top of stack is at the highest index, this is that index. push increases, pop decreases. + + ID3DXMatrixStack(); + void AddRef( int which=0, char *comment = NULL ); + ULONG Release( int which=0, char *comment = NULL ); + + HRESULT Create( void ); + + D3DXMATRIX* GetTop(); + void Push(); + void Pop(); + void LoadIdentity(); + void LoadMatrix( const D3DXMATRIX *pMat ); + void MultMatrix( const D3DXMATRIX *pMat ); + void MultMatrixLocal( const D3DXMATRIX *pMat ); + HRESULT ScaleLocal(FLOAT x, FLOAT y, FLOAT z); + + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + HRESULT RotateAxisLocal(CONST D3DXVECTOR3* pV, FLOAT Angle); + + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + HRESULT TranslateLocal(FLOAT x, FLOAT y, FLOAT z); +}; + +typedef ID3DXMatrixStack* LPD3DXMATRIXSTACK; + +struct RenderTargetState_t +{ + void clear() { V_memset( this, 0, sizeof( *this ) ); } + + CGLMTex *m_pRenderTargets[4]; + CGLMTex *m_pDepthStencil; + + inline bool RefersTo( CGLMTex * pSurf ) const + { + for ( uint i = 0; i < 4; i++ ) + if ( m_pRenderTargets[i] == pSurf ) + return true; + + if ( m_pDepthStencil == pSurf ) + return true; + + return false; + } + + static inline bool LessFunc( const RenderTargetState_t &lhs, const RenderTargetState_t &rhs ) + { + COMPILE_TIME_ASSERT( sizeof( lhs.m_pRenderTargets[0] ) == sizeof( uint32 ) ); + uint64 lhs0 = reinterpret_cast(lhs.m_pRenderTargets)[0]; + uint64 rhs0 = reinterpret_cast(rhs.m_pRenderTargets)[0]; + if ( lhs0 < rhs0 ) + return true; + else if ( lhs0 == rhs0 ) + { + uint64 lhs1 = reinterpret_cast(lhs.m_pRenderTargets)[1]; + uint64 rhs1 = reinterpret_cast(rhs.m_pRenderTargets)[1]; + if ( lhs1 < rhs1 ) + return true; + else if ( lhs1 == rhs1 ) + { + return lhs.m_pDepthStencil < rhs.m_pDepthStencil; + } + } + return false; + } + + inline bool operator < ( const RenderTargetState_t &rhs ) const + { + return LessFunc( *this, rhs ); + } +}; + +typedef CUtlMap< RenderTargetState_t, CGLMFBO *> CGLMFBOMap; + +class simple_bitmap; + +struct TOGL_CLASS IDirect3DDevice9 : public IUnknown +{ + friend class GLMContext; + friend struct IDirect3DBaseTexture9; + friend struct IDirect3DTexture9; + friend struct IDirect3DCubeTexture9; + friend struct IDirect3DVolumeTexture9; + friend struct IDirect3DSurface9; + friend struct IDirect3DVertexBuffer9; + friend struct IDirect3DIndexBuffer9; + friend struct IDirect3DPixelShader9; + friend struct IDirect3DVertexShader9; + friend struct IDirect3DQuery9; + friend struct IDirect3DVertexDeclaration9; + + IDirect3DDevice9(); + virtual ~IDirect3DDevice9(); + + // Create call invoked from IDirect3D9 + HRESULT TOGLMETHODCALLTYPE Create( IDirect3DDevice9Params *params ); + + // + // Basics + // + HRESULT TOGLMETHODCALLTYPE Reset(D3DPRESENT_PARAMETERS* pPresentationParameters); + HRESULT TOGLMETHODCALLTYPE SetViewport(CONST D3DVIEWPORT9* pViewport); + HRESULT TOGLMETHODCALLTYPE GetViewport(D3DVIEWPORT9* pViewport); + HRESULT TOGLMETHODCALLTYPE BeginScene(); + HRESULT TOGLMETHODCALLTYPE Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil); + HRESULT TOGLMETHODCALLTYPE EndScene(); + HRESULT TOGLMETHODCALLTYPE Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,VD3DHWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion); + + // textures + HRESULT TOGLMETHODCALLTYPE CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + HRESULT TOGLMETHODCALLTYPE CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + HRESULT TOGLMETHODCALLTYPE CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture); + HRESULT TOGLMETHODCALLTYPE SetTextureNonInline(DWORD Stage,IDirect3DBaseTexture9* pTexture); + + HRESULT TOGLMETHODCALLTYPE GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture); + + // render targets, color and depthstencil, surfaces, blit + HRESULT TOGLMETHODCALLTYPE CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle, char *debugLabel=NULL); + HRESULT TOGLMETHODCALLTYPE SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget); + HRESULT TOGLMETHODCALLTYPE GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget); + + HRESULT TOGLMETHODCALLTYPE CreateOffscreenPlainSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle); + + HRESULT TOGLMETHODCALLTYPE CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle); + HRESULT TOGLMETHODCALLTYPE SetDepthStencilSurface(IDirect3DSurface9* pNewZStencil); + HRESULT TOGLMETHODCALLTYPE GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface); + + HRESULT TOGLMETHODCALLTYPE GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface); // ? is anyone using this ? + HRESULT TOGLMETHODCALLTYPE GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface); + HRESULT TOGLMETHODCALLTYPE StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter); + + // pixel shaders + HRESULT TOGLMETHODCALLTYPE CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader, const char *pShaderName, char *debugLabel = NULL, const uint32 *pCentroidMask = NULL ); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShader(IDirect3DPixelShader9* pShader); + HRESULT TOGLMETHODCALLTYPE SetPixelShaderNonInline(IDirect3DPixelShader9* pShader); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + + HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount); + HRESULT TOGLMETHODCALLTYPE SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount); + + // vertex shaders + HRESULT TOGLMETHODCALLTYPE CreateVertexShader(CONST DWORD* pFunction,IDirect3DVertexShader9** ppShader, const char *pShaderName, char *debugLabel = NULL); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShader(IDirect3DVertexShader9* pShader); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderNonInline(IDirect3DVertexShader9* pShader); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantBNonInline(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount); + HRESULT TOGLMETHODCALLTYPE SetVertexShaderConstantINonInline(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount); + + // POSIX only - preheating for a specific vertex/pixel shader pair - trigger GLSL link inside GLM + HRESULT TOGLMETHODCALLTYPE LinkShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps ); + HRESULT TOGLMETHODCALLTYPE ValidateShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps ); + HRESULT TOGLMETHODCALLTYPE QueryShaderPair( int index, GLMShaderPairInfo *infoOut ); + + // vertex buffers + HRESULT TOGLMETHODCALLTYPE CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl); + HRESULT TOGLMETHODCALLTYPE SetVertexDeclarationNonInline(IDirect3DVertexDeclaration9* pDecl); + + HRESULT TOGLMETHODCALLTYPE SetFVF(DWORD FVF); // we might not be using these ? + HRESULT TOGLMETHODCALLTYPE GetFVF(DWORD* pFVF); + + HRESULT CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,VD3DHANDLE* pSharedHandle); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); + HRESULT SetStreamSourceNonInline(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride); + + // index buffers + HRESULT TOGLMETHODCALLTYPE CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,VD3DHANDLE* pSharedHandle); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetIndices(IDirect3DIndexBuffer9* pIndexData); + HRESULT TOGLMETHODCALLTYPE SetIndicesNonInline(IDirect3DIndexBuffer9* pIndexData); + + // State management. + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateInline(D3DRENDERSTATETYPE State,DWORD Value); + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetRenderStateConstInline(D3DRENDERSTATETYPE State,DWORD Value); + HRESULT TOGLMETHODCALLTYPE SetRenderState(D3DRENDERSTATETYPE State,DWORD Value); + + FORCEINLINE HRESULT TOGLMETHODCALLTYPE SetSamplerState(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value); + HRESULT TOGLMETHODCALLTYPE SetSamplerStateNonInline(DWORD Sampler,D3DSAMPLERSTATETYPE Type,DWORD Value); + + FORCEINLINE void TOGLMETHODCALLTYPE SetSamplerStates(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter, DWORD MinLod, float LodBias ); + void TOGLMETHODCALLTYPE SetSamplerStatesNonInline(DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, DWORD MinFilter, DWORD MagFilter, DWORD MipFilter, DWORD MinLod, float LodBias ); + +#ifdef OSX + // required for 10.6 support + HRESULT TOGLMETHODCALLTYPE FlushIndexBindings(void); // push index buffer (set index ptr) + HRESULT TOGLMETHODCALLTYPE FlushVertexBindings(uint baseVertexIndex); // push vertex streams (set attrib ptrs) +#endif + + // Draw. + HRESULT TOGLMETHODCALLTYPE DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount); + HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitive(D3DPRIMITIVETYPE PrimitiveType,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount); + HRESULT TOGLMETHODCALLTYPE DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride); + + // misc + BOOL TOGLMETHODCALLTYPE ShowCursor(BOOL bShow); + HRESULT TOGLMETHODCALLTYPE ValidateDevice(DWORD* pNumPasses); + HRESULT TOGLMETHODCALLTYPE SetMaterial(CONST D3DMATERIAL9* pMaterial); + HRESULT TOGLMETHODCALLTYPE LightEnable(DWORD Index,BOOL Enable); + HRESULT TOGLMETHODCALLTYPE SetScissorRect(CONST RECT* pRect); + HRESULT TOGLMETHODCALLTYPE CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery); + HRESULT TOGLMETHODCALLTYPE GetDeviceCaps(D3DCAPS9* pCaps); + HRESULT TOGLMETHODCALLTYPE TestCooperativeLevel(); + HRESULT TOGLMETHODCALLTYPE EvictManagedResources(); + HRESULT TOGLMETHODCALLTYPE SetLight(DWORD Index,CONST D3DLIGHT9*); + void TOGLMETHODCALLTYPE SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp); + + + void TOGLMETHODCALLTYPE SaveGLState(); + void TOGLMETHODCALLTYPE RestoreGLState(); + + // Talk to JasonM about this one. It's tricky in GL. + HRESULT TOGLMETHODCALLTYPE SetClipPlane(DWORD Index,CONST float* pPlane); + + // + // + // **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. + // + // + HRESULT TOGLMETHODCALLTYPE SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix); + HRESULT TOGLMETHODCALLTYPE SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value); + + void TOGLMETHODCALLTYPE AcquireThreadOwnership( ); + void TOGLMETHODCALLTYPE ReleaseThreadOwnership( ); + inline DWORD TOGLMETHODCALLTYPE GetCurrentOwnerThreadId() const { return m_ctx->m_nCurOwnerThreadId; } + + FORCEINLINE void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHint( uint nMaxReg ); + void TOGLMETHODCALLTYPE SetMaxUsedVertexShaderConstantsHintNonInline( uint nMaxReg ); + + void DumpStatsToConsole( const CCommand *pArgs ); + +#if GLMDEBUG + void DumpTextures( const CCommand *pArgs ); +#endif + +private: + IDirect3DDevice9( const IDirect3DDevice9& ); + IDirect3DDevice9& operator= ( const IDirect3DDevice9& ); + // Flushing changes to GL + void FlushClipPlaneEquation(); + void InitStates(); + void FullFlushStates(); + void UpdateBoundFBO(); + void ResetFBOMap(); + void ScrubFBOMap( CGLMTex *pTex ); + + // response to retired objects (when refcount goes to zero and they self-delete..) + void ReleasedVertexDeclaration( IDirect3DVertexDeclaration9 *pDecl ); + void ReleasedTexture( IDirect3DBaseTexture9 *baseTex ); // called from texture destructor - need to scrub samplers + void ReleasedCGLMTex( CGLMTex *pTex ); + void ReleasedSurface( IDirect3DSurface9 *surface ); // called from any surface destructor - need to scrub RT table if an RT + void ReleasedPixelShader( IDirect3DPixelShader9 *pixelShader ); // called from IDirect3DPixelShader9 destructor + void ReleasedVertexShader( IDirect3DVertexShader9 *vertexShader ); // called from IDirect3DVertexShader9 destructor + void ReleasedVertexBuffer( IDirect3DVertexBuffer9 *vertexBuffer ); // called from IDirect3DVertexBuffer9 destructor + void ReleasedIndexBuffer( IDirect3DIndexBuffer9 *indexBuffer ); // called from IDirect3DIndexBuffer9 destructor + void ReleasedQuery( IDirect3DQuery9 *query ); // called from IDirect3DQuery9 destructor + + // Member variables + + DWORD m_nValidMarker; +public: + IDirect3DDevice9Params m_params; // mirror of the creation inputs +private: + + // D3D flavor stuff + IDirect3DSurface9 *m_pRenderTargets[4]; + IDirect3DSurface9 *m_pDepthStencil; + + IDirect3DSurface9 *m_pDefaultColorSurface; // default color surface. + IDirect3DSurface9 *m_pDefaultDepthStencilSurface; // queried by GetDepthStencilSurface. + + IDirect3DVertexDeclaration9 *m_pVertDecl; // Set by SetVertexDeclaration... + D3DStreamDesc m_streams[ D3D_MAX_STREAMS ]; // Set by SetStreamSource.. + CGLMBuffer *m_vtx_buffers[ D3D_MAX_STREAMS ]; + CGLMBuffer *m_pDummy_vtx_buffer; + D3DIndexDesc m_indices; // Set by SetIndices.. + + IDirect3DVertexShader9 *m_vertexShader; // Set by SetVertexShader... + IDirect3DPixelShader9 *m_pixelShader; // Set by SetPixelShader... + + IDirect3DBaseTexture9 *m_textures[GLM_SAMPLER_COUNT]; // set by SetTexture... NULL if stage inactive + + // GLM flavor stuff + GLMContext *m_ctx; + CGLMFBOMap *m_pFBOs; + bool m_bFBODirty; + + struct ObjectStats_t + { + int m_nTotalFBOs; + int m_nTotalVertexShaders; + int m_nTotalPixelShaders; + int m_nTotalVertexDecls; + int m_nTotalIndexBuffers; + int m_nTotalVertexBuffers; + int m_nTotalRenderTargets; + int m_nTotalTextures; + int m_nTotalSurfaces; + int m_nTotalQueries; + + void clear() { V_memset( this, 0, sizeof(* this ) ); } + + ObjectStats_t &operator -= ( const ObjectStats_t &rhs ) + { + m_nTotalFBOs -= rhs.m_nTotalFBOs; + m_nTotalVertexShaders -= rhs.m_nTotalVertexShaders; + m_nTotalPixelShaders -= rhs.m_nTotalPixelShaders; + m_nTotalVertexDecls -= rhs.m_nTotalVertexDecls; + m_nTotalIndexBuffers -= rhs.m_nTotalIndexBuffers; + m_nTotalVertexBuffers -= rhs.m_nTotalVertexBuffers; + m_nTotalRenderTargets -= rhs.m_nTotalRenderTargets; + m_nTotalTextures -= rhs.m_nTotalTextures; + m_nTotalSurfaces -= rhs.m_nTotalSurfaces; + m_nTotalQueries -= m_nTotalQueries; + return *this; + } + }; + ObjectStats_t m_ObjectStats; + ObjectStats_t m_PrevObjectStats; + void PrintObjectStats( const ObjectStats_t &stats ); + + // GL state + struct + { + // render state buckets + GLAlphaTestEnable_t m_AlphaTestEnable; + GLAlphaTestFunc_t m_AlphaTestFunc; + + GLAlphaToCoverageEnable_t m_AlphaToCoverageEnable; + + GLDepthTestEnable_t m_DepthTestEnable; + GLDepthMask_t m_DepthMask; + GLDepthFunc_t m_DepthFunc; + + GLClipPlaneEnable_t m_ClipPlaneEnable[kGLMUserClipPlanes]; + GLClipPlaneEquation_t m_ClipPlaneEquation[kGLMUserClipPlanes]; + + GLColorMaskSingle_t m_ColorMaskSingle; + GLColorMaskMultiple_t m_ColorMaskMultiple; + + GLCullFaceEnable_t m_CullFaceEnable; + GLCullFrontFace_t m_CullFrontFace; + GLPolygonMode_t m_PolygonMode; + GLDepthBias_t m_DepthBias; + GLScissorEnable_t m_ScissorEnable; + GLScissorBox_t m_ScissorBox; + GLViewportBox_t m_ViewportBox; + GLViewportDepthRange_t m_ViewportDepthRange; + + GLBlendEnable_t m_BlendEnable; + GLBlendFactor_t m_BlendFactor; + GLBlendEquation_t m_BlendEquation; + GLBlendColor_t m_BlendColor; + GLBlendEnableSRGB_t m_BlendEnableSRGB; + + GLStencilTestEnable_t m_StencilTestEnable; + GLStencilFunc_t m_StencilFunc; + GLStencilOp_t m_StencilOp; + GLStencilWriteMask_t m_StencilWriteMask; + + GLClearColor_t m_ClearColor; + GLClearDepth_t m_ClearDepth; + GLClearStencil_t m_ClearStencil; + + bool m_FogEnable; // not really pushed to GL, just latched here + + // samplers + //GLMTexSamplingParams m_samplers[GLM_SAMPLER_COUNT]; + } gl; + +#if GL_BATCH_PERF_ANALYSIS + simple_bitmap *m_pBatch_vis_bitmap; + uint m_nBatchVisY; + uint m_nBatchVisFrameIndex, m_nBatchVisFileIdx; + uint m_nNumProgramChanges; + + uint m_nTotalD3DCalls; + double m_flTotalD3DTime; + uint m_nTotalGLCalls; + double m_flTotalGLTime; + uint m_nTotalPrims; + + uint m_nOverallProgramChanges; + uint m_nOverallDraws; + uint m_nOverallPrims; + uint m_nOverallD3DCalls; + double m_flOverallD3DTime; + uint m_nOverallGLCalls; + double m_flOverallGLTime; + + double m_flOverallPresentTime; + double m_flOverallPresentTimeSquared; + double m_flOverallSwapWindowTime; + double m_flOverallSwapWindowTimeSquared; + uint m_nOverallPresents; +#endif +}; + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerState( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value ) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetSamplerStateNonInline( Sampler, Type, Value ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + Assert( Sampler < GLM_SAMPLER_COUNT ); + + m_ctx->SetSamplerDirty( Sampler ); + + switch( Type ) + { + case D3DSAMP_ADDRESSU: + m_ctx->SetSamplerAddressU( Sampler, Value ); + break; + case D3DSAMP_ADDRESSV: + m_ctx->SetSamplerAddressV( Sampler, Value ); + break; + case D3DSAMP_ADDRESSW: + m_ctx->SetSamplerAddressW( Sampler, Value ); + break; + case D3DSAMP_BORDERCOLOR: + m_ctx->SetSamplerBorderColor( Sampler, Value ); + break; + case D3DSAMP_MAGFILTER: + m_ctx->SetSamplerMagFilter( Sampler, Value ); + break; + case D3DSAMP_MIPFILTER: + m_ctx->SetSamplerMipFilter( Sampler, Value ); + break; + case D3DSAMP_MINFILTER: + m_ctx->SetSamplerMinFilter( Sampler, Value ); + break; + case D3DSAMP_MIPMAPLODBIAS: + m_ctx->SetSamplerMipMapLODBias( Sampler, Value ); + break; + case D3DSAMP_MAXMIPLEVEL: + m_ctx->SetSamplerMaxMipLevel( Sampler, Value); + break; + case D3DSAMP_MAXANISOTROPY: + m_ctx->SetSamplerMaxAnisotropy( Sampler, Value); + break; + case D3DSAMP_SRGBTEXTURE: + //m_samplers[ Sampler ].m_srgb = Value; + m_ctx->SetSamplerSRGBTexture(Sampler, Value); + break; + case D3DSAMP_SHADOWFILTER: + m_ctx->SetShadowFilter(Sampler, Value); + break; + + default: DXABSTRACT_BREAK_ON_ERROR(); break; + } + return S_OK; +#endif +} + +FORCEINLINE void TOGLMETHODCALLTYPE IDirect3DDevice9::SetSamplerStates( + DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, + DWORD MinFilter, DWORD MagFilter, DWORD MipFilter, DWORD MinLod, + float LodBias) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + SetSamplerStatesNonInline( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter, MinLod, LodBias ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + Assert( Sampler < GLM_SAMPLER_COUNT); + + m_ctx->SetSamplerDirty( Sampler ); + + m_ctx->SetSamplerStates( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter, MinLod, LodBias ); +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetTexture(DWORD Stage,IDirect3DBaseTexture9* pTexture) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetTextureNonInline( Stage, pTexture ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + Assert( Stage < GLM_SAMPLER_COUNT ); + m_textures[Stage] = pTexture; + m_ctx->SetSamplerTex( Stage, pTexture ? pTexture->m_tex : NULL ); + return S_OK; +#endif +} + +inline GLenum D3DCompareFuncToGL( DWORD function ) +{ + switch ( function ) + { + case D3DCMP_NEVER : return GL_NEVER; // Always fail the test. + case D3DCMP_LESS : return GL_LESS; // Accept the new pixel if its value is less than the value of the current pixel. + case D3DCMP_EQUAL : return GL_EQUAL; // Accept the new pixel if its value equals the value of the current pixel. + case D3DCMP_LESSEQUAL : return GL_LEQUAL; // Accept the new pixel if its value is less than or equal to the value of the current pixel. ** + case D3DCMP_GREATER : return GL_GREATER; // Accept the new pixel if its value is greater than the value of the current pixel. + case D3DCMP_NOTEQUAL : return GL_NOTEQUAL; // Accept the new pixel if its value does not equal the value of the current pixel. + case D3DCMP_GREATEREQUAL: return GL_GEQUAL; // Accept the new pixel if its value is greater than or equal to the value of the current pixel. + case D3DCMP_ALWAYS : return GL_ALWAYS; // Always pass the test. + default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF; + } +} + +FORCEINLINE GLenum D3DBlendOperationToGL( DWORD operation ) +{ + switch (operation) + { + case D3DBLENDOP_ADD : return GL_FUNC_ADD; // The result is the destination added to the source. Result = Source + Destination + case D3DBLENDOP_SUBTRACT : return GL_FUNC_SUBTRACT; // The result is the destination subtracted from to the source. Result = Source - Destination + case D3DBLENDOP_REVSUBTRACT : return GL_FUNC_REVERSE_SUBTRACT; // The result is the source subtracted from the destination. Result = Destination - Source + case D3DBLENDOP_MIN : return GL_MIN; // The result is the minimum of the source and destination. Result = MIN(Source, Destination) + case D3DBLENDOP_MAX : return GL_MAX; // The result is the maximum of the source and destination. Result = MAX(Source, Destination) + default: + DXABSTRACT_BREAK_ON_ERROR(); + return 0xFFFFFFFF; + break; + } +} + +FORCEINLINE GLenum D3DBlendFactorToGL( DWORD equation ) +{ + switch (equation) + { + case D3DBLEND_ZERO : return GL_ZERO; // Blend factor is (0, 0, 0, 0). + case D3DBLEND_ONE : return GL_ONE; // Blend factor is (1, 1, 1, 1). + case D3DBLEND_SRCCOLOR : return GL_SRC_COLOR; // Blend factor is (Rs, Gs, Bs, As). + case D3DBLEND_INVSRCCOLOR : return GL_ONE_MINUS_SRC_COLOR; // Blend factor is (1 - Rs, 1 - Gs, 1 - Bs, 1 - As). + case D3DBLEND_SRCALPHA : return GL_SRC_ALPHA; // Blend factor is (As, As, As, As). + case D3DBLEND_INVSRCALPHA : return GL_ONE_MINUS_SRC_ALPHA; // Blend factor is ( 1 - As, 1 - As, 1 - As, 1 - As). + case D3DBLEND_DESTALPHA : return GL_DST_ALPHA; // Blend factor is (Ad Ad Ad Ad). + case D3DBLEND_INVDESTALPHA : return GL_ONE_MINUS_DST_ALPHA; // Blend factor is (1 - Ad 1 - Ad 1 - Ad 1 - Ad). + case D3DBLEND_DESTCOLOR : return GL_DST_COLOR; // Blend factor is (Rd, Gd, Bd, Ad). + case D3DBLEND_INVDESTCOLOR : return GL_ONE_MINUS_DST_COLOR; // Blend factor is (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad). + case D3DBLEND_SRCALPHASAT : return GL_SRC_ALPHA_SATURATE; // Blend factor is (f, f, f, 1); where f = min(As, 1 - Ad). + + /* + // these are weird.... break if we hit them + case D3DBLEND_BOTHSRCALPHA : Assert(0); return GL_ZERO; // Obsolete. Starting with DirectX 6, you can achieve the same effect by setting the source and destination blend factors to D3DBLEND_SRCALPHA and D3DBLEND_INVSRCALPHA in separate calls. + case D3DBLEND_BOTHINVSRCALPHA: Assert(0); return GL_ZERO; // Source blend factor is (1 - As, 1 - As, 1 - As, 1 - As), and destination blend factor is (As, As, As, As); the destination blend selection is overridden. This blend mode is supported only for the D3DRS_SRCBLEND render state. + case D3DBLEND_BLENDFACTOR : Assert(0); return GL_ZERO; // Constant color blending factor used by the frame-buffer blender. This blend mode is supported only if D3DPBLENDCAPS_BLENDFACTOR is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9. + + dxabstract.h has not heard of these, so let them hit the debugger if they come through + case D3DBLEND_INVBLENDFACTOR: //Inverted constant color-blending factor used by the frame-buffer blender. This blend mode is supported only if the D3DPBLENDCAPS_BLENDFACTOR bit is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9. + case D3DBLEND_SRCCOLOR2: // Blend factor is (PSOutColor[1]r, PSOutColor[1]g, PSOutColor[1]b, not used). This flag is available in Direct3D 9Ex only. + case D3DBLEND_INVSRCCOLOR2: // Blend factor is (1 - PSOutColor[1]r, 1 - PSOutColor[1]g, 1 - PSOutColor[1]b, not used)). This flag is available in Direct3D 9Ex only. + */ + default: + DXABSTRACT_BREAK_ON_ERROR(); + return 0xFFFFFFFF; + break; + } +} + + +FORCEINLINE GLenum D3DStencilOpToGL( DWORD operation ) +{ + switch( operation ) + { + case D3DSTENCILOP_KEEP : return GL_KEEP; + case D3DSTENCILOP_ZERO : return GL_ZERO; + case D3DSTENCILOP_REPLACE : return GL_REPLACE; + case D3DSTENCILOP_INCRSAT : return GL_INCR; + case D3DSTENCILOP_DECRSAT : return GL_DECR; + case D3DSTENCILOP_INVERT : return GL_INVERT; + case D3DSTENCILOP_INCR : return GL_INCR_WRAP_EXT; + case D3DSTENCILOP_DECR : return GL_DECR_WRAP_EXT; + default : DXABSTRACT_BREAK_ON_ERROR(); return 0xFFFFFFFF; + } +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateInline( D3DRENDERSTATETYPE State, DWORD Value ) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetRenderState( State, Value ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + + switch (State) + { + case D3DRS_ZENABLE: // kGLDepthTestEnable + { + gl.m_DepthTestEnable.enable = Value; + m_ctx->WriteDepthTestEnable( &gl.m_DepthTestEnable ); + break; + } + case D3DRS_ZWRITEENABLE: // kGLDepthMask + { + gl.m_DepthMask.mask = Value; + m_ctx->WriteDepthMask( &gl.m_DepthMask ); + break; + } + case D3DRS_ZFUNC: + { + // kGLDepthFunc + GLenum func = D3DCompareFuncToGL( Value ); + gl.m_DepthFunc.func = func; + m_ctx->WriteDepthFunc( &gl.m_DepthFunc ); + break; + } + case D3DRS_COLORWRITEENABLE: // kGLColorMaskSingle + { + gl.m_ColorMaskSingle.r = ((Value & D3DCOLORWRITEENABLE_RED) != 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.g = ((Value & D3DCOLORWRITEENABLE_GREEN)!= 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.b = ((Value & D3DCOLORWRITEENABLE_BLUE) != 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.a = ((Value & D3DCOLORWRITEENABLE_ALPHA)!= 0) ? 0xFF : 0x00; + m_ctx->WriteColorMaskSingle( &gl.m_ColorMaskSingle ); + break; + } + case D3DRS_CULLMODE: // kGLCullFaceEnable / kGLCullFrontFace + { + switch (Value) + { + case D3DCULL_NONE: + { + gl.m_CullFaceEnable.enable = false; + gl.m_CullFrontFace.value = GL_CCW; //doesn't matter + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + + case D3DCULL_CW: + { + gl.m_CullFaceEnable.enable = true; + gl.m_CullFrontFace.value = GL_CW; //origGL_CCW; + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + case D3DCULL_CCW: + { + gl.m_CullFaceEnable.enable = true; + gl.m_CullFrontFace.value = GL_CCW; //origGL_CW; + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + default: + { + DXABSTRACT_BREAK_ON_ERROR(); + break; + } + } + break; + } + //-------------------------------------------------------------------------------------------- alphablend stuff + case D3DRS_ALPHABLENDENABLE: // kGLBlendEnable + { + gl.m_BlendEnable.enable = Value; + m_ctx->WriteBlendEnable( &gl.m_BlendEnable ); + break; + } + case D3DRS_BLENDOP: // kGLBlendEquation // D3D blend-op ==> GL blend equation + { + GLenum equation = D3DBlendOperationToGL( Value ); + gl.m_BlendEquation.equation = equation; + m_ctx->WriteBlendEquation( &gl.m_BlendEquation ); + break; + } + case D3DRS_SRCBLEND: // kGLBlendFactor // D3D blend-factor ==> GL blend factor + case D3DRS_DESTBLEND: // kGLBlendFactor + { + GLenum factor = D3DBlendFactorToGL( Value ); + + if (State==D3DRS_SRCBLEND) + { + gl.m_BlendFactor.srcfactor = factor; + } + else + { + gl.m_BlendFactor.dstfactor = factor; + } + m_ctx->WriteBlendFactor( &gl.m_BlendFactor ); + break; + } + case D3DRS_SRGBWRITEENABLE: // kGLBlendEnableSRGB + { + gl.m_BlendEnableSRGB.enable = Value; + m_ctx->WriteBlendEnableSRGB( &gl.m_BlendEnableSRGB ); + break; + } + //-------------------------------------------------------------------------------------------- alphatest stuff + case D3DRS_ALPHATESTENABLE: + { + gl.m_AlphaTestEnable.enable = Value; + m_ctx->WriteAlphaTestEnable( &gl.m_AlphaTestEnable ); + break; + } + case D3DRS_ALPHAREF: + { + gl.m_AlphaTestFunc.ref = Value / 255.0f; + m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc ); + break; + } + case D3DRS_ALPHAFUNC: + { + GLenum func = D3DCompareFuncToGL( Value );; + gl.m_AlphaTestFunc.func = func; + m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc ); + break; + } + //-------------------------------------------------------------------------------------------- stencil stuff + case D3DRS_STENCILENABLE: // GLStencilTestEnable_t + { + gl.m_StencilTestEnable.enable = Value; + m_ctx->WriteStencilTestEnable( &gl.m_StencilTestEnable ); + break; + } + case D3DRS_STENCILFAIL: // GLStencilOp_t "what do you do if stencil test fails" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.sfail = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + case D3DRS_STENCILZFAIL: // GLStencilOp_t "what do you do if stencil test passes *but* depth test fails, if depth test happened" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.dpfail = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + case D3DRS_STENCILPASS: // GLStencilOp_t "what do you do if stencil test and depth test both pass" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.dppass = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + case D3DRS_STENCILFUNC: // GLStencilFunc_t + { + GLenum stencilfunc = D3DCompareFuncToGL( Value ); + gl.m_StencilFunc.frontfunc = gl.m_StencilFunc.backfunc = stencilfunc; + + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + case D3DRS_STENCILREF: // GLStencilFunc_t + { + gl.m_StencilFunc.ref = Value; + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + case D3DRS_STENCILMASK: // GLStencilFunc_t + { + gl.m_StencilFunc.mask = Value; + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + case D3DRS_STENCILWRITEMASK: // GLStencilWriteMask_t + { + gl.m_StencilWriteMask.mask = Value; + m_ctx->WriteStencilWriteMask( &gl.m_StencilWriteMask ); + break; + } + case D3DRS_FOGENABLE: // none of these are implemented yet... erk + { + gl.m_FogEnable = (Value != 0); + GLMPRINTF(("-D- fogenable = %d",Value )); + break; + } + case D3DRS_SCISSORTESTENABLE: // kGLScissorEnable + { + gl.m_ScissorEnable.enable = Value; + m_ctx->WriteScissorEnable( &gl.m_ScissorEnable ); + break; + } + case D3DRS_DEPTHBIAS: // kGLDepthBias + { + // the value in the dword is actually a float + float fvalue = *(float*)&Value; + gl.m_DepthBias.units = fvalue; + + m_ctx->WriteDepthBias( &gl.m_DepthBias ); + break; + } + // good ref on these: http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/ + case D3DRS_SLOPESCALEDEPTHBIAS: + { + // the value in the dword is actually a float + float fvalue = *(float*)&Value; + gl.m_DepthBias.factor = fvalue; + + m_ctx->WriteDepthBias( &gl.m_DepthBias ); + break; + } + // Alpha to coverage + case D3DRS_ADAPTIVETESS_Y: + { + gl.m_AlphaToCoverageEnable.enable = Value; + m_ctx->WriteAlphaToCoverageEnable( &gl.m_AlphaToCoverageEnable ); + break; + } + case D3DRS_CLIPPLANEENABLE: // kGLClipPlaneEnable + { + // d3d packs all the enables into one word. + // we break that out so we don't do N glEnable calls to sync - + // GLM is tracking one unique enable per plane. + for( int i=0; iWriteClipPlaneEnable( &gl.m_ClipPlaneEnable[x], x ); + break; + } + //-------------------------------------------------------------------------------------------- polygon/fill mode + case D3DRS_FILLMODE: + { + GLuint mode = 0; + switch(Value) + { + case D3DFILL_POINT: mode = GL_POINT; break; + case D3DFILL_WIREFRAME: mode = GL_LINE; break; + case D3DFILL_SOLID: mode = GL_FILL; break; + default: DXABSTRACT_BREAK_ON_ERROR(); break; + } + gl.m_PolygonMode.values[0] = gl.m_PolygonMode.values[1] = mode; + m_ctx->WritePolygonMode( &gl.m_PolygonMode ); + break; + } + } + + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetRenderStateConstInline( D3DRENDERSTATETYPE State, DWORD Value ) +{ + // State is a compile time constant - luckily no need to do anything special to get the compiler to optimize this case. + return SetRenderStateInline( State, Value ); +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetIndices(IDirect3DIndexBuffer9* pIndexData) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetIndicesNonInline( pIndexData ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + // just latch it. + m_indices.m_idxBuffer = pIndexData; + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetStreamSource(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetStreamSourceNonInline( StreamNumber, pStreamData, OffsetInBytes, Stride ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + Assert( StreamNumber < D3D_MAX_STREAMS ); + Assert( ( Stride & 3 ) == 0 ); // we support non-DWORD aligned strides, but on some drivers (like AMD's) perf goes off a cliff + + // perfectly legal to see a vertex buffer of NULL get passed in here. + // so we need an array to track these. + // OK, we are being given the stride, we don't need to calc it.. + + GLMPRINTF(("-X- IDirect3DDevice9::SetStreamSource setting stream #%d to D3D buf %p (GL name %d); offset %d, stride %d", StreamNumber, pStreamData, (pStreamData) ? pStreamData->m_vtxBuffer->m_name: -1, OffsetInBytes, Stride)); + + if ( !pStreamData ) + { + OffsetInBytes = 0; + Stride = 0; + + m_vtx_buffers[ StreamNumber ] = m_pDummy_vtx_buffer; + } + else + { + // We do not support strides of 0 + Assert( Stride > 0 ); + m_vtx_buffers[ StreamNumber ] = pStreamData->m_vtxBuffer; + } + + m_streams[ StreamNumber ].m_vtxBuffer = pStreamData; + m_streams[ StreamNumber ].m_offset = OffsetInBytes; + m_streams[ StreamNumber ].m_stride = Stride; + + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) // groups of 4 floats! +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderConstantFNonInline( StartRegister, pConstantData, Vector4fCount ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersF( kGLMVertexProgram, StartRegister, (float *)pConstantData, Vector4fCount ); + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetVertexShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderConstantBNonInline( StartRegister, pConstantData, BoolCount ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersB( kGLMVertexProgram, StartRegister, (int *)pConstantData, BoolCount ); + return S_OK; +#endif +} + +FORCEINLINE HRESULT IDirect3DDevice9::SetVertexShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) // groups of 4 ints! +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderConstantINonInline( StartRegister, pConstantData, Vector4iCount ); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersI( kGLMVertexProgram, StartRegister, (int *)pConstantData, Vector4iCount ); + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShaderConstantF(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetPixelShaderConstantFNonInline(StartRegister, pConstantData, Vector4fCount); +#else + TOGL_NULL_DEVICE_CHECK; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetProgramParametersF( kGLMFragmentProgram, StartRegister, (float *)pConstantData, Vector4fCount ); + return S_OK; +#endif +} + +HRESULT IDirect3DDevice9::SetVertexShader(IDirect3DVertexShader9* pShader) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexShaderNonInline(pShader); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetVertexProgram( pShader ? pShader->m_vtxProgram : NULL ); + m_vertexShader = pShader; + return S_OK; +#endif +} + +FORCEINLINE HRESULT TOGLMETHODCALLTYPE IDirect3DDevice9::SetPixelShader(IDirect3DPixelShader9* pShader) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetPixelShaderNonInline(pShader); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetFragmentProgram( pShader ? pShader->m_pixProgram : NULL ); + m_pixelShader = pShader; + return S_OK; +#endif +} + +FORCEINLINE HRESULT IDirect3DDevice9::SetVertexDeclaration(IDirect3DVertexDeclaration9* pDecl) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetVertexDeclarationNonInline(pDecl); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_pVertDecl = pDecl; + return S_OK; +#endif +} + +FORCEINLINE void IDirect3DDevice9::SetMaxUsedVertexShaderConstantsHint( uint nMaxReg ) +{ +#if GLMDEBUG || GL_BATCH_PERF_ANALYSIS + return SetMaxUsedVertexShaderConstantsHintNonInline( nMaxReg ); +#else + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + m_ctx->SetMaxUsedVertexShaderConstantsHint( nMaxReg ); +#endif +} + +// ------------------------------------------------------------------------------------------------------------------------------ // +// D3DX +// ------------------------------------------------------------------------------------------------------------------------------ // +struct ID3DXInclude +{ + virtual HRESULT Open(D3DXINCLUDE_TYPE IncludeType, LPCSTR pFileName, LPCVOID pParentData, LPCVOID *ppData, UINT *pBytes); + virtual HRESULT Close(LPCVOID pData); +}; +typedef ID3DXInclude* LPD3DXINCLUDE; + + +struct TOGL_CLASS ID3DXBuffer : public IUnknown +{ + void* GetBufferPointer(); + DWORD GetBufferSize(); +}; + +typedef ID3DXBuffer* LPD3DXBUFFER; + +class ID3DXConstantTable : public IUnknown +{ +}; +typedef ID3DXConstantTable* LPD3DXCONSTANTTABLE; + +TOGL_INTERFACE const char* D3DXGetPixelShaderProfile( IDirect3DDevice9 *pDevice ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ); +TOGL_INTERFACE D3DXVECTOR3* D3DXVec3TransformCoord( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE HRESULT D3DXCreateMatrixStack( DWORD Flags, LPD3DXMATRIXSTACK* ppStack); +TOGL_INTERFACE void D3DXMatrixIdentity( D3DXMATRIX * ); + +TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Subtract( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + pOut->x = pV1->x - pV2->x; + pOut->y = pV1->y - pV2->y; + pOut->z = pV1->z - pV2->z; + return pOut; +} + +TOGL_INTERFACE D3DXINLINE D3DXVECTOR3* D3DXVec3Cross( D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + D3DXVECTOR3 v; + + v.x = pV1->y * pV2->z - pV1->z * pV2->y; + v.y = pV1->z * pV2->x - pV1->x * pV2->z; + v.z = pV1->x * pV2->y - pV1->y * pV2->x; + + *pOut = v; + return pOut; +} + +TOGL_INTERFACE D3DXINLINE FLOAT D3DXVec3Dot( CONST D3DXVECTOR3 *pV1, CONST D3DXVECTOR3 *pV2 ) +{ + return pV1->x * pV2->x + pV1->y * pV2->y + pV1->z * pV2->z; +} + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE D3DXPLANE* D3DXPlaneNormalize( D3DXPLANE *pOut, CONST D3DXPLANE *pP); + +TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ); + + +TOGL_INTERFACE D3DXVECTOR4* D3DXVec4Normalize( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ); + +// Build an ortho projection matrix. (right-handed) +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixOrthoOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn,FLOAT zf ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveRH( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ); + +TOGL_INTERFACE D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf ); + +// Transform a plane by a matrix. The vector (a,b,c) must be normal. +// M should be the inverse transpose of the transformation desired. +TOGL_INTERFACE D3DXPLANE* D3DXPlaneTransform( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ); + +TOGL_INTERFACE IDirect3D9 *Direct3DCreate9(UINT SDKVersion); + +TOGL_INTERFACE void D3DPERF_SetOptions( DWORD dwOptions ); + +TOGL_INTERFACE HRESULT D3DXCompileShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable); + +// fake D3D usage constant for SRGB tex creation +#define D3DUSAGE_TEXTURE_SRGB (0x80000000L) + +#else + + //USE_ACTUAL_DX + #ifndef WIN32 + #error sorry man + #endif + + #ifdef _X360 + #include "d3d9.h" + #include "d3dx9.h" + #else + #include + #include "../../dx9sdk/include/d3d9.h" + #include "../../dx9sdk/include/d3dx9.h" + #endif + typedef HWND VD3DHWND; + +#endif // DX_TO_GL_ABSTRACTION + +#endif // DXABSTRACT_H diff --git a/public/togles/linuxwin/dxabstract_types.h b/public/togles/linuxwin/dxabstract_types.h new file mode 100644 index 00000000..aa3013f3 --- /dev/null +++ b/public/togles/linuxwin/dxabstract_types.h @@ -0,0 +1,1749 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// dxabstract_types.h +// +//================================================================================================== +#ifndef DXABSTRACT_TYPES_H +#define DXABSTRACT_TYPES_H + +#pragma once + +#if GL_BATCH_PERF_ANALYSIS + class simple_bitmap; +#endif + +struct IUnknown; +struct IDirect3D9; +struct IDirect3DDevice9; +struct IDirect3DResource9; +struct IDirect3DBaseTexture9; +struct IDirect3DTexture9; +struct IDirect3DCubeTexture9; +struct IDirect3DVolumeTexture9; +struct IDirect3DSurface9; +struct IDirect3DVertexDeclaration9; +struct IDirect3DQuery9; +struct IDirect3DVertexBuffer9; +struct IDirect3DIndexBuffer9; +struct IDirect3DPixelShader9; +struct IDirect3DVertexShader9; +struct IDirect3DDevice9Params; + +class GLMContext; +struct GLMRect; +struct GLMShaderPairInfo; +class CGLMBuffer; +class CGLMQuery; +class CGLMTex; +class CGLMProgram; +class CGLMFBO; + +#ifdef TOGL_DLL_EXPORT + #define TOGL_INTERFACE DLL_EXPORT + #define TOGL_OVERLOAD DLL_GLOBAL_EXPORT + #define TOGL_CLASS DLL_CLASS_EXPORT + #define TOGL_GLOBAL DLL_GLOBAL_EXPORT +#else + #define TOGL_INTERFACE DLL_IMPORT + #define TOGL_OVERLOAD DLL_GLOBAL_IMPORT + #define TOGL_CLASS DLL_CLASS_IMPORT + #define TOGL_GLOBAL DLL_GLOBAL_IMPORT +#endif + +#define TOGLMETHODCALLTYPE __stdcall +//#define TOGLMETHODCALLTYPE + +#define DXABSTRACT_BREAK_ON_ERROR() DebuggerBreak() + +typedef void* VD3DHWND; +typedef void* VD3DHANDLE; + +#define MAKEFOURCC(ch0, ch1, ch2, ch3) ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) + +// +// +// Stuff that would be in windows.h +// +// +#if !defined(_WINNT_) + + typedef int INT; + typedef unsigned long ULONG; + typedef long LONG; + typedef float FLOAT; + typedef unsigned int DWORD; + typedef unsigned short WORD; + typedef long long LONGLONG; + typedef unsigned int UINT; + typedef long HRESULT; + typedef unsigned char BYTE; + #define CONST const + + #if defined(POSIX) + typedef size_t ULONG_PTR; + #else + typedef unsigned long ULONG_PTR; + #endif + + typedef ULONG_PTR SIZE_T; + + typedef const char* LPCSTR; + typedef char* LPSTR; + typedef DWORD* LPDWORD; + + #define ZeroMemory RtlZeroMemory + #define RtlZeroMemory(Destination,Length) memset((Destination),0,(Length)) + + typedef union _LARGE_INTEGER + { + struct + { + DWORD LowPart; + LONG HighPart; + }; + struct + { + DWORD LowPart; + LONG HighPart; + } u; + LONGLONG QuadPart; + } LARGE_INTEGER; + + typedef struct _GUID + { + bool operator==( const struct _GUID &other ) const; + + unsigned long Data1; + unsigned short Data2; + unsigned short Data3; + unsigned char Data4[ 8 ]; + } GUID; + + typedef struct _RECT + { + int left; + int top; + int right; + int bottom; + } RECT; + + typedef struct tagPOINT + { + LONG x; + LONG y; + } POINT, *PPOINT, *LPPOINT; + + typedef struct _MEMORYSTATUS + { + DWORD dwLength; + SIZE_T dwTotalPhys; + } MEMORYSTATUS, *LPMEMORYSTATUS; + + typedef DWORD COLORREF; + #define RGB(r,g,b) ((COLORREF)(((BYTE)(r)|((WORD)((BYTE)(g))<<8))|(((DWORD)(BYTE)(b))<<16))) + + #define MAKE_HRESULT(sev,fac,code) ((HRESULT) (((unsigned long)(sev)<<31) | ((unsigned long)(fac)<<16) | ((unsigned long)(code))) ) + + #define S_FALSE ((HRESULT)0x00000001L) + #define S_OK 0 + #define E_FAIL ((HRESULT)0x80004005L) + #define E_OUTOFMEMORY ((HRESULT)0x8007000EL) + + #define FAILED(hr) ((HRESULT)(hr) < 0) + #define SUCCEEDED(hr) ((HRESULT)(hr) >= 0) + + struct RGNDATA + { + }; + + typedef const void* LPCVOID; +#endif + +//----------------------------------------------------------------------------- + +typedef enum _D3DFORMAT D3DFORMAT; + +#define D3DSI_OPCODE_MASK 0x0000FFFF +#define D3DSP_TEXTURETYPE_MASK 0x78000000 + +#define D3DUSAGE_AUTOGENMIPMAP 0x00000400L +#define D3DSP_DCL_USAGE_MASK 0x0000000f + +#define D3DSP_OPCODESPECIFICCONTROL_MASK 0x00ff0000 +#define D3DSP_OPCODESPECIFICCONTROL_SHIFT 16 + +// Comparison for dynamic conditional instruction opcodes (i.e. if, breakc) +typedef enum _D3DSHADER_COMPARISON +{ + // < = > + D3DSPC_RESERVED0= 0, // 0 0 0 + D3DSPC_GT = 1, // 0 0 1 + D3DSPC_EQ = 2, // 0 1 0 + D3DSPC_GE = 3, // 0 1 1 + D3DSPC_LT = 4, // 1 0 0 + D3DSPC_NE = 5, // 1 0 1 + D3DSPC_LE = 6, // 1 1 0 + D3DSPC_RESERVED1= 7 // 1 1 1 +} D3DSHADER_COMPARISON; + + +// Comparison is part of instruction opcode token: +#define D3DSHADER_COMPARISON_SHIFT D3DSP_OPCODESPECIFICCONTROL_SHIFT +#define D3DSHADER_COMPARISON_MASK (0x7<>8)&0xFF) +#define D3DSHADER_VERSION_MINOR(_Version) (((_Version)>>0)&0xFF) + +#define D3DSHADER_ADDRESSMODE_SHIFT 13 +#define D3DSHADER_ADDRESSMODE_MASK (1 << D3DSHADER_ADDRESSMODE_SHIFT) + +#define D3DPS_END() 0x0000FFFF + +// ps_2_0 texld controls +#define D3DSI_TEXLD_PROJECT (0x01 << D3DSP_OPCODESPECIFICCONTROL_SHIFT) +#define D3DSI_TEXLD_BIAS (0x02 << D3DSP_OPCODESPECIFICCONTROL_SHIFT) + + +// destination parameter write mask +#define D3DSP_WRITEMASK_0 0x00010000 // Component 0 (X;Red) +#define D3DSP_WRITEMASK_1 0x00020000 // Component 1 (Y;Green) +#define D3DSP_WRITEMASK_2 0x00040000 // Component 2 (Z;Blue) +#define D3DSP_WRITEMASK_3 0x00080000 // Component 3 (W;Alpha) +#define D3DSP_WRITEMASK_ALL 0x000F0000 // All Components + +#define D3DVS_SWIZZLE_SHIFT 16 +#define D3DVS_SWIZZLE_MASK 0x00FF0000 + +// The following bits define where to take component X from: + +#define D3DVS_X_X (0 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_Y (1 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_Z (2 << D3DVS_SWIZZLE_SHIFT) +#define D3DVS_X_W (3 << D3DVS_SWIZZLE_SHIFT) + +// The following bits define where to take component Y from: + +#define D3DVS_Y_X (0 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_Y (1 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_Z (2 << (D3DVS_SWIZZLE_SHIFT + 2)) +#define D3DVS_Y_W (3 << (D3DVS_SWIZZLE_SHIFT + 2)) + +// The following bits define where to take component Z from: + +#define D3DVS_Z_X (0 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_Y (1 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_Z (2 << (D3DVS_SWIZZLE_SHIFT + 4)) +#define D3DVS_Z_W (3 << (D3DVS_SWIZZLE_SHIFT + 4)) + +// The following bits define where to take component W from: + +#define D3DVS_W_X (0 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_Y (1 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_Z (2 << (D3DVS_SWIZZLE_SHIFT + 6)) +#define D3DVS_W_W (3 << (D3DVS_SWIZZLE_SHIFT + 6)) + +// source parameter modifiers +#define D3DSP_SRCMOD_SHIFT 24 +#define D3DSP_SRCMOD_MASK 0x0F000000 + +// ------------------------------------------------------------------------------------------------------------------------------ // +// ENUMS +// ------------------------------------------------------------------------------------------------------------------------------ // + +typedef enum _D3DSHADER_PARAM_SRCMOD_TYPE +{ + D3DSPSM_NONE = 0<= 2.0 + + + D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0 + D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1) + D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0) + D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1) + D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0) + D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1) + D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1) + D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1) + D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values + D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused. +} D3DDECLTYPE; + +typedef enum _D3DDECLMETHOD +{ + D3DDECLMETHOD_DEFAULT = 0, + D3DDECLMETHOD_PARTIALU, + D3DDECLMETHOD_PARTIALV, + D3DDECLMETHOD_CROSSUV, // Normal + D3DDECLMETHOD_UV, + D3DDECLMETHOD_LOOKUP, // Lookup a displacement map + D3DDECLMETHOD_LOOKUPPRESAMPLED, // Lookup a pre-sampled displacement map +} D3DDECLMETHOD; + +typedef enum _D3DDECLUSAGE +{ + D3DDECLUSAGE_POSITION = 0, + D3DDECLUSAGE_BLENDWEIGHT = 1, + D3DDECLUSAGE_BLENDINDICES = 2, + D3DDECLUSAGE_NORMAL = 3, + D3DDECLUSAGE_PSIZE = 4, + D3DDECLUSAGE_TEXCOORD = 5, + D3DDECLUSAGE_TANGENT = 6, + D3DDECLUSAGE_BINORMAL = 7, + D3DDECLUSAGE_TESSFACTOR = 8, + D3DDECLUSAGE_PLUGH = 9, // mystery value + D3DDECLUSAGE_COLOR = 10, + D3DDECLUSAGE_FOG = 11, + D3DDECLUSAGE_DEPTH = 12, + D3DDECLUSAGE_SAMPLE = 13, +} D3DDECLUSAGE; + +typedef enum _D3DPRIMITIVETYPE +{ + D3DPT_POINTLIST = 1, + D3DPT_LINELIST = 2, + D3DPT_TRIANGLELIST = 4, + D3DPT_TRIANGLESTRIP = 5, + D3DPT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DPRIMITIVETYPE; + +// ------------------------------------------------------------------------------------------------------------------------------ // +// STRUCTURES +// ------------------------------------------------------------------------------------------------------------------------------ // + +typedef struct TOGL_CLASS D3DXPLANE +{ + float& operator[]( int i ); + bool operator==( const D3DXPLANE &o ); + bool operator!=( const D3DXPLANE &o ); + operator float*(); + operator const float*() const; + + float a, b, c, d; +} D3DXPLANE; + +typedef enum _D3DVERTEXBLENDFLAGS +{ + D3DVBF_DISABLE = 0, // Disable vertex blending + D3DVBF_1WEIGHTS = 1, // 2 matrix blending + D3DVBF_2WEIGHTS = 2, // 3 matrix blending + D3DVBF_3WEIGHTS = 3, // 4 matrix blending + D3DVBF_TWEENING = 255, // blending using D3DRS_TWEENFACTOR + D3DVBF_0WEIGHTS = 256, // one matrix is used with weight 1.0 + D3DVBF_FORCE_DWORD = 0x7fffffff, // force 32-bit size enum +} D3DVERTEXBLENDFLAGS; + +typedef struct _D3DINDEXBUFFER_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + UINT Size; +} D3DINDEXBUFFER_DESC; + +typedef struct _D3DVERTEXELEMENT9 +{ + WORD Stream; // Stream index + WORD Offset; // Offset in the stream in bytes + BYTE Type; // Data type + BYTE Method; // Processing method + BYTE Usage; // Semantics + BYTE UsageIndex; // Semantic index +} D3DVERTEXELEMENT9, *LPD3DVERTEXELEMENT9; + + +#define MAX_DEVICE_IDENTIFIER_STRING 512 +typedef struct _D3DADAPTER_IDENTIFIER9 +{ + char Driver[MAX_DEVICE_IDENTIFIER_STRING]; + char Description[MAX_DEVICE_IDENTIFIER_STRING]; + char DeviceName[32]; /* Device name for GDI (ex. \\.\DISPLAY1) */ + + LARGE_INTEGER DriverVersion; /* Defined for 32 bit components */ + + DWORD VendorId; + DWORD DeviceId; + DWORD SubSysId; + DWORD Revision; + DWORD VideoMemory; + +} D3DADAPTER_IDENTIFIER9; + +typedef struct _D3DCOLORVALUE +{ + float r; + float g; + float b; + float a; +} D3DCOLORVALUE; + +typedef struct _D3DMATERIAL9 +{ + D3DCOLORVALUE Diffuse; /* Diffuse color RGBA */ + D3DCOLORVALUE Ambient; /* Ambient color RGB */ + D3DCOLORVALUE Specular; /* Specular 'shininess' */ + D3DCOLORVALUE Emissive; /* Emissive color RGB */ + float Power; /* Sharpness if specular highlight */ +} D3DMATERIAL9; + +typedef struct _D3DVOLUME_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + + UINT Width; + UINT Height; + UINT Depth; +} D3DVOLUME_DESC; + +typedef struct _D3DVIEWPORT9 +{ + DWORD X; + DWORD Y; /* Viewport Top left */ + DWORD Width; + DWORD Height; /* Viewport Dimensions */ + float MinZ; /* Min/max of clip Volume */ + float MaxZ; +} D3DVIEWPORT9; + +typedef struct _D3DPSHADERCAPS2_0 +{ + DWORD Caps; + INT DynamicFlowControlDepth; + INT NumTemps; + INT StaticFlowControlDepth; + INT NumInstructionSlots; +} D3DPSHADERCAPS2_0; + +typedef struct _D3DCAPS9 +{ + /* Device Info */ + D3DDEVTYPE DeviceType; + + /* Caps from DX7 Draw */ + DWORD Caps; + DWORD Caps2; + + /* Cursor Caps */ + DWORD CursorCaps; + + /* 3D Device Caps */ + DWORD DevCaps; + + DWORD PrimitiveMiscCaps; + DWORD RasterCaps; + DWORD TextureCaps; + DWORD TextureFilterCaps; // D3DPTFILTERCAPS for IDirect3DTexture9's + + DWORD MaxTextureWidth, MaxTextureHeight; + DWORD MaxVolumeExtent; + + DWORD MaxTextureAspectRatio; + DWORD MaxAnisotropy; + + DWORD TextureOpCaps; + DWORD MaxTextureBlendStages; + DWORD MaxSimultaneousTextures; + + DWORD VertexProcessingCaps; + DWORD MaxActiveLights; + DWORD MaxUserClipPlanes; + DWORD MaxVertexBlendMatrices; + DWORD MaxVertexBlendMatrixIndex; + + DWORD MaxPrimitiveCount; // max number of primitives per DrawPrimitive call + DWORD MaxStreams; + + DWORD VertexShaderVersion; + DWORD MaxVertexShaderConst; // number of vertex shader constant registers + + DWORD PixelShaderVersion; + + // Here are the DX9 specific ones + DWORD DevCaps2; + D3DPSHADERCAPS2_0 PS20Caps; + + DWORD NumSimultaneousRTs; // Will be at least 1 + DWORD MaxVertexShader30InstructionSlots; + DWORD MaxPixelShader30InstructionSlots; + + // only on Posix/GL + DWORD FakeSRGBWrite; // 1 for parts which can't support SRGB writes due to driver issues - 0 for others + DWORD MixedSizeTargets; // 1 for parts which can mix attachment sizes (RT's color vs depth) + DWORD CanDoSRGBReadFromRTs; // 0 when we're on Leopard, 1 when on Snow Leopard +} D3DCAPS9; + +typedef struct _D3DDISPLAYMODE +{ + UINT Width; + UINT Height; + UINT RefreshRate; + D3DFORMAT Format; +} D3DDISPLAYMODE; + +typedef struct _D3DGAMMARAMP +{ + WORD red [256]; + WORD green[256]; + WORD blue [256]; +} D3DGAMMARAMP; + + +/* Resize Optional Parameters */ +typedef struct _D3DPRESENT_PARAMETERS_ +{ + UINT BackBufferWidth; + UINT BackBufferHeight; + D3DFORMAT BackBufferFormat; + UINT BackBufferCount; + + D3DMULTISAMPLE_TYPE MultiSampleType; + DWORD MultiSampleQuality; + + D3DSWAPEFFECT SwapEffect; + VD3DHWND hDeviceWindow; + BOOL Windowed; + BOOL EnableAutoDepthStencil; + D3DFORMAT AutoDepthStencilFormat; + DWORD Flags; + + /* FullScreen_RefreshRateInHz must be zero for Windowed mode */ + UINT FullScreen_RefreshRateInHz; + UINT PresentationInterval; +} D3DPRESENT_PARAMETERS; + +typedef struct _D3DDEVICE_CREATION_PARAMETERS +{ + UINT AdapterOrdinal; + D3DDEVTYPE DeviceType; + VD3DHWND hFocusWindow; + DWORD BehaviorFlags; +} D3DDEVICE_CREATION_PARAMETERS; + +/* Structures for LockBox */ +typedef struct _D3DBOX +{ + UINT Left; + UINT Top; + UINT Right; + UINT Bottom; + UINT Front; + UINT Back; +} D3DBOX; + +typedef struct _D3DLOCKED_BOX +{ + INT RowPitch; + INT SlicePitch; + void* pBits; +} D3DLOCKED_BOX; + +typedef struct _D3DSURFACE_DESC +{ + D3DFORMAT Format; + D3DRESOURCETYPE Type; + DWORD Usage; + D3DPOOL Pool; + + D3DMULTISAMPLE_TYPE MultiSampleType; + DWORD MultiSampleQuality; + UINT Width; + UINT Height; +} D3DSURFACE_DESC; + + +typedef struct _D3DLOCKED_RECT +{ + INT Pitch; + void* pBits; +} D3DLOCKED_RECT; + + +typedef struct _D3DRASTER_STATUS +{ + BOOL InVBlank; + UINT ScanLine; +} D3DRASTER_STATUS; + +typedef enum _D3DLIGHTTYPE +{ + D3DLIGHT_POINT = 1, + D3DLIGHT_SPOT = 2, + D3DLIGHT_DIRECTIONAL = 3, + D3DLIGHT_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DLIGHTTYPE; + +typedef struct TOGL_CLASS _D3DVECTOR +{ + float x; + float y; + float z; +} D3DVECTOR; + +class TOGL_CLASS D3DXVECTOR2 +{ +public: + operator FLOAT* (); + operator CONST FLOAT* () const; + + float x,y; +}; + +class TOGL_CLASS D3DXVECTOR3 : public D3DVECTOR +{ +public: + D3DXVECTOR3() {} + D3DXVECTOR3( float a, float b, float c ); + operator FLOAT* (); + operator CONST FLOAT* () const; +}; + +typedef enum _D3DXINCLUDE_TYPE +{ + D3DXINC_LOCAL, + + // force 32-bit size enum + D3DXINC_FORCE_DWORD = 0x7fffffff + +} D3DXINCLUDE_TYPE; + +typedef struct _D3DLIGHT9 +{ + D3DLIGHTTYPE Type; /* Type of light source */ + D3DCOLORVALUE Diffuse; /* Diffuse color of light */ + D3DCOLORVALUE Specular; /* Specular color of light */ + D3DCOLORVALUE Ambient; /* Ambient color of light */ + D3DVECTOR Position; /* Position in world space */ + D3DVECTOR Direction; /* Direction in world space */ + float Range; /* Cutoff range */ + float Falloff; /* Falloff */ + float Attenuation0; /* Constant attenuation */ + float Attenuation1; /* Linear attenuation */ + float Attenuation2; /* Quadratic attenuation */ + float Theta; /* Inner angle of spotlight cone */ + float Phi; /* Outer angle of spotlight cone */ +} D3DLIGHT9; + +class TOGL_CLASS D3DXVECTOR4 +{ +public: + D3DXVECTOR4() {} + D3DXVECTOR4( float a, float b, float c, float d ); + + float x,y,z,w; +}; + +//---------------------------------------------------------------------------- +// D3DXMACRO: +// ---------- +// Preprocessor macro definition. The application pass in a NULL-terminated +// array of this structure to various D3DX APIs. This enables the application +// to #define tokens at runtime, before the file is parsed. +//---------------------------------------------------------------------------- + +typedef struct _D3DXMACRO +{ + LPCSTR Name; + LPCSTR Definition; + +} D3DXMACRO, *LPD3DXMACRO; + +// ------------------------------------------------------------------------------------------------------------------------------ // +// ------------------------------------------------------------------------------------------------------------------------------ // +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +// +// Also look for any functions marked with "**** FIXED FUNCTION STUFF" +// +// It's only laying around here so we don't have to chop up the shader system a lot to strip out the fixed function code paths. +// ------------------------------------------------------------------------------------------------------------------------------ // +// ------------------------------------------------------------------------------------------------------------------------------ // + +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +typedef enum _D3DTRANSFORMSTATETYPE +{ + D3DTS_VIEW = 2, + D3DTS_PROJECTION = 3, + D3DTS_TEXTURE0 = 16, + D3DTS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTRANSFORMSTATETYPE; + +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +typedef enum _D3DTEXTUREOP +{ + // Control + D3DTOP_DISABLE = 1, // disables stage + D3DTOP_SELECTARG1 = 2, // the default + D3DTOP_SELECTARG2 = 3, + + // Modulate + D3DTOP_MODULATE = 4, // multiply args together + D3DTOP_MODULATE2X = 5, // multiply and 1 bit + D3DTOP_MODULATE4X = 6, // multiply and 2 bits + + // Add + D3DTOP_ADD = 7, // add arguments together + D3DTOP_ADDSIGNED = 8, // add with -0.5 bias + D3DTOP_ADDSIGNED2X = 9, // as above but left 1 bit + D3DTOP_SUBTRACT = 10, // Arg1 - Arg2, with no saturation + D3DTOP_ADDSMOOTH = 11, // add 2 args, subtract product + // Arg1 + Arg2 - Arg1*Arg2 + // = Arg1 + (1-Arg1)*Arg2 + + // Linear alpha blend: Arg1*(Alpha) + Arg2*(1-Alpha) + D3DTOP_BLENDDIFFUSEALPHA = 12, // iterated alpha + D3DTOP_BLENDTEXTUREALPHA = 13, // texture alpha + D3DTOP_BLENDFACTORALPHA = 14, // alpha from D3DRS_TEXTUREFACTOR + + // Linear alpha blend with pre-multiplied arg1 input: Arg1 + Arg2*(1-Alpha) + D3DTOP_BLENDTEXTUREALPHAPM = 15, // texture alpha + D3DTOP_BLENDCURRENTALPHA = 16, // by alpha of current color + + // Specular mapping + D3DTOP_PREMODULATE = 17, // modulate with next texture before use + D3DTOP_MODULATEALPHA_ADDCOLOR = 18, // Arg1.RGB + Arg1.A*Arg2.RGB + // COLOROP only + D3DTOP_MODULATECOLOR_ADDALPHA = 19, // Arg1.RGB*Arg2.RGB + Arg1.A + // COLOROP only + D3DTOP_MODULATEINVALPHA_ADDCOLOR = 20, // (1-Arg1.A)*Arg2.RGB + Arg1.RGB + // COLOROP only + D3DTOP_MODULATEINVCOLOR_ADDALPHA = 21, // (1-Arg1.RGB)*Arg2.RGB + Arg1.A + // COLOROP only + + // Bump mapping + D3DTOP_BUMPENVMAP = 22, // per pixel env map perturbation + D3DTOP_BUMPENVMAPLUMINANCE = 23, // with luminance channel + + // This can do either diffuse or specular bump mapping with correct input. + // Performs the function (Arg1.R*Arg2.R + Arg1.G*Arg2.G + Arg1.B*Arg2.B) + // where each component has been scaled and offset to make it signed. + // The result is replicated into all four (including alpha) channels. + // This is a valid COLOROP only. + D3DTOP_DOTPRODUCT3 = 24, + + // Triadic ops + D3DTOP_MULTIPLYADD = 25, // Arg0 + Arg1*Arg2 + D3DTOP_LERP = 26, // (Arg0)*Arg1 + (1-Arg0)*Arg2 + + D3DTOP_FORCE_DWORD = 0x7fffffff, +} D3DTEXTUREOP; + +// **** FIXED FUNCTION STUFF - None of this stuff needs support in GL. +typedef enum _D3DTEXTURESTAGESTATETYPE +{ + D3DTSS_COLOROP = 1, /* D3DTEXTUREOP - per-stage blending controls for color channels */ + D3DTSS_COLORARG1 = 2, /* D3DTA_* (texture arg) */ + D3DTSS_COLORARG2 = 3, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAOP = 4, /* D3DTEXTUREOP - per-stage blending controls for alpha channel */ + D3DTSS_ALPHAARG1 = 5, /* D3DTA_* (texture arg) */ + D3DTSS_ALPHAARG2 = 6, /* D3DTA_* (texture arg) */ + D3DTSS_BUMPENVMAT00 = 7, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT01 = 8, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT10 = 9, /* float (bump mapping matrix) */ + D3DTSS_BUMPENVMAT11 = 10, /* float (bump mapping matrix) */ + D3DTSS_TEXCOORDINDEX = 11, /* identifies which set of texture coordinates index this texture */ + D3DTSS_BUMPENVLOFFSET = 23, /* float offset for bump map luminance */ + D3DTSS_TEXTURETRANSFORMFLAGS = 24, /* D3DTEXTURETRANSFORMFLAGS controls texture transform */ + D3DTSS_COLORARG0 = 26, /* D3DTA_* third arg for triadic ops */ + D3DTSS_RESULTARG = 28, /* D3DTA_* arg for result (CURRENT or TEMP) */ + + + D3DTSS_FORCE_DWORD = 0x7fffffff, /* force 32-bit size enum */ +} D3DTEXTURESTAGESTATETYPE; + +//===========================================================================// + +enum GLMVertexAttributeIndex +{ + kGLMGenericAttr00 = 0, + kGLMGenericAttr01, + kGLMGenericAttr02, + kGLMGenericAttr03, + kGLMGenericAttr04, + kGLMGenericAttr05, + kGLMGenericAttr06, + kGLMGenericAttr07, + kGLMGenericAttr08, + kGLMGenericAttr09, + kGLMGenericAttr10, + kGLMGenericAttr11, + kGLMGenericAttr12, + kGLMGenericAttr13, + kGLMGenericAttr14, + kGLMGenericAttr15, + + kGLMVertexAttributeIndexMax // ideally < 32 +}; + +struct GLMVertexAttributeDesc // all the info you need to do vertex setup for one attribute +{ + CGLMBuffer *m_pBuffer; // NULL allowed in which case m_offset is the full 32-bit pointer.. so you can draw from plain RAM if desired + GLuint m_nCompCount; // comp count of the attribute (1-4) + GLenum m_datatype; // data type of the attribute (GL_FLOAT, GL_UNSIGNED_BYTE, etc) + GLuint m_stride; + GLuint m_offset; // net offset to attribute 'zero' within the buffer. + GLuint m_streamOffset; // net offset to attribute 'zero' within the buffer. + GLboolean m_normalized; // apply to any fixed point data that needs normalizing, esp color bytes + + inline uint GetDataTypeSizeInBytes() const + { + switch ( m_datatype ) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return 1; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_HALF_FLOAT: + return 2; + case GL_INT: + case GL_FLOAT: + return 4; + default: + Assert( 0 ); + break; + } + return 0; + } + + inline uint GetTotalAttributeSizeInBytes() const { Assert( m_nCompCount ); return m_nCompCount * GetDataTypeSizeInBytes(); } + + // may need a seed value at some point to be able to disambiguate re-lifed buffers holding same pointer + // simpler alternative is to do shoot-down inside the vertex/index buffer free calls. + // I'd rather not have to have each attribute fiddling a ref count on the buffer to which it refers.. + +//#define EQ(fff) ( (src.fff) == (fff) ) + // test in decreasing order of likelihood of difference, but do not include the buffer revision as caller is not supplying it.. + //inline bool operator== ( const GLMVertexAttributeDesc& src ) const { return EQ( m_pBuffer ) && EQ( m_offset ) && EQ( m_stride ) && EQ( m_datatype ) && EQ( m_normalized ) && EQ( m_nCompCount ); } +//#undef EQ + + uint m_bufferRevision; // only set in GLM context's copy, to disambiguate references that are same offset / same buffer but cross an orphan event +}; + +#define MAX_D3DVERTEXELEMENTS 16 + +struct D3DVERTEXELEMENT9_GL +{ + // fields right out of the original decl element (copied) + D3DVERTEXELEMENT9 m_dxdecl; // d3d info + // WORD Stream; // Stream index + // WORD Offset; // Offset in the stream in bytes + // BYTE Type; // Data type + // BYTE Method; // Processing method + // BYTE Usage; // Semantics + // BYTE UsageIndex; // Semantic index + + GLMVertexAttributeDesc m_gldecl; + // CGLMBuffer *m_buffer; // late-dropped from selected stream desc (left NULL, will replace with stream source buffer at sync time) + // GLuint m_datasize; // component count (1,2,3,4) of the attrib + // GLenum m_datatype; // data type of the attribute (GL_FLOAT et al) + // GLuint m_stride; // late-dropped from stream desc + // GLuint m_offset; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL. + // GLuint m_normalized; // net offset to attribute 'zero' within the stream data. Add the stream offset before passing to GL. +}; + +struct IDirect3DDevice9Params +{ + UINT m_adapter; + D3DDEVTYPE m_deviceType; + VD3DHWND m_focusWindow; + DWORD m_behaviorFlags; + D3DPRESENT_PARAMETERS m_presentationParameters; +}; + +#define D3D_MAX_STREAMS 5 //9 +struct D3DStreamDesc +{ + IDirect3DVertexBuffer9 *m_vtxBuffer; + uint m_offset; + uint m_stride; +}; + +struct D3DIndexDesc +{ + IDirect3DIndexBuffer9 *m_idxBuffer; +}; + +// we latch sampler values until draw time and then convert them all to GL form +// note these are similar in name to the fields of a GLMTexSamplingParams but contents are not +// particularly in the texture filtering area + +struct D3DSamplerDesc +{ + DWORD m_srgb; // D3DSAMP_SRGBTEXTURE 0 = no SRGB sampling +}; + +// Tracking and naming sampler dimensions +#define SAMPLER_TYPE_2D 0 +#define SAMPLER_TYPE_CUBE 1 +#define SAMPLER_TYPE_3D 2 +#define SAMPLER_TYPE_UNUSED 3 + +#endif // DXABSTRACT_TYPES_H diff --git a/public/togles/linuxwin/glbase.h b/public/togles/linuxwin/glbase.h new file mode 100644 index 00000000..9c830e6d --- /dev/null +++ b/public/togles/linuxwin/glbase.h @@ -0,0 +1,117 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glbase.h +// +//=============================================================================== + +#ifndef GLBASE_H +#define GLBASE_H + +#ifdef DX_TO_GL_ABSTRACTION + +#undef HAVE_GL_ARB_SYNC + +#ifndef OSX +#define HAVE_GL_ARB_SYNC 1 +#endif + +#ifdef USE_SDL +#include "SDL_opengl.h" +#endif + +#ifdef OSX +#include +#include +#endif + +#ifdef DX_TO_GL_ABSTRACTION + #ifndef WIN32 + #define Debugger DebuggerBreak + #endif + #undef CurrentTime + + #if defined( USE_SDL ) + #include "SDL.h" + #endif +#endif + +//=============================================================================== +// glue to call out to Obj-C land (these are in glmgrcocoa.mm) +#ifdef OSX + typedef void _PseudoNSGLContext; // aka NSOpenGLContext + typedef _PseudoNSGLContext *PseudoNSGLContextPtr; + + CGLContextObj GetCGLContextFromNSGL( PseudoNSGLContextPtr nsglCtx ); +#endif + +// Set TOGL_SUPPORT_NULL_DEVICE to 1 to support the NULL ref device +#define TOGL_SUPPORT_NULL_DEVICE 0 + +#if TOGL_SUPPORT_NULL_DEVICE + #define TOGL_NULL_DEVICE_CHECK if( m_params.m_deviceType == D3DDEVTYPE_NULLREF ) return S_OK; + #define TOGL_NULL_DEVICE_CHECK_RET_VOID if( m_params.m_deviceType == D3DDEVTYPE_NULLREF ) return; +#else + #define TOGL_NULL_DEVICE_CHECK + #define TOGL_NULL_DEVICE_CHECK_RET_VOID +#endif + +// GL_ENABLE_INDEX_VERIFICATION enables index range verification on all dynamic IB/VB's (obviously slow) +#define GL_ENABLE_INDEX_VERIFICATION 0 + +// GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION (currently win32 only) - If 1, VirtualAlloc/VirtualProtect is used to detect cases where the app locks a buffer, copies the ptr away, unlocks, then tries to later write to the buffer. +#define GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION 0 + +#define GL_BATCH_TELEMETRY_ZONES 0 + +// GL_BATCH_PERF_ANALYSIS - Enables gl_batch_vis, and various per-batch telemetry statistics messages. +#define GL_BATCH_PERF_ANALYSIS 0 +#define GL_BATCH_PERF_ANALYSIS_WRITE_PNGS 0 + +// GL_TELEMETRY_ZONES - Causes every single OpenGL call to generate a telemetry event +#define GL_TELEMETRY_ZONES 0 + +// GL_DUMP_ALL_API_CALLS - Causes a debug message to be printed for every API call if s_bDumpCalls bool is set to 1 +#define GL_DUMP_ALL_API_CALLS 0 + +// Must also enable PIX_ENABLE to use GL_TELEMETRY_GPU_ZONES. +#define GL_TELEMETRY_GPU_ZONES 0 + +// Records global # of OpenGL calls/total cycles spent inside GL +#define GL_TRACK_API_TIME GL_BATCH_PERF_ANALYSIS + +#define GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS ( GL_TELEMETRY_ZONES || GL_TRACK_API_TIME || GL_DUMP_ALL_API_CALLS ) + +#if GL_BATCH_PERF_ANALYSIS + #define GL_BATCH_PERF(...) __VA_ARGS__ +#else + #define GL_BATCH_PERF(...) +#endif + +#define kGLMUserClipPlanes 2 +#define kGLMScratchFBOCount 4 + +#endif // DX_TO_GL_ABSTRACTION + +#endif // GLBASE_H diff --git a/public/togles/linuxwin/glentrypoints.h b/public/togles/linuxwin/glentrypoints.h new file mode 100644 index 00000000..a7874463 --- /dev/null +++ b/public/togles/linuxwin/glentrypoints.h @@ -0,0 +1,390 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glentrypoints.h +// +//=============================================================================== + +#ifndef GLENTRYPOINTS_H +#define GLENTRYPOINTS_H + +#pragma once + +#ifdef DX_TO_GL_ABSTRACTION + +#include "tier0/platform.h" +#include "tier0/vprof_telemetry.h" +#include "interface.h" +#include "togles/rendermechanism.h" + +#ifdef LINUX +#include +#endif + +void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback=NULL); + +/* +#define GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS 1 +#define GL_TRACK_API_TIME 1 +#define GL_DUMP_ALL_API_CALLS 1 +*/ + +#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS +class CGLExecuteHelperBase +{ +public: + inline void StartCall(const char *pName); + inline void StopCall(const char *pName); +#if GL_TRACK_API_TIME + uint64 m_nStartTime; +#endif +}; + +template < class FunctionType, typename Result > +class CGLExecuteHelper : public CGLExecuteHelperBase +{ +public: + inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); m_Result = (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); } + + inline operator Result() const { return m_Result; } + inline operator char*() const { return (char*)m_Result; } + + FunctionType m_pFn; + + Result m_Result; +}; + +template < class FunctionType> +class CGLExecuteHelper : public CGLExecuteHelperBase +{ +public: + inline CGLExecuteHelper(FunctionType pFn, const char *pName ) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i); StopCall(pName); } + template inline CGLExecuteHelper(FunctionType pFn, const char *pName, A a, B b, C c, D d, E e, F f, G g, H h, I i, J j) : m_pFn( pFn ) { StartCall(pName); (*m_pFn)(a, b, c, d, e, f, g, h, i, j); StopCall(pName); } + + FunctionType m_pFn; +}; +#endif + +template < class FunctionType, typename Result > +class CDynamicFunctionOpenGLBase +{ +public: + // Construct with a NULL function pointer. You must manually call + // Lookup() before you can call a dynamic function through this interface. + CDynamicFunctionOpenGLBase() : m_pFn(NULL) {} + + // Construct and do a lookup right away. You will need to make sure that + // the lookup actually succeeded, as the gl library might have failed to load + // or (fn) might not exist in it. + CDynamicFunctionOpenGLBase(const char *fn, FunctionType fallback=NULL) : m_pFn(NULL) + { + Lookup(fn, fallback); + } + + // Construct and do a lookup right away. See comments in Lookup() about what (okay) does. + CDynamicFunctionOpenGLBase(const char *fn, bool &okay, FunctionType fallback=NULL) : m_pFn(NULL) + { + Lookup(fn, okay, fallback); + } + + // Load library if necessary, look up symbol. Returns true and sets + // m_pFn on successful lookup, returns false otherwise. If the + // function pointer is already looked up, this return true immediately. + // Use Reset() first if you want to look up the symbol again. + // This function will return false immediately unless (okay) is true. + // This allows you to chain lookups like this: + // bool okay = true; + // x.Lookup(lib, "x", okay); + // y.Lookup(lib, "y", okay); + // z.Lookup(lib, "z", okay); + // if (okay) { printf("All functions were loaded successfully!\n"); } + // If you supply a fallback, it'll be used if the lookup fails (and if + // non-NULL, means this will always return (okay)). + bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL) + { + if (!okay) + return false; + else if (this->m_pFn == NULL) + { + this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, false, (void *) fallback); + this->SetFuncName( fn ); + } + okay = m_pFn != NULL; + return okay; + } + + // Load library if necessary, look up symbol. Returns true and sets + // m_pFn on successful lookup, returns false otherwise. If the + // function pointer is already looked up, this return true immediately. + // Use Reset() first if you want to look up the symbol again. + // This function will return false immediately unless (okay) is true. + // If you supply a fallback, it'll be used if the lookup fails (and if + // non-NULL, means this will always return true). + bool Lookup(const char *fn, FunctionType fallback=NULL) + { + bool okay = true; + return Lookup(fn, okay, fallback); + } + + // Invalidates the current lookup. Makes the function pointer NULL. You + // will need to call Lookup() before you can call a dynamic function + // through this interface again. + void Reset() { m_pFn = NULL; } + + // Force this to be a specific function pointer. + void Force(FunctionType ptr) { m_pFn = ptr; } + + // Retrieve the actual function pointer. + FunctionType Pointer() const { return m_pFn; } + +#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS + #if GL_TELEMETRY_ZONES || GL_DUMP_ALL_API_CALLS + #define GL_FUNC_NAME m_szName + #else + #define GL_FUNC_NAME "" + #endif + + inline CGLExecuteHelper operator() () const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME ); } + + template + inline CGLExecuteHelper operator() (T a) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a); } + + template + inline CGLExecuteHelper operator() (T a, U b) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c ) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g, A h) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i); } + + template + inline CGLExecuteHelper operator() (T a, U b, V c, W d, X e, Y f, Z g, A h, B i, C j) const { return CGLExecuteHelper(m_pFn, GL_FUNC_NAME, a, b, c, d, e, f, g, h, i, j); } +#else + operator FunctionType() const { return m_pFn; } +#endif + + // Can be used to verify that we have an actual function looked up and + // ready to call: if (!MyDynFunc) { printf("Function not found!\n"); } + operator bool () const { return m_pFn != NULL; } + bool operator !() const { return m_pFn == NULL; } + +protected: + FunctionType m_pFn; + +#if GL_TELEMETRY_ZONES || GL_DUMP_ALL_API_CALLS + char m_szName[32]; + inline void SetFuncName(const char *pFn) { V_strncpy( m_szName, pFn, sizeof( m_szName ) ); } +#else + inline void SetFuncName(const char *pFn) { (void)pFn; } +#endif +}; + +// This works a lot like CDynamicFunctionMustInit, but we use SDL_GL_GetProcAddress(). +template < const bool bRequired, class FunctionType, typename Result > +class CDynamicFunctionOpenGL : public CDynamicFunctionOpenGLBase< FunctionType, Result > +{ +private: // forbid default constructor. + CDynamicFunctionOpenGL() {} + +public: + CDynamicFunctionOpenGL(const char *fn, FunctionType fallback=NULL) + { + bool okay = true; + Lookup(fn, okay, fallback); + this->SetFuncName( fn ); + } + + CDynamicFunctionOpenGL(const char *fn, bool &okay, FunctionType fallback=NULL) + { + Lookup(fn, okay, fallback); + this->SetFuncName( fn ); + } + + // Please note this is not virtual. + // !!! FIXME: we might want to fall back and try "EXT" or "ARB" versions in some case. + bool Lookup(const char *fn, bool &okay, FunctionType fallback=NULL) + { + if (this->m_pFn == NULL) + { + this->m_pFn = (FunctionType) VoidFnPtrLookup_GlMgr(fn, okay, bRequired, (void *) fallback); + this->SetFuncName( fn ); + } + return okay; + } +}; + +enum GLDriverStrings_t +{ + cGLVendorString, + cGLRendererString, + cGLVersionString, + cGLExtensionsString, + + cGLTotalDriverStrings +}; + +enum GLDriverProvider_t +{ + cGLDriverProviderUnknown, + cGLDriverProviderNVIDIA, + cGLDriverProviderAMD, + cGLDriverProviderIntel, + cGLDriverProviderIntelOpenSource, + cGLDriverProviderApple, + + cGLTotalDriverProviders +}; + +// This provides all the entry points for a given OpenGL context. +// ENTRY POINTS ARE ONLY VALID FOR THE CONTEXT THAT WAS CURRENT WHEN +// YOU LOOKED THEM UP. 99% of the time, this is not a problem, but +// that 1% is really hard to track down. Always access the GL +// through this class! +class COpenGLEntryPoints +{ + COpenGLEntryPoints( const COpenGLEntryPoints & ); + COpenGLEntryPoints &operator= ( const COpenGLEntryPoints & ); + +public: + // The GL context you are looking up entry points for must be current when you construct this object! + COpenGLEntryPoints(); + ~COpenGLEntryPoints(); + + void ClearEntryPoints(); + uint64 m_nTotalGLCycles, m_nTotalGLCalls; + + int m_nOpenGLVersionMajor; // if GL_VERSION is 2.1.0, this will be set to 2. + int m_nOpenGLVersionMinor; // if GL_VERSION is 2.1.0, this will be set to 1. + int m_nOpenGLVersionPatch; // if GL_VERSION is 2.1.0, this will be set to 0. + bool m_bHave_OpenGL; + + char *m_pGLDriverStrings[cGLTotalDriverStrings]; + GLDriverProvider_t m_nDriverProvider; + +#ifdef OSX +#define GL_EXT(x,glmajor,glminor) bool m_bHave_##x; +#define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (*) arg, ret > fn; +#define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (*) arg, void > fn; +#else +#define _APIENTRY __attribute__((pcs("aapcs"))) APIENTRY +#define GL_EXT(x,glmajor,glminor) bool m_bHave_##x; +#define GL_FUNC(ext,req,ret,fn,arg,call) CDynamicFunctionOpenGL< req, ret (_APIENTRY *) arg, ret > fn; +#define GL_FUNC_VOID(ext,req,fn,arg,call) CDynamicFunctionOpenGL< req, void (_APIENTRY *) arg, void > fn; +#endif + #include "togles/glfuncs.inl" + #undef GL_FUNC_VOID + #undef GL_FUNC + #undef GL_EXT + + bool HasSwapTearExtension() const + { +#ifdef _WIN32 + return m_bHave_WGL_EXT_swap_control_tear; +#else + return m_bHave_GLX_EXT_swap_control_tear; +#endif + } +}; + +// This will be set to the current OpenGL context's entry points. +extern COpenGLEntryPoints *gGL; +typedef void * (*GL_GetProcAddressCallbackFunc_t)(const char *, bool &, const bool, void *); + +#ifdef TOGL_DLL_EXPORT + DLL_EXPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory ); + DLL_EXPORT void ToGLDisconnectLibraries(); + DLL_EXPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback); + DLL_EXPORT void ClearOpenGLEntryPoints(); +#else + DLL_IMPORT COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory ); + DLL_IMPORT void ToGLDisconnectLibraries(); + DLL_IMPORT COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback); + DLL_IMPORT void ClearOpenGLEntryPoints(); +#endif + +inline uint64 get_nsecs() +{ + struct timespec time={0,0}; + clock_gettime(CLOCK_MONOTONIC, &time); + return time.tv_nsec; +} + +#if GL_USE_EXECUTE_HELPER_FOR_ALL_API_CALLS +inline void CGLExecuteHelperBase::StartCall(const char *pName) +{ + (void)pName; + m_nStartTime = get_nsecs(); +} + +inline void CGLExecuteHelperBase::StopCall(const char *pName) +{ + if( gGL ) + { + uint64 time = get_nsecs() - m_nStartTime; + printf("Function %s finished in %llu\n", pName, time); + + if( strcmp(pName, "glBufferSubData") == 0 && time > 1000000 ) + DebuggerBreak(); + } +} +#endif + +#endif // DX_TO_GL_ABSTRACTION + +#endif // GLENTRYPOINTS_H diff --git a/public/togles/linuxwin/glfuncs.h b/public/togles/linuxwin/glfuncs.h new file mode 100644 index 00000000..39dfdc87 --- /dev/null +++ b/public/togles/linuxwin/glfuncs.h @@ -0,0 +1,251 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// !!! FIXME: Some of these aren't base OpenGL...pick out the extensions. +// !!! FIXME: Also, look up these -1, -1 versions numbers. + +GL_FUNC(OpenGL,true,GLenum,glGetError,(void),()) +GL_FUNC_VOID(OpenGL,true,glActiveTexture,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glAlphaFunc,(GLenum a,GLclampf b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glAttachShader,(GLuint a, GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBindAttribLocation,(GLuint a,GLuint b,const GLchar *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glBindBuffer,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBindTexture,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBlendColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glBlendEquation,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glBlendFunc,(GLenum a,GLenum b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glBufferData,(GLenum a, GLsizeiptr b, const GLvoid *c,GLenum d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glClear,(GLbitfield a),(a)) +GL_FUNC_VOID(OpenGL,true,glClearColor,(GLclampf a,GLclampf b,GLclampf c,GLclampf d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glReadPixels, (GLint a, GLint b, GLsizei c, GLsizei d, GLenum e, GLenum f, void * g), (a,b,c,d,e,f,g)) +GL_FUNC_VOID(OpenGL,true,glClearStencil,(GLint a),(a)) +GL_FUNC_VOID(OpenGL,true,glColorMask,(GLboolean a,GLboolean b,GLboolean c,GLboolean d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glCompileShader,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glGetShaderiv,(GLuint a, GLenum b, GLint *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glGetShaderInfoLog,(GLuint a, GLsizei b, GLsizei *c, GLchar *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glGetProgramInfoLog,(GLuint a, GLsizei b, GLsizei *c, GLchar *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glCompressedTexImage2D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLint f,GLsizei g,const GLvoid *h),(a,b,c,d,e,f,g,h)) +GL_FUNC_VOID(OpenGL,true,glCompressedTexImage3D,(GLenum a,GLint b,GLenum c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLsizei h,const GLvoid *i),(a,b,c,d,e,f,g,h,i)) +GL_FUNC(OpenGL,true,GLuint,glCreateProgram,(void),()) +GL_FUNC(OpenGL,true,GLuint,glCreateShader,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDeleteBuffers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDeleteProgram,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glDeleteShader,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glDeleteTextures,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDepthFunc,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDepthMask,(GLboolean a),(a)) +GL_FUNC_VOID(OpenGL,true,glDisable,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glDisableVertexAttribArray,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glDrawArrays,(GLenum a,GLint b,GLsizei c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glDrawBuffers,(GLsizei a,const GLenum *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDetachShader,(GLuint a,GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glDrawRangeElements,(GLenum a,GLuint b,GLuint c,GLsizei d,GLenum e,const GLvoid *f),(a,b,c,d,e,f)) +GL_FUNC_VOID(OpenGL,true,glGetSynciv,(GLsync a, GLenum b, GLsizei c, GLsizei *d, GLint *e),(a,b,c,d,e)) +GL_FUNC(OpenGL,true,GLenum,glClientWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glWaitSync,(GLsync a, GLbitfield b, GLuint64 c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glDeleteSync,(GLsync a),(a)) +GL_FUNC(OpenGL,true,GLsync,glFenceSync,(GLenum a, GLbitfield b),(a,b)) + +#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)) +#endif +GL_FUNC_VOID(OpenGL,true,glEnable,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glEnableVertexAttribArray,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glFinish,(void),()) +GL_FUNC_VOID(OpenGL,true,glFlush,(void),()) +GL_FUNC_VOID(OpenGL,true,glFrontFace,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glGenBuffers,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGenTextures,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGetBooleanv,(GLenum a,GLboolean *b),(a,b)) +//GL_FUNC_VOID(OpenGL,true,glGetInfoLog,(GLuint a,GLsizei b,GLsizei *c,GLchar *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glGetIntegerv,(GLenum a,GLint *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glGetProgramiv,(GLenum a,GLenum b,GLint *c),(a,b,c)) +GL_FUNC(OpenGL,true,const GLubyte *,glGetString,(GLenum a),(a)) +GL_FUNC(OpenGL,true,GLint,glGetUniformLocation,(GLuint a,const GLchar *b),(a,b)) +GL_FUNC(OpenGL,true,GLboolean,glIsEnabled,(GLenum a),(a)) +GL_FUNC(OpenGL,true,GLboolean,glIsTexture,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glLinkProgram,(GLuint a),(a)) +//GL_FUNC_VOID(OpenGL,true,glOrtho,(GLdouble a,GLdouble b,GLdouble c,GLdouble d,GLdouble e,GLdouble f),(a,b,c,d,e,f)) +GL_FUNC_VOID(OpenGL,true,glPixelStorei,(GLenum a,GLint b),(a,b)) +//GL_FUNC_VOID(OpenGL,true,glPolygonMode,(GLenum a,GLenum b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glReadBuffer,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glScissor,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glShaderSource,(GLuint a,GLsizei b,const GLchar **c,const GLint *d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glStencilFunc,(GLenum a,GLint b,GLuint c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glStencilMask,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glStencilOp,(GLenum a,GLenum b,GLenum c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glTexImage2D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLint f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i)) +GL_FUNC_VOID(OpenGL,true,glTexImage3D,(GLenum a,GLint b,GLint c,GLsizei d,GLsizei e,GLsizei f,GLint g,GLenum h,GLenum i,const GLvoid *j),(a,b,c,d,e,f,g,h,i,j)) +GL_FUNC_VOID(OpenGL,true,glTexParameteri,(GLenum a,GLenum b,GLint c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glTexSubImage2D,(GLenum a,GLint b,GLint c,GLint d,GLsizei e,GLsizei f,GLenum g,GLenum h,const GLvoid *i),(a,b,c,d,e,f,g,h,i)) +GL_FUNC_VOID(OpenGL,true,glUniform1i,(GLint a,GLint b),(a,b)) +GL_FUNC(OpenGL,true,GLboolean,glUnmapBuffer,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glUseProgram,(GLuint a),(a)) +GL_FUNC_VOID(OpenGL,true,glVertexAttribPointer,(GLuint a,GLint b,GLenum c,GLboolean d,GLsizei e,const GLvoid *f),(a,b,c,d,e,f)) +GL_FUNC_VOID(OpenGL,true,glViewport,(GLint a,GLint b,GLsizei c,GLsizei d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glClientActiveTexture,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,true,glStencilOpSeparate,(GLenum a,GLenum b,GLenum c,GLenum d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glStencilFuncSeparate,(GLenum a,GLenum b,GLint c,GLuint d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glGetTexLevelParameteriv,(GLenum a,GLint b,GLenum c,GLint *d),(a,b,c,d)) +GL_EXT(GL_EXT_framebuffer_object,-1,-1) +GL_EXT(GL_EXT_framebuffer_blit,-1,-1) +GL_EXT(GL_APPLE_fence,-1,-1) +GL_FUNC(GL_APPLE_fence,false,GLboolean,glTestFenceAPPLE,(GLuint a),(a)) +GL_FUNC_VOID(GL_APPLE_fence,false,glSetFenceAPPLE,(GLuint a),(a)) +GL_FUNC_VOID(GL_APPLE_fence,false,glFinishFenceAPPLE,(GLuint a),(a)) +GL_FUNC_VOID(GL_APPLE_fence,false,glDeleteFencesAPPLE,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_APPLE_fence,false,glGenFencesAPPLE,(GLsizei a,GLuint *b),(a,b)) +GL_EXT(GL_NV_fence,-1,-1) +GL_FUNC(GL_NV_fence,false,GLboolean,glTestFenceNV,(GLuint a),(a)) +GL_FUNC_VOID(GL_NV_fence,false,glSetFenceNV,(GLuint a,GLenum b),(a,b)) +GL_FUNC_VOID(GL_NV_fence,false,glFinishFenceNV,(GLuint a),(a)) +GL_FUNC_VOID(GL_NV_fence,false,glDeleteFencesNV,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_NV_fence,false,glGenFencesNV,(GLsizei a,GLuint *b),(a,b)) +GL_EXT(GL_ARB_sync,3,2) +//#ifdef HAVE_GL_ARB_SYNC +//#endif +GL_EXT(GL_EXT_bindable_uniform,-1,-1) +GL_FUNC_VOID(GL_EXT_bindable_uniform,false,glUniformBufferEXT,(GLuint a,GLint b,GLuint c),(a,b,c)) +GL_FUNC(GL_EXT_bindable_uniform,false,int,glGetUniformBufferSizeEXT,(GLenum a, GLenum b),(a,b)) +GL_FUNC(GL_EXT_bindable_uniform,false,GLintptr,glGetUniformOffsetEXT,(GLenum a, GLenum b),(a,b)) +GL_EXT(GL_APPLE_flush_buffer_range,-1,-1) +GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glBufferParameteriAPPLE,(GLenum a,GLenum b,GLint c),(a,b,c)) +GL_FUNC_VOID(GL_APPLE_flush_buffer_range,false,glFlushMappedBufferRangeAPPLE,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c)) +GL_EXT(GL_ARB_map_buffer_range,-1,-1) +GL_FUNC(OpenGL,false,void*,glMapBufferRange,(GLenum a,GLintptr b,GLsizeiptr c,GLbitfield d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,false,glFlushMappedBufferRange,(GLenum a,GLintptr b,GLsizeiptr c),(a,b,c)) +GL_EXT(GL_ARB_vertex_buffer_object,-1,-1) +GL_FUNC_VOID(OpenGL,true,glBufferSubData,(GLenum a,GLintptr b,GLsizeiptr c,const GLvoid *d),(a,b,c,d)) +GL_EXT(GL_ARB_occlusion_query,-1,-1) +GL_FUNC_VOID(OpenGL,false,glGetQueryObjectuiv,(GLuint a,GLenum b,GLuint *c),(a,b,c)) +GL_EXT(GL_APPLE_texture_range,-1,-1) +GL_FUNC_VOID(GL_APPLE_texture_range,false,glTextureRangeAPPLE,(GLenum a,GLsizei b,void *c),(a,b,c)) +GL_FUNC_VOID(GL_APPLE_texture_range,false,glGetTexParameterPointervAPPLE,(GLenum a,GLenum b,void* *c),(a,b,c)) +GL_EXT(GL_APPLE_client_storage,-1,-1) +GL_EXT(GL_ARB_uniform_buffer,-1,-1) +GL_EXT(GL_ARB_vertex_array_bgra,-1,-1) +GL_EXT(GL_EXT_vertex_array_bgra,-1,-1) +GL_EXT(GL_EXT_framebuffer_multisample_blit_scaled,-1,-1) + +GL_EXT(GL_ARB_framebuffer_object,3,0) +/*GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindFramebuffer,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBindRenderbuffer,(GLenum a,GLuint b),(a,b)) +GL_FUNC(GL_ARB_framebuffer_object,false,GLenum,glCheckFramebufferStatus,(GLenum a),(a)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteRenderbuffers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferRenderbuffer,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture2D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glFramebufferTexture3D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenFramebuffers,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glGenRenderbuffers,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glDeleteFramebuffers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glBlitFramebuffer,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j)) +GL_FUNC_VOID(GL_ARB_framebuffer_object,false,glRenderbufferStorageMultisample,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e)) +*/ +GL_FUNC_VOID(OpenGL,false,glBindFramebuffer,(GLenum a,GLuint b),(a,b)) +GL_FUNC_VOID(OpenGL,false,glBindRenderbuffer,(GLenum a,GLuint b),(a,b)) +GL_FUNC(OpenGL,false,GLenum,glCheckFramebufferStatus,(GLenum a),(a)) +GL_FUNC_VOID(OpenGL,false,glDeleteRenderbuffers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,false,glFramebufferRenderbuffer,(GLenum a,GLenum b,GLenum c,GLuint d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,false,glFramebufferTexture2D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e),(a,b,c,d,e)) +GL_FUNC_VOID(OpenGL,false,glFramebufferTexture3D,(GLenum a,GLenum b,GLenum c,GLuint d,GLint e,GLint f),(a,b,c,d,e,f)) +GL_FUNC_VOID(OpenGL,true,glGenFramebuffers,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,false,glGenRenderbuffers,(GLsizei a,GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,false,glDeleteFramebuffers,(GLsizei a,const GLuint *b),(a,b)) +GL_FUNC_VOID(OpenGL,false,glBlitFramebuffer,(GLint a,GLint b,GLint c,GLint d,GLint e,GLint f,GLint g,GLint h,GLbitfield i,GLenum j),(a,b,c,d,e,f,g,h,i,j)) +GL_FUNC_VOID(OpenGL,false,glRenderbufferStorageMultisample,(GLenum a,GLsizei b,GLenum c,GLsizei d,GLsizei e),(a,b,c,d,e)) + +GL_EXT(GL_GREMEDY_string_marker,-1,-1) +GL_FUNC_VOID(GL_GREMEDY_string_marker,false,glStringMarkerGREMEDY,(GLsizei a,const void *b),(a,b)) +GL_EXT(GL_ARB_debug_output,-1,-1) +GL_FUNC_VOID(OpenGL,false,glDebugMessageCallback,(void (APIENTRY *a)(GLenum, GLenum , GLuint , GLenum , GLsizei , const GLchar* , GLvoid*) ,void* b),(a,b)) +GL_FUNC_VOID(OpenGL,false,glDebugMessageControl,(GLenum a, GLenum b, GLenum c, GLsizei d, const GLuint* e, GLboolean f),(a,b,c,d,e,f)) + +GL_EXT(GL_EXT_direct_state_access,-1,-1) +GL_FUNC_VOID(GL_EXT_direct_state_access,false,glBindMultiTextureEXT,(GLenum a,GLuint b, GLuint c),(a,b,c)) +GL_EXT(GL_NV_bindless_texture,-1,-1) + +#ifndef OSX +GL_FUNC_VOID(OpenGL, true, glGenSamplers, (GLuint a, GLuint *b), (a, b)) +GL_FUNC_VOID(OpenGL, true, glDeleteSamplers, (GLsizei a, const GLuint *b), (a, b)) +GL_FUNC_VOID(OpenGL, true, glBindSampler, (GLuint a, GLuint b), (a, b)) +GL_FUNC_VOID(OpenGL, true, glSamplerParameteri, (GLuint a, GLenum b, GLint c), (a, b, c)) +/*GL_FUNC(GL_NV_bindless_texture, false, GLuint64, glGetTextureHandleNV, (GLuint texture), (texture)) +GL_FUNC(GL_NV_bindless_texture, false, GLuint64, glGetTextureSamplerHandleNV, (GLuint texture, GLuint sampler), (texture, sampler)) +GL_FUNC_VOID(GL_NV_bindless_texture, false, glMakeTextureHandleResidentNV, (GLuint64 handle), (handle)) +GL_FUNC_VOID(GL_NV_bindless_texture, false, glMakeTextureHandleNonResidentNV, (GLuint64 handle), (handle)) +GL_FUNC_VOID(GL_NV_bindless_texture, false, glUniformHandleui64NV, (GLint location, GLuint64 value), (location, value)) +GL_FUNC_VOID(GL_NV_bindless_texture, false, glUniformHandleui64vNV, (int location, GLsizei count, const GLuint64 *value), (location count, value)) +GL_FUNC_VOID(GL_NV_bindless_texture, false, glProgramUniformHandleui64NV, (GLuint program, GLint location, GLuint64 value), (program, location, value)) +GL_FUNC_VOID(GL_NV_bindless_texture, false, glProgramUniformHandleui64vNV, (GLuint program, GLint location, GLsizei count, const GLuint64 *values), (program, location, count, values)) +GL_FUNC(GL_NV_bindless_texture, false, GLboolean, glIsTextureHandleResidentNV, (GLuint64 handle), (handle))*/ +GL_FUNC_VOID(OpenGL,true,glGenQueries,(GLsizei n, GLuint *ids), (n, ids)) +GL_FUNC_VOID(OpenGL,true,glDeleteQueries,(GLsizei n, const GLuint *ids),(n, ids)) +GL_FUNC_VOID(OpenGL,true,glBeginQuery,(GLenum target, GLuint id), (target, id)) +GL_FUNC_VOID(OpenGL,true,glEndQuery,(GLenum target), (target)) +GL_FUNC_VOID(OpenGL,true,glCopyBufferSubData,(GLenum readtarget, GLenum writetarget, GLintptr readoffset, GLintptr writeoffset, GLsizeiptr size),(readtarget, writetarget, readoffset, writeoffset, size)) +#endif // !OSX + +GL_EXT(GL_AMD_pinned_memory,-1,-1) + +#ifndef OSX +GL_FUNC_VOID(OpenGL,true,glGenVertexArrays,(GLsizei n, GLuint *arrays),(n, arrays)) +GL_FUNC_VOID(OpenGL,true,glDeleteVertexArrays,(GLsizei n, GLuint *arrays),(n, arrays)) +GL_FUNC_VOID(OpenGL,true,glBindVertexArray,(GLuint a),(a)) +#endif // !OSX + +GL_EXT(GL_QCOM_alpha_test,-1,-1) + + +GL_EXT(GL_EXT_texture_sRGB_decode,-1,-1) +GL_EXT(GL_NVX_gpu_memory_info,-1,-1) +GL_EXT(GL_ATI_meminfo,-1,-1) +GL_EXT(GL_EXT_texture_compression_s3tc,-1,-1) +GL_EXT(GL_EXT_texture_compression_dxt1,-1,-1) +GL_EXT(GL_ANGLE_texture_compression_dxt3,-1,-1) +GL_EXT(GL_ANGLE_texture_compression_dxt5,-1,-1) + +GL_EXT( GL_EXT_color_buffer_half_float, -1, -1 ) +GL_EXT( GL_EXT_texture_norm16, -1, -1 ) +GL_EXT( GL_EXT_buffer_storage, -1, -1 ) +GL_FUNC_VOID( GL_EXT_buffer_storage, false, glBufferStorageEXT, (GLenum target, GLsizeiptr size, const void *data, GLbitfield flags), (target, size, data, flags) ) +//GL_FUNC_VOID(OpenGL, false,glGetTexImage,(GLenum a,GLint b,GLenum c,GLenum d,GLvoid *e),(a,b,c,d,e)) + + +// This one is an OS extension. We'll add a little helper function to look for it. +#ifdef _WIN32 + GL_EXT(WGL_EXT_swap_control_tear,-1,-1) +#else + GL_EXT(GLX_EXT_swap_control_tear,-1,-1) +#endif + +GL_FUNC_VOID(OpenGL,true,glGetFloatv,(GLenum a,GLfloat *b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glPolygonOffset,(GLfloat a,GLfloat b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glTexParameterfv,(GLenum a,GLenum b,const GLfloat *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glUniform1f,(GLint a,GLfloat b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glUniform4fv,(GLint a,GLsizei b,const GLfloat *c),(a,b,c)) +GL_FUNC_VOID(OpenGL,true,glColor4f,(GLfloat a,GLfloat b,GLfloat c,GLfloat d),(a,b,c,d)) +GL_FUNC_VOID(OpenGL,true,glSamplerParameterf,(GLuint a, GLenum b, GLfloat c), (a, b, c)) +GL_FUNC_VOID(OpenGL,true,glSamplerParameterfv,(GLuint a, GLenum b, const GLfloat *c), (a, b, c)) +GL_FUNC_VOID(GL_QCOM_alpha_test,false,glAlphaFuncQCOM,(GLenum a, GLfloat b),(a,b)) +GL_FUNC_VOID(OpenGL,true,glClearDepthf,(GLfloat a),(a)) +GL_FUNC_VOID(OpenGL,true,glDepthRangef,(GLfloat a,GLfloat b),(a,b)) diff --git a/public/togles/linuxwin/glmdebug.h b/public/togles/linuxwin/glmdebug.h new file mode 100644 index 00000000..f73e28a1 --- /dev/null +++ b/public/togles/linuxwin/glmdebug.h @@ -0,0 +1,180 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +#ifndef GLMDEBUG_H +#define GLMDEBUG_H + +#include "tier0/platform.h" +#if defined( OSX ) +#include +#endif + +// include this anywhere you need to be able to compile-out code related specifically to GLM debugging. + +// we expect DEBUG to be driven by the build system so you can include this header anywhere. +// when we come out, GLMDEBUG will be defined to a value - 0, 1, or 2 +// 0 means no GLM debugging is possible +// 1 means it's possible and resulted from being a debug build +// 2 means it's possible and resulted from being manually forced on for a release build + +#ifdef POSIX + #ifndef GLMDEBUG + #ifdef DEBUG + #define GLMDEBUG 1 // normally 1 here, testing + #else + // #define GLMDEBUG 2 // don't check this in enabled.. + #endif + + #ifndef GLMDEBUG + #define GLMDEBUG 0 + #endif + #endif +#else + #ifndef GLMDEBUG + #define GLMDEBUG 0 + #endif +#endif + +//=============================================================================== +// debug channels + +enum EGLMDebugChannel +{ + ePrintf, + eDebugger, + eGLProfiler +}; + +#if GLMDEBUG + // make all these prototypes disappear in non GLMDEBUG + void GLMDebugInitialize( bool forceReinit=false ); + + bool GLMDetectOGLP( void ); + bool GLMDetectGDB( void ); + uint GLMDetectAvailableChannels( void ); + + uint GLMDebugChannelMask( uint *newValue = NULL ); + // note that GDB and OGLP can both come and go during run - forceCheck will allow that to be detected. + // mask returned is in form of 1< < + eComment, // 3 one off messages --- + eMatrixData, // 4 matrix data -M- + eShaderData, // 5 shader data (params) -S- + eFrameBufData, // 6 FBO data (attachments) -F- + eDXStuff, // 7 dxabstract spew -X- + eAllocations, // 8 tracking allocs and frees -A- + eSlowness, // 9 slow things happening (srgb flips..) -Z- + eDefaultFlavor, // not specified (no marker) + eFlavorCount +}; +uint GLMDebugFlavorMask( uint *newValue = NULL ); + +// make all these prototypes disappear in non GLMDEBUG +#if GLMDEBUG + // these are unconditional outputs, they don't interrogate the string + void GLMStringOut( const char *string ); + void GLMStringOutIndented( const char *string, int indentColumns ); + + #ifdef TOGL_DLL_EXPORT + // these will look at the string to guess its flavor: <, >, ---, -M-, -S- + DLL_EXPORT void GLMPrintfVA( const char *fmt, va_list vargs ); + DLL_EXPORT void GLMPrintf( const char *fmt, ... ); + #else + DLL_IMPORT void GLMPrintfVA( const char *fmt, va_list vargs ); + DLL_IMPORT void GLMPrintf( const char *fmt, ... ); + #endif + + // these take an explicit flavor with a default value + void GLMPrintStr( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor ); + + #define GLMPRINTTEXT_NUMBEREDLINES 0x80000000 + void GLMPrintText( const char *str, EGLMDebugFlavor flavor = eDefaultFlavor, uint options=0 ); // indent each newline + + int GLMIncIndent( int indentDelta ); + int GLMGetIndent( void ); + void GLMSetIndent( int indent ); + +#endif + +// helpful macro if you are in a position to call GLM functions directly (i.e. you live in materialsystem / shaderapidx9) +#if GLMDEBUG + #define GLMPRINTF(args) GLMPrintf args + #define GLMPRINTSTR(args) GLMPrintStr args + #define GLMPRINTTEXT(args) GLMPrintText args +#else + #define GLMPRINTF(args) + #define GLMPRINTSTR(args) + #define GLMPRINTTEXT(args) +#endif + + +//=============================================================================== +// knob twiddling +#ifdef TOGL_DLL_EXPORT + DLL_EXPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value + DLL_EXPORT float GLMKnobToggle( char *knobname ); +#else + DLL_IMPORT float GLMKnob( char *knobname, float *setvalue ); // Pass NULL to not-set the knob value + DLL_IMPORT float GLMKnobToggle( char *knobname ); +#endif + +//=============================================================================== +// other stuff + +#if GLMDEBUG +void GLMTriggerDebuggerBreak(); +inline void GLMDebugger( void ) +{ + if (GLMDebugChannelMask() & (1< +#include +#include +#include +#include +#endif + +#ifdef MAC_OS_X_VERSION_10_9 +typedef uint32_t CGDirectDisplayID; +typedef uint32_t CGOpenGLDisplayMask; +typedef double CGRefreshRate; +#endif + +typedef void _PseudoNSGLContext; // aka NSOpenGLContext +typedef _PseudoNSGLContext *PseudoNSGLContextPtr; + +struct GLMDisplayModeInfoFields +{ + uint m_modePixelWidth; + uint m_modePixelHeight; + uint m_modeRefreshHz; + // are we even going to talk about bit depth... not yet +}; + +struct GLMDisplayInfoFields +{ +#ifdef OSX + CGDirectDisplayID m_cgDisplayID; + CGOpenGLDisplayMask m_glDisplayMask; // result of CGDisplayIDToOpenGLDisplayMask on the cg_displayID. +#endif + uint m_displayPixelWidth; + uint m_displayPixelHeight; +}; + +struct GLMRendererInfoFields +{ + /*properties of interest and their desired values. + + kCGLRPFullScreen = 54, true + kCGLRPAccelerated = 73, true + kCGLRPWindow = 80, true + + kCGLRPRendererID = 70, informational + kCGLRPDisplayMask = 84, informational + kCGLRPBufferModes = 100, informational + kCGLRPColorModes = 103, informational + kCGLRPAccumModes = 104, informational + kCGLRPDepthModes = 105, informational + kCGLRPStencilModes = 106, informational + kCGLRPMaxAuxBuffers = 107, informational + kCGLRPMaxSampleBuffers = 108, informational + kCGLRPMaxSamples = 109, informational + kCGLRPSampleModes = 110, informational + kCGLRPSampleAlpha = 111, informational + kCGLRPVideoMemory = 120, informational + kCGLRPTextureMemory = 121, informational + kCGLRPRendererCount = 128 number of renderers in the CGLRendererInfoObj under examination + + kCGLRPOffScreen = 53, D/C + kCGLRPRobust = 75, FALSE or D/C - aka we're asking for no-fallback + kCGLRPBackingStore = 76, D/C + kCGLRPMPSafe = 78, D/C + kCGLRPMultiScreen = 81, D/C + kCGLRPCompliant = 83, D/C + */ + + + //--------------------------- info we have from CGL renderer queries, IOKit, Gestalt + //--------------------------- these are set up in the displayDB by CocoaMgr + GLint m_fullscreen; + GLint m_accelerated; + GLint m_windowed; + + GLint m_rendererID; + GLint m_displayMask; + GLint m_bufferModes; + GLint m_colorModes; + GLint m_accumModes; + GLint m_depthModes; + GLint m_stencilModes; + + GLint m_maxAuxBuffers; + GLint m_maxSampleBuffers; + GLint m_maxSamples; + GLint m_sampleModes; + GLint m_sampleAlpha; + + GLint m_vidMemory; + GLint m_texMemory; + + uint m_pciVendorID; + uint m_pciDeviceID; + char m_pciModelString[64]; + char m_driverInfoString[64]; + + //--------------------------- OS version related - set up by CocoaMgr + + // OS version found + uint m_osComboVersion; // 0x00XXYYZZ : XX major, YY minor, ZZ minor minor : 10.6.3 --> 0x000A0603. 10.5.8 --> 0x000A0508. + + //--------------------------- shorthands - also set up by CocoaMgr - driven by vendorid / deviceid + + bool m_ati; + bool m_atiR5xx; + bool m_atiR6xx; + bool m_atiR7xx; + bool m_atiR8xx; + bool m_atiNewer; + + bool m_intel; + bool m_intel95x; + bool m_intel3100; + bool m_intelHD4000; + + bool m_nv; + bool m_nvG7x; + bool m_nvG8x; + bool m_nvNewer; + + //--------------------------- context query results - left blank in the display DB - but valid in a GLMContext (call ctx->Caps() to get a const ref) + + // booleans + bool m_hasGammaWrites; // aka glGetBooleanv(GL_FRAMEBUFFER_SRGB_CAPABLE_EXT) / glEnable(GL_FRAMEBUFFER_SRGB_EXT) + bool m_hasMixedAttachmentSizes; // aka ARB_fbo in 10.6.3 - test for min OS vers, then exported ext string + bool m_hasBGRA; // aka GL_BGRA vertex attribs in 10.6.3 - - test for min OS vers, then exported ext string + bool m_hasNewFullscreenMode; // aka 10.6.x "big window" fullscreen mode + bool m_hasNativeClipVertexMode; // aka GLSL gl_ClipVertex does not fall back to SW- OS version and folklore-based + bool m_hasOcclusionQuery; // occlusion query: do you speak it ?! + bool m_hasFramebufferBlit; // framebuffer blit: know what I'm sayin?! + bool m_hasPerfPackage1; // means new MTGL, fast OQ, fast uniform upload, NV can resolve flipped (late summer 2010 post 10.6.4 update) + + // counts + int m_maxAniso; // aniso limit - context query + + // other exts + bool m_hasBindableUniforms; + int m_maxVertexBindableUniforms; + int m_maxFragmentBindableUniforms; + int m_maxBindableUniformSize; + + bool m_hasUniformBuffers; + + // runtime options that aren't negotiable once set + bool m_hasDualShaders; // must supply CLI arg "-glmdualshaders" or we go GLSL only + + //--------------------------- " can'ts " - specific problems that need to be worked around + + bool m_cantBlitReliably; // Intel chipsets have problems blitting sRGB sometimes + bool m_cantAttachSRGB; // NV G8x on 10.5.8 can't have srgb tex on FBO color - separate issue from hasGammaWrites + bool m_cantResolveFlipped; // happens on NV in 10.6.4 and prior - console variable "gl_can_resolve_flipped" can overrule + bool m_cantResolveScaled; // happens everywhere per GL spec but may be relaxed some day - console variable "gl_can_resolve_scaled" can overrule + bool m_costlyGammaFlips; // this means that sRGB sampling state affects shader code gen, resulting in state-dependent code regen + + + //--------------------------- " bads " - known bad drivers + bool m_badDriver1064NV; // this is the bad NVIDIA driver on 10.6.4 - stutter, tex corruption, black screen issues + bool m_badDriver108Intel; // this is the bad Intel HD4000 driver on 10.8 - intermittent crash on GLSL compilation. +}; + + + +#endif diff --git a/public/togles/linuxwin/glmdisplaydb.h b/public/togles/linuxwin/glmdisplaydb.h new file mode 100644 index 00000000..2c21b9a5 --- /dev/null +++ b/public/togles/linuxwin/glmdisplaydb.h @@ -0,0 +1,157 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +#ifndef GLMDISPLAYDB_H +#define GLMDISPLAYDB_H + +#include "tier1/utlvector.h" + +//=============================================================================== +// modes, displays, and renderers +//=============================================================================== + +// GLMDisplayModeInfoFields is in glmdisplay.h + +class GLMDisplayMode +{ +public: + GLMDisplayModeInfoFields m_info; + + GLMDisplayMode( uint width, uint height, uint refreshHz ); + GLMDisplayMode() { }; + ~GLMDisplayMode( void ); + + void Init( uint width, uint height, uint refreshHz ); + void Dump( int which ); +}; + +//=============================================================================== + +// GLMDisplayInfoFields is in glmdisplay.h + +class GLMDisplayInfo +{ +public: + GLMDisplayInfoFields m_info; + CUtlVector< GLMDisplayMode* > *m_modes; // starts out NULL, set by PopulateModes + GLMDisplayMode m_DesktopMode; + +#ifdef OSX + GLMDisplayInfo( CGDirectDisplayID displayID, CGOpenGLDisplayMask displayMask ); +#else + GLMDisplayInfo( void ); +#endif + + ~GLMDisplayInfo( void ); + + void PopulateModes( void ); + + void Dump( int which ); + +#ifdef OSX +private: + int m_display; +#endif +}; + +//=============================================================================== + +// GLMRendererInfoFields is in glmdisplay.h + +class GLMRendererInfo +{ +public: + GLMRendererInfoFields m_info; +#ifdef OSX + CUtlVector< GLMDisplayInfo* > *m_displays; // starts out NULL, set by PopulateDisplays +#else + GLMDisplayInfo *m_display; +#endif + +#ifdef OSX + GLMRendererInfo ( GLMRendererInfoFields *info ); +#else + GLMRendererInfo (); +#endif + ~GLMRendererInfo ( void ); + +#ifndef OSX + void Init( GLMRendererInfoFields *info ); +#endif + void PopulateDisplays(); + void Dump( int which ); +}; + +//=============================================================================== + +#ifdef OSX +// this is just a tuple describing fake adapters which are really renderer/display pairings. +// dxabstract bridges the gap between the d3d adapter-centric world and the GL renderer+display world. +// this makes it straightforward to handle cases like two video cards with two displays on one, and one on the other - +// you get three fake adapters which represent each useful screen. + +// the constraint that dxa will have to follow though, is that if the user wants to change their +// display selection for full screen, they would only be able to pick on that has the same underlying renderer. +// can't change fakeAdapter from one to another with different GL renderer under it. Screen hop but no card hop. + +struct GLMFakeAdapter +{ + int m_rendererIndex; + int m_displayIndex; +}; +#endif + +class GLMDisplayDB +{ +public: +#ifdef OSX + CUtlVector< GLMRendererInfo* > *m_renderers; // starts out NULL, set by PopulateRenderers + CUtlVector< GLMFakeAdapter > m_fakeAdapters; +#else + GLMRendererInfo m_renderer; +#endif + + GLMDisplayDB ( void ); + ~GLMDisplayDB ( void ); + + virtual void PopulateRenderers( void ); + virtual void PopulateFakeAdapters( uint realRendererIndex ); // fake adapters = one real adapter times however many displays are on it + virtual void Populate( void ); + + // The info-get functions return false on success. + virtual int GetFakeAdapterCount( void ); + virtual bool GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut ); + + virtual int GetRendererCount( void ); + virtual bool GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut ); + + virtual int GetDisplayCount( int rendererIndex ); + virtual bool GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut ); + + virtual int GetModeCount( int rendererIndex, int displayIndex ); + virtual bool GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut ); + + virtual void Dump( void ); +}; + +#endif // GLMDISPLAYDB_H diff --git a/public/togles/linuxwin/glmgr.h b/public/togles/linuxwin/glmgr.h new file mode 100644 index 00000000..d3179776 --- /dev/null +++ b/public/togles/linuxwin/glmgr.h @@ -0,0 +1,2339 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glmgr.h +// singleton class, common basis for managing GL contexts +// responsible for tracking adapters and contexts +// +//=============================================================================== + +#ifndef GLMGR_H +#define GLMGR_H + +#pragma once + +#undef HAVE_GL_ARB_SYNC +#ifndef OSX +#define HAVE_GL_ARB_SYNC 1 +#endif + +#include "glbase.h" +#include "glentrypoints.h" +#include "glmdebug.h" +#include "glmdisplay.h" +#include "glmgrext.h" +#include "glmgrbasics.h" +#include "cglmtex.h" +#include "cglmfbo.h" +#include "cglmprogram.h" +#include "cglmbuffer.h" +#include "cglmquery.h" + +#include "tier0/tslist.h" +#include "tier0/vprof_telemetry.h" +#include "materialsystem/IShader.h" +#include "dxabstract_types.h" +#include "tier0/icommandline.h" + +#undef FORCEINLINE +#define FORCEINLINE inline + +//=============================================================================== + +#define GLM_OPENGL_VENDOR_ID 1 +#define GLM_OPENGL_DEFAULT_DEVICE_ID 1 +#define GLM_OPENGL_LOW_PERF_DEVICE_ID 2 + +#define GL_ALPHA_TEST_QCOM 0x0BC0 +#define GL_ALPHA_TEST_FUNC_QCOM 0x0BC1 +#define GL_ALPHA_TEST_REF_QCOM 0x0BC2 + +extern void GLMDebugPrintf( const char *pMsg, ... ); + +extern uint g_nTotalDrawsOrClears, g_nTotalVBLockBytes, g_nTotalIBLockBytes; + +#if GL_TELEMETRY_GPU_ZONES +struct TelemetryGPUStats_t +{ + uint m_nTotalBufferLocksAndUnlocks; + uint m_nTotalTexLocksAndUnlocks; + uint m_nTotalBlit2; + uint m_nTotalResolveTex; + uint m_nTotalPresent; + + inline void Clear() { memset( this, 0, sizeof( *this ) ); } + inline uint GetTotal() const { return m_nTotalBufferLocksAndUnlocks + m_nTotalTexLocksAndUnlocks + m_nTotalBlit2 + m_nTotalResolveTex + m_nTotalPresent; } +}; +extern TelemetryGPUStats_t g_TelemetryGPUStats; +#endif + +struct GLMRect; +typedef void *PseudoGLContextPtr; + +// parrot the D3D present parameters, more or less... "adapter" translates into "active display index" per the m_activeDisplayCount below. +class GLMDisplayParams +{ + public: + + // presumption, these indices are in sync with the current display DB that GLMgr has handy + //int m_rendererIndex; // index of renderer (-1 if root context) + //int m_displayIndex; // index of display in renderer - for FS + //int m_modeIndex; // index of mode in display - for FS + + void *m_focusWindow; // (VD3DHWND aka WindowRef) - what window does this context display into + + bool m_fsEnable; // fullscreen on or not + bool m_vsyncEnable; // vsync on or not + + // height and width have to match the display mode info if full screen. + + uint m_backBufferWidth; // pixel width (aka screen h-resolution if full screen) + uint m_backBufferHeight; // pixel height (aka screen v-resolution if full screen) + D3DFORMAT m_backBufferFormat; // pixel format + uint m_multiSampleCount; // 0 means no MSAA, 2 means 2x MSAA, etc + // uint m_multiSampleQuality; // no MSAA quality control yet + + bool m_enableAutoDepthStencil; // generally set to 'TRUE' per CShaderDeviceDx8::SetPresentParameters + D3DFORMAT m_autoDepthStencilFormat; + + uint m_fsRefreshHz; // if full screen, this refresh rate (likely 0 for LCD's) + + //uint m_rootRendererID; // only used if m_rendererIndex is -1. + //uint m_rootDisplayMask; // only used if m_rendererIndex is -1. + + bool m_mtgl; // enable multi threaded GL driver +}; + +//=============================================================================== + +class GLMgr +{ +public: + + //=========================================================================== + // class methods - singleton + static void NewGLMgr( void ); // instantiate singleton.. + static GLMgr *aGLMgr( void ); // return singleton.. + static void DelGLMgr( void ); // tear down singleton.. + + //=========================================================================== + // plain methods + + #if 0 // turned all these off while new approach is coded + void RefreshDisplayDB( void ); // blow away old display DB, make a new one + GLMDisplayDB *GetDisplayDB( void ); // get a ptr to the one GLMgr keeps. only valid til next refresh. + + // eligible renderers will be ranked by desirability starting at index 0 within the db + // within each renderer, eligible displays will be ranked some kind of desirability (area? dist from menu bar?) + // within each display, eligible modes will be ranked by descending areas + + // calls supplying indices are implicitly making reference to the current DB + bool CaptureDisplay( int rendIndex, int displayIndex, bool captureAll ); // capture one display or all displays + void ReleaseDisplays( void ); // release all captures + + int GetDisplayMode( int rendIndex, int displayIndex ); // retrieve current display res (returns modeIndex) + void SetDisplayMode( GLMDisplayParams *params ); // set the display res (only useful for FS) + #endif + + GLMContext *NewContext( IDirect3DDevice9 *pDevice, GLMDisplayParams *params ); // this will have to change + void DelContext( GLMContext *context ); + + // with usage of CGLMacro.h we could dispense with the "current context" thing + // and just declare a member variable of GLMContext, allowing each glXXX call to be routed directly + // to the correct context + void SetCurrentContext( GLMContext *context ); // make current in calling thread only + GLMContext *GetCurrentContext( void ); + +protected: + friend class GLMContext; + + GLMgr(); + ~GLMgr(); +}; + + +//===========================================================================// + +// helper function to do enable or disable in one step +FORCEINLINE void glSetEnable( GLenum which, bool enable ) +{ + if (enable) + gGL->glEnable(which); + else + gGL->glDisable(which); +} + +// helper function for int vs enum clarity +FORCEINLINE void glGetEnumv( GLenum which, GLenum *dst ) +{ + gGL->glGetIntegerv( which, (int*)dst ); +} + +//===========================================================================// +// +// types to support the GLMContext +// +//===========================================================================// + +// Each state set/get path we are providing caching for, needs its own struct and a comparison operator. +// we also provide an enum of how many such types there are, handy for building dirty masks etc. + +// shorthand macros +#define EQ(fff) ( (src.fff) == (fff) ) + + +//rasterizer +struct GLAlphaTestEnable_t { GLint enable; inline bool operator==(const GLAlphaTestEnable_t& src) const { return EQ(enable); } }; +struct GLAlphaTestFunc_t { GLenum func; GLclampf ref; inline bool operator==(const GLAlphaTestFunc_t& src) const { return EQ(func) && EQ(ref); } }; +struct GLAlphaTest_t { GLint enable; GLenum func; GLclampf ref; }; +struct GLCullFaceEnable_t { GLint enable; inline bool operator==(const GLCullFaceEnable_t& src) const { return EQ(enable); } }; +struct GLCullFrontFace_t { GLenum value; inline bool operator==(const GLCullFrontFace_t& src) const { return EQ(value); } }; +struct GLPolygonMode_t { GLenum values[2]; inline bool operator==(const GLPolygonMode_t& src) const { return EQ(values[0]) && EQ(values[1]); } }; +struct GLDepthBias_t { GLfloat factor; GLfloat units; inline bool operator==(const GLDepthBias_t& src) const { return EQ(factor) && EQ(units); } }; +struct GLScissorEnable_t { GLint enable; inline bool operator==(const GLScissorEnable_t& src) const { return EQ(enable); } }; +struct GLScissorBox_t { GLint x,y; GLsizei width, height; inline bool operator==(const GLScissorBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } }; +struct GLAlphaToCoverageEnable_t{ GLint enable; inline bool operator==(const GLAlphaToCoverageEnable_t& src) const { return EQ(enable); } }; +struct GLViewportBox_t { GLint x,y; GLsizei width, height; uint widthheight; inline bool operator==(const GLViewportBox_t& src) const { return EQ(x) && EQ(y) && EQ(width) && EQ(height); } }; +struct GLViewportDepthRange_t { GLfloat flNear,flFar; inline bool operator==(const GLViewportDepthRange_t& src) const { return EQ(flNear) && EQ(flFar); } }; +struct GLClipPlaneEnable_t { GLint enable; inline bool operator==(const GLClipPlaneEnable_t& src) const { return EQ(enable); } }; +struct GLClipPlaneEquation_t { GLfloat x,y,z,w; inline bool operator==(const GLClipPlaneEquation_t& src) const { return EQ(x) && EQ(y) && EQ(z) && EQ(w); } }; + +//blend +struct GLColorMaskSingle_t { signed char r,g,b,a; inline bool operator==(const GLColorMaskSingle_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLColorMaskMultiple_t { signed char r,g,b,a; inline bool operator==(const GLColorMaskMultiple_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLBlendEnable_t { GLint enable; inline bool operator==(const GLBlendEnable_t& src) const { return EQ(enable); } }; +struct GLBlendFactor_t { GLenum srcfactor,dstfactor; inline bool operator==(const GLBlendFactor_t& src) const { return EQ(srcfactor) && EQ(dstfactor); } }; +struct GLBlendEquation_t { GLenum equation; inline bool operator==(const GLBlendEquation_t& src) const { return EQ(equation); } }; +struct GLBlendColor_t { GLfloat r,g,b,a; inline bool operator==(const GLBlendColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLBlendEnableSRGB_t { GLint enable; inline bool operator==(const GLBlendEnableSRGB_t& src) const { return EQ(enable); } }; + +//depth +struct GLDepthTestEnable_t { GLint enable; inline bool operator==(const GLDepthTestEnable_t& src) const { return EQ(enable); } }; +struct GLDepthFunc_t { GLenum func; inline bool operator==(const GLDepthFunc_t& src) const { return EQ(func); } }; +struct GLDepthMask_t { char mask; inline bool operator==(const GLDepthMask_t& src) const { return EQ(mask); } }; + +//stencil +struct GLStencilTestEnable_t { GLint enable; inline bool operator==(const GLStencilTestEnable_t& src) const { return EQ(enable); } }; +struct GLStencilFunc_t { GLenum frontfunc, backfunc; GLint ref; GLuint mask; inline bool operator==(const GLStencilFunc_t& src) const { return EQ(frontfunc) && EQ(backfunc) && EQ(ref) && EQ(mask); } }; +struct GLStencilOp_t { GLenum sfail; GLenum dpfail; GLenum dppass; inline bool operator==(const GLStencilOp_t& src) const { return EQ(sfail) && EQ(dpfail) && EQ(dppass); } }; +struct GLStencilWriteMask_t { GLint mask; inline bool operator==(const GLStencilWriteMask_t& src) const { return EQ(mask); } }; + +//clearing +struct GLClearColor_t { GLfloat r,g,b,a; inline bool operator==(const GLClearColor_t& src) const { return EQ(r) && EQ(g) && EQ(b) && EQ(a); } }; +struct GLClearDepth_t { GLfloat d; inline bool operator==(const GLClearDepth_t& src) const { return EQ(d); } }; +struct GLClearStencil_t { GLint s; inline bool operator==(const GLClearStencil_t& src) const { return EQ(s); } }; + +#undef EQ + +enum EGLMStateBlockType +{ + kGLAlphaTestEnable, + kGLAlphaTestFunc, + + kGLCullFaceEnable, + kGLCullFrontFace, + + kGLPolygonMode, + + kGLDepthBias, + + kGLScissorEnable, + kGLScissorBox, + + kGLViewportBox, + kGLViewportDepthRange, + + kGLClipPlaneEnable, + kGLClipPlaneEquation, + + kGLColorMaskSingle, + kGLColorMaskMultiple, + + kGLBlendEnable, + kGLBlendFactor, + kGLBlendEquation, + kGLBlendColor, + kGLBlendEnableSRGB, + + kGLDepthTestEnable, + kGLDepthFunc, + kGLDepthMask, + + kGLStencilTestEnable, + kGLStencilFunc, + kGLStencilOp, + kGLStencilWriteMask, + + kGLClearColor, + kGLClearDepth, + kGLClearStencil, + + kGLAlphaToCoverageEnable, + + kGLMStateBlockLimit +}; + +//===========================================================================// + +// templated functions representing GL R/W bottlenecks +// one set of set/get/getdefault is instantiated for each of the GL*** types above. + +// use these from the non array state objects +template void GLContextSet( T *src ); +template void GLContextGet( T *dst ); +template void GLContextGetDefault( T *dst ); + +// use these from the array state objects +template void GLContextSetIndexed( T *src, int index ); +template void GLContextGetIndexed( T *dst, int index ); +template void GLContextGetDefaultIndexed( T *dst, int index ); + +//=============================================================================== +// template specializations for each type of state + + +static GLAlphaTest_t g_alpha_test; + +// --- GLAlphaTestEnable --- +FORCEINLINE void GLContextSet( GLAlphaTestEnable_t *src ) +{ + if( gGL->m_bHave_GL_QCOM_alpha_test ) + glSetEnable( GL_ALPHA_TEST_QCOM, src->enable != 0 ); + else + g_alpha_test.enable = src->enable; +} + +FORCEINLINE void GLContextGet( GLAlphaTestEnable_t *dst ) +{ + if( gGL->m_bHave_GL_QCOM_alpha_test ) + dst->enable = gGL->glIsEnabled( GL_ALPHA_TEST_QCOM ); + else + dst->enable = g_alpha_test.enable; +} + +FORCEINLINE void GLContextGetDefault( GLAlphaTestEnable_t *dst ) +{ + dst->enable = GL_FALSE; +} + +// --- GLAlphaTestFunc --- +FORCEINLINE void GLContextSet( GLAlphaTestFunc_t *src ) +{ + if( gGL->m_bHave_GL_QCOM_alpha_test ) + gGL->glAlphaFuncQCOM( src->func, src->ref ); + + g_alpha_test.func = src->func; + g_alpha_test.ref = src->ref; +} + +FORCEINLINE void GLContextGet( GLAlphaTestFunc_t *dst ) +{ + if( gGL->m_bHave_GL_QCOM_alpha_test ) + { + glGetEnumv( GL_ALPHA_TEST_FUNC_QCOM, &dst->func ); + gGL->glGetFloatv( GL_ALPHA_TEST_REF_QCOM, &dst->ref ); + } + else + { + dst->func = g_alpha_test.func; + dst->ref = g_alpha_test.ref; + } +} + +FORCEINLINE void GLContextGetDefault( GLAlphaTestFunc_t *dst ) +{ + dst->func = GL_ALWAYS; + dst->ref = 0.0f; +} + +// --- GLAlphaToCoverageEnable --- +FORCEINLINE void GLContextSet( GLAlphaToCoverageEnable_t *src ) +{ + glSetEnable( GL_SAMPLE_ALPHA_TO_COVERAGE, src->enable != 0 ); +} + +FORCEINLINE void GLContextGet( GLAlphaToCoverageEnable_t *dst ) +{ + dst->enable = gGL->glIsEnabled( GL_SAMPLE_ALPHA_TO_COVERAGE ); +} + +FORCEINLINE void GLContextGetDefault( GLAlphaToCoverageEnable_t *dst ) +{ + dst->enable = GL_FALSE; +} + +// --- GLCullFaceEnable --- +FORCEINLINE void GLContextSet( GLCullFaceEnable_t *src ) +{ + glSetEnable( GL_CULL_FACE, src->enable != 0 ); +} + +FORCEINLINE void GLContextGet( GLCullFaceEnable_t *dst ) +{ + dst->enable = gGL->glIsEnabled( GL_CULL_FACE ); +} + +FORCEINLINE void GLContextGetDefault( GLCullFaceEnable_t *dst ) +{ + dst->enable = GL_TRUE; +} + + +// --- GLCullFrontFace --- +FORCEINLINE void GLContextSet( GLCullFrontFace_t *src ) +{ + gGL->glFrontFace( src->value ); // legal values are GL_CW or GL_CCW +} + +FORCEINLINE void GLContextGet( GLCullFrontFace_t *dst ) +{ + glGetEnumv( GL_FRONT_FACE, &dst->value ); +} + +FORCEINLINE void GLContextGetDefault( GLCullFrontFace_t *dst ) +{ + dst->value = GL_CCW; +} + + +// --- GLPolygonMode --- +FORCEINLINE void GLContextSet( GLPolygonMode_t *src ) +{ +// gGL->glPolygonMode( GL_FRONT, src->values[0] ); +// gGL->glPolygonMode( GL_BACK, src->values[1] ); +} + +FORCEINLINE void GLContextGet( GLPolygonMode_t *dst ) +{ + glGetEnumv( GL_POLYGON_MODE, &dst->values[0] ); + +} + +FORCEINLINE void GLContextGetDefault( GLPolygonMode_t *dst ) +{ + dst->values[0] = dst->values[1] = GL_FILL; +} + + +// --- GLDepthBias --- +// note the implicit enable / disable. +// if you set non zero values, it is enabled, otherwise not. +FORCEINLINE void GLContextSet( GLDepthBias_t *src ) +{ + bool enable = (src->factor != 0.0f) || (src->units != 0.0f); + + glSetEnable( GL_POLYGON_OFFSET_FILL, enable ); + gGL->glPolygonOffset( src->factor, src->units ); +} + +FORCEINLINE void GLContextGet( GLDepthBias_t *dst ) +{ + gGL->glGetFloatv ( GL_POLYGON_OFFSET_FACTOR, &dst->factor ); + gGL->glGetFloatv ( GL_POLYGON_OFFSET_UNITS, &dst->units ); +} + +FORCEINLINE void GLContextGetDefault( GLDepthBias_t *dst ) +{ + dst->factor = 0.0; + dst->units = 0.0; +} + + +// --- GLScissorEnable --- +FORCEINLINE void GLContextSet( GLScissorEnable_t *src ) +{ + glSetEnable( GL_SCISSOR_TEST, src->enable != 0 ); +} + +FORCEINLINE void GLContextGet( GLScissorEnable_t *dst ) +{ + dst->enable = gGL->glIsEnabled( GL_SCISSOR_TEST ); +} + +FORCEINLINE void GLContextGetDefault( GLScissorEnable_t *dst ) +{ + dst->enable = GL_FALSE; +} + + +// --- GLScissorBox --- +FORCEINLINE void GLContextSet( GLScissorBox_t *src ) +{ + gGL->glScissor ( src->x, src->y, src->width, src->height ); +} + +FORCEINLINE void GLContextGet( GLScissorBox_t *dst ) +{ + gGL->glGetIntegerv ( GL_SCISSOR_BOX, &dst->x ); +} + +FORCEINLINE void GLContextGetDefault( GLScissorBox_t *dst ) +{ + // hmmmm, good question? we can't really know a good answer so we pick a silly one + // and the client better come back with a better answer later. + dst->x = dst->y = 0; + dst->width = dst->height = 16; +} + + +// --- GLViewportBox --- + +FORCEINLINE void GLContextSet( GLViewportBox_t *src ) +{ + Assert( src->width == (int)( src->widthheight & 0xFFFF ) ); + Assert( src->height == (int)( src->widthheight >> 16 ) ); + gGL->glViewport (src->x, src->y, src->width, src->height ); +} + +FORCEINLINE void GLContextGet( GLViewportBox_t *dst ) +{ + gGL->glGetIntegerv ( GL_VIEWPORT, &dst->x ); + dst->widthheight = dst->width | ( dst->height << 16 ); +} + +FORCEINLINE void GLContextGetDefault( GLViewportBox_t *dst ) +{ + // as with the scissor box, we don't know yet, so pick a silly one and change it later + dst->x = dst->y = 0; + dst->width = dst->height = 16; + dst->widthheight = dst->width | ( dst->height << 16 ); +} + + +// --- GLViewportDepthRange --- +FORCEINLINE void GLContextSet( GLViewportDepthRange_t *src ) +{ + gGL->glDepthRangef ( src->flNear, src->flFar ); +} + +FORCEINLINE void GLContextGet( GLViewportDepthRange_t *dst ) +{ + gGL->glGetFloatv( GL_DEPTH_RANGE, &dst->flNear ); +} + +FORCEINLINE void GLContextGetDefault( GLViewportDepthRange_t *dst ) +{ + dst->flNear = 0.0; + dst->flFar = 1.0; +} + +// --- GLClipPlaneEnable --- +FORCEINLINE void GLContextSetIndexed( GLClipPlaneEnable_t *src, int index ) +{ +#if GLMDEBUG + if (CommandLine()->FindParm("-caps_noclipplanes")) + { + if (GLMKnob("caps-key",NULL) > 0.0) + { + // caps ON means NO clipping + src->enable = false; + } + } +#endif + glSetEnable( GL_CLIP_PLANE0 + index, src->enable != 0 ); +} + +FORCEINLINE void GLContextGetIndexed( GLClipPlaneEnable_t *dst, int index ) +{ + dst->enable = gGL->glIsEnabled( GL_CLIP_PLANE0 + index ); +} + +FORCEINLINE void GLContextGetDefaultIndexed( GLClipPlaneEnable_t *dst, int index ) +{ + dst->enable = 0; +} + + + +// --- GLClipPlaneEquation --- +FORCEINLINE void GLContextSetIndexed( GLClipPlaneEquation_t *src, int index ) +{ + // shove into glGlipPlane + +// GLdouble coeffs[4] = { src->x, src->y, src->z, src->w }; +// gGL->glClipPlane( GL_CLIP_PLANE0 + index, coeffs ); +} + +FORCEINLINE void GLContextGetIndexed( GLClipPlaneEquation_t *dst, int index ) +{ + DebuggerBreak(); // do this later + // glClipPlane( GL_CLIP_PLANE0 + index, coeffs ); + // GLdouble coeffs[4] = { src->x, src->y, src->z, src->w }; +} + +FORCEINLINE void GLContextGetDefaultIndexed( GLClipPlaneEquation_t *dst, int index ) +{ + dst->x = 1.0; + dst->y = 0.0; + dst->z = 0.0; + dst->w = 0.0; +} + + +// --- GLColorMaskSingle --- +FORCEINLINE void GLContextSet( GLColorMaskSingle_t *src ) +{ + gGL->glColorMask( src->r, src->g, src->b, src->a ); +} + +FORCEINLINE void GLContextGet( GLColorMaskSingle_t *dst ) +{ + gGL->glGetBooleanv( GL_COLOR_WRITEMASK, (GLboolean*)&dst->r); +} + +FORCEINLINE void GLContextGetDefault( GLColorMaskSingle_t *dst ) +{ + dst->r = dst->g = dst->b = dst->a = 1; +} + + +// --- GLColorMaskMultiple --- +FORCEINLINE void GLContextSetIndexed( GLColorMaskMultiple_t *src, int index ) +{ + GLint Rfbo = 0, Dfbo = 0; + + gGL->glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &Dfbo ); + gGL->glGetIntegerv( GL_READ_FRAMEBUFFER_BINDING, &Rfbo ); + GLint target = Dfbo == Rfbo?GL_FRAMEBUFFER:GL_DRAW_FRAMEBUFFER; + gGL->glBindFramebuffer( target, index ); + gGL->glColorMask ( src->r, src->g, src->b, src->a ); + gGL->glBindFramebuffer( target, Dfbo ); +} + +FORCEINLINE void GLContextGetIndexed( GLColorMaskMultiple_t *dst, int index ) +{ + GLint Rfbo = 0, Dfbo = 0; + + gGL->glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &Dfbo ); + gGL->glGetIntegerv( GL_READ_FRAMEBUFFER_BINDING, &Rfbo ); + GLint target = Dfbo == Rfbo?GL_FRAMEBUFFER:GL_DRAW_FRAMEBUFFER; + gGL->glBindFramebuffer( target, index ); + gGL->glGetBooleanv( GL_COLOR_WRITEMASK, (GLboolean*)&dst->r ); + gGL->glBindFramebuffer( target, Dfbo ); +} + +FORCEINLINE void GLContextGetDefaultIndexed( GLColorMaskMultiple_t *dst, int index ) +{ + dst->r = dst->g = dst->b = dst->a = 1; +} + + +// --- GLBlendEnable --- +FORCEINLINE void GLContextSet( GLBlendEnable_t *src ) +{ + glSetEnable( GL_BLEND, src->enable != 0 ); +} + +FORCEINLINE void GLContextGet( GLBlendEnable_t *dst ) +{ + dst->enable = gGL->glIsEnabled( GL_BLEND ); +} + +FORCEINLINE void GLContextGetDefault( GLBlendEnable_t *dst ) +{ + dst->enable = GL_FALSE; +} + + +// --- GLBlendFactor --- +FORCEINLINE void GLContextSet( GLBlendFactor_t *src ) +{ + gGL->glBlendFunc ( src->srcfactor, src->dstfactor ); +} + +FORCEINLINE void GLContextGet( GLBlendFactor_t *dst ) +{ + glGetEnumv ( GL_BLEND_SRC, &dst->srcfactor ); + glGetEnumv ( GL_BLEND_DST, &dst->dstfactor ); +} + +FORCEINLINE void GLContextGetDefault( GLBlendFactor_t *dst ) +{ + dst->srcfactor = GL_ONE; + dst->dstfactor = GL_ZERO; +} + + +// --- GLBlendEquation --- +FORCEINLINE void GLContextSet( GLBlendEquation_t *src ) +{ + gGL->glBlendEquation ( src->equation ); +} + +FORCEINLINE void GLContextGet( GLBlendEquation_t *dst ) +{ + glGetEnumv ( GL_BLEND_EQUATION, &dst->equation ); +} + +FORCEINLINE void GLContextGetDefault( GLBlendEquation_t *dst ) +{ + dst->equation = GL_FUNC_ADD; +} + + +// --- GLBlendColor --- +FORCEINLINE void GLContextSet( GLBlendColor_t *src ) +{ + gGL->glBlendColor ( src->r, src->g, src->b, src->a ); +} + +FORCEINLINE void GLContextGet( GLBlendColor_t *dst ) +{ + gGL->glGetFloatv ( GL_BLEND_COLOR, &dst->r ); +} + +FORCEINLINE void GLContextGetDefault( GLBlendColor_t *dst ) +{ + //solid white + dst->r = dst->g = dst->b = dst->a = 1.0; +} + + +// --- GLBlendEnableSRGB --- + +#define GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING 0x8210 +#define GL_COLOR_ATTACHMENT0 0x8CE0 + +FORCEINLINE void GLContextSet( GLBlendEnableSRGB_t *src ) +{ +#if GLMDEBUG + // just check in debug... this is too expensive to look at on MTGL + if (src->enable) + { + GLboolean srgb_capable = false; + gGL->glGetBooleanv( GL_FRAMEBUFFER_SRGB_CAPABLE_EXT, &srgb_capable); + + if (src->enable && !srgb_capable) + { + GLMPRINTF(("-Z- srgb-state-set FBO conflict: attempt to enable SRGB on non SRGB capable FBO config")); + } + } +#endif + // this query is not useful unless you have the ARB_framebuffer_srgb ext. + //GLint encoding = 0; + //pfnglGetFramebufferAttachmentParameteriv( GL_DRAW_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING, &encoding ); + + glSetEnable( GL_FRAMEBUFFER_SRGB_EXT, src->enable != 0 ); +} + +FORCEINLINE void GLContextGet( GLBlendEnableSRGB_t *dst ) +{ + dst->enable = gGL->glIsEnabled( GL_FRAMEBUFFER_SRGB_EXT ); +// dst->enable = true; // wtf ? +} + +FORCEINLINE void GLContextGetDefault( GLBlendEnableSRGB_t *dst ) +{ + dst->enable = GL_FALSE; +} + + +// --- GLDepthTestEnable --- +FORCEINLINE void GLContextSet( GLDepthTestEnable_t *src ) +{ + glSetEnable( GL_DEPTH_TEST, src->enable != 0 ); +} + +FORCEINLINE void GLContextGet( GLDepthTestEnable_t *dst ) +{ + dst->enable = gGL->glIsEnabled( GL_DEPTH_TEST ); +} + +FORCEINLINE void GLContextGetDefault( GLDepthTestEnable_t *dst ) +{ + dst->enable = GL_FALSE; +} + + +// --- GLDepthFunc --- +FORCEINLINE void GLContextSet( GLDepthFunc_t *src ) +{ + gGL->glDepthFunc ( src->func ); +} + +FORCEINLINE void GLContextGet( GLDepthFunc_t *dst ) +{ + glGetEnumv ( GL_DEPTH_FUNC, &dst->func ); +} + +FORCEINLINE void GLContextGetDefault( GLDepthFunc_t *dst ) +{ + dst->func = GL_GEQUAL; +} + + +// --- GLDepthMask --- +FORCEINLINE void GLContextSet( GLDepthMask_t *src ) +{ + gGL->glDepthMask ( src->mask ); +} + +FORCEINLINE void GLContextGet( GLDepthMask_t *dst ) +{ + gGL->glGetBooleanv ( GL_DEPTH_WRITEMASK, (GLboolean*)&dst->mask ); +} + +FORCEINLINE void GLContextGetDefault( GLDepthMask_t *dst ) +{ + dst->mask = GL_TRUE; +} + + +// --- GLStencilTestEnable --- +FORCEINLINE void GLContextSet( GLStencilTestEnable_t *src ) +{ + glSetEnable( GL_STENCIL_TEST, src->enable != 0 ); +} + +FORCEINLINE void GLContextGet( GLStencilTestEnable_t *dst ) +{ + dst->enable = gGL->glIsEnabled( GL_STENCIL_TEST ); +} + +FORCEINLINE void GLContextGetDefault( GLStencilTestEnable_t *dst ) +{ + dst->enable = GL_FALSE; +} + + +// --- GLStencilFunc --- +FORCEINLINE void GLContextSet( GLStencilFunc_t *src ) +{ + if (src->frontfunc == src->backfunc) + gGL->glStencilFuncSeparate( GL_FRONT_AND_BACK, src->frontfunc, src->ref, src->mask); + else + { + gGL->glStencilFuncSeparate( GL_FRONT, src->frontfunc, src->ref, src->mask); + gGL->glStencilFuncSeparate( GL_BACK, src->backfunc, src->ref, src->mask); + } +} + +FORCEINLINE void GLContextGet( GLStencilFunc_t *dst ) +{ + glGetEnumv ( GL_STENCIL_FUNC, &dst->frontfunc ); + glGetEnumv ( GL_STENCIL_BACK_FUNC, &dst->backfunc ); + gGL->glGetIntegerv ( GL_STENCIL_REF, &dst->ref ); + gGL->glGetIntegerv ( GL_STENCIL_VALUE_MASK, (GLint*)&dst->mask ); +} + +FORCEINLINE void GLContextGetDefault( GLStencilFunc_t *dst ) +{ + dst->frontfunc = GL_ALWAYS; + dst->backfunc = GL_ALWAYS; + dst->ref = 0; + dst->mask = 0xFFFFFFFF; +} + + +// --- GLStencilOp --- indexed 0=front, 1=back + +FORCEINLINE void GLContextSetIndexed( GLStencilOp_t *src, int index ) +{ + GLenum face = (index==0) ? GL_FRONT : GL_BACK; + gGL->glStencilOpSeparate( face, src->sfail, src->dpfail, src->dppass ); +} + +FORCEINLINE void GLContextGetIndexed( GLStencilOp_t *dst, int index ) +{ + glGetEnumv ( (index==0) ? GL_STENCIL_FAIL : GL_STENCIL_BACK_FAIL, &dst->sfail ); + glGetEnumv ( (index==0) ? GL_STENCIL_PASS_DEPTH_FAIL : GL_STENCIL_BACK_PASS_DEPTH_FAIL, &dst->dpfail ); + glGetEnumv ( (index==0) ? GL_STENCIL_PASS_DEPTH_PASS : GL_STENCIL_BACK_PASS_DEPTH_PASS, &dst->dppass ); +} + +FORCEINLINE void GLContextGetDefaultIndexed( GLStencilOp_t *dst, int index ) +{ + dst->sfail = dst->dpfail = dst->dppass = GL_KEEP; +} + + +// --- GLStencilWriteMask --- +FORCEINLINE void GLContextSet( GLStencilWriteMask_t *src ) +{ + gGL->glStencilMask( src->mask ); +} + +FORCEINLINE void GLContextGet( GLStencilWriteMask_t *dst ) +{ + gGL->glGetIntegerv ( GL_STENCIL_WRITEMASK, &dst->mask ); +} + +FORCEINLINE void GLContextGetDefault( GLStencilWriteMask_t *dst ) +{ + dst->mask = 0xFFFFFFFF; +} + + +// --- GLClearColor --- +FORCEINLINE void GLContextSet( GLClearColor_t *src ) +{ + gGL->glClearColor( src->r, src->g, src->b, src->a ); +} + +FORCEINLINE void GLContextGet( GLClearColor_t *dst ) +{ + gGL->glGetFloatv ( GL_COLOR_CLEAR_VALUE, &dst->r ); +} + +FORCEINLINE void GLContextGetDefault( GLClearColor_t *dst ) +{ + dst->r = dst->g = dst->b = 0.5; + dst->a = 1.0; +} + + +// --- GLClearDepth --- +FORCEINLINE void GLContextSet( GLClearDepth_t *src ) +{ + gGL->glClearDepthf( src->d ); +} + +FORCEINLINE void GLContextGet( GLClearDepth_t *dst ) +{ + gGL->glGetFloatv( GL_DEPTH_CLEAR_VALUE, &dst->d ); +} + +FORCEINLINE void GLContextGetDefault( GLClearDepth_t *dst ) +{ + dst->d = 1.0; +} + + +// --- GLClearStencil --- +FORCEINLINE void GLContextSet( GLClearStencil_t *src ) +{ + gGL->glClearStencil( src->s ); +} + +FORCEINLINE void GLContextGet( GLClearStencil_t *dst ) +{ + gGL->glGetIntegerv ( GL_STENCIL_CLEAR_VALUE, &dst->s ); +} + +FORCEINLINE void GLContextGetDefault( GLClearStencil_t *dst ) +{ + dst->s = 0; +} + +//===========================================================================// + +// caching state object template. One of these is instantiated in the context per unique struct type above +template class GLState +{ + public: + inline GLState() + { + memset( &data, 0, sizeof(data) ); + Default(); + } + + FORCEINLINE void Flush() + { + // immediately blast out the state - it makes no sense to delta it or do anything fancy because shaderapi, dxabstract, and OpenGL itself does this for us (and OpenGL calls with multithreaded drivers are very cheap) + GLContextSet( &data ); + } + + // write: client src into cache + // common case is both false. dirty is calculated, context write is deferred. + FORCEINLINE void Write( const T *src ) + { + data = *src; + Flush(); + } + + // default: write default value to cache, optionally write through + inline void Default( bool noDefer=false ) + { + GLContextGetDefault( &data ); // read default values directly to our cache copy + Flush(); + } + + // read: sel = 0 for cache, 1 for context + inline void Read( T *dst, int sel ) + { + if (sel==0) + *dst = data; + else + GLContextGet( dst ); + } + + // check: verify that context equals cache, return true if mismatched or if illegal values seen + inline bool Check ( void ) + { + T temp; + bool result; + + GLContextGet( &temp ); + result = !(temp == data); + return result; + } + + FORCEINLINE const T &GetData() const { return data; } + + protected: + T data; +}; + +// caching state object template - with multiple values behind it that are indexed +template class GLStateArray +{ + public: + inline GLStateArray() + { + memset( &data, 0, sizeof(data) ); + Default(); + } + + // write cache->context if dirty or forced. + FORCEINLINE void FlushIndex( int index ) + { + // immediately blast out the state - it makes no sense to delta it or do anything fancy because shaderapi, dxabstract, and OpenGL itself does this for us (and OpenGL calls with multithreaded drivers are very cheap) + GLContextSetIndexed( &data[index], index ); + }; + + // write: client src into cache + // common case is both false. dirty is calculated, context write is deferred. + FORCEINLINE void WriteIndex( T *src, int index ) + { + data[index] = *src; + FlushIndex( index ); // dirty becomes false + }; + + // write all slots in the array + FORCEINLINE void Flush() + { + for( int i=0; i < COUNT; i++) + { + FlushIndex( i ); + } + } + + // default: write default value to cache, optionally write through + inline void DefaultIndex( int index ) + { + GLContextGetDefaultIndexed( &data[index], index ); // read default values directly to our cache copy + Flush(); + }; + + inline void Default( void ) + { + for( int i=0; ienable != 0; + } + // note however that we're still tracking what this mode should be, so FlushDrawStates can look at it and adjust the pixel shader + // if fake SRGB mode is in place (m_caps.m_hasGammaWrites is false) + } + + FORCEINLINE void WriteDepthTestEnable( GLDepthTestEnable_t *src ) { m_DepthTestEnable.Write( src ); } + FORCEINLINE void WriteDepthFunc( GLDepthFunc_t *src ) { m_DepthFunc.Write( src ); } + FORCEINLINE void WriteDepthMask( GLDepthMask_t *src ) { m_DepthMask.Write( src ); } + FORCEINLINE void WriteStencilTestEnable( GLStencilTestEnable_t *src ) { m_StencilTestEnable.Write( src ); } + FORCEINLINE void WriteStencilFunc( GLStencilFunc_t *src ) { m_StencilFunc.Write( src ); } + FORCEINLINE void WriteStencilOp( GLStencilOp_t *src, int which ) { m_StencilOp.WriteIndex( src, which ); } + FORCEINLINE void WriteStencilWriteMask( GLStencilWriteMask_t *src ) { m_StencilWriteMask.Write( src ); } + FORCEINLINE void WriteClearColor( GLClearColor_t *src ) { m_ClearColor.Write( src ); } + FORCEINLINE void WriteClearDepth( GLClearDepth_t *src ) { m_ClearDepth.Write( src ); } + FORCEINLINE void WriteClearStencil( GLClearStencil_t *src ) { m_ClearStencil.Write( src ); } + + // debug stuff + void BeginFrame( void ); + void EndFrame( void ); + + // new interactive debug stuff +#if GLMDEBUG + void DebugDump( GLMDebugHookInfo *info, uint options, uint vertDumpMode ); + void DebugHook( GLMDebugHookInfo *info ); + void DebugPresent( void ); + void DebugClear( void ); +#endif + + FORCEINLINE void SetMaxUsedVertexShaderConstantsHint( uint nMaxConstants ); + FORCEINLINE DWORD GetCurrentOwnerThreadId() const { return m_nCurOwnerThreadId; } + + protected: + friend class GLMgr; // only GLMgr can make GLMContext objects + friend class GLMRendererInfo; // only GLMgr can make GLMContext objects + friend class CGLMTex; // tex needs to be able to do binds + friend class CGLMFBO; // fbo needs to be able to do binds + friend class CGLMProgram; + friend class CGLMShaderPair; + friend class CGLMShaderPairCache; + friend class CGLMBuffer; + friend class CGLMBufferSpanManager; + friend class GLMTester; // tester class needs access back into GLMContext + + friend struct IDirect3D9; + friend struct IDirect3DDevice9; + friend struct IDirect3DQuery9; + + // methods------------------------------------------ + + // old GLMContext( GLint displayMask, GLint rendererID, PseudoNSGLContextPtr nsglShareCtx ); + GLMContext( IDirect3DDevice9 *pDevice, GLMDisplayParams *params ); + ~GLMContext(); + +#ifndef OSX + FORCEINLINE GLuint FindSamplerObject( const GLMTexSamplingParams &desiredParams ); +#endif + + FORCEINLINE void SetBufAndVertexAttribPointer( uint nIndex, GLuint nGLName, GLuint stride, GLuint datatype, GLboolean normalized, GLuint nCompCount, const void *pBuf, uint nRevision ) + { + VertexAttribs_t &curAttribs = m_boundVertexAttribs[nIndex]; + if ( nGLName != m_nBoundGLBuffer[kGLMVertexBuffer] ) + { + m_nBoundGLBuffer[kGLMVertexBuffer] = nGLName; + gGL->glBindBuffer( GL_ARRAY_BUFFER, nGLName ); + } + else if ( ( curAttribs.m_pPtr == pBuf ) && + ( curAttribs.m_revision == nRevision ) && + ( curAttribs.m_stride == stride ) && + ( curAttribs.m_datatype == datatype ) && + ( curAttribs.m_normalized == normalized ) && + ( curAttribs.m_nCompCount == nCompCount ) ) + { + return; + } + + curAttribs.m_nCompCount = nCompCount; + curAttribs.m_datatype = datatype; + curAttribs.m_normalized = normalized; + curAttribs.m_stride = stride; + curAttribs.m_pPtr = pBuf; + curAttribs.m_revision = nRevision; + + gGL->glVertexAttribPointer( nIndex, nCompCount, datatype, normalized, stride, pBuf ); + } + + struct CurAttribs_t + { + uint m_nTotalBufferRevision; + IDirect3DVertexDeclaration9 *m_pVertDecl; + D3DStreamDesc m_streams[ D3D_MAX_STREAMS ]; + uint64 m_vtxAttribMap[2]; + }; + + CurAttribs_t m_CurAttribs; + + FORCEINLINE void ClearCurAttribs() + { + m_CurAttribs.m_nTotalBufferRevision = 0; + m_CurAttribs.m_pVertDecl = NULL; + memset( m_CurAttribs.m_streams, 0, sizeof( m_CurAttribs.m_streams ) ); + m_CurAttribs.m_vtxAttribMap[0] = 0xBBBBBBBBBBBBBBBBULL; + m_CurAttribs.m_vtxAttribMap[1] = 0xBBBBBBBBBBBBBBBBULL; + } + + FORCEINLINE void ReleasedShader() { NullProgram(); } + + // textures + FORCEINLINE void SelectTMU( int tmu ) + { + if ( tmu != m_activeTexture ) + { + gGL->glActiveTexture( GL_TEXTURE0 + tmu ); + m_activeTexture = tmu; + } + } + + void BindTexToTMU( CGLMTex *tex, int tmu ); + + // render targets / FBO's + void BindFBOToCtx( CGLMFBO *fbo, GLenum bindPoint = GL_FRAMEBUFFER ); // you can also choose GL_READ_FRAMEBUFFER_EXT / GL_DRAW_FRAMEBUFFER_EXT + + // buffers + FORCEINLINE void BindGLBufferToCtx( GLenum nGLBufType, GLuint nGLName, bool bForce = false ) + { + Assert( ( nGLBufType == GL_ARRAY_BUFFER ) || ( nGLBufType == GL_ELEMENT_ARRAY_BUFFER ) ); + + const uint nIndex = ( nGLBufType == GL_ARRAY_BUFFER ) ? kGLMVertexBuffer : kGLMIndexBuffer; + if ( ( bForce ) || ( m_nBoundGLBuffer[nIndex] != nGLName ) ) + { + m_nBoundGLBuffer[nIndex] = nGLName; + gGL->glBindBuffer( nGLBufType, nGLName ); + } + } + + void BindBufferToCtx( EGLMBufferType type, CGLMBuffer *buff, bool force = false ); // does not twiddle any enables. + + FORCEINLINE void BindIndexBufferToCtx( CGLMBuffer *buff ); + FORCEINLINE void BindVertexBufferToCtx( CGLMBuffer *buff ); + + GLuint CreateTex( GLenum texBind, GLenum internalFormat ); + void CleanupTex( GLenum texBind, GLMTexLayout* pLayout, GLuint tex ); + void DestroyTex( GLenum texBind, GLMTexLayout* pLayout, GLuint tex ); + GLuint FillTexCache( bool holdOne, int newTextures ); + void PurgeTexCache( ); + + // debug font + void GenDebugFontTex( void ); + void DrawDebugText( float x, float y, float z, float drawCharWidth, float drawCharHeight, char *string ); + + CPersistentBuffer* GetCurPersistentBuffer( EGLMBufferType type ) { return &( m_persistentBuffer[m_nCurPersistentBuffer][type] ); } + + // members------------------------------------------ + + // context + DWORD m_nCurOwnerThreadId; + uint m_nThreadOwnershipReleaseCounter; + + bool m_bUseSamplerObjects; + bool m_bTexClientStorage; + + IDirect3DDevice9 *m_pDevice; + GLMRendererInfoFields m_caps; + + bool m_displayParamsValid; // is there a param block copied in yet + GLMDisplayParams m_displayParams; // last known display config, either via constructor, or by SetDisplayParams... + +#if defined( USE_SDL ) + int m_pixelFormatAttribs[100]; // more than enough + PseudoNSGLContextPtr m_nsctx; + void * m_ctx; +#endif + bool m_bUseBoneUniformBuffers; // if true, we use two uniform buffers for vertex shader constants vs. one + + // texture form table + CGLMTexLayoutTable *m_texLayoutTable; + + // context state mirrors + + GLState m_AlphaTestEnable; + + GLState m_AlphaTestFunc; + + GLState m_CullFaceEnable; + GLState m_CullFrontFace; + GLState m_PolygonMode; + + GLState m_DepthBias; + + GLStateArray m_ClipPlaneEnable; + GLStateArray m_ClipPlaneEquation; // dxabstract puts them directly into param slot 253(0) and 254(1) + + GLState m_ScissorEnable; + GLState m_ScissorBox; + + GLState m_AlphaToCoverageEnable; + + GLState m_ViewportBox; + GLState m_ViewportDepthRange; + + GLState m_ColorMaskSingle; + GLStateArray m_ColorMaskMultiple; // need an official constant for the color buffers limit + + GLState m_BlendEnable; + GLState m_BlendFactor; + GLState m_BlendEquation; + GLState m_BlendColor; + GLState m_BlendEnableSRGB; // write to this one to transmit intent to write SRGB encoded pixels to drawing FB + bool m_FakeBlendEnableSRGB; // writes to above will be shunted here if fake SRGB is in effect. + + GLState m_DepthTestEnable; + GLState m_DepthFunc; + GLState m_DepthMask; + + GLState m_StencilTestEnable; // global stencil test enable + GLState m_StencilFunc; // holds front and back stencil funcs + GLStateArray m_StencilOp; // indexed: 0=front 1=back + GLState m_StencilWriteMask; + + GLState m_ClearColor; + GLState m_ClearDepth; + GLState m_ClearStencil; + + // texture bindings and sampler setup + int m_activeTexture; // mirror for glActiveTexture + GLMTexSampler m_samplers[GLM_SAMPLER_COUNT]; + + uint8 m_nDirtySamplerFlags[GLM_SAMPLER_COUNT]; // 0 if the sampler is dirty, 1 if not + uint32 m_nNumDirtySamplers; // # of unique dirty sampler indices in m_nDirtySamplers + uint8 m_nDirtySamplers[GLM_SAMPLER_COUNT + 1]; // dirty sampler indices + + void MarkAllSamplersDirty(); + + struct SamplerHashEntry + { + GLuint m_samplerObject; + GLMTexSamplingParams m_params; + }; + + enum + { + cSamplerObjectHashBits = 9, cSamplerObjectHashSize = 1 << cSamplerObjectHashBits + }; + SamplerHashEntry m_samplerObjectHash[cSamplerObjectHashSize]; + uint m_nSamplerObjectHashNumEntries; + + // texture lock tracking - CGLMTex objects share usage of this + CUtlVector< GLMTexLockDesc > m_texLocks; + + // render target binding - check before draw + // similar to tex sampler mechanism, we track "bound" from "chosen for drawing" separately, + // so binding for creation/setup need not disrupt any notion of what will be used at draw time + + CGLMFBO *m_boundDrawFBO; // FBO on GL_DRAW_FRAMEBUFFER bind point + CGLMFBO *m_boundReadFBO; // FBO on GL_READ_FRAMEBUFFER bind point + // ^ both are set if you bind to GL_FRAMEBUFFER_EXT + + CGLMFBO *m_drawingFBO; // what FBO should be bound at draw time (to both read/draw bp's). + + CGLMFBO *m_blitReadFBO; + CGLMFBO *m_blitDrawFBO; // scratch FBO's for framebuffer blit + + CGLMFBO *m_scratchFBO[ kGLMScratchFBOCount ]; // general purpose FBO's for internal use + + CUtlVector< CGLMFBO* > m_fboTable; // each live FBO goes in the table + + uint m_fragDataMask; + + // program bindings + EGLMProgramLang m_drawingLangAtFrameStart; // selector for start of frame (spills into m_drawingLang) + EGLMProgramLang m_drawingLang; // selector for which language we desire to draw with on the next batch + CGLMProgram *m_drawingProgram[ kGLMNumProgramTypes ]; + bool m_bDirtyPrograms; + + GLMProgramParamsF m_programParamsF[ kGLMNumProgramTypes ]; + GLMProgramParamsB m_programParamsB[ kGLMNumProgramTypes ]; + GLMProgramParamsI m_programParamsI[ kGLMNumProgramTypes ]; // two banks, but only the vertex one is used + EGLMParamWriteMode m_paramWriteMode; + + CGLMProgram *m_pNullFragmentProgram; // write opaque black. Activate when caller asks for null FP + + CGLMProgram *m_preloadTexVertexProgram; // programs to help preload textures (dummies) + CGLMProgram *m_preload2DTexFragmentProgram; + CGLMProgram *m_preload3DTexFragmentProgram; + CGLMProgram *m_preloadCubeTexFragmentProgram; + +#if defined( OSX ) && defined( GLMDEBUG ) + CGLMProgram *m_boundProgram[ kGLMNumProgramTypes ]; +#endif + + CGLMShaderPairCache *m_pairCache; // GLSL only + CGLMShaderPair *m_pBoundPair; // GLSL only + + FORCEINLINE void NewLinkedProgram() { ClearCurAttribs(); } + + //uint m_boundPairRevision; // GLSL only + //GLhandleARB m_boundPairProgram; // GLSL only + + // buffer bindings + GLuint m_nBoundGLBuffer[kGLMNumBufferTypes]; + + struct VertexAttribs_t + { + GLuint m_nCompCount; + GLenum m_datatype; + GLboolean m_normalized; + GLuint m_stride; + const void *m_pPtr; + uint m_revision; + }; + + VertexAttribs_t m_boundVertexAttribs[ kGLMVertexAttributeIndexMax ]; // tracked per attrib for dupe-set-absorb + uint m_lastKnownVertexAttribMask; // tracked for dupe-enable-absorb + int m_nNumSetVertexAttributes; + + // FIXME: Remove this, it's no longer used + GLMVertexSetup m_drawVertexSetup; + + EGLMAttribWriteMode m_attribWriteMode; + + bool m_slowCheckEnable; // turn this on or no native checking is done ("-glmassertslow" or "-glmsspewslow") + bool m_slowAssertEnable; // turn this on to assert on a non-native batch "-glmassertslow" + bool m_slowSpewEnable; // turn this on to log non-native batches to stdout "-glmspewslow" + bool m_checkglErrorsAfterEveryBatch; // turn this on to check for GL errors after each batch (slow) ("-glcheckerrors") + + // debug font texture + CGLMTex *m_debugFontTex; // might be NULL unless you call GenDebugFontTex + CGLMBuffer *m_debugFontIndices; // up to 1024 indices (256 chars times 4) + CGLMBuffer *m_debugFontVertices; // up to 1024 verts + + // batch/frame debugging support + int m_debugFrameIndex; // init to -1. Increment at BeginFrame + + int m_nMaxUsedVertexProgramConstantsHint; + + uint32 m_dwRenderThreadId; + volatile bool m_bIsThreading; + + uint m_nCurFrame; + uint m_nBatchCounter; + + struct TextureEntry_t + { + GLenum m_nTexBind; + GLenum m_nInternalFormat; + GLuint m_nTexName; + }; + + GLuint m_destroyPBO; + CUtlVector< TextureEntry_t > m_availableTextures; + + enum { cNumPersistentBuffers = 3 }; + CPersistentBuffer m_persistentBuffer[cNumPersistentBuffers][kGLMNumBufferTypes]; + uint m_nCurPersistentBuffer; + + void SaveColorMaskAndSetToDefault(); + void RestoreSavedColorMask(); + GLColorMaskSingle_t m_SavedColorMask; + +#if GLMDEBUG + // interactive (DebugHook) debug support + + // using these you can implement frame advance, batch single step, and batch rewind (let it run til next frame and hold on prev batch #) + int m_holdFrameBegin; // -1 if no hold req'd, otherwise # of frame to hold at (at beginframe time) + int m_holdFrameEnd; // -1 if no hold req'd, otherwise # of frame to hold at (at endframe time) + + int m_holdBatch,m_holdBatchFrame; // -1 if no hold, else # of batch&frame to hold at (both must be set) + // these can be expired/cleared to -1 if the frame passes without a hit + // may be desirable to re-pause in that event, as user was expecting a hold to occur + + bool m_debugDelayEnable; // allow sleep delay + uint m_debugDelay; // sleep time per hook call in microseconds (for usleep()) + + // pre-draw global toggles / options + bool m_autoClearColor,m_autoClearDepth,m_autoClearStencil; + float m_autoClearColorValues[4]; + + // debug knobs + int m_selKnobIndex; + float m_selKnobMinValue,m_selKnobMaxValue,m_selKnobIncrement; +#endif + +#if GL_BATCH_PERF_ANALYSIS + uint m_nTotalVSUniformCalls; + uint m_nTotalVSUniformBoneCalls; + uint m_nTotalVSUniformsSet; + uint m_nTotalVSUniformsBoneSet; + uint m_nTotalPSUniformCalls; + uint m_nTotalPSUniformsSet; + + CFlushDrawStatesStats m_FlushStats; +#endif + + void ProcessTextureDeletes(); + CTSQueue m_DeleteTextureQueue; +}; + +#ifndef OSX + +FORCEINLINE void GLMContext::DrawRangeElements( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf ) +{ +#if GL_ENABLE_INDEX_VERIFICATION + DrawRangeElementsNonInline( mode, start, end, count, type, indices, baseVertex, pIndexBuf ); +#else + +#if GLMDEBUG + GLM_FUNC; +#else + //tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s %d-%d count:%d mode:%d type:%d", __FUNCTION__, start, end, count, mode, type ); +#endif + + ++m_nBatchCounter; + + SetIndexBuffer( pIndexBuf ); + + void *indicesActual = (void*)indices; + + if ( pIndexBuf->m_bPseudo ) + { + // you have to pass actual address, not offset + indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_pPseudoBuf ); + } + if (pIndexBuf->m_bUsingPersistentBuffer) + { + indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_nPersistentBufferStartOffset ); + } + +//#if GLMDEBUG +#if 0 + bool hasVP = m_drawingProgram[ kGLMVertexProgram ] != NULL; + bool hasFP = m_drawingProgram[ kGLMFragmentProgram ] != NULL; + + // init debug hook information + GLMDebugHookInfo info; + memset( &info, 0, sizeof(info) ); + info.m_caller = eDrawElements; + + // relay parameters we're operating under + info.m_drawMode = mode; + info.m_drawStart = start; + info.m_drawEnd = end; + info.m_drawCount = count; + info.m_drawType = type; + info.m_drawIndices = indices; + + do + { + // obey global options re pre-draw clear + if ( m_autoClearColor || m_autoClearDepth || m_autoClearStencil ) + { + GLMPRINTF(("-- DrawRangeElements auto clear" )); + this->DebugClear(); + } + + // always sync with editable shader text prior to draw +#if GLMDEBUG + //FIXME disengage this path if context is in GLSL mode.. + // it will need fixes to get the shader pair re-linked etc if edits happen anyway. + + if (m_drawingProgram[ kGLMVertexProgram ]) + { + m_drawingProgram[ kGLMVertexProgram ]->SyncWithEditable(); + } + else + { + AssertOnce(!"drawing with no vertex program bound"); + } + + + if (m_drawingProgram[ kGLMFragmentProgram ]) + { + m_drawingProgram[ kGLMFragmentProgram ]->SyncWithEditable(); + } + else + { + AssertOnce(!"drawing with no fragment program bound"); + } +#endif + // do the drawing + if (hasVP && hasFP) + { + gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex ); + + if ( m_slowCheckEnable ) + { + CheckNative(); + } + } + this->DebugHook( &info ); + + } while ( info.m_loop ); +#else + Assert( m_drawingLang == kGLMGLSL ); + + if ( m_pBoundPair ) + { + gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex ); + +#if GLMDEBUG + if ( m_slowCheckEnable ) + { + CheckNative(); + } +#endif + } +#endif + +#endif // GL_ENABLE_INDEX_VERIFICATION +} + +#endif // #ifndef OSX + +FORCEINLINE void GLMContext::SetVertexProgram( CGLMProgram *pProg ) +{ + m_drawingProgram[kGLMVertexProgram] = pProg; + m_bDirtyPrograms = true; +} + +FORCEINLINE void GLMContext::SetFragmentProgram( CGLMProgram *pProg ) +{ + m_drawingProgram[kGLMFragmentProgram] = pProg ? pProg : m_pNullFragmentProgram; + m_bDirtyPrograms = true; +} + +// "slot" means a vec4-sized thing +// these write into .env parameter space +FORCEINLINE void GLMContext::SetProgramParametersF( EGLMProgramType type, uint baseSlot, float *slotData, uint slotCount ) +{ +#if GLMDEBUG + GLM_FUNC; +#endif + + Assert( baseSlot < kGLMProgramParamFloat4Limit ); + Assert( baseSlot+slotCount <= kGLMProgramParamFloat4Limit ); + +#if GLMDEBUG + GLMPRINTF(("-S-GLMContext::SetProgramParametersF %s slots %d - %d: ", (type==kGLMVertexProgram) ? "VS" : "FS", baseSlot, baseSlot + slotCount - 1 )); + for( uint i=0; i DXABSTRACT_VS_LAST_BONE_SLOT ) + { + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, firstDirty - maxBoneSlots ); + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, highWater - maxBoneSlots ); + } + else if ( firstDirty >= DXABSTRACT_VS_FIRST_BONE_SLOT ) + { + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = DXABSTRACT_VS_LAST_BONE_SLOT + 1; + + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, DXABSTRACT_VS_FIRST_BONE_SLOT ); + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, highWater - maxBoneSlots ); + } + else + { + int nNumActualBones = ( DXABSTRACT_VS_LAST_BONE_SLOT + 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT; + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone, nNumActualBones ); + + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = MIN( m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone, firstDirty ); + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone, highWater - maxBoneSlots ); + } + } + } + else + { + m_programParamsF[type].m_dirtySlotHighWaterNonBone = MAX( m_programParamsF[type].m_dirtySlotHighWaterNonBone, (int)(baseSlot + slotCount) ); + m_programParamsF[type].m_firstDirtySlotNonBone = MIN( m_programParamsF[type].m_firstDirtySlotNonBone, (int)baseSlot ); + } +} + +FORCEINLINE void GLMContext::SetProgramParametersB( EGLMProgramType type, uint baseSlot, int *slotData, uint boolCount ) +{ +#if GLMDEBUG + GLM_FUNC; +#endif + + Assert( m_drawingLang == kGLMGLSL ); + Assert( type==kGLMVertexProgram || type==kGLMFragmentProgram ); + + Assert( baseSlot < kGLMProgramParamBoolLimit ); + Assert( baseSlot+boolCount <= kGLMProgramParamBoolLimit ); + +#if GLMDEBUG + GLMPRINTF(("-S-GLMContext::SetProgramParametersB %s bools %d - %d: ", (type==kGLMVertexProgram) ? "VS" : "FS", baseSlot, baseSlot + boolCount - 1 )); + for( uint i=0; i m_programParamsB[type].m_dirtySlotCount) + m_programParamsB[type].m_dirtySlotCount = baseSlot+boolCount; +} + +FORCEINLINE void GLMContext::SetProgramParametersI( EGLMProgramType type, uint baseSlot, int *slotData, uint slotCount ) // groups of 4 ints... +{ +#if GLMDEBUG + GLM_FUNC; +#endif + + Assert( m_drawingLang == kGLMGLSL ); + Assert( type==kGLMVertexProgram ); + + Assert( baseSlot < kGLMProgramParamInt4Limit ); + Assert( baseSlot+slotCount <= kGLMProgramParamInt4Limit ); + +#if GLMDEBUG + GLMPRINTF(("-S-GLMContext::SetProgramParametersI %s slots %d - %d: ", (type==kGLMVertexProgram) ? "VS" : "FS", baseSlot, baseSlot + slotCount - 1 )); + for( uint i=0; i m_programParamsI[type].m_dirtySlotCount) + { + m_programParamsI[type].m_dirtySlotCount = baseSlot + slotCount; + } +} + +FORCEINLINE void GLMContext::SetSamplerDirty( int sampler ) +{ + Assert( sampler < GLM_SAMPLER_COUNT ); + m_nDirtySamplers[m_nNumDirtySamplers] = sampler; + m_nNumDirtySamplers += m_nDirtySamplerFlags[sampler]; + m_nDirtySamplerFlags[sampler] = 0; +} + +FORCEINLINE void GLMContext::SetSamplerTex( int sampler, CGLMTex *tex ) +{ + Assert( sampler < GLM_SAMPLER_COUNT ); + m_samplers[sampler].m_pBoundTex = tex; + if ( tex ) + { + if ( !gGL->m_bHave_GL_EXT_direct_state_access ) + { + if ( sampler != m_activeTexture ) + { + gGL->glActiveTexture( GL_TEXTURE0 + sampler ); + m_activeTexture = sampler; + } + + gGL->glBindTexture( tex->m_texGLTarget, tex->m_texName ); + } + else + { + gGL->glBindMultiTextureEXT( GL_TEXTURE0 + sampler, tex->m_texGLTarget, tex->m_texName ); + } + } + + if ( !m_bUseSamplerObjects ) + { + SetSamplerDirty( sampler ); + } +} + +FORCEINLINE void GLMContext::SetSamplerMinFilter( int sampler, GLenum Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS ) ); + m_samplers[sampler].m_samp.m_packed.m_minFilter = Value; +} + +FORCEINLINE void GLMContext::SetSamplerMagFilter( int sampler, GLenum Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS ) ); + m_samplers[sampler].m_samp.m_packed.m_magFilter = Value; +} + +FORCEINLINE void GLMContext::SetSamplerMipFilter( int sampler, GLenum Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS ) ); + m_samplers[sampler].m_samp.m_packed.m_mipFilter = Value; +} + +FORCEINLINE void GLMContext::SetSamplerAddressU( int sampler, GLenum Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) ); + m_samplers[sampler].m_samp.m_packed.m_addressU = Value; +} + +FORCEINLINE void GLMContext::SetSamplerAddressV( int sampler, GLenum Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) ); + m_samplers[sampler].m_samp.m_packed.m_addressV = Value; +} + +FORCEINLINE void GLMContext::SetSamplerAddressW( int sampler, GLenum Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) ); + m_samplers[sampler].m_samp.m_packed.m_addressW = Value; +} + +FORCEINLINE void GLMContext::SetSamplerStates( int sampler, GLenum AddressU, GLenum AddressV, GLenum AddressW, GLenum minFilter, GLenum magFilter, GLenum mipFilter, int minLod, float lodBias ) +{ + Assert( AddressU < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) ); + Assert( AddressV < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) ); + Assert( AddressW < ( 1 << GLM_PACKED_SAMPLER_PARAMS_ADDRESS_BITS) ); + Assert( minFilter < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIN_FILTER_BITS ) ); + Assert( magFilter < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MAG_FILTER_BITS ) ); + Assert( mipFilter < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIP_FILTER_BITS ) ); + Assert( minLod < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS ) ); + + GLMTexSamplingParams ¶ms = m_samplers[sampler].m_samp; + params.m_packed.m_addressU = AddressU; + params.m_packed.m_addressV = AddressV; + params.m_packed.m_addressW = AddressW; + params.m_packed.m_minFilter = minFilter; + params.m_packed.m_magFilter = magFilter; + params.m_packed.m_mipFilter = mipFilter; + params.m_packed.m_minLOD = minLod; + + params.m_lodBias = lodBias; +} + +FORCEINLINE void GLMContext::SetSamplerBorderColor( int sampler, DWORD Value ) +{ + m_samplers[sampler].m_samp.m_borderColor = Value; +} + +FORCEINLINE void GLMContext::SetSamplerMipMapLODBias( int sampler, DWORD Value ) +{ + typedef union { + DWORD asDword; + float asFloat; + } Convert_t; + + Convert_t c; + c.asDword = Value; + + m_samplers[sampler].m_samp.m_lodBias = c.asFloat; +} + +FORCEINLINE void GLMContext::SetSamplerMaxMipLevel( int sampler, DWORD Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MIN_LOD_BITS ) ); + m_samplers[sampler].m_samp.m_packed.m_minLOD = Value; +} + +FORCEINLINE void GLMContext::SetSamplerMaxAnisotropy( int sampler, DWORD Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_MAX_ANISO_BITS ) ); + m_samplers[sampler].m_samp.m_packed.m_maxAniso = Value; +} + +FORCEINLINE void GLMContext::SetSamplerSRGBTexture( int sampler, DWORD Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_SRGB_BITS ) ); + m_samplers[sampler].m_samp.m_packed.m_srgb = Value; +} + +FORCEINLINE void GLMContext::SetShadowFilter( int sampler, DWORD Value ) +{ + Assert( Value < ( 1 << GLM_PACKED_SAMPLER_PARAMS_COMPARE_MODE_BITS ) ); + m_samplers[sampler].m_samp.m_packed.m_compareMode = Value; +} + +FORCEINLINE void GLMContext::BindIndexBufferToCtx( CGLMBuffer *buff ) +{ + GLMPRINTF(( "--- GLMContext::BindIndexBufferToCtx buff %p, GL name %d", buff, (buff) ? buff->m_nHandle : -1 )); + + Assert( !buff || ( buff->m_buffGLTarget == GL_ELEMENT_ARRAY_BUFFER ) ); + + GLuint nGLName = buff ? buff->GetHandle() : 0; + + if ( m_nBoundGLBuffer[ kGLMIndexBuffer] == nGLName ) + return; + + m_nBoundGLBuffer[ kGLMIndexBuffer] = nGLName; + gGL->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, nGLName ); +} + +FORCEINLINE void GLMContext::BindVertexBufferToCtx( CGLMBuffer *buff ) +{ + GLMPRINTF(( "--- GLMContext::BindVertexBufferToCtx buff %p, GL name %d", buff, (buff) ? buff->m_nHandle : -1 )); + + Assert( !buff || ( buff->m_buffGLTarget == GL_ARRAY_BUFFER ) ); + + GLuint nGLName = buff ? buff->GetHandle() : 0; + + if ( m_nBoundGLBuffer[ kGLMVertexBuffer] == nGLName ) + return; + + m_nBoundGLBuffer[ kGLMVertexBuffer] = nGLName; + gGL->glBindBuffer( GL_ARRAY_BUFFER, nGLName ); +} + +FORCEINLINE void GLMContext::SetMaxUsedVertexShaderConstantsHint( uint nMaxConstants ) +{ + static bool bUseMaxVertexShadeConstantHints = !CommandLine()->CheckParm("-disablemaxvertexshaderconstanthints"); + if ( bUseMaxVertexShadeConstantHints ) + { + m_nMaxUsedVertexProgramConstantsHint = nMaxConstants; + } +} + +struct GLMTestParams +{ + GLMContext *m_ctx; + int *m_testList; // -1 termed + + bool m_glErrToDebugger; + bool m_glErrToConsole; + + bool m_intlErrToDebugger; + bool m_intlErrToConsole; + + int m_frameCount; // how many frames to test. +}; + +class GLMTester +{ + public: + + GLMTester(GLMTestParams *params); + ~GLMTester(); + + + // optionally callable by test routines to get basic drawables wired up + void StdSetup( void ); + void StdCleanup( void ); + + // callable by test routines to clear the frame or present it + void Clear( void ); + void Present( int seed ); + + // error reporting + void CheckGLError( const char *comment ); // obey m_params setting for console / debugger response + void InternalError( int errcode, char *comment ); // if errcode!=0, obey m_params setting for console / debugger response + + void RunTests(); + + void RunOneTest( int testindex ); + + // test routines themselves + void Test0(); + void Test1(); + void Test2(); + void Test3(); + + GLMTestParams m_params; // copy of caller's params, do not mutate... + + // std-setup stuff + int m_drawWidth, m_drawHeight; + CGLMFBO *m_drawFBO; + CGLMTex *m_drawColorTex; + CGLMTex *m_drawDepthTex; +}; + +class CShowPixelsParams +{ +public: + GLuint m_srcTexName; + int m_width,m_height; + bool m_vsyncEnable; + bool m_fsEnable; // want receiving view to be full screen. for now, just target the main screen. extend later. + bool m_useBlit; // use FBO blit - sending context says it is available. + bool m_noBlit; // the back buffer has already been populated by the caller (perhaps via direct MSAA resolve from multisampled RT tex) + bool m_onlySyncView; // react to full/windowed state change only, do not present bits +}; + +#define kMaxCrawlFrames 100 +#define kMaxCrawlText (kMaxCrawlFrames * 256) +class CStackCrawlParams +{ + public: + uint m_frameLimit; // input: max frames to retrieve + uint m_frameCount; // output: frames found + void *m_crawl[kMaxCrawlFrames]; // call site addresses + char *m_crawlNames[kMaxCrawlFrames]; // pointers into text following, one per decoded name + char m_crawlText[kMaxCrawlText]; +}; + +#endif // GLMGR_H diff --git a/public/togles/linuxwin/glmgrbasics.h b/public/togles/linuxwin/glmgrbasics.h new file mode 100644 index 00000000..a32938ad --- /dev/null +++ b/public/togles/linuxwin/glmgrbasics.h @@ -0,0 +1,332 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glmgrbasics.h +// types, common headers, forward declarations, utilities +// +//=============================================================================== + +#ifndef GLMBASICS_H +#define GLMBASICS_H + +#pragma once + +#ifdef USE_SDL +#include "SDL_opengl.h" +#endif + +#ifdef OSX + #include + #include + #include + #include + +#ifndef MAC_OS_X_VERSION_10_9 + #include + #include +#endif +#endif + +#include "tier0/platform.h" + +#include "bitmap/imageformat.h" +#include "bitvec.h" +#include "tier1/checksum_md5.h" +#include "tier1/utlvector.h" +#include "tier1/convar.h" + +#include + +#include "dxabstract_types.h" + +struct GLMRect; +typedef void *PseudoGLContextPtr; + +// types + + // 3-d integer box (used for texture lock/unlock etc) +struct GLMRegion +{ + int xmin,xmax; + int ymin,ymax; + int zmin,zmax; +}; + +struct GLMRect // follows GL convention - if coming from the D3D rect you will need to fiddle the Y's +{ + int xmin; // left + int ymin; // bottom + int xmax; // right + int ymax; // top +}; + +// macros + +//#define GLMassert(x) assert(x) + +// forward decls +class GLMgr; // singleton +class GLMContext; // GL context +class CGLMContextTester; // testing class +class CGLMTex; +class CGLMFBO; +class CGLMProgram; +class CGLMBuffer; + + +// utilities + +typedef enum +{ + // D3D codes + eD3D_DEVTYPE, + eD3D_FORMAT, + eD3D_RTYPE, + eD3D_USAGE, + eD3D_RSTATE, // render state + eD3D_SIO, // D3D shader bytecode + eD3D_VTXDECLUSAGE, + + // CGL codes + eCGL_RENDID, + + // OpenGL error codes + eGL_ERROR, + + // OpenGL enums + eGL_ENUM, + eGL_RENDERER + +} GLMThing_t; + +// these will look at the string to guess its flavor: <, >, ---, -M-, -S- +#ifdef TOGL_DLL_EXPORT + DLL_EXPORT const char* GLMDecode( GLMThing_t type, unsigned long value ); // decode a numeric const +#else + DLL_IMPORT const char* GLMDecode( GLMThing_t type, unsigned long value ); // decode a numeric const +#endif + +const char* GLMDecodeMask( GLMThing_t type, unsigned long value ); // decode a bitmask + +FORCEINLINE void GLMStop( void ) { DXABSTRACT_BREAK_ON_ERROR(); } + +void GLMEnableTrace( bool on ); + +//=============================================================================== +// output functions + +// expose these in release now +// Mimic PIX events so we can decorate debug spew +DLL_EXPORT void GLMBeginPIXEvent( const char *str ); +DLL_EXPORT void GLMEndPIXEvent( void ); + +class CScopedGLMPIXEvent +{ + CScopedGLMPIXEvent( const CScopedGLMPIXEvent & ); + CScopedGLMPIXEvent& operator= ( const CScopedGLMPIXEvent & ); +public: + inline CScopedGLMPIXEvent( const char *pName ) { GLMBeginPIXEvent( pName ); } + inline ~CScopedGLMPIXEvent() { GLMEndPIXEvent( ); } +}; + +#if GLMDEBUG + + +//=============================================================================== +// classes + +// helper class making function tracking easier to wire up + +class GLMFuncLogger +{ + public: + + // simple function log + GLMFuncLogger( const char *funcName ) + { + m_funcName = funcName; + m_earlyOut = false; + + GLMPrintf( ">%s", m_funcName ); + }; + + // more advanced version lets you pass args (i.e. called parameters or anything else of interest) + // no macro for this one, since no easy way to pass through the args as well as the funcname + GLMFuncLogger( const char *funcName, char *fmt, ... ) + { + m_funcName = funcName; + m_earlyOut = false; + + // this acts like GLMPrintf here + // all the indent policy is down in GLMPrintfVA + // which means we need to inject a ">" at the front of the format string to make this work... sigh. + + char modifiedFmt[2000]; + modifiedFmt[0] = '>'; + strcpy( modifiedFmt+1, fmt ); + + va_list vargs; + va_start(vargs, fmt); + GLMPrintfVA( modifiedFmt, vargs ); + va_end( vargs ); + } + + ~GLMFuncLogger( ) + { + if (m_earlyOut) + { + GLMPrintf( "<%s (early out)", m_funcName ); + } + else + { + GLMPrintf( "<%s", m_funcName ); + } + }; + + void EarlyOut( void ) + { + m_earlyOut = true; + }; + + const char *m_funcName; // set at construction time + bool m_earlyOut; +}; + +// handy macro to go with the function tracking class +#define GLM_FUNC GLMFuncLogger _logger_ ( __FUNCTION__ ) +#else +#define GLM_FUNC tmZone( TELEMETRY_LEVEL1, TMZF_NONE, "%s", __FUNCTION__ ) +#endif + + +// class to keep an in-memory mirror of a file which may be getting edited during run +class CGLMFileMirror +{ +public: + CGLMFileMirror( char *fullpath ); // just associates mirror with file. if file exists it will be read. + //if non existent it will be created with size zero + ~CGLMFileMirror( ); + + bool HasData( void ); // see if data avail + void GetData( char **dataPtr, uint *dataSizePtr ); // read it out + void SetData( char *data, uint dataSize ); // put data in (and write it to disk) + bool PollForChanges( void ); // check disk copy. If different, read it back in and return true. + + void UpdateStatInfo( void ); // make sure stat info is current for our file + void ReadFile( void ); + void WriteFile( void ); + + void OpenInEditor( bool foreground=false ); // pass TRUE if you would like the editor to pop to foreground + + /// how about a "wait for change" method.. + + char *m_path; // fullpath to file + bool m_exists; + struct stat m_stat; // stat results for the file (last time checked) + + char *m_data; // content of file + uint m_size; // length of content + +}; + +// class based on the file mirror, that makes it easy to edit them outside the app. + +// it receives an initial block of text from the engine, and hashes it. ("orig") +// it munges it by duplicating all the text after the "!!" line, and appending it in commented form. ("munged") +// a mirror file is activated, using a filename based on the hash from the orig text. +// if there is already content on disk matching that filename, use that content *unless* the 'blitz' parameter is set. +// (i.e. engine is instructing this subsystem to wipe out any old/modified variants of the text) + + +class CGLMEditableTextItem +{ +public: + CGLMEditableTextItem( char *text, uint size, bool forceOverwrite, char *prefix, char *suffix = NULL ); // create a text blob from text source, optional filename suffix + ~CGLMEditableTextItem( ); + + bool HasData( void ); + bool PollForChanges( void ); // return true if stale i.e. you need to get a new edition + void GetCurrentText( char **textOut, uint *sizeOut ); // query for read access to the active blob (could be the original, could be external edited copy) + void OpenInEditor( bool foreground=false ); // call user attention to this text + + // internal methods + void GenHashOfOrigText( void ); + void GenBaseNameAndFullPath( char *prefix, char *suffix ); + void GenMungedText( bool fromMirror ); + + // members + // orig + uint m_origSize; + char *m_origText; // what was submitted + unsigned char m_origDigest[MD5_DIGEST_LENGTH]; // digest of what was submitted + + // munged + uint m_mungedSize; + char *m_mungedText; // re-processed edition, initial content submission to the file mirror + + // mirror + char *m_mirrorBaseName; // generated from the hash of the orig text, plus the label / prefix + char *m_mirrorFullPath; // base name + CGLMFileMirror *m_mirror; // file mirror itself. holds "official" copy for GetCurrentText to return. +}; + + +// debug font +extern unsigned char g_glmDebugFontMap[16384]; + +// class for cracking multi-part text blobs +// sections are demarcated by beginning-of-line markers submitted in a table by the caller + +struct GLMTextSection +{ + int m_markerIndex; // based on table of markers passed in to constructor + uint m_textOffset; // where is the text - offset + int m_textLength; // how big is the section +}; + +class CGLMTextSectioner +{ +public: + CGLMTextSectioner( char *text, int textSize, const char **markers ); // constructor finds all the sections + ~CGLMTextSectioner( ); + + int Count( void ); // how many sections found + void GetSection( int index, uint *offsetOut, uint *lengthOut, int *markerIndexOut ); + // find section, size, what marker + // note that more than one section can be marked similarly. + // so policy isn't made here, you walk the sections and decide what to do if there are dupes. + + //members + + //section table + CUtlVector< GLMTextSection > m_sectionTable; +}; + +#ifndef OSX +void GLMGPUTimestampManagerInit(); +void GLMGPUTimestampManagerDeinit(); +void GLMGPUTimestampManagerTick(); +#endif + +#endif // GLMBASICS_H diff --git a/public/togles/linuxwin/glmgrext.h b/public/togles/linuxwin/glmgrext.h new file mode 100644 index 00000000..393942a7 --- /dev/null +++ b/public/togles/linuxwin/glmgrext.h @@ -0,0 +1,123 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glmgrext.h +// helper file for extension testing and runtime importing of entry points +// +//=============================================================================== + +#pragma once + +#ifdef OSX +#include +#include +#elif defined(DX_TO_GL_ABSTRACTION) +#include +#include +#else +#error +#endif + +#ifndef GL_EXT_framebuffer_sRGB + #define GL_FRAMEBUFFER_SRGB_EXT 0x8DB9 + #define GL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x8DBA +#endif + +#ifndef ARB_texture_rg + #define GL_COMPRESSED_RED 0x8225 + #define GL_COMPRESSED_RG 0x8226 + #define GL_RG 0x8227 + #define GL_RG_INTEGER 0x8228 + #define GL_R8 0x8229 + #define GL_R16 0x822A + #define GL_RG8 0x822B + #define GL_RG16 0x822C + #define GL_R16F 0x822D + #define GL_R32F 0x822E + #define GL_RG16F 0x822F + #define GL_RG32F 0x8230 + #define GL_R8I 0x8231 + #define GL_R8UI 0x8232 + #define GL_R16I 0x8233 + #define GL_R16UI 0x8234 + #define GL_R32I 0x8235 + #define GL_R32UI 0x8236 + #define GL_RG8I 0x8237 + #define GL_RG8UI 0x8238 + #define GL_RG16I 0x8239 + #define GL_RG16UI 0x823A + #define GL_RG32I 0x823B + #define GL_RG32UI 0x823C +#endif + +#ifndef GL_EXT_bindable_uniform + #define GL_UNIFORM_BUFFER_EXT 0x8DEE +#endif + +// unpublished extension enums (thus the "X") + +// from EXT_framebuffer_multisample_blit_scaled.. +#define XGL_SCALED_RESOLVE_FASTEST_EXT 0x90BA +#define XGL_SCALED_RESOLVE_NICEST_EXT 0x90BB + +#ifndef GL_TEXTURE_MINIMIZE_STORAGE_APPLE +#define GL_TEXTURE_MINIMIZE_STORAGE_APPLE 0x85B6 +#endif + +#ifndef GL_ALL_COMPLETED_NV +#define GL_ALL_COMPLETED_NV 0x84F2 +#endif + +#ifndef GL_MAP_READ_BIT +#define GL_MAP_READ_BIT 0x0001 +#endif + +#ifndef GL_MAP_WRITE_BIT +#define GL_MAP_WRITE_BIT 0x0002 +#endif + +#ifndef GL_MAP_INVALIDATE_RANGE_BIT +#define GL_MAP_INVALIDATE_RANGE_BIT 0x0004 +#endif + +#ifndef GL_MAP_INVALIDATE_BUFFER_BIT +#define GL_MAP_INVALIDATE_BUFFER_BIT 0x0008 +#endif + +#ifndef GL_MAP_FLUSH_EXPLICIT_BIT +#define GL_MAP_FLUSH_EXPLICIT_BIT 0x0010 +#endif + +#ifndef GL_MAP_UNSYNCHRONIZED_BIT +#define GL_MAP_UNSYNCHRONIZED_BIT 0x0020 +#endif + +#ifndef GL_MAP_PERSISTENT_BIT +#define GL_MAP_PERSISTENT_BIT 0x0040 +#endif + +#ifndef GL_MAP_COHERENT_BIT +#define GL_MAP_COHERENT_BIT 0x0080 +#endif + diff --git a/public/togles/rendermechanism.h b/public/togles/rendermechanism.h new file mode 100644 index 00000000..0fc76982 --- /dev/null +++ b/public/togles/rendermechanism.h @@ -0,0 +1,73 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +#ifndef RENDERMECHANISM_H +#define RENDERMECHANISM_H + +#if defined(DX_TO_GL_ABSTRACTION) + +#undef PROTECTED_THINGS_ENABLE + +#include +#include + +#include "tier0/basetypes.h" +#include "tier0/platform.h" + +#include "togles/linuxwin/glmdebug.h" +#include "togles/linuxwin/glbase.h" +#include "togles/linuxwin/glentrypoints.h" +#include "togles/linuxwin/glmdisplay.h" +#include "togles/linuxwin/glmdisplaydb.h" +#include "togles/linuxwin/glmgrbasics.h" +#include "togles/linuxwin/glmgrext.h" +#include "togles/linuxwin/cglmbuffer.h" +#include "togles/linuxwin/cglmtex.h" +#include "togles/linuxwin/cglmfbo.h" +#include "togles/linuxwin/cglmprogram.h" +#include "togles/linuxwin/cglmquery.h" +#include "togles/linuxwin/glmgr.h" +#include "togles/linuxwin/dxabstract_types.h" +#include "togles/linuxwin/dxabstract.h" + +#else + //USE_ACTUAL_DX + #ifdef WIN32 + #ifdef _X360 + #include "d3d9.h" + #include "d3dx9.h" + #else + #include + #include "../../dx9sdk/include/d3d9.h" + #include "../../dx9sdk/include/d3dx9.h" + #endif + typedef HWND VD3DHWND; + #endif + + #define GLMPRINTF(args) + #define GLMPRINTSTR(args) + #define GLMPRINTTEXT(args) +#endif // defined(DX_TO_GL_ABSTRACTION) + +#endif // RENDERMECHANISM_H diff --git a/scripts/waifulib/compiler_optimizations.py b/scripts/waifulib/compiler_optimizations.py index 90dbcbe5..56c35c1e 100644 --- a/scripts/waifulib/compiler_optimizations.py +++ b/scripts/waifulib/compiler_optimizations.py @@ -48,8 +48,8 @@ CFLAGS = { 'common': { # disable thread-safe local static initialization for C++11 code, as it cause crashes on Windows XP 'msvc': ['/D_USING_V110_SDK71_', '/Zi', '/FS', '/Zc:threadSafeInit-', '/MT'], - 'clang': ['-g', '-gdwarf-2', '-fvisibility=hidden'], - 'gcc': ['-g', '-fvisibility=hidden'], + 'clang': ['-g0', '-gdwarf-2', '-fvisibility=hidden'], + 'gcc': ['-g0', '-fvisibility=hidden'], 'owcc': ['-fno-short-enum', '-ffloat-store', '-g3'] }, 'fast': { @@ -75,7 +75,7 @@ CFLAGS = { 'debug': { 'msvc': ['/Od'], 'owcc': ['-O0', '-fno-omit-frame-pointer', '-funwind-tables', '-fno-omit-leaf-frame-pointer'], - 'default': ['-O0'] + 'default': ['-O2', '-ftree-vectorize'] }, 'sanitize': { 'msvc': ['/Od', '/RTC1'], diff --git a/scripts/waifulib/xcompile.py b/scripts/waifulib/xcompile.py index fc5ab628..df70352d 100644 --- a/scripts/waifulib/xcompile.py +++ b/scripts/waifulib/xcompile.py @@ -255,7 +255,7 @@ class Android: if self.is_arm(): if self.arch == 'armeabi-v7a': # ARMv7 support - cflags += ['-mthumb', '-mfpu=neon', '-mcpu=cortex-a9', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS', '-DVECTORIZE_SINCOS'] + cflags += ['-mthumb', '-mfpu=neon-vfpv4', '-mcpu=cortex-a7', '-mtune=cortex-a7', '-DHAVE_EFFICIENT_UNALIGNED_ACCESS', '-DVECTORIZE_SINCOS'] if not self.is_clang() and not self.is_host(): cflags += [ '-mvectorize-with-neon-quad' ] diff --git a/serverbrowser/CustomGames.cpp b/serverbrowser/CustomGames.cpp index 6ccd33fe..d5e71a3c 100644 --- a/serverbrowser/CustomGames.cpp +++ b/serverbrowser/CustomGames.cpp @@ -211,7 +211,7 @@ bool CCustomGames::CheckTagFilter( gameserveritem_t &server ) V_SplitString( m_szTagFilter, ",", TagList ); for ( int i = 0; i < TagList.Count(); i++ ) { - if ( ( Q_strnistr( server.m_szGameTags, TagList[i], MAX_TAG_CHARACTERS ) ) == TagsExclude() ) + if ( ( Q_strnistr( server.m_szGameTags, TagList[i], MAX_TAG_CHARACTERS ) != 0 ) == TagsExclude() ) { bRetVal = false; break; diff --git a/tier1/interface.cpp b/tier1/interface.cpp index 96dd90c9..8170186f 100644 --- a/tier1/interface.cpp +++ b/tier1/interface.cpp @@ -308,12 +308,20 @@ CSysModule *Sys_LoadModule( const char *pModuleName, Sys_Flags flags /* = SYS_NO struct stat statBuf; char *dataPath = getenv("APP_DATA_PATH"); + char *modLibPath = getenv("APP_MOD_LIB"); + if( modLibPath && *modLibPath ) // first load library from mod launcher + { + Q_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/lib%s", modLibPath, pModuleName); + if( stat(szAbsoluteModuleName, &statBuf) != 0 ) + Q_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/%s", modLibPath, pModuleName); + + hDLL = Sys_LoadLibrary(szAbsoluteModuleName, flags); + } Q_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/lib/lib%s", dataPath ,pModuleName); if( stat(szAbsoluteModuleName, &statBuf) != 0 ) Q_snprintf(szAbsoluteModuleName, sizeof(szAbsoluteModuleName), "%s/lib/%s", dataPath ,pModuleName); #else - #ifdef POSIX struct stat statBuf; Q_snprintf(szModuleName, sizeof(szModuleName), "bin/lib%s", pModuleName); @@ -326,7 +334,8 @@ CSysModule *Sys_LoadModule( const char *pModuleName, Sys_Flags flags /* = SYS_NO #endif // ANDROID Msg("LoadLibrary: pModule: %s, path: %s\n", pModuleName, szAbsoluteModuleName); - hDLL = Sys_LoadLibrary( szAbsoluteModuleName, flags ); + if( !hDLL ) + hDLL = Sys_LoadLibrary( szAbsoluteModuleName, flags ); } else Msg("LoadLibrary: path: %s\n", pModuleName); diff --git a/tier1/strtools.cpp b/tier1/strtools.cpp index cfef6b13..af4fa688 100644 --- a/tier1/strtools.cpp +++ b/tier1/strtools.cpp @@ -79,6 +79,7 @@ #include "xbox/xbox_win32stubs.h" #endif #include "tier0/memdbgon.h" +#include "iconv.h" static int FastToLower( char c ) { diff --git a/togles/linuxwin/asanstubs.cpp b/togles/linuxwin/asanstubs.cpp new file mode 100644 index 00000000..d2caa6c1 --- /dev/null +++ b/togles/linuxwin/asanstubs.cpp @@ -0,0 +1,17 @@ +typedef unsigned int uint; + +#include "../public/togles/linuxwin/glmdisplay.h" +#include "../public/togles/linuxwin/glmdisplaydb.h" + +void GLMDisplayDB::PopulateRenderers( void ) { } +void GLMDisplayDB::PopulateFakeAdapters( uint realRendererIndex ) { } // fake adapters = one real adapter times however many displays are on +void GLMDisplayDB::Populate( void ) { } +int GLMDisplayDB::GetFakeAdapterCount( void ) { return 1; } +bool GLMDisplayDB::GetFakeAdapterInfo( int fakeAdapterIndex, int *rendererOut, int *displayOut, GLMRendererInfoFields *rendererInfoOut, GLMDisplayInfoFields *displayInfoOut ) { return true; } +int GLMDisplayDB::GetRendererCount( void ) { return 1; } +bool GLMDisplayDB::GetRendererInfo( int rendererIndex, GLMRendererInfoFields *infoOut ) { return true; } +int GLMDisplayDB::GetDisplayCount( int rendererIndex ) { return 1; } +bool GLMDisplayDB::GetDisplayInfo( int rendererIndex, int displayIndex, GLMDisplayInfoFields *infoOut ) { return true; } +int GLMDisplayDB::GetModeCount( int rendererIndex, int displayIndex ) { } +bool GLMDisplayDB::GetModeInfo( int rendererIndex, int displayIndex, int modeIndex, GLMDisplayModeInfoFields *infoOut ) { return false; } +void GLMDisplayDB::Dump( void ) { } diff --git a/togles/linuxwin/cglmbuffer.cpp b/togles/linuxwin/cglmbuffer.cpp new file mode 100644 index 00000000..14679260 --- /dev/null +++ b/togles/linuxwin/cglmbuffer.cpp @@ -0,0 +1,1136 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmbuffer.cpp +// +//=============================================================================== + +#include "togles/rendermechanism.h" + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + +// 7LS TODO : took out cmdline here +bool g_bUsePseudoBufs = false; //( Plat_GetCommandLineA() ) ? ( strstr( Plat_GetCommandLineA(), "-gl_enable_pseudobufs" ) != NULL ) : false; +#ifdef OSX +// Significant perf degradation on some OSX parts if static buffers not disabled +bool g_bDisableStaticBuffer = true; +#else +bool g_bDisableStaticBuffer = true; //( Plat_GetCommandLineA() ) ? ( strstr( Plat_GetCommandLineA(), "-gl_disable_static_buffer" ) != NULL ) : false; +#endif + +// http://www.opengl.org/registry/specs/ARB/vertex_buffer_object.txt +// http://www.opengl.org/registry/specs/ARB/pixel_buffer_object.txt + +// gl_bufmode: zero means we mark all vertex/index buffers static + +// non zero means buffers are initially marked static.. +// ->but can shift to dynamic upon first 'discard' (orphaning) + +// #define REPORT_LOCK_TIME 0 + +ConVar gl_bufmode( "gl_bufmode", "1" ); + +char ALIGN16 CGLMBuffer::m_StaticBuffers[ GL_MAX_STATIC_BUFFERS ][ GL_STATIC_BUFFER_SIZE ] ALIGN16_POST; +bool CGLMBuffer::m_bStaticBufferUsed[ GL_MAX_STATIC_BUFFERS ]; + +extern bool g_bNullD3DDevice; + +//===========================================================================// + +static uint gMaxPersistentOffset[kGLMNumBufferTypes] = +{ + 0, + 0, + 0, + 0 +}; +CON_COMMAND( gl_persistent_buffer_max_offset, "" ) +{ + ConMsg( "OpenGL Persistent buffer max offset :\n" ); + ConMsg( " Vertex buffer : %d bytes (%f MB) \n", gMaxPersistentOffset[kGLMVertexBuffer], gMaxPersistentOffset[kGLMVertexBuffer] / (1024.0f*1024.0f) ); + ConMsg( " Index buffer : %d bytes (%f MB) \n", gMaxPersistentOffset[kGLMIndexBuffer], gMaxPersistentOffset[kGLMIndexBuffer] / (1024.0f*1024.0f) ); + ConMsg( " Uniform buffer : %d bytes (%f MB) \n", gMaxPersistentOffset[kGLMUniformBuffer], gMaxPersistentOffset[kGLMUniformBuffer] / (1024.0f*1024.0f) ); + ConMsg( " Pixel buffer : %d bytes (%f MB) \n", gMaxPersistentOffset[kGLMPixelBuffer], gMaxPersistentOffset[kGLMPixelBuffer] / (1024.0f*1024.0f) ); +} + +CPersistentBuffer::CPersistentBuffer() +: + m_nSize( 0 ) + , m_nHandle( 0 ) + , m_pImmutablePersistentBuf( NULL ) + , m_nOffset( 0 ) +#ifdef HAVE_GL_ARB_SYNC + , m_nSyncObj( 0 ) +#endif +{} + +CPersistentBuffer::~CPersistentBuffer() +{ + Deinit(); +} + +void CPersistentBuffer::Init( EGLMBufferType type,uint nSize ) +{ +// Assert( gGL->m_bHave_GL_EXT_buffer_storage ); +// Assert( gGL->m_bHave_GL_ARB_map_buffer_range ); + + m_nSize = nSize; + m_nOffset = 0; + m_type = type; + + switch ( type ) + { + case kGLMVertexBuffer: m_buffGLTarget = GL_ARRAY_BUFFER; break; + case kGLMIndexBuffer: m_buffGLTarget = GL_ELEMENT_ARRAY_BUFFER; break; + + default: Assert( nSize == 0 ); + } + + if ( m_nSize > 0 ) + { + gGL->glGenBuffers( 1, &m_nHandle ); + gGL->glBindBuffer( m_buffGLTarget, m_nHandle ); + + // Create persistent immutable buffer that we will permanently map. This buffer can be written from any thread (not just + // the renderthread) + gGL->glBufferStorageEXT( m_buffGLTarget, m_nSize, (const GLvoid *)NULL, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT ); // V_GL_REQ: GL_EXT_buffer_storage, GL_ARB_map_buffer_range, GL_VERSION_4_4 + + // Map the buffer for all of eternity. Pointer can be used from multiple threads. + m_pImmutablePersistentBuf = gGL->glMapBufferRange( m_buffGLTarget, 0, m_nSize, GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT ); // V_GL_REQ: GL_ARB_map_buffer_range, GL_EXT_buffer_storage, GL_VERSION_4_4 + Assert( m_pImmutablePersistentBuf != NULL ); + } +} + +void CPersistentBuffer::Deinit() +{ + if ( !m_pImmutablePersistentBuf ) + { + return; + } + + BlockUntilNotBusy(); + + gGL->glBindBuffer( m_buffGLTarget, m_nHandle ); + gGL->glUnmapBuffer( m_buffGLTarget ); + gGL->glBindBuffer( m_buffGLTarget, 0 ); + + gGL->glDeleteBuffers( 1, &m_nHandle ); + + m_nSize = 0; + m_nHandle = 0; + m_nOffset = 0; + m_pImmutablePersistentBuf = NULL; +} + +void CPersistentBuffer::InsertFence() +{ +#ifdef HAVE_GL_ARB_SYNC + if (m_nSyncObj) + { + gGL->glDeleteSync( m_nSyncObj ); + } + + m_nSyncObj = gGL->glFenceSync( GL_SYNC_GPU_COMMANDS_COMPLETE, 0 ); +#endif +} + +void CPersistentBuffer::BlockUntilNotBusy() +{ +#ifdef HAVE_GL_ARB_SYNC + if (m_nSyncObj) + { + gGL->glClientWaitSync( m_nSyncObj, GL_SYNC_FLUSH_COMMANDS_BIT, 3000000000000ULL ); + + gGL->glDeleteSync( m_nSyncObj ); + + m_nSyncObj = 0; + } +#endif + m_nOffset = 0; +} + +void CPersistentBuffer::Append( uint nSize ) +{ + m_nOffset += nSize; + Assert( m_nOffset <= m_nSize ); + + gMaxPersistentOffset[m_type] = Max( m_nOffset, gMaxPersistentOffset[m_type] ); +} + +//===========================================================================// + +#if GL_ENABLE_INDEX_VERIFICATION + +CGLMBufferSpanManager::CGLMBufferSpanManager() : + m_pCtx( NULL ), + m_nBufType( kGLMVertexBuffer ), + m_nBufSize( 0 ), + m_bDynamic( false ), + m_nSpanEndMax( -1 ), + m_nNumAllocatedBufs( 0 ), + m_nTotalBytesAllocated( 0 ) +{ +} + +CGLMBufferSpanManager::~CGLMBufferSpanManager() +{ + Deinit(); +} + +void CGLMBufferSpanManager::Init( GLMContext *pContext, EGLMBufferType nBufType, uint nInitialCapacity, uint nBufSize, bool bDynamic ) +{ + Assert( ( nBufType == kGLMIndexBuffer ) || ( nBufType == kGLMVertexBuffer ) ); + + m_pCtx = pContext; + m_nBufType = nBufType; + + m_nBufSize = nBufSize; + m_bDynamic = bDynamic; + + m_ActiveSpans.EnsureCapacity( nInitialCapacity ); + m_DeletedSpans.EnsureCapacity( nInitialCapacity ); + m_nSpanEndMax = -1; + + m_nNumAllocatedBufs = 0; + m_nTotalBytesAllocated = 0; +} + +bool CGLMBufferSpanManager::AllocDynamicBuf( uint nSize, GLDynamicBuf_t &buf ) +{ + buf.m_nGLType = GetGLBufType(); + buf.m_nActualBufSize = nSize; + buf.m_nHandle = 0; + buf.m_nSize = nSize; + + m_nNumAllocatedBufs++; + m_nTotalBytesAllocated += buf.m_nActualBufSize; + + return true; +} + +void CGLMBufferSpanManager::ReleaseDynamicBuf( GLDynamicBuf_t &buf ) +{ + Assert( m_nNumAllocatedBufs > 0 ); + m_nNumAllocatedBufs--; + + Assert( m_nTotalBytesAllocated >= (int)buf.m_nActualBufSize ); + m_nTotalBytesAllocated -= buf.m_nActualBufSize; +} + +void CGLMBufferSpanManager::Deinit() +{ + if ( !m_pCtx ) + return; + + for ( int i = 0; i < m_ActiveSpans.Count(); i++ ) + { + if ( m_ActiveSpans[i].m_bOriginalAlloc ) + ReleaseDynamicBuf( m_ActiveSpans[i].m_buf ); + } + m_ActiveSpans.SetCountNonDestructively( 0 ); + + for ( int i = 0; i < m_DeletedSpans.Count(); i++ ) + ReleaseDynamicBuf( m_DeletedSpans[i].m_buf ); + + m_DeletedSpans.SetCountNonDestructively( 0 ); + + m_pCtx->BindGLBufferToCtx( GetGLBufType(), NULL, true ); + + m_nSpanEndMax = -1; + m_pCtx = NULL; + + Assert( !m_nNumAllocatedBufs ); + Assert( !m_nTotalBytesAllocated ); +} + +void CGLMBufferSpanManager::DiscardAllSpans() +{ + for ( int i = 0; i < m_ActiveSpans.Count(); i++ ) + { + if ( m_ActiveSpans[i].m_bOriginalAlloc ) + ReleaseDynamicBuf( m_ActiveSpans[i].m_buf ); + } + m_ActiveSpans.SetCountNonDestructively( 0 ); + + for ( int i = 0; i < m_DeletedSpans.Count(); i++ ) + ReleaseDynamicBuf( m_DeletedSpans[i].m_buf ); + + m_DeletedSpans.SetCountNonDestructively( 0 ); + + m_nSpanEndMax = -1; + + Assert( !m_nNumAllocatedBufs ); + Assert( !m_nTotalBytesAllocated ); +} + +// TODO: Add logic to detect incorrect usage of bNoOverwrite. +CGLMBufferSpanManager::ActiveSpan_t *CGLMBufferSpanManager::AddSpan( uint nOffset, uint nMaxSize, uint nActualSize, bool bDiscard, bool bNoOverwrite ) +{ + (void)bDiscard; + (void)bNoOverwrite; + + const uint nStart = nOffset; + const uint nSize = nActualSize; + const uint nEnd = nStart + nSize; + + GLDynamicBuf_t newDynamicBuf; + if ( !AllocDynamicBuf( nSize, newDynamicBuf ) ) + { + DXABSTRACT_BREAK_ON_ERROR(); + return NULL; + } + + if ( (int)nStart < m_nSpanEndMax ) + { + // Lock region potentially overlaps another previously locked region (since the last discard) - this is a very rarely (if ever) taken path in Source1 games. + int i = 0; + while ( i < m_ActiveSpans.Count() ) + { + ActiveSpan_t &existingSpan = m_ActiveSpans[i]; + if ( ( nEnd <= existingSpan.m_nStart ) || ( nStart >= existingSpan.m_nEnd ) ) + { + i++; + continue; + } + + Warning( "GL performance warning: AddSpan() at offset %u max size %u actual size %u, on a %s %s buffer of total size %u, overwrites an existing active lock span at offset %u size %u!\n", + nOffset, nMaxSize, nActualSize, + m_bDynamic ? "dynamic" : "static", ( m_nBufType == kGLMVertexBuffer ) ? "vertex" : "index", m_nBufSize, + existingSpan.m_nStart, existingSpan.m_nEnd - existingSpan.m_nStart ); + + if ( ( nStart <= existingSpan.m_nStart ) && ( nEnd >= existingSpan.m_nEnd ) ) + { + if ( existingSpan.m_bOriginalAlloc ) + { + // New span totally covers existing span + // Can't immediately delete the span's buffer because it could be referred to by another (child) span. + m_DeletedSpans.AddToTail( existingSpan ); + } + + // Delete span + m_ActiveSpans[i] = m_ActiveSpans[ m_ActiveSpans.Count() - 1 ]; + m_ActiveSpans.SetCountNonDestructively( m_ActiveSpans.Count() - 1 ); + continue; + } + + // New span does NOT fully cover the existing span (partial overlap) + if ( nStart < existingSpan.m_nStart ) + { + // New span starts before existing span, but ends somewhere inside, so shrink it (start moves "right") + existingSpan.m_nStart = nEnd; + } + else if ( nEnd > existingSpan.m_nEnd ) + { + // New span ends after existing span, but starts somewhere inside (end moves "left") + existingSpan.m_nEnd = nStart; + } + else //if ( ( nStart >= existingSpan.m_nStart ) && ( nEnd <= existingSpan.m_nEnd ) ) + { + // New span lies inside of existing span + if ( nStart == existingSpan.m_nStart ) + { + // New span begins inside the existing span (start moves "right") + existingSpan.m_nStart = nEnd; + } + else + { + if ( nEnd < existingSpan.m_nEnd ) + { + // New span is completely inside existing span + m_ActiveSpans.AddToTail( ActiveSpan_t( nEnd, existingSpan.m_nEnd, existingSpan.m_buf, false ) ); + } + + existingSpan.m_nEnd = nStart; + } + } + + Assert( existingSpan.m_nStart < existingSpan.m_nEnd ); + i++; + } + } + + newDynamicBuf.m_nLockOffset = nStart; + newDynamicBuf.m_nLockSize = nSize; + + m_ActiveSpans.AddToTail( ActiveSpan_t( nStart, nEnd, newDynamicBuf, true ) ); + m_nSpanEndMax = MAX( m_nSpanEndMax, (int)nEnd ); + + return &m_ActiveSpans.Tail(); +} + +bool CGLMBufferSpanManager::IsValid( uint nOffset, uint nSize ) const +{ + const uint nEnd = nOffset + nSize; + + int nTotalBytesRemaining = nSize; + + for ( int i = m_ActiveSpans.Count() - 1; i >= 0; --i ) + { + const ActiveSpan_t &span = m_ActiveSpans[i]; + + if ( span.m_nEnd <= nOffset ) + continue; + if ( span.m_nStart >= nEnd ) + continue; + + uint nIntersectStart = MAX( span.m_nStart, nOffset ); + uint nIntersectEnd = MIN( span.m_nEnd, nEnd ); + Assert( nIntersectStart <= nIntersectEnd ); + + nTotalBytesRemaining -= ( nIntersectEnd - nIntersectStart ); + Assert( nTotalBytesRemaining >= 0 ); + if ( nTotalBytesRemaining <= 0 ) + break; + } + + return nTotalBytesRemaining == 0; +} +#endif // GL_ENABLE_INDEX_VERIFICATION + +// glBufferSubData() with a max size limit, to work around NVidia's threaded driver limits (anything > than roughly 256KB triggers a sync with the server thread). +void glBufferSubDataMaxSize( GLenum target, GLintptr offset, GLsizeiptr size, const GLvoid *data, uint nMaxSizePerCall ) +{ +#if TOGL_SUPPORT_NULL_DEVICE + if ( g_bNullD3DDevice ) return; +#endif + + uint nBytesLeft = size; + uint nOfs = 0; + while ( nBytesLeft ) + { + uint nBytesToCopy = MIN( nMaxSizePerCall, nBytesLeft ); + + gGL->glBufferSubData( target, offset + nOfs, nBytesToCopy, static_cast( data ) + nOfs ); + + nBytesLeft -= nBytesToCopy; + nOfs += nBytesToCopy; + } +} + +CGLMBuffer::CGLMBuffer( GLMContext *pCtx, EGLMBufferType type, uint size, uint options ) +{ + m_pCtx = pCtx; + m_type = type; + + m_bDynamic = ( options & GLMBufferOptionDynamic ) != 0; + + switch ( m_type ) + { + case kGLMVertexBuffer: m_buffGLTarget = GL_ARRAY_BUFFER; break; + case kGLMIndexBuffer: m_buffGLTarget = GL_ELEMENT_ARRAY_BUFFER; break; + case kGLMUniformBuffer: m_buffGLTarget = GL_UNIFORM_BUFFER; break; + case kGLMPixelBuffer: m_buffGLTarget = GL_PIXEL_UNPACK_BUFFER; break; + + default: Assert(!"Unknown buffer type" ); DXABSTRACT_BREAK_ON_ERROR(); + } + + m_nSize = size; + m_nActualSize = size; + m_bMapped = false; + m_pLastMappedAddress = NULL; + + m_pStaticBuffer = NULL; + m_nPinnedMemoryOfs = -1; + m_nPersistentBufferStartOffset = 0; + m_bUsingPersistentBuffer = false; + + m_bEnableAsyncMap = false; + m_bEnableExplicitFlush = false; + m_dirtyMinOffset = m_dirtyMaxOffset = 0; // adjust/grow on lock, clear on unlock + + m_pCtx->CheckCurrent(); + m_nRevision = rand(); + + m_pPseudoBuf = NULL; + m_pActualPseudoBuf = NULL; + + m_bPseudo = false; + +#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION + m_bPseudo = true; +#endif + +#if GL_ENABLE_INDEX_VERIFICATION + m_BufferSpanManager.Init( m_pCtx, m_type, 512, m_nSize, m_bDynamic ); + + if ( m_type == kGLMIndexBuffer ) + m_bPseudo = true; +#endif + + if ( g_bUsePseudoBufs && m_bDynamic ) + { + m_bPseudo = true; + } + + if ( m_bPseudo ) + { + m_nHandle = 0; + +#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION + m_nDirtyRangeStart = 0xFFFFFFFF; + m_nDirtyRangeEnd = 0; + + m_nActualSize = ALIGN_VALUE( ( m_nSize + sizeof( uint32 ) ), 4096 ); + m_pPseudoBuf = m_pActualPseudoBuf = (char *)VirtualAlloc( NULL, m_nActualSize, MEM_COMMIT, PAGE_READWRITE ); + if ( !m_pPseudoBuf ) + { + Error( "VirtualAlloc() failed!\n" ); + } + + for ( uint i = 0; i < m_nActualSize / sizeof( uint32 ); i++ ) + { + reinterpret_cast< uint32 * >( m_pPseudoBuf )[i] = 0xDEADBEEF; + } + + DWORD nOldProtect; + BOOL bResult = VirtualProtect( m_pActualPseudoBuf, m_nActualSize, PAGE_READONLY, &nOldProtect ); + if ( !bResult ) + { + Error( "VirtualProtect() failed!\n" ); + } +#else + m_nActualSize = size + 15; + m_pActualPseudoBuf = (char*)malloc( m_nActualSize ); + m_pPseudoBuf = (char*)(((intp)m_pActualPseudoBuf + 15) & ~15); +#endif + + m_pCtx->BindBufferToCtx( m_type, NULL ); // exit with no buffer bound + } + else + { + gGL->glGenBuffers( 1, &m_nHandle ); + + m_pCtx->BindBufferToCtx( m_type, this ); // causes glBindBufferARB + + // buffers start out static, but if they get orphaned and gl_bufmode is non zero, + // then they will get flipped to dynamic. + + GLenum hint = GL_STREAM_DRAW; + switch (m_type) + { + case kGLMVertexBuffer: hint = m_bDynamic ? GL_DYNAMIC_DRAW : GL_STREAM_DRAW; break; + case kGLMIndexBuffer: hint = m_bDynamic ? GL_DYNAMIC_DRAW : GL_STREAM_DRAW; break; + case kGLMUniformBuffer: hint = GL_DYNAMIC_DRAW; break; + case kGLMPixelBuffer: hint = m_bDynamic ? GL_DYNAMIC_DRAW : GL_STREAM_DRAW; break; + + default: Assert(!"Unknown buffer type" ); DXABSTRACT_BREAK_ON_ERROR(); + } + + gGL->glBufferData( m_buffGLTarget, m_nSize, (const GLvoid*)NULL, hint ); // may ultimately need more hints to set the usage correctly (esp for streaming) + + SetModes( false, true, true ); + + m_pCtx->BindBufferToCtx( m_type, NULL ); // unbind me + } +} + +CGLMBuffer::~CGLMBuffer( ) +{ + m_pCtx->CheckCurrent(); + + if ( m_bPseudo ) + { +#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION + BOOL bResult = VirtualFree( m_pActualPseudoBuf, 0, MEM_RELEASE ); + if ( !bResult ) + { + Error( "VirtualFree() failed!\n" ); + } +#else + free( m_pActualPseudoBuf ); +#endif + m_pActualPseudoBuf = NULL; + m_pPseudoBuf = NULL; + } + else + { + gGL->glDeleteBuffers( 1, &m_nHandle ); + } + + m_pCtx = NULL; + m_nHandle = 0; + + m_pLastMappedAddress = NULL; + +#if GL_ENABLE_INDEX_VERIFICATION + m_BufferSpanManager.Deinit(); +#endif +} + +void CGLMBuffer::SetModes( bool bAsyncMap, bool bExplicitFlush, bool bForce ) +{ + // assumes buffer is bound. called by constructor and by Lock. + + if ( m_bPseudo ) + { + // ignore it... + } + else + { + if ( bForce || ( m_bEnableAsyncMap != bAsyncMap ) ) + { + m_bEnableAsyncMap = bAsyncMap; + } + + if ( bForce || ( m_bEnableExplicitFlush != bExplicitFlush ) ) + { + // Note that the GL_ARB_map_buffer_range path handles this in the glMapBufferRange() call in Lock(). + // note the sense of the parameter, it's TRUE if you *want* auto-flush-on-unmap, so for explicit-flush, you turn it to false. + m_bEnableExplicitFlush = bExplicitFlush; + } + } +} + +#if GL_ENABLE_INDEX_VERIFICATION +bool CGLMBuffer::IsSpanValid( uint nOffset, uint nSize ) const +{ + return m_BufferSpanManager.IsValid( nOffset, nSize ); +} +#endif + +void CGLMBuffer::FlushRange( uint offset, uint size ) +{ + if ( m_pStaticBuffer ) + { + } + else if ( m_bPseudo ) + { + // nothing to do + } + else + { +#ifdef REPORT_LOCK_TIME + double flStart = Plat_FloatTime(); +#endif + + gGL->glFlushMappedBufferRange( m_buffGLTarget, (GLintptr)( offset - m_dirtyMinOffset ), (GLsizeiptr)size ); +#ifdef REPORT_LOCK_TIME + double flEnd = Plat_FloatTime(); + if ( flEnd - flStart > 5.0 / 1000.0 ) + { + int nDelta = ( int )( ( flEnd - flStart ) * 1000 ); + if ( nDelta > 2 ) + { + Msg( "**** " ); + } + Msg( "glFlushMappedBufferRange Time %d: ( Name=%d BufSize=%d ) Target=%p Offset=%d FlushSize=%d\n", nDelta, m_nHandle, m_nSize, m_buffGLTarget, offset - m_dirtyMinOffset, size ); + } +#endif + + // If you don't have any extension support here, you'll flush the whole buffer on unmap. Performance loss, but it's still safe and correct. + } +} + +void CGLMBuffer::Lock( GLMBuffLockParams *pParams, char **pAddressOut ) +{ +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmPIXEvent( "CGLMBuffer::Lock" ); + g_TelemetryGPUStats.m_nTotalBufferLocksAndUnlocks++; +#endif + + char *resultPtr = NULL; + + if ( m_bMapped ) + { + DXABSTRACT_BREAK_ON_ERROR(); + return; + } + + m_pCtx->CheckCurrent(); + + Assert( pParams->m_nSize ); + + m_LockParams = *pParams; + + if ( pParams->m_nOffset >= m_nSize ) + { + DXABSTRACT_BREAK_ON_ERROR(); + return; + } + + if ( ( pParams->m_nOffset + pParams->m_nSize ) > m_nSize) + { + DXABSTRACT_BREAK_ON_ERROR(); + return; + } + +#if GL_ENABLE_INDEX_VERIFICATION + if ( pParams->m_bDiscard ) + { + m_BufferSpanManager.DiscardAllSpans(); + } +#endif + + m_pStaticBuffer = NULL; + bool bUsingPersistentBuffer = false; + + uint padding = 0; + if ( m_bDynamic && gGL->m_bHave_GL_EXT_buffer_storage ) + { + // Compute padding to add to make sure the start offset is valid + CPersistentBuffer *pTempBuffer = m_pCtx->GetCurPersistentBuffer( m_type ); + uint persistentBufferOffset = pTempBuffer->GetOffset(); + + if (pParams->m_nOffset > persistentBufferOffset) + { + // Make sure the start offset if valid (adding padding to the persistent buffer) + padding = pParams->m_nOffset - persistentBufferOffset; + } + } + + if ( m_bPseudo ) + { + if ( pParams->m_bDiscard ) + { + m_nRevision++; + } + + // async map modes are a no-op + + // calc lock address + resultPtr = m_pPseudoBuf + pParams->m_nOffset; + +#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION + BOOL bResult; + DWORD nOldProtect; + if ( pParams->m_bDiscard ) + { + bResult = VirtualProtect( m_pActualPseudoBuf, m_nSize, PAGE_READWRITE, &nOldProtect ); + if ( !bResult ) + { + Error( "VirtualProtect() failed!\n" ); + } + + m_nDirtyRangeStart = 0xFFFFFFFF; + m_nDirtyRangeEnd = 0; + + for ( uint i = 0; i < m_nSize / sizeof( uint32 ); i++ ) + { + reinterpret_cast< uint32 * >( m_pPseudoBuf )[i] = 0xDEADBEEF; + } + + bResult = VirtualProtect( m_pActualPseudoBuf, m_nSize, PAGE_READONLY, &nOldProtect ); + if ( !bResult ) + { + Error( "VirtualProtect() failed!\n" ); + } + } + uint nProtectOfs = m_LockParams.m_nOffset & 4095; + uint nProtectEnd = ( m_LockParams.m_nOffset + m_LockParams.m_nSize + 4095 ) & ~4095; + uint nProtectSize = nProtectEnd - nProtectOfs; + bResult = VirtualProtect( m_pActualPseudoBuf + nProtectOfs, nProtectSize, PAGE_READWRITE, &nOldProtect ); + if ( !bResult ) + { + Error( "VirtualProtect() failed!\n" ); + } +#endif + } + else if ( m_bDynamic && gGL->m_bHave_GL_EXT_buffer_storage && ( m_pCtx->GetCurPersistentBuffer( m_type )->GetBytesRemaining() >= ( pParams->m_nSize + padding ) ) ) + { + CPersistentBuffer *pTempBuffer = m_pCtx->GetCurPersistentBuffer( m_type ); + + // Make sure the start offset if valid (adding padding to the persistent buffer) + pTempBuffer->Append( padding ); + + uint persistentBufferOffset = pTempBuffer->GetOffset(); + uint startOffset = persistentBufferOffset - pParams->m_nOffset; + + if ( pParams->m_bDiscard || ( startOffset != m_nPersistentBufferStartOffset ) ) + { + m_nRevision++; + // Offset to be added to the vertex and index buffer when setting the vertex and index buffer (before drawing) + // Since we are using a immutable buffer storage, the persistent buffer is actually bigger than + // buffer size requested upon creation. We keep appending to the end of the persistent buffer + // and therefore need to keep track of the start of the actual buffer (in the persistent one) + m_nPersistentBufferStartOffset = startOffset; + + //DevMsg( "Discard (%s): startOffset = %d\n", pParams->m_bDiscard ? "true" : "false", m_nPersistentBufferStartOffset ); + } + + resultPtr = static_cast(pTempBuffer->GetPtr()) + persistentBufferOffset; + bUsingPersistentBuffer = true; + + //DevMsg( " --> buff=%x, startOffset=%d, paramsOffset=%d, persistOffset = %d\n", this, m_nPersistentBufferStartOffset, pParams->m_nOffset, persistentBufferOffset ); + } + else if ( !g_bDisableStaticBuffer && ( pParams->m_bDiscard || pParams->m_bNoOverwrite ) && ( pParams->m_nSize <= GL_STATIC_BUFFER_SIZE ) ) + { +#if TOGL_SUPPORT_NULL_DEVICE + if ( !g_bNullD3DDevice ) +#endif + { + if ( pParams->m_bDiscard ) + { + m_pCtx->BindBufferToCtx( m_type, this ); + + // observe gl_bufmode on any orphan event. + // if orphaned and bufmode is nonzero, flip it to dynamic. + GLenum hint = gl_bufmode.GetInt() ? GL_DYNAMIC_DRAW : GL_STREAM_DRAW; + gGL->glBufferData( m_buffGLTarget, m_nSize, (const GLvoid*)NULL, hint ); + + m_nRevision++; // revision grows on orphan event + } + } + + m_dirtyMinOffset = pParams->m_nOffset; + m_dirtyMaxOffset = pParams->m_nOffset + pParams->m_nSize; + + switch ( m_type ) + { + case kGLMVertexBuffer: + { + m_pStaticBuffer = m_StaticBuffers[ 0 ]; + break; + } + case kGLMIndexBuffer: + { + m_pStaticBuffer = m_StaticBuffers[ 1 ]; + break; + } + default: + { + DXABSTRACT_BREAK_ON_ERROR(); + return; + } + } + + resultPtr = m_pStaticBuffer; + } + else + { + // bind (yes, even for pseudo - this binds name 0) + m_pCtx->BindBufferToCtx( m_type, this ); + + // perform discard if requested + if ( pParams->m_bDiscard ) + { + // observe gl_bufmode on any orphan event. + // if orphaned and bufmode is nonzero, flip it to dynamic. + + // We always want to call glBufferData( ..., NULL ) on discards, even though we're using the GL_MAP_INVALIDATE_BUFFER_BIT flag, because this flag is actually only a hint according to AMD. + GLenum hint = gl_bufmode.GetInt() ? GL_DYNAMIC_DRAW : GL_STREAM_DRAW; + gGL->glBufferData( m_buffGLTarget, m_nSize, (const GLvoid*)NULL, hint ); + + m_nRevision++; // revision grows on orphan event + } + + // adjust async map option appropriately, leave explicit flush unchanged + SetModes( pParams->m_bNoOverwrite, m_bEnableExplicitFlush ); + + // map + char *mapPtr; + + // m_bEnableAsyncMap is actually pParams->m_bNoOverwrite + GLbitfield parms = GL_MAP_WRITE_BIT | ( m_bEnableAsyncMap ? GL_MAP_UNSYNCHRONIZED_BIT : 0 ) | ( pParams->m_bDiscard ? GL_MAP_INVALIDATE_BUFFER_BIT : 0 ) | ( m_bEnableExplicitFlush ? GL_MAP_FLUSH_EXPLICIT_BIT : 0 ); + +#ifdef REPORT_LOCK_TIME + double flStart = Plat_FloatTime(); +#endif + + mapPtr = (char*)gGL->glMapBufferRange( m_buffGLTarget, pParams->m_nOffset, pParams->m_nSize, parms); + +#ifdef REPORT_LOCK_TIME + double flEnd = Plat_FloatTime(); + if ( flEnd - flStart > 5.0 / 1000.0 ) + { + int nDelta = ( int )( ( flEnd - flStart ) * 1000 ); + if ( nDelta > 2 ) + { + Msg( "**** " ); + } + Msg( "glMapBufferRange Time=%d: ( Name=%d BufSize=%d ) Target=%p Offset=%d LockSize=%d ", nDelta, m_nHandle, m_nSize, m_buffGLTarget, pParams->m_nOffset, pParams->m_nSize ); + if ( parms & GL_MAP_WRITE_BIT ) + { + Msg( "GL_MAP_WRITE_BIT "); + } + if ( parms & GL_MAP_UNSYNCHRONIZED_BIT ) + { + Msg( "GL_MAP_UNSYNCHRONIZED_BIT "); + } + if ( parms & GL_MAP_INVALIDATE_BUFFER_BIT ) + { + Msg( "GL_MAP_INVALIDATE_BUFFER_BIT "); + } + if ( parms & GL_MAP_INVALIDATE_RANGE_BIT ) + { + Msg( "GL_MAP_INVALIDATE_RANGE_BIT "); + } + if ( parms & GL_MAP_FLUSH_EXPLICIT_BIT ) + { + Msg( "GL_MAP_FLUSH_EXPLICIT_BIT "); + } + Msg( "\n" ); + } +#endif + // calculate offset location + resultPtr = mapPtr; + + // set range + m_dirtyMinOffset = pParams->m_nOffset; + m_dirtyMaxOffset = pParams->m_nOffset + pParams->m_nSize; + } + + if ( m_bUsingPersistentBuffer != bUsingPersistentBuffer ) + { + // Up the revision number when switching from a persistent to a non persistent buffer (or vice versa) + // Ensure the right GL buffer is bound before drawing (and vertex attribs properly set) + m_nRevision++; + m_bUsingPersistentBuffer = bUsingPersistentBuffer; + } + + m_bMapped = true; + + m_pLastMappedAddress = (float*)resultPtr; + + *pAddressOut = resultPtr; +} + +void CGLMBuffer::Unlock( int nActualSize, const void *pActualData ) +{ +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmPIXEvent( "CGLMBuffer::Unlock" ); + g_TelemetryGPUStats.m_nTotalBufferLocksAndUnlocks++; +#endif + + m_pCtx->CheckCurrent(); + + if ( !m_bMapped ) + { + DXABSTRACT_BREAK_ON_ERROR(); + return; + } + + if ( nActualSize < 0 ) + { + nActualSize = m_LockParams.m_nSize; + } + + if ( nActualSize > (int)m_LockParams.m_nSize ) + { + DXABSTRACT_BREAK_ON_ERROR(); + return; + } + +#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION + if ( m_bPseudo ) + { + // Check guard DWORD to detect buffer overruns (but are still within the last 4KB page so they don't get caught via pagefaults) + if ( *reinterpret_cast< const uint32 * >( m_pPseudoBuf + m_nSize ) != 0xDEADBEEF ) + { + // If this fires the client app has overwritten the guard DWORD beyond the end of the buffer. + DXABSTRACT_BREAK_ON_ERROR(); + } + + static const uint s_nInitialValues[4] = { 0xEF, 0xBE, 0xAD, 0xDE }; + + int nActualModifiedStart, nActualModifiedEnd; + for ( nActualModifiedStart = 0; nActualModifiedStart < (int)m_LockParams.m_nSize; ++nActualModifiedStart ) + if ( reinterpret_cast< const uint8 * >( m_pLastMappedAddress )[nActualModifiedStart] != s_nInitialValues[ ( m_LockParams.m_nOffset + nActualModifiedStart ) & 3 ] ) + break; + + for ( nActualModifiedEnd = m_LockParams.m_nSize - 1; nActualModifiedEnd > nActualModifiedStart; --nActualModifiedEnd ) + if ( reinterpret_cast< const uint8 * >( m_pLastMappedAddress )[nActualModifiedEnd] != s_nInitialValues[ ( m_LockParams.m_nOffset + nActualModifiedEnd ) & 3 ] ) + break; + + int nNumActualBytesModified = 0; + + if ( nActualModifiedEnd >= nActualModifiedStart ) + { + // The modified check is conservative (i.e. it should always err on the side of detecting <= actual bytes than where actually modified, never more). + // We primarily care about the case where the user lies about the actual # of modified bytes, which can lead to difficult to debug/inconsistent problems with some drivers. + // Round up/down the modified range, because the user's data may alias with the initial buffer values (0xDEADBEEF) so we may miss some bytes that where written. + if ( m_type == kGLMIndexBuffer ) + { + nActualModifiedStart &= ~1; + nActualModifiedEnd = MIN( (int)m_LockParams.m_nSize, ( ( nActualModifiedEnd + 1 ) + 1 ) & ~1 ) - 1; + } + else + { + nActualModifiedStart &= ~3; + nActualModifiedEnd = MIN( (int)m_LockParams.m_nSize, ( ( nActualModifiedEnd + 1 ) + 3 ) & ~3 ) - 1; + } + + nNumActualBytesModified = nActualModifiedEnd + 1; + + if ( nActualSize < nNumActualBytesModified ) + { + // The caller may be lying about the # of actually modified bytes in this lock. + // Has this lock region been previously locked? If so, it may have been previously overwritten before. Otherwise, the region had to be the 0xDEADBEEF fill DWORD at lock time. + if ( ( m_nDirtyRangeStart > m_nDirtyRangeEnd ) || + ( m_LockParams.m_nOffset > m_nDirtyRangeEnd ) || ( ( m_LockParams.m_nOffset + m_LockParams.m_nSize ) <= m_nDirtyRangeStart ) ) + { + // If this fires the client has lied about the actual # of bytes they've modified in the buffer - this will cause unreliable rendering on AMD drivers (because AMD actually pays attention to the actual # of flushed bytes). + DXABSTRACT_BREAK_ON_ERROR(); + } + } + + m_nDirtyRangeStart = MIN( m_nDirtyRangeStart, m_LockParams.m_nOffset + nActualModifiedStart ); + m_nDirtyRangeEnd = MAX( m_nDirtyRangeEnd, m_LockParams.m_nOffset + nActualModifiedEnd ); + } + +#if GL_ENABLE_INDEX_VERIFICATION + if ( nActualModifiedEnd >= nActualModifiedStart ) + { + int n = nActualModifiedEnd + 1; + if ( n != nActualSize ) + { + // The actual detected modified size is < than the reported size, which is common because the last few DWORD's of the vertex format may not actually be used/written (or read by the vertex shader). So just fudge it so the batch consumption checks work. + if ( ( (int)nActualSize - n ) <= 32 ) + { + n = nActualSize; + } + } + + m_BufferSpanManager.AddSpan( m_LockParams.m_nOffset + nActualModifiedStart, m_LockParams.m_nSize, n - nActualModifiedStart, m_LockParams.m_bDiscard, m_LockParams.m_bNoOverwrite ); + } +#endif + } +#elif GL_ENABLE_INDEX_VERIFICATION + if ( nActualSize > 0 ) + { + m_BufferSpanManager.AddSpan( m_LockParams.m_nOffset, m_LockParams.m_nSize, nActualSize, m_LockParams.m_bDiscard, m_LockParams.m_bNoOverwrite ); + } +#endif + +#if GL_BATCH_PERF_ANALYSIS + if ( m_type == kGLMIndexBuffer ) + g_nTotalIBLockBytes += nActualSize; + else if ( m_type == kGLMVertexBuffer ) + g_nTotalVBLockBytes += nActualSize; +#endif + if ( m_bUsingPersistentBuffer ) + { + if ( nActualSize ) + { + CPersistentBuffer *pTempBuffer = m_pCtx->GetCurPersistentBuffer( m_type ); + pTempBuffer->Append( nActualSize ); + + //DevMsg( " <-- actualSize=%d, persistOffset = %d\n", nActualSize, pTempBuffer->GetOffset() ); + } + } + else if ( m_pStaticBuffer ) + { +#if TOGL_SUPPORT_NULL_DEVICE + if ( !g_bNullD3DDevice ) +#endif + { + if ( nActualSize ) + { + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "UnlockSubData" ); + + #ifdef REPORT_LOCK_TIME + double flStart = Plat_FloatTime(); + #endif + m_pCtx->BindBufferToCtx( m_type, this ); + + Assert( nActualSize <= (int)( m_dirtyMaxOffset - m_dirtyMinOffset ) ); + + glBufferSubDataMaxSize( m_buffGLTarget, m_dirtyMinOffset, nActualSize, pActualData ? pActualData : m_pStaticBuffer ); + + #ifdef REPORT_LOCK_TIME + double flEnd = Plat_FloatTime(); + if ( flEnd - flStart > 5.0 / 1000.0 ) + { + int nDelta = ( int )( ( flEnd - flStart ) * 1000 ); + if ( nDelta > 2 ) + { + Msg( "**** " ); + } + // Msg( "glBufferSubData Time=%d: ( Name=%d BufSize=%d ) Target=%p Offset=%d Size=%d\n", nDelta, m_nHandle, m_nSize, m_buffGLTarget, m_dirtyMinOffset, m_dirtyMaxOffset - m_dirtyMinOffset ); + } + #endif + } + } + + m_pStaticBuffer = NULL; + } + else if ( m_bPseudo ) + { + if ( pActualData ) + { + memcpy( m_pLastMappedAddress, pActualData, nActualSize ); + } + +#if GL_ENABLE_UNLOCK_BUFFER_OVERWRITE_DETECTION + uint nProtectOfs = m_LockParams.m_nOffset & 4095; + uint nProtectEnd = ( m_LockParams.m_nOffset + m_LockParams.m_nSize + 4095 ) & ~4095; + uint nProtectSize = nProtectEnd - nProtectOfs; + + DWORD nOldProtect; + BOOL bResult = VirtualProtect( m_pActualPseudoBuf + nProtectOfs, nProtectSize, PAGE_READONLY, &nOldProtect ); + if ( !bResult ) + { + Error( "VirtualProtect() failed!\n" ); + } +#endif + } + else + { + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "UnlockUnmap" ); + + if ( pActualData ) + { + memcpy( m_pLastMappedAddress, pActualData, nActualSize ); + } + + m_pCtx->BindBufferToCtx( m_type, this ); + + Assert( nActualSize <= (int)( m_dirtyMaxOffset - m_dirtyMinOffset ) ); + + // time to do explicit flush (currently m_bEnableExplicitFlush is always true) + if ( m_bEnableExplicitFlush ) + { + FlushRange( m_dirtyMinOffset, nActualSize ); + } + + // clear dirty range no matter what + m_dirtyMinOffset = m_dirtyMaxOffset = 0; // adjust/grow on lock, clear on unlock + +#ifdef REPORT_LOCK_TIME + double flStart = Plat_FloatTime(); +#endif + + gGL->glUnmapBuffer( m_buffGLTarget ); + +#ifdef REPORT_LOCK_TIME + double flEnd = Plat_FloatTime(); + if ( flEnd - flStart > 5.0 / 1000.0 ) + { + int nDelta = ( int )( ( flEnd - flStart ) * 1000 ); + if ( nDelta > 2 ) + { + Msg( "**** " ); + } + Msg( "glUnmapBuffer Time=%d: ( Name=%d BufSize=%d ) Target=%p\n", nDelta, m_nHandle, m_nSize, m_buffGLTarget ); + } +#endif + } + + m_bMapped = false; +} + +GLuint CGLMBuffer::GetHandle() const +{ + return ( m_bUsingPersistentBuffer ? m_pCtx->GetCurPersistentBuffer( m_type )->GetHandle() : m_nHandle ); +} diff --git a/togles/linuxwin/cglmfbo.cpp b/togles/linuxwin/cglmfbo.cpp new file mode 100644 index 00000000..e482ba9e --- /dev/null +++ b/togles/linuxwin/cglmfbo.cpp @@ -0,0 +1,354 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmfbo.cpp +// +//=============================================================================== + +#include "togles/rendermechanism.h" + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + +CGLMFBO::CGLMFBO( GLMContext *ctx ) +{ + m_ctx = ctx; + m_ctx->CheckCurrent(); + + gGL->glGenFramebuffers( 1, &m_name ); + + memset( m_attach, 0, sizeof( m_attach ) ); +} + + +CGLMFBO::~CGLMFBO( ) +{ + m_ctx->CheckCurrent(); + + // detach all known attached textures first... necessary ? + for( int index = 0; index < kAttCount; index++) + { + if (m_attach[ index ].m_tex) + { + TexDetach( (EGLMFBOAttachment)index ); + } + } + + gGL->glDeleteFramebuffers( 1, &m_name ); + + m_name = 0; + m_ctx = NULL; +} + +// the tex attach path should also select a specific slice of the texture... +// and we need a way to make renderbuffers.. + +static GLenum EncodeAttachmentFBO( EGLMFBOAttachment index ) +{ + if (index < kAttDepth) + { + return GL_COLOR_ATTACHMENT0 + (int) index; + } + else + { + switch( index ) + { + case kAttDepth: + return GL_DEPTH_ATTACHMENT; + break; + + case kAttStencil: + return GL_STENCIL_ATTACHMENT; + break; + + case kAttDepthStencil: + return GL_DEPTH_STENCIL_ATTACHMENT; + break; + + default: + GLMStop(); // bad news + break; + } + } + + GLMStop(); // bad news + // shouldn't get here + return GL_COLOR_ATTACHMENT0; +} + +void CGLMFBO::TexAttach( GLMFBOTexAttachParams *params, EGLMFBOAttachment attachIndex, GLenum fboBindPoint ) +{ + // force our parent context to be current + m_ctx->MakeCurrent(); + + // bind to context (will cause FBO object creation on first use) + m_ctx->BindFBOToCtx( this, fboBindPoint ); + + // it's either a plain 2D, a 2D face of a cube map, or a slice of a 3D. + CGLMTex *tex = params->m_tex; + + // always detach what is currently there, if anything + this->TexDetach( attachIndex, fboBindPoint ); + + if (!tex) + { + // andif they pass NULL to us, then we are done. + return; + } + + GLMTexLayout *layout = tex->m_layout; + + GLenum target = tex->m_layout->m_key.m_texGLTarget; + + GLenum attachIndexGL = EncodeAttachmentFBO( attachIndex ); + + switch( target ) + { + case GL_TEXTURE_2D: + { + // we will attach the underlying RBO on a multisampled tex, iff the tex has one, **and** we're not being asked to attach it to the read buffer. + // if we get a req to attach an MSAA tex to the read buffer, chances are it's BlitTex calling, andit has already resolved the tex, so in those + // cases you really do want to attach the texture and not the RBO to the FBO in question. + + bool useRBO = false; // initial state + + if (layout->m_key.m_texFlags & kGLMTexMultisampled) + { + // it is an MSAA tex + if (fboBindPoint == GL_READ_FRAMEBUFFER) + { + // I think you just want to read a resolved tex. + // But I will check that it is resolved first.. + Assert( tex->IsRBODirty() == false ); + } + else + { + // you want to draw into it. You get the RBO bound instead of the tex. + useRBO = true; + } + } + + if (useRBO) + { + // MSAA path - attach the RBO, not the texture, and mark the RBO dirty + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + // you have to attach it both places... + // http://www.opengl.org/wiki/GL_EXT_framebuffer_object + + // bind the RBO to the GL_RENDERBUFFER target + gGL->glBindRenderbuffer( GL_RENDERBUFFER, tex->m_rboName ); + + // attach the GL_RENDERBUFFER target to the depth and stencil attach points + gGL->glFramebufferRenderbuffer( fboBindPoint, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, tex->m_rboName); + gGL->glFramebufferRenderbuffer( fboBindPoint, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, tex->m_rboName); + + // no need to leave the RBO hanging on + gGL->glBindRenderbuffer( GL_RENDERBUFFER, 0 ); + } + else + { + // color attachment (likely 0) + gGL->glBindRenderbuffer( GL_RENDERBUFFER, tex->m_rboName ); + gGL->glFramebufferRenderbuffer( fboBindPoint, attachIndexGL, GL_RENDERBUFFER, tex->m_rboName); + gGL->glBindRenderbuffer( GL_RENDERBUFFER, 0 ); + } + tex->ForceRBODirty(); + } + else + { + // regular path - attaching a texture2d + + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + // you have to attach it both places... + // http://www.opengl.org/wiki/GL_EXT_framebuffer_object + + gGL->glFramebufferTexture2D( fboBindPoint, GL_DEPTH_ATTACHMENT, target, tex->m_texName, params->m_mip ); + gGL->glFramebufferTexture2D( fboBindPoint, GL_STENCIL_ATTACHMENT, target, tex->m_texName, params->m_mip ); + } + else + { + gGL->glFramebufferTexture2D( fboBindPoint, attachIndexGL, target, tex->m_texName, params->m_mip ); + } + } + } + break; + + case GL_TEXTURE_3D: + { +// gGL->glFramebufferTexture3DEXT( fboBindPoint, attachIndexGL, target, tex->m_texName, params->m_mip, params->m_zslice ); + } + break; + + case GL_TEXTURE_CUBE_MAP: + { + // adjust target to steer to the proper face of the cube map + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + params->m_face; + + gGL->glFramebufferTexture2D( fboBindPoint, attachIndexGL, target, tex->m_texName, params->m_mip ); + } + break; + } + + // log the attached tex + m_attach[ attachIndex ] = *params; + + // indicate that the tex has been bound to an RT + tex->m_rtAttachCount++; +} + +void CGLMFBO::TexDetach( EGLMFBOAttachment attachIndex, GLenum fboBindPoint ) +{ + // force our parent context to be current + m_ctx->MakeCurrent(); + + // bind to context (will cause FBO object creation on first use) + m_ctx->BindFBOToCtx( this, fboBindPoint ); + + if (m_attach[ attachIndex ].m_tex) + { + CGLMTex *tex = m_attach[ attachIndex ].m_tex; + GLMTexLayout *layout = tex->m_layout; + GLenum target = tex->m_layout->m_key.m_texGLTarget; + + GLenum attachIndexGL = EncodeAttachmentFBO( attachIndex ); + + switch( target ) + { + case GL_TEXTURE_2D: + { + if (layout->m_key.m_texFlags & kGLMTexMultisampled) + { + // MSAA path - detach the RBO, not the texture + // (is this the right time to resolve? probably better to wait until someone tries to sample the texture) + + gGL->glBindRenderbuffer( GL_RENDERBUFFER, 0 ); + + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + // detach the GL_RENDERBUFFER target at depth and stencil attach points + gGL->glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + + gGL->glFramebufferRenderbuffer( GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + } + else + { + // color attachment (likely 0) + gGL->glFramebufferRenderbuffer( GL_FRAMEBUFFER, attachIndexGL, GL_RENDERBUFFER, 0); + } + } + else + { + // plain tex detach + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + // you have to detach it both places... + // http://www.opengl.org/wiki/GL_EXT_framebuffer_object + + gGL->glFramebufferTexture2D( fboBindPoint, GL_DEPTH_ATTACHMENT, target, 0, 0 ); + gGL->glFramebufferTexture2D( fboBindPoint, GL_STENCIL_ATTACHMENT, target, 0, 0 ); + } + else + { + gGL->glFramebufferTexture2D( fboBindPoint, attachIndexGL, target, 0, 0 ); + } + } + } + break; + + case GL_TEXTURE_3D: + { +// gGL->glFramebufferTexture3DEXT( fboBindPoint, attachIndexGL, target, 0, 0, 0 ); + } + break; + + case GL_TEXTURE_CUBE_MAP: + { + gGL->glFramebufferTexture2D( fboBindPoint, attachIndexGL, target, 0, 0 ); + } + break; + } + + // un-log the attached tex + memset( &m_attach[ attachIndex ], 0, sizeof( m_attach[0] ) ); + + // drop the RT attach count + tex->m_rtAttachCount--; + } + else + { + //Debugger(); // odd, but not harmful - typ comes from D3D code passing NULL into SetRenderTarget + } +} + +void CGLMFBO::TexScrub( CGLMTex *tex ) +{ + // see if it's attached anywhere + for( int attachIndex = 0; attachIndex < kAttCount; attachIndex++ ) + { + if (m_attach[ attachIndex ].m_tex == tex) + { + // blammo + TexDetach( (EGLMFBOAttachment)attachIndex, GL_DRAW_FRAMEBUFFER ); + } + } +} + + +bool CGLMFBO::IsReady( void ) +{ + bool result = false; + + // ensure our parent context is current + m_ctx->CheckCurrent(); + + // bind to context (will cause FBO object creation on first use) + m_ctx->BindFBOToCtx( this ); + + GLenum status; + status = gGL->glCheckFramebufferStatus(GL_FRAMEBUFFER); + +#if 0 + switch(status) + { + case GL_FRAMEBUFFER_COMPLETE_EXT: + result = true; + break; + + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: + result = false; + DebuggerBreak(); + /* choose different formats */ + break; + + default: + result = false; + DebuggerBreak(); + /* programming error; will fail on all hardware */ + break; + } +#endif + return true; +} diff --git a/togles/linuxwin/cglmprogram.cpp b/togles/linuxwin/cglmprogram.cpp new file mode 100644 index 00000000..c2629099 --- /dev/null +++ b/togles/linuxwin/cglmprogram.cpp @@ -0,0 +1,1388 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmprogram.cpp +// +//=============================================================================== + +#include "togles/rendermechanism.h" + +#include "filesystem.h" +#include "tier1/fmtstr.h" +#include "tier1/KeyValues.h" +#include "tier0/fasttimer.h" + +#if GLMDEBUG && defined( _MSC_VER ) +#include +#endif + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + +#if GLMDEBUG +#define GLM_FREE_SHADER_TEXT 0 +#else +#define GLM_FREE_SHADER_TEXT 1 +#endif + +//=============================================================================== + +ConVar gl_shaderpair_cacherows_lg2( "gl_paircache_rows_lg2", "10"); // 10 is minimum +ConVar gl_shaderpair_cacheways_lg2( "gl_paircache_ways_lg2", "5"); // 5 is minimum +ConVar gl_shaderpair_cachelog( "gl_shaderpair_cachelog", "0" ); + +static CCycleCount gShaderCompileTime; +static int gShaderCompileCount = 0; +static CCycleCount gShaderCompileQueryTime; +static CCycleCount gShaderLinkTime; +static int gShaderLinkCount = 0; +static CCycleCount gShaderLinkQueryTime; +CON_COMMAND( gl_shader_compile_time_dump, "Dump stats shader compile time." ) +{ + ConMsg( "Shader Compile Time: %u ms (Count: %d) / Query: %u ms \n", (uint32)gShaderCompileTime.GetMilliseconds(), gShaderCompileCount, (uint32)gShaderCompileQueryTime.GetMilliseconds() ); + ConMsg( "Shader Link Time : %u ms (Count: %d) / Query: %u ms \n", (uint32)gShaderLinkTime.GetMilliseconds(), gShaderLinkCount, (uint32)gShaderLinkQueryTime.GetMilliseconds() ); +} + +//=============================================================================== + + +GLenum GLMProgTypeToARBEnum( EGLMProgramType type ) +{ + GLenum result = 0; + switch(type) + { + case kGLMVertexProgram: result = GL_VERTEX_PROGRAM_ARB; break; + case kGLMFragmentProgram: result = GL_FRAGMENT_PROGRAM_ARB; break; + default: Assert( !"bad program type"); result = 0; break; + } + return result; +} + +GLenum GLMProgTypeToGLSLEnum( EGLMProgramType type ) +{ + GLenum result = 0; + switch(type) + { + case kGLMVertexProgram: result = GL_VERTEX_SHADER; break; + case kGLMFragmentProgram: result = GL_FRAGMENT_SHADER; break; + default: Assert( !"bad program type"); result = 0; break; + } + return result; +} + +CGLMProgram::CGLMProgram( GLMContext *ctx, EGLMProgramType type ) +{ + m_ctx = ctx; + m_ctx->CheckCurrent(); + + m_type = type; + m_nHashTag = rand() ^ ( rand() << 15 ); + m_text = NULL; // no text yet + +#if GLMDEBUG + m_editable = NULL; +#endif + + memset( &m_descs, 0, sizeof( m_descs ) ); + + m_samplerMask = 0; // dxabstract sets this field later + m_samplerTypes = 0; + m_fragDataMask = 0; + m_numDrawBuffers = 0; + memset( &m_drawBuffers, 0, sizeof( m_drawBuffers ) ); + + m_maxSamplers = GLM_SAMPLER_COUNT; + m_nNumUsedSamplers = GLM_SAMPLER_COUNT; + m_maxVertexAttrs = kGLMVertexAttributeIndexMax; + + // create a GLSL shader object. + GLMShaderDesc *glslDesc = &m_descs[ kGLMGLSL ]; + GLenum glslStage = GLMProgTypeToGLSLEnum( m_type ); + + glslDesc->m_object.glsl = gGL->glCreateShader( glslStage );; + + m_shaderName[0] = '\0'; + + m_bTranslatedProgram = false; + + m_nCentroidMask = 0; + m_nShadowDepthSamplerMask = 0; + + m_labelName[0] = '\0'; + m_labelIndex = -1; + m_labelCombo = -1; + + // no text has arrived yet. That's done in SetProgramText. +} + +CGLMProgram::~CGLMProgram( ) +{ + m_ctx->CheckCurrent(); + + // if there is a GLSL shader, delete it + GLMShaderDesc *glslDesc = &m_descs[kGLMGLSL]; + if (glslDesc->m_object.glsl) + { + gGL->glDeleteShader( (uint)glslDesc->m_object.glsl ); // why do I need a cast here again ? + glslDesc->m_object.glsl = 0; + } + +#if GLMDEBUG + if (m_editable) + { + delete m_editable; + m_editable = NULL; + } +#endif + + if (m_text) + { + free( m_text ); + m_text = NULL; + } + m_ctx = NULL; +} + +enum EShaderSection +{ + kGLMARBVertex, kGLMARBVertexDisabled, + kGLMARBFragment, kGLMARBFragmentDisabled, + kGLMGLSLVertex, kGLMGLSLVertexDisabled, + kGLMGLSLFragment, kGLMGLSLFragmentDisabled, +}; + +void CGLMProgram::SetShaderName( const char *name ) +{ + V_strncpy( m_shaderName, name, sizeof( m_shaderName ) ); +} + +void CGLMProgram::SetProgramText( char *text ) +{ + // free old text if any + // clone new text + // scan newtext to find sections + // walk sections, and mark descs to indicate where text is at + + if (m_text) + { + free( m_text ); + m_text = NULL; + } + + // scrub desc text references + for( int i=0; im_textPresent = false; + desc->m_textOffset = 0; + desc->m_textLength = 0; + } + + m_text = strdup( text ); + Assert( m_text != NULL ); + + #if GLMDEBUG + // create editable text item, if it does not already exist + if (!m_editable) + { + char *suffix = ""; + + switch(m_type) + { + case kGLMVertexProgram: suffix = ".vsh"; break; + case kGLMFragmentProgram: suffix = ".fsh"; break; + default: GLMDebugger(); + } + +#ifdef POSIX + CFmtStr debugShaderPath( "%s/debugshaders/", getenv( "HOME" ) ); +#else + CFmtStr debugShaderPath( "debugshaders/" ); +#endif + _mkdir( debugShaderPath.Access() ); + m_editable = new CGLMEditableTextItem( m_text, strlen(m_text), false, debugShaderPath.Access(), suffix ); + + // pull our string back from the editable (it has probably munged it) + if (m_editable->HasData()) + { + ReloadStringFromEditable(); + } + } + #endif + +#if 0 + // scan the text and find sections + CGLMTextSectioner sections( m_text, strlen( m_text ), g_shaderSectionMarkers ); + + int sectionCount = sections.Count(); + for( int i=0; i < sectionCount; i++ ) + { + uint subtextOffset = 0; + uint subtextLength = 0; + int markerIndex = 0; + + sections.GetSection( i, &subtextOffset, &subtextLength, &markerIndex ); +#endif + + uint subtextOffset = 0; + uint subtextLength = strlen( m_text ); + int markerIndex = 0; + + // act on the section + GLMShaderDesc *desc = NULL; + desc = &m_descs[kGLMGLSL]; + + // these steps are generic across both langs + desc->m_textPresent = true; + desc->m_textOffset = subtextOffset; + desc->m_textLength = subtextLength; + desc->m_compiled = false; + desc->m_valid = false; + + // find the label string + // example: + // trans#2871 label:vs-file vertexlit_and_unlit_generic_vs20 vs-index 294912 vs-combo 1234 + + char *lineStr = strstr( m_text, "// trans#" ); + if (lineStr) + { + int scratch = -1; + + if (this->m_type == kGLMVertexProgram) + { + sscanf( lineStr, "// trans#%d label:vs-file %s vs-index %d vs-combo %d", &scratch, m_labelName, &m_labelIndex, &m_labelCombo ); + } + else + { + sscanf( lineStr, "// trans#%d label:ps-file %s ps-index %d ps-combo %d", &scratch, m_labelName, &m_labelIndex, &m_labelCombo ); + } + } +} + +void CGLMProgram::CompileActiveSources ( void ) +{ + // compile everything we have text for + for( int i=0; iFindParm( "-gl_time_shader_compiles" ) != 0); + // If using "-gl_time_shader_compiles", keeps track of total cycle count spent on shader compiles. + CFastTimer shaderCompileTimer; + if (bTimeShaderCompiles) + { + shaderCompileTimer.Start(); + } + + bool noisy = false; noisy; + int loglevel = gl_shaderpair_cachelog.GetInt(); + + switch( lang ) + { + case kGLMGLSL: + { + GLMShaderDesc *glslDesc; + + glslDesc = &m_descs[ kGLMGLSL ]; + + GLenum glslStage = GLMProgTypeToGLSLEnum( m_type ); + glslStage; + + // no GLSL program either + gGL->glUseProgram(0); + + // pump text into GLSL shader object + + char *section = m_text + glslDesc->m_textOffset; + char *lastCharOfSection = section + glslDesc->m_textLength; // actually it's one past the last textual character + lastCharOfSection; + + #if GLMDEBUG + if(noisy) + { + GLMPRINTF((">-D- CGLMProgram::Compile submitting following text for GLSL %s program (name %d) ---------------------", + glslStage == GL_FRAGMENT_SHADER ? "fragment" : "vertex", + glslDesc->m_object.glsl )); + + // we don't have a "print this many chars" call yet + // just temporarily null terminate the text we want to print + + char saveChar = *lastCharOfSection; + + *lastCharOfSection= 0; + GLMPRINTTEXT(( section, eDebugDump )); + *lastCharOfSection= saveChar; + + GLMPRINTF(("<-D- CGLMProgram::Compile GLSL EOT--" )); + } + #endif + + gGL->glShaderSource( glslDesc->m_object.glsl, 1, (const GLchar **)§ion, &glslDesc->m_textLength); + + // compile + gGL->glCompileShader( glslDesc->m_object.glsl ); + + + GLint isCompiled = 0; + gGL->glGetShaderiv(glslDesc->m_object.glsl, GL_COMPILE_STATUS, &isCompiled); + + if(isCompiled == GL_FALSE) + { + GLint maxLength = 0; + gGL->glGetShaderiv(glslDesc->m_object.glsl , GL_INFO_LOG_LENGTH, &maxLength); + + GLchar log[4096]; + gGL->glGetShaderInfoLog( glslDesc->m_object.glsl, sizeof(log), &maxLength, log ); + Msg("shader compile log: %s\n", log); + Msg("Shader %d source is:\n===============\n%s\nn===============\n", glslDesc->m_object.glsl, section); + } + +#if 0 //GLM_FREE_SHADER_TEXT + // Free the shader program text - not needed anymore (GL has its own copy) + if ( m_text && !m_descs[kGLMARB].m_textPresent ) + { + free( m_text ); + m_text = NULL; + } +#endif + + glslDesc->m_compiled = true; // compiled but not necessarily valid + + // Check shader validity at creation time. This will cause the driver to not be able to + // multi-thread/defer shader compiles, but it is useful for getting error messages on the + // shader when it is compiled + bool bValidateShaderEarly = (CommandLine()->FindParm( "-gl_validate_shader_early" ) != 0); + if (bValidateShaderEarly) + { + CheckValidity( lang ); + } + + if (loglevel>=2) + { + char tempname[128]; + //int tempindex = -1; + //int tempcombo = -1; + + //GetLabelIndexCombo( tempname, sizeof(tempname), &tempindex, &tempcombo ); + //printf("\ncompile: - [ %s/%d/%d ] on GL name %d ", tempname, tempindex, tempcombo, glslDesc->m_object.glsl ); + + + GetComboIndexNameString( tempname, sizeof(tempname) ); + printf("\ncompile: %s on GL name %d ", tempname, glslDesc->m_object.glsl ); + } + } + break; + } + + if (bTimeShaderCompiles) + { + shaderCompileTimer.End(); + gShaderCompileTime += shaderCompileTimer.GetDuration(); + gShaderCompileCount++; + } +} + +#if GLMDEBUG + + bool CGLMProgram::PollForChanges( void ) + { + bool result = false; + if (m_editable) + { + result = m_editable->PollForChanges(); + } + return result; + } + + void CGLMProgram::ReloadStringFromEditable( void ) + { + uint dataSize=0; + char *data=NULL; + + m_editable->GetCurrentText( &data, &dataSize ); + + char *buf = (char *)malloc( dataSize+1 ); // we will NULL terminate it, since the mirror copy might not be + memcpy( buf, data, dataSize ); + buf[dataSize] = 0; + + SetProgramText( buf ); + + free( buf ); + } + + bool CGLMProgram::SyncWithEditable( void ) + { + bool result = false; + + if (m_editable->PollForChanges()) + { + ReloadStringFromEditable(); + + CompileActiveSources(); + + // invalidate shader pair cache entries using this shader.. + m_ctx->m_pairCache->PurgePairsWithShader( this ); + + result = true; // result true means "it changed" + } + return result; + } + +#endif + + +// attributes which are general to both stages +// VP and FP: +// +// 0x88A0 PROGRAM_INSTRUCTIONS_ARB VP FP +// 0x88A1 MAX_PROGRAM_INSTRUCTIONS_ARB VP FP +// 0x88A2 PROGRAM_NATIVE_INSTRUCTIONS_ARB VP FP +// 0x88A3 MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB VP FP +// +// 0x88A4 PROGRAM_TEMPORARIES_ARB VP FP +// 0x88A5 MAX_PROGRAM_TEMPORARIES_ARB VP FP +// 0x88A6 PROGRAM_NATIVE_TEMPORARIES_ARB VP FP +// 0x88A7 MAX_PROGRAM_NATIVE_TEMPORARIES_ARB VP FP +// +// 0x88A8 PROGRAM_PARAMETERS_ARB VP FP +// 0x88A9 MAX_PROGRAM_PARAMETERS_ARB VP FP +// 0x88AA PROGRAM_NATIVE_PARAMETERS_ARB VP FP +// 0x88AB MAX_PROGRAM_NATIVE_PARAMETERS_ARB VP FP +// +// 0x88AC PROGRAM_ATTRIBS_ARB VP FP +// 0x88AD MAX_PROGRAM_ATTRIBS_ARB VP FP +// 0x88AE PROGRAM_NATIVE_ATTRIBS_ARB VP FP +// 0x88AF MAX_PROGRAM_NATIVE_ATTRIBS_ARB VP FP +// +// 0x88B4 MAX_PROGRAM_LOCAL_PARAMETERS_ARB VP FP +// 0x88B5 MAX_PROGRAM_ENV_PARAMETERS_ARB VP FP +// 0x88B6 PROGRAM_UNDER_NATIVE_LIMITS_ARB VP FP +// +// VP only: +// +// 0x88B0 PROGRAM_ADDRESS_REGISTERS_ARB VP +// 0x88B1 MAX_PROGRAM_ADDRESS_REGISTERS_ARB VP +// 0x88B2 PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB VP +// 0x88B3 MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB VP +// +// FP only: +// +// 0x8805 PROGRAM_ALU_INSTRUCTIONS_ARB FP +// 0x880B MAX_PROGRAM_ALU_INSTRUCTIONS_ARB FP +// 0x8808 PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB FP +// 0x880E MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB FP + +// 0x8806 PROGRAM_TEX_INSTRUCTIONS_ARB FP +// 0x880C MAX_PROGRAM_TEX_INSTRUCTIONS_ARB FP +// 0x8809 PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB FP +// 0x880F MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB FP + +// 0x8807 PROGRAM_TEX_INDIRECTIONS_ARB FP +// 0x880D MAX_PROGRAM_TEX_INDIRECTIONS_ARB FP +// 0x880A PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB FP +// 0x8810 MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB FP + +struct GLMShaderLimitDesc +{ + GLenum m_valueEnum; + GLenum m_limitEnum; + const char *m_debugName; + char m_flags; + // m_flags - 0x01 for VP, 0x02 for FP, or set both if applicable to both +}; + +// macro to help make the table of what to check +#ifndef LMD +#define LMD( val, flags ) { GL_PROGRAM_##val, GL_MAX_PROGRAM_##val, #val, flags } +#else +#error you need to use a different name for this macro. +#endif + +GLMShaderLimitDesc g_glmShaderLimitDescs[] = +{ + // VP and FP.. +// LMD( INSTRUCTIONS, 3 ), +// LMD( NATIVE_INSTRUCTIONS, 3 ), +// LMD( NATIVE_TEMPORARIES, 3 ), +// LMD( PARAMETERS, 3 ), +// LMD( NATIVE_PARAMETERS, 3 ), +// LMD( ATTRIBS, 3 ), +// LMD( NATIVE_ATTRIBS, 3 ), + + // VP only.. +// LMD( ADDRESS_REGISTERS, 1 ), +// LMD( NATIVE_ADDRESS_REGISTERS, 1 ), + + // FP only.. +// LMD( ALU_INSTRUCTIONS, 2 ), +// LMD( NATIVE_ALU_INSTRUCTIONS, 2 ), +// LMD( TEX_INSTRUCTIONS, 2 ), +// LMD( NATIVE_TEX_INSTRUCTIONS, 2 ), +// LMD( TEX_INDIRECTIONS, 2 ), +// LMD( NATIVE_TEX_INDIRECTIONS, 2 ), + + { 0, 0, NULL, 0 } +}; + +#undef LMD + +bool CGLMProgram::CheckValidity( EGLMProgramLang lang ) +{ + static char *targnames[] = { "vertex", "fragment" }; + + bool bTimeShaderCompiles = (CommandLine()->FindParm( "-gl_time_shader_compiles" ) != 0); + // If using "-gl_time_shader_compiles", keeps track of total cycle count spent on shader compiles. + CFastTimer shaderCompileTimer; + if (bTimeShaderCompiles) + { + shaderCompileTimer.Start(); + } + + bool bValid = false; + +//#error "What the fuck?" + + switch(lang) + { + case kGLMGLSL: + { + GLMShaderDesc *glslDesc; + glslDesc = &m_descs[ kGLMGLSL ]; + + GLenum glslStage = GLMProgTypeToGLSLEnum( m_type ); glslStage; + + Assert( glslDesc->m_compiled ); + + glslDesc->m_valid = true; // assume success til we see otherwise + + // GLSL error check + int compiled = 0; + + gGL->glGetShaderiv(glslDesc->m_object.glsl, GL_COMPILE_STATUS, &compiled); + + if (!compiled) + glslDesc->m_valid = false; + + bValid = glslDesc->m_valid; + } + break; + } + + AssertOnce( bValid ); + + if (bTimeShaderCompiles) + { + shaderCompileTimer.End(); + gShaderCompileQueryTime += shaderCompileTimer.GetDuration(); + } + + return bValid; +} + +void CGLMProgram::LogSlow( EGLMProgramLang lang ) +{ + // find the desc, see if it's marked + GLMShaderDesc *desc = &m_descs[ lang ]; + + if (!desc->m_slowMark) + { +#if !GLM_FREE_SHADER_TEXT + // log it + printf( "\n-------------- Slow %s ( CGLMProgram @ %p, lang %s, name %d ) : \n%s \n", + m_type==kGLMVertexProgram ? "VS" : "FS", + this, + lang==kGLMGLSL ? "GLSL" : "ARB", + (int)(lang==kGLMGLSL ? (int)desc->m_object.glsl : (int)desc->m_object.arb), + m_text + ); +#endif + } + else // complain on a decreasing basis (powers of two) + { + if ( (desc->m_slowMark & (desc->m_slowMark-1)) == 0 ) + { + // short blurb + printf( "\n Slow %s ( CGLMProgram @ %p, lang %s, name %d ) (%d times)", + m_type==kGLMVertexProgram ? "VS" : "FS", + this, + lang==kGLMGLSL ? "GLSL" : "ARB", + (int)(lang==kGLMGLSL ? (int)desc->m_object.glsl : (int)desc->m_object.arb), + desc->m_slowMark+1 + ); + } + } + + // mark it + desc->m_slowMark++; + + +} + +void CGLMProgram::GetLabelIndexCombo ( char *labelOut, int labelOutMaxChars, int *indexOut, int *comboOut ) +{ + // find the label string + // example: + // trans#2871 label:vs-file vertexlit_and_unlit_generic_vs20 vs-index 294912 vs-combo 1234 + // Done in SetProgramText + + *labelOut = 0; + *indexOut = -1; + + if ((strlen( m_labelName ) != 0)) + { + Q_strncpy( labelOut, m_labelName, labelOutMaxChars ); + *indexOut = m_labelIndex; + *comboOut = m_labelCombo; + } +} + +void CGLMProgram::GetComboIndexNameString ( char *stringOut, int stringOutMaxChars ) // mmmmmmmm-nnnnnnnn-filename +{ + // find the label string + // example: + // trans#2871 label:vs-file vertexlit_and_unlit_generic_vs20 vs-index 294912 vs-combo 1234 + // Done in SetProgramText + + *stringOut = 0; + + int len = strlen( m_labelName ); + + if ( (len+20) < stringOutMaxChars ) + { + // output formatted version + sprintf( stringOut, "%08X-%08X-%s", m_labelCombo, m_labelIndex, m_labelName ); + } +} + +//=============================================================================== + + +CGLMShaderPair::CGLMShaderPair( GLMContext *ctx ) +{ + m_ctx = ctx; + m_vertexProg = m_fragmentProg = NULL; + + m_program = gGL->glCreateProgram(); + + m_locVertexParams = -1; + m_locVertexBoneParams = -1; + m_locVertexScreenParams = -1; + m_nScreenWidthHeight = 0xFFFFFFFF; + m_locVertexInteger0 = -1; // "i0" + memset( m_locVertexBool, 0xFF, sizeof( m_locVertexBool ) ); + memset( m_locFragmentBool, 0xFF, sizeof( m_locFragmentBool ) ); + m_bHasBoolOrIntUniforms = false; + + m_locFragmentParams = -1; + + m_locFragmentFakeSRGBEnable = -1; + m_fakeSRGBEnableValue = -1.0f; + + memset( m_locSamplers, 0xFF, sizeof( m_locSamplers ) ); + + m_valid = false; + m_bCheckLinkStatus = false; + m_revision = 0; // bumps to 1 once linked +} + +CGLMShaderPair::~CGLMShaderPair( ) +{ + if (m_program) + { + gGL->glDeleteProgram( m_program ); + m_program = 0; + } +} + +bool CGLMShaderPair::ValidateProgramPair() +{ + if ( m_vertexProg && m_vertexProg->m_descs[kGLMGLSL].m_textPresent && !m_vertexProg->m_descs[kGLMGLSL].m_valid ) + { + m_vertexProg->CheckValidity( kGLMGLSL ); + } + if (m_fragmentProg && m_fragmentProg->m_descs[kGLMGLSL].m_textPresent && !m_fragmentProg->m_descs[kGLMGLSL].m_valid) + { + m_fragmentProg->CheckValidity( kGLMGLSL ); + } + + if ( !m_valid && m_bCheckLinkStatus ) + { + bool bTimeShaderCompiles = (CommandLine()->FindParm( "-gl_time_shader_compiles" ) != 0); + // If using "-gl_time_shader_compiles", keeps track of total cycle count spent on shader compiles. + CFastTimer shaderCompileTimer; + if (bTimeShaderCompiles) + { + shaderCompileTimer.Start(); + } + + // check for success + GLint result = GL_TRUE; + gGL->glGetProgramiv(m_program, GL_LINK_STATUS, &result); + m_bCheckLinkStatus = false; + + if (result == GL_TRUE) + { + // success + + m_valid = true; + m_revision++; + } + else + { + GLint length = 0; + GLint laux = 0; + + // do some digging +#if !GLM_FREE_SHADER_TEXT + char *vtemp = strdup( m_vertexProg->m_text ); + vtemp[m_vertexProg->m_descs[kGLMGLSL].m_textOffset + m_vertexProg->m_descs[kGLMGLSL].m_textLength] = 0; + + char *ftemp = strdup( m_fragmentProg->m_text ); + ftemp[m_fragmentProg->m_descs[kGLMGLSL].m_textOffset + m_fragmentProg->m_descs[kGLMGLSL].m_textLength] = 0; + + GLMPRINTF( ("-D- ----- GLSL vertex program selected: %08x (handle %08x)", m_vertexProg, m_vertexProg->m_descs[kGLMGLSL].m_object.glsl) ); + GLMPRINTTEXT( (vtemp + m_vertexProg->m_descs[kGLMGLSL].m_textOffset, eDebugDump, GLMPRINTTEXT_NUMBEREDLINES) ); + + GLMPRINTF( ("-D- ----- GLSL fragment program selected: %08x (handle %08x)", m_fragmentProg, m_fragmentProg->m_descs[kGLMGLSL].m_object.glsl) ); + GLMPRINTTEXT( (ftemp + m_fragmentProg->m_descs[kGLMGLSL].m_textOffset, eDebugDump, GLMPRINTTEXT_NUMBEREDLINES) ); + + free( ftemp ); + free( vtemp ); +#endif + GLMPRINTF( ("-D- -----end-----") ); + } + + if (m_valid) + { + gGL->glUseProgram( m_program ); + + m_ctx->NewLinkedProgram(); + + m_locVertexParams = gGL->glGetUniformLocation( m_program, "vc" ); + m_locVertexBoneParams = gGL->glGetUniformLocation( m_program, "vcbones" ); + m_locVertexScreenParams = gGL->glGetUniformLocation( m_program, "vcscreen" ); + m_locAlphaRef = gGL->glGetUniformLocation( m_program, "alpha_ref" ); + + m_nScreenWidthHeight = 0xFFFFFFFF; + + m_locVertexInteger0 = gGL->glGetUniformLocation( m_program, "i0" ); + + m_bHasBoolOrIntUniforms = false; + if (m_locVertexInteger0 >= 0) + m_bHasBoolOrIntUniforms = true; + + for (uint i = 0; i < cMaxVertexShaderBoolUniforms; i++) + { + char buf[256]; + V_snprintf( buf, sizeof(buf), "b%d", i ); + m_locVertexBool[i] = gGL->glGetUniformLocation( m_program, buf ); + if (m_locVertexBool[i] != -1) + m_bHasBoolOrIntUniforms = true; + } + + for (uint i = 0; i < cMaxFragmentShaderBoolUniforms; i++) + { + char buf[256]; + V_snprintf( buf, sizeof(buf), "fb%d", i ); + m_locFragmentBool[i] = gGL->glGetUniformLocation( m_program, buf ); + if (m_locFragmentBool[i] != -1) + m_bHasBoolOrIntUniforms = true; + } + + m_locFragmentParams = gGL->glGetUniformLocation( m_program, "pc" ); + + for (uint i = 0; i < kGLMNumProgramTypes; i++) + { + m_NumUniformBufferParams[i] = 0; + + if (i == kGLMVertexProgram) + { + if (m_locVertexParams < 0) + continue; + } + else if (m_locFragmentParams < 0) + continue; + + const uint nNum = (i == kGLMVertexProgram) ? m_vertexProg->m_descs[kGLMGLSL].m_highWater : m_fragmentProg->m_descs[kGLMGLSL].m_highWater; + + uint j; + for (j = 0; j < nNum; j++) + { + char buf[256]; + V_snprintf( buf, sizeof(buf), "%cc[%i]", "vp"[i], j ); + // Grab the handle of each array element, so we can more efficiently update array elements in the middle. + int l = m_UniformBufferParams[i][j] = gGL->glGetUniformLocation( m_program, buf ); + if (l < 0) + break; + } + + m_NumUniformBufferParams[i] = j; + } + + m_locFragmentFakeSRGBEnable = gGL->glGetUniformLocation( m_program, "flSRGBWrite" ); + m_fakeSRGBEnableValue = -1.0f; + + for (int sampler = 0; sampler < 16; sampler++) + { + char tmp[16]; + sprintf( tmp, "sampler%d", sampler ); // sampler0 .. sampler1.. etc + + GLint nLoc = gGL->glGetUniformLocation( m_program, tmp ); + m_locSamplers[sampler] = nLoc; + if (nLoc >= 0) + { + gGL->glUniform1i( nLoc, sampler ); + } + } + } + else + { + m_locVertexParams = -1; + m_locVertexBoneParams = -1; + m_locVertexScreenParams = -1; + m_nScreenWidthHeight = 0xFFFFFFFF; + + m_locVertexInteger0 = -1; + memset( m_locVertexBool, 0xFF, sizeof(m_locVertexBool) ); + memset( m_locFragmentBool, 0xFF, sizeof(m_locFragmentBool) ); + m_bHasBoolOrIntUniforms = false; + + m_locFragmentParams = -1; + m_locFragmentFakeSRGBEnable = -1; + m_fakeSRGBEnableValue = -999; + + memset( m_locSamplers, 0xFF, sizeof(m_locSamplers) ); + + m_revision = 0; + } + + if (bTimeShaderCompiles) + { + shaderCompileTimer.End(); + gShaderLinkQueryTime += shaderCompileTimer.GetDuration(); + } + } + + return m_valid; +} + +// glUseProgram() will be called as a side effect! +bool CGLMShaderPair::SetProgramPair( CGLMProgram *vp, CGLMProgram *fp ) +{ + bool bTimeShaderCompiles = (CommandLine()->FindParm( "-gl_time_shader_compiles" ) != 0); + // If using "-gl_time_shader_compiles", keeps track of total cycle count spent on shader compiles. + CFastTimer shaderCompileTimer; + if (bTimeShaderCompiles) + { + shaderCompileTimer.Start(); + } + + m_valid = false; // assume failure + + // No need to check that vp and fp are valid at this point (ie shader compile succeed) + // It is permissible to attach a shader object to a program before source code has been loaded + // into the shader object or before the shader object has been compiled. The program won't + // link if one or more of the shader objects has not been successfully compiled. + // (Defer querying the compile and link status to take advantage of GLSL shaders + // building in parallels) + bool vpgood = (vp != NULL); + bool fpgood = (fp != NULL); + + if ( !fpgood ) + { + // fragment side allowed to be "null". + fp = m_ctx->m_pNullFragmentProgram; + } + + if ( vpgood && fpgood ) + { + if ( vp->m_nCentroidMask != fp->m_nCentroidMask ) + { + Warning( "CGLMShaderPair::SetProgramPair: Centroid masks differ at link time of vertex shader %s and pixel shader %s!\n", + vp->m_shaderName, fp->m_shaderName ); + } + + // attempt link. but first, detach any previously attached programs + if (m_vertexProg) + { + gGL->glDetachShader(m_program, m_vertexProg->m_descs[kGLMGLSL].m_object.glsl); + m_vertexProg = NULL; + } + + if (m_fragmentProg) + { + gGL->glDetachShader(m_program, m_fragmentProg->m_descs[kGLMGLSL].m_object.glsl); + m_fragmentProg = NULL; + } + + // now attach + + gGL->glAttachShader( m_program, vp->m_descs[kGLMGLSL].m_object.glsl ); + m_vertexProg = vp; + + gGL->glAttachShader( m_program, fp->m_descs[kGLMGLSL].m_object.glsl ); + m_fragmentProg = fp; + + // force the locations for input attributes v0-vN to be at locations 0-N + // use the vertex attrib map to know which slots are live or not... oy! we don't have that map yet... but it's OK. + // fallback - just force v0-v15 to land in locations 0-15 as a standard. + + for( int i = 0; i < 16; i++ ) + { + char tmp[16]; + sprintf(tmp, "v%d", i); // v0 v1 v2 ... et al + + gGL->glBindAttribLocation( m_program, i, tmp ); + } +#if !GLM_FREE_SHADER_TEXT + if (CommandLine()->CheckParm("-dumpallshaders")) + { + // Dump all shaders, for debugging. + FILE* pFile = fopen("shaderdump.txt", "a+"); + if (pFile) + { + fprintf(pFile, "--------------VP:%s\n%s\n", vp->m_shaderName, vp->m_text); + fprintf(pFile, "--------------FP:%s\n%s\n", fp->m_shaderName, fp->m_text); + fclose(pFile); + } + } +#endif + + // now link + gGL->glLinkProgram( m_program ); + + GLint isLinked = 0; + gGL->glGetProgramiv(m_program, GL_LINK_STATUS, &isLinked); + if(isLinked == GL_FALSE) + { + GLint maxLength = 0; + gGL->glGetShaderiv(m_program, GL_INFO_LOG_LENGTH, &maxLength); + + GLchar log[4096]; + gGL->glGetProgramInfoLog( m_program, sizeof(log), &maxLength, log ); + if( maxLength ) + { + Msg("vp: \n%s\nfp: \n%s\n", vp->m_text, fp->m_text ); + Msg("shader %d link log: %s\n", m_program, log); + } + } + + m_bCheckLinkStatus = true; + } + else + { + // fail + Assert(!"Can't link these programs"); + } + + // Check shader validity at creation time. This will cause the driver to not be able to + // multi-thread/defer shader compiles, but it is useful for getting error messages on the + // shader when it is compiled + bool bValidateShaderEarly = (CommandLine()->FindParm( "-gl_validate_shader_early" ) != 0); + if (bValidateShaderEarly) + { + ValidateProgramPair(); + } + + if (bTimeShaderCompiles) + { + shaderCompileTimer.End(); + gShaderLinkTime += shaderCompileTimer.GetDuration(); + gShaderLinkCount++; + } + + return m_valid; +} + + +bool CGLMShaderPair::RefreshProgramPair ( void ) +{ + // re-link and re-query the uniforms. + + // since SetProgramPair knows how to detach previously attached shader objects, just pass the same ones in again. + CGLMProgram *vp = m_vertexProg; + CGLMProgram *fp = m_fragmentProg; + + bool vpgood = (vp!=NULL) && (vp->m_descs[ kGLMGLSL ].m_valid); + bool fpgood = (fp!=NULL) && (fp->m_descs[ kGLMGLSL ].m_valid); + + if (vpgood && fpgood) + { + SetProgramPair( vp, fp ); + } + else + { + DebuggerBreak(); + return false; + } + + return false; +} + + +//=============================================================================== + +CGLMShaderPairCache::CGLMShaderPairCache( GLMContext *ctx ) +{ + m_ctx = ctx; + + m_mark = 1; + + m_rowsLg2 = gl_shaderpair_cacherows_lg2.GetInt(); + if (m_rowsLg2 < 10) + m_rowsLg2 = 10; + m_rows = 1<Purge(); + (void)purgeResult; + Assert( !purgeResult ); + + if (m_entries) + { + free( m_entries ); + m_entries = NULL; + } + + if (m_evictions) + { + free( m_evictions ); + m_evictions = NULL; + } + +#if GL_SHADER_PAIR_CACHE_STATS + if (m_hits) + { + free( m_hits ); + m_hits = NULL; + } +#endif +} + +// Set this convar internally to build or add to the shader pair cache file (link hints) +// We really only expect this to work on POSIX +static ConVar glm_cacheprograms( "glm_cacheprograms", "0", FCVAR_DEVELOPMENTONLY ); + +#define PROGRAM_CACHE_FILE "program_cache.cfg" + +static void WriteToProgramCache( CGLMShaderPair *pair ) +{ + KeyValues *pProgramCache = new KeyValues( "programcache" ); + pProgramCache->LoadFromFile( g_pFullFileSystem, PROGRAM_CACHE_FILE, "MOD" ); + + if ( !pProgramCache ) + { + Warning( "Could not write to program cache file!\n" ); + return; + } + + // extract values of interest which represent a pair of shaders + + char vprogramName[128]; + int vprogramStaticIndex = -1; + int vprogramDynamicIndex = -1; + pair->m_vertexProg->GetLabelIndexCombo( vprogramName, sizeof(vprogramName), &vprogramStaticIndex, &vprogramDynamicIndex ); + + + char pprogramName[128]; + int pprogramStaticIndex = -1; + int pprogramDynamicIndex = -1; + pair->m_fragmentProg->GetLabelIndexCombo( pprogramName, sizeof(pprogramName), &pprogramStaticIndex, &pprogramDynamicIndex ); + + // make up a key - this thing is really a list of tuples, so need not be keyed by anything particular + KeyValues *pProgramKey = pProgramCache->CreateNewKey(); + Assert( pProgramKey ); + + pProgramKey->SetString ( "vs", vprogramName ); + pProgramKey->SetString ( "ps", pprogramName ); + + pProgramKey->SetInt ( "vs_static", vprogramStaticIndex ); + pProgramKey->SetInt ( "ps_static", pprogramStaticIndex ); + + pProgramKey->SetInt ( "vs_dynamic", vprogramDynamicIndex ); + pProgramKey->SetInt ( "ps_dynamic", pprogramDynamicIndex ); + + pProgramCache->SaveToFile( g_pFullFileSystem, PROGRAM_CACHE_FILE, "MOD" ); + pProgramCache->deleteThis(); +} + +// Calls glUseProgram() as a side effect +CGLMShaderPair *CGLMShaderPairCache::SelectShaderPairInternal( CGLMProgram *vp, CGLMProgram *fp, uint extraKeyBits, int rowIndex ) +{ + CGLMShaderPair *result = NULL; + +#if GLMDEBUG + int loglevel = gl_shaderpair_cachelog.GetInt(); +#else + const int loglevel = 0; +#endif + + char vtempname[128]; + int vtempindex = -1; vtempindex; + int vtempcombo = -1; vtempcombo; + + char ptempname[128]; + int ptempindex = -1; ptempindex; + int ptempcombo = -1; ptempcombo; + + CGLMPairCacheEntry *row = HashRowPtr( rowIndex ); + + // Re-probe to find the oldest and first unoccupied entry (this func should be very rarely called if the cache is properly configured so re-scanning shouldn't matter). + int hitway, emptyway, oldestway; + HashRowProbe( row, vp, fp, extraKeyBits, hitway, emptyway, oldestway ); + Assert( hitway == -1 ); + + // we missed. if there is no empty way, then somebody's getting evicted. + int destway = -1; + + if (emptyway>=0) + { + destway = emptyway; + + if (loglevel >= 2) // misses logged at level 3 and higher + { + printf("\nSSP: miss - row %05d - ", rowIndex ); + } + } + else + { + // evict the oldest way + Assert( oldestway >= 0); // better not come back negative + + CGLMPairCacheEntry *evict = row + oldestway; + + Assert( evict->m_pair != NULL ); + Assert( evict->m_pair != m_ctx->m_pBoundPair ); // just check + + ///////////////////////FIXME may need to do a shoot-down if the pair being evicted is currently active in the context + + m_evictions[ rowIndex ]++; + + // log eviction if desired + if (loglevel >= 2) // misses logged at level 3 and higher + { + //evict->m_vertexProg->GetLabelIndexCombo( vtempname, sizeof(vtempname), &vtempindex, &vtempcombo ); + //evict->m_fragmentProg->GetLabelIndexCombo( ptempname, sizeof(ptempname), &ptempindex, &ptempcombo ); + //printf("\nSSP: miss - row %05d - [ %s/%d/%d %s/%d/%d ]'s %d'th eviction - ", rowIndex, vtempname, vtempindex, vtempcombo, ptempname, ptempindex, ptempcombo, m_evictions[ rowIndex ] ); + + evict->m_vertexProg->GetComboIndexNameString( vtempname, sizeof(vtempname) ); + evict->m_fragmentProg->GetComboIndexNameString( ptempname, sizeof(ptempname) ); + printf("\nSSP: miss - row %05d - [ %s + %s ]'s %d'th eviction - ", rowIndex, vtempname, ptempname, m_evictions[ rowIndex ] ); + } + + delete evict->m_pair; evict->m_pair = NULL; + memset( evict, 0, sizeof(*evict) ); + + destway = oldestway; + } + + // make the new entry + CGLMPairCacheEntry *newentry = row + destway; + + newentry->m_lastMark = m_mark; + newentry->m_vertexProg = vp; + newentry->m_fragmentProg = fp; + newentry->m_extraKeyBits = extraKeyBits; + newentry->m_pair = new CGLMShaderPair( m_ctx ); + Assert( newentry->m_pair ); + newentry->m_pair->SetProgramPair( vp, fp ); + + if (loglevel >= 2) // say a little bit more + { + //newentry->m_vertexProg->GetLabelIndexCombo( vtempname, sizeof(vtempname), &vtempindex, &vtempcombo ); + //newentry->m_fragmentProg->GetLabelIndexCombo( ptempname, sizeof(ptempname), &ptempindex, &ptempcombo ); + //printf("new [ %s/%d/%d %s/%d/%d ]", vtempname, vtempindex, vtempcombo, ptempname, ptempindex, ptempcombo ); + + newentry->m_vertexProg->GetComboIndexNameString( vtempname, sizeof(vtempname) ); + newentry->m_fragmentProg->GetComboIndexNameString( ptempname, sizeof(ptempname) ); + printf("new [ %s + %s ]", vtempname, ptempname ); + } + + m_mark = m_mark+1; + if (!m_mark) // somewhat unlikely this will ever be reached.. but we need to avoid zero as a mark value + { + m_mark = 1; + } + + result = newentry->m_pair; + + if (glm_cacheprograms.GetInt()) + { + WriteToProgramCache( newentry->m_pair ); + } + + return result; +} + +void CGLMShaderPairCache::QueryShaderPair( int index, GLMShaderPairInfo *infoOut ) +{ + if ( (index<0) || ( static_cast(index) >= (m_rows*m_ways) ) ) + { + // no such location + memset( infoOut, 0, sizeof(*infoOut) ); + + infoOut->m_status = -1; + } + else + { + // locate the entry, and see if an active pair is present. + // if so, extract info and return with m_status=1. + // if not, exit with m_status = 0. + + CGLMPairCacheEntry *entry = &m_entries[index]; + + if (entry->m_pair) + { + // live + // extract values of interest for caller + + entry->m_pair->m_vertexProg->GetLabelIndexCombo ( infoOut->m_vsName, sizeof(infoOut->m_vsName), &infoOut->m_vsStaticIndex, &infoOut->m_vsDynamicIndex ); + entry->m_pair->m_fragmentProg->GetLabelIndexCombo ( infoOut->m_psName, sizeof(infoOut->m_psName), &infoOut->m_psStaticIndex, &infoOut->m_psDynamicIndex ); + + infoOut->m_status = 1; + } + else + { + // not + memset( infoOut, 0, sizeof(*infoOut) ); + infoOut->m_status = 0; + } + } +} + +bool CGLMShaderPairCache::PurgePairsWithShader( CGLMProgram *prog ) +{ + bool result = false; + + // walk all rows*ways + int limit = m_rows * m_ways; + for( int i=0; i < limit; i++) + { + CGLMPairCacheEntry *entry = &m_entries[i]; + + if (entry->m_pair) + { + //scrub it, if not currently bound, and if the supplied shader matches either stage + if ( (entry->m_vertexProg==prog) || (entry->m_fragmentProg==prog) ) + { + // found it, but does it conflict with bound pair ? + if (entry->m_pair == m_ctx->m_pBoundPair) + { + m_ctx->m_pBoundPair = NULL; + m_ctx->m_bDirtyPrograms = true; + } + delete entry->m_pair; + memset( entry, 0, sizeof(*entry) ); + } + } + } + return result; +} + +bool CGLMShaderPairCache::Purge( void ) +{ + bool result = false; + + // walk all rows*ways + int limit = m_rows * m_ways; + for( int i=0; i < limit; i++) + { + CGLMPairCacheEntry *entry = &m_entries[i]; + + if (entry->m_pair) + { + //scrub it, unless the pair is the currently bound pair in our parent glm context + if (entry->m_pair != m_ctx->m_pBoundPair) + { + delete entry->m_pair; + memset( entry, 0, sizeof(*entry) ); + } + else + { + result = true; + } + } + } + return result; +} + +void CGLMShaderPairCache::DumpStats ( void ) +{ +#if GL_SHADER_PAIR_CACHE_STATS + printf("\n------------------\npair cache stats"); + int total = 0; + for( uint row=0; row < m_rows; row++ ) + { + if ( (m_evictions[row] != 0) || (m_hits[row] != 0) ) + { + printf("\n row %d : %d evictions, %d hits",row,m_evictions[row], m_hits[row]); + total += m_evictions[row]; + } + } + printf("\n\npair cache evictions: %d\n-----------------------\n",total ); +#endif +} + + //=============================== + + diff --git a/togles/linuxwin/cglmquery.cpp b/togles/linuxwin/cglmquery.cpp new file mode 100644 index 00000000..99aac9f8 --- /dev/null +++ b/togles/linuxwin/cglmquery.cpp @@ -0,0 +1,363 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmquery.cpp +// +//=============================================================================== + +#include "togles/rendermechanism.h" + +#ifndef _WIN32 + #include +#endif + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + +//=============================================================================== + +// http://www.opengl.org/registry/specs/ARB/occlusion_query.txt +// Workaround for "Calling either GenQueriesARB or DeleteQueriesARB while any query of any target is active causes an INVALID_OPERATION error to be generated." +uint CGLMQuery::s_nTotalOcclusionQueryCreatesOrDeletes; + +extern ConVar gl_errorcheckall; +extern ConVar gl_errorcheckqueries; +extern ConVar gl_errorchecknone; + +// how many microseconds to wait after a failed query-available test +// presently on MTGL this doesn't happen, but it could change, keep this handy +ConVar gl_nullqueries( "gl_nullqueries", "0" ); + + +//=============================================================================== + +CGLMQuery::CGLMQuery( GLMContext *ctx, GLMQueryParams *params ) +{ + // get the type of query requested + // generate name(s) needed + // set initial state appropriately + + m_ctx = ctx; + m_params = *params; + + m_name = 0; + m_syncobj = 0; + + m_started = m_stopped = m_done = false; + + m_nullQuery = false; + // assume value of convar at start time + // does not change during individual query lifetime + // started null = stays null + // started live = stays live + + switch(m_params.m_type) + { + case EOcclusion: + { + //make an occlusion query (and a fence to go with it) + gGL->glGenQueries( 1, &m_name ); + s_nTotalOcclusionQueryCreatesOrDeletes++; + GLMPRINTF(("-A- CGLMQuery(OQ) created name %d", m_name)); + } + break; + + case EFence: + //make a fence - no aux fence needed + + m_syncobj = 0; + + if (gGL->m_bHave_GL_ARB_sync) + { /* GL_ARB_sync doesn't separate gen and set, so we do glFenceSync() later. */ } + else if (gGL->m_bHave_GL_NV_fence) + gGL->glGenFencesNV(1, &m_name ); + else if (gGL->m_bHave_GL_APPLE_fence) + gGL->glGenFencesAPPLE(1, &m_name ); + + GLMPRINTF(("-A- CGLMQuery(fence) created name %d", m_name)); + break; + } + +} + +CGLMQuery::~CGLMQuery() +{ + GLMPRINTF(("-A-> ~CGLMQuery")); + + // make sure query has completed (might not be necessary) + // delete the name(s) + + switch(m_params.m_type) + { + case EOcclusion: + { + // do a finish occlusion query ? + GLMPRINTF(("-A- ~CGLMQuery(OQ) deleting name %d", m_name)); + gGL->glDeleteQueries(1, &m_name ); + s_nTotalOcclusionQueryCreatesOrDeletes++; + } + break; + + case EFence: + { + // do a finish fence ? + GLMPRINTF(("-A- ~CGLMQuery(fence) deleting name %llu", gGL->m_bHave_GL_ARB_sync ? (unsigned long long) m_syncobj : (unsigned long long) m_name)); +#ifdef HAVE_GL_ARB_SYNC + if (gGL->m_bHave_GL_ARB_sync) + gGL->glDeleteSync( m_syncobj ); + else +#endif + if (gGL->m_bHave_GL_NV_fence) + gGL->glDeleteFencesNV(1, &m_name ); + else if (gGL->m_bHave_GL_APPLE_fence) + gGL->glDeleteFencesAPPLE(1, &m_name ); + } + break; + } + + m_name = 0; + m_syncobj = 0; + + GLMPRINTF(("-A-< ~CGLMQuery")); +} + + + + +void CGLMQuery::Start( void ) // "start counting" +{ + m_nullQuery = (gl_nullqueries.GetInt() != 0); // latch value for remainder of query life + + m_started = true; + m_stopped = false; + m_done = false; + + switch(m_params.m_type) + { + case EOcclusion: + { + if (m_nullQuery) + { + // do nothing.. + } + else + { + gGL->glBeginQuery( GL_ANY_SAMPLES_PASSED, m_name ); + } + } + break; + + case EFence: +#ifdef HAVE_GL_ARB_SYNC + if (gGL->m_bHave_GL_ARB_sync) + { + if (m_syncobj != 0) gGL->glDeleteSync(m_syncobj); + m_syncobj = gGL->glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + } + else +#endif + if (gGL->m_bHave_GL_NV_fence) + gGL->glSetFenceNV( m_name, GL_ALL_COMPLETED_NV ); + else if (gGL->m_bHave_GL_APPLE_fence) + gGL->glSetFenceAPPLE( m_name ); + + m_stopped = true; // caller should not call Stop on a fence, it self-stops + break; + } +} + +void CGLMQuery::Stop( void ) // "stop counting" +{ + Assert(m_started); + + if ( m_stopped ) + return; + + switch(m_params.m_type) + { + case EOcclusion: + { + if (m_nullQuery) + { + // do nothing.. + } + else + { + gGL->glEndQuery( GL_ANY_SAMPLES_PASSED ); // we are only putting the request-to-stop-counting into the cmd stream. + } + } + break; + + case EFence: + // nop - you don't "end" a fence, you just test it and/or finish it out in Complete + break; + } + + m_stopped = true; +} + +bool CGLMQuery::IsDone( void ) +{ + Assert(m_started); + Assert(m_stopped); + + if(!m_done) // you can ask more than once, but we only check until it comes back as done. + { + // on occlusion: glGetQueryObjectivARB - large cost on pre SLGU, cheap after + // on fence: glTestFence* on the fence + switch(m_params.m_type) + { + case EOcclusion: // just test the fence that was set after the query begin + { + if (m_nullQuery) + { + // do almost nothing.. but claim work is complete + m_done = true; + } + else + { + // prepare to pay a big price on drivers prior to 10.6.4+SLGU + + GLuint available = 0; + gGL->glGetQueryObjectuiv(m_name, GL_QUERY_RESULT_AVAILABLE, &available ); + + m_done = (available != 0); + } + } + break; + + case EFence: + { +#ifdef HAVE_GL_ARB_SYNC + if (gGL->m_bHave_GL_ARB_sync) + m_done = (gGL->glClientWaitSync( m_syncobj, 0, 0 ) == GL_ALREADY_SIGNALED); + else +#endif + if ( m_name == 0 ) + m_done = true; + else if (gGL->m_bHave_GL_NV_fence) + m_done = gGL->glTestFenceNV( m_name ) != 0; + else if (gGL->m_bHave_GL_APPLE_fence) + m_done = gGL->glTestFenceAPPLE( m_name ) != 0; + + if (m_done) + { + if (gGL->m_bHave_GL_ARB_sync) + { /* no-op; we already know it's set to GL_ALREADY_SIGNALED. */ } + else + { + if (gGL->m_bHave_GL_NV_fence) + gGL->glFinishFenceNV( m_name ); // no set fence goes un-finished + else if (gGL->m_bHave_GL_APPLE_fence) + gGL->glFinishFenceAPPLE( m_name ); // no set fence goes un-finished + } + } + } + break; + } + } + + return m_done; +} + +void CGLMQuery::Complete( uint *result ) +{ + uint resultval = 0; + //bool bogus_available = false; + + // blocking call if not done + Assert(m_started); + Assert(m_stopped); + + switch(m_params.m_type) + { + case EOcclusion: + { + if (m_nullQuery) + { + m_done = true; + resultval = 0; // we did say "null queries..." + } + else + { + gGL->glGetQueryObjectuiv( m_name, GL_QUERY_RESULT, &resultval); + m_done = true; + } + } + break; + + case EFence: + { + if(!m_done) + { +#ifdef HAVE_GL_ARB_SYNC + if (gGL->m_bHave_GL_ARB_sync) + { + if (gGL->glClientWaitSync( m_syncobj, 0, 0 ) != GL_ALREADY_SIGNALED) + { + GLenum syncstate; + do { + const GLuint64 timeout = 10 * ((GLuint64)1000 * 1000 * 1000); // 10 seconds in nanoseconds. + (void)timeout; + syncstate = gGL->glClientWaitSync( m_syncobj, GL_SYNC_FLUSH_COMMANDS_BIT, 0 ); + } while (syncstate == GL_TIMEOUT_EXPIRED); // any errors or success break out of this loop. + } + } + else +#endif + if (gGL->m_bHave_GL_NV_fence) + gGL->glFinishFenceNV( m_name ); + else if (gGL->m_bHave_GL_APPLE_fence) + gGL->glFinishFenceAPPLE( m_name ); + + m_done = true; // for clarity or if they try to Complete twice + } + } + break; + } + + Assert( m_done ); + + // reset state for re-use - i.e. you have to call Complete if you want to re-use the object + m_started = m_stopped = m_done = false; + + if (result) // caller may pass NULL if not interested in result, for example to clear a fence + { + *result = resultval; + } +} + + + + // accessors for the started/stopped state +bool CGLMQuery::IsStarted ( void ) +{ + return m_started; +} + +bool CGLMQuery::IsStopped ( void ) +{ + return m_stopped; +} + diff --git a/togles/linuxwin/cglmtex.cpp b/togles/linuxwin/cglmtex.cpp new file mode 100644 index 00000000..da4c9a11 --- /dev/null +++ b/togles/linuxwin/cglmtex.cpp @@ -0,0 +1,4383 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// cglmtex.cpp +// +//=============================================================================== + +#include "togles/rendermechanism.h" + +extern "C" { +#include "decompress.h" +} + +#include "tier0/icommandline.h" +#include "glmtexinlines.h" + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + +#if defined(OSX) +#include "appframework/ilaunchermgr.h" +extern ILauncherMgr *g_pLauncherMgr; +#endif + +//=============================================================================== + +#if GLMDEBUG +CGLMTex *g_pFirstCGMLTex; +#endif + +ConVar gl_pow2_tempmem( "gl_pow2_tempmem", "0", FCVAR_INTERNAL_USE, + "If set, use power-of-two allocations for temporary texture memory during uploads. " + "May help with fragmentation on certain systems caused by heavy churn of large allocations." ); + +#define TEXSPACE_LOGGING 0 + +// encoding layout to an index where the bits read +// 4 : 1 if compressed +// 2 : 1 if not power of two +// 1 : 1 if mipmapped + +bool pwroftwo (int val ) +{ + return (val & (val-1)) == 0; +} + +int sEncodeLayoutAsIndex( GLMTexLayoutKey *key ) +{ + int index = 0; + + if (key->m_texFlags & kGLMTexMipped) + { + index |= 1; + } + + if ( ! ( pwroftwo(key->m_xSize) && pwroftwo(key->m_ySize) && pwroftwo(key->m_zSize) ) ) + { + // if not all power of two + index |= 2; + } + + if (GetFormatDesc( key->m_texFormat )->m_chunkSize >1 ) + { + index |= 4; + } + + return index; +} + +static unsigned long g_texGlobalBytes[8]; + +//=============================================================================== + +const GLMTexFormatDesc g_formatDescTable[] = +{ + // not yet handled by this table: + // D3DFMT_INDEX16, D3DFMT_VERTEXDATA // D3DFMT_INDEX32, + // WTF { D3DFMT_R5G6R5 ???, GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 1, 2 }, + // WTF { D3DFMT_A ???, GL_ALPHA8, GL_ALPHA, GL_UNSIGNED_BYTE, 1, 1 }, + // ??? D3DFMT_V8U8, + // ??? D3DFMT_Q8W8V8U8, + // ??? D3DFMT_X8L8V8U8, + // ??? D3DFMT_R32F, + // ??? D3DFMT_D24X4S4 unsure how to handle or if it is ever used.. + // ??? D3DFMT_D15S1 ever used ? + // ??? D3DFMT_D24X8 ever used? + + // summ-name d3d-format gl-int-format gl-int-format-srgb gl-data-format gl-data-type chunksize, bytes-per-sqchunk + { "_D16", D3DFMT_D16, GL_DEPTH_COMPONENT16, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT, 1, 2 }, + { "_D24X8", D3DFMT_D24X8, GL_DEPTH_COMPONENT24, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, 1, 4 }, // ??? unsure on this one + { "_D24S8", D3DFMT_D24S8, GL_DEPTH24_STENCIL8_EXT, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, 1, 4 }, + + { "_A8R8G8B8", D3DFMT_A8R8G8B8, GL_RGBA8, GL_SRGB8_ALPHA8_EXT, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 1, 4 }, + { "_A4R4G4B4", D3DFMT_A4R4G4B4, GL_RGBA4, 0, GL_BGRA, GL_UNSIGNED_SHORT_4_4_4_4_REV, 1, 2 }, + { "_X8R8G8B8", D3DFMT_X8R8G8B8, GL_RGB8, GL_SRGB8_EXT, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 1, 4 }, + + { "_X1R5G5B5", D3DFMT_X1R5G5B5, GL_RGB5, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 1, 2 }, + { "_A1R5G5B5", D3DFMT_A1R5G5B5, GL_RGB5_A1, 0, GL_BGRA, GL_UNSIGNED_SHORT_1_5_5_5_REV, 1, 2 }, + + { "_L8", D3DFMT_L8, GL_LUMINANCE8, GL_SLUMINANCE8_EXT, GL_LUMINANCE, GL_UNSIGNED_BYTE, 1, 1 }, + { "_A8L8", D3DFMT_A8L8, GL_LUMINANCE8_ALPHA8, GL_SLUMINANCE8_ALPHA8_EXT, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE, 1, 2 }, + + { "_DXT1", D3DFMT_DXT1, GL_COMPRESSED_RGB_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_S3TC_DXT1_EXT, GL_RGB, GL_UNSIGNED_BYTE, 4, 8 }, + { "_DXT3", D3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, GL_RGBA, GL_UNSIGNED_BYTE, 4, 16 }, + { "_DXT5", D3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, GL_RGBA, GL_UNSIGNED_BYTE, 4, 16 }, + + { "_A16B16G16R16F", D3DFMT_A16B16G16R16F, GL_RGBA16F_ARB, 0, GL_RGBA, GL_HALF_FLOAT_ARB, 1, 8 }, + { "_A16B16G16R16", D3DFMT_A16B16G16R16, GL_RGBA16, 0, GL_RGBA, GL_UNSIGNED_SHORT, 1, 8 }, // 16bpc integer tex + + { "_A32B32G32R32F", D3DFMT_A32B32G32R32F, GL_RGBA32F_ARB, 0, GL_RGBA, GL_FLOAT, 1, 16 }, + + { "_R8G8B8", D3DFMT_R8G8B8, GL_RGB8, GL_SRGB8_EXT, GL_BGR, GL_UNSIGNED_BYTE, 1, 3 }, + + { "_A8", D3DFMT_A8, GL_ALPHA8, 0, GL_ALPHA, GL_UNSIGNED_BYTE, 1, 1 }, + { "_R5G6B5", D3DFMT_R5G6B5, GL_RGB, GL_SRGB_EXT, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, 1, 2 }, + + // fakey tex formats: the stated GL format and the memory layout may not agree (U8V8 for example) + + // _Q8W8V8U8 we just pass through as RGBA bytes. Shader does scale/bias fix + { "_Q8W8V8U8", D3DFMT_Q8W8V8U8, GL_RGBA8, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, 1, 4 }, // straight ripoff of D3DFMT_A8R8G8B8 + + // U8V8 is exposed to the client as 2-bytes per texel, but we download it as 3-byte RGB. + // WriteTexels needs to do that conversion from rg8 to rgb8 in order to be able to download it correctly + { "_V8U8", D3DFMT_V8U8, GL_RGB8, 0, GL_RG, GL_BYTE, 1, 2 }, + + { "_R32F", D3DFMT_R32F, GL_R32F, GL_R32F, GL_RED, GL_FLOAT, 1, 4 }, +//$ TODO: Need to merge bitmap changes over from Dota to get these formats. +#if 0 + { "_A2R10G10B10", D3DFMT_A2R10G10B10, GL_RGB10_A2, GL_RGB10_A2, GL_RGBA, GL_UNSIGNED_INT_10_10_10_2, 1, 4 }, + { "_A2B10G10R10", D3DFMT_A2B10G10R10, GL_RGB10_A2, GL_RGB10_A2, GL_BGRA, GL_UNSIGNED_INT_10_10_10_2, 1, 4 }, +#endif + + /* + // NV shadow depth tex + D3DFMT_NV_INTZ = 0x5a544e49, // MAKEFOURCC('I','N','T','Z') + D3DFMT_NV_RAWZ = 0x5a574152, // MAKEFOURCC('R','A','W','Z') + + // NV null tex + D3DFMT_NV_NULL = 0x4c4c554e, // MAKEFOURCC('N','U','L','L') + + // ATI shadow depth tex + D3DFMT_ATI_D16 = 0x36314644, // MAKEFOURCC('D','F','1','6') + D3DFMT_ATI_D24S8 = 0x34324644, // MAKEFOURCC('D','F','2','4') + + // ATI 1N and 2N compressed tex + D3DFMT_ATI_2N = 0x32495441, // MAKEFOURCC('A', 'T', 'I', '2') + D3DFMT_ATI_1N = 0x31495441, // MAKEFOURCC('A', 'T', 'I', '1') + */ +}; + +int g_formatDescTableCount = sizeof(g_formatDescTable) / sizeof( g_formatDescTable[0] ); + +const GLMTexFormatDesc *GetFormatDesc( D3DFORMAT format ) +{ + for( int i=0; i= range) DebuggerBreak(); + + *valuebuf = (*valuebuf << width) | scaled; +} + +// return true if successful +bool GLMGenTexels( GLMGenTexelParams *params ) +{ + unsigned char chunkbuf[256]; // can't think of any chunk this big.. + + const GLMTexFormatDesc *format = GetFormatDesc( params->m_format ); + + if (!format) + { + return FALSE; // fail + } + + // this section just generates one square chunk in the desired format + unsigned long *temp32 = (unsigned long*)chunkbuf; + unsigned int chunksize = 0; // we can sanity check against the format table with this + + switch( params->m_format ) + { + // comment shows byte order in RAM + // lowercase is bit arrangement in a byte + + case D3DFMT_A8R8G8B8: // B G R A + InsertTexelComponentFixed( params->a, 8, temp32 ); // A is inserted first and winds up at most significant bits after insertions follow + InsertTexelComponentFixed( params->r, 8, temp32 ); + InsertTexelComponentFixed( params->g, 8, temp32 ); + InsertTexelComponentFixed( params->b, 8, temp32 ); + chunksize = 4; + break; + + case D3DFMT_A4R4G4B4: // [ggggbbbb] [aaaarrrr] RA (nibbles) + InsertTexelComponentFixed( params->a, 4, temp32 ); + InsertTexelComponentFixed( params->r, 4, temp32 ); + InsertTexelComponentFixed( params->g, 4, temp32 ); + InsertTexelComponentFixed( params->b, 4, temp32 ); + chunksize = 2; + break; + + case D3DFMT_X8R8G8B8: // B G R X + InsertTexelComponentFixed( 0.0, 8, temp32 ); + InsertTexelComponentFixed( params->r, 8, temp32 ); + InsertTexelComponentFixed( params->g, 8, temp32 ); + InsertTexelComponentFixed( params->b, 8, temp32 ); + chunksize = 4; + break; + + case D3DFMT_X1R5G5B5: // [gggbbbbb] [xrrrrrgg] + InsertTexelComponentFixed( 0.0, 1, temp32 ); + InsertTexelComponentFixed( params->r, 5, temp32 ); + InsertTexelComponentFixed( params->g, 5, temp32 ); + InsertTexelComponentFixed( params->b, 5, temp32 ); + chunksize = 2; + break; + + case D3DFMT_A1R5G5B5: // [gggbbbbb] [arrrrrgg] + InsertTexelComponentFixed( params->a, 1, temp32 ); + InsertTexelComponentFixed( params->r, 5, temp32 ); + InsertTexelComponentFixed( params->g, 5, temp32 ); + InsertTexelComponentFixed( params->b, 5, temp32 ); + chunksize = 2; + break; + + case D3DFMT_L8: // L // caller, use R for L + InsertTexelComponentFixed( params->r, 8, temp32 ); + chunksize = 1; + break; + + case D3DFMT_A8L8: // L A // caller, use R for L and A for A + InsertTexelComponentFixed( params->a, 8, temp32 ); + InsertTexelComponentFixed( params->r, 8, temp32 ); + chunksize = 2; + break; + + case D3DFMT_R8G8B8: // B G R + InsertTexelComponentFixed( params->r, 8, temp32 ); + InsertTexelComponentFixed( params->g, 8, temp32 ); + InsertTexelComponentFixed( params->b, 8, temp32 ); + chunksize = 3; + break; + + case D3DFMT_A8: // A + InsertTexelComponentFixed( params->a, 8, temp32 ); + chunksize = 1; + break; + + case D3DFMT_R5G6B5: // [gggbbbbb] [rrrrrggg] + InsertTexelComponentFixed( params->r, 5, temp32 ); + InsertTexelComponentFixed( params->g, 6, temp32 ); + InsertTexelComponentFixed( params->b, 5, temp32 ); + chunksize = 2; + break; + + case D3DFMT_DXT1: + { + memset( temp32, 0, 8 ); // zap 8 bytes + + // two 565 RGB words followed by 32 bits of 2-bit interp values for a 4x4 block + // we write the same color to both slots and all zeroes for the mask (one color total) + + unsigned long dxt1_color = 0; + + // generate one such word and clone it + InsertTexelComponentFixed( params->r, 5, &dxt1_color ); + InsertTexelComponentFixed( params->g, 6, &dxt1_color ); + InsertTexelComponentFixed( params->b, 5, &dxt1_color ); + + // dupe + dxt1_color = dxt1_color | (dxt1_color<<16); + + // write into chunkbuf + *(unsigned long*)&chunkbuf[0] = dxt1_color; + + // color mask bits after that are already set to all zeroes. chunk is done. + chunksize = 8; + } + break; + + case D3DFMT_DXT3: + { + memset( temp32, 0, 16 ); // zap 16 bytes + + // eight bytes of alpha (16 4-bit alpha nibbles) + // followed by a DXT1 block + + unsigned long dxt3_alpha = 0; + for( int i=0; i<8; i++) + { + // splat same alpha through block + InsertTexelComponentFixed( params->a, 4, &dxt3_alpha ); + } + + unsigned long dxt3_color = 0; + + // generate one such word and clone it + InsertTexelComponentFixed( params->r, 5, &dxt3_color ); + InsertTexelComponentFixed( params->g, 6, &dxt3_color ); + InsertTexelComponentFixed( params->b, 5, &dxt3_color ); + + // dupe + dxt3_color = dxt3_color | (dxt3_color<<16); + + // write into chunkbuf + *(unsigned long*)&chunkbuf[0] = dxt3_alpha; + *(unsigned long*)&chunkbuf[4] = dxt3_alpha; + *(unsigned long*)&chunkbuf[8] = dxt3_color; + *(unsigned long*)&chunkbuf[12] = dxt3_color; + + chunksize = 16; + } + break; + + case D3DFMT_DXT5: + { + memset( temp32, 0, 16 ); // zap 16 bytes + + // DXT5 has 8 bytes of compressed alpha, then 8 bytes of compressed RGB like DXT1. + + // the 8 alpha bytes are 2 bytes of endpoint alpha values, then 16x3 bits of interpolants. + // so to write a single alpha value, just figure out the value, store it in both the first two bytes then store zeroes. + + InsertTexelComponentFixed( params->a, 8, (unsigned long*)&chunkbuf[0] ); + InsertTexelComponentFixed( params->a, 8, (unsigned long*)&chunkbuf[0] ); + // rest of the alpha mask was already zeroed. + + // now do colors + unsigned long dxt5_color = 0; + + // generate one such word and clone it + InsertTexelComponentFixed( params->r, 5, &dxt5_color ); + InsertTexelComponentFixed( params->g, 6, &dxt5_color ); + InsertTexelComponentFixed( params->b, 5, &dxt5_color ); + + // dupe + dxt5_color = dxt5_color | (dxt5_color<<16); + + // write into chunkbuf + *(unsigned long*)&chunkbuf[8] = dxt5_color; + *(unsigned long*)&chunkbuf[12] = dxt5_color; + + chunksize = 16; + } + break; + + + case D3DFMT_A32B32G32R32F: + { + *(float*)&chunkbuf[0] = params->r; + *(float*)&chunkbuf[4] = params->g; + *(float*)&chunkbuf[8] = params->b; + *(float*)&chunkbuf[12] = params->a; + + chunksize = 16; + } + break; + + case D3DFMT_A16B16G16R16: + memset( chunkbuf, 0, 8 ); + // R and G wind up in the first 32 bits + // B and A wind up in the second 32 bits + + InsertTexelComponentFixed( params->a, 16, (unsigned long*)&chunkbuf[4] ); // winds up as MSW of second word (note [4]) - thus last in RAM + InsertTexelComponentFixed( params->b, 16, (unsigned long*)&chunkbuf[4] ); + + InsertTexelComponentFixed( params->g, 16, (unsigned long*)&chunkbuf[0] ); + InsertTexelComponentFixed( params->r, 16, (unsigned long*)&chunkbuf[0] ); // winds up as LSW of first word, thus first in RAM + + chunksize = 8; + break; + + // not done yet + + + //case D3DFMT_D16: + //case D3DFMT_D24X8: + //case D3DFMT_D24S8: + + //case D3DFMT_A16B16G16R16F: + + default: + return FALSE; // fail + break; + } + + // once the chunk buffer is filled.. + + // sanity check the reported chunk size. + if (static_cast(chunksize) != format->m_bytesPerSquareChunk) + { + DebuggerBreak(); + return FALSE; + } + + // verify that the amount you want to write will not exceed the limit byte count + unsigned long destByteCount = chunksize * params->m_chunkCount; + + if (static_cast(destByteCount) > params->m_byteCountLimit) + { + DebuggerBreak(); + return FALSE; + } + + // write the bytes. + unsigned char *destP = (unsigned char*)params->m_dest; + for( int chunk=0; chunk < params->m_chunkCount; chunk++) + { + for( uint byteindex = 0; byteindex < chunksize; byteindex++) + { + *destP++ = chunkbuf[byteindex]; + } + } + params->m_bytesWritten = destP - (unsigned char*)params->m_dest; + + return TRUE; +} + + +//=============================================================================== +bool LessFunc_GLMTexLayoutKey( const GLMTexLayoutKey &a, const GLMTexLayoutKey &b ) +{ + #define DO_LESS(fff) if (a.fff != b.fff) { return (a.fff< b.fff); } + + DO_LESS(m_texGLTarget); + DO_LESS(m_texFormat); + DO_LESS(m_texFlags); + DO_LESS(m_texSamples); + DO_LESS(m_xSize); + DO_LESS(m_ySize) + DO_LESS(m_zSize); + + #undef DO_LESS + + return false; // they are equal +} + +CGLMTexLayoutTable::CGLMTexLayoutTable() +{ + m_layoutMap.SetLessFunc( LessFunc_GLMTexLayoutKey ); +} + +GLMTexLayout *CGLMTexLayoutTable::NewLayoutRef( GLMTexLayoutKey *pDesiredKey ) +{ + GLMTexLayoutKey tempKey; + GLMTexLayoutKey *key = pDesiredKey; + + // look up 'key' in the map and see if it's a hit, if so, bump the refcount and return + // if not, generate a completed layout based on the key, add to map, set refcount to 1, return that + + const GLMTexFormatDesc *formatDesc = GetFormatDesc( key->m_texFormat ); + + //bool compression = (formatDesc->m_chunkSize > 1) != 0; + if (!formatDesc) + { + GLMStop(); // bad news + } + + if ( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) + { + if ( ( formatDesc->m_glIntFormatSRGB != 0 ) && ( ( key->m_texFlags & kGLMTexSRGB ) == 0 ) ) + { + tempKey = *pDesiredKey; + key = &tempKey; + + // Slam on SRGB texture flag, and we'll use GL_EXT_texture_sRGB_decode to selectively turn it off in the samplers + key->m_texFlags |= kGLMTexSRGB; + } + } + + unsigned short index = m_layoutMap.Find( *key ); + if (index != m_layoutMap.InvalidIndex()) + { + // found it + //printf(" -hit- "); + GLMTexLayout *layout = m_layoutMap[ index ]; + + // bump ref count + layout->m_refCount ++; + + return layout; + } + else + { + //printf(" -miss- "); + // need to make a new one + // to allocate it, we need to know how big to make it (slice count) + + // figure out how many mip levels are in play + int mipCount = 1; + if (key->m_texFlags & kGLMTexMipped) + { + int largestAxis = key->m_xSize; + + if (key->m_ySize > largestAxis) + largestAxis = key->m_ySize; + + if (key->m_zSize > largestAxis) + largestAxis = key->m_zSize; + + mipCount = 0; + while( largestAxis > 0 ) + { + mipCount ++; + largestAxis >>= 1; + } + } + + int faceCount = 1; + if (key->m_texGLTarget == GL_TEXTURE_CUBE_MAP) + { + faceCount = 6; + } + + int sliceCount = mipCount * faceCount; + + if (key->m_texFlags & kGLMTexMultisampled) + { + Assert( (key->m_texGLTarget == GL_TEXTURE_2D) ); + Assert( sliceCount == 1 ); + + // assume non mipped + Assert( (key->m_texFlags & kGLMTexMipped) == 0 ); + Assert( (key->m_texFlags & kGLMTexMippedAuto) == 0 ); + + // assume renderable and srgb + Assert( (key->m_texFlags & kGLMTexRenderable) !=0 ); + //Assert( (key->m_texFlags & kGLMTexSRGB) !=0 ); //FIXME don't assert on making depthstencil surfaces which are non srgb + + // double check sample count (FIXME need real limit check here against device/driver) + Assert( (key->m_texSamples==2) || (key->m_texSamples==4) || (key->m_texSamples==6) || (key->m_texSamples==8) ); + } + + // now we know enough to allocate and populate the new tex layout. + + // malloc the new layout + int layoutSize = sizeof( GLMTexLayout ) + (sliceCount * sizeof( GLMTexLayoutSlice )); + GLMTexLayout *layout = (GLMTexLayout *)malloc( layoutSize ); + memset( layout, 0, layoutSize ); + + // clone the key in there + memset( &layout->m_key, 0x00, sizeof(layout->m_key) ); + layout->m_key = *key; + + // set refcount + layout->m_refCount = 1; + + // save the format desc + layout->m_format = (GLMTexFormatDesc *)formatDesc; + + // we know the mipcount from before + layout->m_mipCount = mipCount; + + // we know the face count too + layout->m_faceCount = faceCount; + + // slice count is the product + layout->m_sliceCount = mipCount * faceCount; + + // we can now fill in the slices. + GLMTexLayoutSlice *slicePtr = &layout->m_slices[0]; + int storageOffset = 0; + + //bool compressed = (formatDesc->m_chunkSize > 1); // true if DXT + + for( int mip = 0; mip < mipCount; mip ++ ) + { + for( int face = 0; face < faceCount; face++ ) + { + // note application of chunk size which is 1 for uncompressed, and 4 for compressed tex (DXT) + // note also that the *dimensions* must scale down to 1 + // but that the *storage* cannot go below 4x4. + // we introduce the "storage sizes" which are clamped, to compute the storage footprint. + + int storage_x,storage_y,storage_z; + + slicePtr->m_xSize = layout->m_key.m_xSize >> mip; + slicePtr->m_xSize = MAX( slicePtr->m_xSize, 1 ); // dimension can't go to zero + storage_x = MAX( slicePtr->m_xSize, formatDesc->m_chunkSize ); // storage extent can't go below chunk size + + slicePtr->m_ySize = layout->m_key.m_ySize >> mip; + slicePtr->m_ySize = MAX( slicePtr->m_ySize, 1 ); // dimension can't go to zero + storage_y = MAX( slicePtr->m_ySize, formatDesc->m_chunkSize ); // storage extent can't go below chunk size + + slicePtr->m_zSize = layout->m_key.m_zSize >> mip; + slicePtr->m_zSize = MAX( slicePtr->m_zSize, 1 ); // dimension can't go to zero + storage_z = MAX( slicePtr->m_zSize, 1); // storage extent for Z cannot go below '1'. + + //if (compressed) NO NO NO do not lie about the dimensionality, just fudge the storage. + //{ + // // round up to multiple of 4 in X and Y axes + // slicePtr->m_xSize = (slicePtr->m_xSize+3) & (~3); + // slicePtr->m_ySize = (slicePtr->m_ySize+3) & (~3); + //} + + int xchunks = (storage_x / formatDesc->m_chunkSize ); + int ychunks = (storage_y / formatDesc->m_chunkSize ); + + slicePtr->m_storageSize = (xchunks * ychunks * formatDesc->m_bytesPerSquareChunk) * storage_z; + slicePtr->m_storageOffset = storageOffset; + + storageOffset += slicePtr->m_storageSize; + storageOffset = ( (storageOffset+0x0F) & (~0x0F)); // keep each MIP starting on a 16 byte boundary. + + slicePtr++; + } + } + + layout->m_storageTotalSize = storageOffset; + //printf("\n size %08x for key (x=%d y=%d z=%d, fmt=%08x, bpsc=%d)", layout->m_storageTotalSize, key->m_xSize, key->m_ySize, key->m_zSize, key->m_texFormat, formatDesc->m_bytesPerSquareChunk ); + + // generate summary + // "target, format, +/- mips, base size" + char scratch[1024]; + + char *targetname = "?"; + switch( key->m_texGLTarget ) + { + case GL_TEXTURE_2D: targetname = "2D "; break; + case GL_TEXTURE_3D: targetname = "3D "; break; + case GL_TEXTURE_CUBE_MAP: targetname = "CUBE"; break; + } + + sprintf( scratch, "[%s %s %dx%dx%d mips=%d slices=%d flags=%02lX%s]", + targetname, + formatDesc->m_formatSummary, + layout->m_key.m_xSize, layout->m_key.m_ySize, layout->m_key.m_zSize, + mipCount, + sliceCount, + layout->m_key.m_texFlags, + (layout->m_key.m_texFlags & kGLMTexSRGB) ? " SRGB" : "" + ); + layout->m_layoutSummary = strdup( scratch ); + //GLMPRINTF(("-D- new tex layout [ %s ]", scratch )); + + // then insert into map. disregard returned index. + m_layoutMap.Insert( layout->m_key, layout ); + + return layout; + } +} + +void CGLMTexLayoutTable::DelLayoutRef( GLMTexLayout *layout ) +{ + // locate layout in hash, drop refcount + // (some GC step later on will harvest expired layouts - not like it's any big challenge to re-generate them) + + unsigned short index = m_layoutMap.Find( layout->m_key ); + if (index != m_layoutMap.InvalidIndex()) + { + // found it + GLMTexLayout *layout = m_layoutMap[ index ]; + + // drop ref count + layout->m_refCount --; + + //assert( layout->m_refCount >= 0 ); + } + else + { + // that's bad + GLMStop(); + } +} + +void CGLMTexLayoutTable::DumpStats( ) +{ + for (uint i=0; im_refCount, layout->m_storageTotalSize, (layout->m_refCount*layout->m_storageTotalSize), layout->m_layoutSummary ); + } +} + +ConVar gl_texmsaalog ( "gl_texmsaalog", "0"); + +ConVar gl_rt_forcergba ( "gl_rt_forcergba", "1" ); // on teximage of a renderable tex, pass GL_RGBA in place of GL_BGRA + +ConVar gl_minimize_rt_tex ( "gl_minimize_rt_tex", "0" ); // if 1, set the GL_TEXTURE_MINIMIZE_STORAGE_APPLE texture parameter to cut off mipmaps for RT's +ConVar gl_minimize_all_tex ( "gl_minimize_all_tex", "1" ); // if 1, set the GL_TEXTURE_MINIMIZE_STORAGE_APPLE texture parameter to cut off mipmaps for textures which are unmipped +ConVar gl_minimize_tex_log ( "gl_minimize_tex_log", "0" ); // if 1, printf the names of the tex that got minimized + +CGLMTex::CGLMTex( GLMContext *ctx, GLMTexLayout *layout, uint levels, const char *debugLabel ) +{ +#if GLMDEBUG + m_pPrevTex = NULL; + m_pNextTex = g_pFirstCGMLTex; + if ( m_pNextTex ) + { + Assert( m_pNextTex->m_pPrevTex == NULL ); + m_pNextTex->m_pPrevTex = this; + } + g_pFirstCGMLTex = this; +#endif + + // caller has responsibility to make 'ctx' current, but we check to be sure. + ctx->CheckCurrent(); + + m_nLastResolvedBatchCounter = ctx->m_nBatchCounter; + + // note layout requested + m_layout = layout; + m_texGLTarget = m_layout->m_key.m_texGLTarget; + + m_nSamplerType = SAMPLER_TYPE_UNUSED; + switch ( m_texGLTarget ) + { + case GL_TEXTURE_CUBE_MAP: m_nSamplerType = SAMPLER_TYPE_CUBE; break; + case GL_TEXTURE_2D: m_nSamplerType = SAMPLER_TYPE_2D; break; + case GL_TEXTURE_3D: m_nSamplerType = SAMPLER_TYPE_3D; break; + default: + Assert( 0 ); + break; + } + + m_maxActiveMip = -1; //index of highest mip that has been written - increase as each mip arrives + m_minActiveMip = 999; //index of lowest mip that has been written - lower it as each mip arrives + + // note context owner + m_ctx = ctx; + + // clear the bind point flags + //m_bindPoints.ClearAll(); + + // clear the RT attach count + m_rtAttachCount = 0; + + // come up with a GL name for this texture. + m_texName = ctx->CreateTex( m_texGLTarget, m_layout->m_format->m_glIntFormat ); + + m_pBlitSrcFBO = NULL; + m_pBlitDstFBO = NULL; + + // Sense whether to try and apply client storage upon teximage/subimage. + // This should only be true if we're running on OSX 10.6 or it was explicitly + // enabled with -gl_texclientstorage on the command line. + m_texClientStorage = ctx->m_bTexClientStorage; + + // flag that we have not yet been explicitly kicked into VRAM.. + m_texPreloaded = false; + + // clone the debug label if there is one. + m_debugLabel = debugLabel ? strdup(debugLabel) : NULL; + + // if tex is MSAA renderable, make an RBO, else zero the RBO name and dirty bit + if (layout->m_key.m_texFlags & kGLMTexMultisampled) + { + gGL->glGenRenderbuffers( 1, &m_rboName ); + + // so we have enough info to go ahead and bind the RBO and put storage on it? + // try it. + gGL->glBindRenderbuffer( GL_RENDERBUFFER, m_rboName ); + + // quietly clamp if sample count exceeds known limit for the device + int sampleCount = layout->m_key.m_texSamples; + + if (sampleCount > ctx->Caps().m_maxSamples) + { + sampleCount = ctx->Caps().m_maxSamples; // clamp + } + + GLenum msaaFormat = (layout->m_key.m_texFlags & kGLMTexSRGB) ? layout->m_format->m_glIntFormatSRGB : layout->m_format->m_glIntFormat; + gGL->glRenderbufferStorageMultisample( GL_RENDERBUFFER, + sampleCount, // not "layout->m_key.m_texSamples" + msaaFormat, + layout->m_key.m_xSize, + layout->m_key.m_ySize ); + + if (gl_texmsaalog.GetInt()) + { + printf( "\n == MSAA Tex %p %s : MSAA RBO is intformat %s (%x)", this, m_debugLabel?m_debugLabel:"", GLMDecode( eGL_ENUM, msaaFormat ), msaaFormat ); + } + + gGL->glBindRenderbuffer( GL_RENDERBUFFER, 0 ); + } + else + { + m_rboName = 0; + } + + // at this point we have the complete description of the texture, and a name for it, but no data and no actual GL object. + // we know this name has bever seen duty before, so we're going to hard-bind it to TMU 0, displacing any other tex that might have been bound there. + // any previously bound tex will be unbound and appropriately marked as a result. + // the active TMU will be set as a side effect. + CGLMTex *pPrevTex = ctx->m_samplers[0].m_pBoundTex; + ctx->BindTexToTMU( this, 0 ); + + m_SamplingParams.SetToDefaults(); + m_SamplingParams.SetToTarget( m_texGLTarget ); + + // OK, our texture now exists and is bound on the active TMU. Not drawable yet though. + + // Create backing storage and fill it + if ( !(layout->m_key.m_texFlags & kGLMTexRenderable) && m_texClientStorage ) + { + m_backing = (char *)malloc( m_layout->m_storageTotalSize ); + memset( m_backing, 0, m_layout->m_storageTotalSize ); + + // track bytes allocated for non-RT's + int formindex = sEncodeLayoutAsIndex( &layout->m_key ); + + g_texGlobalBytes[ formindex ] += m_layout->m_storageTotalSize; + + #if TEXSPACE_LOGGING + printf( "\n Tex %s added %d bytes in form %d which is now %d bytes", m_debugLabel ? m_debugLabel : "-", m_layout->m_storageTotalSize, formindex, g_texGlobalBytes[ formindex ] ); + printf( "\n\t\t[ %d %d %d %d %d %d %d %d ]", + g_texGlobalBytes[ 0 ],g_texGlobalBytes[ 1 ],g_texGlobalBytes[ 2 ],g_texGlobalBytes[ 3 ], + g_texGlobalBytes[ 4 ],g_texGlobalBytes[ 5 ],g_texGlobalBytes[ 6 ],g_texGlobalBytes[ 7 ] + ); + #endif + } + else + { + m_backing = NULL; + + m_texClientStorage = false; + } + + // init lock count + // lock reqs are tracked by the owning context + m_lockCount = 0; + + m_sliceFlags.SetCount( m_layout->m_sliceCount ); + for( int i=0; i< m_layout->m_sliceCount; i++) + { + m_sliceFlags[i] = 0; + // kSliceValid = false (we have not teximaged each slice yet) + // kSliceStorageValid = false (the storage allocated does not reflect what is in the tex) + // kSliceLocked = false (the slices are not locked) + // kSliceFullyDirty = false (this does not come true til first lock) + } + + // texture minimize parameter keeps driver from allocing mips when it should not, by being explicit about the ones that have no mips. + + bool setMinimizeParameter = false; + bool minimize_rt = (gl_minimize_rt_tex.GetInt()!=0); + bool minimize_all = (gl_minimize_all_tex.GetInt()!=0); + + if (layout->m_key.m_texFlags & kGLMTexRenderable) + { + // it's an RT. if mips were not explicitly requested, and "gl_minimize_rt_tex" is true, set the minimize parameter. + if ( (minimize_rt || minimize_all) && ( !(layout->m_key.m_texFlags & kGLMTexMipped) ) ) + { + setMinimizeParameter = true; + } + } + else + { + // not an RT. if mips were not requested, and "gl_minimize_all_tex" is true, set the minimize parameter. + if ( minimize_all && ( !(layout->m_key.m_texFlags & kGLMTexMipped) ) ) + { + setMinimizeParameter = true; + } + } + + if (setMinimizeParameter) + { + if (gl_minimize_tex_log.GetInt()) + { + printf("\n minimizing storage for tex '%s' [%s] ", m_debugLabel?m_debugLabel:"-", m_layout->m_layoutSummary ); + } + } + + // after a lot of pain with texture completeness... + // always push black into all slices of all newly created textures. + + #if 0 + bool pushRenderableSlices = (m_layout->m_key.m_texFlags & kGLMTexRenderable) != 0; + bool pushTexSlices = true; // just do it everywhere (m_layout->m_mipCount>1) && (m_layout->m_format->m_chunkSize !=1) ; + if (pushTexSlices) + { + // fill storage with mostly-opaque purple + + GLMGenTexelParams genp; + memset( &genp, 0, sizeof(genp) ); + + genp.m_format = m_layout->m_format->m_d3dFormat; + const GLMTexFormatDesc *format = GetFormatDesc( genp.m_format ); + + genp.m_dest = m_backing; // dest addr + genp.m_chunkCount = m_layout->m_storageTotalSize / format->m_bytesPerSquareChunk; // fill the whole slab + genp.m_byteCountLimit = m_layout->m_storageTotalSize; // limit writes to this amount + + genp.r = 1.0; + genp.g = 0.0; + genp.b = 1.0; + genp.a = 0.75; + + GLMGenTexels( &genp ); + } + #endif + + //if (pushRenderableSlices || pushTexSlices) + if ( !( ( layout->m_key.m_texFlags & kGLMTexMipped ) && ( levels == ( unsigned ) m_layout->m_mipCount ) ) ) + { + for( int face=0; face m_faceCount; face++) + { + for( int mip=0; mip m_mipCount; mip++) + { + // we're not really going to lock, we're just going to write the blank data from the backing store we just made + GLMTexLockDesc desc; + + desc.m_req.m_tex = this; + desc.m_req.m_face = face; + desc.m_req.m_mip = mip; + + desc.m_sliceIndex = CalcSliceIndex( face, mip ); + + GLMTexLayoutSlice *slice = &m_layout->m_slices[ desc.m_sliceIndex ]; + + desc.m_req.m_region.xmin = desc.m_req.m_region.ymin = desc.m_req.m_region.zmin = 0; + desc.m_req.m_region.xmax = slice->m_xSize; + desc.m_req.m_region.ymax = slice->m_ySize; + desc.m_req.m_region.zmax = slice->m_zSize; + + desc.m_sliceBaseOffset = slice->m_storageOffset; // doesn't really matter... we're just pushing zeroes.. + desc.m_sliceRegionOffset = 0; + + WriteTexels( &desc, true, (layout->m_key.m_texFlags & kGLMTexRenderable)!=0 ); // write whole slice - but disable data source if it's an RT, as there's no backing + } + } + } + GLMPRINTF(("-A- -**TEXNEW '%-60s' name=%06d size=%09d storage=%08x label=%s ", m_layout->m_layoutSummary, m_texName, m_layout->m_storageTotalSize, m_backing, m_debugLabel ? m_debugLabel : "-" )); + + ctx->BindTexToTMU( pPrevTex, 0 ); +} + +CGLMTex::~CGLMTex( ) +{ +#if GLMDEBUG + if ( m_pPrevTex ) + { + Assert( m_pPrevTex->m_pNextTex == this ); + m_pPrevTex->m_pNextTex = m_pNextTex; + } + else + { + Assert( g_pFirstCGMLTex == this ); + g_pFirstCGMLTex = m_pNextTex; + } + if ( m_pNextTex ) + { + Assert( m_pNextTex->m_pPrevTex == this ); + m_pNextTex->m_pPrevTex = m_pPrevTex; + } + m_pNextTex = m_pPrevTex = NULL; +#endif + + if ( !(m_layout->m_key.m_texFlags & kGLMTexRenderable) ) + { + int formindex = sEncodeLayoutAsIndex( &m_layout->m_key ); + + g_texGlobalBytes[ formindex ] -= m_layout->m_storageTotalSize; + + #if TEXSPACE_LOGGING + printf( "\n Tex %s freed %d bytes in form %d which is now %d bytes", m_debugLabel ? m_debugLabel : "-", m_layout->m_storageTotalSize, formindex, g_texGlobalBytes[ formindex ] ); + printf( "\n\t\t[ %d %d %d %d %d %d %d %d ]", + g_texGlobalBytes[ 0 ],g_texGlobalBytes[ 1 ],g_texGlobalBytes[ 2 ],g_texGlobalBytes[ 3 ], + g_texGlobalBytes[ 4 ],g_texGlobalBytes[ 5 ],g_texGlobalBytes[ 6 ],g_texGlobalBytes[ 7 ] + ); + #endif + } + + GLMPRINTF(("-A- -**TEXDEL '%-60s' name=%06d size=%09d storage=%08x label=%s ", m_layout->m_layoutSummary, m_texName, m_layout->m_storageTotalSize, m_backing, m_debugLabel ? m_debugLabel : "-" )); + // check first to see if we were still bound anywhere or locked... these should be failures. + + if ( m_pBlitSrcFBO ) + { + m_ctx->DelFBO( m_pBlitSrcFBO ); + m_pBlitSrcFBO = NULL; + } + + if ( m_pBlitDstFBO ) + { + m_ctx->DelFBO( m_pBlitDstFBO ); + m_pBlitDstFBO = NULL; + } + + if ( m_rboName ) + { + gGL->glDeleteRenderbuffers( 1, &m_rboName ); + m_rboName = 0; + } + + // if all that is OK, then delete the underlying tex + if ( m_texName ) + { + m_ctx->DestroyTex( m_texGLTarget, m_layout, m_texName ); + m_texName = 0; + } + + // release our usage of the layout + m_ctx->m_texLayoutTable->DelLayoutRef( m_layout ); + m_layout = NULL; + + if (m_backing) + { + free( m_backing ); + m_backing = NULL; + } + + if (m_debugLabel) + { + free( m_debugLabel ); + m_debugLabel = NULL; + } + + m_ctx = NULL; +} + +int CGLMTex::CalcSliceIndex( int face, int mip ) +{ + // faces of the same mip level are adjacent. "face major" storage + int index = (mip * m_layout->m_faceCount) + face; + + return index; +} + +void CGLMTex::CalcTexelDataOffsetAndStrides( int sliceIndex, int x, int y, int z, int *offsetOut, int *yStrideOut, int *zStrideOut ) +{ + int offset = 0; + int yStride = 0; + int zStride = 0; + + GLMTexFormatDesc *format = m_layout->m_format; + if (format->m_chunkSize==1) + { + // figure out row stride and layer stride + yStride = format->m_bytesPerSquareChunk * m_layout->m_slices[sliceIndex].m_xSize; // bytes per texel row (y stride) + zStride = yStride * m_layout->m_slices[sliceIndex].m_ySize; // bytes per texel layer (if 3D tex) + + offset = x * format->m_bytesPerSquareChunk; // lateral offset + offset += (y * yStride); // scanline offset + offset += (z * zStride); // should be zero for 2D tex + } + else + { + yStride = format->m_bytesPerSquareChunk * (m_layout->m_slices[sliceIndex].m_xSize / format->m_chunkSize); + zStride = yStride * (m_layout->m_slices[sliceIndex].m_ySize / format->m_chunkSize); + + // compressed format. scale the x,y,z values into chunks. + // assert if any of them are not multiples of a chunk. + int chunkx = x / format->m_chunkSize; + int chunky = y / format->m_chunkSize; + int chunkz = z / format->m_chunkSize; + + if ( (chunkx * format->m_chunkSize) != x) + { + GLMStop(); + } + + if ( (chunky * format->m_chunkSize) != y) + { + GLMStop(); + } + + if ( (chunkz * format->m_chunkSize) != z) + { + GLMStop(); + } + + offset = chunkx * format->m_bytesPerSquareChunk; // lateral offset + offset += (chunky * yStride); // chunk row offset + offset += (chunkz * zStride); // should be zero for 2D tex + } + + *offsetOut = offset; + *yStrideOut = yStride; + *zStrideOut = zStride; +} + +extern void convert_texture( GLint &internalformat, GLsizei width, GLsizei height, GLenum &format, GLenum &type, void *data ); + +void CGLMTex::ReadTexels( GLMTexLockDesc *desc, bool readWholeSlice ) +{ + GLMRegion readBox; + + if (readWholeSlice) + { + readBox.xmin = readBox.ymin = readBox.zmin = 0; + + readBox.xmax = m_layout->m_slices[ desc->m_sliceIndex ].m_xSize; + readBox.ymax = m_layout->m_slices[ desc->m_sliceIndex ].m_ySize; + readBox.zmax = m_layout->m_slices[ desc->m_sliceIndex ].m_zSize; + } + else + { + readBox = desc->m_req.m_region; + } + + CGLMTex *pPrevTex = m_ctx->m_samplers[0].m_pBoundTex; + m_ctx->BindTexToTMU( this, 0 ); // SelectTMU(n) is a side effect + + if (readWholeSlice) + { + // make this work first.... then write the partial path + // (Hmmmm, I don't think we will ever actually need a partial path - + // since we have no notion of a partially valid slice of storage + + GLMTexFormatDesc *format = m_layout->m_format; + GLenum target = m_layout->m_key.m_texGLTarget; + + void *sliceAddress = m_backing + m_layout->m_slices[ desc->m_sliceIndex ].m_storageOffset; // this would change for PBO + //int sliceSize = m_layout->m_slices[ desc->m_sliceIndex ].m_storageSize; + + // interestingly enough, we can use the same path for both 2D and 3D fetch + + + switch( target ) + { + case GL_TEXTURE_CUBE_MAP: + + // adjust target to steer to the proper face, then fall through to the 2D texture path. + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc->m_req.m_face; + + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + { + // check compressed or not + if (format->m_chunkSize != 1) + { + // compressed path + // http://www.opengl.org/sdk/docs/man/xhtml/glGetCompressedTexImage.xml + // TODO(nillerusr): implement me! +/* + gGL->glGetCompressedTexImage( target, // target + desc->m_req.m_mip, // level + sliceAddress ); // destination +*/ + } + else + { + // uncompressed path + // http://www.opengl.org/sdk/docs/man/xhtml/glGetTexImage.xml + GLuint fbo; + GLint Rfbo = 0, Dfbo = 0; + + gGL->glGetIntegerv( GL_DRAW_FRAMEBUFFER_BINDING, &Dfbo ); + gGL->glGetIntegerv( GL_READ_FRAMEBUFFER_BINDING, &Rfbo ); + + gGL->glGenFramebuffers(1, &fbo); + gGL->glBindFramebuffer(GL_FRAMEBUFFER, fbo); + gGL->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_ctx->m_samplers[0].m_pBoundTex->m_texName, 0); + + GLenum fmt = format->m_glDataFormat; + if( fmt == GL_BGR ) + fmt = GL_RGB; + else if( fmt == GL_BGRA ) + fmt = GL_RGBA; + + gGL->glReadPixels(0, 0, m_layout->m_slices[ desc->m_sliceIndex ].m_xSize, m_layout->m_slices[ desc->m_sliceIndex ].m_ySize, fmt, format->m_glDataType == GL_UNSIGNED_INT_8_8_8_8_REV ? GL_UNSIGNED_BYTE : format->m_glDataType, sliceAddress); + GLint intformat = format->m_glDataFormat; + GLenum _format = format->m_glDataFormat; + GLenum _type = format->m_glDataType; + + // TODO(nillerusr): Don't convert, should change m_format to another one + convert_texture(intformat, m_layout->m_slices[ desc->m_sliceIndex ].m_xSize, m_layout->m_slices[ desc->m_sliceIndex ].m_ySize, _format, _type, sliceAddress); + + gGL->glBindFramebuffer(GL_READ_FRAMEBUFFER, Rfbo); + gGL->glBindFramebuffer(GL_DRAW_FRAMEBUFFER, Dfbo); + + gGL->glDeleteFramebuffers(1, &fbo); + } + } + break; + } + } + else + { + GLMStop(); + } + + m_ctx->BindTexToTMU( pPrevTex, 0 ); +} + +struct mem_s +{ + const int value; + const char *str; +} g_glEnums[] = +{ +{ 0x0000, "GL_ZERO" }, +{ 0x0001, "GL_ONE" }, +{ 0x0004, "GL_TRIANGLES" }, +{ 0x0005, "GL_TRIANGLE_STRIP" }, +{ 0x0006, "GL_TRIANGLE_FAN" }, +{ 0x0007, "GL_QUADS" }, +{ 0x0008, "GL_QUAD_STRIP" }, +{ 0x0009, "GL_POLYGON" }, +{ 0x0200, "GL_NEVER" }, +{ 0x0201, "GL_LESS" }, +{ 0x0202, "GL_EQUAL" }, +{ 0x0203, "GL_LEQUAL" }, +{ 0x0204, "GL_GREATER" }, +{ 0x0205, "GL_NOTEQUAL" }, +{ 0x0206, "GL_GEQUAL" }, +{ 0x0207, "GL_ALWAYS" }, +{ 0x0300, "GL_SRC_COLOR" }, +{ 0x0301, "GL_ONE_MINUS_SRC_COLOR" }, +{ 0x0302, "GL_SRC_ALPHA" }, +{ 0x0303, "GL_ONE_MINUS_SRC_ALPHA" }, +{ 0x0304, "GL_DST_ALPHA" }, +{ 0x0305, "GL_ONE_MINUS_DST_ALPHA" }, +{ 0x0306, "GL_DST_COLOR" }, +{ 0x0307, "GL_ONE_MINUS_DST_COLOR" }, +{ 0x0308, "GL_SRC_ALPHA_SATURATE" }, +{ 0x0400, "GL_FRONT_LEFT" }, +{ 0x0401, "GL_FRONT_RIGHT" }, +{ 0x0402, "GL_BACK_LEFT" }, +{ 0x0403, "GL_BACK_RIGHT" }, +{ 0x0404, "GL_FRONT" }, +{ 0x0405, "GL_BACK" }, +{ 0x0406, "GL_LEFT" }, +{ 0x0407, "GL_RIGHT" }, +{ 0x0408, "GL_FRONT_AND_BACK" }, +{ 0x0409, "GL_AUX0" }, +{ 0x040A, "GL_AUX1" }, +{ 0x040B, "GL_AUX2" }, +{ 0x040C, "GL_AUX3" }, +{ 0x0500, "GL_INVALID_ENUM" }, +{ 0x0501, "GL_INVALID_VALUE" }, +{ 0x0502, "GL_INVALID_OPERATION" }, +{ 0x0503, "GL_STACK_OVERFLOW" }, +{ 0x0504, "GL_STACK_UNDERFLOW" }, +{ 0x0505, "GL_OUT_OF_MEMORY" }, +{ 0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION" }, +{ 0x0600, "GL_2D" }, +{ 0x0601, "GL_3D" }, +{ 0x0602, "GL_3D_COLOR" }, +{ 0x0603, "GL_3D_COLOR_TEXTURE" }, +{ 0x0604, "GL_4D_COLOR_TEXTURE" }, +{ 0x0700, "GL_PASS_THROUGH_TOKEN" }, +{ 0x0701, "GL_POINT_TOKEN" }, +{ 0x0702, "GL_LINE_TOKEN" }, +{ 0x0703, "GL_POLYGON_TOKEN" }, +{ 0x0704, "GL_BITMAP_TOKEN" }, +{ 0x0705, "GL_DRAW_PIXEL_TOKEN" }, +{ 0x0706, "GL_COPY_PIXEL_TOKEN" }, +{ 0x0707, "GL_LINE_RESET_TOKEN" }, +{ 0x0800, "GL_EXP" }, +{ 0x0801, "GL_EXP2" }, +{ 0x0900, "GL_CW" }, +{ 0x0901, "GL_CCW" }, +{ 0x0A00, "GL_COEFF" }, +{ 0x0A01, "GL_ORDER" }, +{ 0x0A02, "GL_DOMAIN" }, +{ 0x0B00, "GL_CURRENT_COLOR" }, +{ 0x0B01, "GL_CURRENT_INDEX" }, +{ 0x0B02, "GL_CURRENT_NORMAL" }, +{ 0x0B03, "GL_CURRENT_TEXTURE_COORDS" }, +{ 0x0B04, "GL_CURRENT_RASTER_COLOR" }, +{ 0x0B05, "GL_CURRENT_RASTER_INDEX" }, +{ 0x0B06, "GL_CURRENT_RASTER_TEXTURE_COORDS" }, +{ 0x0B07, "GL_CURRENT_RASTER_POSITION" }, +{ 0x0B08, "GL_CURRENT_RASTER_POSITION_VALID" }, +{ 0x0B09, "GL_CURRENT_RASTER_DISTANCE" }, +{ 0x0B10, "GL_POINT_SMOOTH" }, +{ 0x0B11, "GL_POINT_SIZE" }, +{ 0x0B12, "GL_POINT_SIZE_RANGE" }, +{ 0x0B12, "GL_SMOOTH_POINT_SIZE_RANGE" }, +{ 0x0B13, "GL_POINT_SIZE_GRANULARITY" }, +{ 0x0B13, "GL_SMOOTH_POINT_SIZE_GRANULARITY" }, +{ 0x0B20, "GL_LINE_SMOOTH" }, +{ 0x0B21, "GL_LINE_WIDTH" }, +{ 0x0B22, "GL_LINE_WIDTH_RANGE" }, +{ 0x0B22, "GL_SMOOTH_LINE_WIDTH_RANGE" }, +{ 0x0B23, "GL_LINE_WIDTH_GRANULARITY" }, +{ 0x0B23, "GL_SMOOTH_LINE_WIDTH_GRANULARITY" }, +{ 0x0B24, "GL_LINE_STIPPLE" }, +{ 0x0B25, "GL_LINE_STIPPLE_PATTERN" }, +{ 0x0B26, "GL_LINE_STIPPLE_REPEAT" }, +{ 0x0B30, "GL_LIST_MODE" }, +{ 0x0B31, "GL_MAX_LIST_NESTING" }, +{ 0x0B32, "GL_LIST_BASE" }, +{ 0x0B33, "GL_LIST_INDEX" }, +{ 0x0B40, "GL_POLYGON_MODE" }, +{ 0x0B41, "GL_POLYGON_SMOOTH" }, +{ 0x0B42, "GL_POLYGON_STIPPLE" }, +{ 0x0B43, "GL_EDGE_FLAG" }, +{ 0x0B44, "GL_CULL_FACE" }, +{ 0x0B45, "GL_CULL_FACE_MODE" }, +{ 0x0B46, "GL_FRONT_FACE" }, +{ 0x0B50, "GL_LIGHTING" }, +{ 0x0B51, "GL_LIGHT_MODEL_LOCAL_VIEWER" }, +{ 0x0B52, "GL_LIGHT_MODEL_TWO_SIDE" }, +{ 0x0B53, "GL_LIGHT_MODEL_AMBIENT" }, +{ 0x0B54, "GL_SHADE_MODEL" }, +{ 0x0B55, "GL_COLOR_MATERIAL_FACE" }, +{ 0x0B56, "GL_COLOR_MATERIAL_PARAMETER" }, +{ 0x0B57, "GL_COLOR_MATERIAL" }, +{ 0x0B60, "GL_FOG" }, +{ 0x0B61, "GL_FOG_INDEX" }, +{ 0x0B62, "GL_FOG_DENSITY" }, +{ 0x0B63, "GL_FOG_START" }, +{ 0x0B64, "GL_FOG_END" }, +{ 0x0B65, "GL_FOG_MODE" }, +{ 0x0B66, "GL_FOG_COLOR" }, +{ 0x0B70, "GL_DEPTH_RANGE" }, +{ 0x0B71, "GL_DEPTH_TEST" }, +{ 0x0B72, "GL_DEPTH_WRITEMASK" }, +{ 0x0B73, "GL_DEPTH_CLEAR_VALUE" }, +{ 0x0B74, "GL_DEPTH_FUNC" }, +{ 0x0B80, "GL_ACCUM_CLEAR_VALUE" }, +{ 0x0B90, "GL_STENCIL_TEST" }, +{ 0x0B91, "GL_STENCIL_CLEAR_VALUE" }, +{ 0x0B92, "GL_STENCIL_FUNC" }, +{ 0x0B93, "GL_STENCIL_VALUE_MASK" }, +{ 0x0B94, "GL_STENCIL_FAIL" }, +{ 0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL" }, +{ 0x0B96, "GL_STENCIL_PASS_DEPTH_PASS" }, +{ 0x0B97, "GL_STENCIL_REF" }, +{ 0x0B98, "GL_STENCIL_WRITEMASK" }, +{ 0x0BA0, "GL_MATRIX_MODE" }, +{ 0x0BA1, "GL_NORMALIZE" }, +{ 0x0BA2, "GL_VIEWPORT" }, +{ 0x0BA3, "GL_MODELVIEW_STACK_DEPTH" }, +{ 0x0BA4, "GL_PROJECTION_STACK_DEPTH" }, +{ 0x0BA5, "GL_TEXTURE_STACK_DEPTH" }, +{ 0x0BA6, "GL_MODELVIEW_MATRIX" }, +{ 0x0BA7, "GL_PROJECTION_MATRIX" }, +{ 0x0BA8, "GL_TEXTURE_MATRIX" }, +{ 0x0BB0, "GL_ATTRIB_STACK_DEPTH" }, +{ 0x0BB1, "GL_CLIENT_ATTRIB_STACK_DEPTH" }, +{ 0x0BC0, "GL_ALPHA_TEST" }, +{ 0x0BC1, "GL_ALPHA_TEST_FUNC" }, +{ 0x0BC2, "GL_ALPHA_TEST_REF" }, +{ 0x0BD0, "GL_DITHER" }, +{ 0x0BE0, "GL_BLEND_DST" }, +{ 0x0BE1, "GL_BLEND_SRC" }, +{ 0x0BE2, "GL_BLEND" }, +{ 0x0BF0, "GL_LOGIC_OP_MODE" }, +{ 0x0BF1, "GL_INDEX_LOGIC_OP" }, +{ 0x0BF2, "GL_COLOR_LOGIC_OP" }, +{ 0x0C00, "GL_AUX_BUFFERS" }, +{ 0x0C01, "GL_DRAW_BUFFER" }, +{ 0x0C02, "GL_READ_BUFFER" }, +{ 0x0C10, "GL_SCISSOR_BOX" }, +{ 0x0C11, "GL_SCISSOR_TEST" }, +{ 0x0C20, "GL_INDEX_CLEAR_VALUE" }, +{ 0x0C21, "GL_INDEX_WRITEMASK" }, +{ 0x0C22, "GL_COLOR_CLEAR_VALUE" }, +{ 0x0C23, "GL_COLOR_WRITEMASK" }, +{ 0x0C30, "GL_INDEX_MODE" }, +{ 0x0C31, "GL_RGBA_MODE" }, +{ 0x0C32, "GL_DOUBLEBUFFER" }, +{ 0x0C33, "GL_STEREO" }, +{ 0x0C40, "GL_RENDER_MODE" }, +{ 0x0C50, "GL_PERSPECTIVE_CORRECTION_HINT" }, +{ 0x0C51, "GL_POINT_SMOOTH_HINT" }, +{ 0x0C52, "GL_LINE_SMOOTH_HINT" }, +{ 0x0C53, "GL_POLYGON_SMOOTH_HINT" }, +{ 0x0C54, "GL_FOG_HINT" }, +{ 0x0C60, "GL_TEXTURE_GEN_S" }, +{ 0x0C61, "GL_TEXTURE_GEN_T" }, +{ 0x0C62, "GL_TEXTURE_GEN_R" }, +{ 0x0C63, "GL_TEXTURE_GEN_Q" }, +{ 0x0C70, "GL_PIXEL_MAP_I_TO_I" }, +{ 0x0C71, "GL_PIXEL_MAP_S_TO_S" }, +{ 0x0C72, "GL_PIXEL_MAP_I_TO_R" }, +{ 0x0C73, "GL_PIXEL_MAP_I_TO_G" }, +{ 0x0C74, "GL_PIXEL_MAP_I_TO_B" }, +{ 0x0C75, "GL_PIXEL_MAP_I_TO_A" }, +{ 0x0C76, "GL_PIXEL_MAP_R_TO_R" }, +{ 0x0C77, "GL_PIXEL_MAP_G_TO_G" }, +{ 0x0C78, "GL_PIXEL_MAP_B_TO_B" }, +{ 0x0C79, "GL_PIXEL_MAP_A_TO_A" }, +{ 0x0CB0, "GL_PIXEL_MAP_I_TO_I_SIZE" }, +{ 0x0CB1, "GL_PIXEL_MAP_S_TO_S_SIZE" }, +{ 0x0CB2, "GL_PIXEL_MAP_I_TO_R_SIZE" }, +{ 0x0CB3, "GL_PIXEL_MAP_I_TO_G_SIZE" }, +{ 0x0CB4, "GL_PIXEL_MAP_I_TO_B_SIZE" }, +{ 0x0CB5, "GL_PIXEL_MAP_I_TO_A_SIZE" }, +{ 0x0CB6, "GL_PIXEL_MAP_R_TO_R_SIZE" }, +{ 0x0CB7, "GL_PIXEL_MAP_G_TO_G_SIZE" }, +{ 0x0CB8, "GL_PIXEL_MAP_B_TO_B_SIZE" }, +{ 0x0CB9, "GL_PIXEL_MAP_A_TO_A_SIZE" }, +{ 0x0CF0, "GL_UNPACK_SWAP_BYTES" }, +{ 0x0CF1, "GL_UNPACK_LSB_FIRST" }, +{ 0x0CF2, "GL_UNPACK_ROW_LENGTH" }, +{ 0x0CF3, "GL_UNPACK_SKIP_ROWS" }, +{ 0x0CF4, "GL_UNPACK_SKIP_PIXELS" }, +{ 0x0CF5, "GL_UNPACK_ALIGNMENT" }, +{ 0x0D00, "GL_PACK_SWAP_BYTES" }, +{ 0x0D01, "GL_PACK_LSB_FIRST" }, +{ 0x0D02, "GL_PACK_ROW_LENGTH" }, +{ 0x0D03, "GL_PACK_SKIP_ROWS" }, +{ 0x0D04, "GL_PACK_SKIP_PIXELS" }, +{ 0x0D05, "GL_PACK_ALIGNMENT" }, +{ 0x0D10, "GL_MAP_COLOR" }, +{ 0x0D11, "GL_MAP_STENCIL" }, +{ 0x0D12, "GL_INDEX_SHIFT" }, +{ 0x0D13, "GL_INDEX_OFFSET" }, +{ 0x0D14, "GL_RED_SCALE" }, +{ 0x0D15, "GL_RED_BIAS" }, +{ 0x0D16, "GL_ZOOM_X" }, +{ 0x0D17, "GL_ZOOM_Y" }, +{ 0x0D18, "GL_GREEN_SCALE" }, +{ 0x0D19, "GL_GREEN_BIAS" }, +{ 0x0D1A, "GL_BLUE_SCALE" }, +{ 0x0D1B, "GL_BLUE_BIAS" }, +{ 0x0D1C, "GL_ALPHA_SCALE" }, +{ 0x0D1D, "GL_ALPHA_BIAS" }, +{ 0x0D1E, "GL_DEPTH_SCALE" }, +{ 0x0D1F, "GL_DEPTH_BIAS" }, +{ 0x0D30, "GL_MAX_EVAL_ORDER" }, +{ 0x0D31, "GL_MAX_LIGHTS" }, +{ 0x0D32, "GL_MAX_CLIP_PLANES" }, +{ 0x0D33, "GL_MAX_TEXTURE_SIZE" }, +{ 0x0D34, "GL_MAX_PIXEL_MAP_TABLE" }, +{ 0x0D35, "GL_MAX_ATTRIB_STACK_DEPTH" }, +{ 0x0D36, "GL_MAX_MODELVIEW_STACK_DEPTH" }, +{ 0x0D37, "GL_MAX_NAME_STACK_DEPTH" }, +{ 0x0D38, "GL_MAX_PROJECTION_STACK_DEPTH" }, +{ 0x0D39, "GL_MAX_TEXTURE_STACK_DEPTH" }, +{ 0x0D3A, "GL_MAX_VIEWPORT_DIMS" }, +{ 0x0D3B, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH" }, +{ 0x0D50, "GL_SUBPIXEL_BITS" }, +{ 0x0D51, "GL_INDEX_BITS" }, +{ 0x0D52, "GL_RED_BITS" }, +{ 0x0D53, "GL_GREEN_BITS" }, +{ 0x0D54, "GL_BLUE_BITS" }, +{ 0x0D55, "GL_ALPHA_BITS" }, +{ 0x0D56, "GL_DEPTH_BITS" }, +{ 0x0D57, "GL_STENCIL_BITS" }, +{ 0x0D58, "GL_ACCUM_RED_BITS" }, +{ 0x0D59, "GL_ACCUM_GREEN_BITS" }, +{ 0x0D5A, "GL_ACCUM_BLUE_BITS" }, +{ 0x0D5B, "GL_ACCUM_ALPHA_BITS" }, +{ 0x0D70, "GL_NAME_STACK_DEPTH" }, +{ 0x0D80, "GL_AUTO_NORMAL" }, +{ 0x0D90, "GL_MAP1_COLOR_4" }, +{ 0x0D91, "GL_MAP1_INDEX" }, +{ 0x0D92, "GL_MAP1_NORMAL" }, +{ 0x0D93, "GL_MAP1_TEXTURE_COORD_1" }, +{ 0x0D94, "GL_MAP1_TEXTURE_COORD_2" }, +{ 0x0D95, "GL_MAP1_TEXTURE_COORD_3" }, +{ 0x0D96, "GL_MAP1_TEXTURE_COORD_4" }, +{ 0x0D97, "GL_MAP1_VERTEX_3" }, +{ 0x0D98, "GL_MAP1_VERTEX_4" }, +{ 0x0DB0, "GL_MAP2_COLOR_4" }, +{ 0x0DB1, "GL_MAP2_INDEX" }, +{ 0x0DB2, "GL_MAP2_NORMAL" }, +{ 0x0DB3, "GL_MAP2_TEXTURE_COORD_1" }, +{ 0x0DB4, "GL_MAP2_TEXTURE_COORD_2" }, +{ 0x0DB5, "GL_MAP2_TEXTURE_COORD_3" }, +{ 0x0DB6, "GL_MAP2_TEXTURE_COORD_4" }, +{ 0x0DB7, "GL_MAP2_VERTEX_3" }, +{ 0x0DB8, "GL_MAP2_VERTEX_4" }, +{ 0x0DD0, "GL_MAP1_GRID_DOMAIN" }, +{ 0x0DD1, "GL_MAP1_GRID_SEGMENTS" }, +{ 0x0DD2, "GL_MAP2_GRID_DOMAIN" }, +{ 0x0DD3, "GL_MAP2_GRID_SEGMENTS" }, +{ 0x0DE0, "GL_TEXTURE_1D" }, +{ 0x0DE1, "GL_TEXTURE_2D" }, +{ 0x0DF0, "GL_FEEDBACK_BUFFER_POINTER" }, +{ 0x0DF1, "GL_FEEDBACK_BUFFER_SIZE" }, +{ 0x0DF2, "GL_FEEDBACK_BUFFER_TYPE" }, +{ 0x0DF3, "GL_SELECTION_BUFFER_POINTER" }, +{ 0x0DF4, "GL_SELECTION_BUFFER_SIZE" }, +{ 0x1000, "GL_TEXTURE_WIDTH" }, +{ 0x1001, "GL_TEXTURE_HEIGHT" }, +{ 0x1003, "GL_TEXTURE_INTERNAL_FORMAT" }, +{ 0x1004, "GL_TEXTURE_BORDER_COLOR" }, +{ 0x1005, "GL_TEXTURE_BORDER" }, +{ 0x1100, "GL_DONT_CARE" }, +{ 0x1101, "GL_FASTEST" }, +{ 0x1102, "GL_NICEST" }, +{ 0x1200, "GL_AMBIENT" }, +{ 0x1201, "GL_DIFFUSE" }, +{ 0x1202, "GL_SPECULAR" }, +{ 0x1203, "GL_POSITION" }, +{ 0x1204, "GL_SPOT_DIRECTION" }, +{ 0x1205, "GL_SPOT_EXPONENT" }, +{ 0x1206, "GL_SPOT_CUTOFF" }, +{ 0x1207, "GL_CONSTANT_ATTENUATION" }, +{ 0x1208, "GL_LINEAR_ATTENUATION" }, +{ 0x1209, "GL_QUADRATIC_ATTENUATION" }, +{ 0x1300, "GL_COMPILE" }, +{ 0x1301, "GL_COMPILE_AND_EXECUTE" }, +{ 0x1400, "GL_BYTE " }, +{ 0x1401, "GL_UBYTE" }, +{ 0x1402, "GL_SHORT" }, +{ 0x1403, "GL_USHRT" }, +{ 0x1404, "GL_INT " }, +{ 0x1405, "GL_UINT " }, +{ 0x1406, "GL_FLOAT" }, +{ 0x1407, "GL_2_BYTES" }, +{ 0x1408, "GL_3_BYTES" }, +{ 0x1409, "GL_4_BYTES" }, +{ 0x140A, "GL_DOUBLE" }, +{ 0x140B, "GL_HALF_FLOAT" }, +{ 0x1500, "GL_CLEAR" }, +{ 0x1501, "GL_AND" }, +{ 0x1502, "GL_AND_REVERSE" }, +{ 0x1503, "GL_COPY" }, +{ 0x1504, "GL_AND_INVERTED" }, +{ 0x1505, "GL_NOOP" }, +{ 0x1506, "GL_XOR" }, +{ 0x1507, "GL_OR" }, +{ 0x1508, "GL_NOR" }, +{ 0x1509, "GL_EQUIV" }, +{ 0x150A, "GL_INVERT" }, +{ 0x150B, "GL_OR_REVERSE" }, +{ 0x150C, "GL_COPY_INVERTED" }, +{ 0x150D, "GL_OR_INVERTED" }, +{ 0x150E, "GL_NAND" }, +{ 0x150F, "GL_SET" }, +{ 0x1600, "GL_EMISSION" }, +{ 0x1601, "GL_SHININESS" }, +{ 0x1602, "GL_AMBIENT_AND_DIFFUSE" }, +{ 0x1603, "GL_COLOR_INDEXES" }, +{ 0x1700, "GL_MODELVIEW" }, +{ 0x1700, "GL_MODELVIEW0_ARB" }, +{ 0x1701, "GL_PROJECTION" }, +{ 0x1702, "GL_TEXTURE" }, +{ 0x1800, "GL_COLOR" }, +{ 0x1801, "GL_DEPTH" }, +{ 0x1802, "GL_STENCIL" }, +{ 0x1900, "GL_COLOR_INDEX" }, +{ 0x1901, "GL_STENCIL_INDEX" }, +{ 0x1902, "GL_DEPTH_COMPONENT" }, +{ 0x1903, "GL_RED" }, +{ 0x1904, "GL_GREEN" }, +{ 0x1905, "GL_BLUE" }, +{ 0x1906, "GL_ALPHA" }, +{ 0x1907, "GL_RGB" }, +{ 0x1908, "GL_RGBA" }, +{ 0x1909, "GL_LUMINANCE" }, +{ 0x190A, "GL_LUMINANCE_ALPHA" }, +{ 0x1A00, "GL_BITMAP" }, +{ 0x1B00, "GL_POINT" }, +{ 0x1B01, "GL_LINE" }, +{ 0x1B02, "GL_FILL" }, +{ 0x1C00, "GL_RENDER" }, +{ 0x1C01, "GL_FEEDBACK" }, +{ 0x1C02, "GL_SELECT" }, +{ 0x1D00, "GL_FLAT" }, +{ 0x1D01, "GL_SMOOTH" }, +{ 0x1E00, "GL_KEEP" }, +{ 0x1E01, "GL_REPLACE" }, +{ 0x1E02, "GL_INCR" }, +{ 0x1E03, "GL_DECR" }, +{ 0x1F00, "GL_VENDOR" }, +{ 0x1F01, "GL_RENDERER" }, +{ 0x1F02, "GL_VERSION" }, +{ 0x1F03, "GL_EXTENSIONS" }, +{ 0x2000, "GL_S" }, +{ 0x2001, "GL_T" }, +{ 0x2002, "GL_R" }, +{ 0x2003, "GL_Q" }, +{ 0x2100, "GL_MODULATE" }, +{ 0x2101, "GL_DECAL" }, +{ 0x2200, "GL_TEXTURE_ENV_MODE" }, +{ 0x2201, "GL_TEXTURE_ENV_COLOR" }, +{ 0x2300, "GL_TEXTURE_ENV" }, +{ 0x2400, "GL_EYE_LINEAR" }, +{ 0x2401, "GL_OBJECT_LINEAR" }, +{ 0x2402, "GL_SPHERE_MAP" }, +{ 0x2500, "GL_TEXTURE_GEN_MODE" }, +{ 0x2501, "GL_OBJECT_PLANE" }, +{ 0x2502, "GL_EYE_PLANE" }, +{ 0x2600, "GL_NEAREST" }, +{ 0x2601, "GL_LINEAR" }, +{ 0x2700, "GL_NEAREST_MIPMAP_NEAREST" }, +{ 0x2701, "GL_LINEAR_MIPMAP_NEAREST" }, +{ 0x2702, "GL_NEAREST_MIPMAP_LINEAR" }, +{ 0x2703, "GL_LINEAR_MIPMAP_LINEAR" }, +{ 0x2800, "GL_TEXTURE_MAG_FILTER" }, +{ 0x2801, "GL_TEXTURE_MIN_FILTER" }, +{ 0x2802, "GL_TEXTURE_WRAP_S" }, +{ 0x2803, "GL_TEXTURE_WRAP_T" }, +{ 0x2900, "GL_CLAMP" }, +{ 0x2901, "GL_REPEAT" }, +{ 0x2A00, "GL_POLYGON_OFFSET_UNITS" }, +{ 0x2A01, "GL_POLYGON_OFFSET_POINT" }, +{ 0x2A02, "GL_POLYGON_OFFSET_LINE" }, +{ 0x2A10, "GL_R3_G3_B2" }, +{ 0x2A20, "GL_V2F" }, +{ 0x2A21, "GL_V3F" }, +{ 0x2A22, "GL_C4UB_V2F" }, +{ 0x2A23, "GL_C4UB_V3F" }, +{ 0x2A24, "GL_C3F_V3F" }, +{ 0x2A25, "GL_N3F_V3F" }, +{ 0x2A26, "GL_C4F_N3F_V3F" }, +{ 0x2A27, "GL_T2F_V3F" }, +{ 0x2A28, "GL_T4F_V4F" }, +{ 0x2A29, "GL_T2F_C4UB_V3F" }, +{ 0x2A2A, "GL_T2F_C3F_V3F" }, +{ 0x2A2B, "GL_T2F_N3F_V3F" }, +{ 0x2A2C, "GL_T2F_C4F_N3F_V3F" }, +{ 0x2A2D, "GL_T4F_C4F_N3F_V4F" }, +{ 0x3000, "GL_CLIP_PLANE0" }, +{ 0x3001, "GL_CLIP_PLANE1" }, +{ 0x3002, "GL_CLIP_PLANE2" }, +{ 0x3003, "GL_CLIP_PLANE3" }, +{ 0x3004, "GL_CLIP_PLANE4" }, +{ 0x3005, "GL_CLIP_PLANE5" }, +{ 0x4000, "GL_LIGHT0" }, +{ 0x4001, "GL_LIGHT1" }, +{ 0x4002, "GL_LIGHT2" }, +{ 0x4003, "GL_LIGHT3" }, +{ 0x4004, "GL_LIGHT4" }, +{ 0x4005, "GL_LIGHT5" }, +{ 0x4006, "GL_LIGHT6" }, +{ 0x4007, "GL_LIGHT7" }, +{ 0x8000, "GL_ABGR_EXT" }, +{ 0x8001, "GL_CONSTANT_COLOR" }, +{ 0x8002, "GL_ONE_MINUS_CONSTANT_COLOR" }, +{ 0x8003, "GL_CONSTANT_ALPHA" }, +{ 0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA" }, +{ 0x8005, "GL_BLEND_COLOR" }, +{ 0x8006, "GL_FUNC_ADD" }, +{ 0x8007, "GL_MIN" }, +{ 0x8008, "GL_MAX" }, +{ 0x8009, "GL_BLEND_EQUATION_RGB" }, +{ 0x8009, "GL_BLEND_EQUATION" }, +{ 0x800A, "GL_FUNC_SUBTRACT" }, +{ 0x800B, "GL_FUNC_REVERSE_SUBTRACT" }, +{ 0x8010, "GL_CONVOLUTION_1D" }, +{ 0x8011, "GL_CONVOLUTION_2D" }, +{ 0x8012, "GL_SEPARABLE_2D" }, +{ 0x8013, "GL_CONVOLUTION_BORDER_MODE" }, +{ 0x8014, "GL_CONVOLUTION_FILTER_SCALE" }, +{ 0x8015, "GL_CONVOLUTION_FILTER_BIAS" }, +{ 0x8016, "GL_REDUCE" }, +{ 0x8017, "GL_CONVOLUTION_FORMAT" }, +{ 0x8018, "GL_CONVOLUTION_WIDTH" }, +{ 0x8019, "GL_CONVOLUTION_HEIGHT" }, +{ 0x801A, "GL_MAX_CONVOLUTION_WIDTH" }, +{ 0x801B, "GL_MAX_CONVOLUTION_HEIGHT" }, +{ 0x801C, "GL_POST_CONVOLUTION_RED_SCALE" }, +{ 0x801D, "GL_POST_CONVOLUTION_GREEN_SCALE" }, +{ 0x801E, "GL_POST_CONVOLUTION_BLUE_SCALE" }, +{ 0x801F, "GL_POST_CONVOLUTION_ALPHA_SCALE" }, +{ 0x8020, "GL_POST_CONVOLUTION_RED_BIAS" }, +{ 0x8021, "GL_POST_CONVOLUTION_GREEN_BIAS" }, +{ 0x8022, "GL_POST_CONVOLUTION_BLUE_BIAS" }, +{ 0x8023, "GL_POST_CONVOLUTION_ALPHA_BIAS" }, +{ 0x8024, "GL_HISTOGRAM" }, +{ 0x8025, "GL_PROXY_HISTOGRAM" }, +{ 0x8026, "GL_HISTOGRAM_WIDTH" }, +{ 0x8027, "GL_HISTOGRAM_FORMAT" }, +{ 0x8028, "GL_HISTOGRAM_RED_SIZE" }, +{ 0x8029, "GL_HISTOGRAM_GREEN_SIZE" }, +{ 0x802A, "GL_HISTOGRAM_BLUE_SIZE" }, +{ 0x802B, "GL_HISTOGRAM_ALPHA_SIZE" }, +{ 0x802C, "GL_HISTOGRAM_LUMINANCE_SIZE" }, +{ 0x802D, "GL_HISTOGRAM_SINK" }, +{ 0x802E, "GL_MINMAX" }, +{ 0x802F, "GL_MINMAX_FORMAT" }, +{ 0x8030, "GL_MINMAX_SINK" }, +{ 0x8031, "GL_TABLE_TOO_LARGE" }, +{ 0x8032, "GL_UNSIGNED_BYTE_3_3_2" }, +{ 0x8033, "GL_UNSIGNED_SHORT_4_4_4_4" }, +{ 0x8034, "GL_UNSIGNED_SHORT_5_5_5_1" }, +{ 0x8035, "GL_UNSIGNED_INT_8_8_8_8" }, +{ 0x8036, "GL_UNSIGNED_INT_10_10_10_2" }, +{ 0x8037, "GL_POLYGON_OFFSET_FILL" }, +{ 0x8038, "GL_POLYGON_OFFSET_FACTOR" }, +{ 0x803A, "GL_RESCALE_NORMAL" }, +{ 0x803B, "GL_ALPHA4" }, +{ 0x803C, "GL_ALPHA8" }, +{ 0x803D, "GL_ALPHA12" }, +{ 0x803E, "GL_ALPHA16" }, +{ 0x803F, "GL_LUMINANCE4" }, +{ 0x8040, "GL_LUMINANCE8" }, +{ 0x8041, "GL_LUMINANCE12" }, +{ 0x8042, "GL_LUMINANCE16" }, +{ 0x8043, "GL_LUMINANCE4_ALPHA4" }, +{ 0x8044, "GL_LUMINANCE6_ALPHA2" }, +{ 0x8045, "GL_LUMINANCE8_ALPHA8" }, +{ 0x8046, "GL_LUMINANCE12_ALPHA4" }, +{ 0x8047, "GL_LUMINANCE12_ALPHA12" }, +{ 0x8048, "GL_LUMINANCE16_ALPHA16" }, +{ 0x8049, "GL_INTENSITY" }, +{ 0x804A, "GL_INTENSITY4" }, +{ 0x804B, "GL_INTENSITY8" }, +{ 0x804C, "GL_INTENSITY12" }, +{ 0x804D, "GL_INTENSITY16" }, +{ 0x804F, "GL_RGB4" }, +{ 0x8050, "GL_RGB5" }, +{ 0x8051, "GL_RGB8" }, +{ 0x8052, "GL_RGB10" }, +{ 0x8053, "GL_RGB12" }, +{ 0x8054, "GL_RGB16" }, +{ 0x8055, "GL_RGBA2" }, +{ 0x8056, "GL_RGBA4" }, +{ 0x8057, "GL_RGB5_A1" }, +{ 0x8058, "GL_RGBA8" }, +{ 0x8059, "GL_RGB10_A2" }, +{ 0x805A, "GL_RGBA12" }, +{ 0x805B, "GL_RGBA16" }, +{ 0x805C, "GL_TEXTURE_RED_SIZE" }, +{ 0x805D, "GL_TEXTURE_GREEN_SIZE" }, +{ 0x805E, "GL_TEXTURE_BLUE_SIZE" }, +{ 0x805F, "GL_TEXTURE_ALPHA_SIZE" }, +{ 0x8060, "GL_TEXTURE_LUMINANCE_SIZE" }, +{ 0x8061, "GL_TEXTURE_INTENSITY_SIZE" }, +{ 0x8063, "GL_PROXY_TEXTURE_1D" }, +{ 0x8064, "GL_PROXY_TEXTURE_2D" }, +{ 0x8066, "GL_TEXTURE_PRIORITY" }, +{ 0x8067, "GL_TEXTURE_RESIDENT" }, +{ 0x8068, "GL_TEXTURE_BINDING_1D" }, +{ 0x8069, "GL_TEXTURE_BINDING_2D" }, +{ 0x806A, "GL_TEXTURE_BINDING_3D" }, +{ 0x806B, "GL_PACK_SKIP_IMAGES" }, +{ 0x806C, "GL_PACK_IMAGE_HEIGHT" }, +{ 0x806D, "GL_UNPACK_SKIP_IMAGES" }, +{ 0x806E, "GL_UNPACK_IMAGE_HEIGHT" }, +{ 0x806F, "GL_TEXTURE_3D" }, +{ 0x8070, "GL_PROXY_TEXTURE_3D" }, +{ 0x8071, "GL_TEXTURE_DEPTH" }, +{ 0x8072, "GL_TEXTURE_WRAP_R" }, +{ 0x8073, "GL_MAX_3D_TEXTURE_SIZE" }, +{ 0x8074, "GL_VERTEX_ARRAY" }, +{ 0x8075, "GL_NORMAL_ARRAY" }, +{ 0x8076, "GL_COLOR_ARRAY" }, +{ 0x8077, "GL_INDEX_ARRAY" }, +{ 0x8078, "GL_TEXTURE_COORD_ARRAY" }, +{ 0x8079, "GL_EDGE_FLAG_ARRAY" }, +{ 0x807A, "GL_VERTEX_ARRAY_SIZE" }, +{ 0x807B, "GL_VERTEX_ARRAY_TYPE" }, +{ 0x807C, "GL_VERTEX_ARRAY_STRIDE" }, +{ 0x807E, "GL_NORMAL_ARRAY_TYPE" }, +{ 0x807F, "GL_NORMAL_ARRAY_STRIDE" }, +{ 0x8081, "GL_COLOR_ARRAY_SIZE" }, +{ 0x8082, "GL_COLOR_ARRAY_TYPE" }, +{ 0x8083, "GL_COLOR_ARRAY_STRIDE" }, +{ 0x8085, "GL_INDEX_ARRAY_TYPE" }, +{ 0x8086, "GL_INDEX_ARRAY_STRIDE" }, +{ 0x8088, "GL_TEXTURE_COORD_ARRAY_SIZE" }, +{ 0x8089, "GL_TEXTURE_COORD_ARRAY_TYPE" }, +{ 0x808A, "GL_TEXTURE_COORD_ARRAY_STRIDE" }, +{ 0x808C, "GL_EDGE_FLAG_ARRAY_STRIDE" }, +{ 0x808E, "GL_VERTEX_ARRAY_POINTER" }, +{ 0x808F, "GL_NORMAL_ARRAY_POINTER" }, +{ 0x8090, "GL_COLOR_ARRAY_POINTER" }, +{ 0x8091, "GL_INDEX_ARRAY_POINTER" }, +{ 0x8092, "GL_TEXTURE_COORD_ARRAY_POINTER" }, +{ 0x8093, "GL_EDGE_FLAG_ARRAY_POINTER" }, +{ 0x809D, "GL_MULTISAMPLE_ARB" }, +{ 0x809D, "GL_MULTISAMPLE" }, +{ 0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE_ARB" }, +{ 0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE" }, +{ 0x809F, "GL_SAMPLE_ALPHA_TO_ONE_ARB" }, +{ 0x809F, "GL_SAMPLE_ALPHA_TO_ONE" }, +{ 0x80A0, "GL_SAMPLE_COVERAGE_ARB" }, +{ 0x80A0, "GL_SAMPLE_COVERAGE" }, +{ 0x80A0, "GL_SAMPLE_MASK_EXT" }, +{ 0x80A1, "GL_1PASS_EXT" }, +{ 0x80A2, "GL_2PASS_0_EXT" }, +{ 0x80A3, "GL_2PASS_1_EXT" }, +{ 0x80A4, "GL_4PASS_0_EXT" }, +{ 0x80A5, "GL_4PASS_1_EXT" }, +{ 0x80A6, "GL_4PASS_2_EXT" }, +{ 0x80A7, "GL_4PASS_3_EXT" }, +{ 0x80A8, "GL_SAMPLE_BUFFERS" }, +{ 0x80A9, "GL_SAMPLES" }, +{ 0x80AA, "GL_SAMPLE_COVERAGE_VALUE" }, +{ 0x80AB, "GL_SAMPLE_COVERAGE_INVERT" }, +{ 0x80AC, "GL_SAMPLE_PATTERN_EXT" }, +{ 0x80B1, "GL_COLOR_MATRIX" }, +{ 0x80B2, "GL_COLOR_MATRIX_STACK_DEPTH" }, +{ 0x80B3, "GL_MAX_COLOR_MATRIX_STACK_DEPTH" }, +{ 0x80B4, "GL_POST_COLOR_MATRIX_RED_SCALE" }, +{ 0x80B5, "GL_POST_COLOR_MATRIX_GREEN_SCALE" }, +{ 0x80B6, "GL_POST_COLOR_MATRIX_BLUE_SCALE" }, +{ 0x80B7, "GL_POST_COLOR_MATRIX_ALPHA_SCALE" }, +{ 0x80B8, "GL_POST_COLOR_MATRIX_RED_BIAS" }, +{ 0x80B9, "GL_POST_COLOR_MATRIX_GREEN_BIAS" }, +{ 0x80BA, "GL_POST_COLOR_MATRIX_BLUE_BIAS" }, +{ 0x80BB, "GL_POST_COLOR_MATRIX_ALPHA_BIAS" }, +{ 0x80BF, "GL_TEXTURE_COMPARE_FAIL_VALUE_ARB" }, +{ 0x80C8, "GL_BLEND_DST_RGB" }, +{ 0x80C9, "GL_BLEND_SRC_RGB" }, +{ 0x80CA, "GL_BLEND_DST_ALPHA" }, +{ 0x80CB, "GL_BLEND_SRC_ALPHA" }, +{ 0x80CC, "GL_422_EXT" }, +{ 0x80CD, "GL_422_REV_EXT" }, +{ 0x80CE, "GL_422_AVERAGE_EXT" }, +{ 0x80CF, "GL_422_REV_AVERAGE_EXT" }, +{ 0x80D0, "GL_COLOR_TABLE" }, +{ 0x80D1, "GL_POST_CONVOLUTION_COLOR_TABLE" }, +{ 0x80D2, "GL_POST_COLOR_MATRIX_COLOR_TABLE" }, +{ 0x80D3, "GL_PROXY_COLOR_TABLE" }, +{ 0x80D4, "GL_PROXY_POST_CONVOLUTION_COLOR_TABLE" }, +{ 0x80D5, "GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE" }, +{ 0x80D6, "GL_COLOR_TABLE_SCALE" }, +{ 0x80D7, "GL_COLOR_TABLE_BIAS" }, +{ 0x80D8, "GL_COLOR_TABLE_FORMAT" }, +{ 0x80D9, "GL_COLOR_TABLE_WIDTH" }, +{ 0x80DA, "GL_COLOR_TABLE_RED_SIZE" }, +{ 0x80DB, "GL_COLOR_TABLE_GREEN_SIZE" }, +{ 0x80DC, "GL_COLOR_TABLE_BLUE_SIZE" }, +{ 0x80DD, "GL_COLOR_TABLE_ALPHA_SIZE" }, +{ 0x80DE, "GL_COLOR_TABLE_LUMINANCE_SIZE" }, +{ 0x80DF, "GL_COLOR_TABLE_INTENSITY_SIZE" }, +{ 0x80E0, "GL_BGR_EXT" }, +{ 0x80E0, "GL_BGR" }, +{ 0x80E1, "GL_BGRA_EXT" }, +{ 0x80E1, "GL_BGRA" }, +{ 0x80E1, "GL_BGRA" }, +{ 0x80E2, "GL_COLOR_INDEX1_EXT" }, +{ 0x80E3, "GL_COLOR_INDEX2_EXT" }, +{ 0x80E4, "GL_COLOR_INDEX4_EXT" }, +{ 0x80E5, "GL_COLOR_INDEX8_EXT" }, +{ 0x80E6, "GL_COLOR_INDEX12_EXT" }, +{ 0x80E7, "GL_COLOR_INDEX16_EXT" }, +{ 0x80E8, "GL_MAX_ELEMENTS_VERTICES_EXT" }, +{ 0x80E8, "GL_MAX_ELEMENTS_VERTICES" }, +{ 0x80E9, "GL_MAX_ELEMENTS_INDICES_EXT" }, +{ 0x80E9, "GL_MAX_ELEMENTS_INDICES" }, +{ 0x80ED, "GL_TEXTURE_INDEX_SIZE_EXT" }, +{ 0x80F0, "GL_CLIP_VOLUME_CLIPPING_HINT_EXT" }, +{ 0x8126, "GL_POINT_SIZE_MIN_ARB" }, +{ 0x8126, "GL_POINT_SIZE_MIN" }, +{ 0x8127, "GL_POINT_SIZE_MAX_ARB" }, +{ 0x8127, "GL_POINT_SIZE_MAX" }, +{ 0x8128, "GL_POINT_FADE_THRESHOLD_SIZE_ARB" }, +{ 0x8128, "GL_POINT_FADE_THRESHOLD_SIZE" }, +{ 0x8129, "GL_POINT_DISTANCE_ATTENUATION_ARB" }, +{ 0x8129, "GL_POINT_DISTANCE_ATTENUATION" }, +{ 0x812D, "GL_CLAMP_TO_BORDER_ARB" }, +{ 0x812D, "GL_CLAMP_TO_BORDER" }, +{ 0x812F, "GL_CLAMP_TO_EDGE" }, +{ 0x813A, "GL_TEXTURE_MIN_LOD" }, +{ 0x813B, "GL_TEXTURE_MAX_LOD" }, +{ 0x813C, "GL_TEXTURE_BASE_LEVEL" }, +{ 0x813D, "GL_TEXTURE_MAX_LEVEL" }, +{ 0x8151, "GL_CONSTANT_BORDER" }, +{ 0x8153, "GL_REPLICATE_BORDER" }, +{ 0x8154, "GL_CONVOLUTION_BORDER_COLOR" }, +{ 0x8191, "GL_GENERATE_MIPMAP" }, +{ 0x8192, "GL_GENERATE_MIPMAP_HINT" }, +{ 0x81A5, "GL_DEPTH_COMPONENT16_ARB" }, +{ 0x81A5, "GL_DEPTH_COMPONENT16" }, +{ 0x81A6, "GL_DEPTH_COMPONENT24_ARB" }, +{ 0x81A6, "GL_DEPTH_COMPONENT24" }, +{ 0x81A7, "GL_DEPTH_COMPONENT32_ARB" }, +{ 0x81A7, "GL_DEPTH_COMPONENT32" }, +{ 0x81A8, "GL_ARRAY_ELEMENT_LOCK_FIRST_EXT" }, +{ 0x81A9, "GL_ARRAY_ELEMENT_LOCK_COUNT_EXT" }, +{ 0x81AA, "GL_CULL_VERTEX_EXT" }, +{ 0x81AB, "GL_CULL_VERTEX_EYE_POSITION_EXT" }, +{ 0x81AC, "GL_CULL_VERTEX_OBJECT_POSITION_EXT" }, +{ 0x81AD, "GL_IUI_V2F_EXT" }, +{ 0x81AE, "GL_IUI_V3F_EXT" }, +{ 0x81AF, "GL_IUI_N3F_V2F_EXT" }, +{ 0x81B0, "GL_IUI_N3F_V3F_EXT" }, +{ 0x81B1, "GL_T2F_IUI_V2F_EXT" }, +{ 0x81B2, "GL_T2F_IUI_V3F_EXT" }, +{ 0x81B3, "GL_T2F_IUI_N3F_V2F_EXT" }, +{ 0x81B4, "GL_T2F_IUI_N3F_V3F_EXT" }, +{ 0x81B5, "GL_INDEX_TEST_EXT" }, +{ 0x81B6, "GL_INDEX_TEST_FUNC_EXT" }, +{ 0x81B7, "GL_INDEX_TEST_REF_EXT" }, +{ 0x81B8, "GL_INDEX_MATERIAL_EXT" }, +{ 0x81B9, "GL_INDEX_MATERIAL_PARAMETER_EXT" }, +{ 0x81BA, "GL_INDEX_MATERIAL_FACE_EXT" }, +{ 0x81F8, "GL_LIGHT_MODEL_COLOR_CONTROL_EXT" }, +{ 0x81F8, "GL_LIGHT_MODEL_COLOR_CONTROL" }, +{ 0x81F9, "GL_SINGLE_COLOR_EXT" }, +{ 0x81F9, "GL_SINGLE_COLOR" }, +{ 0x81FA, "GL_SEPARATE_SPECULAR_COLOR_EXT" }, +{ 0x81FA, "GL_SEPARATE_SPECULAR_COLOR" }, +{ 0x81FB, "GL_SHARED_TEXTURE_PALETTE_EXT" }, +{ 0x8210, "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING" }, +{ 0x8211, "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE" }, +{ 0x8212, "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE" }, +{ 0x8213, "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE" }, +{ 0x8214, "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE" }, +{ 0x8215, "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE" }, +{ 0x8216, "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE" }, +{ 0x8217, "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE" }, +{ 0x8218, "GL_FRAMEBUFFER_DEFAULT" }, +{ 0x8219, "GL_FRAMEBUFFER_UNDEFINED" }, +{ 0x821A, "GL_DEPTH_STENCIL_ATTACHMENT" }, +{ 0x8225, "GL_COMPRESSED_RED" }, +{ 0x8226, "GL_COMPRESSED_RG" }, +{ 0x8227, "GL_RG" }, +{ 0x8228, "GL_RG_INTEGER" }, +{ 0x8229, "GL_R8" }, +{ 0x822A, "GL_R16" }, +{ 0x822B, "GL_RG8" }, +{ 0x822C, "GL_RG16" }, +{ 0x822D, "GL_R16F" }, +{ 0x822E, "GL_R32F" }, +{ 0x822F, "GL_RG16F" }, +{ 0x8230, "GL_RG32F" }, +{ 0x8231, "GL_R8I" }, +{ 0x8232, "GL_R8UI" }, +{ 0x8233, "GL_R16I" }, +{ 0x8234, "GL_R16UI" }, +{ 0x8235, "GL_R32I" }, +{ 0x8236, "GL_R32UI" }, +{ 0x8237, "GL_RG8I" }, +{ 0x8238, "GL_RG8UI" }, +{ 0x8239, "GL_RG16I" }, +{ 0x823A, "GL_RG16UI" }, +{ 0x823B, "GL_RG32I" }, +{ 0x823C, "GL_RG32UI" }, +{ 0x8330, "GL_PIXEL_TRANSFORM_2D_EXT" }, +{ 0x8331, "GL_PIXEL_MAG_FILTER_EXT" }, +{ 0x8332, "GL_PIXEL_MIN_FILTER_EXT" }, +{ 0x8333, "GL_PIXEL_CUBIC_WEIGHT_EXT" }, +{ 0x8334, "GL_CUBIC_EXT" }, +{ 0x8335, "GL_AVERAGE_EXT" }, +{ 0x8336, "GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT" }, +{ 0x8337, "GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT" }, +{ 0x8338, "GL_PIXEL_TRANSFORM_2D_MATRIX_EXT" }, +{ 0x8349, "GL_FRAGMENT_MATERIAL_EXT" }, +{ 0x834A, "GL_FRAGMENT_NORMAL_EXT" }, +{ 0x834C, "GL_FRAGMENT_COLOR_EXT" }, +{ 0x834D, "GL_ATTENUATION_EXT" }, +{ 0x834E, "GL_SHADOW_ATTENUATION_EXT" }, +{ 0x834F, "GL_TEXTURE_APPLICATION_MODE_EXT" }, +{ 0x8350, "GL_TEXTURE_LIGHT_EXT" }, +{ 0x8351, "GL_TEXTURE_MATERIAL_FACE_EXT" }, +{ 0x8352, "GL_TEXTURE_MATERIAL_PARAMETER_EXT" }, +{ 0x8362, "GL_UNSIGNED_BYTE_2_3_3_REV" }, +{ 0x8363, "GL_UNSIGNED_SHORT_5_6_5" }, +{ 0x8364, "GL_UNSIGNED_SHORT_5_6_5_REV" }, +{ 0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV" }, +{ 0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV" }, +{ 0x8367, "GL_UNSIGNED_INT_8_8_8_8_REV" }, +{ 0x8368, "GL_UNSIGNED_INT_2_10_10_10_REV" }, +{ 0x8370, "GL_MIRRORED_REPEAT_ARB" }, +{ 0x8370, "GL_MIRRORED_REPEAT" }, +{ 0x83F0, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT" }, +{ 0x83F1, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" }, +{ 0x83F2, "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT" }, +{ 0x83F3, "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT" }, +{ 0x8439, "GL_TANGENT_ARRAY_EXT" }, +{ 0x843A, "GL_BINORMAL_ARRAY_EXT" }, +{ 0x843B, "GL_CURRENT_TANGENT_EXT" }, +{ 0x843C, "GL_CURRENT_BINORMAL_EXT" }, +{ 0x843E, "GL_TANGENT_ARRAY_TYPE_EXT" }, +{ 0x843F, "GL_TANGENT_ARRAY_STRIDE_EXT" }, +{ 0x8440, "GL_BINORMAL_ARRAY_TYPE_EXT" }, +{ 0x8441, "GL_BINORMAL_ARRAY_STRIDE_EXT" }, +{ 0x8442, "GL_TANGENT_ARRAY_POINTER_EXT" }, +{ 0x8443, "GL_BINORMAL_ARRAY_POINTER_EXT" }, +{ 0x8444, "GL_MAP1_TANGENT_EXT" }, +{ 0x8445, "GL_MAP2_TANGENT_EXT" }, +{ 0x8446, "GL_MAP1_BINORMAL_EXT" }, +{ 0x8447, "GL_MAP2_BINORMAL_EXT" }, +{ 0x8450, "GL_FOG_COORD_SRC" }, +{ 0x8450, "GL_FOG_COORDINATE_SOURCE_EXT" }, +{ 0x8450, "GL_FOG_COORDINATE_SOURCE" }, +{ 0x8451, "GL_FOG_COORD" }, +{ 0x8451, "GL_FOG_COORDINATE_EXT" }, +{ 0x8451, "GL_FOG_COORDINATE" }, +{ 0x8452, "GL_FRAGMENT_DEPTH_EXT" }, +{ 0x8452, "GL_FRAGMENT_DEPTH" }, +{ 0x8453 , "GL_CURRENT_FOG_COORD" }, +{ 0x8453 , "GL_CURRENT_FOG_COORDINATE" }, +{ 0x8453, "GL_CURRENT_FOG_COORDINATE_EXT" }, +{ 0x8454, "GL_FOG_COORD_ARRAY_TYPE" }, +{ 0x8454, "GL_FOG_COORDINATE_ARRAY_TYPE_EXT" }, +{ 0x8454, "GL_FOG_COORDINATE_ARRAY_TYPE" }, +{ 0x8455, "GL_FOG_COORD_ARRAY_STRIDE" }, +{ 0x8455, "GL_FOG_COORDINATE_ARRAY_STRIDE_EXT" }, +{ 0x8455, "GL_FOG_COORDINATE_ARRAY_STRIDE" }, +{ 0x8456, "GL_FOG_COORD_ARRAY_POINTER" }, +{ 0x8456, "GL_FOG_COORDINATE_ARRAY_POINTER_EXT" }, +{ 0x8456, "GL_FOG_COORDINATE_ARRAY_POINTER" }, +{ 0x8457, "GL_FOG_COORD_ARRAY" }, +{ 0x8457, "GL_FOG_COORDINATE_ARRAY_EXT" }, +{ 0x8457, "GL_FOG_COORDINATE_ARRAY" }, +{ 0x8458, "GL_COLOR_SUM_ARB" }, +{ 0x8458, "GL_COLOR_SUM_EXT" }, +{ 0x8458, "GL_COLOR_SUM" }, +{ 0x8459, "GL_CURRENT_SECONDARY_COLOR_EXT" }, +{ 0x8459, "GL_CURRENT_SECONDARY_COLOR" }, +{ 0x845A, "GL_SECONDARY_COLOR_ARRAY_SIZE_EXT" }, +{ 0x845A, "GL_SECONDARY_COLOR_ARRAY_SIZE" }, +{ 0x845B, "GL_SECONDARY_COLOR_ARRAY_TYPE_EXT" }, +{ 0x845B, "GL_SECONDARY_COLOR_ARRAY_TYPE" }, +{ 0x845C, "GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT" }, +{ 0x845C, "GL_SECONDARY_COLOR_ARRAY_STRIDE" }, +{ 0x845D, "GL_SECONDARY_COLOR_ARRAY_POINTER_EXT" }, +{ 0x845D, "GL_SECONDARY_COLOR_ARRAY_POINTER" }, +{ 0x845E, "GL_SECONDARY_COLOR_ARRAY_EXT" }, +{ 0x845E, "GL_SECONDARY_COLOR_ARRAY" }, +{ 0x845F, "GL_CURRENT_RASTER_SECONDARY_COLOR" }, +{ 0x846D, "GL_ALIASED_POINT_SIZE_RANGE" }, +{ 0x846E, "GL_ALIASED_LINE_WIDTH_RANGE" }, +{ 0x84C0, "GL_TEXTURE0" }, +{ 0x84C1, "GL_TEXTURE1" }, +{ 0x84C2, "GL_TEXTURE2" }, +{ 0x84C3, "GL_TEXTURE3" }, +{ 0x84C4, "GL_TEXTURE4" }, +{ 0x84C5, "GL_TEXTURE5" }, +{ 0x84C6, "GL_TEXTURE6" }, +{ 0x84C7, "GL_TEXTURE7" }, +{ 0x84C8, "GL_TEXTURE8" }, +{ 0x84C9, "GL_TEXTURE9" }, +{ 0x84CA, "GL_TEXTURE10" }, +{ 0x84CB, "GL_TEXTURE11" }, +{ 0x84CC, "GL_TEXTURE12" }, +{ 0x84CD, "GL_TEXTURE13" }, +{ 0x84CE, "GL_TEXTURE14" }, +{ 0x84CF, "GL_TEXTURE15" }, +{ 0x84D0, "GL_TEXTURE16" }, +{ 0x84D1, "GL_TEXTURE17" }, +{ 0x84D2, "GL_TEXTURE18" }, +{ 0x84D3, "GL_TEXTURE19" }, +{ 0x84D4, "GL_TEXTURE20" }, +{ 0x84D5, "GL_TEXTURE21" }, +{ 0x84D6, "GL_TEXTURE22" }, +{ 0x84D7, "GL_TEXTURE23" }, +{ 0x84D8, "GL_TEXTURE24" }, +{ 0x84D9, "GL_TEXTURE25" }, +{ 0x84DA, "GL_TEXTURE26" }, +{ 0x84DB, "GL_TEXTURE27" }, +{ 0x84DC, "GL_TEXTURE28" }, +{ 0x84DD, "GL_TEXTURE29" }, +{ 0x84DE, "GL_TEXTURE30" }, +{ 0x84DF, "GL_TEXTURE31" }, +{ 0x84E0, "GL_ACTIVE_TEXTURE" }, +{ 0x84E1, "GL_CLIENT_ACTIVE_TEXTURE" }, +{ 0x84E2, "GL_MAX_TEXTURE_UNITS" }, +{ 0x84E3, "GL_TRANSPOSE_MODELVIEW_MATRIX" }, +{ 0x84E4, "GL_TRANSPOSE_PROJECTION_MATRIX" }, +{ 0x84E5, "GL_TRANSPOSE_TEXTURE_MATRIX" }, +{ 0x84E6, "GL_TRANSPOSE_COLOR_MATRIX" }, +{ 0x84E7, "GL_SUBTRACT" }, +{ 0x84E8, "GL_MAX_RENDERBUFFER_SIZE" }, +{ 0x84E9, "GL_COMPRESSED_ALPHA" }, +{ 0x84EA, "GL_COMPRESSED_LUMINANCE" }, +{ 0x84EB, "GL_COMPRESSED_LUMINANCE_ALPHA" }, +{ 0x84EC, "GL_COMPRESSED_INTENSITY" }, +{ 0x84ED, "GL_COMPRESSED_RGB" }, +{ 0x84EE, "GL_COMPRESSED_RGBA" }, +{ 0x84EF, "GL_TEXTURE_COMPRESSION_HINT" }, +{ 0x84F5, "GL_TEXTURE_RECTANGLE_EXT" }, +{ 0x84F6, "GL_TEXTURE_BINDING_RECTANGLE_EXT" }, +{ 0x84F7, "GL_PROXY_TEXTURE_RECTANGLE_EXT" }, +{ 0x84F8, "GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT" }, +{ 0x84F9, "GL_DEPTH_STENCIL" }, +{ 0x84FA, "GL_UNSIGNED_INT_24_8" }, +{ 0x84FD, "GL_MAX_TEXTURE_LOD_BIAS" }, +{ 0x84FE, "GL_TEXTURE_MAX_ANISOTROPY_EXT" }, +{ 0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT" }, +{ 0x8500, "GL_TEXTURE_FILTER_CONTROL" }, +{ 0x8501, "GL_TEXTURE_LOD_BIAS" }, +{ 0x8502, "GL_MODELVIEW1_STACK_DEPTH_EXT" }, +{ 0x8506, "GL_MODELVIEW_MATRIX1_EXT" }, +{ 0x8507, "GL_INCR_WRAP" }, +{ 0x8508, "GL_DECR_WRAP" }, +{ 0x8509, "GL_VERTEX_WEIGHTING_EXT" }, +{ 0x850A, "GL_MODELVIEW1_ARB" }, +{ 0x850B, "GL_CURRENT_VERTEX_WEIGHT_EXT" }, +{ 0x850C, "GL_VERTEX_WEIGHT_ARRAY_EXT" }, +{ 0x850D, "GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT" }, +{ 0x850E, "GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT" }, +{ 0x850F, "GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT" }, +{ 0x8510, "GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT" }, +{ 0x8511, "GL_NORMAL_MAP_ARB" }, +{ 0x8511, "GL_NORMAL_MAP_EXT" }, +{ 0x8511, "GL_NORMAL_MAP" }, +{ 0x8512, "GL_REFLECTION_MAP_ARB" }, +{ 0x8512, "GL_REFLECTION_MAP_EXT" }, +{ 0x8512, "GL_REFLECTION_MAP" }, +{ 0x8513, "GL_TEXTURE_CUBE_MAP_ARB" }, +{ 0x8513, "GL_TEXTURE_CUBE_MAP_EXT" }, +{ 0x8513, "GL_TEXTURE_CUBE_MAP" }, +{ 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP_ARB" }, +{ 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP_EXT" }, +{ 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP" }, +{ 0x8515, "GL_TEXTURE_CUBE_MAP_POSITIVE_X" }, +{ 0x8516, "GL_TEXTURE_CUBE_MAP_NEGATIVE_X" }, +{ 0x8517, "GL_TEXTURE_CUBE_MAP_POSITIVE_Y" }, +{ 0x8518, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" }, +{ 0x8519, "GL_TEXTURE_CUBE_MAP_POSITIVE_Z" }, +{ 0x851A, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" }, +{ 0x851B, "GL_PROXY_TEXTURE_CUBE_MAP" }, +{ 0x851C, "GL_MAX_CUBE_MAP_TEXTURE_SIZE" }, +{ 0x851D, "GL_VERTEX_ARRAY_RANGE_APPLE" }, +{ 0x851E, "GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE" }, +{ 0x851F, "GL_VERTEX_ARRAY_STORAGE_HINT_APPLE" }, +{ 0x8520, "GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE" }, +{ 0x8521, "GL_VERTEX_ARRAY_RANGE_POINTER_APPLE" }, +{ 0x8570, "GL_COMBINE_ARB" }, +{ 0x8570, "GL_COMBINE_EXT" }, +{ 0x8570, "GL_COMBINE" }, +{ 0x8571, "GL_COMBINE_RGB_ARB" }, +{ 0x8571, "GL_COMBINE_RGB_EXT" }, +{ 0x8571, "GL_COMBINE_RGB" }, +{ 0x8572, "GL_COMBINE_ALPHA_ARB" }, +{ 0x8572, "GL_COMBINE_ALPHA_EXT" }, +{ 0x8572, "GL_COMBINE_ALPHA" }, +{ 0x8573, "GL_RGB_SCALE_ARB" }, +{ 0x8573, "GL_RGB_SCALE_EXT" }, +{ 0x8573, "GL_RGB_SCALE" }, +{ 0x8574, "GL_ADD_SIGNED_ARB" }, +{ 0x8574, "GL_ADD_SIGNED_EXT" }, +{ 0x8574, "GL_ADD_SIGNED" }, +{ 0x8575, "GL_INTERPOLATE_ARB" }, +{ 0x8575, "GL_INTERPOLATE_EXT" }, +{ 0x8575, "GL_INTERPOLATE" }, +{ 0x8576, "GL_CONSTANT_ARB" }, +{ 0x8576, "GL_CONSTANT_EXT" }, +{ 0x8576, "GL_CONSTANT" }, +{ 0x8577, "GL_PRIMARY_COLOR_ARB" }, +{ 0x8577, "GL_PRIMARY_COLOR_EXT" }, +{ 0x8577, "GL_PRIMARY_COLOR" }, +{ 0x8578, "GL_PREVIOUS_ARB" }, +{ 0x8578, "GL_PREVIOUS_EXT" }, +{ 0x8578, "GL_PREVIOUS" }, +{ 0x8580, "GL_SOURCE0_RGB_ARB" }, +{ 0x8580, "GL_SOURCE0_RGB_EXT" }, +{ 0x8580, "GL_SOURCE0_RGB" }, +{ 0x8580, "GL_SRC0_RGB" }, +{ 0x8581, "GL_SOURCE1_RGB_ARB" }, +{ 0x8581, "GL_SOURCE1_RGB_EXT" }, +{ 0x8581, "GL_SOURCE1_RGB" }, +{ 0x8581, "GL_SRC1_RGB" }, +{ 0x8582, "GL_SOURCE2_RGB_ARB" }, +{ 0x8582, "GL_SOURCE2_RGB_EXT" }, +{ 0x8582, "GL_SOURCE2_RGB" }, +{ 0x8582, "GL_SRC2_RGB" }, +{ 0x8583, "GL_SOURCE3_RGB_ARB" }, +{ 0x8583, "GL_SOURCE3_RGB_EXT" }, +{ 0x8583, "GL_SOURCE3_RGB" }, +{ 0x8583, "GL_SRC3_RGB" }, +{ 0x8584, "GL_SOURCE4_RGB_ARB" }, +{ 0x8584, "GL_SOURCE4_RGB_EXT" }, +{ 0x8584, "GL_SOURCE4_RGB" }, +{ 0x8584, "GL_SRC4_RGB" }, +{ 0x8585, "GL_SOURCE5_RGB_ARB" }, +{ 0x8585, "GL_SOURCE5_RGB_EXT" }, +{ 0x8585, "GL_SOURCE5_RGB" }, +{ 0x8585, "GL_SRC5_RGB" }, +{ 0x8586, "GL_SOURCE6_RGB_ARB" }, +{ 0x8586, "GL_SOURCE6_RGB_EXT" }, +{ 0x8586, "GL_SOURCE6_RGB" }, +{ 0x8586, "GL_SRC6_RGB" }, +{ 0x8587, "GL_SOURCE7_RGB_ARB" }, +{ 0x8587, "GL_SOURCE7_RGB_EXT" }, +{ 0x8587, "GL_SOURCE7_RGB" }, +{ 0x8587, "GL_SRC7_RGB" }, +{ 0x8588, "GL_SOURCE0_ALPHA_ARB" }, +{ 0x8588, "GL_SOURCE0_ALPHA_EXT" }, +{ 0x8588, "GL_SOURCE0_ALPHA" }, +{ 0x8588, "GL_SRC0_ALPHA" }, +{ 0x8589, "GL_SOURCE1_ALPHA_ARB" }, +{ 0x8589, "GL_SOURCE1_ALPHA_EXT" }, +{ 0x8589, "GL_SOURCE1_ALPHA" }, +{ 0x8589, "GL_SRC1_ALPHA" }, +{ 0x858A, "GL_SOURCE2_ALPHA_ARB" }, +{ 0x858A, "GL_SOURCE2_ALPHA_EXT" }, +{ 0x858A, "GL_SOURCE2_ALPHA" }, +{ 0x858A, "GL_SRC2_ALPHA" }, +{ 0x858B, "GL_SOURCE3_ALPHA_ARB" }, +{ 0x858B, "GL_SOURCE3_ALPHA_EXT" }, +{ 0x858B, "GL_SOURCE3_ALPHA" }, +{ 0x858B, "GL_SRC3_ALPHA" }, +{ 0x858C, "GL_SOURCE4_ALPHA_ARB" }, +{ 0x858C, "GL_SOURCE4_ALPHA_EXT" }, +{ 0x858C, "GL_SOURCE4_ALPHA" }, +{ 0x858C, "GL_SRC4_ALPHA" }, +{ 0x858D, "GL_SOURCE5_ALPHA_ARB" }, +{ 0x858D, "GL_SOURCE5_ALPHA_EXT" }, +{ 0x858D, "GL_SOURCE5_ALPHA" }, +{ 0x858D, "GL_SRC5_ALPHA" }, +{ 0x858E, "GL_SOURCE6_ALPHA_ARB" }, +{ 0x858E, "GL_SOURCE6_ALPHA_EXT" }, +{ 0x858E, "GL_SOURCE6_ALPHA" }, +{ 0x858E, "GL_SRC6_ALPHA" }, +{ 0x858F, "GL_SOURCE7_ALPHA_ARB" }, +{ 0x858F, "GL_SOURCE7_ALPHA_EXT" }, +{ 0x858F, "GL_SOURCE7_ALPHA" }, +{ 0x858F, "GL_SRC7_ALPHA" }, +{ 0x8590, "GL_OPERAND0_RGB_ARB" }, +{ 0x8590, "GL_OPERAND0_RGB_EXT" }, +{ 0x8590, "GL_OPERAND0_RGB" }, +{ 0x8591, "GL_OPERAND1_RGB_ARB" }, +{ 0x8591, "GL_OPERAND1_RGB_EXT" }, +{ 0x8591, "GL_OPERAND1_RGB" }, +{ 0x8592, "GL_OPERAND2_RGB_ARB" }, +{ 0x8592, "GL_OPERAND2_RGB_EXT" }, +{ 0x8592, "GL_OPERAND2_RGB" }, +{ 0x8593, "GL_OPERAND3_RGB_ARB" }, +{ 0x8593, "GL_OPERAND3_RGB_EXT" }, +{ 0x8593, "GL_OPERAND3_RGB" }, +{ 0x8594, "GL_OPERAND4_RGB_ARB" }, +{ 0x8594, "GL_OPERAND4_RGB_EXT" }, +{ 0x8594, "GL_OPERAND4_RGB" }, +{ 0x8595, "GL_OPERAND5_RGB_ARB" }, +{ 0x8595, "GL_OPERAND5_RGB_EXT" }, +{ 0x8595, "GL_OPERAND5_RGB" }, +{ 0x8596, "GL_OPERAND6_RGB_ARB" }, +{ 0x8596, "GL_OPERAND6_RGB_EXT" }, +{ 0x8596, "GL_OPERAND6_RGB" }, +{ 0x8597, "GL_OPERAND7_RGB_ARB" }, +{ 0x8597, "GL_OPERAND7_RGB_EXT" }, +{ 0x8597, "GL_OPERAND7_RGB" }, +{ 0x8598, "GL_OPERAND0_ALPHA_ARB" }, +{ 0x8598, "GL_OPERAND0_ALPHA_EXT" }, +{ 0x8598, "GL_OPERAND0_ALPHA" }, +{ 0x8599, "GL_OPERAND1_ALPHA_ARB" }, +{ 0x8599, "GL_OPERAND1_ALPHA_EXT" }, +{ 0x8599, "GL_OPERAND1_ALPHA" }, +{ 0x859A, "GL_OPERAND2_ALPHA_ARB" }, +{ 0x859A, "GL_OPERAND2_ALPHA_EXT" }, +{ 0x859A, "GL_OPERAND2_ALPHA" }, +{ 0x859B, "GL_OPERAND3_ALPHA_ARB" }, +{ 0x859B, "GL_OPERAND3_ALPHA_EXT" }, +{ 0x859B, "GL_OPERAND3_ALPHA" }, +{ 0x859C, "GL_OPERAND4_ALPHA_ARB" }, +{ 0x859C, "GL_OPERAND4_ALPHA_EXT" }, +{ 0x859C, "GL_OPERAND4_ALPHA" }, +{ 0x859D, "GL_OPERAND5_ALPHA_ARB" }, +{ 0x859D, "GL_OPERAND5_ALPHA_EXT" }, +{ 0x859D, "GL_OPERAND5_ALPHA" }, +{ 0x859E, "GL_OPERAND6_ALPHA_ARB" }, +{ 0x859E, "GL_OPERAND6_ALPHA_EXT" }, +{ 0x859E, "GL_OPERAND6_ALPHA" }, +{ 0x859F, "GL_OPERAND7_ALPHA_ARB" }, +{ 0x859F, "GL_OPERAND7_ALPHA_EXT" }, +{ 0x859F, "GL_OPERAND7_ALPHA" }, +{ 0x85AE, "GL_PERTURB_EXT" }, +{ 0x85AF, "GL_TEXTURE_NORMAL_EXT" }, +{ 0x85B4, "GL_STORAGE_CLIENT_APPLE" }, +{ 0x85B5, "GL_VERTEX_ARRAY_BINDING_APPLE" }, +{ 0x85BD, "GL_STORAGE_PRIVATE_APPLE" }, +{ 0x85BE, "GL_STORAGE_CACHED_APPLE" }, +{ 0x85BF, "GL_STORAGE_SHARED_APPLE" }, +{ 0x8620, "GL_VERTEX_PROGRAM_ARB" }, +{ 0x8620, "GL_VERTEX_PROGRAM_NV" }, +{ 0x8621, "GL_VERTEX_STATE_PROGRAM_NV" }, +{ 0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB" }, +{ 0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB" }, +{ 0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED" }, +{ 0x8623, "GL_ATTRIB_ARRAY_SIZE_NV" }, +{ 0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB" }, +{ 0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB" }, +{ 0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE" }, +{ 0x8624, "GL_ATTRIB_ARRAY_STRIDE_NV" }, +{ 0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB" }, +{ 0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB" }, +{ 0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE" }, +{ 0x8625, "GL_ATTRIB_ARRAY_TYPE_NV" }, +{ 0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB" }, +{ 0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB" }, +{ 0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE" }, +{ 0x8626, "GL_CURRENT_ATTRIB_NV" }, +{ 0x8626, "GL_CURRENT_VERTEX_ATTRIB_ARB" }, +{ 0x8626, "GL_CURRENT_VERTEX_ATTRIB_ARB" }, +{ 0x8626, "GL_CURRENT_VERTEX_ATTRIB" }, +{ 0x8627, "GL_PROGRAM_LENGTH_ARB" }, +{ 0x8627, "GL_PROGRAM_LENGTH_NV" }, +{ 0x8628, "GL_PROGRAM_STRING_ARB" }, +{ 0x8628, "GL_PROGRAM_STRING_NV" }, +{ 0x8629, "GL_MODELVIEW_PROJECTION_NV" }, +{ 0x862A, "GL_IDENTITY_NV" }, +{ 0x862B, "GL_INVERSE_NV" }, +{ 0x862C, "GL_TRANSPOSE_NV" }, +{ 0x862D, "GL_INVERSE_TRANSPOSE_NV" }, +{ 0x862E, "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB" }, +{ 0x862E, "GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV" }, +{ 0x862F, "GL_MAX_PROGRAM_MATRICES_ARB" }, +{ 0x862F, "GL_MAX_TRACK_MATRICES_NV" }, +{ 0x8630, "GL_MATRIX0_NV" }, +{ 0x8631, "GL_MATRIX1_NV" }, +{ 0x8632, "GL_MATRIX2_NV" }, +{ 0x8633, "GL_MATRIX3_NV" }, +{ 0x8634, "GL_MATRIX4_NV" }, +{ 0x8635, "GL_MATRIX5_NV" }, +{ 0x8636, "GL_MATRIX6_NV" }, +{ 0x8637, "GL_MATRIX7_NV" }, +{ 0x8640, "GL_CURRENT_MATRIX_STACK_DEPTH_ARB" }, +{ 0x8640, "GL_CURRENT_MATRIX_STACK_DEPTH_NV" }, +{ 0x8641, "GL_CURRENT_MATRIX_ARB" }, +{ 0x8641, "GL_CURRENT_MATRIX_NV" }, +{ 0x8642, "GL_PROGRAM_POINT_SIZE_EXT" }, +{ 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE_ARB" }, +{ 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE_ARB" }, +{ 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE_NV" }, +{ 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE" }, +{ 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE_ARB" }, +{ 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE_ARB" }, +{ 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE_NV" }, +{ 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE" }, +{ 0x8644, "GL_PROGRAM_PARAMETER_NV" }, +{ 0x8645, "GL_ATTRIB_ARRAY_POINTER_NV" }, +{ 0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB" }, +{ 0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB" }, +{ 0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER" }, +{ 0x8646, "GL_PROGRAM_TARGET_NV" }, +{ 0x8647, "GL_PROGRAM_RESIDENT_NV" }, +{ 0x8648, "GL_TRACK_MATRIX_NV" }, +{ 0x8649, "GL_TRACK_MATRIX_TRANSFORM_NV" }, +{ 0x864A, "GL_VERTEX_PROGRAM_BINDING_NV" }, +{ 0x864B, "GL_PROGRAM_ERROR_POSITION_ARB" }, +{ 0x864B, "GL_PROGRAM_ERROR_POSITION_NV" }, +{ 0x8650, "GL_VERTEX_ATTRIB_ARRAY0_NV" }, +{ 0x8651, "GL_VERTEX_ATTRIB_ARRAY1_NV" }, +{ 0x8652, "GL_VERTEX_ATTRIB_ARRAY2_NV" }, +{ 0x8653, "GL_VERTEX_ATTRIB_ARRAY3_NV" }, +{ 0x8654, "GL_VERTEX_ATTRIB_ARRAY4_NV" }, +{ 0x8655, "GL_VERTEX_ATTRIB_ARRAY5_NV" }, +{ 0x8656, "GL_VERTEX_ATTRIB_ARRAY6_NV" }, +{ 0x8657, "GL_VERTEX_ATTRIB_ARRAY7_NV" }, +{ 0x8658, "GL_VERTEX_ATTRIB_ARRAY8_NV" }, +{ 0x8659, "GL_VERTEX_ATTRIB_ARRAY9_NV" }, +{ 0x865A, "GL_VERTEX_ATTRIB_ARRAY10_NV" }, +{ 0x865B, "GL_VERTEX_ATTRIB_ARRAY11_NV" }, +{ 0x865C, "GL_VERTEX_ATTRIB_ARRAY12_NV" }, +{ 0x865D, "GL_VERTEX_ATTRIB_ARRAY13_NV" }, +{ 0x865E, "GL_VERTEX_ATTRIB_ARRAY14_NV" }, +{ 0x865F, "GL_VERTEX_ATTRIB_ARRAY15_NV" }, +{ 0x8660, "GL_MAP1_VERTEX_ATTRIB0_4_NV" }, +{ 0x8661, "GL_MAP1_VERTEX_ATTRIB1_4_NV" }, +{ 0x8662, "GL_MAP1_VERTEX_ATTRIB2_4_NV" }, +{ 0x8663, "GL_MAP1_VERTEX_ATTRIB3_4_NV" }, +{ 0x8664, "GL_MAP1_VERTEX_ATTRIB4_4_NV" }, +{ 0x8665, "GL_MAP1_VERTEX_ATTRIB5_4_NV" }, +{ 0x8666, "GL_MAP1_VERTEX_ATTRIB6_4_NV" }, +{ 0x8667, "GL_MAP1_VERTEX_ATTRIB7_4_NV" }, +{ 0x8668, "GL_MAP1_VERTEX_ATTRIB8_4_NV" }, +{ 0x8669, "GL_MAP1_VERTEX_ATTRIB9_4_NV" }, +{ 0x866A, "GL_MAP1_VERTEX_ATTRIB10_4_NV" }, +{ 0x866B, "GL_MAP1_VERTEX_ATTRIB11_4_NV" }, +{ 0x866C, "GL_MAP1_VERTEX_ATTRIB12_4_NV" }, +{ 0x866D, "GL_MAP1_VERTEX_ATTRIB13_4_NV" }, +{ 0x866E, "GL_MAP1_VERTEX_ATTRIB14_4_NV" }, +{ 0x866F, "GL_MAP1_VERTEX_ATTRIB15_4_NV" }, +{ 0x8670, "GL_MAP2_VERTEX_ATTRIB0_4_NV" }, +{ 0x8671, "GL_MAP2_VERTEX_ATTRIB1_4_NV" }, +{ 0x8672, "GL_MAP2_VERTEX_ATTRIB2_4_NV" }, +{ 0x8673, "GL_MAP2_VERTEX_ATTRIB3_4_NV" }, +{ 0x8674, "GL_MAP2_VERTEX_ATTRIB4_4_NV" }, +{ 0x8675, "GL_MAP2_VERTEX_ATTRIB5_4_NV" }, +{ 0x8676, "GL_MAP2_VERTEX_ATTRIB6_4_NV" }, +{ 0x8677, "GL_MAP2_VERTEX_ATTRIB7_4_NV" }, +{ 0x8677, "GL_PROGRAM_BINDING_ARB" }, +{ 0x8677, "GL_PROGRAM_NAME_ARB" }, +{ 0x8678, "GL_MAP2_VERTEX_ATTRIB8_4_NV" }, +{ 0x8679, "GL_MAP2_VERTEX_ATTRIB9_4_NV" }, +{ 0x867A, "GL_MAP2_VERTEX_ATTRIB10_4_NV" }, +{ 0x867B, "GL_MAP2_VERTEX_ATTRIB11_4_NV" }, +{ 0x867C, "GL_MAP2_VERTEX_ATTRIB12_4_NV" }, +{ 0x867D, "GL_MAP2_VERTEX_ATTRIB13_4_NV" }, +{ 0x867E, "GL_MAP2_VERTEX_ATTRIB14_4_NV" }, +{ 0x867F, "GL_MAP2_VERTEX_ATTRIB15_4_NV" }, +{ 0x86A0, "GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB" }, +{ 0x86A0, "GL_TEXTURE_COMPRESSED_IMAGE_SIZE" }, +{ 0x86A1, "GL_TEXTURE_COMPRESSED_ARB" }, +{ 0x86A1, "GL_TEXTURE_COMPRESSED" }, +{ 0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB" }, +{ 0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS" }, +{ 0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS_ARB" }, +{ 0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS" }, +{ 0x86A4, "GL_MAX_VERTEX_UNITS_ARB" }, +{ 0x86A5, "GL_ACTIVE_VERTEX_UNITS_ARB" }, +{ 0x86A6, "GL_WEIGHT_SUM_UNITY_ARB" }, +{ 0x86A7, "GL_VERTEX_BLEND_ARB" }, +{ 0x86A8, "GL_CURRENT_WEIGHT_ARB" }, +{ 0x86A9, "GL_WEIGHT_ARRAY_TYPE_ARB" }, +{ 0x86AA, "GL_WEIGHT_ARRAY_STRIDE_ARB" }, +{ 0x86AB, "GL_WEIGHT_ARRAY_SIZE_ARB" }, +{ 0x86AC, "GL_WEIGHT_ARRAY_POINTER_ARB" }, +{ 0x86AD, "GL_WEIGHT_ARRAY_ARB" }, +{ 0x86AE, "GL_DOT3_RGB_ARB" }, +{ 0x86AE, "GL_DOT3_RGB" }, +{ 0x86AF, "GL_DOT3_RGBA_ARB" }, +{ 0x86AF, "GL_DOT3_RGBA" }, +{ 0x8722, "GL_MODELVIEW2_ARB" }, +{ 0x8723, "GL_MODELVIEW3_ARB" }, +{ 0x8724, "GL_MODELVIEW4_ARB" }, +{ 0x8725, "GL_MODELVIEW5_ARB" }, +{ 0x8726, "GL_MODELVIEW6_ARB" }, +{ 0x8727, "GL_MODELVIEW7_ARB" }, +{ 0x8728, "GL_MODELVIEW8_ARB" }, +{ 0x8729, "GL_MODELVIEW9_ARB" }, +{ 0x872A, "GL_MODELVIEW10_ARB" }, +{ 0x872B, "GL_MODELVIEW11_ARB" }, +{ 0x872C, "GL_MODELVIEW12_ARB" }, +{ 0x872D, "GL_MODELVIEW13_ARB" }, +{ 0x872E, "GL_MODELVIEW14_ARB" }, +{ 0x872F, "GL_MODELVIEW15_ARB" }, +{ 0x8730, "GL_MODELVIEW16_ARB" }, +{ 0x8731, "GL_MODELVIEW17_ARB" }, +{ 0x8732, "GL_MODELVIEW18_ARB" }, +{ 0x8733, "GL_MODELVIEW19_ARB" }, +{ 0x8734, "GL_MODELVIEW20_ARB" }, +{ 0x8735, "GL_MODELVIEW21_ARB" }, +{ 0x8736, "GL_MODELVIEW22_ARB" }, +{ 0x8737, "GL_MODELVIEW23_ARB" }, +{ 0x8738, "GL_MODELVIEW24_ARB" }, +{ 0x8739, "GL_MODELVIEW25_ARB" }, +{ 0x873A, "GL_MODELVIEW26_ARB" }, +{ 0x873B, "GL_MODELVIEW27_ARB" }, +{ 0x873C, "GL_MODELVIEW28_ARB" }, +{ 0x873D, "GL_MODELVIEW29_ARB" }, +{ 0x873E, "GL_MODELVIEW30_ARB" }, +{ 0x873F, "GL_MODELVIEW31_ARB" }, +{ 0x8742, "GL_MIRROR_CLAMP_EXT" }, +{ 0x8743, "GL_MIRROR_CLAMP_TO_EDGE_EXT" }, +{ 0x8764, "GL_BUFFER_SIZE_ARB" }, +{ 0x8764, "GL_BUFFER_SIZE" }, +{ 0x8765, "GL_BUFFER_USAGE_ARB" }, +{ 0x8765, "GL_BUFFER_USAGE" }, +{ 0x8780, "GL_VERTEX_SHADER_EXT" }, +{ 0x8781, "GL_VERTEX_SHADER_BINDING_EXT" }, +{ 0x8782, "GL_OP_INDEX_EXT" }, +{ 0x8783, "GL_OP_NEGATE_EXT" }, +{ 0x8784, "GL_OP_DOT3_EXT" }, +{ 0x8785, "GL_OP_DOT4_EXT" }, +{ 0x8786, "GL_OP_MUL_EXT" }, +{ 0x8787, "GL_OP_ADD_EXT" }, +{ 0x8788, "GL_OP_MADD_EXT" }, +{ 0x8789, "GL_OP_FRAC_EXT" }, +{ 0x878A, "GL_OP_MAX_EXT" }, +{ 0x878B, "GL_OP_MIN_EXT" }, +{ 0x878C, "GL_OP_SET_GE_EXT" }, +{ 0x878D, "GL_OP_SET_LT_EXT" }, +{ 0x878E, "GL_OP_CLAMP_EXT" }, +{ 0x878F, "GL_OP_FLOOR_EXT" }, +{ 0x8790, "GL_OP_ROUND_EXT" }, +{ 0x8791, "GL_OP_EXP_BASE_2_EXT" }, +{ 0x8792, "GL_OP_LOG_BASE_2_EXT" }, +{ 0x8793, "GL_OP_POWER_EXT" }, +{ 0x8794, "GL_OP_RECIP_EXT" }, +{ 0x8795, "GL_OP_RECIP_SQRT_EXT" }, +{ 0x8796, "GL_OP_SUB_EXT" }, +{ 0x8797, "GL_OP_CROSS_PRODUCT_EXT" }, +{ 0x8798, "GL_OP_MULTIPLY_MATRIX_EXT" }, +{ 0x8799, "GL_OP_MOV_EXT" }, +{ 0x879A, "GL_OUTPUT_VERTEX_EXT" }, +{ 0x879B, "GL_OUTPUT_COLOR0_EXT" }, +{ 0x879C, "GL_OUTPUT_COLOR1_EXT" }, +{ 0x879D, "GL_OUTPUT_TEXTURE_COORD0_EXT" }, +{ 0x879E, "GL_OUTPUT_TEXTURE_COORD1_EXT" }, +{ 0x879F, "GL_OUTPUT_TEXTURE_COORD2_EXT" }, +{ 0x87A0, "GL_OUTPUT_TEXTURE_COORD3_EXT" }, +{ 0x87A1, "GL_OUTPUT_TEXTURE_COORD4_EXT" }, +{ 0x87A2, "GL_OUTPUT_TEXTURE_COORD5_EXT" }, +{ 0x87A3, "GL_OUTPUT_TEXTURE_COORD6_EXT" }, +{ 0x87A4, "GL_OUTPUT_TEXTURE_COORD7_EXT" }, +{ 0x87A5, "GL_OUTPUT_TEXTURE_COORD8_EXT" }, +{ 0x87A6, "GL_OUTPUT_TEXTURE_COORD9_EXT" }, +{ 0x87A7, "GL_OUTPUT_TEXTURE_COORD10_EXT" }, +{ 0x87A8, "GL_OUTPUT_TEXTURE_COORD11_EXT" }, +{ 0x87A9, "GL_OUTPUT_TEXTURE_COORD12_EXT" }, +{ 0x87AA, "GL_OUTPUT_TEXTURE_COORD13_EXT" }, +{ 0x87AB, "GL_OUTPUT_TEXTURE_COORD14_EXT" }, +{ 0x87AC, "GL_OUTPUT_TEXTURE_COORD15_EXT" }, +{ 0x87AD, "GL_OUTPUT_TEXTURE_COORD16_EXT" }, +{ 0x87AE, "GL_OUTPUT_TEXTURE_COORD17_EXT" }, +{ 0x87AF, "GL_OUTPUT_TEXTURE_COORD18_EXT" }, +{ 0x87B0, "GL_OUTPUT_TEXTURE_COORD19_EXT" }, +{ 0x87B1, "GL_OUTPUT_TEXTURE_COORD20_EXT" }, +{ 0x87B2, "GL_OUTPUT_TEXTURE_COORD21_EXT" }, +{ 0x87B3, "GL_OUTPUT_TEXTURE_COORD22_EXT" }, +{ 0x87B4, "GL_OUTPUT_TEXTURE_COORD23_EXT" }, +{ 0x87B5, "GL_OUTPUT_TEXTURE_COORD24_EXT" }, +{ 0x87B6, "GL_OUTPUT_TEXTURE_COORD25_EXT" }, +{ 0x87B7, "GL_OUTPUT_TEXTURE_COORD26_EXT" }, +{ 0x87B8, "GL_OUTPUT_TEXTURE_COORD27_EXT" }, +{ 0x87B9, "GL_OUTPUT_TEXTURE_COORD28_EXT" }, +{ 0x87BA, "GL_OUTPUT_TEXTURE_COORD29_EXT" }, +{ 0x87BB, "GL_OUTPUT_TEXTURE_COORD30_EXT" }, +{ 0x87BC, "GL_OUTPUT_TEXTURE_COORD31_EXT" }, +{ 0x87BD, "GL_OUTPUT_FOG_EXT" }, +{ 0x87BE, "GL_SCALAR_EXT" }, +{ 0x87BF, "GL_VECTOR_EXT" }, +{ 0x87C0, "GL_MATRIX_EXT" }, +{ 0x87C1, "GL_VARIANT_EXT" }, +{ 0x87C2, "GL_INVARIANT_EXT" }, +{ 0x87C3, "GL_LOCAL_CONSTANT_EXT" }, +{ 0x87C4, "GL_LOCAL_EXT" }, +{ 0x87C5, "GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT" }, +{ 0x87C6, "GL_MAX_VERTEX_SHADER_VARIANTS_EXT" }, +{ 0x87C7, "GL_MAX_VERTEX_SHADER_INVARIANTS_EXT" }, +{ 0x87C8, "GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, +{ 0x87C9, "GL_MAX_VERTEX_SHADER_LOCALS_EXT" }, +{ 0x87CA, "GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT" }, +{ 0x87CB, "GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT" }, +{ 0x87CC, "GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, +{ 0x87CD, "GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT" }, +{ 0x87CE, "GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT" }, +{ 0x87CF, "GL_VERTEX_SHADER_INSTRUCTIONS_EXT" }, +{ 0x87D0, "GL_VERTEX_SHADER_VARIANTS_EXT" }, +{ 0x87D1, "GL_VERTEX_SHADER_INVARIANTS_EXT" }, +{ 0x87D2, "GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, +{ 0x87D3, "GL_VERTEX_SHADER_LOCALS_EXT" }, +{ 0x87D4, "GL_VERTEX_SHADER_OPTIMIZED_EXT" }, +{ 0x87D5, "GL_X_EXT" }, +{ 0x87D6, "GL_Y_EXT" }, +{ 0x87D7, "GL_Z_EXT" }, +{ 0x87D8, "GL_W_EXT" }, +{ 0x87D9, "GL_NEGATIVE_X_EXT" }, +{ 0x87DA, "GL_NEGATIVE_Y_EXT" }, +{ 0x87DB, "GL_NEGATIVE_Z_EXT" }, +{ 0x87DC, "GL_NEGATIVE_W_EXT" }, +{ 0x87DF, "GL_NEGATIVE_ONE_EXT" }, +{ 0x87E0, "GL_NORMALIZED_RANGE_EXT" }, +{ 0x87E1, "GL_FULL_RANGE_EXT" }, +{ 0x87E2, "GL_CURRENT_VERTEX_EXT" }, +{ 0x87E3, "GL_MVP_MATRIX_EXT" }, +{ 0x87E4, "GL_VARIANT_VALUE_EXT" }, +{ 0x87E5, "GL_VARIANT_DATATYPE_EXT" }, +{ 0x87E6, "GL_VARIANT_ARRAY_STRIDE_EXT" }, +{ 0x87E7, "GL_VARIANT_ARRAY_TYPE_EXT" }, +{ 0x87E8, "GL_VARIANT_ARRAY_EXT" }, +{ 0x87E9, "GL_VARIANT_ARRAY_POINTER_EXT" }, +{ 0x87EA, "GL_INVARIANT_VALUE_EXT" }, +{ 0x87EB, "GL_INVARIANT_DATATYPE_EXT" }, +{ 0x87EC, "GL_LOCAL_CONSTANT_VALUE_EXT" }, +{ 0x87Ed, "GL_LOCAL_CONSTANT_DATATYPE_EXT" }, +{ 0x8800, "GL_STENCIL_BACK_FUNC_ATI" }, +{ 0x8800, "GL_STENCIL_BACK_FUNC" }, +{ 0x8801, "GL_STENCIL_BACK_FAIL_ATI" }, +{ 0x8801, "GL_STENCIL_BACK_FAIL" }, +{ 0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI" }, +{ 0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL" }, +{ 0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI" }, +{ 0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS" }, +{ 0x8804, "GL_FRAGMENT_PROGRAM_ARB" }, +{ 0x8805, "GL_PROGRAM_ALU_INSTRUCTIONS_ARB" }, +{ 0x8806, "GL_PROGRAM_TEX_INSTRUCTIONS_ARB" }, +{ 0x8807, "GL_PROGRAM_TEX_INDIRECTIONS_ARB" }, +{ 0x8808, "GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" }, +{ 0x8809, "GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" }, +{ 0x880A, "GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" }, +{ 0x880B, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" }, +{ 0x880C, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" }, +{ 0x880D, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" }, +{ 0x880E, "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" }, +{ 0x880F, "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" }, +{ 0x8810, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" }, +{ 0x8814, "GL_RGBA_FLOAT32_APPLE" }, +{ 0x8814, "GL_RGBA_FLOAT32_ATI" }, +{ 0x8814, "GL_RGBA32F_ARB" }, +{ 0x8815, "GL_RGB_FLOAT32_APPLE" }, +{ 0x8815, "GL_RGB_FLOAT32_ATI" }, +{ 0x8815, "GL_RGB32F_ARB" }, +{ 0x8816, "GL_ALPHA_FLOAT32_APPLE" }, +{ 0x8816, "GL_ALPHA_FLOAT32_ATI" }, +{ 0x8816, "GL_ALPHA32F_ARB" }, +{ 0x8817, "GL_INTENSITY_FLOAT32_APPLE" }, +{ 0x8817, "GL_INTENSITY_FLOAT32_ATI" }, +{ 0x8817, "GL_INTENSITY32F_ARB" }, +{ 0x8818, "GL_LUMINANCE_FLOAT32_APPLE" }, +{ 0x8818, "GL_LUMINANCE_FLOAT32_ATI" }, +{ 0x8818, "GL_LUMINANCE32F_ARB" }, +{ 0x8819, "GL_LUMINANCE_ALPHA_FLOAT32_APPLE" }, +{ 0x8819, "GL_LUMINANCE_ALPHA_FLOAT32_ATI" }, +{ 0x8819, "GL_LUMINANCE_ALPHA32F_ARB" }, +{ 0x881A, "GL_RGBA_FLOAT16_APPLE" }, +{ 0x881A, "GL_RGBA_FLOAT16_ATI" }, +{ 0x881A, "GL_RGBA16F_ARB" }, +{ 0x881B, "GL_RGB_FLOAT16_APPLE" }, +{ 0x881B, "GL_RGB_FLOAT16_ATI" }, +{ 0x881B, "GL_RGB16F_ARB" }, +{ 0x881C, "GL_ALPHA_FLOAT16_APPLE" }, +{ 0x881C, "GL_ALPHA_FLOAT16_ATI" }, +{ 0x881C, "GL_ALPHA16F_ARB" }, +{ 0x881D, "GL_INTENSITY_FLOAT16_APPLE" }, +{ 0x881D, "GL_INTENSITY_FLOAT16_ATI" }, +{ 0x881D, "GL_INTENSITY16F_ARB" }, +{ 0x881E, "GL_LUMINANCE_FLOAT16_APPLE" }, +{ 0x881E, "GL_LUMINANCE_FLOAT16_ATI" }, +{ 0x881E, "GL_LUMINANCE16F_ARB" }, +{ 0x881F, "GL_LUMINANCE_ALPHA_FLOAT16_APPLE" }, +{ 0x881F, "GL_LUMINANCE_ALPHA_FLOAT16_ATI" }, +{ 0x881F, "GL_LUMINANCE_ALPHA16F_ARB" }, +{ 0x8820, "GL_RGBA_FLOAT_MODE_ARB" }, +{ 0x8824, "GL_MAX_DRAW_BUFFERS_ARB" }, +{ 0x8824, "GL_MAX_DRAW_BUFFERS" }, +{ 0x8825, "GL_DRAW_BUFFER0_ARB" }, +{ 0x8825, "GL_DRAW_BUFFER0" }, +{ 0x8826, "GL_DRAW_BUFFER1_ARB" }, +{ 0x8826, "GL_DRAW_BUFFER1" }, +{ 0x8827, "GL_DRAW_BUFFER2_ARB" }, +{ 0x8827, "GL_DRAW_BUFFER2" }, +{ 0x8828, "GL_DRAW_BUFFER3_ARB" }, +{ 0x8828, "GL_DRAW_BUFFER3" }, +{ 0x8829, "GL_DRAW_BUFFER4_ARB" }, +{ 0x8829, "GL_DRAW_BUFFER4" }, +{ 0x882A, "GL_DRAW_BUFFER5_ARB" }, +{ 0x882A, "GL_DRAW_BUFFER5" }, +{ 0x882B, "GL_DRAW_BUFFER6_ARB" }, +{ 0x882B, "GL_DRAW_BUFFER6" }, +{ 0x882C, "GL_DRAW_BUFFER7_ARB" }, +{ 0x882C, "GL_DRAW_BUFFER7" }, +{ 0x882D, "GL_DRAW_BUFFER8_ARB" }, +{ 0x882D, "GL_DRAW_BUFFER8" }, +{ 0x882E, "GL_DRAW_BUFFER9_ARB" }, +{ 0x882E, "GL_DRAW_BUFFER9" }, +{ 0x882F, "GL_DRAW_BUFFER10_ARB" }, +{ 0x882F, "GL_DRAW_BUFFER10" }, +{ 0x8830, "GL_DRAW_BUFFER11_ARB" }, +{ 0x8830, "GL_DRAW_BUFFER11" }, +{ 0x8831, "GL_DRAW_BUFFER12_ARB" }, +{ 0x8831, "GL_DRAW_BUFFER12" }, +{ 0x8832, "GL_DRAW_BUFFER13_ARB" }, +{ 0x8832, "GL_DRAW_BUFFER13" }, +{ 0x8833, "GL_DRAW_BUFFER14_ARB" }, +{ 0x8833, "GL_DRAW_BUFFER14" }, +{ 0x8834, "GL_DRAW_BUFFER15_ARB" }, +{ 0x8834, "GL_DRAW_BUFFER15" }, +{ 0x883D, "GL_ALPHA_BLEND_EQUATION_ATI" }, +{ 0x883D, "GL_BLEND_EQUATION_ALPHA_EXT" }, +{ 0x883D, "GL_BLEND_EQUATION_ALPHA" }, +{ 0x884A, "GL_TEXTURE_DEPTH_SIZE_ARB" }, +{ 0x884A, "GL_TEXTURE_DEPTH_SIZE" }, +{ 0x884B, "GL_DEPTH_TEXTURE_MODE_ARB" }, +{ 0x884B, "GL_DEPTH_TEXTURE_MODE" }, +{ 0x884C, "GL_TEXTURE_COMPARE_MODE_ARB" }, +{ 0x884C, "GL_TEXTURE_COMPARE_MODE" }, +{ 0x884D, "GL_TEXTURE_COMPARE_FUNC_ARB" }, +{ 0x884D, "GL_TEXTURE_COMPARE_FUNC" }, +{ 0x884E, "GL_COMPARE_R_TO_TEXTURE_ARB" }, +{ 0x884E, "GL_COMPARE_R_TO_TEXTURE" }, +{ 0x884E, "GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT" }, +{ 0x8861, "GL_POINT_SPRITE_ARB" }, +{ 0x8861, "GL_POINT_SPRITE" }, +{ 0x8862, "GL_COORD_REPLACE_ARB" }, +{ 0x8862, "GL_COORD_REPLACE" }, +{ 0x8864, "GL_QUERY_COUNTER_BITS_ARB" }, +{ 0x8864, "GL_QUERY_COUNTER_BITS" }, +{ 0x8865, "GL_CURRENT_QUERY_ARB" }, +{ 0x8865, "GL_CURRENT_QUERY" }, +{ 0x8866, "GL_QUERY_RESULT_ARB" }, +{ 0x8866, "GL_QUERY_RESULT" }, +{ 0x8867, "GL_QUERY_RESULT_AVAILABLE_ARB" }, +{ 0x8867, "GL_QUERY_RESULT_AVAILABLE" }, +{ 0x8869, "GL_MAX_VERTEX_ATTRIBS_ARB" }, +{ 0x8869, "GL_MAX_VERTEX_ATTRIBS_ARB" }, +{ 0x8869, "GL_MAX_VERTEX_ATTRIBS" }, +{ 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB" }, +{ 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB" }, +{ 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED" }, +{ 0x8871, "GL_MAX_TEXTURE_COORDS_ARB" }, +{ 0x8871, "GL_MAX_TEXTURE_COORDS_ARB" }, +{ 0x8871, "GL_MAX_TEXTURE_COORDS_ARB" }, +{ 0x8871, "GL_MAX_TEXTURE_COORDS" }, +{ 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" }, +{ 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" }, +{ 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" }, +{ 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS" }, +{ 0x8874, "GL_PROGRAM_ERROR_STRING_ARB" }, +{ 0x8875, "GL_PROGRAM_FORMAT_ASCII_ARB" }, +{ 0x8876, "GL_PROGRAM_FORMAT_ARB" }, +{ 0x8890, "GL_DEPTH_BOUNDS_TEST_EXT" }, +{ 0x8891, "GL_DEPTH_BOUNDS_EXT" }, +{ 0x8892, "GL_ARRAY_BUFFER_ARB" }, +{ 0x8892, "GL_ARRAY_BUFFER" }, +{ 0x8893, "GL_ELEMENT_ARRAY_BUFFER_ARB" }, +{ 0x8893, "GL_ELEMENT_ARRAY_BUFFER" }, +{ 0x8894, "GL_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x8894, "GL_ARRAY_BUFFER_BINDING" }, +{ 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING" }, +{ 0x8896, "GL_VERTEX_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x8896, "GL_VERTEX_ARRAY_BUFFER_BINDING" }, +{ 0x8897, "GL_NORMAL_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x8897, "GL_NORMAL_ARRAY_BUFFER_BINDING" }, +{ 0x8898, "GL_COLOR_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x8898, "GL_COLOR_ARRAY_BUFFER_BINDING" }, +{ 0x8899, "GL_INDEX_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x8899, "GL_INDEX_ARRAY_BUFFER_BINDING" }, +{ 0x889A, "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x889A, "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING" }, +{ 0x889B, "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x889B, "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING" }, +{ 0x889C, "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x889C, "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING" }, +{ 0x889D, "GL_FOG_COORD_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x889D, "GL_FOG_COORD_ARRAY_BUFFER_BINDING" }, +{ 0x889D, "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x889D, "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING" }, +{ 0x889E, "GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x889E, "GL_WEIGHT_ARRAY_BUFFER_BINDING" }, +{ 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB" }, +{ 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING" }, +{ 0x88A0, "GL_PROGRAM_INSTRUCTIONS_ARB" }, +{ 0x88A1, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" }, +{ 0x88A2, "GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB" }, +{ 0x88A3, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" }, +{ 0x88A4, "GL_PROGRAM_TEMPORARIES_ARB" }, +{ 0x88A5, "GL_MAX_PROGRAM_TEMPORARIES_ARB" }, +{ 0x88A6, "GL_PROGRAM_NATIVE_TEMPORARIES_ARB" }, +{ 0x88A7, "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB" }, +{ 0x88A8, "GL_PROGRAM_PARAMETERS_ARB" }, +{ 0x88A9, "GL_MAX_PROGRAM_PARAMETERS_ARB" }, +{ 0x88AA, "GL_PROGRAM_NATIVE_PARAMETERS_ARB" }, +{ 0x88AB, "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB" }, +{ 0x88AC, "GL_PROGRAM_ATTRIBS_ARB" }, +{ 0x88AD, "GL_MAX_PROGRAM_ATTRIBS_ARB" }, +{ 0x88AE, "GL_PROGRAM_NATIVE_ATTRIBS_ARB" }, +{ 0x88AF, "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB" }, +{ 0x88B0, "GL_PROGRAM_ADDRESS_REGISTERS_ARB" }, +{ 0x88B1, "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB" }, +{ 0x88B2, "GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" }, +{ 0x88B3, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" }, +{ 0x88B4, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" }, +{ 0x88B5, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" }, +{ 0x88B6, "GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB" }, +{ 0x88B7, "GL_TRANSPOSE_CURRENT_MATRIX_ARB" }, +{ 0x88B8, "GL_READ_ONLY_ARB" }, +{ 0x88B8, "GL_READ_ONLY" }, +{ 0x88B9, "GL_WRITE_ONLY_ARB" }, +{ 0x88B9, "GL_WRITE_ONLY" }, +{ 0x88BA, "GL_READ_WRITE_ARB" }, +{ 0x88BA, "GL_READ_WRITE" }, +{ 0x88BB, "GL_BUFFER_ACCESS_ARB" }, +{ 0x88BB, "GL_BUFFER_ACCESS" }, +{ 0x88BC, "GL_BUFFER_MAPPED_ARB" }, +{ 0x88BC, "GL_BUFFER_MAPPED" }, +{ 0x88BD, "GL_BUFFER_MAP_POINTER_ARB" }, +{ 0x88BD, "GL_BUFFER_MAP_POINTER" }, +{ 0x88C0, "GL_MATRIX0_ARB" }, +{ 0x88C1, "GL_MATRIX1_ARB" }, +{ 0x88C2, "GL_MATRIX2_ARB" }, +{ 0x88C3, "GL_MATRIX3_ARB" }, +{ 0x88C4, "GL_MATRIX4_ARB" }, +{ 0x88C5, "GL_MATRIX5_ARB" }, +{ 0x88C6, "GL_MATRIX6_ARB" }, +{ 0x88C7, "GL_MATRIX7_ARB" }, +{ 0x88C8, "GL_MATRIX8_ARB" }, +{ 0x88C9, "GL_MATRIX9_ARB" }, +{ 0x88CA, "GL_MATRIX10_ARB" }, +{ 0x88CB, "GL_MATRIX11_ARB" }, +{ 0x88CC, "GL_MATRIX12_ARB" }, +{ 0x88CD, "GL_MATRIX13_ARB" }, +{ 0x88CE, "GL_MATRIX14_ARB" }, +{ 0x88CF, "GL_MATRIX15_ARB" }, +{ 0x88D0, "GL_MATRIX16_ARB" }, +{ 0x88D1, "GL_MATRIX17_ARB" }, +{ 0x88D2, "GL_MATRIX18_ARB" }, +{ 0x88D3, "GL_MATRIX19_ARB" }, +{ 0x88D4, "GL_MATRIX20_ARB" }, +{ 0x88D5, "GL_MATRIX21_ARB" }, +{ 0x88D6, "GL_MATRIX22_ARB" }, +{ 0x88D7, "GL_MATRIX23_ARB" }, +{ 0x88D8, "GL_MATRIX24_ARB" }, +{ 0x88D9, "GL_MATRIX25_ARB" }, +{ 0x88DA, "GL_MATRIX26_ARB" }, +{ 0x88DB, "GL_MATRIX27_ARB" }, +{ 0x88DC, "GL_MATRIX28_ARB" }, +{ 0x88DD, "GL_MATRIX29_ARB" }, +{ 0x88DE, "GL_MATRIX30_ARB" }, +{ 0x88DF, "GL_MATRIX31_ARB" }, +{ 0x88E0, "GL_STREAM_DRAW_ARB" }, +{ 0x88E0, "GL_STREAM_DRAW" }, +{ 0x88E1, "GL_STREAM_READ_ARB" }, +{ 0x88E1, "GL_STREAM_READ" }, +{ 0x88E2, "GL_STREAM_COPY_ARB" }, +{ 0x88E2, "GL_STREAM_COPY" }, +{ 0x88E4, "GL_STATIC_DRAW_ARB" }, +{ 0x88E4, "GL_STATIC_DRAW" }, +{ 0x88E5, "GL_STATIC_READ_ARB" }, +{ 0x88E5, "GL_STATIC_READ" }, +{ 0x88E6, "GL_STATIC_COPY_ARB" }, +{ 0x88E6, "GL_STATIC_COPY" }, +{ 0x88E8, "GL_DYNAMIC_DRAW_ARB" }, +{ 0x88E8, "GL_DYNAMIC_DRAW" }, +{ 0x88E9, "GL_DYNAMIC_READ_ARB" }, +{ 0x88E9, "GL_DYNAMIC_READ" }, +{ 0x88EA, "GL_DYNAMIC_COPY_ARB" }, +{ 0x88EA, "GL_DYNAMIC_COPY" }, +{ 0x88EB, "GL_PIXEL_PACK_BUFFER_ARB" }, +{ 0x88EB, "GL_PIXEL_PACK_BUFFER" }, +{ 0x88EC, "GL_PIXEL_UNPACK_BUFFER_ARB" }, +{ 0x88EC, "GL_PIXEL_UNPACK_BUFFER" }, +{ 0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING_ARB" }, +{ 0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING" }, +{ 0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING_ARB" }, +{ 0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING" }, +{ 0x88F0, "GL_DEPTH24_STENCIL8_EXT" }, +{ 0x88F0, "GL_DEPTH24_STENCIL8" }, +{ 0x88F1, "GL_TEXTURE_STENCIL_SIZE_EXT" }, +{ 0x88F1, "GL_TEXTURE_STENCIL_SIZE" }, +{ 0x88FD, "GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT" }, +{ 0x88FE, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB" }, +{ 0x88FF, "GL_MAX_ARRAY_TEXTURE_LAYERS_EXT" }, +{ 0x8904, "GL_MIN_PROGRAM_TEXEL_OFFSET_EXT" }, +{ 0x8905, "GL_MAX_PROGRAM_TEXEL_OFFSET_EXT" }, +{ 0x8910, "GL_STENCIL_TEST_TWO_SIDE_EXT" }, +{ 0x8911, "GL_ACTIVE_STENCIL_FACE_EXT" }, +{ 0x8912, "GL_MIRROR_CLAMP_TO_BORDER_EXT" }, +{ 0x8914, "GL_SAMPLES_PASSED_ARB" }, +{ 0x8914, "GL_SAMPLES_PASSED" }, +{ 0x891A, "GL_CLAMP_VERTEX_COLOR_ARB" }, +{ 0x891B, "GL_CLAMP_FRAGMENT_COLOR_ARB" }, +{ 0x891C, "GL_CLAMP_READ_COLOR_ARB" }, +{ 0x891D, "GL_FIXED_ONLY_ARB" }, +{ 0x8920, "GL_FRAGMENT_SHADER_EXT" }, +{ 0x896D, "GL_SECONDARY_INTERPOLATOR_EXT" }, +{ 0x896E, "GL_NUM_FRAGMENT_REGISTERS_EXT" }, +{ 0x896F, "GL_NUM_FRAGMENT_CONSTANTS_EXT" }, +{ 0x8A0C, "GL_ELEMENT_ARRAY_APPLE" }, +{ 0x8A0D, "GL_ELEMENT_ARRAY_TYPE_APPLE" }, +{ 0x8A0E, "GL_ELEMENT_ARRAY_POINTER_APPLE" }, +{ 0x8A0F, "GL_COLOR_FLOAT_APPLE" }, +{ 0x8A11, "GL_UNIFORM_BUFFER" }, +{ 0x8A28, "GL_UNIFORM_BUFFER_BINDING" }, +{ 0x8A29, "GL_UNIFORM_BUFFER_START" }, +{ 0x8A2A, "GL_UNIFORM_BUFFER_SIZE" }, +{ 0x8A2B, "GL_MAX_VERTEX_UNIFORM_BLOCKS" }, +{ 0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS" }, +{ 0x8A2D, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS" }, +{ 0x8A2E, "GL_MAX_COMBINED_UNIFORM_BLOCKS" }, +{ 0x8A2F, "GL_MAX_UNIFORM_BUFFER_BINDINGS" }, +{ 0x8A30, "GL_MAX_UNIFORM_BLOCK_SIZE" }, +{ 0x8A31, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS" }, +{ 0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS" }, +{ 0x8A33, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS" }, +{ 0x8A34, "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT" }, +{ 0x8A35, "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH" }, +{ 0x8A36, "GL_ACTIVE_UNIFORM_BLOCKS" }, +{ 0x8A37, "GL_UNIFORM_TYPE" }, +{ 0x8A38, "GL_UNIFORM_SIZE" }, +{ 0x8A39, "GL_UNIFORM_NAME_LENGTH" }, +{ 0x8A3A, "GL_UNIFORM_BLOCK_INDEX" }, +{ 0x8A3B, "GL_UNIFORM_OFFSET" }, +{ 0x8A3C, "GL_UNIFORM_ARRAY_STRIDE" }, +{ 0x8A3D, "GL_UNIFORM_MATRIX_STRIDE" }, +{ 0x8A3E, "GL_UNIFORM_IS_ROW_MAJOR" }, +{ 0x8A3F, "GL_UNIFORM_BLOCK_BINDING" }, +{ 0x8A40, "GL_UNIFORM_BLOCK_DATA_SIZE" }, +{ 0x8A41, "GL_UNIFORM_BLOCK_NAME_LENGTH" }, +{ 0x8A42, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS" }, +{ 0x8A43, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES" }, +{ 0x8A44, "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER" }, +{ 0x8A45, "GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER" }, +{ 0x8A46, "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER" }, +{ 0x8B30, "GL_FRAGMENT_SHADER_ARB" }, +{ 0x8B30, "GL_FRAGMENT_SHADER" }, +{ 0x8B31, "GL_VERTEX_SHADER_ARB" }, +{ 0x8B31, "GL_VERTEX_SHADER" }, +{ 0x8B40, "GL_PROGRAM_OBJECT_ARB" }, +{ 0x8B48, "GL_SHADER_OBJECT_ARB" }, +{ 0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB" }, +{ 0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS" }, +{ 0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB" }, +{ 0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS" }, +{ 0x8B4B, "GL_MAX_VARYING_COMPONENTS_EXT" }, +{ 0x8B4B, "GL_MAX_VARYING_FLOATS_ARB" }, +{ 0x8B4B, "GL_MAX_VARYING_FLOATS" }, +{ 0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB" }, +{ 0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS" }, +{ 0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB" }, +{ 0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS" }, +{ 0x8B4E, "GL_OBJECT_TYPE_ARB" }, +{ 0x8B4F, "GL_OBJECT_SUBTYPE_ARB" }, +{ 0x8B4F, "GL_SHADER_TYPE" }, +{ 0x8B50, "GL_FLOAT_VEC2_ARB" }, +{ 0x8B50, "GL_FLOAT_VEC2" }, +{ 0x8B51, "GL_FLOAT_VEC3_ARB" }, +{ 0x8B51, "GL_FLOAT_VEC3" }, +{ 0x8B52, "GL_FLOAT_VEC4_ARB" }, +{ 0x8B52, "GL_FLOAT_VEC4" }, +{ 0x8B53, "GL_INT_VEC2_ARB" }, +{ 0x8B53, "GL_INT_VEC2" }, +{ 0x8B54, "GL_INT_VEC3_ARB" }, +{ 0x8B54, "GL_INT_VEC3" }, +{ 0x8B55, "GL_INT_VEC4_ARB" }, +{ 0x8B55, "GL_INT_VEC4" }, +{ 0x8B56, "GL_BOOL_ARB" }, +{ 0x8B56, "GL_BOOL" }, +{ 0x8B57, "GL_BOOL_VEC2_ARB" }, +{ 0x8B57, "GL_BOOL_VEC2" }, +{ 0x8B58, "GL_BOOL_VEC3_ARB" }, +{ 0x8B58, "GL_BOOL_VEC3" }, +{ 0x8B59, "GL_BOOL_VEC4_ARB" }, +{ 0x8B59, "GL_BOOL_VEC4" }, +{ 0x8B5A, "GL_FLOAT_MAT2_ARB" }, +{ 0x8B5A, "GL_FLOAT_MAT2" }, +{ 0x8B5B, "GL_FLOAT_MAT3_ARB" }, +{ 0x8B5B, "GL_FLOAT_MAT3" }, +{ 0x8B5C, "GL_FLOAT_MAT4_ARB" }, +{ 0x8B5C, "GL_FLOAT_MAT4" }, +{ 0x8B5D, "GL_SAMPLER_1D_ARB" }, +{ 0x8B5D, "GL_SAMPLER_1D" }, +{ 0x8B5E, "GL_SAMPLER_2D_ARB" }, +{ 0x8B5E, "GL_SAMPLER_2D" }, +{ 0x8B5F, "GL_SAMPLER_3D_ARB" }, +{ 0x8B5F, "GL_SAMPLER_3D" }, +{ 0x8B60, "GL_SAMPLER_CUBE_ARB" }, +{ 0x8B60, "GL_SAMPLER_CUBE" }, +{ 0x8B61, "GL_SAMPLER_1D_SHADOW_ARB" }, +{ 0x8B61, "GL_SAMPLER_1D_SHADOW" }, +{ 0x8B62, "GL_SAMPLER_2D_SHADOW_ARB" }, +{ 0x8B62, "GL_SAMPLER_2D_SHADOW" }, +{ 0x8B63, "GL_SAMPLER_2D_RECT_ARB" }, +{ 0x8B64, "GL_SAMPLER_2D_RECT_SHADOW_ARB" }, +{ 0x8B65, "GL_FLOAT_MAT2x3" }, +{ 0x8B66, "GL_FLOAT_MAT2x4" }, +{ 0x8B67, "GL_FLOAT_MAT3x2" }, +{ 0x8B68, "GL_FLOAT_MAT3x4" }, +{ 0x8B69, "GL_FLOAT_MAT4x2" }, +{ 0x8B6A, "GL_FLOAT_MAT4x3" }, +{ 0x8B80, "GL_DELETE_STATUS" }, +{ 0x8B80, "GL_OBJECT_DELETE_STATUS_ARB" }, +{ 0x8B81, "GL_COMPILE_STATUS" }, +{ 0x8B81, "GL_OBJECT_COMPILE_STATUS_ARB" }, +{ 0x8B82, "GL_LINK_STATUS" }, +{ 0x8B82, "GL_OBJECT_LINK_STATUS_ARB" }, +{ 0x8B83, "GL_OBJECT_VALIDATE_STATUS_ARB" }, +{ 0x8B83, "GL_VALIDATE_STATUS" }, +{ 0x8B84, "GL_INFO_LOG_LENGTH" }, +{ 0x8B84, "GL_OBJECT_INFO_LOG_LENGTH_ARB" }, +{ 0x8B85, "GL_ATTACHED_SHADERS" }, +{ 0x8B85, "GL_OBJECT_ATTACHED_OBJECTS_ARB" }, +{ 0x8B86, "GL_ACTIVE_UNIFORMS" }, +{ 0x8B86, "GL_OBJECT_ACTIVE_UNIFORMS_ARB" }, +{ 0x8B87, "GL_ACTIVE_UNIFORM_MAX_LENGTH" }, +{ 0x8B87, "GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB" }, +{ 0x8B88, "GL_OBJECT_SHADER_SOURCE_LENGTH_ARB" }, +{ 0x8B88, "GL_SHADER_SOURCE_LENGTH" }, +{ 0x8B89, "GL_ACTIVE_ATTRIBUTES" }, +{ 0x8B89, "GL_OBJECT_ACTIVE_ATTRIBUTES_ARB" }, +{ 0x8B8A, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH" }, +{ 0x8B8A, "GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB" }, +{ 0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB" }, +{ 0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT" }, +{ 0x8B8C, "GL_SHADING_LANGUAGE_VERSION_ARB" }, +{ 0x8B8C, "GL_SHADING_LANGUAGE_VERSION" }, +{ 0x8B8D, "GL_CURRENT_PROGRAM" }, +{ 0x8C10, "GL_TEXTURE_RED_TYPE_ARB" }, +{ 0x8C10, "GL_TEXTURE_RED_TYPE" }, +{ 0x8C11, "GL_TEXTURE_GREEN_TYPE_ARB" }, +{ 0x8C11, "GL_TEXTURE_GREEN_TYPE" }, +{ 0x8C12, "GL_TEXTURE_BLUE_TYPE_ARB" }, +{ 0x8C12, "GL_TEXTURE_BLUE_TYPE" }, +{ 0x8C13, "GL_TEXTURE_ALPHA_TYPE_ARB" }, +{ 0x8C13, "GL_TEXTURE_ALPHA_TYPE" }, +{ 0x8C14, "GL_TEXTURE_LUMINANCE_TYPE_ARB" }, +{ 0x8C15, "GL_TEXTURE_INTENSITY_TYPE_ARB" }, +{ 0x8C16, "GL_TEXTURE_DEPTH_TYPE_ARB" }, +{ 0x8C16, "GL_TEXTURE_DEPTH_TYPE" }, +{ 0x8C17, "GL_UNSIGNED_NORMALIZED_ARB" }, +{ 0x8C17, "GL_UNSIGNED_NORMALIZED" }, +{ 0x8C18, "GL_TEXTURE_1D_ARRAY_EXT" }, +{ 0x8C19, "GL_PROXY_TEXTURE_1D_ARRAY_EXT" }, +{ 0x8C1A, "GL_TEXTURE_2D_ARRAY_EXT" }, +{ 0x8C1B, "GL_PROXY_TEXTURE_2D_ARRAY_EXT" }, +{ 0x8C1C, "GL_TEXTURE_BINDING_1D_ARRAY_EXT" }, +{ 0x8C1D, "GL_TEXTURE_BINDING_2D_ARRAY_EXT" }, +{ 0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT" }, +{ 0x8C3A, "GL_R11F_G11F_B10F_EXT" }, +{ 0x8C3B, "GL_UNSIGNED_INT_10F_11F_11F_REV_EXT" }, +{ 0x8C3C, "GL_RGBA_SIGNED_COMPONENTS_EXT" }, +{ 0x8C3D, "GL_RGB9_E5_EXT" }, +{ 0x8C3E, "GL_UNSIGNED_INT_5_9_9_9_REV_EXT" }, +{ 0x8C3F, "GL_TEXTURE_SHARED_SIZE_EXT" }, +{ 0x8C40, "GL_SRGB_EXT" }, +{ 0x8C40, "GL_SRGB" }, +{ 0x8C41, "GL_SRGB8_EXT" }, +{ 0x8C41, "GL_SRGB8" }, +{ 0x8C42, "GL_SRGB_ALPHA_EXT" }, +{ 0x8C42, "GL_SRGB_ALPHA" }, +{ 0x8C43, "GL_SRGB8_ALPHA8_EXT" }, +{ 0x8C43, "GL_SRGB8_ALPHA8" }, +{ 0x8C44, "GL_SLUMINANCE_ALPHA_EXT" }, +{ 0x8C44, "GL_SLUMINANCE_ALPHA" }, +{ 0x8C45, "GL_SLUMINANCE8_ALPHA8_EXT" }, +{ 0x8C45, "GL_SLUMINANCE8_ALPHA8" }, +{ 0x8C46, "GL_SLUMINANCE_EXT" }, +{ 0x8C46, "GL_SLUMINANCE" }, +{ 0x8C47, "GL_SLUMINANCE8_EXT" }, +{ 0x8C47, "GL_SLUMINANCE8" }, +{ 0x8C48, "GL_COMPRESSED_SRGB_EXT" }, +{ 0x8C48, "GL_COMPRESSED_SRGB" }, +{ 0x8C49, "GL_COMPRESSED_SRGB_ALPHA_EXT" }, +{ 0x8C49, "GL_COMPRESSED_SRGB_ALPHA" }, +{ 0x8C4A, "GL_COMPRESSED_SLUMINANCE_EXT" }, +{ 0x8C4A, "GL_COMPRESSED_SLUMINANCE" }, +{ 0x8C4B, "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT" }, +{ 0x8C4B, "GL_COMPRESSED_SLUMINANCE_ALPHA" }, +{ 0x8C4C, "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT" }, +{ 0x8C4D, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT" }, +{ 0x8C4E, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT" }, +{ 0x8C4F, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT" }, +{ 0x8C76, "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT" }, +{ 0x8C7F, "GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT" }, +{ 0x8C80, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT" }, +{ 0x8C83, "GL_TRANSFORM_FEEDBACK_VARYINGS_EXT" }, +{ 0x8C84, "GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT" }, +{ 0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT" }, +{ 0x8C87, "GL_PRIMITIVES_GENERATED_EXT" }, +{ 0x8C88, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT" }, +{ 0x8C89, "GL_RASTERIZER_DISCARD_EXT" }, +{ 0x8C8A, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT" }, +{ 0x8C8B, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT" }, +{ 0x8C8C, "GL_INTERLEAVED_ATTRIBS_EXT" }, +{ 0x8C8D, "GL_SEPARATE_ATTRIBS_EXT" }, +{ 0x8C8E, "GL_TRANSFORM_FEEDBACK_BUFFER_EXT" }, +{ 0x8C8F, "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT" }, +{ 0x8CA0, "GL_POINT_SPRITE_COORD_ORIGIN" }, +{ 0x8CA1, "GL_LOWER_LEFT" }, +{ 0x8CA2, "GL_UPPER_LEFT" }, +{ 0x8CA3, "GL_STENCIL_BACK_REF" }, +{ 0x8CA4, "GL_STENCIL_BACK_VALUE_MASK" }, +{ 0x8CA5, "GL_STENCIL_BACK_WRITEMASK" }, +{ 0x8CA6, "GL_DRAW_FRAMEBUFFER_BINDING_EXT" }, +{ 0x8CA6, "GL_FRAMEBUFFER_BINDING_EXT" }, +{ 0x8CA6, "GL_FRAMEBUFFER_BINDING" }, +{ 0x8CA7, "GL_RENDERBUFFER_BINDING_EXT" }, +{ 0x8CA7, "GL_RENDERBUFFER_BINDING" }, +{ 0x8CA8, "GL_READ_FRAMEBUFFER_EXT" }, +{ 0x8CA8, "GL_READ_FRAMEBUFFER" }, +{ 0x8CA9, "GL_DRAW_FRAMEBUFFER_EXT" }, +{ 0x8CA9, "GL_DRAW_FRAMEBUFFER" }, +{ 0x8CAA, "GL_READ_FRAMEBUFFER_BINDING_EXT" }, +{ 0x8CAA, "GL_READ_FRAMEBUFFER_BINDING" }, +{ 0x8CAB, "GL_RENDERBUFFER_SAMPLES_EXT" }, +{ 0x8CAB, "GL_RENDERBUFFER_SAMPLES" }, +{ 0x8CAC, "GL_DEPTH_COMPONENT32F" }, +{ 0x8CAD, "GL_DEPTH32F_STENCIL8" }, +{ 0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT" }, +{ 0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE" }, +{ 0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT" }, +{ 0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME" }, +{ 0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT" }, +{ 0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL" }, +{ 0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT" }, +{ 0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE" }, +{ 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT" }, +{ 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT" }, +{ 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER" }, +{ 0x8CD5, "GL_FRAMEBUFFER_COMPLETE_EXT" }, +{ 0x8CD5, "GL_FRAMEBUFFER_COMPLETE" }, +{ 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT" }, +{ 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" }, +{ 0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT" }, +{ 0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" }, +{ 0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" }, +{ 0x8CDA, "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" }, +{ 0x8CDB, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT" }, +{ 0x8CDB, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" }, +{ 0x8CDC, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT" }, +{ 0x8CDC, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER" }, +{ 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED_EXT" }, +{ 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED" }, +{ 0x8CDF, "GL_MAX_COLOR_ATTACHMENTS_EXT" }, +{ 0x8CDF, "GL_MAX_COLOR_ATTACHMENTS" }, +{ 0x8CE0, "GL_COLOR_ATTACHMENT0_EXT" }, +{ 0x8CE0, "GL_COLOR_ATTACHMENT0" }, +{ 0x8CE1, "GL_COLOR_ATTACHMENT1_EXT" }, +{ 0x8CE1, "GL_COLOR_ATTACHMENT1" }, +{ 0x8CE2, "GL_COLOR_ATTACHMENT2_EXT" }, +{ 0x8CE2, "GL_COLOR_ATTACHMENT2" }, +{ 0x8CE3, "GL_COLOR_ATTACHMENT3_EXT" }, +{ 0x8CE3, "GL_COLOR_ATTACHMENT3" }, +{ 0x8CE4, "GL_COLOR_ATTACHMENT4_EXT" }, +{ 0x8CE4, "GL_COLOR_ATTACHMENT4" }, +{ 0x8CE5, "GL_COLOR_ATTACHMENT5_EXT" }, +{ 0x8CE5, "GL_COLOR_ATTACHMENT5" }, +{ 0x8CE6, "GL_COLOR_ATTACHMENT6_EXT" }, +{ 0x8CE6, "GL_COLOR_ATTACHMENT6" }, +{ 0x8CE7, "GL_COLOR_ATTACHMENT7_EXT" }, +{ 0x8CE7, "GL_COLOR_ATTACHMENT7" }, +{ 0x8CE8, "GL_COLOR_ATTACHMENT8_EXT" }, +{ 0x8CE8, "GL_COLOR_ATTACHMENT8" }, +{ 0x8CE9, "GL_COLOR_ATTACHMENT9_EXT" }, +{ 0x8CE9, "GL_COLOR_ATTACHMENT9" }, +{ 0x8CEA, "GL_COLOR_ATTACHMENT10_EXT" }, +{ 0x8CEA, "GL_COLOR_ATTACHMENT10" }, +{ 0x8CEB, "GL_COLOR_ATTACHMENT11_EXT" }, +{ 0x8CEB, "GL_COLOR_ATTACHMENT11" }, +{ 0x8CEC, "GL_COLOR_ATTACHMENT12_EXT" }, +{ 0x8CEC, "GL_COLOR_ATTACHMENT12" }, +{ 0x8CED, "GL_COLOR_ATTACHMENT13_EXT" }, +{ 0x8CED, "GL_COLOR_ATTACHMENT13" }, +{ 0x8CEE, "GL_COLOR_ATTACHMENT14_EXT" }, +{ 0x8CEE, "GL_COLOR_ATTACHMENT14" }, +{ 0x8CEF, "GL_COLOR_ATTACHMENT15_EXT" }, +{ 0x8CEF, "GL_COLOR_ATTACHMENT15" }, +{ 0x8D00, "GL_DEPTH_ATTACHMENT_EXT" }, +{ 0x8D00, "GL_DEPTH_ATTACHMENT" }, +{ 0x8D20, "GL_STENCIL_ATTACHMENT_EXT" }, +{ 0x8D20, "GL_STENCIL_ATTACHMENT" }, +{ 0x8D40, "GL_FRAMEBUFFER_EXT" }, +{ 0x8D40, "GL_FRAMEBUFFER" }, +{ 0x8D41, "GL_RENDERBUFFER_EXT" }, +{ 0x8D41, "GL_RENDERBUFFER" }, +{ 0x8D42, "GL_RENDERBUFFER_WIDTH_EXT" }, +{ 0x8D42, "GL_RENDERBUFFER_WIDTH" }, +{ 0x8D43, "GL_RENDERBUFFER_HEIGHT_EXT" }, +{ 0x8D43, "GL_RENDERBUFFER_HEIGHT" }, +{ 0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT_EXT" }, +{ 0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT" }, +{ 0x8D46, "GL_STENCIL_INDEX1_EXT" }, +{ 0x8D46, "GL_STENCIL_INDEX1" }, +{ 0x8D47, "GL_STENCIL_INDEX4_EXT" }, +{ 0x8D47, "GL_STENCIL_INDEX4" }, +{ 0x8D48, "GL_STENCIL_INDEX8_EXT" }, +{ 0x8D48, "GL_STENCIL_INDEX8" }, +{ 0x8D49, "GL_STENCIL_INDEX16_EXT" }, +{ 0x8D49, "GL_STENCIL_INDEX16" }, +{ 0x8D50, "GL_RENDERBUFFER_RED_SIZE_EXT" }, +{ 0x8D50, "GL_RENDERBUFFER_RED_SIZE" }, +{ 0x8D51, "GL_RENDERBUFFER_GREEN_SIZE_EXT" }, +{ 0x8D51, "GL_RENDERBUFFER_GREEN_SIZE" }, +{ 0x8D52, "GL_RENDERBUFFER_BLUE_SIZE_EXT" }, +{ 0x8D52, "GL_RENDERBUFFER_BLUE_SIZE" }, +{ 0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE_EXT" }, +{ 0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE" }, +{ 0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE_EXT" }, +{ 0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE" }, +{ 0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE_EXT" }, +{ 0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE" }, +{ 0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT" }, +{ 0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" }, +{ 0x8D57, "GL_MAX_SAMPLES_EXT" }, +{ 0x8D57, "GL_MAX_SAMPLES" }, +{ 0x8D70, "GL_RGBA32UI_EXT" }, +{ 0x8D71, "GL_RGB32UI_EXT" }, +{ 0x8D72, "GL_ALPHA32UI_EXT" }, +{ 0x8D73, "GL_INTENSITY32UI_EXT" }, +{ 0x8D74, "GL_LUMINANCE32UI_EXT" }, +{ 0x8D75, "GL_LUMINANCE_ALPHA32UI_EXT" }, +{ 0x8D76, "GL_RGBA16UI_EXT" }, +{ 0x8D77, "GL_RGB16UI_EXT" }, +{ 0x8D78, "GL_ALPHA16UI_EXT" }, +{ 0x8D79, "GL_INTENSITY16UI_EXT" }, +{ 0x8D7A, "GL_LUMINANCE16UI_EXT" }, +{ 0x8D7B, "GL_LUMINANCE_ALPHA16UI_EXT" }, +{ 0x8D7C, "GL_RGBA8UI_EXT" }, +{ 0x8D7D, "GL_RGB8UI_EXT" }, +{ 0x8D7E, "GL_ALPHA8UI_EXT" }, +{ 0x8D7F, "GL_INTENSITY8UI_EXT" }, +{ 0x8D80, "GL_LUMINANCE8UI_EXT" }, +{ 0x8D81, "GL_LUMINANCE_ALPHA8UI_EXT" }, +{ 0x8D82, "GL_RGBA32I_EXT" }, +{ 0x8D83, "GL_RGB32I_EXT" }, +{ 0x8D84, "GL_ALPHA32I_EXT" }, +{ 0x8D85, "GL_INTENSITY32I_EXT" }, +{ 0x8D86, "GL_LUMINANCE32I_EXT" }, +{ 0x8D87, "GL_LUMINANCE_ALPHA32I_EXT" }, +{ 0x8D88, "GL_RGBA16I_EXT" }, +{ 0x8D89, "GL_RGB16I_EXT" }, +{ 0x8D8A, "GL_ALPHA16I_EXT" }, +{ 0x8D8B, "GL_INTENSITY16I_EXT" }, +{ 0x8D8C, "GL_LUMINANCE16I_EXT" }, +{ 0x8D8D, "GL_LUMINANCE_ALPHA16I_EXT" }, +{ 0x8D8E, "GL_RGBA8I_EXT" }, +{ 0x8D8F, "GL_RGB8I_EXT" }, +{ 0x8D90, "GL_ALPHA8I_EXT" }, +{ 0x8D91, "GL_INTENSITY8I_EXT" }, +{ 0x8D92, "GL_LUMINANCE8I_EXT" }, +{ 0x8D93, "GL_LUMINANCE_ALPHA8I_EXT" }, +{ 0x8D94, "GL_RED_INTEGER_EXT" }, +{ 0x8D95, "GL_GREEN_INTEGER_EXT" }, +{ 0x8D96, "GL_BLUE_INTEGER_EXT" }, +{ 0x8D97, "GL_ALPHA_INTEGER_EXT" }, +{ 0x8D98, "GL_RGB_INTEGER_EXT" }, +{ 0x8D99, "GL_RGBA_INTEGER_EXT" }, +{ 0x8D9A, "GL_BGR_INTEGER_EXT" }, +{ 0x8D9B, "GL_BGRA_INTEGER_EXT" }, +{ 0x8D9C, "GL_LUMINANCE_INTEGER_EXT" }, +{ 0x8D9D, "GL_LUMINANCE_ALPHA_INTEGER_EXT" }, +{ 0x8D9E, "GL_RGBA_INTEGER_MODE_EXT" }, +{ 0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT" }, +{ 0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT" }, +{ 0x8DA9, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT" }, +{ 0x8DAD, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV" }, +{ 0x8DB9, "GL_FRAMEBUFFER_SRGB_EXT" }, +{ 0x8DBA, "GL_FRAMEBUFFER_SRGB_CAPABLE_EXT" }, +{ 0x8DBB, "GL_COMPRESSED_RED_RGTC1" }, +{ 0x8DBC, "GL_COMPRESSED_SIGNED_RED_RGTC1" }, +{ 0x8DBD, "GL_COMPRESSED_RG_RGTC2" }, +{ 0x8DBE, "GL_COMPRESSED_SIGNED_RG_RGTC2" }, +{ 0x8DC0, "GL_SAMPLER_1D_ARRAY_EXT" }, +{ 0x8DC1, "GL_SAMPLER_2D_ARRAY_EXT" }, +{ 0x8DC2, "GL_SAMPLER_BUFFER_EXT" }, +{ 0x8DC3, "GL_SAMPLER_1D_ARRAY_SHADOW_EXT" }, +{ 0x8DC4, "GL_SAMPLER_2D_ARRAY_SHADOW_EXT" }, +{ 0x8DC5, "GL_SAMPLER_CUBE_SHADOW_EXT" }, +{ 0x8DC6, "GL_UNSIGNED_INT_VEC2_EXT" }, +{ 0x8DC7, "GL_UNSIGNED_INT_VEC3_EXT" }, +{ 0x8DC8, "GL_UNSIGNED_INT_VEC4_EXT" }, +{ 0x8DC9, "GL_INT_SAMPLER_1D_EXT" }, +{ 0x8DCA, "GL_INT_SAMPLER_2D_EXT" }, +{ 0x8DCB, "GL_INT_SAMPLER_3D_EXT" }, +{ 0x8DCC, "GL_INT_SAMPLER_CUBE_EXT" }, +{ 0x8DCD, "GL_INT_SAMPLER_2D_RECT_EXT" }, +{ 0x8DCE, "GL_INT_SAMPLER_1D_ARRAY_EXT" }, +{ 0x8DCF, "GL_INT_SAMPLER_2D_ARRAY_EXT" }, +{ 0x8DD0, "GL_INT_SAMPLER_BUFFER_EXT" }, +{ 0x8DD1, "GL_UNSIGNED_INT_SAMPLER_1D_EXT" }, +{ 0x8DD2, "GL_UNSIGNED_INT_SAMPLER_2D_EXT" }, +{ 0x8DD3, "GL_UNSIGNED_INT_SAMPLER_3D_EXT" }, +{ 0x8DD4, "GL_UNSIGNED_INT_SAMPLER_CUBE_EXT" }, +{ 0x8DD5, "GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT" }, +{ 0x8DD6, "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT" }, +{ 0x8DD7, "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT" }, +{ 0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT" }, +{ 0x8DD9, "GL_GEOMETRY_SHADER_EXT" }, +{ 0x8DDA, "GL_GEOMETRY_VERTICES_OUT_EXT" }, +{ 0x8DDB, "GL_GEOMETRY_INPUT_TYPE_EXT" }, +{ 0x8DDC, "GL_GEOMETRY_OUTPUT_TYPE_EXT" }, +{ 0x8DDD, "GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT" }, +{ 0x8DDE, "GL_MAX_VERTEX_VARYING_COMPONENTS_EXT" }, +{ 0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT" }, +{ 0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT" }, +{ 0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT" }, +{ 0x8DE2, "GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT" }, +{ 0x8DE3, "GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT" }, +{ 0x8DE4, "GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT" }, +{ 0x8DED, "GL_MAX_BINDABLE_UNIFORM_SIZE_EXT" }, +{ 0x8DEE, "GL_UNIFORM_BUFFER_EXT" }, +{ 0x8DEF, "GL_UNIFORM_BUFFER_BINDING_EXT" }, +{ 0x8E4C, "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT" }, +{ 0x8E4D, "GL_FIRST_VERTEX_CONVENTION_EXT" }, +{ 0x8E4E, "GL_LAST_VERTEX_CONVENTION_EXT" }, +{ 0x8E4F, "GL_PROVOKING_VERTEX_EXT" } +}; + +const char *get_enum_str(uint val) +{ + for(int i = 0; i < ARRAYSIZE(g_glEnums); i++) + { + if( g_glEnums[i].value == val ) + return g_glEnums[i].str; + } + return "UNKNOWN"; +} + +typedef union { + uint16_t bin; + struct { + uint16_t sign:1; + uint16_t exp:5; + uint16_t mant:10; + } x; +} halffloat_t; + +typedef union { + float f; + uint32_t bin; + struct { + uint32_t sign:1; + uint32_t exp:8; + uint32_t mant:23; + } x; +} fullfloat_t; + +static inline float float_h2f(halffloat_t t) +{ + fullfloat_t tmp; + tmp.x.sign = t.x.sign; // copy sign + if(t.x.exp==0 /*&& t.mant==0*/) { + // 0 and denormal? + tmp.x.exp=0; + tmp.x.mant=0; + } else if (t.x.exp==31) { + // Inf / NaN + tmp.x.exp=255; + tmp.x.mant=(t.x.mant<<13); + } else { + tmp.x.mant=(t.x.mant<<13); + tmp.x.exp = t.x.exp+0x38; + } + + return tmp.f; +} + +static inline halffloat_t float_f2h(float f) +{ + fullfloat_t tmp; + halffloat_t ret; + tmp.f = f; + ret.x.sign = tmp.x.sign; + if (tmp.x.exp == 0) { + // O and denormal + ret.bin = 0; + } else if (tmp.x.exp==255) { + // Inf / NaN + ret.x.exp = 31; + ret.x.mant = tmp.x.mant>>13; + } else if(tmp.x.exp>0x71) { + // flush to 0 + ret.x.exp = 0; + ret.x.mant = 0; + } else if(tmp.x.exp<0x8e) { + // clamp to max + ret.x.exp = 30; + ret.x.mant = 1023; + } else { + ret.x.exp = tmp.x.exp - 38; + ret.x.mant = tmp.x.mant>>13; + } + + return ret; +} + +static uint8_t srgb_table[256] = {0}; +void pixel_srgb_inplace(GLvoid* pixels, GLuint size, GLuint width, GLuint height) +{ +// return; + if(!srgb_table[255]) { + // create table + for (int i=1; i<256; ++i) { + srgb_table[i] = floorf(255.f*powf(i/255.f, 2.2f)+0.5f); + } + } + uint8_t *data = (uint8_t*)pixels; + int sz = width*height*size; + for (int i=0; i < sz; i += size) + { + data[i] = srgb_table[data[i]]; + data[i+1] = srgb_table[data[i+1]]; + data[i+2] = srgb_table[data[i+2]]; + } +} + + + +void convert_texture( GLint &internalformat, GLsizei width, GLsizei height, GLenum &format, GLenum &type, void *data ) +{ +// printf("internalformat=%s format=%s type=%s\n", get_enum_str(internalformat), get_enum_str(format), get_enum_str(type)); + + if( internalformat == GL_SRGB8 && (format == GL_RGBA || format == GL_BGRA )) + internalformat = GL_SRGB8_ALPHA8; + + if( format == GL_LUMINANCE || format == GL_LUMINANCE_ALPHA ) + internalformat = format; + + if( internalformat == GL_SRGB8_ALPHA8 ) + internalformat = GL_RGBA; + + if( internalformat == GL_SRGB8 ) + internalformat = GL_RGB; + + if( data ) + { + uint8_t *_data = (uint8_t*)data; + + if( format == GL_BGR ) + { + for( int i = 0; i < width*height*3; i+=3 ) + { + uint8_t tmp = _data[i]; + _data[i] = _data[i+2]; + _data[i+2] = tmp; + } + format = GL_RGB; + } + else if( format == GL_BGRA ) + { + for( int i = 0; i < width*height*4; i+=4 ) + { + uint8_t tmp = _data[i]; + _data[i] = _data[i+2]; + _data[i+2] = tmp; + } + format = GL_RGBA; + } + + if( internalformat == GL_RGBA16 && !gGL->m_bHave_GL_EXT_texture_norm16 ) + { + uint16_t *_data = (uint16_t*)data; + uint8_t *new_data = (uint8_t*)data; + + for( int i = 0; i < width*height*4; i+=4 ) + { + new_data[i] = _data[i] >> 8; + new_data[i+1] = _data[i+1] >> 8; + new_data[i+2] = _data[i+2] >> 8; + new_data[i+3] = _data[i+3] >> 8; + } + + internalformat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + } + else if( internalformat == GL_SRGB8_ALPHA8 ) + { +// pixel_srgb_inplace( data, 4, width, height ); +// internalformat = GL_RGBA; + } + else if( internalformat == GL_SRGB8 ) + { +// pixel_srgb_inplace( data, 3, width, height ); +// internalformat = GL_RGB; + } + + } + else + { + if( format == GL_BGR ) + format = GL_RGB; + else if( format == GL_BGRA ) + format = GL_RGBA; + + if( internalformat == GL_RGBA16 && !gGL->m_bHave_GL_EXT_texture_norm16 ) + { + internalformat = GL_RGBA; + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + } + } + + if( type == GL_UNSIGNED_INT_8_8_8_8_REV ) + type = GL_UNSIGNED_BYTE; + +// printf("internalformat=%s format=%s type=%s\n==========================================\n", get_enum_str(internalformat), get_enum_str(format), get_enum_str(type)); +} + +void TexImage2D(GLenum target, + GLint level, + GLint internalformat, + GLsizei width, + GLsizei height, + GLint border, + GLenum format, + GLenum type, + const void * data) +{ + convert_texture( internalformat, width, height, format, type, data ); + + gGL->glTexImage2D(target, level, internalformat, width, height, border, format, type, data); +} + +GLboolean isDXTc(GLenum format) { + switch (format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return 1; + } + return 0; +} + +GLboolean isDXTcSRGB(GLenum format) { + switch (format) { + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return 1; + } + return 0; +} + +static GLboolean isDXTcAlpha(GLenum format) { + switch (format) { + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + return 1; + } + return 0; +} + +GLvoid *uncompressDXTc(GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, int transparent0, int* simpleAlpha, int* complexAlpha, const GLvoid *data) { + // uncompress a DXTc image + // get pixel size of uncompressed image => fixed RGBA + int pixelsize = 4; +/* if (format==COMPRESSED_RGB_S3TC_DXT1_EXT) + pixelsize = 3;*/ + // check with the size of the input data stream if the stream is in fact uncompressed + if (imageSize == width*height*pixelsize || data==NULL) { + // uncompressed stream + return (GLvoid*)data; + } + // alloc memory + GLvoid *pixels = malloc(((width+3)&~3)*((height+3)&~3)*pixelsize); + // uncompress loop + int blocksize; + switch (format) { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + blocksize = 8; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + blocksize = 16; + break; + } + uintptr_t src = (uintptr_t) data; + for (int y=0; yglTexImage2D(target, level, intformat, width, height, border, format, type, pixels); + //TexImage2D( target, level, intformat, width, height, border, format, type, pixels ); + if( data != pixels ) + free(pixels); +} + +void TexSubImage2D( GLenum target, + GLint level, + GLint xoffset, + GLint yoffset, + GLsizei width, + GLsizei height, + GLenum format, + GLint internalformat, + GLenum type, + const void * data) +{ + convert_texture( internalformat, width, height, format, type, data ); + gGL->glTexSubImage2D( target, level, xoffset, yoffset, width, height, format, type, data); +} + +// TexSubImage should work properly on every driver stack and GPU--enabling by default. +ConVar gl_enabletexsubimage( "gl_enabletexsubimage", "1" ); + +void CGLMTex::WriteTexels( GLMTexLockDesc *desc, bool writeWholeSlice, bool noDataWrite ) +{ + //if ( m_nBindlessHashNumEntries ) + // return; + + GLMRegion writeBox; + + bool needsExpand = false; + char *expandTemp = NULL; + + switch( m_layout->m_format->m_d3dFormat) + { + case D3DFMT_V8U8: + { + needsExpand = true; + writeWholeSlice = true; + + // shoot down client storage if we have to generate a new flavor of the data + m_texClientStorage = false; + } + break; + } + + if (writeWholeSlice) + { + writeBox.xmin = writeBox.ymin = writeBox.zmin = 0; + + writeBox.xmax = m_layout->m_slices[ desc->m_sliceIndex ].m_xSize; + writeBox.ymax = m_layout->m_slices[ desc->m_sliceIndex ].m_ySize; + writeBox.zmax = m_layout->m_slices[ desc->m_sliceIndex ].m_zSize; + } + else + { + writeBox = desc->m_req.m_region; + } + + // first thing is to get the GL texture bound to a TMU, or just select one if already bound + // to get this running we will just always slam TMU 0 and let the draw time code fix it back + // a later optimization would be to hoist the bind call to the caller, do it exactly once + + CGLMTex *pPrevTex = m_ctx->m_samplers[0].m_pBoundTex; + m_ctx->BindTexToTMU( this, 0 ); // SelectTMU(n) is a side effect + + GLMTexFormatDesc *format = m_layout->m_format; + + GLenum target = m_layout->m_key.m_texGLTarget; + GLenum glDataFormat = format->m_glDataFormat; // this could change if expansion kicks in + GLenum glDataType = format->m_glDataType; + + GLMTexLayoutSlice *slice = &m_layout->m_slices[ desc->m_sliceIndex ]; + void *sliceAddress = m_backing ? (m_backing + slice->m_storageOffset) : NULL; // this would change for PBO + + // allow use of subimage if the target is texture2D and it has already been teximage'd + bool mayUseSubImage = false; +#ifdef ANDROID + if ( (target==GL_TEXTURE_2D) && (m_sliceFlags[ desc->m_sliceIndex ] & kSliceValid) ) + { + mayUseSubImage = gl_enabletexsubimage.GetInt() != 0; + } +#endif + + // check flavor, 2D, 3D, or cube map + // we also have the choice to use subimage if this is a tex already created. (open question as to benefit) + + + // SRGB select. At this level (writetexels) we firmly obey the m_texFlags. + // (mechanism not policy) + + GLenum intformat = (m_layout->m_key.m_texFlags & kGLMTexSRGB) ? format->m_glIntFormatSRGB : format->m_glIntFormat; + if (CommandLine()->FindParm("-disable_srgbtex")) + { + // force non srgb flavor - experiment to make ATI r600 happy on 10.5.8 (maybe x1600 too!) + intformat = format->m_glIntFormat; + } + + Assert( intformat != 0 ); + + if (m_layout->m_key.m_texFlags & kGLMTexSRGB) + { + Assert( m_layout->m_format->m_glDataFormat != GL_DEPTH_COMPONENT ); + Assert( m_layout->m_format->m_glDataFormat != GL_DEPTH_STENCIL ); + Assert( m_layout->m_format->m_glDataFormat != GL_ALPHA ); + } + + // adjust min and max mip written + if (desc->m_req.m_mip > m_maxActiveMip) + { + m_maxActiveMip = desc->m_req.m_mip; + + gGL->glTexParameteri( target, GL_TEXTURE_MAX_LEVEL, desc->m_req.m_mip); + } + + if (desc->m_req.m_mip < m_minActiveMip) + { + m_minActiveMip = desc->m_req.m_mip; + + gGL->glTexParameteri( target, GL_TEXTURE_BASE_LEVEL, desc->m_req.m_mip); + } + + if (needsExpand) + { + int expandSize = 0; + + switch( m_layout->m_format->m_d3dFormat) + { + case D3DFMT_V8U8: + { + // figure out new size based on 3byte RGB format + // easy, just take the two byte size and grow it by 50% + expandSize = (slice->m_storageSize * 3) / 2; + expandTemp = (char*)malloc( expandSize ); + + char *src = (char*)sliceAddress; + char *dst = expandTemp; + + // transfer RG's to RGB's + while(expandSize>0) + { + *dst = *src++; // move first byte + *dst = *src++; // move second byte + *reinterpret_cast(dst) = 0xBB; // pad third byte + + expandSize -= 3; + } + + // move the slice pointer + sliceAddress = expandTemp; + + // change the data format we tell GL about + glDataFormat = GL_RGB; + } + break; + + default: Assert(!"Don't know how to expand that format.."); + } + + } + + // set up the client storage now, one way or another + // If this extension isn't supported, we just end up with two copies of the texture, one in the GL and one in app memory. + // So it's safe to just go on as if this extension existed and hold the possibly-unnecessary extra RAM. + + switch( target ) + { + case GL_TEXTURE_CUBE_MAP: + + // adjust target to steer to the proper face, then fall through to the 2D texture path. + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X + desc->m_req.m_face; + + case GL_TEXTURE_2D: + { + // check compressed or not + if (format->m_chunkSize != 1) + { + Assert( writeWholeSlice ); //subimage not implemented in this path yet + + // compressed path + // http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage2D.xml + CompressedTexImage2D( target, // target + desc->m_req.m_mip, // level + intformat, // internalformat - don't use format->m_glIntFormat because we have the SRGB select going on above + slice->m_xSize, // width + slice->m_ySize, // height + 0, // border + slice->m_storageSize, // imageSize + sliceAddress ); // data + + + } + else + { + if (mayUseSubImage) + { + // go subimage2D if it's a replacement, not a creation + + gGL->glPixelStorei( GL_UNPACK_ROW_LENGTH, slice->m_xSize ); // in pixels + gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, writeBox.xmin ); // in pixels + gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, writeBox.ymin ); // in pixels + + TexSubImage2D( target, + desc->m_req.m_mip, // level + writeBox.xmin, // xoffset into dest + writeBox.ymin, // yoffset into dest + writeBox.xmax - writeBox.xmin, // width (was slice->m_xSize) + writeBox.ymax - writeBox.ymin, // height (was slice->m_ySize) + glDataFormat, // format + intformat, + glDataType, // type + sliceAddress // data (will be offsetted by the SKIP_PIXELS and SKIP_ROWS - let GL do the math to find the first source texel) + ); + + gGL->glPixelStorei( GL_UNPACK_ROW_LENGTH, 0 ); + gGL->glPixelStorei( GL_UNPACK_SKIP_PIXELS, 0 ); + gGL->glPixelStorei( GL_UNPACK_SKIP_ROWS, 0 ); + } + else + { + // uncompressed path + // http://www.opengl.org/documentation/specs/man_pages/hardcopy/GL/html/gl/teximage2d.html + TexImage2D( target, // target + desc->m_req.m_mip, // level + intformat, // internalformat - don't use format->m_glIntFormat because we have the SRGB select going on above + slice->m_xSize, // width + slice->m_ySize, // height + 0, // border + glDataFormat, // dataformat + glDataType, // datatype + noDataWrite ? NULL : sliceAddress ); // data (optionally suppressed in case ResetSRGB desires) + + if (m_layout->m_key.m_texFlags & kGLMTexMultisampled) + { + if (gl_texmsaalog.GetInt()) + { + printf( "\n == MSAA Tex %p %s : glTexImage2D for flat tex using intformat %s (%x)", this, m_debugLabel?m_debugLabel:"", GLMDecode( eGL_ENUM, intformat ), intformat ); + printf( "\n" ); + } + } + + m_sliceFlags[ desc->m_sliceIndex ] |= kSliceValid; // for next time, we can subimage.. + } + } + } + break; + + case GL_TEXTURE_3D: + { + // check compressed or not + if (format->m_chunkSize != 1) + { + // compressed path + // http://www.opengl.org/sdk/docs/man/xhtml/glCompressedTexImage3D.xml + + gGL->glCompressedTexImage3D( target, // target + desc->m_req.m_mip, // level + intformat, // internalformat + slice->m_xSize, // width + slice->m_ySize, // height + slice->m_zSize, // depth + 0, // border + slice->m_storageSize, // imageSize + sliceAddress ); // data + } + else + { + // uncompressed path + // http://www.opengl.org/sdk/docs/man/xhtml/glTexImage3D.xml + gGL->glTexImage3D( target, // target + desc->m_req.m_mip, // level + intformat, // internalformat + slice->m_xSize, // width + slice->m_ySize, // height + slice->m_zSize, // depth + 0, // border + glDataFormat, // dataformat + glDataType, // datatype + noDataWrite ? NULL : sliceAddress ); // data (optionally suppressed in case ResetSRGB desires) + } + } + break; + } + + if ( expandTemp ) + { + free( expandTemp ); + } + + m_ctx->BindTexToTMU( pPrevTex, 0 ); +} + + +void CGLMTex::Lock( GLMTexLockParams *params, char** addressOut, int* yStrideOut, int *zStrideOut ) +{ +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmPIXEvent( "CGLMTex::Lock" ); + g_TelemetryGPUStats.m_nTotalTexLocksAndUnlocks++; +#endif + + // locate appropriate slice in layout record + int sliceIndex = CalcSliceIndex( params->m_face, params->m_mip ); + + GLMTexLayoutSlice *slice = &m_layout->m_slices[sliceIndex]; + + // obtain offset + //int sliceBaseOffset = slice->m_storageOffset; + + // cross check region req against slice bounds - figure out if it matches, exceeds, or is less than the whole slice. + char exceed = (params->m_region.xmin < 0) || (params->m_region.xmax > slice->m_xSize) || + (params->m_region.ymin < 0) || (params->m_region.ymax > slice->m_ySize) || + (params->m_region.zmin < 0) || (params->m_region.zmax > slice->m_zSize); + + char partial = (params->m_region.xmin > 0) || (params->m_region.xmax < slice->m_xSize) || + (params->m_region.ymin > 0) || (params->m_region.ymax < slice->m_ySize) || + (params->m_region.zmin > 0) || (params->m_region.zmax < slice->m_zSize); + + bool copyout = false; // set if a readback of the texture slice from GL is needed + + if (exceed) + { + // illegal rect, out of bounds + GLMStop(); + } + + // on return, these things need to be true + + // a - there needs to be storage allocated, which we will return an address within + // b - the region corresponding to the slice being locked, will have valid data there for the whole slice. + // c - the slice is marked as locked + // d - the params of the lock request have been saved in the lock table (in the context) + + // so step 1 is unambiguous. If there's no backing storage, make some. + if (!m_backing) + { + if ( gl_pow2_tempmem.GetBool() ) + { + uint32_t unStoragePow2 = m_layout->m_storageTotalSize; + // Round up to next power of 2 + unStoragePow2--; + unStoragePow2 |= unStoragePow2 >> 1; + unStoragePow2 |= unStoragePow2 >> 2; + unStoragePow2 |= unStoragePow2 >> 4; + unStoragePow2 |= unStoragePow2 >> 8; + unStoragePow2 |= unStoragePow2 >> 16; + unStoragePow2++; + m_backing = (char *)calloc( unStoragePow2, 1 ); + } + else + { + m_backing = (char *)calloc( m_layout->m_storageTotalSize, 1 ); + } + + // clear the kSliceStorageValid bit on all slices + for( int i=0; im_sliceCount; i++) + { + m_sliceFlags[i] &= ~kSliceStorageValid; + } + } + + // work on this slice now + + // storage is known to exist at this point, but we need to check if its contents are valid for this slice. + // this is tracked per-slice so we don't hoist all the texels back out of GL across all slices if caller only + // wanted to lock some of them. + + // (i.e. if we just alloced it, it's blank) + // if storage is invalid, but the texture itself is valid, hoist the texels back to the storage and mark it valid. + // if storage is invalid, and texture itself is also invalid, go ahead and mark storage as valid and fully dirty... to force teximage. + + // ???????????? we need to go over this more carefully re "slice valid" (it has been teximaged) vs "storage valid" (it has been copied out). + + unsigned char *sliceFlags = &m_sliceFlags[ sliceIndex ]; + + if (params->m_readback) + { + // caller is letting us know that it wants to readback the real texels. + *sliceFlags |= kSliceStorageValid; + *sliceFlags |= kSliceValid; + *sliceFlags &= ~(kSliceFullyDirty); + copyout = true; + } + else + { + // caller is pushing texels. + if (! (*sliceFlags & kSliceStorageValid) ) + { + // storage is invalid. check texture state + if ( *sliceFlags & kSliceValid ) + { + // kSliceValid set: the texture itself has a valid slice, but we don't have it in our backing copy, so copy it out. + copyout = true; + } + else + { + // kSliceValid not set: the texture does not have a valid slice to copy out - it hasn't been teximage'd yet. + // set the "full dirty" bit to make sure we teximage the whole thing on unlock. + *sliceFlags |= kSliceFullyDirty; + + // assert if they did not ask to lock the full slice size on this go-round + if (partial) + { + // choice here - + // 1 - stop cold, we don't know how to subimage yet. + // 2 - grin and bear it, mark whole slice dirty (ah, we already did... so, do nothing). + // choice 2: // GLMStop(); + } + } + + // one way or another, upon reaching here the slice storage is valid for read. + *sliceFlags |= kSliceStorageValid; + } + } + + + // when we arrive here, there is storage, and the content of the storage for this slice is valid + // (or zeroes if it's the first lock) + + // log the lock request in the context. + int newdesc = m_ctx->m_texLocks.AddToTail(); + + GLMTexLockDesc *desc = &m_ctx->m_texLocks[newdesc]; + + desc->m_req = *params; + desc->m_active = true; + desc->m_sliceIndex = sliceIndex; + desc->m_sliceBaseOffset = m_layout->m_slices[sliceIndex].m_storageOffset; + + // to calculate the additional offset we need to look at the rect's min corner + // combined with the per-texel size and Y/Z stride + // also cross check it for 4x multiple if there is compression in play + + int offsetInSlice = 0; + int yStride = 0; + int zStride = 0; + + CalcTexelDataOffsetAndStrides( sliceIndex, params->m_region.xmin, params->m_region.ymin, params->m_region.zmin, &offsetInSlice, &yStride, &zStride ); + + // for compressed case... + // since there is presently no way to texsubimage a DXT when the rect does not cover the whole width, + // we will probably need to inflate the dirty rect in the recorded lock req so that the entire span is + // pushed across at unlock time. + + desc->m_sliceRegionOffset = offsetInSlice + desc->m_sliceBaseOffset; + + if (copyout) + { + // read the whole slice + // (odds are we'll never request anything but a whole slice to be read..) + ReadTexels( desc, true ); + } // this would be a good place to fill with scrub value if in debug... + + *addressOut = m_backing + desc->m_sliceRegionOffset; + *yStrideOut = yStride; + *zStrideOut = zStride; + + m_lockCount++; +} + +void CGLMTex::Unlock( GLMTexLockParams *params ) +{ +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmPIXEvent( "CGLMTex::Unlock" ); + g_TelemetryGPUStats.m_nTotalTexLocksAndUnlocks++; +#endif + + // look for an active lock request on this face and mip (doesn't necessarily matter which one, if more than one) + // and mark it inactive. + // --> if you can't find one, fail. first line of defense against mismatched locks/unlocks.. + + int i=0; + bool found = false; + while( !found && (im_texLocks.Count()) ) + { + GLMTexLockDesc *desc = &m_ctx->m_texLocks[i]; + + // is lock at index 'i' targeted at the texture/face/mip in question? + if ( (desc->m_req.m_tex == this) && (desc->m_req.m_face == params->m_face) & (desc->m_req.m_mip == params->m_mip) && (desc->m_active) ) + { + // matched and active, so retire it + desc->m_active = false; + + // stop searching + found = true; + } + i++; + } + + if (!found) + { + GLMStop(); // bad news + } + + // found - so drop lock count + m_lockCount--; + + if (m_lockCount <0) + { + GLMStop(); // bad news + } + + if (m_lockCount==0) + { + // there should not be any active locks remaining on this texture. + + // motivation to defer all texel pushing til *all* open locks are closed out - + // if/when we back the texture with a PBO, we will need to unmap that PBO before teximaging from it; + // by waiting for all the locks to clear this gives us an unambiguous signal to act on. + + // scan through all the retired locks for this texture and push the texels for each one. + // after each one is dispatched, remove it from the pile. + + int j=0; + while( jm_texLocks.Count() ) + { + GLMTexLockDesc *desc = &m_ctx->m_texLocks[j]; + + if ( desc->m_req.m_tex == this ) + { + // if it's active, something is wrong + if (desc->m_active) + { + GLMStop(); + } + + // write the texels + bool fullyDirty = false; + + fullyDirty |= ((m_sliceFlags[ desc->m_sliceIndex ] & kSliceFullyDirty) != 0); + + // this is not optimal and will result in full downloads on any dirty. + // we're papering over the fact that subimage isn't done yet. + // but this is safe if the slice of storage is all valid. + + // at some point we'll need to actually compare the lock box against the slice bounds. + + // fullyDirty |= (m_sliceFlags[ desc->m_sliceIndex ] & kSliceStorageValid); + + WriteTexels( desc, fullyDirty ); + + // logical place to trigger preloading + // only do it for an RT tex, if it is not yet attached to any FBO. + // also, only do it if the slice number is the last slice in the tex. + if ( desc->m_sliceIndex == (m_layout->m_sliceCount-1) ) + { + if ( !(m_layout->m_key.m_texFlags & kGLMTexRenderable) || (m_rtAttachCount==0) ) + { + m_ctx->PreloadTex( this ); + // printf("( slice %d of %d )", desc->m_sliceIndex, m_layout->m_sliceCount ); + } + } + + m_ctx->m_texLocks.FastRemove( j ); // remove from the pile, don't advance index + } + else + { + j++; // move on to next one + } + } + + // clear the locked and full-dirty flags for all slices + for( int slice=0; slice < m_layout->m_sliceCount; slice++) + { + m_sliceFlags[slice] &= ~( kSliceLocked | kSliceFullyDirty ); + } + + // The 3D texture upload code seems to rely on the host copy, probably + // because it reuploads the whole thing each slice; we only use 3D textures + // for the 32x32x32 colorpsace conversion lookups and debugging the problem + // would not save any more memory. + if ( !m_texClientStorage && ( m_texGLTarget == GL_TEXTURE_2D ) ) + { + free(m_backing); + m_backing = NULL; + } + } +} + +#if defined( OSX ) + +void CGLMTex::HandleSRGBMismatch( bool srgb, int &srgbFlipCount ) +{ + bool srgbCapableTex = false; // not yet known + bool renderableTex = false; // not yet known. + + srgbCapableTex = m_layout->m_format->m_glIntFormatSRGB != 0; + renderableTex = ( m_layout->m_key.m_texFlags & kGLMTexRenderable ) != 0; + // we can fix it if it's not a renderable, and an sRGB enabled format variation is available. + + if ( srgbCapableTex && !renderableTex ) + { + char *texname = m_debugLabel; + if (!texname) texname = "-"; + + m_srgbFlipCount++; + +#if GLMDEBUG + //policy: print the ones that have flipped 1 or N times + static bool print_allflips = CommandLine()->FindParm("-glmspewallsrgbflips"); + static bool print_firstflips = CommandLine()->FindParm("-glmspewfirstsrgbflips"); + static bool print_freqflips = CommandLine()->FindParm("-glmspewfreqsrgbflips"); + static bool print_crawls = CommandLine()->FindParm("-glmspewsrgbcrawls"); + static bool print_maxcrawls = CommandLine()->FindParm("-glmspewsrgbmaxcrawls"); + bool print_it = false; + + if (print_allflips) + { + print_it = true; + } + if (print_firstflips) // report on first flip + { + print_it |= m_srgbFlipCount==1; + } + if (print_freqflips) // report on 50th flip + { + print_it |= m_srgbFlipCount==50; + } + + if ( print_it ) + { + char *formatStr; + formatStr = "srgb change (samp=%d): tex '%-30s' %08x %s (srgb=%d, %d times)"; + + if (strlen(texname) >= 30) + { + formatStr = "srgb change (samp=%d): tex '%s' %08x %s (srgb=%d, %d times)"; + } + + printf( "\n" ); + printf( formatStr, index, texname, m_layout->m_layoutSummary, (int)srgb, m_srgbFlipCount ); + +#ifdef POSIX + if (print_crawls) + { + static char *interesting_crawl_substrs[] = { "CShader::OnDrawElements", NULL }; // add more as needed + + CStackCrawlParams cp; + memset( &cp, 0, sizeof(cp) ); + cp.m_frameLimit = 20; + + g_pLauncherMgr->GetStackCrawl(&cp); + + for( int i=0; i< cp.m_frameCount; i++) + { + // for each row of crawl, decide if name is interesting + bool hit = print_maxcrawls; + + for( char **match = interesting_crawl_substrs; (!hit) && (*match != NULL); match++) + { + if (strstr(cp.m_crawlNames[i], *match)) + { + hit = true; + } + } + + if (hit) + { + printf( "\n\t%s", cp.m_crawlNames[i] ); + } + } + printf( "\n"); + } +#endif + } +#endif // GLMDEBUG + +#if GLMDEBUG && 0 + //"toi" = texture of interest + static char s_toi[256] = "colorcorrection"; + if (strstr( texname, s_toi )) + { + // breakpoint on this if you like + GLMPRINTF(( "srgb change %d for %s", m_srgbFlipCount, texname )); + } +#endif + + // re-submit the tex unless we're stifling it + static bool s_nosrgbflips = CommandLine()->FindParm( "-glmnosrgbflips" ); + if ( !s_nosrgbflips ) + { + ResetSRGB( srgb, false ); + } + } + else + { + //GLMPRINTF(("-Z- srgb sampling conflict: NOT fixing tex %08x [%s] (srgb req: %d) because (tex-srgb-capable=%d tex-renderable=%d)", m_textures[index], m_textures[index]->m_tex->m_layout->m_layoutSummary, (int)glsamp->m_srgb, (int)srgbCapableTex, (int)renderableTex )); + // we just leave the sampler state where it is, and that's life + } +} + + +void CGLMTex::ResetSRGB( bool srgb, bool noDataWrite ) +{ + // see if requested SRGB state differs from the known one + bool wasSRGB = (m_layout->m_key.m_texFlags & kGLMTexSRGB); + GLMTexLayout *oldLayout = m_layout; // need to m_ctx->m_texLayoutTable->DelLayoutRef on this one if we flip + + if (srgb != wasSRGB) + { + // we're going to need a new layout (though the storage size should be the same - check it) + GLMTexLayoutKey newKey = m_layout->m_key; + + newKey.m_texFlags &= (~kGLMTexSRGB); // turn off that bit + newKey.m_texFlags |= srgb ? kGLMTexSRGB : 0; // turn on that bit if it should be so + + // get new layout + GLMTexLayout *newLayout = m_ctx->m_texLayoutTable->NewLayoutRef( &newKey ); + + // if SRGB requested, verify that the layout we just got can do it. + // if it can't, delete the new layout ref and bail. + if (srgb && (newLayout->m_format->m_glIntFormatSRGB == 0)) + { + Assert( !"Can't enable SRGB mode on this format" ); + m_ctx->m_texLayoutTable->DelLayoutRef( newLayout ); + return; + } + + // check sizes and fail if no match + if( newLayout->m_storageTotalSize != oldLayout->m_storageTotalSize ) + { + Assert( !"Bug: layout sizes don't match on SRGB change" ); + m_ctx->m_texLayoutTable->DelLayoutRef( newLayout ); + return; + } + + // commit to new layout + m_layout = newLayout; + m_texGLTarget = m_layout->m_key.m_texGLTarget; + + // check same size + Assert( m_layout->m_storageTotalSize == oldLayout->m_storageTotalSize ); + + Assert( newLayout != oldLayout ); + + // release old + m_ctx->m_texLayoutTable->DelLayoutRef( oldLayout ); + oldLayout = NULL; + + // force texel re-DL + + // note this messes with TMU 0 as side effect of WriteTexels + // so we save and restore the TMU 0 binding first + + // since we're likely to be called in dxabstract when it is syncing sampler state, we can't go trampling the bindings. + // a refinement would be to have each texture make a note of which TMU they're bound on, and just use that active TMU for DL instead of 0. + CGLMTex *tmu0save = m_ctx->m_samplers[0].m_pBoundTex; + + for( int face=0; face m_faceCount; face++) + { + for( int mip=0; mip m_mipCount; mip++) + { + // we're not really going to lock, we're just going to rewrite the orig data + GLMTexLockDesc desc; + + desc.m_req.m_tex = this; + desc.m_req.m_face = face; + desc.m_req.m_mip = mip; + + desc.m_sliceIndex = CalcSliceIndex( face, mip ); + + GLMTexLayoutSlice *slice = &m_layout->m_slices[ desc.m_sliceIndex ]; + + desc.m_req.m_region.xmin = desc.m_req.m_region.ymin = desc.m_req.m_region.zmin = 0; + desc.m_req.m_region.xmax = slice->m_xSize; + desc.m_req.m_region.ymax = slice->m_ySize; + desc.m_req.m_region.zmax = slice->m_zSize; + + desc.m_sliceBaseOffset = slice->m_storageOffset; // doesn't really matter... we're just pushing zeroes.. + desc.m_sliceRegionOffset = 0; + + WriteTexels( &desc, true, noDataWrite ); // write whole slice. and avoid pushing real bits if the caller requests (RT's) + } + } + + // put it back + m_ctx->BindTexToTMU( tmu0save, 0 ); + } +} +#endif + +bool CGLMTex::IsRBODirty() const +{ + return m_nLastResolvedBatchCounter != m_ctx->m_nBatchCounter; +} + +void CGLMTex::ForceRBONonDirty() +{ + m_nLastResolvedBatchCounter = m_ctx->m_nBatchCounter; +} + +void CGLMTex::ForceRBODirty() +{ + m_nLastResolvedBatchCounter = m_ctx->m_nBatchCounter - 1; +} diff --git a/togles/linuxwin/decompress.c b/togles/linuxwin/decompress.c new file mode 100644 index 00000000..eabd6893 --- /dev/null +++ b/togles/linuxwin/decompress.c @@ -0,0 +1,341 @@ +#include +#include + +/* +DXT1/DXT3/DXT5 texture decompression + +The original code is from Benjamin Dobell, see below for details. Compared to +the original this one adds DXT3 decompression, is valid C89, and is x64 +compatible as it uses fixed size integers everywhere. It also uses a different +PackRGBA order. + +--- + +Copyright (c) 2012, Matth�us G. "Anteru" Chajdas (http://anteru.net) + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- + +Copyright (C) 2009 Benjamin Dobell, Glass Echidna + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +--- +*/ +static uint32_t PackRGBA (uint8_t r, uint8_t g, uint8_t b, uint8_t a) +{ + return r | (g << 8) | (b << 16) | (a << 24); +} + +static void DecompressBlockDXT1Internal (const uint8_t* block, + uint32_t* output, + uint32_t outputStride, + int transparent0, int* simpleAlpha, int *complexAlpha, + const uint8_t* alphaValues) +{ + uint32_t temp, code; + + uint16_t color0, color1; + uint8_t r0, g0, b0, r1, g1, b1; + + int i, j; + + color0 = *(const uint16_t*)(block); + color1 = *(const uint16_t*)(block + 2); + + temp = (color0 >> 11) * 255 + 16; + r0 = (uint8_t)((temp/32 + temp)/32); + temp = ((color0 & 0x07E0) >> 5) * 255 + 32; + g0 = (uint8_t)((temp/64 + temp)/64); + temp = (color0 & 0x001F) * 255 + 16; + b0 = (uint8_t)((temp/32 + temp)/32); + + temp = (color1 >> 11) * 255 + 16; + r1 = (uint8_t)((temp/32 + temp)/32); + temp = ((color1 & 0x07E0) >> 5) * 255 + 32; + g1 = (uint8_t)((temp/64 + temp)/64); + temp = (color1 & 0x001F) * 255 + 16; + b1 = (uint8_t)((temp/32 + temp)/32); + + code = *(const uint32_t*)(block + 4); + + if (color0 > color1) { + for (j = 0; j < 4; ++j) { + for (i = 0; i < 4; ++i) { + uint32_t finalColor, positionCode; + uint8_t alpha; + + alpha = alphaValues [j*4+i]; + + finalColor = 0; + positionCode = (code >> 2*(4*j+i)) & 0x03; + + switch (positionCode) { + case 0: + finalColor = PackRGBA(r0, g0, b0, alpha); + break; + case 1: + finalColor = PackRGBA(r1, g1, b1, alpha); + break; + case 2: + finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, alpha); + break; + case 3: + finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, alpha); + break; + } + if(!alpha) + *simpleAlpha = 1; + else if(alpha<0xff) + *complexAlpha = 1; + output [j*outputStride + i] = finalColor; + } + } + } else { + for (j = 0; j < 4; ++j) { + for (i = 0; i < 4; ++i) { + uint32_t finalColor, positionCode; + uint8_t alpha; + + alpha = alphaValues [j*4+i]; + + finalColor = 0; + positionCode = (code >> 2*(4*j+i)) & 0x03; + + switch (positionCode) { + case 0: + finalColor = PackRGBA(r0, g0, b0, alpha); + break; + case 1: + finalColor = PackRGBA(r1, g1, b1, alpha); + break; + case 2: + finalColor = PackRGBA((r0+r1)/2, (g0+g1)/2, (b0+b1)/2, alpha); + break; + case 3: + if(transparent0) alpha=0; + finalColor = PackRGBA(0, 0, 0, alpha); + break; + } + + if(!alpha) + *simpleAlpha = 1; + else if(alpha<0xff) + *complexAlpha = 1; + + output [j*outputStride + i] = finalColor; + } + } + } +} + +/* +void DecompressBlockDXT1(): Decompresses one block of a DXT1 texture and stores the resulting pixels at the appropriate offset in 'image'. + +uint32_t x: x-coordinate of the first pixel in the block. +uint32_t y: y-coordinate of the first pixel in the block. +uint32_t width: width of the texture being decompressed. +const uint8_t *blockStorage: pointer to the block to decompress. +uint32_t *image: pointer to image where the decompressed pixel data should be stored. +*/ +void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width, + const uint8_t* blockStorage, + int transparent0, int* simpleAlpha, int *complexAlpha, + uint32_t* image) +{ + static const uint8_t const_alpha [] = { + 255, 255, 255, 255, + 255, 255, 255, 255, + 255, 255, 255, 255, + 255, 255, 255, 255 + }; + + DecompressBlockDXT1Internal (blockStorage, + image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, const_alpha); +} + +/* +void DecompressBlockDXT5(): Decompresses one block of a DXT5 texture and stores the resulting pixels at the appropriate offset in 'image'. + +uint32_t x: x-coordinate of the first pixel in the block. +uint32_t y: y-coordinate of the first pixel in the block. +uint32_t width: width of the texture being decompressed. +const uint8_t *blockStorage: pointer to the block to decompress. +uint32_t *image: pointer to image where the decompressed pixel data should be stored. +*/ +void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width, + const uint8_t* blockStorage, + int transparent0, int* simpleAlpha, int *complexAlpha, + uint32_t* image) +{ + uint8_t alpha0, alpha1; + const uint8_t* bits; + uint32_t alphaCode1; + uint16_t alphaCode2; + + uint16_t color0, color1; + uint8_t r0, g0, b0, r1, g1, b1; + + int i, j; + + uint32_t temp, code; + + alpha0 = *(blockStorage); + alpha1 = *(blockStorage + 1); + + bits = blockStorage + 2; + alphaCode1 = bits[2] | (bits[3] << 8) | (bits[4] << 16) | (bits[5] << 24); + alphaCode2 = bits[0] | (bits[1] << 8); + + color0 = *(const uint16_t*)(blockStorage + 8); + color1 = *(const uint16_t*)(blockStorage + 10); + + temp = (color0 >> 11) * 255 + 16; + r0 = (uint8_t)((temp/32 + temp)/32); + temp = ((color0 & 0x07E0) >> 5) * 255 + 32; + g0 = (uint8_t)((temp/64 + temp)/64); + temp = (color0 & 0x001F) * 255 + 16; + b0 = (uint8_t)((temp/32 + temp)/32); + + temp = (color1 >> 11) * 255 + 16; + r1 = (uint8_t)((temp/32 + temp)/32); + temp = ((color1 & 0x07E0) >> 5) * 255 + 32; + g1 = (uint8_t)((temp/64 + temp)/64); + temp = (color1 & 0x001F) * 255 + 16; + b1 = (uint8_t)((temp/32 + temp)/32); + + code = *(const uint32_t*)(blockStorage + 12); + + for (j = 0; j < 4; j++) { + for (i = 0; i < 4; i++) { + uint8_t finalAlpha; + int alphaCode, alphaCodeIndex; + uint8_t colorCode; + uint32_t finalColor; + + alphaCodeIndex = 3*(4*j+i); + if (alphaCodeIndex <= 12) { + alphaCode = (alphaCode2 >> alphaCodeIndex) & 0x07; + } else if (alphaCodeIndex == 15) { + alphaCode = (alphaCode2 >> 15) | ((alphaCode1 << 1) & 0x06); + } else /* alphaCodeIndex >= 18 && alphaCodeIndex <= 45 */ { + alphaCode = (alphaCode1 >> (alphaCodeIndex - 16)) & 0x07; + } + + if (alphaCode == 0) { + finalAlpha = alpha0; + } else if (alphaCode == 1) { + finalAlpha = alpha1; + } else { + if (alpha0 > alpha1) { + finalAlpha = (uint8_t)(((8-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/7); + } else { + if (alphaCode == 6) { + finalAlpha = 0; + } else if (alphaCode == 7) { + finalAlpha = 255; + } else { + finalAlpha = (uint8_t)(((6-alphaCode)*alpha0 + (alphaCode-1)*alpha1)/5); + } + } + } + + colorCode = (code >> 2*(4*j+i)) & 0x03; + finalColor = 0; + + switch (colorCode) { + case 0: + finalColor = PackRGBA(r0, g0, b0, finalAlpha); + break; + case 1: + finalColor = PackRGBA(r1, g1, b1, finalAlpha); + break; + case 2: + finalColor = PackRGBA((2*r0+r1)/3, (2*g0+g1)/3, (2*b0+b1)/3, finalAlpha); + break; + case 3: + finalColor = PackRGBA((r0+2*r1)/3, (g0+2*g1)/3, (b0+2*b1)/3, finalAlpha); + break; + } + + if(finalAlpha==0) *simpleAlpha = 1; + else if(finalAlpha<0xff) *complexAlpha = 1; + + image [i + x + (width* (y+j))] = finalColor; + } + } +} + +/* +void DecompressBlockDXT3(): Decompresses one block of a DXT3 texture and stores the resulting pixels at the appropriate offset in 'image'. + +uint32_t x: x-coordinate of the first pixel in the block. +uint32_t y: y-coordinate of the first pixel in the block. +uint32_t height: height of the texture being decompressed. +const uint8_t *blockStorage: pointer to the block to decompress. +uint32_t *image: pointer to image where the decompressed pixel data should be stored. +*/ +void DecompressBlockDXT3(uint32_t x, uint32_t y, uint32_t width, + const uint8_t* blockStorage, + int transparent0, int* simpleAlpha, int *complexAlpha, + uint32_t* image) +{ + int i; + + uint8_t alphaValues [16] = { 0 }; + + for (i = 0; i < 4; ++i) { + const uint16_t* alphaData = (const uint16_t*) (blockStorage); + + alphaValues [i*4 + 0] = (((*alphaData) >> 0) & 0xF ) * 17; + alphaValues [i*4 + 1] = (((*alphaData) >> 4) & 0xF ) * 17; + alphaValues [i*4 + 2] = (((*alphaData) >> 8) & 0xF ) * 17; + alphaValues [i*4 + 3] = (((*alphaData) >> 12) & 0xF) * 17; + + blockStorage += 2; + } + + DecompressBlockDXT1Internal (blockStorage, + image + x + (y * width), width, transparent0, simpleAlpha, complexAlpha, alphaValues); +} + +// Texture DXT1 / DXT5 compression +// Using STB "on file" library +// go there https://github.com/nothings/stb +// for more details and other libs + +#define STB_DXT_IMPLEMENTATION +#include "stb_dxt_104.h" diff --git a/togles/linuxwin/decompress.h b/togles/linuxwin/decompress.h new file mode 100644 index 00000000..e9e5da83 --- /dev/null +++ b/togles/linuxwin/decompress.h @@ -0,0 +1,19 @@ +#ifndef _GL4ES_DECOMPRESS_H_ +#define _GL4ES_DECOMPRESS_H_ + +void DecompressBlockDXT1(uint32_t x, uint32_t y, uint32_t width, + const uint8_t* blockStorage, + int transparent0, int* simpleAlpha, int *complexAlpha, + uint32_t* image); + +void DecompressBlockDXT3(uint32_t x, uint32_t y, uint32_t width, + const uint8_t* blockStorage, + int transparent0, int* simpleAlpha, int *complexAlpha, + uint32_t* image); + +void DecompressBlockDXT5(uint32_t x, uint32_t y, uint32_t width, + const uint8_t* blockStorage, + int transparent0, int* simpleAlpha, int *complexAlpha, + uint32_t* image); + +#endif // _GL4ES_DECOMPRESS_H_ diff --git a/togles/linuxwin/decompress.o b/togles/linuxwin/decompress.o new file mode 100644 index 00000000..3e88c104 Binary files /dev/null and b/togles/linuxwin/decompress.o differ diff --git a/togles/linuxwin/dx9asmtogl2.cpp b/togles/linuxwin/dx9asmtogl2.cpp new file mode 100644 index 00000000..f97d2e7f --- /dev/null +++ b/togles/linuxwin/dx9asmtogl2.cpp @@ -0,0 +1,3953 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +//------------------------------------------------------------------------------ +// DX9AsmToGL2.cpp +//------------------------------------------------------------------------------ +// Immediately include gl.h, etc. here to avoid compilation warnings. +#include +#include + +#include "togles/rendermechanism.h" +#include "tier0/dbg.h" +#include "tier1/strtools.h" +#include "tier1/utlbuffer.h" +#include "dx9asmtogl2.h" + +#include "materialsystem/IShader.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + +#ifdef POSIX +#define strcat_s( a, b, c) V_strcat( a, c, b ) +#endif + +#define DST_REGISTER 0 +#define SRC_REGISTER 1 + +// Flags to PrintUsageAndIndexToString. +#define SEMANTIC_OUTPUT 0x01 +#define SEMANTIC_INPUT 0x02 + +#define UNDECLARED_OUTPUT 0xFFFFFFFF +#define UNDECLARED_INPUT 0xFFFFFFFF + +#ifndef POSIX +#define Debugger() Assert(0) +#endif + +//#define Assert(n) if( !(n) ){ TranslationError(); } + +static char g_szShadow2D[] = + "uniform sampler2D u_ShadowMap;\n" + "#define invSize 0.001953125\n" + "#define size 512.0\n" + "vec4 _shadow2D( sampler2D u_depthTex, vec3 suv)\n" + "{\n" + "vec2 p1 = suv.xy;\n" + "vec2 p2 = suv.xy+vec2(0.0,invSize);\n" + "vec2 p3 = suv.xy+vec2(invSize,0.0);\n" + "vec2 p4 = suv.xy+vec2(invSize);\n" + "float d = texture(u_depthTex,p1).r;\n" + "float r = float(d>suv.z);\n" + "d = texture(u_depthTex,p2).r;\n" + "float r2 = float(d>suv.z);\n" + "d = texture(u_depthTex,p3).r;\n" + "float r3 = float(d>suv.z);\n" + "d = texture(u_depthTex,p4).r;\n" + "float r4 = float(d>suv.z);\n" + "p1*=size;\n" + "float a = p1.y-floor(p1.y);\n" + "float b = p1.x-floor(p1.x);\n" + "float gg = mix(mix(r,r2,a),mix(r3,r4,a),b);\n" + "return vec4(gg, gg, gg, gg);" + "}\n" + "#define shadow2D _shadow2D\n"; + +static char g_szShadow2DProj[] = + "float _shadow2DProj( vec4 projection, vec2 texel, float NdotL )\n" + "{\n" + "vec3 coord = vec3( projection.xyz / ( projection.w + 0.0005 )); // z-bias\n" + "coord.s = float( clamp( float( coord.s ), texel.x, 1.0 - texel.x ));\n" + "coord.t = float( clamp( float( coord.t ), texel.y, 1.0 - texel.y ));\n" + "coord.r = float( clamp( float( coord.r ), 0.0, 1.0 ));\n" + "return _shadow2D( u_ShadowMap, coord );\n" + "}\n" + "#define shadow2DProj _shadow2DProj\n"; + +static char *g_szVecZeros[] = { NULL, "0.0", "vec2( 0.0, 0.0 )", "vec3( 0.0, 0.0, 0.0 )", "vec4( 0.0, 0.0, 0.0, 0.0 )" }; +static char *g_szVecOnes[] = { NULL, "1.0", "vec2( 1.0, 1.0 )", "vec3( 1.0, 1.0, 1.0 )", "vec4( 1.0, 1.0, 1.0, 1.0 )" }; +static char *g_szDefaultSwizzle = "xyzw"; +static char *g_szDefaultSwizzleStrings[] = { "x", "y", "z", "w" }; +static char *g_szSamplerStrings[] = { "2D", "CUBE", "3D" }; + +static const char *g_pAtomicTempVarName = "atomic_temp_var"; +static const char *g_pTangentAttributeName = "g_tangent"; + +int __cdecl SortInts( const int *a, const int *b ) +{ + if ( *a < *b ) + return -1; + else if ( *a > *b ) + return 1; + else + return 0; +} + +void StripExtraTrailingZeros( char *pStr ) +{ + int len = (int)V_strlen( pStr ); + while ( len >= 2 && pStr[len-1] == '0' && pStr[len-2] != '.' ) + { + pStr[len-1] = 0; + --len; + } +} + +void D3DToGL::PrintToBufWithIndents( CUtlBuffer &buf, const char *pFormat, ... ) +{ + va_list marker; + va_start( marker, pFormat ); + + char szTemp[1024]; + V_vsnprintf( szTemp, sizeof( szTemp ), pFormat, marker ); + va_end( marker ); + + PrintIndentation( (char*)buf.Base(), buf.Size() ); + strcat_s( (char*)buf.Base(), buf.Size(), szTemp ); +} + +void PrintToBuf( CUtlBuffer &buf, const char *pFormat, ... ) +{ + va_list marker; + va_start( marker, pFormat ); + + char szTemp[1024]; + V_vsnprintf( szTemp, sizeof( szTemp ), pFormat, marker ); + va_end( marker ); + + strcat_s( (char*)buf.Base(), buf.Size(), szTemp ); +} + +void PrintToBuf( char *pOut, int nOutSize, const char *pFormat, ... ) +{ + int nStrlen = V_strlen( pOut ); + pOut += nStrlen; + nOutSize -= nStrlen; + + va_list marker; + va_start( marker, pFormat ); + V_vsnprintf( pOut, nOutSize, pFormat, marker ); + va_end( marker ); +} + +// Return the number of letters following the dot. +// Returns 4 if there is no dot. +// (So "r0.xy" returns 2 and "r0" returns 4). +int GetNumWriteMaskEntries( const char *pParam ) +{ + const char *pDot = strchr( pParam, '.' ); + if ( pDot ) + return V_strlen( pDot + 1 ); + else + return 4; +} + +const char* GetSwizzleDot( const char *pParam ) +{ + const char *pDot = strrchr( pParam, '.' ); + + const char *pSquareClose = strrchr( pParam, ']' ); + + if ( pSquareClose ) + { + // The test against ']' catches cases like, so we point to the last dot vc[int(va_r.x) + 29].x + if ( pDot && ( pSquareClose < pDot ) ) + return pDot; + else + return NULL; + } + + // Make sure the next character is a valid swizzle since we want to treat strings like vec4( gl_Normal, 0.0 ) as a whole param name. + if ( pDot && ( ( *(pDot+1) == 'x' ) || ( *(pDot+1) == 'y' ) || ( *(pDot+1) == 'z' ) || ( *(pDot+1) == 'w' ) || + ( *(pDot+1) == 'r' ) || ( *(pDot+1) == 'g' ) || ( *(pDot+1) == 'b' ) || ( *(pDot+1) == 'z' ) ) ) + { + return pDot; + } + + return NULL; +} + +int GetNumSwizzleComponents( const char *pParam ) +{ + // Special scalar output which won't accept a swizzle + if ( !V_stricmp( pParam, "gl_FogFragCoord" ) ) + return 1; + + // Special scalar output which won't accept a swizzle + if ( !V_stricmp( pParam, "gl_FragDepth" ) ) + return 1; + + // Special scalar output which won't accept a swizzle + if ( !V_stricmp( pParam, "a0" ) ) + return 1; + + const char *pDot = GetSwizzleDot( pParam ); + if ( pDot ) + { + pDot++; // Step over the dot + + int nNumSwizzleComponents = 0; + while ( ( *pDot == 'x' ) || ( *pDot == 'y' ) || ( *pDot == 'z' ) || ( *pDot == 'w' ) || + ( *pDot == 'r' ) || ( *pDot == 'g' ) || ( *pDot == 'b' ) || ( *pDot == 'z' ) ) + { + nNumSwizzleComponents++; + pDot++; + } + + return nNumSwizzleComponents; + } + + return 0; +} + +char GetSwizzleComponent( const char *pParam, int n ) +{ + Assert( n < 4 ); + + const char *pDot = GetSwizzleDot( pParam ); + if ( pDot ) + { + ++pDot; + int nComponents = (int)V_strlen( pDot ); + Assert( nComponents > 0 ); + + if ( n < nComponents ) + return pDot[n]; + else + return pDot[nComponents-1]; + } + + return g_szDefaultSwizzle[n]; +} + +// Replace the parameter name and leave the swizzle intact. +// So "somevar.xyz" becomes "othervar.xyz". +void ReplaceParamName( const char *pSrc, const char *pNewParamName, char *pOut, int nOutLen ) +{ + // Start with the new parameter name. + V_strncpy( pOut, pNewParamName, nOutLen ); + + // Now add the swizzle if necessary. + const char *pDot = GetSwizzleDot( pSrc ); + if ( pDot ) + { + V_strncat( pOut, pDot, nOutLen ); + } +} + +void GetParamNameWithoutSwizzle( const char *pParam, char *pOut, int nOutLen ) +{ + char *pParamStart = (char *) pParam; + const char *pDot = GetSwizzleDot( pParam ); // dot followed by valid swizzle characters + bool bAbsWrapper = false; + + // Check for abs() or -abs() wrapper and strip it off during the fixup + if ( !V_strncmp( pParam, "abs(", 4 ) || !V_strncmp( pParam, "-abs(", 5 ) ) + { + const char *pOpenParen = strchr( pParam, '(' ); // FIRST opening paren + const char *pClosingParen = strrchr( pParam, ')' ); // LAST closing paren + + Assert ( pOpenParen && pClosingParen ); + pClosingParen; // hush compiler + + pParamStart = (char *) pOpenParen; + pParamStart++; + bAbsWrapper = true; + } + + if ( pDot ) + { + int nToCopy = MIN( nOutLen-1, pDot - pParamStart ); + memcpy( pOut, pParamStart, nToCopy ); + pOut[nToCopy] = 0; + } + else + { + V_strncpy( pOut, pParamStart, bAbsWrapper ? nOutLen - 1 : nOutLen ); + } +} + +bool DoParamNamesMatch( const char *pParam1, const char *pParam2 ) +{ + char szTemp[2][256]; + GetParamNameWithoutSwizzle( pParam1, szTemp[0], sizeof( szTemp[0] ) ); + GetParamNameWithoutSwizzle( pParam2, szTemp[1], sizeof( szTemp[1] ) ); + return ( V_stricmp( szTemp[0], szTemp[1] ) == 0 ); +} + + + +// Extract the n'th component of the swizzle mask. +// If n would exceed the length of the swizzle mask, then it looks up into "xyzw". +void WriteParamWithSingleMaskEntry( const char *pParam, int n, char *pOut, int nOutLen ) +{ + bool bCloseParen = false; + if ( !V_strncmp( pParam, "-abs(", 5 ) ) + { + V_strcpy( pOut, "-abs(" ); + bCloseParen = true; + + pOut += 5; nOutLen -= 5; + } + else if ( !V_strncmp( pParam, "abs(", 4 ) ) + { + V_strcpy( pOut, "abs(" ); + bCloseParen = true; + + pOut += 4; nOutLen -= 4; + } + + GetParamNameWithoutSwizzle( pParam, pOut, nOutLen ); + PrintToBuf( pOut, nOutLen, "." ); + PrintToBuf( pOut, nOutLen, "%c", GetSwizzleComponent( pParam, n ) ); + + if ( bCloseParen ) + { + PrintToBuf( pOut, nOutLen, ")" ); + } +} + + +float uint32ToFloat( uint32 dw ) +{ + return *((float*)&dw); +} + +CUtlString EnsureNumSwizzleComponents( const char *pSrcRegisterName, int nComponents ) +{ + int nExisting = GetNumSwizzleComponents( pSrcRegisterName ); + if ( nExisting == nComponents ) + return pSrcRegisterName; + + bool bAbsWrapper = false; // Parameter wrapped in an abs() + bool bAbsNegative = false; // -abs() + char szSrcRegister[128]; + V_strncpy( szSrcRegister, pSrcRegisterName, sizeof(szSrcRegister) ); + + // Check for abs() or -abs() wrapper and strip it off during the fixup + if ( !V_strncmp( pSrcRegisterName, "abs(", 4 ) || !V_strncmp( pSrcRegisterName, "-abs(", 5 ) ) + { + bAbsWrapper = true; + bAbsNegative = pSrcRegisterName[0] == '-'; + + const char *pOpenParen = strchr( pSrcRegisterName, '(' ); // FIRST opening paren + const char *pClosingParen = strrchr( pSrcRegisterName, ')' ); // LAST closing paren + + Assert ( pOpenParen && pClosingParen ); // If we start with abs( and don't get both parens, something is very wrong + + // Copy out just the register name with no abs() + int nRegNameLength = pClosingParen - pOpenParen - 1; + V_strncpy( szSrcRegister, pOpenParen+1, nRegNameLength + 1 ); // Kind of a weird function...copy more than you need and slam the last char to NULL-terminate + } + + char szReg[256]; + GetParamNameWithoutSwizzle( szSrcRegister, szReg, sizeof( szReg ) ); + if ( nComponents == 0 ) + return szReg; + + PrintToBuf( szReg, sizeof( szReg ), "." ); + if ( nExisting > nComponents ) + { + // DX ASM will sometimes have statements like "NRM r0.xyz, r1.yzww", where it just doesn't use the last part of r1. So we won't either. + for ( int i=0; i < nComponents; i++ ) + { + PrintToBuf( szReg, sizeof( szReg ), "%c", GetSwizzleComponent( szSrcRegister, i ) ); + } + } + else + { + if ( nExisting == 0 ) + { + // We've got something like r0 and need N more components, so add as much of "xyzw" is needed. + for ( int i=0; i < nComponents; i++ ) + PrintToBuf( szReg, sizeof( szReg ), "%c", g_szDefaultSwizzle[i] ); + } + else + { + // We've got something like r0.x and need N more components, so replicate the X so it looks like r0.xxx + V_strncpy( szReg, szSrcRegister, sizeof( szReg ) ); + char cLast = szSrcRegister[ V_strlen( szSrcRegister ) - 1 ]; + for ( int i=nExisting; i < nComponents; i++ ) + { + PrintToBuf( szReg, sizeof( szReg ), "%c", cLast ); + } + } + } + + if ( bAbsWrapper ) + { + char szTemp[128]; + V_strncpy( szTemp, szReg, sizeof(szTemp) ); + V_snprintf( szReg, sizeof( szReg ), "%sabs(%s)", bAbsNegative ? "-" : "", szTemp ) ; + } + + return szReg; +} + +static void TranslationError() +{ + GLMDebugPrintf( "D3DToGL: GLSL translation error!\n" ); + DebuggerBreakIfDebugging(); + + Error( "D3DToGL: GLSL translation error!\n" ); +} + +D3DToGL::D3DToGL() +{ +} + +uint32 D3DToGL::GetNextToken( void ) +{ + uint32 dwToken = *m_pdwNextToken; + m_pdwNextToken++; + return dwToken; +} + +void D3DToGL::SkipTokens( uint32 numToSkip ) +{ + m_pdwNextToken += numToSkip; +} + +uint32 D3DToGL::Opcode( uint32 dwToken ) +{ + return ( dwToken & D3DSI_OPCODE_MASK ); +} + +uint32 D3DToGL::OpcodeSpecificData (uint32 dwToken) +{ + return ( ( dwToken & D3DSP_OPCODESPECIFICCONTROL_MASK ) >> D3DSP_OPCODESPECIFICCONTROL_SHIFT ); +} + +uint32 D3DToGL::TextureType ( uint32 dwToken ) +{ + return ( dwToken & D3DSP_TEXTURETYPE_MASK ); // Note this one doesn't shift due to weird D3DSAMPLER_TEXTURE_TYPE enum +} + + + +// Print GLSL intrinsic corresponding to particular instruction +bool D3DToGL::OpenIntrinsic( uint32 inst, char* buff, int nBufLen, uint32 destDimension, uint32 nArgumentDimension ) +{ + // Some GLSL intrinsics need type conversion, which we do in this routine + // As a result, the caller must sometimes close both parentheses, not just one + bool bDoubleClose = false; + + if ( nArgumentDimension == 0 ) + { + nArgumentDimension = 4; + } + + switch ( inst ) + { + case D3DSIO_RSQ: + V_snprintf( buff, nBufLen, "inversesqrt( " ); + break; + case D3DSIO_DP3: + case D3DSIO_DP4: + if ( destDimension == 1 ) + { + V_snprintf( buff, nBufLen, "dot( " ); + } + else + { + if ( !destDimension ) + destDimension = 4; + V_snprintf( buff, nBufLen, "vec%d( dot( ", destDimension ); + bDoubleClose = true; + } + break; + case D3DSIO_MIN: + V_snprintf( buff, nBufLen, "min( " ); + break; + case D3DSIO_MAX: + V_snprintf( buff, nBufLen, "max( " ); + break; + case D3DSIO_SLT: + if ( nArgumentDimension == 1 ) + { + V_snprintf( buff, nBufLen, "float( " ); // lessThan doesn't have a scalar version + } + else + { + Assert( nArgumentDimension > 1 ); + V_snprintf( buff, nBufLen, "vec%d( lessThan( ", nArgumentDimension ); + bDoubleClose = true; + } + break; + case D3DSIO_SGE: + if ( nArgumentDimension == 1 ) + { + V_snprintf( buff, nBufLen, "float( " ); // greaterThanEqual doesn't have a scalar version + } + else + { + Assert( nArgumentDimension > 1 ); + V_snprintf( buff, nBufLen, "vec%d( greaterThanEqual( ", nArgumentDimension ); + bDoubleClose = true; + } + break; + case D3DSIO_EXP: + V_snprintf( buff, nBufLen, "exp( " ); // exp2 ? + break; + case D3DSIO_LOG: + V_snprintf( buff, nBufLen, "log( " ); // log2 ? + break; + case D3DSIO_LIT: + TranslationError(); + V_snprintf( buff, nBufLen, "lit( " ); // gonna have to write this one + break; + case D3DSIO_DST: + V_snprintf( buff, nBufLen, "dst( " ); // gonna have to write this one + break; + case D3DSIO_LRP: + Assert( !m_bVertexShader ); + V_snprintf( buff, nBufLen, "mix( " ); + break; + case D3DSIO_FRC: + V_snprintf( buff, nBufLen, "fract( " ); + break; + case D3DSIO_M4x4: + TranslationError(); + V_snprintf( buff, nBufLen, "m4x4" ); + break; + case D3DSIO_M4x3: + case D3DSIO_M3x4: + case D3DSIO_M3x3: + case D3DSIO_M3x2: + case D3DSIO_CALL: + case D3DSIO_CALLNZ: + case D3DSIO_LOOP: + case D3DSIO_RET: + case D3DSIO_ENDLOOP: + case D3DSIO_LABEL: + case D3DSIO_DCL: + TranslationError(); + break; + case D3DSIO_POW: + V_snprintf( buff, nBufLen, "pow( " ); + break; + case D3DSIO_CRS: + V_snprintf( buff, nBufLen, "cross( " ); + break; + case D3DSIO_SGN: + TranslationError(); + V_snprintf( buff, nBufLen, "sign( " ); + break; + case D3DSIO_ABS: + V_snprintf( buff, nBufLen, "abs( " ); + break; + case D3DSIO_NRM: + TranslationError(); + V_snprintf( buff, nBufLen, "normalize( " ); + break; + case D3DSIO_SINCOS: + TranslationError(); + V_snprintf( buff, nBufLen, "sincos( " ); // gonna have to write this one + break; + case D3DSIO_REP: + case D3DSIO_ENDREP: + case D3DSIO_IF: + case D3DSIO_IFC: + case D3DSIO_ELSE: + case D3DSIO_ENDIF: + case D3DSIO_BREAK: + case D3DSIO_BREAKC: // TODO: these are the reason we even need GLSL...gotta make these work + TranslationError(); + break; + case D3DSIO_DEFB: + case D3DSIO_DEFI: + TranslationError(); + break; + case D3DSIO_TEXCOORD: + V_snprintf( buff, nBufLen, "texcoord" ); + break; + case D3DSIO_TEXKILL: + V_snprintf( buff, nBufLen, "kill( " ); // wrap the discard instruction? + break; + case D3DSIO_TEX: + TranslationError(); + V_snprintf( buff, nBufLen, "TEX" ); // We shouldn't get here + break; + case D3DSIO_TEXBEM: + case D3DSIO_TEXBEML: + case D3DSIO_TEXREG2AR: + case D3DSIO_TEXREG2GB: + case D3DSIO_TEXM3x2PAD: + case D3DSIO_TEXM3x2TEX: + case D3DSIO_TEXM3x3PAD: + case D3DSIO_TEXM3x3TEX: + case D3DSIO_TEXM3x3SPEC: + case D3DSIO_TEXM3x3VSPEC: + TranslationError(); + break; + case D3DSIO_EXPP: + V_snprintf( buff, nBufLen, "exp( " ); + break; + case D3DSIO_LOGP: + V_snprintf( buff, nBufLen, "log( " ); + break; + case D3DSIO_CND: + TranslationError(); + break; + case D3DSIO_DEF: + TranslationError(); + V_snprintf( buff, nBufLen, "DEF" ); + break; + case D3DSIO_TEXREG2RGB: + case D3DSIO_TEXDP3TEX: + case D3DSIO_TEXM3x2DEPTH: + case D3DSIO_TEXDP3: + case D3DSIO_TEXM3x3: + TranslationError(); + break; + case D3DSIO_TEXDEPTH: + V_snprintf( buff, nBufLen, "texdepth" ); + break; + case D3DSIO_CMP: + TranslationError(); + Assert( !m_bVertexShader ); + V_snprintf( buff, nBufLen, "CMP" ); + break; + case D3DSIO_BEM: + TranslationError(); + break; + case D3DSIO_DP2ADD: + TranslationError(); + break; + case D3DSIO_DSX: + case D3DSIO_DSY: + TranslationError(); + break; + case D3DSIO_TEXLDD: + V_snprintf( buff, nBufLen, "texldd" ); + break; + case D3DSIO_SETP: + TranslationError(); + break; + case D3DSIO_TEXLDL: + V_snprintf( buff, nBufLen, "texldl" ); + break; + case D3DSIO_BREAKP: + case D3DSIO_PHASE: + TranslationError(); + break; + } + + return bDoubleClose; +} + + +const char* D3DToGL::GetGLSLOperatorString( uint32 inst ) +{ + if ( inst == D3DSIO_ADD ) + return "+"; + else if ( inst == D3DSIO_SUB ) + return "-"; + else if ( inst == D3DSIO_MUL ) + return "*"; + + Error( "GetGLSLOperatorString: unknown operator" ); + return "zzzz"; +} + + +// Print ASM opcode +void D3DToGL::PrintOpcode( uint32 inst, char* buff, int nBufLen ) +{ + switch ( inst ) + { + case D3DSIO_NOP: + V_snprintf( buff, nBufLen, "NOP" ); + TranslationError(); + break; + case D3DSIO_MOV: + V_snprintf( buff, nBufLen, "MOV" ); + break; + case D3DSIO_ADD: + V_snprintf( buff, nBufLen, "ADD" ); + break; + case D3DSIO_SUB: + V_snprintf( buff, nBufLen, "SUB" ); + break; + case D3DSIO_MAD: + V_snprintf( buff, nBufLen, "MAD" ); + break; + case D3DSIO_MUL: + V_snprintf( buff, nBufLen, "MUL" ); + break; + case D3DSIO_RCP: + V_snprintf( buff, nBufLen, "RCP" ); + break; + case D3DSIO_RSQ: + V_snprintf( buff, nBufLen, "RSQ" ); + break; + case D3DSIO_DP3: + V_snprintf( buff, nBufLen, "DP3" ); + break; + case D3DSIO_DP4: + V_snprintf( buff, nBufLen, "DP4" ); + break; + case D3DSIO_MIN: + V_snprintf( buff, nBufLen, "MIN" ); + break; + case D3DSIO_MAX: + V_snprintf( buff, nBufLen, "MAX" ); + break; + case D3DSIO_SLT: + V_snprintf( buff, nBufLen, "SLT" ); + break; + case D3DSIO_SGE: + V_snprintf( buff, nBufLen, "SGE" ); + break; + case D3DSIO_EXP: + V_snprintf( buff, nBufLen, "EX2" ); + break; + case D3DSIO_LOG: + V_snprintf( buff, nBufLen, "LG2" ); + break; + case D3DSIO_LIT: + V_snprintf( buff, nBufLen, "LIT" ); + break; + case D3DSIO_DST: + V_snprintf( buff, nBufLen, "DST" ); + break; + case D3DSIO_LRP: + Assert( !m_bVertexShader ); + V_snprintf( buff, nBufLen, "LRP" ); + break; + case D3DSIO_FRC: + V_snprintf( buff, nBufLen, "FRC" ); + break; + case D3DSIO_M4x4: + V_snprintf( buff, nBufLen, "m4x4" ); + break; + case D3DSIO_M4x3: + case D3DSIO_M3x4: + case D3DSIO_M3x3: + case D3DSIO_M3x2: + case D3DSIO_CALL: + case D3DSIO_CALLNZ: + case D3DSIO_LOOP: + case D3DSIO_RET: + case D3DSIO_ENDLOOP: + case D3DSIO_LABEL: + TranslationError(); + break; + case D3DSIO_DCL: + V_snprintf( buff, nBufLen, "DCL" ); + break; + case D3DSIO_POW: + V_snprintf( buff, nBufLen, "POW" ); + break; + case D3DSIO_CRS: + V_snprintf( buff, nBufLen, "XPD" ); + break; + case D3DSIO_SGN: + TranslationError(); + V_snprintf( buff, nBufLen, "SGN" ); + break; + case D3DSIO_ABS: + V_snprintf( buff, nBufLen, "ABS" ); + break; + case D3DSIO_NRM: + TranslationError(); + V_snprintf( buff, nBufLen, "NRM" ); + break; + case D3DSIO_SINCOS: + Assert( !m_bVertexShader ); + V_snprintf( buff, nBufLen, "SCS" ); + break; + case D3DSIO_REP: + case D3DSIO_ENDREP: + case D3DSIO_IF: + case D3DSIO_IFC: + case D3DSIO_ELSE: + case D3DSIO_ENDIF: + case D3DSIO_BREAK: + case D3DSIO_BREAKC: + TranslationError(); + break; + case D3DSIO_MOVA: + Assert( m_bVertexShader ); + V_snprintf( buff, nBufLen, "MOV" ); // We're always moving into a temp instead, so this is MOV instead of ARL + break; + case D3DSIO_DEFB: + case D3DSIO_DEFI: + TranslationError(); + break; + case D3DSIO_TEXCOORD: + V_snprintf( buff, nBufLen, "texcoord" ); + break; + case D3DSIO_TEXKILL: + V_snprintf( buff, nBufLen, "KIL" ); + break; + case D3DSIO_TEX: + V_snprintf( buff, nBufLen, "TEX" ); + break; + case D3DSIO_TEXBEM: + case D3DSIO_TEXBEML: + case D3DSIO_TEXREG2AR: + case D3DSIO_TEXREG2GB: + case D3DSIO_TEXM3x2PAD: + case D3DSIO_TEXM3x2TEX: + case D3DSIO_TEXM3x3PAD: + case D3DSIO_TEXM3x3TEX: + case D3DSIO_TEXM3x3SPEC: + case D3DSIO_TEXM3x3VSPEC: + TranslationError(); + break; + case D3DSIO_EXPP: + V_snprintf( buff, nBufLen, "EXP" ); + break; + case D3DSIO_LOGP: + V_snprintf( buff, nBufLen, "LOG" ); + break; + case D3DSIO_CND: + TranslationError(); + break; + case D3DSIO_DEF: + V_snprintf( buff, nBufLen, "DEF" ); + break; + case D3DSIO_TEXREG2RGB: + case D3DSIO_TEXDP3TEX: + case D3DSIO_TEXM3x2DEPTH: + case D3DSIO_TEXDP3: + case D3DSIO_TEXM3x3: + TranslationError(); + break; + case D3DSIO_TEXDEPTH: + V_snprintf( buff, nBufLen, "texdepth" ); + break; + case D3DSIO_CMP: + Assert( !m_bVertexShader ); + V_snprintf( buff, nBufLen, "CMP" ); + break; + case D3DSIO_BEM: + TranslationError(); + break; + case D3DSIO_DP2ADD: + TranslationError(); + break; + case D3DSIO_DSX: + case D3DSIO_DSY: + TranslationError(); + break; + case D3DSIO_TEXLDD: + V_snprintf( buff, nBufLen, "texldd" ); + break; + case D3DSIO_SETP: + TranslationError(); + break; + case D3DSIO_TEXLDL: + V_snprintf( buff, nBufLen, "texldl" ); + break; + case D3DSIO_BREAKP: + case D3DSIO_PHASE: + TranslationError(); + break; + } +} + +CUtlString D3DToGL::GetUsageAndIndexString( uint32 dwToken, int fSemanticFlags ) +{ + char szTemp[1024]; + PrintUsageAndIndexToString( dwToken, szTemp, sizeof( szTemp ), fSemanticFlags ); + return szTemp; +} + +//------------------------------------------------------------------------------ +// Helper function which prints ASCII representation of usage-usageindex pair to string +// +// Strictly used by vertex shaders +// not used any more now that we have attribmap metadata +//------------------------------------------------------------------------------ +void D3DToGL::PrintUsageAndIndexToString( uint32 dwToken, char* strUsageUsageIndexName, int nBufLen, int fSemanticFlags ) +{ + uint32 dwUsage = ( dwToken & D3DSP_DCL_USAGE_MASK ); + uint32 dwUsageIndex = ( dwToken & D3DSP_DCL_USAGEINDEX_MASK ) >> D3DSP_DCL_USAGEINDEX_SHIFT; + + switch ( dwUsage ) + { + case D3DDECLUSAGE_POSITION: + if ( m_bVertexShader ) + { + if ( fSemanticFlags & SEMANTIC_OUTPUT ) + V_snprintf( strUsageUsageIndexName, nBufLen, "vTempPos" ); // effectively gl_Position + else + V_snprintf( strUsageUsageIndexName, nBufLen, "gl_Vertex" ); + } + else + { + // .xy = position in viewport coordinates + // .z = depth + V_snprintf( strUsageUsageIndexName, nBufLen, "gl_FragCoord" ); + } + + break; + case D3DDECLUSAGE_BLENDWEIGHT: + V_snprintf( strUsageUsageIndexName, nBufLen, "vertex.attrib[1]" ); // "vertex.attrib[12]" ); // or [1] + break; + case D3DDECLUSAGE_BLENDINDICES: + V_snprintf( strUsageUsageIndexName, nBufLen, "vertex.attrib[13]" ); // "vertex.attrib[13]" ); // or [ 7 ] + break; + case D3DDECLUSAGE_NORMAL: + V_snprintf( strUsageUsageIndexName, nBufLen, "vec4( gl_Normal, 0.0 )" ); + break; + case D3DDECLUSAGE_PSIZE: + TranslationError(); + V_snprintf( strUsageUsageIndexName, nBufLen, "_psize" ); // no analog + break; + case D3DDECLUSAGE_TEXCOORD: + V_snprintf( strUsageUsageIndexName, nBufLen, "oT%d", dwUsageIndex ); + break; + case D3DDECLUSAGE_TANGENT: + + NoteTangentInputUsed(); + V_strncpy( strUsageUsageIndexName, g_pTangentAttributeName, nBufLen ); + + break; + case D3DDECLUSAGE_BINORMAL: + V_snprintf( strUsageUsageIndexName, nBufLen, "vertex.attrib[14]" ); // aka texc[6] + break; +// case D3DDECLUSAGE_TESSFACTOR: +// TranslationError(); +// V_snprintf( strUsageUsageIndexName, nBufLen, "_position" ); // no analog +// break; +// case D3DDECLUSAGE_POSITIONT: +// TranslationError(); +// V_snprintf( strUsageUsageIndexName, nBufLen, "_positiont" ); // no analog +// break; + case D3DDECLUSAGE_COLOR: + + Assert( dwUsageIndex <= 1 ); +// if ( fSemanticFlags & SEMANTIC_OUTPUT ) +// V_snprintf( strUsageUsageIndexName, nBufLen, dwUsageIndex != 0 ? "gl_BackColor" : "gl_FrontColor" ); +// else + V_snprintf( strUsageUsageIndexName, nBufLen, dwUsageIndex != 0 ? "_gl_FrontSecondaryColor" : "_gl_FrontColor" ); + break; + case D3DDECLUSAGE_FOG: + TranslationError(); + break; + case D3DDECLUSAGE_DEPTH: + TranslationError(); + V_snprintf( strUsageUsageIndexName, nBufLen, "_depth" ); // no analog + break; + case D3DDECLUSAGE_SAMPLE: + TranslationError(); + V_snprintf( strUsageUsageIndexName, nBufLen, "_sample" ); // no analog + break; + default: + Debugger(); + break; + } +} + +uint32 D3DToGL::GetRegType( uint32 dwRegToken ) +{ + return ( ( dwRegToken & D3DSP_REGTYPE_MASK2 ) >> D3DSP_REGTYPE_SHIFT2 ) | ( ( dwRegToken & D3DSP_REGTYPE_MASK ) >> D3DSP_REGTYPE_SHIFT ); +} + +void D3DToGL::PrintIndentation( char *pBuf, int nBufLen ) +{ + for( int i=0; i 5 && V_strcmp( &pRegister[nLen-5], ".xyzw" ) == 0 ) + pRegister[nLen-5] = 0; +} + + +// This returns 0 for x, 1 for y, 2 for z, and 3 for w. +int GetSwizzleComponentVectorIndex( char chMask ) +{ + if ( chMask == 'x' ) + return 0; + else if ( chMask == 'y' ) + return 1; + else if ( chMask == 'z' ) + return 2; + else if ( chMask == 'w' ) + return 3; + + Error( "GetSwizzleComponentVectorIndex( '%c' ) - invalid parameter.\n", chMask ); + return 0; +} + + +// GLSL needs the # of src masks to match the dest write mask. +// +// So this: +// r0.xy = r1 + r2; +// becomes: +// r0.xy = r1.xy + r2.xy; +// +// +// Also, and this is the trickier one: GLSL reads the source registers from their first component on +// whereas D3D reads them as referenced in the dest register mask! +// +// So this code in D3D: +// r0.yz = c0.x + c1.wxyz +// Really means: +// r0.y = c0.x + c1.x +// r0.z = c0.x + c1.y +// So we translate it to this in GLSL: +// r0.yz = c0.xx + c1.wx +// r0.yz = c0.xx + c1.xy +// +CUtlString D3DToGL::FixGLSLSwizzle( const char *pDestRegisterName, const char *pSrcRegisterName ) +{ + bool bAbsWrapper = false; // Parameter wrapped in an abs() + bool bAbsNegative = false; // -abs() + char szSrcRegister[128]; + V_strncpy( szSrcRegister, pSrcRegisterName, sizeof(szSrcRegister) ); + + // Check for abs() or -abs() wrapper and strip it off during the fixup + if ( !V_strncmp( pSrcRegisterName, "abs(", 4 ) || !V_strncmp( pSrcRegisterName, "-abs(", 5 ) ) + { + bAbsWrapper = true; + bAbsNegative = pSrcRegisterName[0] == '-'; + + const char *pOpenParen = strchr( pSrcRegisterName, '(' ); // FIRST opening paren + const char *pClosingParen = strrchr( pSrcRegisterName, ')' ); // LAST closing paren + + Assert ( pOpenParen && pClosingParen ); // If we start with abs( and don't get both parens, something is very wrong + + // Copy out just the register name with no abs() + int nRegNameLength = pClosingParen - pOpenParen - 1; + V_strncpy( szSrcRegister, pOpenParen+1, nRegNameLength + 1 ); // Kind of a weird function...copy more than you need and slam the last char to NULL-terminate + + } + + int nSwizzlesInDest = GetNumSwizzleComponents( pDestRegisterName ); + if ( nSwizzlesInDest == 0 ) + nSwizzlesInDest = 4; + + char szFixedSrcRegister[128]; + GetParamNameWithoutSwizzle( szSrcRegister, szFixedSrcRegister, sizeof( szFixedSrcRegister ) ); + V_strncat( szFixedSrcRegister, ".", sizeof( szFixedSrcRegister ) ); + for ( int i=0; i < nSwizzlesInDest; i++ ) + { + char chDestWriteMask = GetSwizzleComponent( pDestRegisterName, i ); + int nVectorIndex = GetSwizzleComponentVectorIndex( chDestWriteMask ); + + char ch[2]; + ch[0] = GetSwizzleComponent( szSrcRegister, nVectorIndex ); + ch[1] = 0; + V_strncat( szFixedSrcRegister, ch, sizeof( szFixedSrcRegister ) ); + } + + SimplifyFourParamRegister( szFixedSrcRegister ); + + if ( bAbsWrapper ) + { + char szTempSrcRegister[128]; + V_strncpy( szTempSrcRegister, szFixedSrcRegister, sizeof(szTempSrcRegister) ); + V_snprintf( szFixedSrcRegister, sizeof( szFixedSrcRegister ), "%sabs(%s)", bAbsNegative ? "-" : "", szTempSrcRegister ) ; + } + + return szFixedSrcRegister; +} + +// Weird encoding...bits are split apart in the dwToken +inline uint32 GetRegTypeFromToken( uint32 dwToken ) +{ + return ( ( dwToken & D3DSP_REGTYPE_MASK2 ) >> D3DSP_REGTYPE_SHIFT2 ) | ( ( dwToken & D3DSP_REGTYPE_MASK ) >> D3DSP_REGTYPE_SHIFT ); +} + +void D3DToGL::FlagIndirectRegister( uint32 dwToken, int *pARLDestReg ) +{ + if ( !pARLDestReg ) + return; + + switch ( dwToken & D3DVS_SWIZZLE_MASK & D3DVS_X_W ) + { + case D3DVS_X_X: + *pARLDestReg = ARL_DEST_X; + break; + case D3DVS_X_Y: + *pARLDestReg = ARL_DEST_Y; + break; + case D3DVS_X_Z: + *pARLDestReg = ARL_DEST_Z; + break; + case D3DVS_X_W: + *pARLDestReg = ARL_DEST_W; + break; + } +} + + +//------------------------------------------------------------------------------ +// PrintParameterToString() +// +// Helper function which prints ASCII representation of passed Parameter dwToken +// to string. Token defines parameter details. The dwSourceOrDest parameter says +// whether or not this is a source or destination register +//------------------------------------------------------------------------------ +void D3DToGL::PrintParameterToString ( uint32 dwToken, uint32 dwSourceOrDest, char *pRegisterName, int nBufLen, bool bForceScalarSource, int *pARLDestReg ) +{ + char buff[32]; + bool bAllowWriteMask = true; + bool bAllowSwizzle = true; + + uint32 dwRegNum = dwToken & D3DSP_REGNUM_MASK; + + uint32 dwRegType, dwSwizzle; + uint32 dwSrcModifier = D3DSPSM_NONE; + + // Clear string to zero length + pRegisterName[ 0 ] = 0; + + dwRegType = GetRegTypeFromToken( dwToken ); + + // If this is a dest register + if ( dwSourceOrDest == DST_REGISTER ) + { + // Instruction modifiers + if ( dwToken & D3DSPDM_PARTIALPRECISION ) + { +// strcat_s( pRegisterName, nBufLen, "_pp" ); + } + + if ( dwToken & D3DSPDM_MSAMPCENTROID) + { +// strcat_s( pRegisterName, nBufLen, "_centroid" ); + } + } + + // If this is a source register + if ( dwSourceOrDest == SRC_REGISTER ) + { + dwSrcModifier = dwToken & D3DSP_SRCMOD_MASK; + + // If there are any source modifiers, check to see if they're at + // least partially "prefix" and prepend appropriately + if ( dwSrcModifier != D3DSPSM_NONE ) + { + switch ( dwSrcModifier ) + { + // These four start with just minus... (some may result in "postfix" notation as well later on) + case D3DSPSM_NEG: // negate + strcat_s( pRegisterName, nBufLen, "-" ); + break; + case D3DSPSM_BIASNEG: // bias and negate + case D3DSPSM_SIGNNEG: // sign and negate + case D3DSPSM_X2NEG: // *2 and negate + TranslationError(); + strcat_s( pRegisterName, nBufLen, "-" ); + break; + case D3DSPSM_COMP: // complement + TranslationError(); + strcat_s( pRegisterName, nBufLen, "1-" ); + break; + case D3DSPSM_ABS: // abs() + strcat_s( pRegisterName, nBufLen, "abs(" ); + + break; + case D3DSPSM_ABSNEG: // -abs() + strcat_s( pRegisterName, nBufLen, "-abs(" ); + + break; + case D3DSPSM_NOT: // for predicate register: "!p0" + TranslationError(); + strcat_s( pRegisterName, nBufLen, "!" ); + break; + } + } + } + + // Register name (from type and number) + switch ( dwRegType ) + { + case D3DSPR_TEMP: + V_snprintf( buff, sizeof( buff ), "r%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + m_dwTempUsageMask |= 0x00000001 << dwRegNum; // Keep track of the use of this temp + break; + case D3DSPR_INPUT: + if ( !m_bVertexShader && ( dwSourceOrDest == SRC_REGISTER ) ) + { + if ( m_dwMajorVersion == 3 ) + { + V_snprintf( buff, sizeof( buff ), "oTempT%d", dwRegNum ); + } + else + { + V_snprintf( buff, sizeof( buff ), dwRegNum == 0 ? "_gl_FrontColor" : "_gl_FrontSecondaryColor" ); + } + strcat_s( pRegisterName, nBufLen, buff ); + } + else + { + V_snprintf( buff, sizeof( buff ), "v%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + } + break; + case D3DSPR_CONST: + if ( m_bConstantRegisterDefined[dwRegNum] ) + { + char szConstantRegName[3]; + if ( m_bVertexShader ) + { + V_snprintf( szConstantRegName, 3, "vd" ); + } + else + { + V_snprintf( szConstantRegName, 3, "pd" ); + } + + // Put defined constants into their own namespace "d" + V_snprintf( buff, sizeof( buff ), "%s%d", szConstantRegName, dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + } + else if ( dwToken & D3DSHADER_ADDRESSMODE_MASK ) // Indirect addressing (e.g. skinning in a vertex shader) + { + char szConstantRegName[16]; + if ( m_bVertexShader ) + { + V_snprintf( szConstantRegName, 3, "vc" ); + } + else // No indirect addressing in PS, this shouldn't happen + { + TranslationError(); + V_snprintf( szConstantRegName, 3, "pc" ); + } + + if ( ( m_bGenerateBoneUniformBuffer ) && ( dwRegNum >= DXABSTRACT_VS_FIRST_BONE_SLOT ) ) + { + if( dwRegNum < DXABSTRACT_VS_LAST_BONE_SLOT ) + { + dwRegNum -= DXABSTRACT_VS_FIRST_BONE_SLOT; + V_strcpy( szConstantRegName, "vcbones" ); + + m_nHighestBoneRegister = ( DXABSTRACT_VS_PARAM_SLOTS - 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT; + } + else + { + dwRegNum -= ( DXABSTRACT_VS_LAST_BONE_SLOT + 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT; + m_nHighestRegister = m_bGenerateBoneUniformBuffer ? ( ( DXABSTRACT_VS_PARAM_SLOTS - 1 ) - ( ( DXABSTRACT_VS_LAST_BONE_SLOT + 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT ) ): ( DXABSTRACT_VS_PARAM_SLOTS - 1 ); + } + } + else + { + m_nHighestRegister = m_bGenerateBoneUniformBuffer ? ( ( DXABSTRACT_VS_PARAM_SLOTS - 1 ) - ( ( DXABSTRACT_VS_LAST_BONE_SLOT + 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT ) ): ( DXABSTRACT_VS_PARAM_SLOTS - 1 ); + } + + // Index into single pc/vc[] register array with relative addressing + int nDstReg = -1; + FlagIndirectRegister( GetNextToken(), &nDstReg ); + if ( pARLDestReg ) + *pARLDestReg = nDstReg; + + Assert( nDstReg != ARL_DEST_NONE ); + int nSrcSwizzle = 'x'; + if ( nDstReg == ARL_DEST_Y ) + nSrcSwizzle = 'y'; + else if ( nDstReg == ARL_DEST_Z ) + nSrcSwizzle = 'z'; + else if ( nDstReg == ARL_DEST_W ) + nSrcSwizzle = 'w'; + V_snprintf( buff, sizeof( buff ), "%s[int(va_r.%c) + %d]", szConstantRegName, nSrcSwizzle, dwRegNum ); + + strcat_s( pRegisterName, nBufLen, buff ); + + // Must allow swizzling, otherwise this example doesn't compile right: mad r3.xyz, c27[a0.w].w, r3, r7 + //bAllowSwizzle = false; + } + else // Direct addressing of constant array + { + char szConstantRegName[16]; + V_snprintf( szConstantRegName, 3, m_bVertexShader ? "vc" : "pc" ); + + if ( ( m_bGenerateBoneUniformBuffer ) && ( dwRegNum >= DXABSTRACT_VS_FIRST_BONE_SLOT ) ) + { + if( dwRegNum < DXABSTRACT_VS_LAST_BONE_SLOT ) + { + dwRegNum -= DXABSTRACT_VS_FIRST_BONE_SLOT; + V_strcpy( szConstantRegName, "vcbones" ); + + m_nHighestBoneRegister = MAX( m_nHighestBoneRegister, (int)dwRegNum ); + } + else + { + // handles case where constants after the bones are used (c217 onwards), these are to be concatenated with those before the bones (c0-c57) + // keep track of regnum for concatenated array + dwRegNum -= ( DXABSTRACT_VS_LAST_BONE_SLOT + 1 ) - DXABSTRACT_VS_FIRST_BONE_SLOT; + m_nHighestRegister = MAX( m_nHighestRegister, dwRegNum ); + } + } + else + { + //// NOGO if (dwRegNum != 255) // have seen cases where dwRegNum is 0xFF... need to figure out where those opcodes are coming from + { + m_nHighestRegister = MAX( m_nHighestRegister, dwRegNum ); + } + + Assert( m_nHighestRegister < DXABSTRACT_VS_PARAM_SLOTS ); + } + + // Index into single pc/vc[] register array with absolute addressing, same for GLSL and ASM + V_snprintf( buff, sizeof( buff ), "%s[%d]", szConstantRegName, dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + } + break; + case D3DSPR_ADDR: // aliases to D3DSPR_TEXTURE + if ( m_bVertexShader ) + { + Assert( dwRegNum == 0 ); + + V_snprintf( buff, sizeof( buff ), "va_r" ); + } + else // D3DSPR_TEXTURE in the pixel shader + { + // If dest reg, this is an iterator/varying declaration + if ( dwSourceOrDest == DST_REGISTER ) + { + // Is this iterator centroid? + if ( m_nCentroidMask & ( 0x00000001 << dwRegNum ) ) + { + V_snprintf( buff, sizeof( buff ), "centroid in vec4 oT%d", dwRegNum ); // centroid varying + } + else + { + V_snprintf( buff, sizeof( buff ), "in vec4 oT%d", dwRegNum ); + } + bAllowWriteMask = false; + } + else // source register + { + V_snprintf( buff, sizeof( buff ), "oT%d", dwRegNum ); + } + } + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_RASTOUT: // vertex shader oPos + Assert( m_bVertexShader ); + Assert( m_dwMajorVersion == 2 ); + switch( dwRegNum ) + { + case D3DSRO_POSITION: + strcat_s( pRegisterName, nBufLen, "vTempPos" ); // In GLSL, this ends up in gl_Position later on + m_bDeclareVSOPos = true; + break; + + case D3DSRO_FOG: + if( !m_bFogFragCoord ) + { + StrcatToHeaderCode("varying highp vec4 _gl_FogFragCoord;\n"); + m_bFogFragCoord = true; + } + + strcat_s( pRegisterName, nBufLen, "_gl_FogFragCoord" ); + m_bDeclareVSOFog = true; + break; + + default: + printf( "\nD3DSPR_RASTOUT: dwRegNum is %08x and token is %08x", dwRegNum, dwToken ); + TranslationError(); + break; + } + break; + case D3DSPR_ATTROUT: + Assert( m_bVertexShader ); + Assert( m_dwMajorVersion == 2 ); + + if ( dwRegNum == 0 ) + { + if( !m_bFrontColor ) + { + StrcatToHeaderCode("varying highp vec4 _gl_FrontColor;\n"); + m_bFrontColor = true; + } + + V_snprintf( buff, sizeof( buff ), "_gl_FrontColor" ); + } + else if ( dwRegNum == 1 ) + { + if( !m_bFrontSecondaryColor ) + { + StrcatToHeaderCode("varying highp vec4 _gl_FrontSecondaryColor;\n"); + m_bFrontSecondaryColor = true; + } + + V_snprintf( buff, sizeof( buff ), "_gl_FrontSecondaryColor" ); + } + else + { + Error( "Invalid D3DSPR_ATTROUT index" ); + } + + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_TEXCRDOUT: // aliases to D3DSPR_OUTPUT + if ( m_bVertexShader ) + { + if ( m_nVSPositionOutput == (int32) dwRegNum ) + { + V_snprintf( buff, sizeof( buff ), "vTempPos" ); // This output varying is the position + } + else if ( m_dwMajorVersion == 3 ) + { + V_snprintf( buff, sizeof( buff ), "oTempT%d", dwRegNum ); + } + else + { + V_snprintf( buff, sizeof( buff ), "oT%d", dwRegNum ); + } + + m_dwTexCoordOutMask |= ( 0x00000001 << dwRegNum ); + } + else + { + V_snprintf( buff, sizeof( buff ), "oC%d", dwRegNum ); + } + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_CONSTINT: + V_snprintf( buff, sizeof( buff ), "i%d", dwRegNum ); // Loops use these + strcat_s( pRegisterName, nBufLen, buff ); + m_dwConstIntUsageMask |= 0x00000001 << dwRegNum; // Keep track of the use of this integer constant + break; + case D3DSPR_COLOROUT: + if( dwRegNum+1 > m_iFragDataCount ) + m_iFragDataCount = dwRegNum+1; + + V_snprintf( buff, sizeof( buff ), "gl_FragData[%d]", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + m_bOutputColorRegister[dwRegNum] = true; + break; + case D3DSPR_DEPTHOUT: + V_snprintf( buff, sizeof( buff ), "gl_FragDepth" ); + strcat_s( pRegisterName, nBufLen, buff ); + m_bOutputDepthRegister = true; + break; + case D3DSPR_SAMPLER: + V_snprintf( buff, sizeof( buff ), "sampler%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_CONST2: + TranslationError(); + V_snprintf( buff, sizeof( buff ), "c%d", dwRegNum+2048); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_CONST3: + TranslationError(); + V_snprintf( buff, sizeof( buff ), "c%d", dwRegNum+4096); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_CONST4: + TranslationError(); + V_snprintf( buff, sizeof( buff ), "c%d", dwRegNum+6144); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_CONSTBOOL: + V_snprintf( buff, sizeof( buff ), m_bVertexShader ? "b%d" : "fb%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + m_dwConstBoolUsageMask |= 0x00000001 << dwRegNum; // Keep track of the use of this bool constant + break; + case D3DSPR_LOOP: + TranslationError(); + V_snprintf( buff, sizeof( buff ), "aL%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_TEMPFLOAT16: + TranslationError(); + V_snprintf( buff, sizeof( buff ), "temp_float16_xxx%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_MISCTYPE: + Assert( dwRegNum == 0 ); // So far, we know that MISC[0] is gl_FragCoord (aka vPos in DX ASM parlance), but we don't know about any other MISC registers + V_snprintf( buff, sizeof( buff ), "gl_FragCoord" ); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_LABEL: + TranslationError(); + V_snprintf( buff, sizeof( buff ), "label%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + break; + case D3DSPR_PREDICATE: + TranslationError(); + V_snprintf( buff, sizeof( buff ), "p%d", dwRegNum ); + strcat_s( pRegisterName, nBufLen, buff ); + break; + } + + // If this is a dest register + if ( dwSourceOrDest == DST_REGISTER ) + { + // + // Write masks + // + // If some (not all, not none) of the write masks are set, we should include them + // + if ( bAllowWriteMask && ( !((dwToken & D3DSP_WRITEMASK_ALL) == D3DSP_WRITEMASK_ALL) || ((dwToken & D3DSP_WRITEMASK_ALL) == 0x00000000) ) ) + { + // Put the dot on there + strcat_s( pRegisterName, nBufLen, "." ); + + // Optionally put on the x, y, z or w + int nMasksWritten = 0; + if ( dwToken & D3DSP_WRITEMASK_0 ) + { + strcat_s( pRegisterName, nBufLen, "x" ); + ++nMasksWritten; + } + if ( dwToken & D3DSP_WRITEMASK_1 ) + { + strcat_s( pRegisterName, nBufLen, "y" ); + ++nMasksWritten; + } + if ( dwToken & D3DSP_WRITEMASK_2 ) + { + strcat_s( pRegisterName, nBufLen, "z" ); + ++nMasksWritten; + } + if ( dwToken & D3DSP_WRITEMASK_3 ) + { + strcat_s( pRegisterName, nBufLen, "w" ); + ++nMasksWritten; + } + } + } + else // must be a source register + { + if ( bAllowSwizzle ) // relative addressing hard-codes the swizzle on a0.x + { + uint32 dwXSwizzle, dwYSwizzle, dwZSwizzle, dwWSwizzle; + + // Mask out the swizzle modifier + dwSwizzle = dwToken & D3DVS_SWIZZLE_MASK; + + // If there are any swizzles at all, tack on the appropriate notation + if ( dwSwizzle != D3DVS_NOSWIZZLE ) + { + // Separate out the two-bit codes for each component swizzle + dwXSwizzle = dwSwizzle & D3DVS_X_W; + dwYSwizzle = dwSwizzle & D3DVS_Y_W; + dwZSwizzle = dwSwizzle & D3DVS_Z_W; + dwWSwizzle = dwSwizzle & D3DVS_W_W; + + // Put on the dot + strcat_s( pRegisterName, nBufLen, "." ); + + // See where X comes from + switch ( dwXSwizzle ) + { + case D3DVS_X_X: + strcat_s( pRegisterName, nBufLen, "x" ); + break; + case D3DVS_X_Y: + strcat_s( pRegisterName, nBufLen, "y" ); + break; + case D3DVS_X_Z: + strcat_s( pRegisterName, nBufLen, "z" ); + break; + case D3DVS_X_W: + strcat_s( pRegisterName, nBufLen, "w" ); + break; + } + + if ( !bForceScalarSource ) + { + // If the source of the remaining components are aren't + // identical to the source of x, continue with swizzle + if ( ((dwXSwizzle >> D3DVS_SWIZZLE_SHIFT) != (dwYSwizzle >> (D3DVS_SWIZZLE_SHIFT + 2))) || // X and Y sources match? + ((dwXSwizzle >> D3DVS_SWIZZLE_SHIFT) != (dwZSwizzle >> (D3DVS_SWIZZLE_SHIFT + 4))) || // X and Z sources match? + ((dwXSwizzle >> D3DVS_SWIZZLE_SHIFT) != (dwWSwizzle >> (D3DVS_SWIZZLE_SHIFT + 6)))) // X and W sources match? + { + + // OpenGL seems to want us to have either 1 or 4 components in a swizzle, so just plow on through the rest + switch ( dwYSwizzle ) + { + case D3DVS_Y_X: + strcat_s( pRegisterName, nBufLen, "x" ); + break; + case D3DVS_Y_Y: + strcat_s( pRegisterName, nBufLen, "y" ); + break; + case D3DVS_Y_Z: + strcat_s( pRegisterName, nBufLen, "z" ); + break; + case D3DVS_Y_W: + strcat_s( pRegisterName, nBufLen, "w" ); + break; + } + + switch ( dwZSwizzle ) + { + case D3DVS_Z_X: + strcat_s( pRegisterName, nBufLen, "x" ); + break; + case D3DVS_Z_Y: + strcat_s( pRegisterName, nBufLen, "y" ); + break; + case D3DVS_Z_Z: + strcat_s( pRegisterName, nBufLen, "z" ); + break; + case D3DVS_Z_W: + strcat_s( pRegisterName, nBufLen, "w" ); + break; + } + + switch ( dwWSwizzle ) + { + case D3DVS_W_X: + strcat_s( pRegisterName, nBufLen, "x" ); + break; + case D3DVS_W_Y: + strcat_s( pRegisterName, nBufLen, "y" ); + break; + case D3DVS_W_Z: + strcat_s( pRegisterName, nBufLen, "z" ); + break; + case D3DVS_W_W: + strcat_s( pRegisterName, nBufLen, "w" ); + break; + } + + } + + } // end !bForceScalarSource + } + else // dwSwizzle == D3DVS_NOSWIZZLE + { + // If this is a MOVA / ARL, GL on the Mac requires us to tack the .x onto the source register + if ( bForceScalarSource ) + { + strcat_s( pRegisterName, nBufLen, ".x" ); + } + } + } // bAllowSwizzle + + // If there are any source modifiers, check to see if they're at + // least partially "postfix" and tack them on as appropriate + if ( dwSrcModifier != D3DSPSM_NONE ) + { + switch ( dwSrcModifier ) + { + case D3DSPSM_BIAS: // bias + case D3DSPSM_BIASNEG: // bias and negate + TranslationError(); + strcat_s( pRegisterName, nBufLen, "_bx2" ); + break; + case D3DSPSM_SIGN: // sign + case D3DSPSM_SIGNNEG: // sign and negate + TranslationError(); + strcat_s( pRegisterName, nBufLen, "_sgn" ); + break; + case D3DSPSM_X2: // *2 + case D3DSPSM_X2NEG: // *2 and negate + TranslationError(); + strcat_s( pRegisterName, nBufLen, "_x2" ); + break; + case D3DSPSM_ABS: // abs() + case D3DSPSM_ABSNEG: // -abs() + strcat_s( pRegisterName, nBufLen, ")" ); + break; + case D3DSPSM_DZ: // divide through by z component + TranslationError(); + strcat_s( pRegisterName, nBufLen, "_dz" ); + break; + case D3DSPSM_DW: // divide through by w component + TranslationError(); + strcat_s( pRegisterName, nBufLen, "_dw" ); + break; + } + } // end postfix modifiers (really only ps.1.x) + } +} + +void D3DToGL::RecordInputAndOutputPositions() +{ + // Remember where we are in the token stream. + m_pRecordedInputTokenStart = m_pdwNextToken; + + // Remember where our outputs are. + m_nRecordedParamCodeStrlen = V_strlen( (char*)m_pBufParamCode->Base() ); + m_nRecordedALUCodeStrlen = V_strlen( (char*)m_pBufALUCode->Base() ); + m_nRecordedAttribCodeStrlen = V_strlen( (char*)m_pBufAttribCode->Base() ); +} +void D3DToGL::AddTokenHexCodeToBuffer( char *pBuffer, int nSize, int nLastStrlen ) +{ + int nCurStrlen = V_strlen( pBuffer ); + if ( nCurStrlen == nLastStrlen ) + return; + + // Build a string with all the hex codes of the tokens since last time. + char szHex[512]; + szHex[0] = '\n'; + V_snprintf( &szHex[1], sizeof( szHex )-1, HEXCODE_HEADER ); + int nTokens = MIN( 10, m_pdwNextToken - m_pRecordedInputTokenStart ); + for ( int i=0; i < nTokens; i++ ) + { + char szTemp[32]; + V_snprintf( szTemp, sizeof( szTemp ), "0x%x ", m_pRecordedInputTokenStart[i] ); + V_strncat( szHex, szTemp, sizeof( szHex ) ); + } + V_strncat( szHex, "\n", sizeof( szHex ) ); + + // Insert the hex codes into the string. + int nBytesToInsert = V_strlen( szHex ); + if ( nCurStrlen + nBytesToInsert + 1 >= nSize ) + Error( "Buffer overflow writing token hex codes" ); + + if ( m_bPutHexCodesAfterLines ) + { + // Put it at the end of the last line. + if ( pBuffer[nCurStrlen-1] == '\n' ) + pBuffer[nCurStrlen-1] = 0; + + V_strncat( pBuffer, &szHex[1], nSize ); + } + else + { + memmove( pBuffer + nLastStrlen + nBytesToInsert, pBuffer + nLastStrlen, nCurStrlen - nLastStrlen + 1 ); + memcpy( pBuffer + nLastStrlen, szHex, nBytesToInsert ); + } +} + +void D3DToGL::AddTokenHexCode() +{ + if ( m_pdwNextToken > m_pRecordedInputTokenStart ) + { + AddTokenHexCodeToBuffer( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size(), m_nRecordedParamCodeStrlen ); + AddTokenHexCodeToBuffer( (char*)m_pBufALUCode->Base(), m_pBufALUCode->Size(), m_nRecordedALUCodeStrlen ); + AddTokenHexCodeToBuffer( (char*)m_pBufAttribCode->Base(), m_pBufAttribCode->Size(), m_nRecordedAttribCodeStrlen ); + } +} + +uint32 D3DToGL::MaintainAttributeMap( uint32 dwToken, uint32 dwRegToken ) +{ + // Check that this reg index has not been used before - if it has, let Houston know + uint dwRegIndex = dwRegToken & D3DSP_REGNUM_MASK; + if ( m_dwAttribMap[ dwRegIndex ] == 0xFFFFFFFF ) + { + // log it + // semantic/usage in the higher nibble + // usage index in the low nibble + + uint usage = dwToken & D3DSP_DCL_USAGE_MASK; + uint usageindex = ( dwToken & D3DSP_DCL_USAGEINDEX_MASK ) >> D3DSP_DCL_USAGEINDEX_SHIFT; + + m_dwAttribMap[ dwRegIndex ] = ( usage << 4 ) | usageindex; + + // avoid writing 0xBB since runtime code uses that for an 'unused' marker + if ( m_dwAttribMap[ dwRegIndex ] == 0xBB ) + { + Debugger(); + } + } + else + { + //not OK + Debugger(); + } + + return dwRegIndex; +} + +void D3DToGL::Handle_DCL() +{ + uint32 dwToken = GetNextToken(); // What kind of dcl is this... + uint32 dwRegToken = GetNextToken(); // Look ahead to register token + + uint32 dwUsage = ( dwToken & D3DSP_DCL_USAGE_MASK ); + uint32 dwUsageIndex = ( dwToken & D3DSP_DCL_USAGEINDEX_MASK ) >> D3DSP_DCL_USAGEINDEX_SHIFT; + + uint32 dwRegNum = dwRegToken & D3DSP_REGNUM_MASK; + uint32 nRegType = GetRegTypeFromToken( dwRegToken ); + + if ( m_bVertexShader ) + { + // If this is an output, remember the index (what the ASM code calls o0, o1, o2..) and the semantic. + // When GetParameterString( DST_REGISTER ) hits this one, we'll return "oN". + // At the end of the main() function, we'll insert a bunch of statements like "gl_Color = o2" based on what we remembered here. + if ( ( m_dwMajorVersion >= 3 ) && ( nRegType == D3DSPR_OUTPUT ) ) + { +// uint32 dwRegComponents = ( dwRegToken & D3DSP_WRITEMASK_ALL ) >> 16; // Components used by the output register (1 means float, 3 means vec2, 7 means vec3, f means vec4) + + if ( dwRegNum >= MAX_DECLARED_OUTPUTS ) + Error( "Output register number (%d) too high (only %d supported).", dwRegNum, MAX_DECLARED_OUTPUTS ); + + if ( m_DeclaredOutputs[dwRegNum] != UNDECLARED_OUTPUT ) + Error( "Output dcl_ hit for register #%d more than once!", dwRegNum ); + + Assert( dwToken != UNDECLARED_OUTPUT ); + m_DeclaredOutputs[dwRegNum] = dwToken; + + //uint32 dwUsage = ( dwToken & D3DSP_DCL_USAGE_MASK ); + //uint32 dwUsageIndex = ( dwToken & D3DSP_DCL_USAGEINDEX_MASK ) >> D3DSP_DCL_USAGEINDEX_SHIFT; + + // Flag which o# output register maps to gl_Position + if ( dwUsage == D3DDECLUSAGE_POSITION ) + { + m_nVSPositionOutput = dwUsageIndex; + m_bDeclareVSOPos = true; + } + + if ( m_bAddHexCodeComments ) + { + CUtlString sParam2 = GetUsageAndIndexString( dwToken, SEMANTIC_OUTPUT ); + PrintToBuf( *m_pBufHeaderCode, "// [GL remembering that oT%d maps to %s]\n", dwRegNum, sParam2.String() ); + } + + } + else if ( GetRegType( dwRegToken ) == D3DSPR_SAMPLER ) + { + // We can support vertex texturing if necessary, but I can't find a use case in any branch. (HW morphing in L4D2 isn't enabled, and the comments indicate that r_hwmorph isn't compatible with mat_queue_mode anyway, and CS:GO/DoTA don't use vertex shader texturing.) + TranslationError(); + + int nRegNum = dwRegToken & D3DSP_REGNUM_MASK; + switch ( TextureType( dwToken ) ) + { + default: + case D3DSTT_UNKNOWN: + case D3DSTT_2D: + m_dwSamplerTypes[nRegNum] = SAMPLER_TYPE_2D; + break; + case D3DSTT_CUBE: + m_dwSamplerTypes[nRegNum] = SAMPLER_TYPE_CUBE; + break; + case D3DSTT_VOLUME: + m_dwSamplerTypes[nRegNum] = SAMPLER_TYPE_3D; + break; + } + + // Track sampler declarations + m_dwSamplerUsageMask |= 1 << nRegNum; + } + else + { + Assert( GetRegType( dwRegToken ) == D3DSPR_INPUT); + + CUtlString sParam1 = GetParameterString( dwRegToken, DST_REGISTER, false, NULL ); + CUtlString sParam2 = GetUsageAndIndexString( dwToken, SEMANTIC_INPUT ); + + sParam2 = FixGLSLSwizzle( sParam1, sParam2 ); + PrintToBuf( *m_pBufHeaderCode, "in vec4 %s; // ", sParam1.String() ); + + MaintainAttributeMap( dwToken, dwRegToken ); + + char temp[128]; + // regnum goes straight into the vertex.attrib[n] index + sprintf( temp, "%08x %08x\n", dwToken, dwRegToken ); + StrcatToHeaderCode( temp ); + } + } + else // Pixel shader + { + // If the register is a sampler, the dcl has a dimension decorator that we have to save for subsequent TEX instructions + uint32 nRegType = GetRegType( dwRegToken ); + if ( nRegType == D3DSPR_SAMPLER ) + { + int nRegNum = dwRegToken & D3DSP_REGNUM_MASK; + switch ( TextureType( dwToken ) ) + { + default: + case D3DSTT_UNKNOWN: + case D3DSTT_2D: + m_dwSamplerTypes[nRegNum] = SAMPLER_TYPE_2D; + break; + case D3DSTT_CUBE: + m_dwSamplerTypes[nRegNum] = SAMPLER_TYPE_CUBE; + break; + case D3DSTT_VOLUME: + m_dwSamplerTypes[nRegNum] = SAMPLER_TYPE_3D; + break; + } + + // Track sampler declarations + m_dwSamplerUsageMask |= 1 << nRegNum; + } + else // Not a sampler, we're going to generate varying declaration code + { + // In pixel shaders we only declare texture coordinate varyings since they may be using centroid + if ( ( m_dwMajorVersion == 3 ) && ( nRegType == D3DSPR_INPUT ) ) + { + Assert( m_DeclaredInputs[dwRegNum] == UNDECLARED_INPUT ); + m_DeclaredInputs[dwRegNum] = dwToken; + + if ( ( dwUsage != D3DDECLUSAGE_COLOR ) && ( dwUsage != D3DDECLUSAGE_TEXCOORD ) ) + { + TranslationError(); // Not supported yet, but can be if we need it. + } + + if ( dwUsage == D3DDECLUSAGE_TEXCOORD ) + { + char buf[256]; + if ( m_nCentroidMask & ( 0x00000001 << dwUsageIndex ) ) + { + V_snprintf( buf, sizeof( buf ), "centroid in vec4 oT%d;\n", dwUsageIndex ); // centroid varying + } + else + { + V_snprintf( buf, sizeof( buf ), "in vec4 oT%d;\n", dwUsageIndex ); + } + + StrcatToHeaderCode( buf ); + } + } + else if ( nRegType == D3DSPR_TEXTURE ) + { + char buff[256]; + PrintParameterToString( dwRegToken, DST_REGISTER, buff, sizeof( buff ), false, NULL ); + PrintToBuf( *m_pBufHeaderCode, "%s;\n",buff ); + } + else + { + // No need to declare anything (probably D3DSPR_MISCTYPE either VPOS or VFACE) + } + } + } +} + +static bool IsFloatNaN( float f ) +{ + const uint nBits = *reinterpret_cast(&f); + const uint nExponent = ( nBits >> 23 ) & 0xFF; + + return ( nExponent == 255 ); +} + +static inline bool EqualTol( double a, double b, double t ) +{ + return fabs( a - b ) <= ( ( MAX( fabs( a ), fabs( b ) ) + 1.0 ) * t ); +} + +// Originally written by Bruce Dawson, see: +// See http://randomascii.wordpress.com/2012/03/08/float-precisionfrom-zero-to-100-digits-2/ +// This class represents a very limited high-precision number with 'count' 32-bit +// unsigned elements. +template +struct HighPrec +{ + typedef unsigned T; + typedef unsigned long long Product_t; + static const int kWordShift = 32; + HighPrec() + { + memset(m_data, 0, sizeof(m_data)); + m_nLowestNonZeroIndex = ARRAYSIZE(m_data); + } + + // Insert the bits from value into m_data, shifted in from the bottom (least + // significant end) by the specified number of bits. A shift of zero or less + // means that none of the bits will be shifted in. A shift of one means that + // the high bit of value will be in the bottom of the last element of m_data - + // the least significant bit. A shift of kWordShift means that value will be + // in the least significant element of m_data, and so on. + void InsertLowBits(T value, int shiftAmount) + { + if (shiftAmount <= 0) + return; + + int subShift = shiftAmount & (kWordShift - 1); + int bigShift = shiftAmount / kWordShift; + Product_t result = (Product_t)value << subShift; + T resultLow = (T)result; + T resultHigh = result >> kWordShift; + + // Use an unsigned type so that negative numbers will become large, + // which makes the range checking below simpler. + unsigned highIndex = ARRAYSIZE(m_data) - 1 - bigShift; + // Write the results to the data array. If the index is too large + // then that means that the data was shifted off the edge. + if ( (highIndex < ARRAYSIZE(m_data)) && ( resultHigh ) ) + { + m_data[highIndex] |= resultHigh; + m_nLowestNonZeroIndex = MIN( m_nLowestNonZeroIndex, highIndex ); + } + + if ( ( highIndex + 1 < ARRAYSIZE(m_data)) && ( resultLow ) ) + { + m_data[highIndex + 1] |= resultLow; + m_nLowestNonZeroIndex = MIN( m_nLowestNonZeroIndex, highIndex + 1 ); + } + } + + // Insert the bits from value into m_data, shifted in from the top (most + // significant end) by the specified number of bits. A shift of zero or less + // means that none of the bits will be shifted in. A shift of one means that + // the low bit of value will be in the top of the first element of m_data - + // the most significant bit. A shift of kWordShift means that value will be + // in the most significant element of m_data, and so on. + void InsertTopBits(T value, int shiftAmount) + { + InsertLowBits(value, (ARRAYSIZE(m_data) + 1) * kWordShift - shiftAmount); + } + + // Return true if all elements of m_data are zero. + bool IsZero() const + { + bool bIsZero = ( m_nLowestNonZeroIndex == ARRAYSIZE(m_data) ); + +#ifdef DEBUG + for (int i = 0; i < ARRAYSIZE(m_data); ++i) + { + if (m_data[i]) + { + Assert( !bIsZero ); + return false; + } + } + Assert( bIsZero ); +#endif + + return bIsZero; + } + + // Divide by div and return the remainder, from 0 to div-1. + // Standard long-division algorithm. + T DivReturnRemainder(T divisor) + { + T remainder = 0; + +#ifdef DEBUG + for (uint j = 0; j < m_nLowestNonZeroIndex; ++j) + { + Assert( m_data[j] == 0 ); + } +#endif + + int nNewLowestNonZeroIndex = ARRAYSIZE(m_data); + for (int i = m_nLowestNonZeroIndex; i < ARRAYSIZE(m_data); ++i) + { + Product_t dividend = ((Product_t)remainder << kWordShift) + m_data[i]; + Product_t result = dividend / divisor; + remainder = T(dividend % divisor); + + m_data[i] = T(result); + + if ( ( result ) && ( nNewLowestNonZeroIndex == ARRAYSIZE(m_data) ) ) + nNewLowestNonZeroIndex = i; + } + m_nLowestNonZeroIndex = nNewLowestNonZeroIndex; + + return remainder; + } + + // The individual 'digits' (32-bit unsigned integers actually) that + // make up the number. The most-significant digit is in m_data[0]. + T m_data[count]; + + uint m_nLowestNonZeroIndex; +}; + +union Double_t +{ + Double_t(double num = 0.0f) : f(num) {} + // Portable extraction of components. + bool Negative() const { return (i >> 63) != 0; } + int64_t RawMantissa() const { return i & ((1LL << 52) - 1); } + int64_t RawExponent() const { return (i >> 52) & 0x7FF; } + + int64_t i; + double f; +}; + +static uint PrintDoubleInt( char *pBuf, uint nBufSize, double f, uint nMinChars ) +{ + static const char *pDigits = "00010203040506070809101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899"; + + Assert( !nMinChars || ( ( nMinChars % 6 ) == 0 ) ); + + char *pLastChar = pBuf + nBufSize - 1; + char *pDst = pLastChar; + *pDst-- = '\0'; + + // Put the double in our magic union so we can grab the components. + union Double_t num(f); + + // Get the character that represents the sign. + // Check for NaNs or infinity. + if (num.RawExponent() == 2047) + { + TranslationError(); + } + + // Adjust for the exponent bias. + int exponentValue = int(num.RawExponent() - 1023); + // Add the implied one to the mantissa. + uint64_t mantissaValue = (1ll << 52) + num.RawMantissa(); + // Special-case for denormals - no special exponent value and + // no implied one. + if (num.RawExponent() == 0) + { + exponentValue = -1022; + mantissaValue = num.RawMantissa(); + } + uint32_t mantissaHigh = mantissaValue >> 32; + uint32_t mantissaLow = mantissaValue & 0xFFFFFFFF; + + // The first bit of the mantissa has an implied value of one and this can + // be shifted 1023 positions to the left, so that's 1024 bits to the left + // of the binary point, or 32 32-bit words for the integer part. + HighPrec<32> intPart; + // When our exponentValue is zero (a number in the 1.0 to 2.0 range) + // we have a 53-bit mantissa and the implied value of the highest bit + // is 1. We need to shift 12 bits in from the bottom to get that 53rd bit + // into the ones spot in the integral portion. + // To complicate it a bit more we have to insert the mantissa as two parts. + intPart.InsertLowBits(mantissaHigh, 12 + exponentValue); + intPart.InsertLowBits(mantissaLow, 12 + exponentValue - 32); + + bool bAnyDigitsLeft; + do + { + uint remainder = intPart.DivReturnRemainder( 1000000 ); // 10^6 + uint origRemainer = remainder; (void)origRemainer; + + bAnyDigitsLeft = !intPart.IsZero(); + + if ( bAnyDigitsLeft ) + { + uint n = remainder % 100U; remainder /= 100U; *reinterpret_cast(pDst - 1) = reinterpret_cast(pDigits)[n]; + n = remainder % 100U; remainder /= 100U; *reinterpret_cast(pDst - 1 - 2) = reinterpret_cast(pDigits)[n]; + Assert( remainder < 100U ); + *reinterpret_cast(pDst - 1 - 4) = reinterpret_cast(pDigits)[remainder]; + pDst -= 6; + } + else + { + uint n = remainder % 100U; remainder /= 100U; *reinterpret_cast(pDst - 1) = reinterpret_cast(pDigits)[n]; --pDst; if ( ( n >= 10 ) || ( remainder ) ) --pDst; + if ( remainder ) + { + n = remainder % 100U; remainder /= 100U; *reinterpret_cast(pDst - 1) = reinterpret_cast(pDigits)[n]; --pDst; if ( ( n >= 10 ) || ( remainder ) ) --pDst; + + if ( remainder ) + { + Assert( remainder < 100U ); + *reinterpret_cast(pDst - 1) = reinterpret_cast(pDigits)[remainder]; --pDst; if ( remainder >= 10 ) --pDst; + } + } + } + + } while ( bAnyDigitsLeft ); + + uint l = pLastChar - pDst; + + while ( ( l - 1 ) < nMinChars ) + { + *pDst-- = '0'; + l++; + } + + Assert( (int)l == ( pLastChar - pDst ) ); + + Assert( l <= nBufSize ); + + memmove( pBuf, pDst + 1, l ); + return l - 1; +} + +// FloatToString is equivalent to sprintf( "%.12f" ), but doesn't have any dependencies on the current locale setting. +// Unfortunately, high accuracy radix conversion is actually pretty tricky to do right. +// Most importantly, this function has the same max roundtrip (IEEE->ASCII->IEEE) error as the MS CRT functions and can reliably handle extremely large inputs. +static void FloatToString( char *pBuf, uint nBufSize, double fConst ) +{ + char *pEnd = pBuf + nBufSize; + char *pDst = pBuf; + + double flVal = fConst; + if ( IsFloatNaN( flVal ) ) + { + flVal = 0; + } + + if ( flVal < 0.0f ) + { + *pDst++ = '-'; + flVal = -flVal; + } + + double flInt; + double flFract = modf( flVal, &flInt ); + + flFract = floor( flFract * 1000000000000.0 + .5 ); + + if ( !flInt ) + { + *pDst++ = '0'; + } + else + { + uint l = PrintDoubleInt( pDst, pEnd - pDst, flInt, 0 ); + pDst += l; + } + + *pDst++ = '.'; + if ( !flFract ) + { + *pDst++ = '0'; + *pDst++ = '\0'; + } + else + { + uint l = PrintDoubleInt( pDst, pEnd - pDst, flFract, 12 ); + pDst += l; + + StripExtraTrailingZeros( pBuf ); // Turn 1.00000 into 1.0 + } +} + +#if 0 +#include "vstdlib/random.h" +static void TestFloatConversion() +{ + for ( ; ; ) + { + double fConst; + switch ( rand() % 4 ) + { + case 0: + fConst = RandomFloat( -1e-30, 1e+30 ); break; + case 1: + fConst = RandomFloat( -1e-10, 1e+10 ); break; + case 2: + fConst = RandomFloat( -1e-5, 1e+5 ); break; + default: + fConst = RandomFloat( -1, 1 ); break; + } + + char szTemp[1024]; + + // FloatToString does not rely on V_snprintf(), so it can't be affected by the current locale setting. + FloatToString( szTemp, sizeof( szTemp ), fConst ); + + static double flMaxErr1; + static double flMaxErr2; + + // Compare FloatToString()'s results vs. V_snprintf()'s, also track maximum error of each. + double flCheck = atof( szTemp ); + double flErr = fabs( flCheck - fConst ); + flMaxErr1 = MAX( flMaxErr1, flErr ); + Assert( EqualTol( flCheck, fConst, .000000125 ) ); + + char szTemp2[256]; + V_snprintf( szTemp2, sizeof( szTemp2 ), "%.12f", fConst ); + StripExtraTrailingZeros( szTemp2 ); + + if ( !strchr( szTemp2, '.' ) ) + { + V_strncat( szTemp2, ".0", sizeof( szTemp2 ) ); + } + double flCheck2 = atof( szTemp2 ); + double flErr2 = fabs( flCheck2 - fConst ); + flMaxErr2 = MAX( flMaxErr2, flErr2 ); + Assert( EqualTol( flCheck2, fConst, .000000125 ) ); + + if ( flMaxErr1 > flMaxErr2 ) + { + GLMDebugPrintf( "!\n" ); + } + } +} +#endif + +void D3DToGL::Handle_DEFIB( uint32 instruction ) +{ + Assert( ( instruction == D3DSIO_DEFI ) || ( instruction == D3DSIO_DEFB ) ); + + // which register is being defined + uint32 dwToken = GetNextToken(); + + uint32 nRegNum = dwToken & D3DSP_REGNUM_MASK; + + uint32 regType = GetRegTypeFromToken( dwToken ); + + + if ( regType == D3DSPR_CONSTINT ) + { + m_dwDefConstIntUsageMask |= ( 1 << nRegNum ); + + uint x = GetNextToken(); + uint y = GetNextToken(); + uint z = GetNextToken(); + uint w = GetNextToken(); + NOTE_UNUSED(y); NOTE_UNUSED(z); NOTE_UNUSED(w); + + Assert( nRegNum < 32 ); + if ( nRegNum < 32 ) + { + m_dwDefConstIntIterCount[nRegNum] = x; + } + } + else + { + TranslationError(); + } + +} + +void D3DToGL::Handle_DEF() +{ + //TestFloatConversion(); + + // + // JasonM TODO: catch D3D's sincos-specific D3DSINCOSCONST1 and D3DSINCOSCONST2 constants and filter them out here + // + + // Which register is being defined + uint32 dwToken = GetNextToken(); + + // Note that this constant was explicitly defined + m_bConstantRegisterDefined[dwToken & D3DSP_REGNUM_MASK] = true; + CUtlString sParamName = GetParameterString( dwToken, DST_REGISTER, false, NULL ); + + PrintIndentation( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size() ); + PrintToBuf( *m_pBufParamCode, "vec4 %s = vec4( ", sParamName.String() ); + + // Run through the 4 floats + for ( int i=0; i < 4; i++ ) + { + float fConst = uint32ToFloat( GetNextToken() ); + + char szTemp[1024]; + + FloatToString( szTemp, sizeof( szTemp ), fConst ); + +#if 0 + static double flMaxErr1; + static double flMaxErr2; + + // Compare FloatToString()'s results vs. V_snprintf()'s, also track maximum error of each. + double flCheck = atof( szTemp ); + double flErr = fabs( flCheck - fConst ); + flMaxErr1 = MAX( flMaxErr1, flErr ); + Assert( EqualTol( flCheck, fConst, .000000125 ) ); + + char szTemp2[256]; + V_snprintf( szTemp2, sizeof( szTemp2 ), "%.12f", fConst ); + StripExtraTrailingZeros( szTemp2 ); + + if ( !strchr( szTemp2, '.' ) ) + { + V_strncat( szTemp2, ".0", sizeof( szTemp2 ) ); + } + double flCheck2 = atof( szTemp2 ); + double flErr2 = fabs( flCheck2 - fConst ); + flMaxErr2 = MAX( flMaxErr2, flErr2 ); + Assert( EqualTol( flCheck2, fConst, .000000125 ) ); + + if ( flMaxErr1 > flMaxErr2 ) + { + GLMDebugPrintf( "!\n" ); + } +#endif + + PrintToBuf( *m_pBufParamCode, i != 3 ? "%s, " : "%s", szTemp ); // end with comma-space + } + + PrintToBuf( *m_pBufParamCode, " );\n" ); +} + +void D3DToGL::Handle_MAD( uint32 nInstruction ) +{ + uint32 nDestToken = GetNextToken(); + CUtlString sParam1 = GetParameterString( nDestToken, DST_REGISTER, false, NULL ); + int nARLComp0 = ARL_DEST_NONE; + CUtlString sParam2 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp0 ); + int nARLComp1 = ARL_DEST_NONE; + CUtlString sParam3 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp1 ); + int nARLComp2 = ARL_DEST_NONE; + CUtlString sParam4 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp2 ); + + // This optionally inserts a move from our dummy address register to the .x component of the real one + InsertMoveFromAddressRegister( m_pBufALUCode, nARLComp0, nARLComp1, nARLComp2 ); + + sParam2 = FixGLSLSwizzle( sParam1, sParam2 ); + sParam3 = FixGLSLSwizzle( sParam1, sParam3 ); + sParam4 = FixGLSLSwizzle( sParam1, sParam4 ); + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s * %s + %s;\n", sParam1.String(), sParam2.String(), sParam3.String(), sParam4.String() ); + + // If the _SAT instruction modifier is used, then do a saturate here. + if ( nDestToken & D3DSPDM_SATURATE ) + { + int nComponents = GetNumSwizzleComponents( sParam1.String() ); + if ( nComponents == 0 ) + nComponents = 4; + + PrintToBufWithIndents( *m_pBufALUCode, "%s = clamp( %s, %s, %s );\n", sParam1.String(), sParam1.String(), g_szVecZeros[nComponents], g_szVecOnes[nComponents] ); + } +} + + +void D3DToGL::Handle_DP2ADD() +{ + char pDestReg[64], pSrc0Reg[64], pSrc1Reg[64], pSrc2Reg[64]; + uint32 nDestToken = GetNextToken(); + PrintParameterToString( nDestToken, DST_REGISTER, pDestReg, sizeof( pDestReg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc0Reg, sizeof( pSrc0Reg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc1Reg, sizeof( pSrc1Reg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc2Reg, sizeof( pSrc2Reg ), false, NULL ); + + // We should only be assigning to a single component of the dest. + Assert( GetNumSwizzleComponents( pDestReg ) == 1 ); + Assert( GetNumSwizzleComponents( pSrc2Reg ) == 1 ); + + // This is a 2D dot product, so we only want two entries from the middle components. + CUtlString sArg0 = EnsureNumSwizzleComponents( pSrc0Reg, 2 ); + CUtlString sArg1 = EnsureNumSwizzleComponents( pSrc1Reg, 2 ); + + PrintToBufWithIndents( *m_pBufALUCode, "%s = dot( %s, %s ) + %s;\n", pDestReg, sArg0.String(), sArg1.String(), pSrc2Reg ); + + // If the _SAT instruction modifier is used, then do a saturate here. + if ( nDestToken & D3DSPDM_SATURATE ) + { + int nComponents = GetNumSwizzleComponents( pDestReg ); + if ( nComponents == 0 ) + nComponents = 4; + + PrintToBufWithIndents( *m_pBufALUCode, "%s = clamp( %s, %s, %s );\n", pDestReg, pDestReg, g_szVecZeros[nComponents], g_szVecOnes[nComponents] ); + } +} + + +void D3DToGL::Handle_SINCOS() +{ + char pDestReg[64], pSrc0Reg[64]; + PrintParameterToString( GetNextToken(), DST_REGISTER, pDestReg, sizeof( pDestReg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc0Reg, sizeof( pSrc0Reg ), true, NULL ); + m_bNeedsSinCosDeclarations = true; + + + CUtlString sDest( pDestReg ); + CUtlString sArg0 = EnsureNumSwizzleComponents( pSrc0Reg, 1 );// Ensure input is scalar + CUtlString sResult( "vSinCosTmp.xy" ); // Always going to populate this + sResult = FixGLSLSwizzle( sDest, sResult ); // Make sure we match the desired output reg + + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.z = %s * %s;\n", sArg0.String(), sArg0.String() ); + + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.xy = vSinCosTmp.zz * scA.xy + scA.wz;\n" ); + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.xy = vSinCosTmp.xy * vSinCosTmp.zz + scB.xy;\n" ); + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.xy = vSinCosTmp.xy * vSinCosTmp.zz + scB.wz;\n" ); + + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.x = vSinCosTmp.x * %s;\n", sArg0.String() ); + + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.xy = vSinCosTmp.xy * vSinCosTmp.xx;\n" ); + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.xy = vSinCosTmp.xy + vSinCosTmp.xy;\n" ); + PrintToBufWithIndents( *m_pBufALUCode, "vSinCosTmp.x = -vSinCosTmp.x + scB.z;\n" ); + + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s;\n", sDest.String(), sResult.String() ); + + if ( m_dwMajorVersion < 3 ) + { + // Eat two more tokens since D3D defines Taylor series constants that we won't need + // Only valid for pixel and vertex shader version earlier than 3_0 + // (http://msdn.microsoft.com/en-us/library/windows/hardware/ff569710(v=vs.85).aspx) + SkipTokens( 2 ); + } +} + + +void D3DToGL::Handle_LRP( uint32 nInstruction ) +{ + uint32 nDestToken = GetNextToken(); + CUtlString sDest = GetParameterString( nDestToken, DST_REGISTER, false, NULL ); + int nARLComp0 = ARL_DEST_NONE; + CUtlString sParam0 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp0 ); + int nARLComp1 = ARL_DEST_NONE; + CUtlString sParam1 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp1 ); + int nARLComp2 = ARL_DEST_NONE; + CUtlString sParam2 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp2 ); + + // This optionally inserts a move from our dummy address register to the .x component of the real one + InsertMoveFromAddressRegister( m_pBufALUCode, nARLComp0, nARLComp1, nARLComp2 ); + + sParam0 = FixGLSLSwizzle( sDest, sParam0 ); + sParam1 = FixGLSLSwizzle( sDest, sParam1 ); + sParam2 = FixGLSLSwizzle( sDest, sParam2 ); + + // dest = src0 * (src1 - src2) + src2; + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s * ( %s - %s ) + %s;\n", sDest.String(), sParam0.String(), sParam1.String(), sParam2.String(), sParam2.String() ); + + // If the _SAT instruction modifier is used, then do a saturate here. + if ( nDestToken & D3DSPDM_SATURATE ) + { + int nComponents = GetNumSwizzleComponents( sDest.String() ); + if ( nComponents == 0 ) + nComponents = 4; + + PrintToBufWithIndents( *m_pBufALUCode, "%s = clamp( %s, %s, %s );\n", sDest.String(), sDest.String(), g_szVecZeros[nComponents], g_szVecOnes[nComponents] ); + } +} + + +void D3DToGL::Handle_TEX( uint32 dwToken, bool bIsTexLDL ) +{ + char pDestReg[64], pSrc0Reg[64], pSrc1Reg[64]; + PrintParameterToString( GetNextToken(), DST_REGISTER, pDestReg, sizeof( pDestReg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc0Reg, sizeof( pSrc0Reg ), false, NULL ); + + DWORD dwSrc1Token = GetNextToken(); + PrintParameterToString( dwSrc1Token, SRC_REGISTER, pSrc1Reg, sizeof( pSrc1Reg ), false, NULL ); + + Assert( (dwSrc1Token & D3DSP_REGNUM_MASK) < ARRAYSIZE( m_dwSamplerTypes ) ); + uint32 nSamplerType = m_dwSamplerTypes[dwSrc1Token & D3DSP_REGNUM_MASK]; + if ( nSamplerType == SAMPLER_TYPE_2D ) + { + const bool bIsShadowSampler = ( ( 1 << ( (int) ( dwSrc1Token & D3DSP_REGNUM_MASK ) ) ) & m_nShadowDepthSamplerMask ) != 0; + + if ( bIsTexLDL ) + { + CUtlString sCoordVar = EnsureNumSwizzleComponents( pSrc0Reg, bIsShadowSampler ? 3 : 2 ); + + // Strip out the W component of the pSrc0Reg and pass that as the LOD to texture2DLod. + char szLOD[128], szExtra[8]; + GetParamNameWithoutSwizzle( pSrc0Reg, szLOD, sizeof( szLOD ) ); + V_snprintf( szExtra, sizeof( szExtra ), ".%c", GetSwizzleComponent( pSrc0Reg, 3 ) ); + V_strncat( szLOD, szExtra, sizeof( szLOD ) ); + + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s( %s, %s, %s );\n", pDestReg, "textureLod", pSrc1Reg, sCoordVar.String(), szLOD ); + } + else if ( bIsShadowSampler ) + { + // .z is meant to contain the object depth, while .xy contains the 2D tex coords + CUtlString sCoordVar3D = EnsureNumSwizzleComponents( pSrc0Reg, 3 ); + + PrintToBufWithIndents( *m_pBufALUCode, "%s = vec4(texture( %s, %s ));\n", pDestReg, pSrc1Reg, sCoordVar3D.String() ); + Assert( m_dwSamplerTypes[dwSrc1Token & D3DSP_REGNUM_MASK] == SAMPLER_TYPE_2D ); + } + else if( ( OpcodeSpecificData( dwToken ) << D3DSP_OPCODESPECIFICCONTROL_SHIFT ) == D3DSI_TEXLD_PROJECT ) + { + // This projective case is after the shadow case intentionally, due to the way that "projective" + // loads are overloaded in our D3D shaders for shadow lookups. + // + // We use the vec4 variant of texture2DProj() intentionally here, since it lines up well with Direct3D. + + CUtlString s4DProjCoords = EnsureNumSwizzleComponents( pSrc0Reg, 4 ); // Ensure vec4 variant + PrintToBufWithIndents( *m_pBufALUCode, "%s = textureProj( %s, %s );\n", pDestReg, pSrc1Reg, s4DProjCoords.String() ); + } + else + { + CUtlString sCoordVar = EnsureNumSwizzleComponents( pSrc0Reg, bIsShadowSampler ? 3 : 2 ); + PrintToBufWithIndents( *m_pBufALUCode, "%s = texture( %s, %s );\n", pDestReg, pSrc1Reg, sCoordVar.String() ); + } + } + else if ( nSamplerType == SAMPLER_TYPE_3D ) + { + if ( bIsTexLDL ) + { + TranslationError(); + } + + CUtlString sCoordVar = EnsureNumSwizzleComponents( pSrc0Reg, 3 ); + PrintToBufWithIndents( *m_pBufALUCode, "%s = texture( %s, %s );\n", pDestReg, pSrc1Reg, sCoordVar.String() ); + } + else if ( nSamplerType == SAMPLER_TYPE_CUBE ) + { + if ( bIsTexLDL ) + { + TranslationError(); + } + + CUtlString sCoordVar = EnsureNumSwizzleComponents( pSrc0Reg, 3 ); + PrintToBufWithIndents( *m_pBufALUCode, "%s = texture( %s, %s );\n", pDestReg, pSrc1Reg, sCoordVar.String() ); + } + else + { + Error( "TEX instruction: unsupported sampler type used" ); + } +} + +void D3DToGL::StrcatToHeaderCode( const char *pBuf ) +{ + strcat_s( (char*)m_pBufHeaderCode->Base(), m_pBufHeaderCode->Size(), pBuf ); +} + +void D3DToGL::StrcatToALUCode( const char *pBuf ) +{ + PrintIndentation( (char*)m_pBufALUCode->Base(), m_pBufALUCode->Size() ); + + strcat_s( (char*)m_pBufALUCode->Base(), m_pBufALUCode->Size(), pBuf ); +} + +void D3DToGL::StrcatToParamCode( const char *pBuf ) +{ + strcat_s( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size(), pBuf ); +} + +void D3DToGL::StrcatToAttribCode( const char *pBuf ) +{ + strcat_s( (char*)m_pBufAttribCode->Base(), m_pBufAttribCode->Size(), pBuf ); +} + +void D3DToGL::Handle_TexLDD( uint32 nInstruction ) +{ + TranslationError(); // Not supported yet, but can be if we need it. +} + + +void D3DToGL::Handle_TexCoord() +{ + TranslationError(); + + // If ps_1_4, this is texcrd + if ( (m_dwMajorVersion == 1) && (m_dwMinorVersion == 4) && (!m_bVertexShader) ) + { + StrcatToALUCode( "texcrd" ); + } + else // else it's texcoord + { + TranslationError(); + StrcatToALUCode( "texcoord" ); + } + + char buff[256]; + PrintParameterToString( GetNextToken(), DST_REGISTER, buff, sizeof( buff ), false, NULL ); + StrcatToALUCode( buff ); + + // If ps_1_4, texcrd also has a source parameter + if ((m_dwMajorVersion == 1) && (m_dwMinorVersion == 4) && (!m_bVertexShader)) + { + StrcatToALUCode( ", " ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, buff, sizeof( buff ), false, NULL ); + StrcatToALUCode( buff ); + } + + StrcatToALUCode( ";\n" ); +} + +void D3DToGL::Handle_BREAKC( uint32 dwToken ) +{ + uint nComparison = ( dwToken & D3DSHADER_COMPARISON_MASK ) >> D3DSHADER_COMPARISON_SHIFT; + + const char *pComparison = "?"; + switch ( nComparison ) + { + case D3DSPC_GT: pComparison = ">"; break; + case D3DSPC_EQ: pComparison = "=="; break; + case D3DSPC_GE: pComparison = ">="; break; + case D3DSPC_LT: pComparison = "<"; break; + case D3DSPC_NE: pComparison = "!="; break; + case D3DSPC_LE: pComparison = "<="; break; + default: + TranslationError(); + } + + char src0[256]; + uint32 src0Token = GetNextToken(); + PrintParameterToString( src0Token, SRC_REGISTER, src0, sizeof( src0 ), false, NULL ); + + char src1[256]; + uint32 src1Token = GetNextToken(); + PrintParameterToString( src1Token, SRC_REGISTER, src1, sizeof( src1 ), false, NULL ); + + PrintToBufWithIndents( *m_pBufALUCode, "if (%s %s %s) break;\n", src0, pComparison, src1 ); +} + +void D3DToGL::HandleBinaryOp_GLSL( uint32 nInstruction ) +{ + uint32 nDestToken = GetNextToken(); + CUtlString sParam1 = GetParameterString( nDestToken, DST_REGISTER, false, NULL ); + int nARLComp0 = ARL_DEST_NONE; + CUtlString sParam2 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp0 ); + int nARLComp1 = ARL_DEST_NONE; + CUtlString sParam3 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp1 ); + + // This optionally inserts a move from our dummy address register to the .x component of the real one + InsertMoveFromAddressRegister( m_pBufALUCode, nARLComp0, nARLComp1 ); + + // Since DP3 and DP4 have a scalar as the dest and vectors as the src, don't screw with the swizzle specifications. + if ( nInstruction == D3DSIO_DP3 ) + { + sParam2 = EnsureNumSwizzleComponents( sParam2, 3 ); + sParam3 = EnsureNumSwizzleComponents( sParam3, 3 ); + } + else if ( nInstruction == D3DSIO_DP4 ) + { + sParam2 = EnsureNumSwizzleComponents( sParam2, 4 ); + sParam3 = EnsureNumSwizzleComponents( sParam3, 4 ); + } + else if ( nInstruction == D3DSIO_DST ) + { + m_bUsesDSTInstruction = true; + sParam2 = EnsureNumSwizzleComponents( sParam2, 4 ); + sParam3 = EnsureNumSwizzleComponents( sParam3, 4 ); + } + else + { + sParam2 = FixGLSLSwizzle( sParam1, sParam2 ); + sParam3 = FixGLSLSwizzle( sParam1, sParam3 ); + } + + char buff[256]; + if ( nInstruction == D3DSIO_ADD || nInstruction == D3DSIO_SUB || nInstruction == D3DSIO_MUL ) + { + // These all look like x = y op z + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s %s %s;\n", sParam1.String(), sParam2.String(), GetGLSLOperatorString( nInstruction ), sParam3.String() ); + } + else + { + int nDestComponents = GetNumSwizzleComponents( sParam1.String() ); + int nSrcComponents = GetNumSwizzleComponents( sParam2.String() ); + + // All remaining instructions can use GLSL intrinsics like dot() and cross(). + bool bDoubleClose = OpenIntrinsic( nInstruction, buff, sizeof( buff ), nDestComponents, nSrcComponents ); + + if ( ( nSrcComponents == 1 ) && ( nInstruction == D3DSIO_SGE ) ) + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s%s >= %s );\n", sParam1.String(), buff, sParam2.String(), sParam3.String() ); + } + else if ( ( nSrcComponents == 1 ) && ( nInstruction == D3DSIO_SLT ) ) + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s%s < %s );\n", sParam1.String(), buff, sParam2.String(), sParam3.String() ); + } + else + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s%s, %s %s;\n", sParam1.String(), buff, sParam2.String(), sParam3.String(), bDoubleClose ? ") )" : ")" ); + } + } + + // If the _SAT instruction modifier is used, then do a saturate here. + if ( nDestToken & D3DSPDM_SATURATE ) + { + int nComponents = GetNumSwizzleComponents( sParam1.String() ); + if ( nComponents == 0 ) + nComponents = 4; + + PrintToBufWithIndents( *m_pBufALUCode, "%s = clamp( %s, %s, %s );\n", sParam1.String(), sParam1.String(), g_szVecZeros[nComponents], g_szVecOnes[nComponents] ); + } +} + +void D3DToGL::HandleBinaryOp_ASM( uint32 nInstruction ) +{ + CUtlString sParam1 = GetParameterString( GetNextToken(), DST_REGISTER, false, NULL ); + int nARLComp0 = ARL_DEST_NONE; + CUtlString sParam2 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp0 ); + int nARLComp1 = ARL_DEST_NONE; + CUtlString sParam3 = GetParameterString( GetNextToken(), SRC_REGISTER, false, &nARLComp1 ); + + // This optionally inserts a move from our dummy address register to the .x component of the real one + InsertMoveFromAddressRegister( m_pBufALUCode, nARLComp0, nARLComp1 ); + + char buff[256]; + PrintOpcode( nInstruction, buff, sizeof( buff ) ); + PrintToBufWithIndents( *m_pBufALUCode, "%s%s, %s, %s;\n", buff, sParam1.String(), sParam2.String(), sParam3.String() ); +} + +void D3DToGL::WriteGLSLCmp( const char *pDestReg, const char *pSrc0Reg, const char *pSrc1Reg, const char *pSrc2Reg ) +{ + int nWriteMaskEntries = GetNumWriteMaskEntries( pDestReg ); + for ( int i=0; i < nWriteMaskEntries; i++ ) + { + char params[4][256]; + WriteParamWithSingleMaskEntry( pDestReg, i, params[0], sizeof( params[0] ) ); + WriteParamWithSingleMaskEntry( pSrc0Reg, i, params[1], sizeof( params[1] ) ); + WriteParamWithSingleMaskEntry( pSrc1Reg, i, params[2], sizeof( params[2] ) ); + WriteParamWithSingleMaskEntry( pSrc2Reg, i, params[3], sizeof( params[3] ) ); + + PrintToBufWithIndents( *m_pBufALUCode, "%s = ( %s >= 0.0 ) ? %s : %s;\n", params[0], params[1], params[2], params[3] ); + } +} + +void D3DToGL::Handle_CMP() +{ + // In Direct3D, result = (src0 >= 0.0) ? src1 : src2 + // In OpenGL, result = (src0 < 0.0) ? src1 : src2 + // + // As a result, arguments are effectively in a different order than Direct3D! !#$&*!%#$& + char pDestReg[64], pSrc0Reg[64], pSrc1Reg[64], pSrc2Reg[64]; + uint32 nDestToken = GetNextToken(); + PrintParameterToString( nDestToken, DST_REGISTER, pDestReg, sizeof( pDestReg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc0Reg, sizeof( pSrc0Reg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc1Reg, sizeof( pSrc1Reg ), false, NULL ); + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc2Reg, sizeof( pSrc2Reg ), false, NULL ); + + // These are a tricky case.. we have to expand it out into multiple statements. + char szDestBase[256]; + GetParamNameWithoutSwizzle( pDestReg, szDestBase, sizeof( szDestBase ) ); + + V_strncpy( pSrc0Reg, FixGLSLSwizzle( pDestReg, pSrc0Reg ), sizeof( pSrc0Reg ) ); + V_strncpy( pSrc1Reg, FixGLSLSwizzle( pDestReg, pSrc1Reg ), sizeof( pSrc1Reg ) ); + V_strncpy( pSrc2Reg, FixGLSLSwizzle( pDestReg, pSrc2Reg ), sizeof( pSrc2Reg ) ); + + // This isn't reliable! + //if ( DoParamNamesMatch( pDestReg, pSrc0Reg ) && GetNumSwizzleComponents( pDestReg ) > 1 ) + if ( 1 ) + { + // So the dest register is the same as the comparand. We're in danger of screwing up our results. + // + // For example, this code: + // CMP r0.xy, r0.xx, r1, r2 + // would generate this: + // r0.x = (r0.x >= 0) ? r1.x : r2.x; + // r0.y = (r0.x >= 0) ? r1.x : r2.x; + // + // But the first lines changes r0.x and thus screws the atomicity of the CMP instruction for the second line. + // So we assign r0 to a temporary first and then write to the temporary. + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s;\n", g_pAtomicTempVarName, szDestBase ); + + char szTempVar[256]; + ReplaceParamName( pDestReg, g_pAtomicTempVarName, szTempVar, sizeof( szTempVar ) ); + WriteGLSLCmp( szTempVar, pSrc0Reg, pSrc1Reg, pSrc2Reg ); + + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s;\n", szDestBase, g_pAtomicTempVarName ); + m_bUsedAtomicTempVar = true; + } + else + { + // Just write out the simple expanded version of the CMP. No need to use atomic_temp_var. + WriteGLSLCmp( pDestReg, pSrc0Reg, pSrc1Reg, pSrc2Reg ); + } + + // If the _SAT instruction modifier is used, then do a saturate here. + if ( nDestToken & D3DSPDM_SATURATE ) + { + int nComponents = GetNumSwizzleComponents( pDestReg ); + if ( nComponents == 0 ) + nComponents = 4; + + PrintToBufWithIndents( *m_pBufALUCode, "%s = clamp( %s, %s, %s );\n", pDestReg, pDestReg, g_szVecZeros[nComponents], g_szVecOnes[nComponents] ); + } +} + +void D3DToGL::Handle_NRM() +{ + char pDestReg[64]; + char pSrc0Reg[64]; + PrintParameterToString( GetNextToken(), DST_REGISTER, pDestReg, sizeof( pDestReg ), false, NULL ); + int nARLSrcComp = ARL_DEST_NONE; + PrintParameterToString( GetNextToken(), SRC_REGISTER, pSrc0Reg, sizeof( pSrc0Reg ), false, &nARLSrcComp ); + + if ( nARLSrcComp != -1 ) + { + InsertMoveFromAddressRegister( m_pBufALUCode, nARLSrcComp, -1, -1 ); + } + + CUtlString sSrc = EnsureNumSwizzleComponents( pSrc0Reg, 3 ); + PrintToBufWithIndents( *m_pBufALUCode, "%s = normalize( %s );\n", pDestReg, sSrc.String() ); +} + +void D3DToGL::Handle_UnaryOp( uint32 nInstruction ) +{ + uint32 nDestToken = GetNextToken(); + CUtlString sParam1 = GetParameterString( nDestToken, DST_REGISTER, false, NULL ); + CUtlString sParam2 = GetParameterString( GetNextToken(), SRC_REGISTER, false, NULL ); + sParam2 = FixGLSLSwizzle( sParam1, sParam2 ); + + + if ( nInstruction == D3DSIO_MOV ) + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s;\n", sParam1.String(), sParam2.String() ); + } + else if ( nInstruction == D3DSIO_RSQ ) + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = inversesqrt( %s );\n", sParam1.String(), sParam2.String() ); + } + else if ( nInstruction == D3DSIO_RCP ) + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = 1.0 / %s;\n", sParam1.String(), sParam2.String() ); + } + else if ( nInstruction == D3DSIO_EXP ) + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = exp2( %s );\n", sParam1.String(), sParam2.String() ); + } + else if ( nInstruction == D3DSIO_FRC ) + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = fract( %s );\n", sParam1.String(), sParam2.String() ); + } + else if ( nInstruction == D3DSIO_LOG ) // d3d 'log' is log base 2 + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = log2( %s );\n", sParam1.String(), sParam2.String() ); + } + else if ( nInstruction == D3DSIO_ABS ) // rbarris did this one, Jason please check + { + PrintToBufWithIndents( *m_pBufALUCode, "%s = abs( %s );\n", sParam1.String(), sParam2.String() ); + } + else if ( nInstruction == D3DSIO_MOVA ) + { + m_bDeclareAddressReg = true; + PrintToBufWithIndents( *m_pBufALUCode, "%s = %s;\n", sParam1.String(), sParam2.String() ); + + if ( !m_bGenerateBoneUniformBuffer ) + { + m_nHighestRegister = DXABSTRACT_VS_PARAM_SLOTS - 1; + } + } + else + { + Error( "Unsupported instruction" ); + } + + // If the _SAT instruction modifier is used, then do a saturate here. + if ( nDestToken & D3DSPDM_SATURATE ) + { + int nComponents = GetNumSwizzleComponents( sParam1.String() ); + if ( nComponents == 0 ) + { + nComponents = 4; + } + + PrintToBufWithIndents( *m_pBufALUCode, "%s = clamp( %s, %s, %s );\n", sParam1.String(), sParam1.String(), g_szVecZeros[nComponents], g_szVecOnes[nComponents] ); + } +} + +void D3DToGL::WriteGLSLSamplerDefinitions() +{ + int nSamplersWritten = 0; + bool m_bSampler3d = false; + bool m_bShadowSampler = false; + for ( int i=0; i < ARRAYSIZE( m_dwSamplerTypes ); i++ ) + { + if ( m_dwSamplerTypes[i] == SAMPLER_TYPE_2D ) + { + if ( ( ( 1 << i ) & m_nShadowDepthSamplerMask ) != 0 ) + { + if( !m_bShadowSampler ) + { + PrintToBuf( *m_pBufHeaderCode, "precision lowp sampler2DShadow;\n", i ); + m_bShadowSampler = true; + } + PrintToBuf( *m_pBufHeaderCode, "uniform sampler2DShadow sampler%d;\n", i ); + } + else + { + PrintToBuf( *m_pBufHeaderCode, "uniform sampler2D sampler%d;\n", i ); + } + ++nSamplersWritten; + } + else if ( m_dwSamplerTypes[i] == SAMPLER_TYPE_3D ) + { + if( !m_bSampler3d ) + { + StrcatToHeaderCode( "precision mediump sampler3D;\n" ); + m_bSampler3d = true; + } + PrintToBuf( *m_pBufHeaderCode, "uniform sampler3D sampler%d;\n", i ); + ++nSamplersWritten; + } + else if ( m_dwSamplerTypes[i] == SAMPLER_TYPE_CUBE ) + { + PrintToBuf( *m_pBufHeaderCode, "uniform samplerCube sampler%d;\n", i ); + ++nSamplersWritten; + } + else if ( m_dwSamplerTypes[i] != SAMPLER_TYPE_UNUSED ) + { + Error( "Unknown sampler type." ); + } + } + + if ( nSamplersWritten > 0 ) + PrintToBuf( *m_pBufHeaderCode, "\n\n" ); +} + +void D3DToGL::WriteGLSLOutputVariableAssignments() +{ + if ( m_bVertexShader ) + { + // Map output "oN" registers back to GLSL output variables. + if ( m_bAddHexCodeComments ) + { + PrintToBuf( *m_pBufAttribCode, "\n// Now we're storing the oN variables from the output dcl_ statements back into their GLSL equivalents.\n" ); + } + + for ( int i=0; i < ARRAYSIZE( m_DeclaredOutputs ); i++ ) + { + if ( m_DeclaredOutputs[i] == UNDECLARED_OUTPUT ) + continue; + + if ( ( m_dwTexCoordOutMask & ( 1 << i ) ) == 0 ) + continue; + + uint32 dwToken = m_DeclaredOutputs[i]; + + uint32 dwUsage = ( dwToken & D3DSP_DCL_USAGE_MASK ); + uint32 dwUsageIndex = ( dwToken & D3DSP_DCL_USAGEINDEX_MASK ) >> D3DSP_DCL_USAGEINDEX_SHIFT; + + if ( ( dwUsage == D3DDECLUSAGE_FOG ) || ( dwUsage == D3DDECLUSAGE_PSIZE ) ) + { + TranslationError(); // Not supported yet, but can be if we need it. + } + + if ( dwUsage == D3DDECLUSAGE_COLOR ) + { + if( !m_bFrontColor ) + { + StrcatToHeaderCode("varying highp vec4 _gl_FrontColor;\n"); + m_bFrontColor = true; + } + + PrintToBufWithIndents( *m_pBufALUCode, "%s = oTempT%d;\n", dwUsageIndex ? "gl_FrontSecondaryColor" : "_gl_FrontColor", i ); + } + else if ( dwUsage == D3DDECLUSAGE_TEXCOORD ) + { + char buf[256]; + if ( m_nCentroidMask & ( 0x00000001 << dwUsageIndex ) ) + { + V_snprintf( buf, sizeof( buf ), "centroid out vec4 oT%d;\n", dwUsageIndex ); // centroid varying + } + else + { + V_snprintf( buf, sizeof( buf ), "out vec4 oT%d;\n", dwUsageIndex ); + } + StrcatToHeaderCode( buf ); + + PrintToBufWithIndents( *m_pBufALUCode, "oT%d = oTempT%d;\n", dwUsageIndex, i ); + } + } + } +} + +void D3DToGL::WriteGLSLInputVariableAssignments() +{ + if ( m_bVertexShader ) + return; + + for ( int i=0; i < ARRAYSIZE( m_DeclaredInputs ); i++ ) + { + if ( m_DeclaredInputs[i] == UNDECLARED_INPUT ) + continue; + + uint32 dwToken = m_DeclaredInputs[i]; + + uint32 dwUsage = ( dwToken & D3DSP_DCL_USAGE_MASK ); + uint32 dwUsageIndex = ( dwToken & D3DSP_DCL_USAGEINDEX_MASK ) >> D3DSP_DCL_USAGEINDEX_SHIFT; + + if ( dwUsage == D3DDECLUSAGE_COLOR ) + { + PrintToBufWithIndents( *m_pBufAttribCode, "vec4 oTempT%d = %s;\n", i, dwUsageIndex ? "_gl_FrontSecondaryColor" : "_gl_FrontColor" ); + } + else if ( dwUsage == D3DDECLUSAGE_TEXCOORD ) + { + PrintToBufWithIndents( *m_pBufAttribCode, "vec4 oTempT%d = oT%d;\n", i, dwUsageIndex ); + } + } +} + +void D3DToGL::Handle_DeclarativeNonDclOp( uint32 nInstruction ) +{ + char buff[128]; + uint32 dwToken = GetNextToken(); + PrintParameterToString( dwToken, DST_REGISTER, buff, sizeof( buff ), false, NULL ); + + if ( nInstruction == D3DSIO_TEXKILL ) + { + // TEXKILL is supposed to discard the pixel if any of the src register's X, Y, or Z components are less than zero. + // We have to translate it to something like: + // if ( r0.x < 0.0 || r0.y < 0.0 ) + // discard; + char c[3]; + c[0] = GetSwizzleComponent( buff, 0 ); + c[1] = GetSwizzleComponent( buff, 1 ); + c[2] = GetSwizzleComponent( buff, 2 ); + + // Get the unique components. + char cUnique[3]; + cUnique[0] = c[0]; + + int nUnique = 1; + if ( c[1] != c[0] ) + cUnique[nUnique++] = c[1]; + + if ( c[2] != c[1] && c[2] != c[0] ) + cUnique[nUnique++] = c[2]; + + // Get the src register base name. + char szBase[256]; + GetParamNameWithoutSwizzle( buff, szBase, sizeof( szBase ) ); + + PrintToBufWithIndents( *m_pBufALUCode, "if ( %s.%c < 0.0 ", szBase, cUnique[0] ); + for ( int i=1; i < nUnique; i++ ) + { + PrintToBuf( *m_pBufALUCode, "|| %s.%c < 0.0 ", szBase, cUnique[i] ); + } + PrintToBuf( *m_pBufALUCode, ")\n{\n\tdiscard;\n}\n" ); + } + else + { + char szOpcode[128]; + PrintOpcode( nInstruction, szOpcode, sizeof( szOpcode ) ); + StrcatToALUCode( szOpcode ); + + StrcatToALUCode( buff ); + StrcatToALUCode( ";\n" ); + } +} + + +void D3DToGL::NoteTangentInputUsed() +{ + if ( !m_bTangentInputUsed ) + { + m_bTangentInputUsed = true; +// PrintToBuf( *m_pBufParamCode, "attribute vec4 %s;\n", g_pTangentAttributeName ); + } +} + + +// These are the only ARL instructions that should appear in the instruction stream +void D3DToGL::InsertMoveInstruction( CUtlBuffer *pCode, int nARLComponent ) +{ + PrintIndentation( ( char * )pCode->Base(), pCode->Size() ); + + switch ( nARLComponent ) + { + case ARL_DEST_X: + strcat_s( ( char * )pCode->Base(), pCode->Size(), "a0 = int( va_r.x );\n" ); + break; + case ARL_DEST_Y: + strcat_s( ( char * )pCode->Base(), pCode->Size(), "a0 = int( va_r.y );\n" ); + break; + case ARL_DEST_Z: + strcat_s( ( char * )pCode->Base(), pCode->Size(), "a0 = int( va_r.z );\n" ); + break; + case ARL_DEST_W: + strcat_s( ( char * )pCode->Base(), pCode->Size(), "a0 = int( va_r.w );\n" ); + break; + } +} + +// This optionally inserts a move from our dummy address register to the .x component of the real one +void D3DToGL::InsertMoveFromAddressRegister( CUtlBuffer *pCode, int nARLComp0, int nARLComp1, int nARLComp2 /* = ARL_DEST_NONE */ ) +{ + // We no longer need to do this in GLSL - we put the cast to int from the dummy address register va_r.x, va_r.y, etc. directly into the instruction + return; +} + + +//------------------------------------------------------------------------------ +// TranslateShader() +// +// This is the main function that the outside world sees. A pointer to the +// uint32 stream returned from the D3DX compile routine is parsed and used +// to write human-readable asm code into the character array pointed to by +// pDisassembledCode. An error code is returned. +//------------------------------------------------------------------------------ + + +int D3DToGL::TranslateShader( uint32* code, CUtlBuffer *pBufDisassembledCode, bool *bVertexShader, uint32 options, int32 nShadowDepthSamplerMask, uint32 nCentroidMask, char *debugLabel ) +{ + CUtlString sLine, sParamName; + uint32 i, dwToken, nInstruction, nNumTokensToSkip; + char buff[256]; + + // obey options + m_bUseEnvParams = (options & D3DToGL_OptionUseEnvParams) != 0; + m_bDoFixupZ = (options & D3DToGL_OptionDoFixupZ) != 0; + m_bDoFixupY = (options & D3DToGL_OptionDoFixupY) != 0; + m_bDoUserClipPlanes = (options & D3DToGL_OptionDoUserClipPlanes) != 0; + + m_bFrontSecondaryColor = false; + m_bFogFragCoord = false; + m_bColor = false; + m_bFrontColor = false; + m_bSecondaryColor = false; + m_iFragDataCount = 0; + + m_bAddHexCodeComments = (options & D3DToGL_AddHexComments) != 0; + m_bPutHexCodesAfterLines = (options & D3DToGL_PutHexCommentsAfterLines) != 0; + m_bGeneratingDebugText = (options & D3DToGL_GeneratingDebugText) != 0; + m_bGenerateSRGBWriteSuffix = (options & D3DToGL_OptionSRGBWriteSuffix) != 0; + m_bGenerateSRGBWriteSuffix = false; + + if( debugLabel && (V_strstr( debugLabel ,"vertexlit_and_unlit_generic_ps") || V_strstr( debugLabel ,"vertexlit_and_unlit_generic_bump_ps") ) ) + m_bGenerateSRGBWriteSuffix = true; + + m_NumIndentTabs = 1; // start code indented one tab + m_nLoopDepth = 0; + + // debugging + m_bSpew = (options & D3DToGL_OptionSpew) != 0; + + // These are not accessed below in a way that will cause them to glow, so + // we could overflow these and/or the buffer pointed to by pDisassembledCode + m_pBufAttribCode = new CUtlBuffer( 100, 10000, CUtlBuffer::TEXT_BUFFER ); + m_pBufParamCode = new CUtlBuffer( 100, 10000, CUtlBuffer::TEXT_BUFFER ); + m_pBufALUCode = new CUtlBuffer( 100, 60000, CUtlBuffer::TEXT_BUFFER ); + + // Pointers to text buffers for assembling sections of the program + m_pBufHeaderCode = pBufDisassembledCode; + char *pAttribMapStart = NULL; + ((char*)m_pBufHeaderCode->Base())[0] = 0; + ((char*)m_pBufAttribCode->Base())[0] = 0; + ((char*)m_pBufParamCode->Base())[0] = 0; + ((char*)m_pBufALUCode->Base())[0] = 0; + + + for ( i=0; iBase(), m_pBufHeaderCode->Size(), "#version 300 es\nprecision highp float;\n#define varying in\n\n%s", glslExtText ); + m_bVertexShader = false; + } + else // vertex shader + { + m_bGenerateSRGBWriteSuffix = false; + V_snprintf( (char *)m_pBufHeaderCode->Base(), m_pBufHeaderCode->Size(), "#version 300 es\nprecision highp float;\n#define attribute in\n#define varying out\n%s//ATTRIBMAP-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx-xx\n", glslExtText ); + + // find that first '-xx' which is where the attrib map will be written later. + pAttribMapStart = strstr( (char *)m_pBufHeaderCode->Base(), "-xx" ) + 1; + + m_bVertexShader = true; + } + + *bVertexShader = m_bVertexShader; + + m_bGenerateBoneUniformBuffer = m_bVertexShader && ((options & D3DToGL_OptionGenerateBoneUniformBuffer) != 0); + + if ( m_bAddHexCodeComments ) + { + RecordInputAndOutputPositions(); + } + + if ( m_bSpew ) + { + printf("\n************* translating shader " ); + } + + int opcounter = 0; + + // Loop until we hit the end dwToken...note that D3DPS_END() == D3DVS_END() so this works for either + while ( dwToken != D3DPS_END() ) + { + if ( m_bAddHexCodeComments ) + { + AddTokenHexCode(); + RecordInputAndOutputPositions(); + } + +#ifdef POSIX + int tokenIndex = m_pdwNextToken - code; +#endif + int aluCodeLength0 = V_strlen( (char *) m_pBufALUCode->Base() ); + + dwToken = GetNextToken(); // Get next dwToken in the stream + nInstruction = Opcode( dwToken ); // Mask out the instruction opcode + + if ( m_bSpew ) + { +#ifdef POSIX + printf("\n** token# %04x inst# %04d opcode %s (%08x)", tokenIndex, opcounter, GLMDecode(eD3D_SIO, nInstruction), dwToken ); +#endif + opcounter++; + } + + switch ( nInstruction ) + { + // -- No arguments at all ----------------------------------------------- + case D3DSIO_NOP: + // D3D compiler outputs NOPs when shader debugging/optimizations are disabled. + break; + + case D3DSIO_PHASE: + case D3DSIO_RET: + case D3DSIO_ENDLOOP: + case D3DSIO_BREAK: + TranslationError(); + PrintOpcode( nInstruction, buff, sizeof( buff ) ); + StrcatToALUCode( buff ); + StrcatToALUCode( ";\n" ); + break; + + // -- "Declarative" non dcl ops ---------------------------------------- + case D3DSIO_TEXDEPTH: + case D3DSIO_TEXKILL: + Handle_DeclarativeNonDclOp( nInstruction ); + break; + + // -- Unary ops ------------------------------------------------- + case D3DSIO_BEM: + case D3DSIO_TEXBEM: + case D3DSIO_TEXBEML: + case D3DSIO_TEXDP3: + case D3DSIO_TEXDP3TEX: + case D3DSIO_TEXM3x2DEPTH: + case D3DSIO_TEXM3x2TEX: + case D3DSIO_TEXM3x3: + case D3DSIO_TEXM3x3PAD: + case D3DSIO_TEXM3x3TEX: + case D3DSIO_TEXM3x3VSPEC: + case D3DSIO_TEXREG2AR: + case D3DSIO_TEXREG2GB: + case D3DSIO_TEXREG2RGB: + case D3DSIO_LABEL: + case D3DSIO_CALL: + case D3DSIO_LOOP: + case D3DSIO_BREAKP: + case D3DSIO_DSX: + case D3DSIO_DSY: + TranslationError(); + break; + + case D3DSIO_IFC: + { + static const char *s_szCompareStrings[ 7 ] = + { + "__INVALID__", + ">", + "==", + ">=", + "<", + "!=", + "<=" + }; + + // Compare mode is encoded in instruction token + uint32 dwCompareMode = OpcodeSpecificData( dwToken ); + + Assert( ( dwCompareMode >= 1 ) && ( dwCompareMode <= 6 ) ); + + // Get left side of compare + dwToken = GetNextToken(); + char szLeftSide[32]; + PrintParameterToString( dwToken, SRC_REGISTER, szLeftSide, sizeof( szLeftSide ), false, NULL ); + + // Get right side of compare + dwToken = GetNextToken(); + char szRightSide[32]; + PrintParameterToString( dwToken, SRC_REGISTER, szRightSide, sizeof( szRightSide ), false, NULL ); + + PrintToBufWithIndents( *m_pBufALUCode, "if ( %s %s %s )\n", szLeftSide, s_szCompareStrings[dwCompareMode], szRightSide ); + StrcatToALUCode( "{\n" ); + m_NumIndentTabs++; + + break; + } + case D3DSIO_IF: + dwToken = GetNextToken(); + PrintParameterToString( dwToken, SRC_REGISTER, buff, sizeof( buff ), false, NULL ); + + PrintToBufWithIndents( *m_pBufALUCode, "if ( %s )\n", buff ); + StrcatToALUCode( "{\n" ); + m_NumIndentTabs++; + + break; + + case D3DSIO_ELSE: + m_NumIndentTabs--; + StrcatToALUCode( "}\n" ); + StrcatToALUCode( "else\n" ); + StrcatToALUCode( "{\n" ); + m_NumIndentTabs++; + + break; + + case D3DSIO_ENDIF: + m_NumIndentTabs--; + StrcatToALUCode( "}\n" ); + + break; + + case D3DSIO_REP: + dwToken = GetNextToken(); + PrintParameterToString( dwToken, SRC_REGISTER, buff, sizeof( buff ), false, NULL ); + + // In practice, this is the only form of for loop that will appear in DX asm + PrintToBufWithIndents( *m_pBufALUCode, "for( int i=0; i < %s; i++ )\n", buff ); + StrcatToALUCode( "{\n" ); + + m_nLoopDepth++; + + // For now, we don't deal with loop nesting + // Easy enough to fix later with an array of loop names i, j, k etc + Assert( m_nLoopDepth <= 1 ); + + m_NumIndentTabs++; + + break; + + case D3DSIO_ENDREP: + m_nLoopDepth--; + m_NumIndentTabs--; + StrcatToALUCode( "}\n" ); + + break; + + case D3DSIO_NRM: + Handle_NRM(); + break; + + case D3DSIO_MOVA: + + Handle_UnaryOp( nInstruction ); + + break; + + // Unary operations + case D3DSIO_MOV: + case D3DSIO_RCP: + case D3DSIO_RSQ: + case D3DSIO_EXP: + case D3DSIO_EXPP: + case D3DSIO_LOG: + case D3DSIO_LOGP: + case D3DSIO_FRC: + case D3DSIO_LIT: + case D3DSIO_ABS: + Handle_UnaryOp( nInstruction ); + break; + + // -- Binary ops ------------------------------------------------- + case D3DSIO_TEXM3x3SPEC: + case D3DSIO_M4x4: + case D3DSIO_M4x3: + case D3DSIO_M3x4: + case D3DSIO_M3x3: + case D3DSIO_M3x2: + case D3DSIO_CALLNZ: + case D3DSIO_SETP: + TranslationError(); + break; + + case D3DSIO_BREAKC: + Handle_BREAKC( dwToken ); + break; + + // Binary Operations + case D3DSIO_ADD: + case D3DSIO_SUB: + case D3DSIO_MUL: + case D3DSIO_DP3: + case D3DSIO_DP4: + case D3DSIO_MIN: + case D3DSIO_MAX: + case D3DSIO_DST: + case D3DSIO_SLT: + case D3DSIO_SGE: + case D3DSIO_CRS: + case D3DSIO_POW: + HandleBinaryOp_GLSL( nInstruction ); + + break; + + // -- Ternary ops ------------------------------------------------- + case D3DSIO_DP2ADD: + Handle_DP2ADD(); + break; + case D3DSIO_LRP: + Handle_LRP( nInstruction ); + break; + case D3DSIO_SGN: + Assert( m_bVertexShader ); + TranslationError(); // TODO emulate with SLT etc + break; + case D3DSIO_CND: + TranslationError(); + break; + case D3DSIO_CMP: + Handle_CMP(); + break; + case D3DSIO_SINCOS: + Handle_SINCOS(); + break; + case D3DSIO_MAD: + Handle_MAD( nInstruction ); + break; + + // -- Quaternary op ------------------------------------------------ + case D3DSIO_TEXLDD: + Handle_TexLDD( nInstruction ); + break; + + // -- Special cases: texcoord vs texcrd and tex vs texld ----------- + case D3DSIO_TEXCOORD: + Handle_TexCoord(); + break; + + case D3DSIO_TEX: + Handle_TEX( dwToken, false ); + break; + + case D3DSIO_TEXLDL: + Handle_TEX( nInstruction, true ); + break; + + case D3DSIO_DCL: + Handle_DCL(); + break; + + case D3DSIO_DEFB: + case D3DSIO_DEFI: + Handle_DEFIB( nInstruction ); + break; + + case D3DSIO_DEF: + Handle_DEF(); + break; + + case D3DSIO_COMMENT: + // Using OpcodeSpecificData() can fail here since the comments can be longer than 0xff dwords + nNumTokensToSkip = ( dwToken & 0x0fff0000 ) >> 16; + SkipTokens( nNumTokensToSkip ); + break; + + case D3DSIO_END: + break; + } + + if ( m_bSpew ) + { + int aluCodeLength1 = V_strlen( (char *) m_pBufALUCode->Base() ); + if ( aluCodeLength1 != aluCodeLength0 ) + { + // code was emitted + printf( "\n > %s", ((char *)m_pBufALUCode->Base()) + aluCodeLength0 ); + + aluCodeLength0 = aluCodeLength1; + } + } + } + + // Note that this constant packing expects .wzyx swizzles in case we ever use the SINCOS code in a ps_2_x shader + // + // The Microsoft do cumentation on this is all kinds of broken and, strangely, these numbers don't even + // match the D3DSINCOSCONST1 and D3DSINCOSCONST2 constants used by the D3D assembly sincos instruction... + if ( m_bNeedsSinCosDeclarations ) + { + PrintIndentation( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size() ); + StrcatToParamCode( "vec4 scA = vec4( -1.55009923e-6, -2.17013894e-5, 0.00260416674, 0.00026041668 );\n" ); + PrintIndentation( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size() ); + StrcatToParamCode( "vec4 scB = vec4( -0.020833334, -0.125, 1.0, 0.5 );\n" ); + } + + // Stick in the sampler mask in hex + PrintToBuf( *m_pBufHeaderCode, "%sSAMPLERMASK-%x\n", "//", m_dwSamplerUsageMask ); + + uint nSamplerTypes = 0; + for ( int i = 0; i < 16; i++ ) + { + Assert( m_dwSamplerTypes[i] < 4); + nSamplerTypes |= ( m_dwSamplerTypes[i] << ( i * 2 ) ); + } + + PrintToBuf( *m_pBufHeaderCode, "%sSAMPLERTYPES-%x\n", "//", nSamplerTypes ); + + // fragData outputs referenced + uint nFragDataMask = 0; + for ( int i = 0; i < 4; i++ ) + { + nFragDataMask |= m_bOutputColorRegister[ i ] ? ( 1 << i ) : 0; + } + + PrintToBuf( *m_pBufHeaderCode, "%sFRAGDATAMASK-%x\n", "//", nFragDataMask ); + + // Uniforms + + PrintToBuf( *m_pBufHeaderCode, "//HIGHWATER-%d\n", m_nHighestRegister + 1 ); + if ( ( m_bVertexShader ) && ( m_bGenerateBoneUniformBuffer ) ) + { + PrintToBuf( *m_pBufHeaderCode, "//HIGHWATERBONE-%i\n", m_nHighestBoneRegister + 1 ); + } + + PrintToBuf( *m_pBufHeaderCode, "\nuniform vec4 %s[%d];\n", m_bVertexShader ? "vc" : "pc", m_nHighestRegister + 1 ); + + if ( ( m_nHighestBoneRegister >= 0 ) && ( m_bVertexShader ) && ( m_bGenerateBoneUniformBuffer ) ) + { + PrintToBuf( *m_pBufHeaderCode, "\nuniform vec4 %s[%d];\n", "vcbones", m_nHighestBoneRegister + 1 ); + } + + if ( m_bVertexShader ) + { + PrintToBuf( *m_pBufHeaderCode, "\nuniform vec4 vcscreen;\n" ); + } + + for( int i=0; i<32; i++ ) + { + if ( ( m_dwConstIntUsageMask & ( 0x00000001 << i ) ) && + ( !( m_dwDefConstIntUsageMask & ( 0x00000001 << i ) ) ) + ) + { + PrintToBuf( *m_pBufHeaderCode, "uniform int i%d ;\n", i ); + } + } + + for( int i=0; i<32; i++ ) + { + if ( m_dwDefConstIntUsageMask & ( 0x00000001 << i ) ) + { + PrintToBuf( *m_pBufHeaderCode, "const int i%d = %i;\n", i, m_dwDefConstIntIterCount[i] ); + } + } + + for( int i=0; i<32; i++ ) + { + if ( m_dwConstBoolUsageMask & ( 0x00000001 << i ) ) + { + PrintToBuf( *m_pBufHeaderCode, m_bVertexShader ? "uniform bool b%d;\n" : "uniform bool fb%d;\n", i ); + } + } + + // Control bit for sRGB Write suffix + + if ( m_bGenerateSRGBWriteSuffix ) + { + // R500 Hookup + // Set this guy to 1 when the sRGBWrite state is true, otherwise 0 + StrcatToHeaderCode( "uniform float flSRGBWrite;\n" ); + } + + PrintToBuf( *m_pBufHeaderCode, "\n" ); + + // Write samplers + WriteGLSLSamplerDefinitions(); + + if ( m_bUsesDSTInstruction ) + { + PrintToBuf( *m_pBufHeaderCode, "vec4 dst(vec4 src0,vec4 src1) { return vec4(1.0f,src0.y*src1.y,src0.z,src1.w); }\n" ); + } + + if ( m_bDeclareAddressReg ) + { + if ( !m_bGenerateBoneUniformBuffer ) + { + m_nHighestRegister = DXABSTRACT_VS_PARAM_SLOTS - 1; + } + + PrintIndentation( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size() ); + StrcatToParamCode( "vec4 va_r;\n" ); + } + + char *pTempVarStr = "TEMP"; + pTempVarStr = "vec4"; + + // Declare temps in Param code buffer + for( int i=0; i<32; i++ ) + { + if ( m_dwTempUsageMask & ( 0x00000001 << i ) ) + { + PrintIndentation( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size() ); + PrintToBuf( *m_pBufParamCode, "%s r%d;\n", pTempVarStr, i ); + } + } + + if ( m_bVertexShader && (m_bDoUserClipPlanes || m_bDoFixupZ || m_bDoFixupY ) ) + { + PrintIndentation( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size() ); + StrcatToParamCode( "vec4 vTempPos;\n" ); + } + + if ( ( m_bVertexShader ) && ( m_dwMajorVersion == 3 ) ) + { + for ( int i = 0; i < 32; i++ ) + { + if ( m_dwTexCoordOutMask & ( 1 << i ) ) + { + PrintIndentation( (char*)m_pBufParamCode->Base(), m_pBufParamCode->Size() ); + + char buf[256]; + V_snprintf( buf, sizeof( buf ), "vec4 oTempT%i = vec4( 0, 0, 0, 0 );\n", i ); + StrcatToParamCode( buf ); + } + } + } + + if ( m_bNeedsSinCosDeclarations ) + { + StrcatToParamCode( "vec3 vSinCosTmp;\n" ); // declare temp used by GLSL sin and cos intrinsics + } + + // Optional temps needed to emulate d2add instruction in DX pixel shaders + if ( m_bNeedsD2AddTemp ) + { + PrintToBuf( *m_pBufParamCode, "%s DP2A0;\n%s DP2A1;\n", pTempVarStr, pTempVarStr ); + } + + // Optional temp needed to emulate lerp instruction in DX vertex shaders + if ( m_bNeedsLerpTemp ) + { + PrintToBuf( *m_pBufParamCode, "%s LRP_TEMP;\n", pTempVarStr ); + } + + // Optional temp needed to emulate NRM instruction in DX shaders + if ( m_bNeedsNRMTemp ) + { + PrintToBuf( *m_pBufParamCode, "%s NRM_TEMP;\n", pTempVarStr ); + } + + if ( m_bDeclareVSOPos && m_bVertexShader ) + { + if ( m_bDoUserClipPlanes ) + { +// StrcatToALUCode( "gl_ClipVertex = vTempPos;\n" ); // if user clip is enabled, jam clip space position into gl_ClipVertex + } + + if ( m_bDoFixupZ || m_bDoFixupY ) + { + // TODO: insert clip distance computation something like this: + // + // StrcatToALUCode( "DP4 oCLP[0].x, oPos, vc[215]; \n" ); + // + + if ( m_bDoFixupZ ) + { + StrcatToALUCode( "vTempPos.z = vTempPos.z * vc[0].z - vTempPos.w; // z' = (2*z)-w\n" ); + } + + if ( m_bDoFixupY ) + { + // append instructions to flip Y over + // new Y = -(old Y) + StrcatToALUCode( "vTempPos.y = -vTempPos.y; // y' = -y \n" ); + } + + // Apply half pixel offset (0.5f pixel offset D3D) to output vertices to account for the pixel center difference between D3D9 and OpenGL. + // This is the actual work in the shader. This works out to be 0.5 pixels wide because clip space is 2 units wide (-1, 1). + StrcatToALUCode( "vTempPos.xy += vcscreen.xy * vTempPos.w;\n" ); + + StrcatToALUCode( "gl_Position = vTempPos;\n" ); + } + else + { + StrcatToParamCode( "OUTPUT oPos = result.position;\n" ); + + // TODO: insert clip distance computation something like this: + // + // StrcatToALUCode( "DP4 oCLP[0].x, oPos, c[215]; \n" ); + // + } + } + + if ( m_bVertexShader ) + { + if ( m_dwMajorVersion == 3 ) + { + WriteGLSLOutputVariableAssignments(); + } + else + { + for ( int i=0; i<32; i++ ) + { + char outTexCoordBuff[64]; + + // Don't declare a varying for the output that is mapped to the position output + if ( i != m_nVSPositionOutput ) + { + if ( m_dwTexCoordOutMask & ( 0x00000001 << i ) ) + { + if ( m_nCentroidMask & ( 0x00000001 << i ) ) + { + V_snprintf( outTexCoordBuff, sizeof( outTexCoordBuff ), "centroid out vec4 oT%d;\n", i ); // centroid varying + StrcatToHeaderCode( outTexCoordBuff ); + } + else + { + V_snprintf( outTexCoordBuff, sizeof( outTexCoordBuff ), "out vec4 oT%d;\n", i ); + StrcatToHeaderCode( outTexCoordBuff ); + } + } + } + } + } + } + else + { + if ( m_dwMajorVersion == 3 ) + { + WriteGLSLInputVariableAssignments(); + } + } + + // do some annotation at the end of the attrib block + { + char temp[5000]; + + if ( m_bVertexShader ) + { + // write attrib map into the text starting at pAttribMapStart - two hex digits per attrib + for( int i=0; i<16; i++ ) + { + if ( m_dwAttribMap[i] != 0xFFFFFFFF ) + { + V_snprintf( temp, sizeof(temp), "%02X", m_dwAttribMap[i] ); + memcpy( pAttribMapStart + (i*3), temp, 2 ); + } + } + } + + PrintIndentation( (char*)m_pBufAttribCode->Base(), m_pBufAttribCode->Size() ); + + // This used to write out a translation counter into the shader as a comment. However, the order that shaders get in here + // is non-deterministic between runs, and the change in this comment would cause shaders to appear different to the GL disk cache, + // significantly increasing app load time. + // Other code looks for trans#%d, so we can't just remove it. Instead, output it as 0. + V_snprintf( temp, sizeof(temp), "%s trans#%d label:%s\n", "//", 0, debugLabel ? debugLabel : "none" ); + StrcatToAttribCode( temp ); + } + + // If we actually sample from a shadow depth sampler, we need to declare the shadow option at the top + if ( m_bDeclareShadowOption ) + { + StrcatToHeaderCode( "OPTION ARB_fragment_program_shadow;\n" ); + } + + if( m_iFragDataCount || m_bGenerateSRGBWriteSuffix ) + { + char buf[256]; + snprintf(buf, sizeof buf, "out vec4 _gl_FragData[%d];\n#define gl_FragData _gl_FragData\n", m_iFragDataCount); + StrcatToHeaderCode( buf ); + } + +#define FindSubcode(a) (V_strstr((char*)m_pBufALUCode->Base(), a) != 0 || V_strstr((char*)m_pBufHeaderCode->Base(), a) != 0 || V_strstr((char*)m_pBufParamCode->Base(), a) != 0 || V_strstr((char*)m_pBufAttribCode->Base(), a) != 0 ) + +/* + if( FindSubcode("shadow2DProj") ) + { + StrcatToHeaderCode( g_szShadow2D ); + StrcatToHeaderCode( g_szShadow2DProj ); + } + else if( FindSubcode("shadow2D") ) + StrcatToHeaderCode( g_szShadow2D );*/ + + if( FindSubcode("_gl_FrontColor") && !m_bFrontColor ) + StrcatToHeaderCode( "in vec4 _gl_FrontColor;\n" ); + + if( FindSubcode("_gl_FrontSecondaryColor") && !m_bFrontSecondaryColor ) + StrcatToHeaderCode( "in vec4 _gl_FrontSecondaryColor;\n" ); + + if( m_iFragDataCount && bVertexShader ) + StrcatToHeaderCode( "\nuniform float alpha_ref;\n" ); + + StrcatToHeaderCode( "\nvoid main()\n{\n" ); + if ( m_bUsedAtomicTempVar ) + { + PrintToBufWithIndents( *m_pBufHeaderCode, "vec4 %s;\n\n", g_pAtomicTempVarName ); + } + + // sRGB Write suffix + if ( m_bGenerateSRGBWriteSuffix ) + { + // StrcatToALUCode( "vec3 sRGBFragData;\n" ); + // StrcatToALUCode( "sRGBFragData.xyz = log( gl_FragData[0].xyz );\n" ); + // StrcatToALUCode( "sRGBFragData.xyz = sRGBFragData.xyz * vec3( 0.754545f, 0.754545f, 0.754545f );\n" ); + // StrcatToALUCode( "sRGBFragData.xyz = exp( sRGBFragData.xyz );\n" ); + StrcatToALUCode( "gl_FragData[0].xyz = pow(gl_FragData[0].xyz, vec3(1.0/2.2));\n" ); + } + + if( m_iFragDataCount && bVertexShader ) + StrcatToALUCode( "if( gl_FragData[0].a < alpha_ref ) { discard; };\n" ); + + strcat_s( (char*)m_pBufALUCode->Base(), m_pBufALUCode->Size(), "}\n" ); + + // Put all of the strings together for final program ( pHeaderCode + pAttribCode + pParamCode + pALUCode ) + StrcatToHeaderCode( (char*)m_pBufAttribCode->Base() ); + StrcatToHeaderCode( (char*)m_pBufParamCode->Base() ); + StrcatToHeaderCode( (char*)m_pBufALUCode->Base() ); + + // Cleanup - don't touch m_pBufHeaderCode, as it is managed by the caller + delete m_pBufAttribCode; + delete m_pBufParamCode; + delete m_pBufALUCode; + m_pBufAttribCode = m_pBufParamCode = m_pBufALUCode = NULL; + + if ( m_bSpew ) + { + printf("\n************* translation complete\n\n " ); + } + + return DISASM_OK; +} diff --git a/togles/linuxwin/dx9asmtogl2.h b/togles/linuxwin/dx9asmtogl2.h new file mode 100644 index 00000000..2751c5f5 --- /dev/null +++ b/togles/linuxwin/dx9asmtogl2.h @@ -0,0 +1,268 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +//------------------------------------------------------------------------------ +// DX9AsmToGL2.h +//------------------------------------------------------------------------------ + +#ifndef DX9_ASM_TO_GL_2_H +#define DX9_ASM_TO_GL_2_H +#include "tier1/utlstring.h" + +#define DISASM_OK 0 +#define DISASM_ERROR 1 + +#define MAX_SHADER_CONSTANTS 512 + +#define MAX_DECLARED_OUTPUTS 32 +#define MAX_DECLARED_INPUTS 32 + +#define HEXCODE_HEADER "// Hex: " + +// Option bits +#define D3DToGL_OptionUseEnvParams 0x0001 +#define D3DToGL_OptionDoFixupZ 0x0002 // Add instructions to put Z in the right interval for GL +#define D3DToGL_OptionDoFixupY 0x0004 // Add instructions to flip the Y over for GL +#define D3DToGL_OptionDoUserClipPlanes 0x0008 // ARB mode: Include OPTION vertex_program_2 and append DP4's to write into oCLP[0] and oCLP[1] + // GLSL mode: generate code to write gl_ClipVertex + +#define D3DToGL_AddHexComments 0x0020 // Include hex comments in the code for debugging +#define D3DToGL_PutHexCommentsAfterLines 0x0040 // If D3DToGL_AddHexComments is set, this puts the codes to the right, rather than on separate lines +#define D3DToGL_GeneratingDebugText 0x0080 // This tells it that we're just getting info for debugging so go easy on asserts and errors +#define D3DToGL_OptionSRGBWriteSuffix 0x0400 // Tack sRGB conversion suffix on to pixel shaders +#define D3DToGL_OptionGenerateBoneUniformBuffer 0x0800 // if enabled, the vertex shader "bone" registers (all regs DXABSTRACT_VS_FIRST_BONE_SLOT and higher) will be separated out into another uniform buffer (vcbone) +#define D3DToGL_OptionUseBindlessTexturing 0x1000 +#define D3DToGL_OptionSpew 0x80000000 + +// Code for which component of the "dummy" address register is needed by an instruction +#define ARL_DEST_NONE -1 +#define ARL_DEST_X 0 +#define ARL_DEST_Y 1 +#define ARL_DEST_Z 2 +#define ARL_DEST_W 3 + +class D3DToGL +{ +private: + // Pointers for dwToken stream management + uint32* m_pdwBaseToken; + uint32* m_pdwNextToken; + + // Vertex shader or pixel shader, and version (necessary because some opcodes alias) + bool m_bVertexShader; + uint32 m_dwMinorVersion; + uint32 m_dwMajorVersion; + + // Option flags + bool m_bUseEnvParams; // set D3DToGL_OptionUseEnvParams in 'options' to use + bool m_bDoFixupZ; // set D3DToGL_OptionDoFixupZ + bool m_bDoFixupY; // set D3DToGL_OptionDoFixupZ + bool m_bDoUserClipPlanes; // set D3DToGL_OptionDoUserClipPlanes + bool m_bSpew; // set D3DToGL_OptionSpew + bool m_bGenerateSRGBWriteSuffix; // set D3DToGL_OptionSRGBWriteSuffix + bool m_bGenerateBoneUniformBuffer; + bool m_bUseBindlessTexturing; + bool m_bFogFragCoord; + bool m_bFrontSecondaryColor; + bool m_bColor; + bool m_bSecondaryColor; + bool m_bFrontColor; + + + // Counter for dealing with nested loops + int m_nLoopDepth; + + // Add "// Hex: 0xFFEEF00"-type statements after each instruction is parsed. + bool m_bAddHexCodeComments; // set D3DToGL_AddHexComments + + // Only applicable if m_bAddHexCodeComments is true. + // If this is true, then it puts the hex code comments to the right of the instructions in a comment + // rather than preceding the instructions. + // Defaults to FALSE. + bool m_bPutHexCodesAfterLines; // set D3DToGL_PutHexCommentsAtEnd + + // This tells it that we're just getting info for debugging so go easy on asserts and errors. + // Defaults to FALSE. + bool m_bGeneratingDebugText; + + // Various scratch temps needed to handle mis-matches in instruction sets between D3D and OpenGL + bool m_bNeedsD2AddTemp; + bool m_bNeedsNRMTemp; + bool m_bDeclareAddressReg; + bool m_bNeedsLerpTemp; + bool m_bNeedsSinCosDeclarations; + + // Keep track of which vs outputs are used so we can declare them + bool m_bDeclareVSOPos; + bool m_bDeclareVSOFog; + uint32 m_dwTexCoordOutMask; + + int32 m_nVSPositionOutput; + + // Mask of varyings which need centroid decoration + uint32 m_nCentroidMask; + + // Keep track of which temps are used so they can be declared + uint32 m_dwTempUsageMask; + uint32 m_dwTempBoolUsageMask; + bool m_bOutputColorRegister[4]; + bool m_bOutputDepthRegister; + + // Declaration of integer and bool constants + uint32 m_dwConstIntUsageMask; + uint32 m_dwConstBoolUsageMask; + + uint32 m_dwDefConstIntUsageMask; + uint32 m_dwDefConstIntIterCount[32]; + + // Did we use atomic_temp_var? + bool m_bUsedAtomicTempVar; + + // Track constants so we know how to declare them + bool m_bConstantRegisterDefined[MAX_SHADER_CONSTANTS]; + + // Track sampler types when declared so we can properly decorate TEX instructions + uint32 m_dwSamplerTypes[32]; + + // Track sampler usage + uint32 m_dwSamplerUsageMask; + + // Track shadow sampler usage + int m_nShadowDepthSamplerMask; + bool m_bDeclareShadowOption; + + // Track attribute references + // init to 0xFFFFFFFF (unhit) + // index by (dwRegToken & D3DSP_REGNUM_MASK) in VS DCL insns + // fill with (usage<<4) | (usage index). + uint32 m_dwAttribMap[16]; + + // Register high water mark + uint32 m_nHighestRegister; + int32 m_nHighestBoneRegister; + + // GLSL does indentation for readability + int m_NumIndentTabs; + + // Output buffers. + CUtlBuffer *m_pBufHeaderCode; + CUtlBuffer *m_pBufAttribCode; + CUtlBuffer *m_pBufParamCode; + CUtlBuffer *m_pBufALUCode; + + char *m_pFinalAssignmentsCode; + int m_nFinalAssignmentsBufSize; + + // Recorded positions for debugging. + uint32* m_pRecordedInputTokenStart; + int m_nRecordedParamCodeStrlen; + int m_nRecordedALUCodeStrlen; + int m_nRecordedAttribCodeStrlen; + + // In GLSL mode, these store the semantic attached to each oN register. + // They are the values that you pass to GetUsageIndexAndString. + uint32 m_DeclaredOutputs[MAX_DECLARED_OUTPUTS]; + + uint32 m_DeclaredInputs[MAX_DECLARED_INPUTS]; + + // Have they used the tangent input semantic (i.e. is g_pTangentAttributeName declared)? + bool m_bTangentInputUsed; + uint m_iFragDataCount; + + bool m_bUsesDSTInstruction; + +private: + // Utilities to aid in decoding token stream + uint32 GetNextToken( void ); + void SkipTokens( uint32 numToSkip ); + uint32 Opcode( uint32 dwToken ); + uint32 OpcodeSpecificData( uint32 dwToken ); + uint32 TextureType ( uint32 dwToken ); + uint32 GetRegType( uint32 dwRegToken ); + + // Write to the different buffers. + void StrcatToHeaderCode( const char *pBuf ); + void StrcatToALUCode( const char *pBuf ); + void StrcatToParamCode( const char *pBuf ); + void StrcatToAttribCode( const char *pBuf ); + void PrintToBufWithIndents( CUtlBuffer &buf, const char *pFormat, ... ); + + // This helps write the token hex codes into the output stream for debugging. + void AddTokenHexCodeToBuffer( char *pBuffer, int nSize, int nLastStrlen ); + void RecordInputAndOutputPositions(); + void AddTokenHexCode(); + + // Utilities for decoding tokens in to strings according to ASM syntax + void PrintOpcode( uint32 inst, char* buff, int nBufLen ); + + // fSemanticFlags is SEMANTIC_INPUT or SEMANTIC_OUTPUT. + void PrintUsageAndIndexToString( uint32 dwToken, char* strUsageUsageIndexName, int nBufLen, int fSemanticFlags ); + CUtlString GetUsageAndIndexString( uint32 dwToken, int fSemanticFlags ); + CUtlString GetParameterString( uint32 dwToken, uint32 dwSourceOrDest, bool bForceScalarSource, int *pARLDestReg ); + const char* GetGLSLOperatorString( uint32 inst ); + + void PrintParameterToString ( uint32 dwToken, uint32 dwSourceOrDest, char *pRegisterName, int nBufLen, bool bForceScalarSource, int *pARLDestReg ); + + void InsertMoveFromAddressRegister( CUtlBuffer *pCode, int nARLComp0, int nARLComp1, int nARLComp2 = ARL_DEST_NONE ); + void InsertMoveInstruction( CUtlBuffer *pCode, int nARLComponent ); + void FlagIndirectRegister( uint32 dwToken, int *pARLDestReg ); + + // Utilities for decoding tokens in to strings according to GLSL syntax + bool OpenIntrinsic( uint32 inst, char* buff, int nBufLen, uint32 destDimension, uint32 nArgumentDimension ); + void PrintIndentation( char *pBuf, int nBufLen ); + + uint32 MaintainAttributeMap( uint32 dwToken, uint32 dwRegToken ); + + CUtlString FixGLSLSwizzle( const char *pDestRegisterName, const char *pSrcRegisterName ); + void WriteGLSLCmp( const char *pDestReg, const char *pSrc0Reg, const char *pSrc1Reg, const char *pSrc2Reg ); + void WriteGLSLSamplerDefinitions(); + void WriteGLSLOutputVariableAssignments(); + void WriteGLSLInputVariableAssignments(); + void NoteTangentInputUsed(); + + void Handle_DCL(); + void Handle_DEF(); + void Handle_DEFIB( uint32 nInstruction ); + void Handle_MAD( uint32 nInstruction ); + void Handle_DP2ADD(); + void Handle_SINCOS(); + void Handle_LRP( uint32 nInstruction ); + void Handle_TEX( uint32 dwToken, bool bIsTexLDL ); + void Handle_TexLDD( uint32 nInstruction ); + void Handle_TexCoord(); + void Handle_UnaryOp( uint32 nInstruction ); + void Handle_BREAKC( uint32 dwToken ); + void HandleBinaryOp_GLSL( uint32 nInstruction ); + void HandleBinaryOp_ASM( uint32 nInstruction ); + void Handle_CMP(); + void Handle_NRM(); + void Handle_DeclarativeNonDclOp( uint32 nInstruction ); + +public: + D3DToGL(); + + int TranslateShader( uint32* code, CUtlBuffer *pBufDisassembledCode, bool *bVertexShader, uint32 options, int32 nShadowDepthSamplerMask, uint32 nCentroidMask, char *debugLabel ); +}; + + +#endif // DX9_ASM_TO_GL_2_H diff --git a/togles/linuxwin/dxabstract.cpp b/togles/linuxwin/dxabstract.cpp new file mode 100644 index 00000000..84d6a3f3 --- /dev/null +++ b/togles/linuxwin/dxabstract.cpp @@ -0,0 +1,6841 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// dxabstract.cpp +// +//================================================================================================== +#include "togles/rendermechanism.h" +#include "tier0/vprof_telemetry.h" +#include "tier0/dbg.h" +#include "tier0/threadtools.h" +#include "tier0/vprof.h" +#include "tier1/strtools.h" +#include "tier1/utlbuffer.h" +#include "dx9asmtogl2.h" +#include "mathlib/vmatrix.h" +#include "materialsystem/IShader.h" + +#include "glmgr_flush.inl" + +#if defined(OSX) || defined(LINUX) || (defined (WIN32) && defined( DX_TO_GL_ABSTRACTION )) + #include "appframework/ilaunchermgr.h" + extern ILauncherMgr *g_pLauncherMgr; +#endif + +#include "tier0/icommandline.h" +#include "tier0/memdbgon.h" + +#ifdef USE_ACTUAL_DX + +#pragma comment( lib, "../../dx9sdk/lib/d3d9.lib" ) +#pragma comment( lib, "../../dx9sdk/lib/d3dx9.lib" ) + +#else + +#ifdef POSIX +#define strcat_s( a, b, c) V_strcat( a, c, b ) +#endif + +#define D3D_DEVICE_VALID_MARKER 0x12EBC845 +#define GL_PUBLIC_ENTRYPOINT_CHECKS( dev ) Assert( dev->GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); Assert( dev->m_nValidMarker == D3D_DEVICE_VALID_MARKER ); +// ------------------------------------------------------------------------------------------------------------------------------ // +bool g_bNullD3DDevice; + +static D3DToGL g_D3DToOpenGLTranslatorGLSL; +static IDirect3DDevice9 *g_pD3D_Device; + +#if GL_BATCH_PERF_ANALYSIS + #include "../../thirdparty/miniz/simple_bitmap.h" + #include "../../thirdparty/miniz/miniz.c" + + ConVar gl_batch_vis_abs_scale( "gl_batch_vis_abs_scale", ".050" ); + ConVar gl_present_vis_abs_scale( "gl_present_vis_abs_scale", ".050" ); + //ConVar gl_batch_vis_y_scale( "gl_batch_vis_y_scale", "0.007" ); + ConVar gl_batch_vis_y_scale( "gl_batch_vis_y_scale", "0.0" ); + static double s_rdtsc_to_ms; + + uint64 g_nTotalD3DCycles; + uint g_nTotalD3DCalls; + + class CGLBatchPerfCallTimer + { + public: + inline CGLBatchPerfCallTimer() { g_nTotalD3DCalls++; g_nTotalD3DCycles -= TM_FAST_TIME(); } + inline ~CGLBatchPerfCallTimer() { g_nTotalD3DCycles += TM_FAST_TIME(); } + }; + + #define GL_BATCH_PERF_CALL_TIMER CGLBatchPerfCallTimer scopedCallTimer; +#else + #define GL_BATCH_PERF_CALL_TIMER +#endif // GL_BATCH_PERF_ANALYSIS + +ConVar gl_batch_vis( "gl_batch_vis", "0" ); + +// ------------------------------------------------------------------------------------------------------------------------------ // +// functions that are dependant on g_pLauncherMgr + +inline GLMDisplayDB *GetDisplayDB( void ) +{ + return g_pLauncherMgr->GetDisplayDB(); +} + +inline void RenderedSize( uint &width, uint &height, bool set ) +{ + g_pLauncherMgr->RenderedSize( width, height, set ); +} + +inline void GetStackCrawl( CStackCrawlParams *params ) +{ + g_pLauncherMgr->GetStackCrawl(params); +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#if defined( WIN32 ) + +bool D3DMATRIX::operator == ( CONST D3DMATRIX& src) const +{ + return V_memcmp( (void*)this, (void*)&src, sizeof(this) ) == 0; +} + +D3DMATRIX::operator void* () +{ + return (void*)this; +} + +#endif + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- D3DXMATRIX operators + +#endif + +D3DXMATRIX D3DXMATRIX::operator*( const D3DXMATRIX &o ) const +{ + D3DXMATRIX result; + + D3DXMatrixMultiply( &result, this, &o ); // this = lhs o = rhs result = this * o + + return result; +} + +D3DXMATRIX::operator FLOAT* () +{ + return (float*)this; +} + +float& D3DXMATRIX::operator()( int row, int column ) +{ + return m[row][column]; +} + +const float& D3DXMATRIX::operator()( int row, int column ) const +{ + return m[row][column]; +} + +bool D3DXMATRIX::operator != ( CONST D3DXMATRIX& src ) const +{ + return V_memcmp( (void*)this, (void*)&src, sizeof(this) ) != 0; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- D3DXPLANE operators + +#endif + +float& D3DXPLANE::operator[]( int i ) +{ + return ((float*)this)[i]; +} + +bool D3DXPLANE::operator==( const D3DXPLANE &o ) +{ + return a == o.a && b == o.b && c == o.c && d == o.d; +} + +bool D3DXPLANE::operator!=( const D3DXPLANE &o ) +{ + return !( *this == o ); +} + +D3DXPLANE::operator float*() +{ + return (float*)this; +} + +D3DXPLANE::operator const float*() const +{ + return (const float*)this; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- D3DXVECTOR2 operators + +#endif + +D3DXVECTOR2::operator FLOAT* () +{ + return (float*)this; +} + +D3DXVECTOR2::operator CONST FLOAT* () const +{ + return (const float*)this; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- D3DXVECTOR3 operators + +#endif + +D3DXVECTOR3::D3DXVECTOR3( float a, float b, float c ) +{ + x = a; + y = b; + z = c; +} + +D3DXVECTOR3::operator FLOAT* () +{ + return (float*)this; +} + +D3DXVECTOR3::operator CONST FLOAT* () const +{ + return (const float*)this; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- D3DXVECTOR4 operators + +#endif + +D3DXVECTOR4::D3DXVECTOR4( float a, float b, float c, float d ) +{ + x = a; + y = b; + z = c; + w = d; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +DWORD IDirect3DResource9::SetPriority(DWORD PriorityNew) +{ +// DXABSTRACT_BREAK_ON_ERROR(); +// GLMPRINTF(( "-X- SetPriority" )); + // no-op city + return 0; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DBaseTexture9 + +#endif + +IDirect3DBaseTexture9::~IDirect3DBaseTexture9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF(( ">-A- ~IDirect3DBaseTexture9" )); + + if (m_device) + { + Assert( m_device->m_ObjectStats.m_nTotalTextures >= 1 ); + m_device->m_ObjectStats.m_nTotalTextures--; + + GLMPRINTF(( "-A- ~IDirect3DBaseTexture9 taking normal delete path on %08x, device is %08x ", this, m_device )); + m_device->ReleasedTexture( this ); + + if (m_tex) + { + GLMPRINTF(("-A- ~IDirect3DBaseTexture9 deleted '%s' @ %08x (GLM %08x) %s",m_tex->m_layout->m_layoutSummary, this, m_tex, m_tex->m_debugLabel ? m_tex->m_debugLabel : "" )); + + m_device->ReleasedCGLMTex( m_tex ); + + m_tex->m_ctx->DelTex( m_tex ); + m_tex = NULL; + } + else + { + GLMPRINTF(( "-A- ~IDirect3DBaseTexture9 : whoops, no tex to delete here ?" )); + } + m_device = NULL; // ** THIS ** is the only place to scrub this. Don't do it in the subclass destructors. + } + else + { + GLMPRINTF(( "-A- ~IDirect3DBaseTexture9 taking strange delete path on %08x, device is %08x ", this, m_device )); + } + + GLMPRINTF(( "<-A- ~IDirect3DBaseTexture9" )); +} + +D3DRESOURCETYPE IDirect3DBaseTexture9::GetType() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + return m_restype; //D3DRTYPE_TEXTURE; +} + +DWORD IDirect3DBaseTexture9::GetLevelCount() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + return m_tex->m_layout->m_mipCount; +} + +HRESULT IDirect3DBaseTexture9::GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + Assert (Level < static_cast(m_tex->m_layout->m_mipCount)); + + D3DSURFACE_DESC result = m_descZero; + // then mutate it for the level of interest + + GLMTexLayoutSlice *slice = &m_tex->m_layout->m_slices[ m_tex->CalcSliceIndex( 0, Level ) ]; + + result.Width = slice->m_xSize; + result.Height = slice->m_ySize; + + *pDesc = result; + + return S_OK; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DTexture9 + +#endif + +HRESULT IDirect3DDevice9::CreateTexture(UINT Width,UINT Height,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DTexture9** ppTexture,VD3DHANDLE* pSharedHandle, char *pDebugLabel ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + + m_ObjectStats.m_nTotalTextures++; + + GLMPRINTF((">-A-IDirect3DDevice9::CreateTexture")); + IDirect3DTexture9 *dxtex = new IDirect3DTexture9; + dxtex->m_restype = D3DRTYPE_TEXTURE; + + dxtex->m_device = this; + + dxtex->m_descZero.Format = Format; + dxtex->m_descZero.Type = D3DRTYPE_TEXTURE; + dxtex->m_descZero.Usage = Usage; + dxtex->m_descZero.Pool = Pool; + + dxtex->m_descZero.MultiSampleType = D3DMULTISAMPLE_NONE; + dxtex->m_descZero.MultiSampleQuality = 0; + dxtex->m_descZero.Width = Width; + dxtex->m_descZero.Height = Height; + + GLMTexLayoutKey key; + memset( &key, 0, sizeof(key) ); + + key.m_texGLTarget = GL_TEXTURE_2D; + key.m_texFormat = Format; + + if (Levels>1) + { + key.m_texFlags |= kGLMTexMipped; + } + + // http://msdn.microsoft.com/en-us/library/bb172625(VS.85).aspx + + // complain if any usage bits come down that I don't know. + uint knownUsageBits = (D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET | D3DUSAGE_DYNAMIC | D3DUSAGE_TEXTURE_SRGB | D3DUSAGE_DEPTHSTENCIL); + if ( (Usage & knownUsageBits) != Usage ) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + + if (Usage & D3DUSAGE_AUTOGENMIPMAP) + { + key.m_texFlags |= kGLMTexMipped | kGLMTexMippedAuto; + } + + if (Usage & D3DUSAGE_DYNAMIC) + { + // GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME + } + + if (Usage & D3DUSAGE_TEXTURE_SRGB) + { + key.m_texFlags |= kGLMTexSRGB; + } + + if (Usage & D3DUSAGE_RENDERTARGET) + { + Assert( !(Usage & D3DUSAGE_DEPTHSTENCIL) ); + + m_ObjectStats.m_nTotalRenderTargets++; + + key.m_texFlags |= kGLMTexRenderable; + + const GLMTexFormatDesc *pFmtDesc = GetFormatDesc( key.m_texFormat ); + if ( pFmtDesc->m_glIntFormatSRGB != 0 ) + { + key.m_texFlags |= kGLMTexSRGB; // this catches callers of CreateTexture who set the "renderable" option - they get an SRGB tex + } + + if (m_ctx->Caps().m_cantAttachSRGB) + { + // this config can't support SRGB render targets. quietly turn off the sRGB bit. + key.m_texFlags &= ~kGLMTexSRGB; + } + } + + if ( ( Format == D3DFMT_D16 ) || ( Format == D3DFMT_D24X8 ) || ( Format == D3DFMT_D24S8 ) ) + { + key.m_texFlags |= kGLMTexIsDepth; + } + if ( Format == D3DFMT_D24S8 ) + { + key.m_texFlags |= kGLMTexIsStencil; + } + + key.m_xSize = Width; + key.m_ySize = Height; + key.m_zSize = 1; + + CGLMTex *tex = m_ctx->NewTex( &key, Levels, pDebugLabel ); + if (!tex) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + dxtex->m_tex = tex; + + dxtex->m_tex->m_srgbFlipCount = 0; + + m_ObjectStats.m_nTotalSurfaces++; + + dxtex->m_surfZero = new IDirect3DSurface9; + dxtex->m_surfZero->m_restype = (D3DRESOURCETYPE)0; // this is a ref to a tex, not the owner... + + // do not do an AddRef here. + + dxtex->m_surfZero->m_device = this; + + dxtex->m_surfZero->m_desc = dxtex->m_descZero; + dxtex->m_surfZero->m_tex = tex; + dxtex->m_surfZero->m_face = 0; + dxtex->m_surfZero->m_mip = 0; + + GLMPRINTF(("-A- IDirect3DDevice9::CreateTexture created '%s' @ %08x (GLM %08x) %s",tex->m_layout->m_layoutSummary, dxtex, tex, pDebugLabel ? pDebugLabel : "" )); + + *ppTexture = dxtex; + + GLMPRINTF(("<-A-IDirect3DDevice9::CreateTexture")); + return S_OK; +} + + +IDirect3DTexture9::~IDirect3DTexture9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + GLMPRINTF(( ">-A- IDirect3DTexture9" )); + + // IDirect3DBaseTexture9::~IDirect3DBaseTexture9 frees up m_tex + // we take care of surfZero + + if (m_device) + { + m_device->ReleasedTexture( this ); + + if (m_surfZero) + { + ULONG refc = m_surfZero->Release( 0, "~IDirect3DTexture9 public release (surfZero)" ); (void)refc; + Assert( !refc ); + m_surfZero = NULL; + } + // leave m_device alone! + } + + GLMPRINTF(( "<-A- IDirect3DTexture9" )); +} + +HRESULT IDirect3DTexture9::LockRect(UINT Level,D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DTexture9::UnlockRect(UINT Level) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DTexture9::GetSurfaceLevel(UINT Level,IDirect3DSurface9** ppSurfaceLevel) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + // we create and pass back a surface, and the client is on the hook to release it. tidy. + + m_device->m_ObjectStats.m_nTotalSurfaces++; + + IDirect3DSurface9 *surf = new IDirect3DSurface9; + surf->m_restype = (D3DRESOURCETYPE)0; // 0 is special and means this 'surface' does not own its m_tex + + // Dicey...higher level code seems to want this and not want this. Are we missing some AddRef/Release behavior elsewhere? + // trying to turn this off - experimental - 26Oct2010 surf->AddRef(); + + surf->m_device = this->m_device; + + GLMTexLayoutSlice *slice = &m_tex->m_layout->m_slices[ m_tex->CalcSliceIndex( 0, Level ) ]; + + surf->m_desc = m_descZero; + surf->m_desc.Width = slice->m_xSize; + surf->m_desc.Height = slice->m_ySize; + + surf->m_tex = m_tex; + surf->m_face = 0; + surf->m_mip = Level; + + *ppSurfaceLevel = surf; + + return S_OK; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DCubeTexture9 + +#endif + +HRESULT IDirect3DDevice9::CreateCubeTexture(UINT EdgeLength,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DCubeTexture9** ppCubeTexture,VD3DHANDLE* pSharedHandle, char *pDebugLabel) +{ + GL_BATCH_PERF_CALL_TIMER; + Assert( m_ctx->m_nCurOwnerThreadId == ThreadGetCurrentId() ); + GLMPRINTF((">-A- IDirect3DDevice9::CreateCubeTexture")); + + Assert( m_ctx->m_nCurOwnerThreadId == ThreadGetCurrentId() ); + + m_ObjectStats.m_nTotalTextures++; + + IDirect3DCubeTexture9 *dxtex = new IDirect3DCubeTexture9; + dxtex->m_restype = D3DRTYPE_CUBETEXTURE; + + dxtex->m_device = this; + + dxtex->m_descZero.Format = Format; + dxtex->m_descZero.Type = D3DRTYPE_CUBETEXTURE; + dxtex->m_descZero.Usage = Usage; + dxtex->m_descZero.Pool = Pool; + + dxtex->m_descZero.MultiSampleType = D3DMULTISAMPLE_NONE; + dxtex->m_descZero.MultiSampleQuality = 0; + dxtex->m_descZero.Width = EdgeLength; + dxtex->m_descZero.Height = EdgeLength; + + GLMTexLayoutKey key; + memset( &key, 0, sizeof(key) ); + + key.m_texGLTarget = GL_TEXTURE_CUBE_MAP; + key.m_texFormat = Format; + + if (Levels>1) + { + key.m_texFlags |= kGLMTexMipped; + } + + // http://msdn.microsoft.com/en-us/library/bb172625(VS.85).aspx + // complain if any usage bits come down that I don't know. + uint knownUsageBits = (D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET | D3DUSAGE_DYNAMIC | D3DUSAGE_TEXTURE_SRGB); + if ( (Usage & knownUsageBits) != Usage ) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + + if (Usage & D3DUSAGE_AUTOGENMIPMAP) + { + key.m_texFlags |= kGLMTexMipped | kGLMTexMippedAuto; + } + + if (Usage & D3DUSAGE_RENDERTARGET) + { + key.m_texFlags |= kGLMTexRenderable; + + m_ObjectStats.m_nTotalRenderTargets++; + } + + if (Usage & D3DUSAGE_DYNAMIC) + { + //GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME + } + + if (Usage & D3DUSAGE_TEXTURE_SRGB) + { + key.m_texFlags |= kGLMTexSRGB; + } + + key.m_xSize = EdgeLength; + key.m_ySize = EdgeLength; + key.m_zSize = 1; + + CGLMTex *tex = m_ctx->NewTex( &key, Levels, pDebugLabel ); + if (!tex) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + dxtex->m_tex = tex; + + dxtex->m_tex->m_srgbFlipCount = 0; + + for( int face = 0; face < 6; face ++) + { + m_ObjectStats.m_nTotalSurfaces++; + + dxtex->m_surfZero[face] = new IDirect3DSurface9; + dxtex->m_surfZero[face]->m_restype = (D3DRESOURCETYPE)0; // 0 is special and means this 'surface' does not own its m_tex + // do not do an AddRef here. + + dxtex->m_surfZero[face]->m_device = this; + + dxtex->m_surfZero[face]->m_desc = dxtex->m_descZero; + dxtex->m_surfZero[face]->m_tex = tex; + dxtex->m_surfZero[face]->m_face = face; + dxtex->m_surfZero[face]->m_mip = 0; + } + + GLMPRINTF(("-A- IDirect3DDevice9::CreateCubeTexture created '%s' @ %08x (GLM %08x)",tex->m_layout->m_layoutSummary, dxtex, tex )); + + *ppCubeTexture = dxtex; + + GLMPRINTF(("<-A- IDirect3DDevice9::CreateCubeTexture")); + + return S_OK; +} + +IDirect3DCubeTexture9::~IDirect3DCubeTexture9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF(( ">-A- ~IDirect3DCubeTexture9" )); + + if (m_device) + { + GLMPRINTF(( "-A- ~IDirect3DCubeTexture9 taking normal delete path on %08x, device is %08x, surfzero[0] is %08x ", this, m_device, m_surfZero[0] )); + m_device->ReleasedTexture( this ); + + // let IDirect3DBaseTexture9::~IDirect3DBaseTexture9 free up m_tex + // we handle the surfZero array for the faces + + for( int face = 0; face < 6; face ++) + { + if (m_surfZero[face]) + { + Assert( m_surfZero[face]->m_device == m_device ); + ULONG refc = m_surfZero[face]->Release( 0, "~IDirect3DCubeTexture9 public release (surfZero)"); + if ( refc!=0 ) + { + GLMPRINTF(( "-A- ~IDirect3DCubeTexture9 seeing non zero refcount on surfzero[%d] => %d ", face, refc )); + } + m_surfZero[face] = NULL; + } + } + // leave m_device alone! + } + else + { + GLMPRINTF(( "-A- ~IDirect3DCubeTexture9 taking strange delete path on %08x, device is %08x, surfzero[0] is %08x ", this, m_device, m_surfZero[0] )); + } + + GLMPRINTF(( "<-A- ~IDirect3DCubeTexture9" )); +} + +HRESULT IDirect3DCubeTexture9::GetCubeMapSurface(D3DCUBEMAP_FACES FaceType,UINT Level,IDirect3DSurface9** ppCubeMapSurface) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + // we create and pass back a surface, and the client is on the hook to release it... + + m_device->m_ObjectStats.m_nTotalSurfaces++; + + IDirect3DSurface9 *surf = new IDirect3DSurface9; + surf->m_restype = (D3DRESOURCETYPE)0; // 0 is special and means this 'surface' does not own its m_tex + + GLMTexLayoutSlice *slice = &m_tex->m_layout->m_slices[ m_tex->CalcSliceIndex( FaceType, Level ) ]; + + surf->m_device = this->m_device; + + surf->m_desc = m_descZero; + surf->m_desc.Width = slice->m_xSize; + surf->m_desc.Height = slice->m_ySize; + + surf->m_tex = m_tex; + surf->m_face = FaceType; + surf->m_mip = Level; + + *ppCubeMapSurface = surf; + + return S_OK; +} + +HRESULT IDirect3DCubeTexture9::GetLevelDesc(UINT Level,D3DSURFACE_DESC *pDesc) +{ + GL_BATCH_PERF_CALL_TIMER; + Assert (Level < static_cast(m_tex->m_layout->m_mipCount)); + + D3DSURFACE_DESC result = m_descZero; + // then mutate it for the level of interest + + GLMTexLayoutSlice *slice = &m_tex->m_layout->m_slices[ m_tex->CalcSliceIndex( 0, Level ) ]; + + result.Width = slice->m_xSize; + result.Height = slice->m_ySize; + + *pDesc = result; + + return S_OK; +} + + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DVolumeTexture9 + +#endif + +HRESULT IDirect3DDevice9::CreateVolumeTexture(UINT Width,UINT Height,UINT Depth,UINT Levels,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DVolumeTexture9** ppVolumeTexture,VD3DHANDLE* pSharedHandle, char *pDebugLabel) +{ + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF((">-A- IDirect3DDevice9::CreateVolumeTexture")); + // set dxtex->m_restype to D3DRTYPE_VOLUMETEXTURE... + + Assert( m_ctx->m_nCurOwnerThreadId == ThreadGetCurrentId() ); + + m_ObjectStats.m_nTotalTextures++; + + IDirect3DVolumeTexture9 *dxtex = new IDirect3DVolumeTexture9; + dxtex->m_restype = D3DRTYPE_VOLUMETEXTURE; + + dxtex->m_device = this; + + dxtex->m_descZero.Format = Format; + dxtex->m_descZero.Type = D3DRTYPE_VOLUMETEXTURE; + dxtex->m_descZero.Usage = Usage; + dxtex->m_descZero.Pool = Pool; + + dxtex->m_descZero.MultiSampleType = D3DMULTISAMPLE_NONE; + dxtex->m_descZero.MultiSampleQuality = 0; + dxtex->m_descZero.Width = Width; + dxtex->m_descZero.Height = Height; + + // also a volume specific desc + dxtex->m_volDescZero.Format = Format; + dxtex->m_volDescZero.Type = D3DRTYPE_VOLUMETEXTURE; + dxtex->m_volDescZero.Usage = Usage; + dxtex->m_volDescZero.Pool = Pool; + + dxtex->m_volDescZero.Width = Width; + dxtex->m_volDescZero.Height = Height; + dxtex->m_volDescZero.Depth = Depth; + + GLMTexLayoutKey key; + memset( &key, 0, sizeof(key) ); + + key.m_texGLTarget = GL_TEXTURE_3D; + key.m_texFormat = Format; + + if (Levels>1) + { + key.m_texFlags |= kGLMTexMipped; + } + + // http://msdn.microsoft.com/en-us/library/bb172625(VS.85).aspx + // complain if any usage bits come down that I don't know. + uint knownUsageBits = (D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET | D3DUSAGE_DYNAMIC | D3DUSAGE_TEXTURE_SRGB); + if ( (Usage & knownUsageBits) != Usage ) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + + if (Usage & D3DUSAGE_AUTOGENMIPMAP) + { + key.m_texFlags |= kGLMTexMipped | kGLMTexMippedAuto; + } + + if (Usage & D3DUSAGE_RENDERTARGET) + { + key.m_texFlags |= kGLMTexRenderable; + + m_ObjectStats.m_nTotalRenderTargets++; + } + + if (Usage & D3DUSAGE_DYNAMIC) + { + GLMPRINTF(("-X- DYNAMIC tex usage ignored..")); //FIXME + } + + if (Usage & D3DUSAGE_TEXTURE_SRGB) + { + key.m_texFlags |= kGLMTexSRGB; + } + + key.m_xSize = Width; + key.m_ySize = Height; + key.m_zSize = Depth; + + CGLMTex *tex = m_ctx->NewTex( &key, Levels, pDebugLabel ); + if (!tex) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + dxtex->m_tex = tex; + + dxtex->m_tex->m_srgbFlipCount = 0; + + m_ObjectStats.m_nTotalSurfaces++; + + dxtex->m_surfZero = new IDirect3DSurface9; + dxtex->m_surfZero->m_restype = (D3DRESOURCETYPE)0; // this is a ref to a tex, not the owner... + // do not do an AddRef here. + + dxtex->m_surfZero->m_device = this; + + dxtex->m_surfZero->m_desc = dxtex->m_descZero; + dxtex->m_surfZero->m_tex = tex; + dxtex->m_surfZero->m_face = 0; + dxtex->m_surfZero->m_mip = 0; + + GLMPRINTF(("-A- IDirect3DDevice9::CreateVolumeTexture created '%s' @ %08x (GLM %08x)",tex->m_layout->m_layoutSummary, dxtex, tex )); + + *ppVolumeTexture = dxtex; + + GLMPRINTF(("<-A- IDirect3DDevice9::CreateVolumeTexture")); + + return S_OK; +} + +IDirect3DVolumeTexture9::~IDirect3DVolumeTexture9() +{ + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF((">-A- ~IDirect3DVolumeTexture9")); + + if (m_device) + { + m_device->ReleasedTexture( this ); + + // let IDirect3DBaseTexture9::~IDirect3DBaseTexture9 free up m_tex + // we handle m_surfZero + + if (m_surfZero) + { + ULONG refc = m_surfZero->Release( 0, "~IDirect3DVolumeTexture9 public release (surfZero)" ); (void)refc; + Assert( !refc ); + m_surfZero = NULL; + } + // leave m_device alone! + } + + GLMPRINTF(("<-A- ~IDirect3DVolumeTexture9")); +} + +HRESULT IDirect3DVolumeTexture9::LockBox(UINT Level,D3DLOCKED_BOX* pLockedVolume,CONST D3DBOX* pBox,DWORD Flags) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + GLMTexLockParams lockreq; + memset( &lockreq, 0, sizeof(lockreq) ); + + lockreq.m_tex = this->m_tex; + lockreq.m_face = 0; + lockreq.m_mip = Level; + + lockreq.m_region.xmin = pBox->Left; + lockreq.m_region.ymin = pBox->Top; + lockreq.m_region.zmin = pBox->Front; + lockreq.m_region.xmax = pBox->Right; + lockreq.m_region.ymax = pBox->Bottom; + lockreq.m_region.zmax = pBox->Back; + + char *lockAddress; + int yStride; + int zStride; + + lockreq.m_tex->Lock( &lockreq, &lockAddress, &yStride, &zStride ); + + pLockedVolume->RowPitch = yStride; + pLockedVolume->SlicePitch = yStride; + pLockedVolume->pBits = lockAddress; + + return S_OK; +} + +HRESULT IDirect3DVolumeTexture9::UnlockBox(UINT Level) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + GLMTexLockParams lockreq; + memset( &lockreq, 0, sizeof(lockreq) ); + + lockreq.m_tex = this->m_tex; + lockreq.m_face = 0; + lockreq.m_mip = Level; + + this->m_tex->Unlock( &lockreq ); + + return S_OK; +} + +HRESULT IDirect3DVolumeTexture9::GetLevelDesc( UINT Level, D3DVOLUME_DESC *pDesc ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + if (Level > static_cast(m_tex->m_layout->m_mipCount)) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + + D3DVOLUME_DESC result = m_volDescZero; + // then mutate it for the level of interest + + GLMTexLayoutSlice *slice = &m_tex->m_layout->m_slices[ m_tex->CalcSliceIndex( 0, Level ) ]; + + result.Width = slice->m_xSize; + result.Height = slice->m_ySize; + result.Depth = slice->m_zSize; + + *pDesc = result; + + return S_OK; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DSurface9 + +#endif + +IDirect3DSurface9::~IDirect3DSurface9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + // not much to do here, but good to verify that these things are being freed (and they are) + //GLMPRINTF(("-A- ~IDirect3DSurface9 - signpost")); + + if (m_device) + { + GLMPRINTF(("-A- ~IDirect3DSurface9 - taking real delete path on %08x device %08x", this, m_device)); + m_device->ReleasedSurface( this ); + + memset( &m_desc, 0, sizeof(m_desc) ); + + if (m_restype != 0) // signal that we are a surface that owns this tex (render target) + { + if (m_tex) + { + GLMPRINTF(("-A- ~IDirect3DSurface9 deleted '%s' @ %08x (GLM %08x) %s",m_tex->m_layout->m_layoutSummary, this, m_tex, m_tex->m_debugLabel ? m_tex->m_debugLabel : "" )); + + m_device->ReleasedCGLMTex( m_tex ); + + m_tex->m_ctx->DelTex( m_tex ); + m_tex = NULL; + } + else + { + GLMPRINTF(( "-A- ~IDirect3DSurface9 : whoops, no tex to delete here ?" )); + } + } + else + { + m_tex = NULL; // we are just a view on the tex, we don't own the tex, do not delete it + } + + m_face = m_mip = 0; + + m_device = NULL; + } + else + { + GLMPRINTF(("-A- ~IDirect3DSurface9 - taking strange delete path on %08x device %08x", this, m_device)); + } +} + +HRESULT IDirect3DSurface9::LockRect(D3DLOCKED_RECT* pLockedRect,CONST RECT* pRect,DWORD Flags) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMTexLockParams lockreq; + memset( &lockreq, 0, sizeof(lockreq) ); + + lockreq.m_tex = this->m_tex; + lockreq.m_face = this->m_face; + lockreq.m_mip = this->m_mip; + + lockreq.m_region.xmin = pRect->left; + lockreq.m_region.ymin = pRect->top; + lockreq.m_region.zmin = 0; + lockreq.m_region.xmax = pRect->right; + lockreq.m_region.ymax = pRect->bottom; + lockreq.m_region.zmax = 1; + + if ((Flags & (D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK)) == (D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK) ) + { + // smells like readback, force texel readout + lockreq.m_readback = true; + } + + char *lockAddress; + int yStride; + int zStride; + + lockreq.m_tex->Lock( &lockreq, &lockAddress, &yStride, &zStride ); + + pLockedRect->Pitch = yStride; + pLockedRect->pBits = lockAddress; + + return S_OK; +} + +HRESULT IDirect3DSurface9::UnlockRect() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMTexLockParams lockreq; + memset( &lockreq, 0, sizeof(lockreq) ); + + lockreq.m_tex = this->m_tex; + lockreq.m_face = this->m_face; + lockreq.m_mip = this->m_mip; + + lockreq.m_tex->Unlock( &lockreq ); + + return S_OK; +} + +HRESULT IDirect3DSurface9::GetDesc(D3DSURFACE_DESC *pDesc) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + *pDesc = m_desc; + return S_OK; +} + + +// ------------------------------------------------------------------------------------------------------------------------------ // + + +#ifdef OSX + +#pragma mark ----- IDirect3D9 ------------------------------------------------------- + +#endif + +IDirect3D9::~IDirect3D9() +{ + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF(("-A- ~IDirect3D9 - signpost")); +} + +UINT IDirect3D9::GetAdapterCount() +{ + GL_BATCH_PERF_CALL_TIMER; + GLMgr::NewGLMgr(); // init GL manager + + GLMDisplayDB *db = GetDisplayDB(); + int dxAdapterCount = db->GetFakeAdapterCount(); + + return dxAdapterCount; +} + +static void FillD3DCaps9( const GLMRendererInfoFields &glmRendererInfo, D3DCAPS9* pCaps ) +{ + // fill in the pCaps record for adapter... we zero most of it and just fill in the fields that we think the caller wants. + Q_memset( pCaps, 0, sizeof(*pCaps) ); + + + /* Device Info */ + pCaps->DeviceType = D3DDEVTYPE_HAL; + + /* Caps from DX7 Draw */ + pCaps->Caps = 0; // does anyone look at this ? + + pCaps->Caps2 = D3DCAPS2_DYNAMICTEXTURES; + /* Cursor Caps */ + pCaps->CursorCaps = 0; // nobody looks at this + + /* 3D Device Caps */ + pCaps->DevCaps = D3DDEVCAPS_HWTRANSFORMANDLIGHT; + + pCaps->TextureCaps = D3DPTEXTURECAPS_CUBEMAP | D3DPTEXTURECAPS_MIPCUBEMAP | D3DPTEXTURECAPS_NONPOW2CONDITIONAL | D3DPTEXTURECAPS_PROJECTED; + // D3DPTEXTURECAPS_NOPROJECTEDBUMPENV ? + // D3DPTEXTURECAPS_POW2 ? + // caller looks at POT support like this: + // pCaps->m_SupportsNonPow2Textures = + // ( !( caps.TextureCaps & D3DPTEXTURECAPS_POW2 ) || + // ( caps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL ) ); + // so we should set D3DPTEXTURECAPS_NONPOW2CONDITIONAL bit ? + + + pCaps->PrimitiveMiscCaps = 0; //only the HDR setup looks at this for D3DPMISCCAPS_SEPARATEALPHABLEND. + // ? D3DPMISCCAPS_SEPARATEALPHABLEND + // ? D3DPMISCCAPS_BLENDOP + // ? D3DPMISCCAPS_CLIPPLANESCALEDPOINTS + // ? D3DPMISCCAPS_CLIPTLVERTS D3DPMISCCAPS_COLORWRITEENABLE D3DPMISCCAPS_MASKZ D3DPMISCCAPS_TSSARGTEMP + + + pCaps->RasterCaps = D3DPRASTERCAPS_SCISSORTEST + | D3DPRASTERCAPS_SLOPESCALEDEPTHBIAS // ref'd in CShaderDeviceMgrDx8::ComputeCapsFromD3D + | D3DPRASTERCAPS_DEPTHBIAS // ref'd in CShaderDeviceMgrDx8::ComputeCapsFromD3D + ; + + pCaps->TextureFilterCaps = D3DPTFILTERCAPS_MINFANISOTROPIC | D3DPTFILTERCAPS_MAGFANISOTROPIC; + + pCaps->MaxTextureWidth = 4096; + pCaps->MaxTextureHeight = 4096; + pCaps->MaxVolumeExtent = 1024; //guesses + + pCaps->MaxTextureAspectRatio = 0; // imply no limit on AR + + pCaps->MaxAnisotropy = glmRendererInfo.m_maxAniso; + + pCaps->TextureOpCaps = D3DTEXOPCAPS_ADD | D3DTEXOPCAPS_MODULATE2X; //guess + //DWORD MaxTextureBlendStages; + //DWORD MaxSimultaneousTextures; + + pCaps->VertexProcessingCaps = D3DVTXPCAPS_TEXGEN_SPHEREMAP; + + pCaps->MaxActiveLights = 8; // guess + + + // MaxUserClipPlanes. A bit complicated.. + // it's difficult to make this fluid without teaching the engine about a cap that could change during run. + + // start it out set to '2'. + // turn it off, if we're in GLSL mode but do not have native clip plane capability. + pCaps->MaxUserClipPlanes = 2; // assume good news + + // is user asking for it to be off ? + if ( CommandLine()->CheckParm( "-nouserclip" ) ) + { + pCaps->MaxUserClipPlanes = 0; + } + + pCaps->MaxVertexBlendMatrices = 0; // see if anyone cares + pCaps->MaxVertexBlendMatrixIndex = 0; // see if anyone cares + + pCaps->MaxPrimitiveCount = 32768; // guess + pCaps->MaxStreams = D3D_MAX_STREAMS; // guess + + pCaps->VertexShaderVersion = 0x300; // model 3.0 + pCaps->MaxVertexShaderConst = DXABSTRACT_VS_PARAM_SLOTS; // number of vertex shader constant registers + + pCaps->PixelShaderVersion = 0x300; // model 3.0 + + // Here are the DX9 specific ones + pCaps->DevCaps2 = D3DDEVCAPS2_STREAMOFFSET; + + pCaps->PS20Caps.NumInstructionSlots = 512; // guess + // only examined once: + // pCaps->m_SupportsPixelShaders_2_b = ( ( caps.PixelShaderVersion & 0xffff ) >= 0x0200) && (caps.PS20Caps.NumInstructionSlots >= 512); + //pCaps->m_SupportsPixelShaders_2_b = 1; + + pCaps->NumSimultaneousRTs = 1; // Will be at least 1 + pCaps->MaxVertexShader30InstructionSlots = 0; + pCaps->MaxPixelShader30InstructionSlots = 0; + +#if DX_TO_GL_ABSTRACTION + pCaps->FakeSRGBWrite = !glmRendererInfo.m_hasGammaWrites; + pCaps->CanDoSRGBReadFromRTs = !glmRendererInfo.m_cantAttachSRGB; + pCaps->MixedSizeTargets = glmRendererInfo.m_hasMixedAttachmentSizes; +#endif +} + +HRESULT IDirect3D9::GetDeviceCaps(UINT Adapter, D3DDEVTYPE DeviceType, D3DCAPS9* pCaps) +{ + GL_BATCH_PERF_CALL_TIMER; + // Generally called from "CShaderDeviceMgrDx8::ComputeCapsFromD3D" in ShaderDeviceDX8.cpp + + // "Adapter" is used to index amongst the set of fake-adapters maintained in the display DB + GLMDisplayDB *db = GetDisplayDB(); + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + + bool result = db->GetFakeAdapterInfo( Adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); (void)result; + Assert (!result); + // just leave glmRendererInfo filled out for subsequent code to look at as needed. + + FillD3DCaps9( glmRendererInfo, pCaps ); + + return S_OK; +} + +HRESULT IDirect3D9::GetAdapterIdentifier( UINT Adapter, DWORD Flags, D3DADAPTER_IDENTIFIER9* pIdentifier ) +{ + GL_BATCH_PERF_CALL_TIMER; + // Generally called from "CShaderDeviceMgrDx8::ComputeCapsFromD3D" in ShaderDeviceDX8.cpp + + Assert( Flags == D3DENUM_WHQL_LEVEL ); // we're not handling any other queries than this yet + + Q_memset( pIdentifier, 0, sizeof(*pIdentifier) ); + + GLMDisplayDB *db = GetDisplayDB(); + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + + // the D3D "Adapter" number feeds the fake adapter index + bool result = db->GetFakeAdapterInfo( Adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); (void)result; + Assert (!result); + +#ifndef OSX + if( glmRendererInfo.m_rendererID ) +#endif + { + const char *pRenderer = GLMDecode( eGL_RENDERER, glmRendererInfo.m_rendererID & 0x00FFFF00 ); + + Q_snprintf( pIdentifier->Driver, sizeof(pIdentifier->Driver), "OpenGL %s (%08x)", + pRenderer, glmRendererInfo.m_rendererID ); + + Q_snprintf( pIdentifier->Description, sizeof(pIdentifier->Description), "%s - %dx%d - %dMB VRAM", + pRenderer, + glmDisplayInfo.m_displayPixelWidth, glmDisplayInfo.m_displayPixelHeight, + glmRendererInfo.m_vidMemory >> 20 ); + } +#ifndef OSX + else + { + static CDynamicFunctionOpenGL< true, const GLubyte *( APIENTRY *)(GLenum name), const GLubyte * > glGetString("glGetString"); + + const char *pszStringVendor = ( const char * )glGetString( GL_VENDOR ); // NVIDIA Corporation + const char *pszStringRenderer = ( const char * )glGetString( GL_RENDERER ); // GeForce GTX 680/PCIe/SSE2 + const char *pszStringVersion = ( const char * )glGetString( GL_VERSION ); // 4.2.0 NVIDIA 304.22 + + Q_snprintf( pIdentifier->Driver, sizeof( pIdentifier->Driver ), "OpenGL %s (%s)", + pszStringVendor, pszStringRenderer ); + Q_snprintf( pIdentifier->Description, sizeof( pIdentifier->Description ), "%s (%s) %s - %dx%d", + pszStringVendor, pszStringRenderer, pszStringVersion, + glmDisplayInfo.m_displayPixelWidth, glmDisplayInfo.m_displayPixelHeight ); + } +#endif // !OSX + + pIdentifier->VendorId = glmRendererInfo.m_pciVendorID; // 4318; + pIdentifier->DeviceId = glmRendererInfo.m_pciDeviceID; // 401; + pIdentifier->SubSysId = 0; // 3358668866; + pIdentifier->Revision = 0; // 162; + pIdentifier->VideoMemory = glmRendererInfo.m_vidMemory; // amount of video memory in bytes + + #if 0 + // this came from the shaderapigl effort + Q_strncpy( pIdentifier->Driver, "Fake-Video-Card", MAX_DEVICE_IDENTIFIER_STRING ); + Q_strncpy( pIdentifier->Description, "Fake-Video-Card", MAX_DEVICE_IDENTIFIER_STRING ); + pIdentifier->VendorId = 4318; + pIdentifier->DeviceId = 401; + pIdentifier->SubSysId = 3358668866; + pIdentifier->Revision = 162; + #endif + + return S_OK; +} + +HRESULT IDirect3D9::CheckDeviceFormat(UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,DWORD Usage,D3DRESOURCETYPE RType,D3DFORMAT CheckFormat) +{ + GL_BATCH_PERF_CALL_TIMER; + if (0) // hush for now, less spew + { + GLMPRINTF(("-X- ** IDirect3D9::CheckDeviceFormat: \n -- Adapter=%d || DeviceType=%4x:%s || AdapterFormat=%8x:%s\n -- RType %8x: %s\n -- CheckFormat %8x: %s\n -- Usage %8x: %s", + Adapter, + DeviceType, GLMDecode(eD3D_DEVTYPE, DeviceType), + AdapterFormat, GLMDecode(eD3D_FORMAT, AdapterFormat), + RType, GLMDecode(eD3D_RTYPE, RType), + CheckFormat, GLMDecode(eD3D_FORMAT, CheckFormat), + Usage, GLMDecodeMask( eD3D_USAGE, Usage ) )); + } + + HRESULT result = D3DERR_NOTAVAILABLE; // failure + + DWORD knownUsageMask = D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP + | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_SRGBWRITE | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING + | D3DUSAGE_QUERY_VERTEXTEXTURE; + (void)knownUsageMask; + + // FramebufferSRGB stuff. + // basically a format is only allowed to have SRGB usage for writing, if you have the framebuffer SRGB extension. + // so, check for that capability with GLM adapter db, and if it's not there, don't mark that bit as usable in any of our formats. + GLMDisplayDB *db = GetDisplayDB(); + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + + bool dbresult = db->GetFakeAdapterInfo( Adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); (void)dbresult; + Assert (!dbresult); + + Assert ((Usage & knownUsageMask) == Usage); + + DWORD legalUsage = 0; + switch( AdapterFormat ) + { + case D3DFMT_X8R8G8B8: + switch( RType ) + { + case D3DRTYPE_TEXTURE: + switch( CheckFormat ) + { + case D3DFMT_DXT1: + case D3DFMT_DXT3: + case D3DFMT_DXT5: + legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_QUERY_SRGBREAD; + + //open question: is auto gen of mipmaps is allowed or attempted on any DXT textures. + break; + + case D3DFMT_A8R8G8B8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + break; + +//$ TODO: Need to merge bitmap changes over from Dota to get these formats. +#if 0 + case D3DFMT_A2R10G10B10: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + break; + + case D3DFMT_A2B10G10R10: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + break; +#endif + + case D3DFMT_R32F: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + break; + + case D3DFMT_A16B16G16R16: + legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + break; + + case D3DFMT_A16B16G16R16F: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE; + + if ( !glmRendererInfo.m_atiR5xx ) + { + legalUsage |= D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + } + break; + + case D3DFMT_A32B32G32R32F: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_RENDERTARGET | D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE; + + if ( !glmRendererInfo.m_atiR5xx && !glmRendererInfo.m_nvG7x ) + { + legalUsage |= D3DUSAGE_QUERY_FILTER | D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING; + } + break; + + case D3DFMT_R5G6B5: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + //----------------------------------------------------------- + // these come in from TestTextureFormat in ColorFormatDX8.cpp which is being driven by InitializeColorInformation... + // which is going to try all 8 combinations of (vertex texturable / render targetable / filterable ) on every image format it knows. + + case D3DFMT_R8G8B8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_QUERY_SRGBREAD; + break; + + case D3DFMT_X8R8G8B8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + legalUsage |= D3DUSAGE_QUERY_SRGBREAD | D3DUSAGE_QUERY_SRGBWRITE; + break; + + // one and two channel textures... we'll have to fake these as four channel tex if we want to support them + case D3DFMT_L8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + case D3DFMT_A8L8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + case D3DFMT_A8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + // going to need to go back and double check all of these.. + case D3DFMT_X1R5G5B5: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + case D3DFMT_A4R4G4B4: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + case D3DFMT_A1R5G5B5: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + case D3DFMT_V8U8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + break; + + case D3DFMT_Q8W8V8U8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + // what the heck is QWVU8 ... ? + break; + + case D3DFMT_X8L8V8U8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_AUTOGENMIPMAP | D3DUSAGE_QUERY_FILTER; + // what the heck is XLVU8 ... ? + break; + + // formats with depth... + + case D3DFMT_D16: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL; + // just a guess on the legal usages + break; + + case D3DFMT_D24S8: legalUsage = D3DUSAGE_DYNAMIC | D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL; + // just a guess on the legal usages + break; + + // vendor formats... try marking these all invalid for now + case D3DFMT_NV_INTZ: + case D3DFMT_NV_RAWZ: + case D3DFMT_NV_NULL: + case D3DFMT_ATI_D16: + case D3DFMT_ATI_D24S8: + case D3DFMT_ATI_2N: + case D3DFMT_ATI_1N: + legalUsage = 0; + break; + + //----------------------------------------------------------- + + default: + Assert(!"Unknown check format"); + result = D3DERR_NOTAVAILABLE; + break; + } + + if ((Usage & legalUsage) == Usage) + { + result = S_OK; + } + else + { + DWORD unsatBits = Usage & (~legalUsage); // clear the bits of the req that were legal, leaving the illegal ones + unsatBits; + GLMPRINTF(( "-X- --> NOT OK: flags %8x:%s", unsatBits,GLMDecodeMask( eD3D_USAGE, unsatBits ) )); + result = D3DERR_NOTAVAILABLE; + } + break; + + case D3DRTYPE_SURFACE: + switch( static_cast(CheckFormat) ) + { + case 0x434f5441: + case 0x41415353: + result = D3DERR_NOTAVAILABLE; + break; + + case D3DFMT_D24S8: + result = S_OK; + break; + //** IDirect3D9::CheckDeviceFormat adapter=0, DeviceType= 1:D3DDEVTYPE_HAL, AdapterFormat= 5:D3DFMT_X8R8G8B8, RType= 1:D3DRTYPE_SURFACE, CheckFormat=434f5441:UNKNOWN + //** IDirect3D9::CheckDeviceFormat adapter=0, DeviceType= 1:D3DDEVTYPE_HAL, AdapterFormat= 5:D3DFMT_X8R8G8B8, RType= 1:D3DRTYPE_SURFACE, CheckFormat=41415353:UNKNOWN + //** IDirect3D9::CheckDeviceFormat adapter=0, DeviceType= 1:D3DDEVTYPE_HAL, AdapterFormat= 5:D3DFMT_X8R8G8B8, RType= 1:D3DRTYPE_SURFACE, CheckFormat=434f5441:UNKNOWN + //** IDirect3D9::CheckDeviceFormat adapter=0, DeviceType= 1:D3DDEVTYPE_HAL, AdapterFormat= 5:D3DFMT_X8R8G8B8, RType= 1:D3DRTYPE_SURFACE, CheckFormat=41415353:UNKNOWN + } + break; + + default: + Assert(!"Unknown resource type"); + result = D3DERR_NOTAVAILABLE; + break; + } + break; + + default: + Assert(!"Unknown adapter format"); + result = D3DERR_NOTAVAILABLE; + break; + } + + return result; +} + +UINT IDirect3D9::GetAdapterModeCount(UINT Adapter,D3DFORMAT Format) +{ + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF(( "-X- IDirect3D9::GetAdapterModeCount: Adapter=%d || Format=%8x:%s", Adapter, Format, GLMDecode(eD3D_FORMAT, Format) )); + + uint modeCount=0; + + GLMDisplayDB *db = GetDisplayDB(); + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + + // the D3D "Adapter" number feeds the fake adapter index + bool result = db->GetFakeAdapterInfo( Adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); (void)result; + Assert (!result); + + modeCount = db->GetModeCount( glmRendererIndex, glmDisplayIndex ); + GLMPRINTF(( "-X- --> result is %d", modeCount )); + + return modeCount; +} + +HRESULT IDirect3D9::EnumAdapterModes(UINT Adapter,D3DFORMAT Format,UINT Mode,D3DDISPLAYMODE* pMode) +{ + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF(( "-X- IDirect3D9::EnumAdapterModes: Adapter=%d || Format=%8x:%s || Mode=%d", Adapter, Format, GLMDecode(eD3D_FORMAT, Format), Mode )); + + Assert(Format==D3DFMT_X8R8G8B8); + + GLMDisplayDB *db = GetDisplayDB(); + + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + GLMDisplayModeInfoFields glmModeInfo; + + // the D3D "Adapter" number feeds the fake adapter index + bool result = db->GetFakeAdapterInfo( Adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); + Assert (!result); + if (result) return D3DERR_NOTAVAILABLE; + + bool result2 = db->GetModeInfo( glmRendererIndex, glmDisplayIndex, Mode, &glmModeInfo ); + Assert( !result2 ); + if (result2) return D3DERR_NOTAVAILABLE; + + pMode->Width = glmModeInfo.m_modePixelWidth; + pMode->Height = glmModeInfo.m_modePixelHeight; + pMode->RefreshRate = glmModeInfo.m_modeRefreshHz; // "adapter default" + pMode->Format = Format; // whatever you asked for ? + + GLMPRINTF(( "-X- IDirect3D9::EnumAdapterModes returning mode size (%d,%d) and D3DFMT_X8R8G8B8",pMode->Width,pMode->Height )); + return S_OK; +} + +HRESULT IDirect3D9::CheckDeviceType(UINT Adapter,D3DDEVTYPE DevType,D3DFORMAT AdapterFormat,D3DFORMAT BackBufferFormat,BOOL bWindowed) +{ + GL_BATCH_PERF_CALL_TIMER; + //FIXME: we just say "OK" on any query + + GLMPRINTF(( "-X- IDirect3D9::CheckDeviceType: Adapter=%d || DevType=%d:%s || AdapterFormat=%d:%s || BackBufferFormat=%d:%s || bWindowed=%d", + Adapter, + DevType, GLMDecode(eD3D_DEVTYPE,DevType), + AdapterFormat, GLMDecode(eD3D_FORMAT, AdapterFormat), + BackBufferFormat, GLMDecode(eD3D_FORMAT, BackBufferFormat), + (int) bWindowed )); + + return S_OK; +} + +HRESULT IDirect3D9::GetAdapterDisplayMode(UINT Adapter,D3DDISPLAYMODE* pMode) +{ + GL_BATCH_PERF_CALL_TIMER; + // asking what the current mode is + GLMPRINTF(("-X- IDirect3D9::GetAdapterDisplayMode: Adapter=%d", Adapter )); + + GLMDisplayDB *db = GetDisplayDB(); + + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + GLMDisplayModeInfoFields glmModeInfo; + + // the D3D "Adapter" number feeds the fake adapter index + bool result = db->GetFakeAdapterInfo( Adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); + Assert(!result); + if (result) return D3DERR_INVALIDCALL; + + int modeIndex = -1; // pass -1 as a mode index to find out about whatever the current mode is on the selected display + + bool modeResult = db->GetModeInfo( glmRendererIndex, glmDisplayIndex, modeIndex, &glmModeInfo ); + Assert (!modeResult); + if (modeResult) return D3DERR_INVALIDCALL; + + pMode->Width = glmModeInfo.m_modePixelWidth; + pMode->Height = glmModeInfo.m_modePixelHeight; + pMode->RefreshRate = glmModeInfo.m_modeRefreshHz; // "adapter default" + pMode->Format = D3DFMT_X8R8G8B8; //FIXME, this is a SWAG + + return S_OK; +} + +HRESULT IDirect3D9::CheckDepthStencilMatch(UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT AdapterFormat,D3DFORMAT RenderTargetFormat,D3DFORMAT DepthStencilFormat) +{ + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF(("-X- IDirect3D9::CheckDepthStencilMatch: Adapter=%d || DevType=%d:%s || AdapterFormat=%d:%s || RenderTargetFormat=%d:%s || DepthStencilFormat=%d:%s", + Adapter, + DeviceType, GLMDecode(eD3D_DEVTYPE,DeviceType), + AdapterFormat, GLMDecode(eD3D_FORMAT, AdapterFormat), + RenderTargetFormat, GLMDecode(eD3D_FORMAT, RenderTargetFormat), + DepthStencilFormat, GLMDecode(eD3D_FORMAT, DepthStencilFormat) )); + + // one known request looks like this: + // AdapterFormat=5:D3DFMT_X8R8G8B8 || RenderTargetFormat=3:D3DFMT_A8R8G8B8 || DepthStencilFormat=2:D3DFMT_D24S8 + + // return S_OK for that one combo, DXABSTRACT_BREAK_ON_ERROR() on anything else + HRESULT result = D3DERR_NOTAVAILABLE; // failure + + switch( AdapterFormat ) + { + case D3DFMT_X8R8G8B8: + { + if ( (RenderTargetFormat == D3DFMT_A8R8G8B8) && (DepthStencilFormat == D3DFMT_D24S8) ) + { + result = S_OK; + } + } + break; + } + + Assert( result == S_OK ); + + return result; +} + +HRESULT IDirect3D9::CheckDeviceMultiSampleType( UINT Adapter,D3DDEVTYPE DeviceType,D3DFORMAT SurfaceFormat,BOOL Windowed,D3DMULTISAMPLE_TYPE MultiSampleType,DWORD* pQualityLevels ) +{ + GL_BATCH_PERF_CALL_TIMER; + GLMDisplayDB *db = GetDisplayDB(); + + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + //GLMDisplayModeInfoFields glmModeInfo; + + // the D3D "Adapter" number feeds the fake adapter index + bool result = db->GetFakeAdapterInfo( Adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); + Assert( !result ); + if ( result ) + return D3DERR_INVALIDCALL; + + + if ( !CommandLine()->FindParm("-glmenabletrustmsaa") ) + { + // These ghetto drivers don't get MSAA + if ( ( glmRendererInfo.m_nvG7x || glmRendererInfo.m_atiR5xx ) && ( MultiSampleType > D3DMULTISAMPLE_NONE ) ) + { + if ( pQualityLevels ) + { + *pQualityLevels = 0; + } + return D3DERR_NOTAVAILABLE; + } + } + + switch ( MultiSampleType ) + { + case D3DMULTISAMPLE_NONE: // always return true + if ( pQualityLevels ) + { + *pQualityLevels = 1; + } + return S_OK; + break; + + case D3DMULTISAMPLE_2_SAMPLES: + case D3DMULTISAMPLE_4_SAMPLES: + case D3DMULTISAMPLE_6_SAMPLES: + case D3DMULTISAMPLE_8_SAMPLES: + // note the fact that the d3d enums for 2, 4, 6, 8 samples are equal to 2,4,6,8... + if (glmRendererInfo.m_maxSamples >= (int)MultiSampleType ) + { + if ( pQualityLevels ) + { + *pQualityLevels = 1; + } + return S_OK; + } + else + { + return D3DERR_NOTAVAILABLE; + } + break; + + default: + if ( pQualityLevels ) + { + *pQualityLevels = 0; + } + return D3DERR_NOTAVAILABLE; + break; + } + return D3DERR_NOTAVAILABLE; +} + +HRESULT IDirect3D9::CreateDevice(UINT Adapter,D3DDEVTYPE DeviceType,VD3DHWND hFocusWindow,DWORD BehaviorFlags,D3DPRESENT_PARAMETERS* pPresentationParameters,IDirect3DDevice9** ppReturnedDeviceInterface) +{ + GL_BATCH_PERF_CALL_TIMER; + +#if GLMDEBUG + GLMDebugPrintf( "WARNING: GLMEBUG is 1, perf. is going to be low!" ); + Warning( "WARNING: GLMEBUG is 1, perf. is going to be low!" ); +#endif +#if !TOGL_SUPPORT_NULL_DEVICE + if (DeviceType == D3DDEVTYPE_NULLREF) + { + Error( "Must define TOGL_SUPPORT_NULL_DEVICE to use the NULL device" ); + DebuggerBreak(); + return E_FAIL; + } +#endif + + // constrain these inputs for the time being + // BackBufferFormat -> A8R8G8B8 + // BackBufferCount -> 1; + // MultiSampleType -> D3DMULTISAMPLE_NONE + // AutoDepthStencilFormat -> D3DFMT_D24S8 + + // NULL out the return pointer so if we exit early it is not set + *ppReturnedDeviceInterface = NULL; + + // assume success unless something is sour + HRESULT result = S_OK; + + // relax this check for now + //if (pPresentationParameters->BackBufferFormat != D3DFMT_A8R8G8B8) + //{ + // DXABSTRACT_BREAK_ON_ERROR(); + // result = -1; + //} + + //rbarris 24Aug10 - relaxing this check - we don't care if the game asks for two backbuffers, it's moot + //if ( pPresentationParameters->BackBufferCount != 1 ) + //{ + // DXABSTRACT_BREAK_ON_ERROR(); + // result = D3DERR_NOTAVAILABLE; + //} + + if ( pPresentationParameters->AutoDepthStencilFormat != D3DFMT_D24S8 ) + { + DXABSTRACT_BREAK_ON_ERROR(); + result = D3DERR_NOTAVAILABLE; + } + + if ( result == S_OK ) + { + // create an IDirect3DDevice9 + // it will make a GLMContext and set up some drawables + + IDirect3DDevice9Params devparams; + memset( &devparams, 0, sizeof(devparams) ); + + devparams.m_adapter = Adapter; + devparams.m_deviceType = DeviceType; + devparams.m_focusWindow = hFocusWindow; // is this meaningful? is this a WindowRef ? follow it up the chain.. + devparams.m_behaviorFlags = BehaviorFlags; + devparams.m_presentationParameters = *pPresentationParameters; + + IDirect3DDevice9 *dev = new IDirect3DDevice9; + + result = dev->Create( &devparams ); + + if ( result == S_OK ) + { + *ppReturnedDeviceInterface = dev; + } + + g_bNullD3DDevice = ( DeviceType == D3DDEVTYPE_NULLREF ); + } + return result; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DQuery9 + +#endif + +HRESULT IDirect3DQuery9::Issue(DWORD dwIssueFlags) +{ + GL_BATCH_PERF_CALL_TIMER; + Assert( m_device->m_nValidMarker == D3D_DEVICE_VALID_MARKER ); + // Flags field for Issue + // #define D3DISSUE_END (1 << 0) // Tells the runtime to issue the end of a query, changing it's state to "non-signaled". + // #define D3DISSUE_BEGIN (1 << 1) // Tells the runtime to issue the beginng of a query. + + // Make sure calling thread owns the GL context. + Assert( m_ctx->m_nCurOwnerThreadId == ThreadGetCurrentId() ); + + if (dwIssueFlags & D3DISSUE_BEGIN) + { + m_nIssueStartThreadID = ThreadGetCurrentId(); + m_nIssueStartDrawCallIndex = g_nTotalDrawsOrClears; + m_nIssueStartFrameIndex = m_ctx->m_nCurFrame; + m_nIssueStartQueryCreationCounter = CGLMQuery::s_nTotalOcclusionQueryCreatesOrDeletes; + + switch( m_type ) + { + case D3DQUERYTYPE_OCCLUSION: + m_query->Start(); // drop "start counter" call into stream + break; + + default: + Assert(!"Can't use D3DISSUE_BEGIN on this query"); + break; + } + } + + if (dwIssueFlags & D3DISSUE_END) + { + m_nIssueEndThreadID = ThreadGetCurrentId(); + m_nIssueEndDrawCallIndex = g_nTotalDrawsOrClears; + m_nIssueEndFrameIndex = m_ctx->m_nCurFrame; + m_nIssueEndQueryCreationCounter = CGLMQuery::s_nTotalOcclusionQueryCreatesOrDeletes; + + switch( m_type ) + { + case D3DQUERYTYPE_OCCLUSION: + m_query->Stop(); // drop "end counter" call into stream + break; + + case D3DQUERYTYPE_EVENT: + m_nIssueStartThreadID = m_nIssueEndThreadID; + m_nIssueStartDrawCallIndex = m_nIssueEndDrawCallIndex; + m_nIssueStartFrameIndex = m_nIssueEndFrameIndex; + m_nIssueStartQueryCreationCounter = m_nIssueEndQueryCreationCounter; + + // End is very weird with respect to Events (fences). + // DX9 docs say to use End to put the fence in the stream. So we map End to GLM's Start. + // http://msdn.microsoft.com/en-us/library/ee422167(VS.85).aspx + m_query->Start(); // drop "set fence" into stream + break; + } + } + return S_OK; +} + +HRESULT IDirect3DQuery9::GetData(void* pData,DWORD dwSize,DWORD dwGetDataFlags) +{ + GL_BATCH_PERF_CALL_TIMER; + Assert( m_device->m_nValidMarker == D3D_DEVICE_VALID_MARKER ); + HRESULT result = S_FALSE ; + DWORD nCurThreadId = ThreadGetCurrentId(); + + // Make sure calling thread owns the GL context. + Assert( m_ctx->m_nCurOwnerThreadId == nCurThreadId ); + if ( pData ) + { + *(uint*)pData = 0; + } + + if ( !m_query->IsStarted() || !m_query->IsStopped() ) + { + Assert(!"Can't GetData before issue/start/stop"); + printf("\n** IDirect3DQuery9::GetData: can't GetData before issue/start/stop"); + return S_FALSE; + } + + // GetData is not always called with the flush bit. + + // if an answer is not yet available - return S_FALSE. + // if an answer is available - return S_OK and write the answer into *pData. + bool done = false; + bool flush = (dwGetDataFlags & D3DGETDATA_FLUSH) != 0; // aka spin until done + + // hmmm both of these paths are the same, maybe we could fold them up + if ( m_type == D3DQUERYTYPE_OCCLUSION ) + { + // Detect cases that are actually just not supported with the way we're using GL queries. (For example, beginning a query, then creating/deleting any query, the ending the same query is not supported.) + // Also extra paranoid to detect/work around various NV/AMD driver issues. + if ( ( ( m_nIssueStartThreadID != nCurThreadId ) || ( m_nIssueEndThreadID != nCurThreadId ) ) || + ( m_nIssueStartDrawCallIndex == m_nIssueEndDrawCallIndex ) || ( m_nIssueStartFrameIndex != m_nIssueEndFrameIndex ) || + ( m_nIssueStartQueryCreationCounter != m_nIssueEndQueryCreationCounter ) ) + { + // The thread Issue() was called on differs from GetData() - NV's driver doesn't like this, not sure about AMD. Just fake the results if a flush is requested. + // There are various ways to properly handle this scenario, but in practice it only seems to occur in non-critical times (during shutdown or when mat_queue_mode is changed in L4D2). + if ( flush ) + { + gGL->glFlush(); + } + +#if 0 + if ( ( m_nIssueStartThreadID != nCurThreadId ) || ( m_nIssueEndThreadID != nCurThreadId ) ) + { + GLMDebugPrintf( "IDirect3DQuery9::GetData: GetData() called from different thread verses the issueing thread()!\n" ); + } +#endif + if ( m_nIssueStartQueryCreationCounter != m_nIssueEndQueryCreationCounter ) + { + GLMDebugPrintf( "IDirect3DQuery9::GetData: One or more queries have been created or released while this query was still issued! This scenario is not supported in GL.\n"); + } + + // Return with a non-standard error code, so the caller has a chance to do something halfway intelligent. + return D3DERR_NOTAVAILABLE; + } + } + + switch( m_type ) + { + case D3DQUERYTYPE_OCCLUSION: + { + + if ( flush ) + { + uint oqValue = 0; + CFastTimer tm; + tm.Start(); + + + // Is this flush actually necessary? According to the extension it's not. + // It doesn't seem to matter if this is a glFlush() or glFinish() with NVidia's driver (tested in MT mode - not sure if it matters), it still can take several calls to IsDone() before we can stop waiting for the query results. + // On AMD, this flush logic fails during shutdown (the query results never become available) - tried a bunch of experiments and checks with no luck. + + m_query->Complete(&oqValue); + + + double flTotalTime = tm.GetDurationInProgress().GetSeconds() * 1000.0f; + if ( flTotalTime > .5f ) + { + // Give up - something silly has obviously gone wrong in the driver, lying is better than stalling potentially forever. + // This occurs on AMD (single threaded driver) during shutdown, not sure why yet. It has nothing to do with threading. It may have to do with releasing queries or other objects. + // We must return a result otherwise the app itself could hang, waiting infinitely. + //Assert( 0 ); + Warning( "IDirect3DQuery9::GetData(): Occlusion query flush took %3.3fms!\n", flTotalTime ); + } + if (pData) + { + *(uint*)pData = oqValue; + } + result = S_OK; + } + else + { + done = m_query->IsDone(); + if (done) + { + uint oqValue = 0; // or we could just pass pData directly to Complete... + m_query->Complete(&oqValue); + if (pData) + { + *(uint*)pData = oqValue; + } + result = S_OK; + } + else + { + result = S_FALSE; + Assert( !flush ); + } + } + } + break; + + case D3DQUERYTYPE_EVENT: + { + done = m_query->IsDone(); + if ( ( done ) || ( flush ) ) + { + m_query->Complete(NULL); // this will block on pre-SLGU + + result = S_OK; + } + else + { + result = S_FALSE; + Assert( !flush ); + } + } + break; + } + + return result; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DVertexBuffer9 + +#endif + +HRESULT IDirect3DDevice9::CreateVertexBuffer(UINT Length,DWORD Usage,DWORD FVF,D3DPOOL Pool,IDirect3DVertexBuffer9** ppVertexBuffer,VD3DHANDLE* pSharedHandle) +{ + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF(( ">-A- IDirect3DDevice9::CreateVertexBuffer" )); + Assert( m_ctx->m_nCurOwnerThreadId == ThreadGetCurrentId() ); + + m_ObjectStats.m_nTotalVertexBuffers++; + + IDirect3DVertexBuffer9 *newbuff = new IDirect3DVertexBuffer9; + + newbuff->m_device = this; + + newbuff->m_ctx = m_ctx; + + // FIXME need to find home or use for the Usage, FVF, Pool values passed in + uint options = 0; + + if (Usage&D3DUSAGE_DYNAMIC) + { + options |= GLMBufferOptionDynamic; + } + + newbuff->m_vtxBuffer = m_ctx->NewBuffer( kGLMVertexBuffer, Length, options ) ; + + newbuff->m_vtxDesc.Type = D3DRTYPE_VERTEXBUFFER; + newbuff->m_vtxDesc.Usage = Usage; + newbuff->m_vtxDesc.Pool = Pool; + newbuff->m_vtxDesc.Size = Length; + + *ppVertexBuffer = newbuff; + + GLMPRINTF(( "<-A- IDirect3DDevice9::CreateVertexBuffer" )); + + return S_OK; +} + +IDirect3DVertexBuffer9::~IDirect3DVertexBuffer9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF(( ">-A- ~IDirect3DVertexBuffer9" )); + + if (m_device) + { + m_device->ReleasedVertexBuffer( this ); + + if (m_ctx && m_vtxBuffer) + { + GLMPRINTF(( ">-A- ~IDirect3DVertexBuffer9 deleting m_vtxBuffer" )); + m_ctx->DelBuffer( m_vtxBuffer ); + m_vtxBuffer = NULL; + GLMPRINTF(( "<-A- ~IDirect3DVertexBuffer9 deleting m_vtxBuffer - done" )); + } + m_device = NULL; + } + + GLMPRINTF(( "<-A- ~IDirect3DVertexBuffer9" )); +} + +HRESULT IDirect3DVertexBuffer9::Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + tmZoneFiltered( TELEMETRY_LEVEL2, 25, TMZF_NONE, "VB Lock" ); + + // FIXME would be good to have "can't lock twice" logic + + Assert( !(Flags & D3DLOCK_READONLY) ); // not impl'd +// Assert( !(Flags & D3DLOCK_NOSYSLOCK) ); // not impl'd - it triggers though + + GLMBuffLockParams lockreq; + lockreq.m_nOffset = OffsetToLock; + lockreq.m_nSize = SizeToLock; + lockreq.m_bNoOverwrite = (Flags & D3DLOCK_NOOVERWRITE) != 0; + lockreq.m_bDiscard = (Flags & D3DLOCK_DISCARD) != 0; + + m_vtxBuffer->Lock( &lockreq, (char**)ppbData ); + + GLMPRINTF(("-X- IDirect3DDevice9::Lock on D3D buf %p (GL name %d) offset %d, size %d => address %p", this, this->m_vtxBuffer->m_nHandle, OffsetToLock, SizeToLock, *ppbData)); + return S_OK; +} + +HRESULT IDirect3DVertexBuffer9::Unlock() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + tmZoneFiltered( TELEMETRY_LEVEL2, 25, TMZF_NONE, "VB Unlock" ); + + m_vtxBuffer->Unlock(); + return S_OK; +} + +void IDirect3DVertexBuffer9::UnlockActualSize( uint nActualSize, const void *pActualData ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + tmZoneFiltered( TELEMETRY_LEVEL2, 25, TMZF_NONE, "VB UnlockActualSize" ); + + m_vtxBuffer->Unlock( nActualSize, pActualData ); +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + + +#ifdef OSX + +#pragma mark ----- IDirect3DIndexBuffer9 + +#endif + +HRESULT IDirect3DDevice9::CreateIndexBuffer(UINT Length,DWORD Usage,D3DFORMAT Format,D3DPOOL Pool,IDirect3DIndexBuffer9** ppIndexBuffer,VD3DHANDLE* pSharedHandle) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + GLMPRINTF(( ">-A- IDirect3DDevice9::CreateIndexBuffer" )); + + // it is important to save all the create info, since GetDesc could get called later to query it + + m_ObjectStats.m_nTotalIndexBuffers++; + + IDirect3DIndexBuffer9 *newbuff = new IDirect3DIndexBuffer9; + + newbuff->m_device = this; + + newbuff->m_restype = D3DRTYPE_INDEXBUFFER; // hmmmmmmm why are we not derived from d3dresource.. + + newbuff->m_ctx = m_ctx; + + // FIXME need to find home or use for the Usage, Format, Pool values passed in + uint options = 0; + + if (Usage&D3DUSAGE_DYNAMIC) + { + options |= GLMBufferOptionDynamic; + } + + newbuff->m_idxBuffer = m_ctx->NewBuffer( kGLMIndexBuffer, Length, options ) ; + + newbuff->m_idxDesc.Format = Format; + newbuff->m_idxDesc.Type = D3DRTYPE_INDEXBUFFER; + newbuff->m_idxDesc.Usage = Usage; + newbuff->m_idxDesc.Pool = Pool; + newbuff->m_idxDesc.Size = Length; + + *ppIndexBuffer = newbuff; + + GLMPRINTF(( "<-A- IDirect3DDevice9::CreateIndexBuffer" )); + + return S_OK; +} + +IDirect3DIndexBuffer9::~IDirect3DIndexBuffer9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF(( ">-A- ~IDirect3DIndexBuffer9" )); + + if (m_device) + { + m_device->ReleasedIndexBuffer( this ); + + if (m_ctx && m_idxBuffer) + { + GLMPRINTF(( ">-A- ~IDirect3DIndexBuffer9 deleting m_idxBuffer" )); + m_ctx->DelBuffer( m_idxBuffer ); + GLMPRINTF(( "<-A- ~IDirect3DIndexBuffer9 deleting m_idxBuffer - done" )); + } + m_device = NULL; + } + else + { + } + + GLMPRINTF(( "<-A- ~IDirect3DIndexBuffer9" )); +} + + +HRESULT IDirect3DIndexBuffer9::Lock(UINT OffsetToLock,UINT SizeToLock,void** ppbData,DWORD Flags) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + // FIXME would be good to have "can't lock twice" logic + + tmZoneFiltered( TELEMETRY_LEVEL2, 25, TMZF_NONE, "IB Lock" ); + + GLMBuffLockParams lockreq; + lockreq.m_nOffset = OffsetToLock; + lockreq.m_nSize = SizeToLock; + lockreq.m_bNoOverwrite = ( Flags & D3DLOCK_NOOVERWRITE ) != 0; + lockreq.m_bDiscard = ( Flags & D3DLOCK_DISCARD ) != 0; + + m_idxBuffer->Lock( &lockreq, (char**)ppbData ); + + return S_OK; +} + +HRESULT IDirect3DIndexBuffer9::Unlock() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + + tmZoneFiltered( TELEMETRY_LEVEL2, 25, TMZF_NONE, "IB Unlock" ); + + m_idxBuffer->Unlock(); + + return S_OK; +} + +void IDirect3DIndexBuffer9::UnlockActualSize( uint nActualSize, const void *pActualData ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + tmZoneFiltered( TELEMETRY_LEVEL2, 25, TMZF_NONE, "IB UnlockActualSize" ); + + m_idxBuffer->Unlock( nActualSize, pActualData ); +} + +HRESULT IDirect3DIndexBuffer9::GetDesc(D3DINDEXBUFFER_DESC *pDesc) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + *pDesc = m_idxDesc; + return S_OK; +} + + +// ------------------------------------------------------------------------------------------------------------------------------ // + +#ifdef OSX + +#pragma mark ----- IDirect3DDevice9 ------------------------------------------------- + +#endif + +void ConvertPresentationParamsToGLMDisplayParams( D3DPRESENT_PARAMETERS *d3dp, GLMDisplayParams *gldp ) +{ + memset( gldp, 0, sizeof(*gldp) ); + + gldp->m_fsEnable = !d3dp->Windowed; + + // see http://msdn.microsoft.com/en-us/library/ee416515(VS.85).aspx + // note that the values below are the only ones mentioned by Source engine; there are many others + switch(d3dp->PresentationInterval) + { + case D3DPRESENT_INTERVAL_ONE: + gldp->m_vsyncEnable = true; // "The driver will wait for the vertical retrace period (the runtime will beam-follow to prevent tearing)." + break; + + case D3DPRESENT_INTERVAL_IMMEDIATE: + gldp->m_vsyncEnable = false; // "The runtime updates the window client area immediately and might do so more than once during the adapter refresh period." + break; + + default: + gldp->m_vsyncEnable = true; // if I don't know it, you're getting vsync enabled. + break; + } + + gldp->m_backBufferWidth = d3dp->BackBufferWidth; + gldp->m_backBufferHeight = d3dp->BackBufferHeight; + gldp->m_backBufferFormat = d3dp->BackBufferFormat; + gldp->m_multiSampleCount = d3dp->MultiSampleType; // it's a count really + + gldp->m_enableAutoDepthStencil = d3dp->EnableAutoDepthStencil != 0; + gldp->m_autoDepthStencilFormat = d3dp->AutoDepthStencilFormat; + + gldp->m_fsRefreshHz = d3dp->FullScreen_RefreshRateInHz; + + // some fields in d3d PB we're not acting on yet... + // UINT BackBufferCount; + // DWORD MultiSampleQuality; + // D3DSWAPEFFECT SwapEffect; + // VD3DHWND hDeviceWindow; + // DWORD Flags; +} + +void UnpackD3DRSITable( void ); + +HRESULT IDirect3DDevice9::Create( IDirect3DDevice9Params *params ) +{ + g_pD3D_Device = this; + + GLMDebugPrintf( "IDirect3DDevice9::Create: BackBufWidth: %u, BackBufHeight: %u, D3DFMT: %u, BackBufCount: %u, MultisampleType: %u, MultisampleQuality: %u\n", + params->m_presentationParameters.BackBufferWidth, + params->m_presentationParameters.BackBufferHeight, + params->m_presentationParameters.BackBufferFormat, + params->m_presentationParameters.BackBufferCount, + params->m_presentationParameters.MultiSampleType, + params->m_presentationParameters.MultiSampleQuality ); + + UnpackD3DRSITable(); + + m_ObjectStats.clear(); + m_PrevObjectStats.clear(); + +#if GL_BATCH_PERF_ANALYSIS && GL_BATCH_PERF_ANALYSIS_WRITE_PNGS + m_pBatch_vis_bitmap = NULL; +#endif + + GL_BATCH_PERF_CALL_TIMER; + GLMPRINTF((">-X-IDirect3DDevice9::Create")); + HRESULT result = S_OK; + + // create an IDirect3DDevice9 + // make a GLMContext and set up some drawables + m_params = *params; + + m_ctx = NULL; + + V_memset( m_pRenderTargets, 0, sizeof( m_pRenderTargets ) ); + m_pDepthStencil = NULL; + + m_pDefaultColorSurface = NULL; + m_pDefaultDepthStencilSurface = NULL; + + memset( m_streams, 0, sizeof(m_streams) ); + memset( m_vtx_buffers, 0, sizeof( m_vtx_buffers ) ); + memset( m_textures, 0, sizeof(m_textures) ); + //memset( m_samplers, 0, sizeof(m_samplers) ); + + m_indices.m_idxBuffer = NULL; + + m_vertexShader = NULL; + m_pixelShader = NULL; + + m_pVertDecl = NULL; + + //============================================================================ + // param block for GLM context create + GLMDisplayParams glmParams; + ConvertPresentationParamsToGLMDisplayParams( ¶ms->m_presentationParameters, &glmParams ); + + glmParams.m_mtgl = true; // forget this idea -> (params->m_behaviorFlags & D3DCREATE_MULTITHREADED) != 0; + // the call above fills in a bunch of things, but doesn't know about anything outside of the presentation params. + // those tend to be the things that do not change after create, so we do those here in Create. + + glmParams.m_focusWindow = params->m_focusWindow; + + #if 0 //FIXME-HACK + // map the D3D "adapter" to a renderer/display pair + // (that GPU will have to stay set as-is for any subsequent mode changes) + + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + + // the D3D "Adapter" number feeds the fake adapter index + bool adaptResult = GLMgr::aGLMgr()->GetDisplayDB()->GetFakeAdapterInfo( params->m_adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); + Assert(!adaptResult); + + glmParams.m_rendererIndex = glmRendererIndex; + glmParams.m_displayIndex = glmDisplayIndex; + // glmParams.m_modeIndex hmmmmm, client doesn't give us a mode number, just a resolution.. + #endif + + m_ctx = GLMgr::aGLMgr()->NewContext( this, &glmParams ); + if (!m_ctx) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Create (error out)")); + return (HRESULT) -1; + } + + // make an FBO to draw into and activate it. + m_ctx->m_drawingFBO = m_ctx->NewFBO(); + + // bind it to context. will receive attachments shortly. + m_ctx->BindFBOToCtx( m_ctx->m_drawingFBO, GL_FRAMEBUFFER ); + + m_bFBODirty = false; + + m_pFBOs = new CGLMFBOMap(); + m_pFBOs->SetLessFunc( RenderTargetState_t::LessFunc ); + + // we create two IDirect3DSurface9's. These will be known as the internal render target 0 and the depthstencil. + + GLMPRINTF(("-X- IDirect3DDevice9::Create making color render target...")); + // color surface + result = this->CreateRenderTarget( + m_params.m_presentationParameters.BackBufferWidth, // width + m_params.m_presentationParameters.BackBufferHeight, // height + m_params.m_presentationParameters.BackBufferFormat, // format + m_params.m_presentationParameters.MultiSampleType, // MSAA depth + m_params.m_presentationParameters.MultiSampleQuality, // MSAA quality + true, // lockable + &m_pDefaultColorSurface, // ppSurface + NULL, // shared handle + "InternalRT0" + ); + + if (result != S_OK) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Create (error out)")); + return result; + } + // do not do an AddRef.. + + GLMPRINTF(("-X- IDirect3DDevice9::Create making color render target complete -> %08x", m_pDefaultColorSurface )); + + GLMPRINTF(("-X- IDirect3DDevice9::Create setting color render target...")); + result = this->SetRenderTarget(0, m_pDefaultColorSurface); + if (result != S_OK) + { + GLMPRINTF(("< IDirect3DDevice9::Create (error out)")); + return result; + } + GLMPRINTF(("-X- IDirect3DDevice9::Create setting color render target complete.")); + + Assert (m_params.m_presentationParameters.EnableAutoDepthStencil); + + GLMPRINTF(("-X- IDirect3DDevice9::Create making depth-stencil...")); + result = CreateDepthStencilSurface( + m_params.m_presentationParameters.BackBufferWidth, // width + m_params.m_presentationParameters.BackBufferHeight, // height + m_params.m_presentationParameters.AutoDepthStencilFormat, // format + m_params.m_presentationParameters.MultiSampleType, // MSAA depth + m_params.m_presentationParameters.MultiSampleQuality, // MSAA quality + TRUE, // enable z-buffer discard ???? + &m_pDefaultDepthStencilSurface, // ppSurface + NULL // shared handle + ); + if (result != S_OK) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Create (error out)")); + return result; + } + // do not do an AddRef here.. + + GLMPRINTF(("-X- IDirect3DDevice9::Create making depth-stencil complete -> %08x", m_pDefaultDepthStencilSurface)); + GLMPRINTF(("-X- Direct3DDevice9::Create setting depth-stencil render target...")); + result = this->SetDepthStencilSurface(m_pDefaultDepthStencilSurface); + if (result != S_OK) + { + DXABSTRACT_BREAK_ON_ERROR(); + GLMPRINTF(("<-X- IDirect3DDevice9::Create (error out)")); + return result; + } + GLMPRINTF(("-X- IDirect3DDevice9::Create setting depth-stencil render target complete.")); + + UpdateBoundFBO(); + + bool ready = m_ctx->m_drawingFBO->IsReady(); + if (!ready) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Create (error out)")); + return (HRESULT)-1; + } + + // this next part really needs to be inside GLMContext.. or replaced with D3D style viewport setup calls. + m_ctx->GenDebugFontTex(); + + // blast the gl state mirror... + memset( &this->gl, 0, sizeof( this->gl ) ); + + InitStates(); + + GLScissorEnable_t defScissorEnable = { true }; + GLScissorBox_t defScissorBox = { 0,0, (GLsizei)m_params.m_presentationParameters.BackBufferWidth, (GLsizei)m_params.m_presentationParameters.BackBufferHeight }; + GLViewportBox_t defViewportBox = { 0,0, (GLsizei)m_params.m_presentationParameters.BackBufferWidth, (GLsizei)m_params.m_presentationParameters.BackBufferHeight, m_params.m_presentationParameters.BackBufferWidth | ( m_params.m_presentationParameters.BackBufferHeight << 16 ) }; + GLViewportDepthRange_t defViewportDepthRange = { 0.1, 1000.0 }; + GLCullFaceEnable_t defCullFaceEnable = { true }; + GLCullFrontFace_t defCullFrontFace = { GL_CCW }; + + gl.m_ScissorEnable = defScissorEnable; + gl.m_ScissorBox = defScissorBox; + gl.m_ViewportBox = defViewportBox; + gl.m_ViewportDepthRange = defViewportDepthRange; + gl.m_CullFaceEnable = defCullFaceEnable; + gl.m_CullFrontFace = defCullFrontFace; + + FullFlushStates(); + + GLMPRINTF(("<-X- IDirect3DDevice9::Create complete")); + + // so GetClientRect can return sane answers + //uint width, height; + RenderedSize( m_params.m_presentationParameters.BackBufferWidth, m_params.m_presentationParameters.BackBufferHeight, true ); // true = set + +#if GL_TELEMETRY_GPU_ZONES + g_TelemetryGPUStats.Clear(); +#endif + + GL_BATCH_PERF( + g_nTotalD3DCalls = 0, g_nTotalD3DCycles = 0, m_nBatchVisY = 0, m_nBatchVisFrameIndex = 0, m_nBatchVisFileIdx = 0, m_nNumProgramChanges = 0, m_flTotalD3DTime = 0, m_nTotalD3DCalls = 0, + m_flTotalD3DTime = 0, m_nTotalGLCalls = 0, m_flTotalGLTime = 0, m_nOverallDraws = 0, m_nOverallPrims = 0, m_nOverallD3DCalls = 0, m_flOverallD3DTime = 0, m_nOverallGLCalls = 0, m_flOverallGLTime = 0, m_nOverallProgramChanges = 0, + m_flOverallPresentTime = 0, m_flOverallPresentTimeSquared = 0, m_nOverallPresents = 0, m_flOverallSwapWindowTime = 0, m_flOverallSwapWindowTimeSquared = 0, m_nTotalPrims = 0; ); + + g_nTotalDrawsOrClears = 0; + + gGL->m_nTotalGLCycles = 0; + gGL->m_nTotalGLCalls = 0; + + m_pDummy_vtx_buffer = new CGLMBuffer( m_ctx, kGLMVertexBuffer, 4096, 0 ); + m_vtx_buffers[0] = m_pDummy_vtx_buffer; + m_vtx_buffers[1] = m_pDummy_vtx_buffer; + m_vtx_buffers[2] = m_pDummy_vtx_buffer; + m_vtx_buffers[3] = m_pDummy_vtx_buffer; + + return result; +} + +IDirect3DDevice9::IDirect3DDevice9() : + m_nValidMarker( D3D_DEVICE_VALID_MARKER ) +{ +} +IDirect3DDevice9::~IDirect3DDevice9() +{ + Assert( m_nValidMarker == D3D_DEVICE_VALID_MARKER ); +#if GL_BATCH_PERF_ANALYSIS && GL_BATCH_PERF_ANALYSIS_WRITE_PNGS + delete m_pBatch_vis_bitmap; +#endif + + delete m_pDummy_vtx_buffer; + for ( int i = 0; i < 4; i++ ) + SetRenderTarget( i, NULL ); + SetDepthStencilSurface( NULL ); + if ( m_pDefaultColorSurface ) + { + m_pDefaultColorSurface->Release( 0, "IDirect3DDevice9::~IDirect3DDevice9 release color surface" ); + m_pDefaultColorSurface = NULL; + } + if ( m_pDefaultDepthStencilSurface ) + { + m_pDefaultDepthStencilSurface->Release( 0, "IDirect3DDevice9::~IDirect3DDevice9 release depth surface" ); + m_pDefaultDepthStencilSurface = NULL; + } + + if ( m_pFBOs ) + { + ResetFBOMap(); + } + + GLMPRINTF(( "-D- IDirect3DDevice9::~IDirect3DDevice9 signpost" )); // want to know when this is called, if ever + + g_pD3D_Device = NULL; + if ( m_ObjectStats.m_nTotalFBOs ) GLMDebugPrintf( "Leaking %i FBOs\n", m_ObjectStats.m_nTotalFBOs ); + if ( m_ObjectStats.m_nTotalVertexShaders ) ConMsg( "Leaking %i vertex shaders\n", m_ObjectStats.m_nTotalVertexShaders ); + if ( m_ObjectStats.m_nTotalPixelShaders ) ConMsg( "Leaking %i pixel shaders\n", m_ObjectStats.m_nTotalPixelShaders ); + if ( m_ObjectStats.m_nTotalVertexDecls ) ConMsg( "Leaking %i vertex decls\n", m_ObjectStats.m_nTotalVertexDecls ); + if ( m_ObjectStats.m_nTotalIndexBuffers ) ConMsg( "Leaking %i index buffers\n", m_ObjectStats.m_nTotalIndexBuffers ); + if ( m_ObjectStats.m_nTotalVertexBuffers ) ConMsg( "Leaking %i vertex buffers\n", m_ObjectStats.m_nTotalVertexBuffers ); + if ( m_ObjectStats.m_nTotalTextures ) ConMsg( "Leaking %i textures\n", m_ObjectStats.m_nTotalTextures ); + if ( m_ObjectStats.m_nTotalSurfaces ) ConMsg( "Leaking %i surfaces\n", m_ObjectStats.m_nTotalSurfaces ); + if ( m_ObjectStats.m_nTotalQueries ) ConMsg( "Leaking %i queries\n", m_ObjectStats.m_nTotalQueries ); + if ( m_ObjectStats.m_nTotalRenderTargets ) ConMsg( "Leaking %i render targets\n", m_ObjectStats.m_nTotalRenderTargets ); + GLMgr::aGLMgr()->DelContext( m_ctx ); + m_ctx = NULL; + m_nValidMarker = 0xDEADBEEF; +} + +#ifdef OSX + +#pragma mark ----- Basics - (IDirect3DDevice9) + +#endif + + +HRESULT IDirect3DDevice9::Reset(D3DPRESENT_PARAMETERS* pPresentationParameters) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + Assert( m_nValidMarker == D3D_DEVICE_VALID_MARKER ); + HRESULT result = S_OK; + + // define the task of reset as: + // provide new drawable RT's for the backbuffer (color and depthstencil). + // fix up viewport / scissor.. + // then pass the new presentation parameters through to GLM. + // (it will in turn notify appframework on the next present... which may be very soon, as mode changes are usually spotted inside Present() ). + + // so some of this looks a lot like Create - we're just a subset of what it does. + // with a little work you could refactor this to be common code. + + GLMDebugPrintf( "IDirect3DDevice9::Reset: BackBufWidth: %u, BackBufHeight: %u, D3DFMT: %u, BackBufCount: %u, MultisampleType: %u, MultisampleQuality: %u\n", + pPresentationParameters->BackBufferWidth, + pPresentationParameters->BackBufferHeight, + pPresentationParameters->BackBufferFormat, + pPresentationParameters->BackBufferCount, + pPresentationParameters->MultiSampleType, + pPresentationParameters->MultiSampleQuality ); + + //------------------------------------------------------------------------------- absorb new presentation params.. + + m_params.m_presentationParameters = *pPresentationParameters; + + //------------------------------------------------------------------------------- color buffer.. + // release old color surface if it's there.. + if ( m_pDefaultColorSurface ) + { + ULONG refc = m_pDefaultColorSurface->Release( 0, "IDirect3DDevice9::Reset public release color surface" ); (void)refc; + Assert( !refc ); + m_pDefaultColorSurface = NULL; + } + + GLMPRINTF(("-X- IDirect3DDevice9::Reset making new color render target...")); + + // color surface + result = this->CreateRenderTarget( + m_params.m_presentationParameters.BackBufferWidth, // width + m_params.m_presentationParameters.BackBufferHeight, // height + m_params.m_presentationParameters.BackBufferFormat, // format + m_params.m_presentationParameters.MultiSampleType, // MSAA depth + m_params.m_presentationParameters.MultiSampleQuality, // MSAA quality + true, // lockable + &m_pDefaultColorSurface, // ppSurface + NULL // shared handle + ); + + if ( result != S_OK ) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Reset (error out)")); + return result; + } + // do not do an AddRef here.. + + GLMPRINTF(("-X- IDirect3DDevice9::Reset making color render target complete -> %08x", m_pDefaultColorSurface )); + + GLMPRINTF(("-X- IDirect3DDevice9::Reset setting color render target...")); + + result = this->SetDepthStencilSurface( NULL ); + + result = this->SetRenderTarget( 0, m_pDefaultColorSurface ); + if (result != S_OK) + { + GLMPRINTF(("< IDirect3DDevice9::Reset (error out)")); + return result; + } + GLMPRINTF(("-X- IDirect3DDevice9::Reset setting color render target complete.")); + + + //-------------------------------------------------------------------------------depth stencil buffer + // release old depthstencil surface if it's there.. + if ( m_pDefaultDepthStencilSurface ) + { + ULONG refc = m_pDefaultDepthStencilSurface->Release( 0, "IDirect3DDevice9::Reset public release depthstencil surface" ); (void)refc; + Assert(!refc); + m_pDefaultDepthStencilSurface = NULL; + } + + Assert (m_params.m_presentationParameters.EnableAutoDepthStencil); + + GLMPRINTF(("-X- IDirect3DDevice9::Reset making depth-stencil...")); + result = CreateDepthStencilSurface( + m_params.m_presentationParameters.BackBufferWidth, // width + m_params.m_presentationParameters.BackBufferHeight, // height + m_params.m_presentationParameters.AutoDepthStencilFormat, // format + m_params.m_presentationParameters.MultiSampleType, // MSAA depth + m_params.m_presentationParameters.MultiSampleQuality, // MSAA quality + TRUE, // enable z-buffer discard ???? + &m_pDefaultDepthStencilSurface, // ppSurface + NULL // shared handle + ); + if (result != S_OK) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Reset (error out)")); + return result; + } + // do not do an AddRef here.. + + GLMPRINTF(("-X- IDirect3DDevice9::Reset making depth-stencil complete -> %08x", m_pDefaultDepthStencilSurface)); + + GLMPRINTF(("-X- IDirect3DDevice9::Reset setting depth-stencil render target...")); + result = this->SetDepthStencilSurface(m_pDefaultDepthStencilSurface); + if (result != S_OK) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Reset (error out)")); + return result; + } + GLMPRINTF(("-X- IDirect3DDevice9::Reset setting depth-stencil render target complete.")); + + UpdateBoundFBO(); + + bool ready = m_ctx->m_drawingFBO->IsReady(); + if (!ready) + { + GLMPRINTF(("<-X- IDirect3DDevice9::Reset (error out)")); + return D3DERR_DEVICELOST; + } + + //-------------------------------------------------------------------------------zap viewport and scissor to new backbuffer size + + InitStates(); + + GLScissorEnable_t defScissorEnable = { true }; + GLScissorBox_t defScissorBox = { 0,0, (GLsizei)m_params.m_presentationParameters.BackBufferWidth, (GLsizei)m_params.m_presentationParameters.BackBufferHeight }; + GLViewportBox_t defViewportBox = { 0,0, (GLsizei)m_params.m_presentationParameters.BackBufferWidth, (GLsizei)m_params.m_presentationParameters.BackBufferHeight, m_params.m_presentationParameters.BackBufferWidth | ( m_params.m_presentationParameters.BackBufferHeight << 16 ) }; + GLViewportDepthRange_t defViewportDepthRange = { 0.1, 1000.0 }; + GLCullFaceEnable_t defCullFaceEnable = { true }; + GLCullFrontFace_t defCullFrontFace = { GL_CCW }; + + gl.m_ScissorEnable = defScissorEnable; + gl.m_ScissorBox = defScissorBox; + gl.m_ViewportBox = defViewportBox; + gl.m_ViewportDepthRange = defViewportDepthRange; + gl.m_CullFaceEnable = defCullFaceEnable; + gl.m_CullFrontFace = defCullFrontFace; + + FullFlushStates(); + + //-------------------------------------------------------------------------------finally, propagate new display params to GLM context + GLMDisplayParams glmParams; + ConvertPresentationParamsToGLMDisplayParams( pPresentationParameters, &glmParams ); + + // steal back previously sent focus window... + glmParams.m_focusWindow = m_ctx->m_displayParams.m_focusWindow; + Assert( glmParams.m_focusWindow != NULL ); + + // so GetClientRect can return sane answers + //uint width, height; + RenderedSize( pPresentationParameters->BackBufferWidth, pPresentationParameters->BackBufferHeight, true ); // true = set + + m_ctx->Reset(); + + m_ctx->SetDisplayParams( &glmParams ); + + return S_OK; +} + +HRESULT IDirect3DDevice9::SetViewport(CONST D3DVIEWPORT9* pViewport) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + GLMPRINTF(("-X- IDirect3DDevice9::SetViewport : minZ %f, maxZ %f",pViewport->MinZ, pViewport->MaxZ )); + + gl.m_ViewportBox.x = pViewport->X; + gl.m_ViewportBox.width = pViewport->Width; + + gl.m_ViewportBox.y = pViewport->Y; + gl.m_ViewportBox.height = pViewport->Height; + + gl.m_ViewportBox.widthheight = pViewport->Width | ( pViewport->Height << 16 ); + + m_ctx->WriteViewportBox( &gl.m_ViewportBox ); + + gl.m_ViewportDepthRange.flNear = pViewport->MinZ; + gl.m_ViewportDepthRange.flFar = pViewport->MaxZ; + m_ctx->WriteViewportDepthRange( &gl.m_ViewportDepthRange ); + + return S_OK; +} + +HRESULT IDirect3DDevice9::GetViewport( D3DVIEWPORT9* pViewport ) +{ + // 7LS - unfinished, used in scaleformuirenderimpl.cpp (only width and height required) + GL_BATCH_PERF_CALL_TIMER; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + GLMPRINTF(("-X- IDirect3DDevice9::GetViewport " )); + + pViewport->X = gl.m_ViewportBox.x; + pViewport->Width = gl.m_ViewportBox.width; + + pViewport->Y = gl.m_ViewportBox.y; + pViewport->Height = gl.m_ViewportBox.height; + + pViewport->MinZ = gl.m_ViewportDepthRange.flNear; + pViewport->MaxZ = gl.m_ViewportDepthRange.flFar; + + return S_OK; +} + +HRESULT IDirect3DDevice9::BeginScene() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + m_ctx->BeginFrame(); + + return S_OK; +} + +HRESULT IDirect3DDevice9::EndScene() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + m_ctx->EndFrame(); + return S_OK; +} + + +// stolen from glmgrbasics.cpp + +enum ECarbonModKeyIndex +{ + EcmdKeyBit = 8, /* command key down?*/ + EshiftKeyBit = 9, /* shift key down?*/ + EalphaLockBit = 10, /* alpha lock down?*/ + EoptionKeyBit = 11, /* option key down?*/ + EcontrolKeyBit = 12 /* control key down?*/ +}; + +enum ECarbonModKeyMask +{ + EcmdKey = 1 << EcmdKeyBit, + EshiftKey = 1 << EshiftKeyBit, + EalphaLock = 1 << EalphaLockBit, + EoptionKey = 1 << EoptionKeyBit, + EcontrolKey = 1 << EcontrolKeyBit +}; + +void IDirect3DDevice9::PrintObjectStats( const ObjectStats_t &stats ) +{ + ConMsg( "Total FBOs: %i\n", stats.m_nTotalFBOs ); + ConMsg( "Total vertex shaders: %i\n", stats.m_nTotalVertexShaders ); + ConMsg( "Total pixel shaders: %i\n", stats.m_nTotalPixelShaders ); + ConMsg( "Total vertex decls: %i\n", stats.m_nTotalVertexDecls ); + ConMsg( "Total index buffers: %i\n", stats.m_nTotalIndexBuffers ); + ConMsg( "Total vertex buffers: %i\n", stats.m_nTotalVertexBuffers ); + ConMsg( "Total textures: %i\n", stats.m_nTotalTextures ); + ConMsg( "Total surfaces: %i\n", stats.m_nTotalSurfaces ); + ConMsg( "Total queries: %i\n", stats.m_nTotalQueries ); + ConMsg( "Total render targets: %i\n", stats.m_nTotalRenderTargets ); +} + +void IDirect3DDevice9::DumpStatsToConsole( const CCommand *pArgs ) +{ +#if GL_BATCH_PERF_ANALYSIS + ConMsg( "Overall: Batches: %u, Prims: %u, Program Changes: %u\n", m_nOverallDraws, m_nOverallPrims, m_nOverallProgramChanges ); + ConMsg( "Overall: D3D Calls: %u D3D Time: %4.3fms, Avg D3D Time Per Call: %4.9fms\n", m_nOverallD3DCalls, m_flOverallD3DTime, m_nOverallD3DCalls ? ( m_flOverallD3DTime / m_nOverallD3DCalls ) : 0.0f ); + ConMsg( "Overall: GL Calls: %u GL Time: %4.3fms, Avg GL Time Per Call: %4.9fms\n", m_nOverallGLCalls, m_flOverallGLTime, m_nOverallGLCalls ? ( m_flOverallGLTime / m_nOverallGLCalls ) : 0.0f ); + + ConMsg( "D3DPresent: %u, Overall Time: %4.3fms, Avg: %4.6fms, Std Dev: %4.6fms\n", + m_nOverallPresents, + m_flOverallPresentTime, m_nOverallPresents ? ( m_flOverallPresentTime / m_nOverallPresents ) : 0.0f, + m_nOverallPresents ? ( sqrt( ( m_flOverallPresentTimeSquared / m_nOverallPresents ) - ( m_flOverallPresentTime / m_nOverallPresents ) * ( m_flOverallPresentTime / m_nOverallPresents ) ) ) : 0.0f ); + + ConMsg( "GL SwapWindow(): Overall Time: %4.3fms, Avg: %4.6fms, Std Dev: %4.6fms\n", + m_flOverallSwapWindowTime, m_nOverallPresents ? ( m_flOverallSwapWindowTime / m_nOverallPresents ) : 0.0f, + m_nOverallPresents ? ( sqrt( ( m_flOverallSwapWindowTimeSquared / m_nOverallPresents ) - ( m_flOverallSwapWindowTime / m_nOverallPresents ) * ( m_flOverallSwapWindowTime / m_nOverallPresents ) ) ) : 0.0f ); + + if ( ( pArgs ) && ( pArgs->ArgC() == 2 ) && (pArgs->Arg(1)[0] != '0') ) + { + m_nOverallDraws = 0; + m_nOverallPrims = 0; + m_nOverallProgramChanges = 0; + m_nOverallD3DCalls = 0; + m_flOverallD3DTime = 0; + m_nOverallGLCalls = 0; + m_flOverallGLTime = 0; + m_flOverallPresentTime = 0; + m_flOverallPresentTimeSquared = 0; + m_flOverallSwapWindowTime = 0; + m_flOverallSwapWindowTimeSquared = 0; + m_nOverallPresents = 0; + } +#endif + ConMsg( "Totals:\n" ); + m_ObjectStats.m_nTotalFBOs = m_pFBOs->Count(); + PrintObjectStats( m_ObjectStats ); + ObjectStats_t delta( m_ObjectStats ); + delta -= m_PrevObjectStats; + ConMsg( "Delta:\n" ); + PrintObjectStats( delta ); + m_PrevObjectStats = m_ObjectStats; +} + +static void gl_dump_stats_func( const CCommand &args ) +{ + if ( g_pD3D_Device ) + { + g_pD3D_Device->DumpStatsToConsole( &args ); + } +} + +static ConCommand gl_dump_stats( "gl_dump_stats", gl_dump_stats_func ); +#if GLMDEBUG +void IDirect3DDevice9::DumpTextures( const CCommand *pArgs ) +{ + Assert( m_nValidMarker == D3D_DEVICE_VALID_MARKER ); + (void)pArgs; + CGLMTex *pCurTex = g_pFirstCGMLTex; + if ( pCurTex ) + { + Assert( pCurTex->m_pPrevTex == NULL ); + } + ConMsg( "--- Internal CGLMTex's:\n" ); + uint nNumFound = 0; + while ( pCurTex ) + { + nNumFound++; + ConMsg( "Tex \"%s\", Layout: \"%s\", Size: %u, RT: %u, Depth: %u, Stencil: %u, MSAA: %u\n", + pCurTex->m_debugLabel ? pCurTex->m_debugLabel : "?", + pCurTex->m_layout->m_layoutSummary, + pCurTex->m_layout->m_storageTotalSize, + ( pCurTex->m_layout->m_key.m_texFlags & kGLMTexRenderable ) ? 1 : 0, + ( pCurTex->m_layout->m_key.m_texFlags & kGLMTexIsDepth ) ? 1 : 0, + ( pCurTex->m_layout->m_key.m_texFlags & kGLMTexIsStencil ) ? 1 : 0, + ( pCurTex->m_layout->m_key.m_texFlags & kGLMTexMultisampled ) ? 1 : 0 ); + CGLMTex *pNextTex = pCurTex->m_pNextTex; + if ( pNextTex ) + { + Assert( pNextTex->m_pPrevTex == pCurTex ); + } + pCurTex = pNextTex; + } + ConMsg( "--- Found %u total CGLMTex's\n", nNumFound ); +} +static void gl_dump_textures_func( const CCommand &args ) +{ + if ( g_pD3D_Device ) + { + g_pD3D_Device->DumpTextures( &args ); + } +} +static ConCommand gl_dump_textures( "gl_dump_textures", gl_dump_textures_func ); + +#endif + +ConVar gl_blitmode( "gl_blitmode", "1" ); +ConVar dxa_nullrefresh_capslock( "dxa_nullrefresh_capslock", "0" ); + +HRESULT IDirect3DDevice9::Present(CONST RECT* pSourceRect,CONST RECT* pDestRect,VD3DHWND hDestWindowOverride,CONST RGNDATA* pDirtyRegion) +{ + GL_BATCH_PERF( g_nTotalD3DCalls++; ) + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + + TOGL_NULL_DEVICE_CHECK; + + if ( m_bFBODirty ) + { + UpdateBoundFBO(); + } + + // before attempting to present a tex, make sure it's been resolved if it was MSAA. + // if we push that responsibility down to m_ctx->Present, it could probably do it without an extra copy. + // i.e. anticipate the blit from the resolvedtex to GL_BACK, and just do that instead. + + // no explicit ResolveTex call first - that got pushed down into GLMContext::Present + +#if GL_BATCH_PERF_ANALYSIS + uint64 nStartGLCycles = gGL->m_nTotalGLCycles; + nStartGLCycles; + + CFastTimer tm; + tm.Start(); +#endif + + m_ctx->Present( m_pDefaultColorSurface->m_tex ); + +#if GL_BATCH_PERF_ANALYSIS + double flPresentTime = tm.GetDurationInProgress().GetMillisecondsF(); + double flGLSwapWindowTime = g_pLauncherMgr->GetPrevGLSwapWindowTime(); + + m_flOverallPresentTime += flPresentTime; + m_flOverallPresentTimeSquared += flPresentTime * flPresentTime; + m_flOverallSwapWindowTime += flGLSwapWindowTime; + m_flOverallSwapWindowTimeSquared += flGLSwapWindowTime * flGLSwapWindowTime; + m_nOverallPresents++; + + uint64 nEndGLCycles = gGL->m_nTotalGLCycles; + nEndGLCycles; + + m_flTotalD3DTime += flPresentTime + g_nTotalD3DCycles * s_rdtsc_to_ms; + m_nTotalD3DCalls += g_nTotalD3DCalls; + + m_flTotalGLTime += gGL->m_nTotalGLCycles * s_rdtsc_to_ms; + m_nTotalGLCalls += gGL->m_nTotalGLCalls; + + m_nOverallProgramChanges += m_nNumProgramChanges; + m_nOverallDraws += g_nTotalDrawsOrClears; + m_nOverallPrims += m_nTotalPrims; + m_nOverallD3DCalls += m_nTotalD3DCalls; + m_flOverallD3DTime += m_flTotalD3DTime; + m_nOverallGLCalls += m_nTotalGLCalls; + m_flOverallGLTime += m_flTotalGLTime; + + static int nPrevBatchVis = -1; + +#if GL_BATCH_PERF_ANALYSIS_WRITE_PNGS + if ((nPrevBatchVis == 1) && m_pBatch_vis_bitmap && m_pBatch_vis_bitmap->is_valid()) + { + double flTotalGLPresentTime = ( nEndGLCycles - nStartGLCycles ) * s_rdtsc_to_ms; + + m_pBatch_vis_bitmap->fill_box(0, m_nBatchVisY, (uint)(.5f + flPresentTime / gl_present_vis_abs_scale.GetFloat() * m_pBatch_vis_bitmap->width()), 10, 255, 16, 128); + m_pBatch_vis_bitmap->additive_fill_box(0, m_nBatchVisY, (uint)(.5f + flTotalGLPresentTime / gl_present_vis_abs_scale.GetFloat() * m_pBatch_vis_bitmap->width()), 10, 0, 255, 128); + m_nBatchVisY += 10; + + uint y = MAX(m_nBatchVisY + 20, 600), l = 0; + m_pBatch_vis_bitmap->draw_formatted_text(0, y+8*(l++), 1, 255, 255, 255, "OpenGL Frame: %u, Batches+Clears: %u, Prims: %u, Program Changes: %u", m_nOverallPresents, g_nTotalDrawsOrClears, m_nTotalPrims, m_nNumProgramChanges ); + m_pBatch_vis_bitmap->draw_formatted_text(0, y+8*(l++), 1, 255, 255, 255, "Frame: D3D Calls: %u, D3D Time: %3.3fms", m_nTotalD3DCalls, m_flTotalD3DTime); + m_pBatch_vis_bitmap->draw_formatted_text(0, y+8*(l++), 1, 255, 255, 255, "Frame: GL Calls: %u, GL Time: %3.3fms", m_nTotalGLCalls, m_flTotalGLTime); + l++; + m_pBatch_vis_bitmap->draw_formatted_text(0, y+8*(l++), 1, 255, 255, 255, "Overall: Batches: %u, Prims: %u, Program Changes: %u", m_nOverallDraws, m_nOverallPrims, m_nOverallProgramChanges ); + m_pBatch_vis_bitmap->draw_formatted_text(0, y+8*(l++), 1, 255, 255, 255, "Overall: D3D Calls: %u D3D Time: %4.3fms", m_nOverallD3DCalls, m_flOverallD3DTime ); + m_pBatch_vis_bitmap->draw_formatted_text(0, y+8*(l++), 1, 255, 255, 255, "Overall: GL Calls: %u GL Time: %4.3fms", m_nOverallGLCalls, m_flOverallGLTime ); + + size_t png_size = 0; + void *pPNG_data = tdefl_write_image_to_png_file_in_memory(m_pBatch_vis_bitmap->get_ptr(), m_pBatch_vis_bitmap->width(), m_pBatch_vis_bitmap->height(), 3, &png_size, true); + if (pPNG_data) + { + char filename[256]; + V_snprintf(filename, sizeof(filename), "left4dead2/batchvis_%u_%u.png", m_nBatchVisFileIdx, m_nBatchVisFrameIndex); + FILE* pFile = fopen(filename, "wb"); + if (pFile) + { + fwrite(pPNG_data, png_size, 1, pFile); + fclose(pFile); + } + free(pPNG_data); + } + m_nBatchVisFrameIndex++; + m_nBatchVisY = 0; + m_pBatch_vis_bitmap->cls(); + } +#endif + + if (nPrevBatchVis != (int)gl_batch_vis.GetBool()) + { + if ( !m_pBatch_vis_bitmap ) + m_pBatch_vis_bitmap = new simple_bitmap; + + nPrevBatchVis = gl_batch_vis.GetBool(); + if (!nPrevBatchVis) + { + DumpStatsToConsole( NULL ); + m_pBatch_vis_bitmap->clear(); + } + else + { + m_pBatch_vis_bitmap->init(768, 1024); + } + m_nBatchVisY = 0; + m_nBatchVisFrameIndex = 0; + m_nBatchVisFileIdx = (uint)time(NULL); //rand(); + + m_nOverallProgramChanges = 0; + m_nOverallDraws = 0; + m_nOverallD3DCalls = 0; + m_flOverallD3DTime = 0; + m_nOverallGLCalls = 0; + m_flOverallGLTime = 0; + m_flOverallPresentTime = 0; + m_flOverallPresentTimeSquared = 0; + m_flOverallSwapWindowTime = 0; + m_flOverallSwapWindowTimeSquared = 0; + m_nOverallPresents = 0; + } + + g_nTotalD3DCycles = 0; + g_nTotalD3DCalls = 0; + gGL->m_nTotalGLCycles = 0; + gGL->m_nTotalGLCalls = 0; + + m_nNumProgramChanges = 0; + m_flTotalD3DTime = 0; + m_nTotalD3DCalls = 0; + m_flTotalGLTime = 0; + m_nTotalGLCalls = 0; + m_nTotalPrims = 0; +#else + if ( gl_batch_vis.GetBool() ) + { + gl_batch_vis.SetValue( false ); + + ConMsg( "Must define GL_BATCH_PERF_ANALYSIS to use this feature" ); + } +#endif + + g_nTotalDrawsOrClears = 0; + +#if GL_TELEMETRY_GPU_ZONES + g_TelemetryGPUStats.Clear(); +#endif + + return S_OK; +} + +#ifdef OSX + +#pragma mark ----- Textures - (IDirect3DDevice9) +#pragma mark ( create functions for each texture are now adjacent to the rest of the methods for each texture class) + +#endif + +HRESULT IDirect3DDevice9::GetTexture(DWORD Stage,IDirect3DBaseTexture9** ppTexture) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + // if implemented, should it increase the ref count ?? + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + + +#ifdef OSX + +#pragma mark ----- RTs and Surfaces - (IDirect3DDevice9) + +#endif + +HRESULT IDirect3DDevice9::CreateRenderTarget(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Lockable,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle, char *pDebugLabel) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + HRESULT result = S_OK; + + m_ObjectStats.m_nTotalSurfaces++; + m_ObjectStats.m_nTotalRenderTargets++; + + IDirect3DSurface9 *surf = new IDirect3DSurface9; + surf->m_restype = D3DRTYPE_SURFACE; + + surf->m_device = this; // always set device on creations! + + GLMTexLayoutKey rtkey; + memset( &rtkey, 0, sizeof(rtkey) ); + + rtkey.m_texGLTarget = GL_TEXTURE_2D; + rtkey.m_xSize = Width; + rtkey.m_ySize = Height; + rtkey.m_zSize = 1; + + rtkey.m_texFormat = Format; + rtkey.m_texFlags = kGLMTexRenderable; + + rtkey.m_texFlags |= kGLMTexSRGB; // all render target tex are SRGB mode + if (m_ctx->Caps().m_cantAttachSRGB) + { + // this config can't support SRGB render targets. quietly turn off the sRGB bit. + rtkey.m_texFlags &= ~kGLMTexSRGB; + } + + if ( (MultiSample !=0) && (!m_ctx->Caps().m_nvG7x) ) + { + rtkey.m_texFlags |= kGLMTexMultisampled; + rtkey.m_texSamples = MultiSample; + // FIXME no support for "MS quality" yet + } + + surf->m_tex = m_ctx->NewTex( &rtkey, 1, pDebugLabel ); + surf->m_face = 0; + surf->m_mip = 0; + + //desc + surf->m_desc.Format = Format; + surf->m_desc.Type = D3DRTYPE_SURFACE; + surf->m_desc.Usage = 0; //FIXME ??????????? + surf->m_desc.Pool = D3DPOOL_DEFAULT; //FIXME ??????????? + surf->m_desc.MultiSampleType = MultiSample; + surf->m_desc.MultiSampleQuality = MultisampleQuality; + surf->m_desc.Width = Width; + surf->m_desc.Height = Height; + + *ppSurface = (result==S_OK) ? surf : NULL; + + #if IUNKNOWN_ALLOC_SPEW + char scratch[1024]; + sprintf(scratch,"RT %s", surf->m_tex->m_layout->m_layoutSummary ); + surf->SetMark( true, scratch ); + #endif + + + return result; +} + +void IDirect3DDevice9::UpdateBoundFBO() +{ + RenderTargetState_t renderTargetState; + for ( uint i = 0; i < 4; i++ ) + { + renderTargetState.m_pRenderTargets[i] = m_pRenderTargets[i] ? m_pRenderTargets[i]->m_tex : NULL; + } + renderTargetState.m_pDepthStencil = m_pDepthStencil ? m_pDepthStencil->m_tex : NULL; + CUtlMap < RenderTargetState_t, CGLMFBO * >::IndexType_t index = m_pFBOs->Find( renderTargetState ); + + if ( m_pFBOs->IsValidIndex( index ) ) + { + Assert( (*m_pFBOs)[index] ); + + m_ctx->m_drawingFBO = (*m_pFBOs)[index]; + } + else + { + CGLMFBO *newFBO = m_ctx->NewFBO(); + + m_pFBOs->Insert( renderTargetState, newFBO ); + + uint nNumBound = 0; + + for ( uint i = 0; i < 4; i++ ) + { + if ( !m_pRenderTargets[i] ) + continue; + + GLMFBOTexAttachParams rtParams; + memset( &rtParams, 0, sizeof(rtParams) ); + + rtParams.m_tex = m_pRenderTargets[i]->m_tex; + rtParams.m_face = m_pRenderTargets[i]->m_face; + rtParams.m_mip = m_pRenderTargets[i]->m_mip; + rtParams.m_zslice = 0; + + newFBO->TexAttach( &rtParams, (EGLMFBOAttachment)(kAttColor0 + i) ); + nNumBound++; + } + + if ( m_pDepthStencil ) + { + GLMFBOTexAttachParams depthParams; + memset( &depthParams, 0, sizeof(depthParams) ); + + depthParams.m_tex = m_pDepthStencil->m_tex; + + EGLMFBOAttachment destAttach = (depthParams.m_tex->m_layout->m_format->m_glDataFormat != 34041) ? kAttDepth : kAttDepthStencil; + + newFBO->TexAttach( &depthParams, destAttach ); + nNumBound++; + } + + (void)nNumBound; + + Assert( nNumBound ); + +#if GLMDEBUG + Assert( newFBO->IsReady() ); +#endif + + m_ctx->m_drawingFBO = newFBO; + } + + m_ctx->BindFBOToCtx( m_ctx->m_drawingFBO, GL_FRAMEBUFFER ); + + m_bFBODirty = false; +} + +void IDirect3DDevice9::ResetFBOMap() +{ + if ( !m_pFBOs ) + return; + + FOR_EACH_MAP_FAST( (*m_pFBOs), i ) + { + const RenderTargetState_t &rtState = m_pFBOs->Key( i ); (void)rtState; + CGLMFBO *pFBO = (*m_pFBOs)[i]; + + m_ctx->DelFBO( pFBO ); + } + + m_pFBOs->Purge(); + + m_bFBODirty = true; +} + +void IDirect3DDevice9::ScrubFBOMap( CGLMTex *pTex ) +{ + Assert( pTex ); + + if ( !m_pFBOs ) + return; + + CUtlVectorFixed< RenderTargetState_t, 128 > fbosToRemove; + + FOR_EACH_MAP_FAST( (*m_pFBOs), i ) + { + const RenderTargetState_t &rtState = m_pFBOs->Key( i ); + CGLMFBO *pFBO = (*m_pFBOs)[i]; (void)pFBO; + + if ( rtState.RefersTo( pTex ) ) + { + fbosToRemove.AddToTail( rtState ); + } + } + + for ( int i = 0; i < fbosToRemove.Count(); ++i ) + { + const RenderTargetState_t &rtState = fbosToRemove[i]; + + CUtlMap < RenderTargetState_t, CGLMFBO * >::IndexType_t index = m_pFBOs->Find( rtState ); + + if ( !m_pFBOs->IsValidIndex( index ) ) + { + Assert( 0 ); + continue; + } + + CGLMFBO *pFBO = (*m_pFBOs)[index]; + + m_ctx->DelFBO( pFBO ); + + m_pFBOs->RemoveAt( index ); + + m_bFBODirty = true; + } + + //GLMDebugPrintf( "IDirect3DDevice9::ScrubFBOMap: Removed %u entries\n", fbosToRemove.Count() ); +} +HRESULT IDirect3DDevice9::SetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9* pRenderTarget) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "%s", __FUNCTION__ ); + + Assert( RenderTargetIndex < 4 ); + + HRESULT result = S_OK; + + GLMPRINTF(("-F- SetRenderTarget index=%d, surface=%8x (tex=%8x %s)", + RenderTargetIndex, + pRenderTarget, + pRenderTarget ? pRenderTarget->m_tex : NULL, + pRenderTarget ? pRenderTarget->m_tex->m_layout->m_layoutSummary : "" + )); + + // note that it is OK to pass NULL for pRenderTarget, it implies that you would like to detach any color buffer from that target index + + // behaviors... + // if new surf is same as old surf, no change in refcount, in fact, it's early exit + IDirect3DSurface9 *oldTarget = m_pRenderTargets[RenderTargetIndex]; + + if (pRenderTarget == oldTarget) + { + GLMPRINTF(("-F- --> no change",RenderTargetIndex)); + return S_OK; + } + + + // Fix this if porting to x86_64 + if ( m_pRenderTargets[RenderTargetIndex] ) + + + { + + + + + + + + + + + + // we now know that the new surf is not the same as the old surf. + // you can't assume either one is non NULL here though. + + m_pRenderTargets[RenderTargetIndex]->Release( 1, "-A SetRenderTarget private release" ); + } + + if (pRenderTarget) + { + pRenderTarget->AddRef( 1, "+A SetRenderTarget private addref" ); // again, private refcount being raised + } + m_pRenderTargets[RenderTargetIndex] = pRenderTarget; + + m_bFBODirty = true; + +/* + if (!pRenderTarget) + { + GLMPRINTF(("-F- --> Setting NULL render target on index=%d ",RenderTargetIndex)); + } + else + { + GLMPRINTF(("-F- --> attaching index=%d on drawing FBO (%8x)",RenderTargetIndex, m_drawableFBO)); + // attach color to FBO + GLMFBOTexAttachParams rtParams; + memset( &rtParams, 0, sizeof(rtParams) ); + + rtParams.m_tex = pRenderTarget->m_tex; + rtParams.m_face = pRenderTarget->m_face; + rtParams.m_mip = pRenderTarget->m_mip; + rtParams.m_zslice = 0; // FIXME if you ever want to be able to render to slices of a 3D tex.. + + m_drawableFBO->TexAttach( &rtParams, (EGLMFBOAttachment)(kAttColor0 + RenderTargetIndex) ); + } +*/ + +#if GL_BATCH_PERF_ANALYSIS && GL_BATCH_PERF_ANALYSIS_WRITE_PNGS + if ( m_pBatch_vis_bitmap && m_pBatch_vis_bitmap->is_valid() && !RenderTargetIndex ) + { + m_pBatch_vis_bitmap->fill_box(0, m_nBatchVisY, m_pBatch_vis_bitmap->width(), 1, 30, 20, 20); + m_nBatchVisY += 1; + } +#endif + + return result; +} + + +HRESULT IDirect3DDevice9::GetRenderTarget(DWORD RenderTargetIndex,IDirect3DSurface9** ppRenderTarget) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + if ( !m_pRenderTargets[ RenderTargetIndex ] ) + return D3DERR_NOTFOUND; + + if ( ( RenderTargetIndex > 4 ) || !ppRenderTarget ) + return D3DERR_INVALIDCALL; + + // safe because of early exit on NULL above + m_pRenderTargets[ RenderTargetIndex ]->AddRef(0, "+B GetRenderTarget public addref"); // per http://msdn.microsoft.com/en-us/library/bb174404(VS.85).aspx + + *ppRenderTarget = m_pRenderTargets[ RenderTargetIndex ]; + + return S_OK; +} + +HRESULT IDirect3DDevice9::CreateOffscreenPlainSurface( UINT Width,UINT Height,D3DFORMAT Format,D3DPOOL Pool,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + // set surf->m_restype to D3DRTYPE_SURFACE... + + // this is almost identical to CreateRenderTarget.. + + HRESULT result = S_OK; + + m_ObjectStats.m_nTotalSurfaces++; + m_ObjectStats.m_nTotalRenderTargets++; + + IDirect3DSurface9 *surf = new IDirect3DSurface9; + surf->m_restype = D3DRTYPE_SURFACE; + + surf->m_device = this; // always set device on creations! + + GLMTexLayoutKey rtkey; + memset( &rtkey, 0, sizeof(rtkey) ); + + rtkey.m_texGLTarget = GL_TEXTURE_2D; + rtkey.m_xSize = Width; + rtkey.m_ySize = Height; + rtkey.m_zSize = 1; + + rtkey.m_texFormat = Format; + rtkey.m_texFlags = kGLMTexRenderable; + + surf->m_tex = m_ctx->NewTex( &rtkey, 1, "offscreen plain surface" ); + surf->m_face = 0; + surf->m_mip = 0; + + //desc + surf->m_desc.Format = Format; + surf->m_desc.Type = D3DRTYPE_SURFACE; + surf->m_desc.Usage = 0; + surf->m_desc.Pool = D3DPOOL_DEFAULT; + surf->m_desc.MultiSampleType = D3DMULTISAMPLE_NONE; + surf->m_desc.MultiSampleQuality = 0; + surf->m_desc.Width = Width; + surf->m_desc.Height = Height; + + *ppSurface = (result==S_OK) ? surf : NULL; + + return result; +} + +HRESULT IDirect3DDevice9::CreateDepthStencilSurface(UINT Width,UINT Height,D3DFORMAT Format,D3DMULTISAMPLE_TYPE MultiSample,DWORD MultisampleQuality,BOOL Discard,IDirect3DSurface9** ppSurface,VD3DHANDLE* pSharedHandle) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + Assert( ( Format == D3DFMT_D16 ) || ( Format == D3DFMT_D24X8 ) || ( Format == D3DFMT_D24S8 ) ); + HRESULT result = S_OK; + + m_ObjectStats.m_nTotalSurfaces++; + m_ObjectStats.m_nTotalRenderTargets++; + + IDirect3DSurface9 *surf = new IDirect3DSurface9; + surf->m_restype = D3DRTYPE_SURFACE; + + surf->m_device = this; // always set device on creations! + + GLMTexLayoutKey depthkey; + memset( &depthkey, 0, sizeof(depthkey) ); + + depthkey.m_texGLTarget = GL_TEXTURE_2D; + depthkey.m_xSize = Width; + depthkey.m_ySize = Height; + depthkey.m_zSize = 1; + + depthkey.m_texFormat = Format; + depthkey.m_texFlags = kGLMTexRenderable | kGLMTexIsDepth; + + if ( Format == D3DFMT_D24S8 ) + { + depthkey.m_texFlags |= kGLMTexIsStencil; + } + + if ( (MultiSample !=0) && (!m_ctx->Caps().m_nvG7x) ) + { + depthkey.m_texFlags |= kGLMTexMultisampled; + depthkey.m_texSamples = MultiSample; + // FIXME no support for "MS quality" yet + } + + surf->m_tex = m_ctx->NewTex( &depthkey, 1, "depth-stencil surface" ); + surf->m_face = 0; + surf->m_mip = 0; + + //desc + + surf->m_desc.Format = Format; + surf->m_desc.Type = D3DRTYPE_SURFACE; + surf->m_desc.Usage = 0; //FIXME ??????????? + surf->m_desc.Pool = D3DPOOL_DEFAULT; //FIXME ??????????? + surf->m_desc.MultiSampleType = MultiSample; + surf->m_desc.MultiSampleQuality = MultisampleQuality; + surf->m_desc.Width = Width; + surf->m_desc.Height = Height; + + *ppSurface = (result==S_OK) ? surf : NULL; + + return result; +} + +HRESULT IDirect3DDevice9::SetDepthStencilSurface( IDirect3DSurface9* pNewZStencil ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + HRESULT result = S_OK; + + GLMPRINTF(("-F- SetDepthStencilSurface, surface=%8x (tex=%8x %s)", + pNewZStencil, + pNewZStencil ? pNewZStencil->m_tex : NULL, + pNewZStencil ? pNewZStencil->m_tex->m_layout->m_layoutSummary : "" + )); + + if ( pNewZStencil == m_pDepthStencil ) + { + GLMPRINTF(("-F- --> no change")); + return S_OK; + } + + if ( pNewZStencil ) + { + pNewZStencil->AddRef(1, "+A SetDepthStencilSurface private addref"); + } + + if ( m_pDepthStencil ) + { + // Note this Release() could cause the surface to be deleted! + m_pDepthStencil->Release(1, "-A SetDepthStencilSurface private release"); + } + + m_pDepthStencil = pNewZStencil; + + m_bFBODirty = true; + + return result; +} + +HRESULT IDirect3DDevice9::GetDepthStencilSurface(IDirect3DSurface9** ppZStencilSurface) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + if ( !ppZStencilSurface ) + { + return D3DERR_INVALIDCALL; + } + + if ( !m_pDepthStencil ) + { + *ppZStencilSurface = NULL; + return D3DERR_NOTFOUND; + } + + m_pDepthStencil->AddRef(0, "+B GetDepthStencilSurface public addref"); // per http://msdn.microsoft.com/en-us/library/bb174384(VS.85).aspx + + *ppZStencilSurface = m_pDepthStencil; + + return S_OK; +} + +HRESULT IDirect3DDevice9::GetRenderTargetData(IDirect3DSurface9* pRenderTarget,IDirect3DSurface9* pDestSurface) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + // is it just a blit ? + + this->StretchRect( pRenderTarget, NULL, pDestSurface, NULL, D3DTEXF_NONE ); // is this good enough ??? + + return S_OK; +} + +HRESULT IDirect3DDevice9::GetFrontBufferData(UINT iSwapChain,IDirect3DSurface9* pDestSurface) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DDevice9::StretchRect(IDirect3DSurface9* pSourceSurface,CONST RECT* pSourceRect,IDirect3DSurface9* pDestSurface,CONST RECT* pDestRect,D3DTEXTUREFILTERTYPE Filter) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + // find relevant slices in GLM tex + + if ( m_bFBODirty ) + { + UpdateBoundFBO(); + } + + CGLMTex *srcTex = pSourceSurface->m_tex; + int srcSliceIndex = srcTex->CalcSliceIndex( pSourceSurface->m_face, pSourceSurface->m_mip ); + GLMTexLayoutSlice *srcSlice = &srcTex->m_layout->m_slices[ srcSliceIndex ]; + + CGLMTex *dstTex = pDestSurface->m_tex; + int dstSliceIndex = dstTex->CalcSliceIndex( pDestSurface->m_face, pDestSurface->m_mip ); + GLMTexLayoutSlice *dstSlice = &dstTex->m_layout->m_slices[ dstSliceIndex ]; + + if ( dstTex->m_rboName != 0 ) + { + Assert(!"No path yet for blitting into an MSAA tex"); + return S_OK; + } + + bool useFastBlit = (gl_blitmode.GetInt() != 0); + + if ( !useFastBlit && (srcTex->m_rboName !=0)) // old way, we do a resolve to scratch tex first (necessitating two step blit) + { + m_ctx->ResolveTex( srcTex, true ); + } + + // set up source/dest rect in GLM form + GLMRect srcRect, dstRect; + + // d3d nomenclature: + // Y=0 is the visual top and also aligned with V=0. + + srcRect.xmin = pSourceRect ? pSourceRect->left : 0; + srcRect.xmax = pSourceRect ? pSourceRect->right : srcSlice->m_xSize; + srcRect.ymin = pSourceRect ? pSourceRect->top : 0; + srcRect.ymax = pSourceRect ? pSourceRect->bottom : srcSlice->m_ySize; + + dstRect.xmin = pDestRect ? pDestRect->left : 0; + dstRect.xmax = pDestRect ? pDestRect->right : dstSlice->m_xSize; + dstRect.ymin = pDestRect ? pDestRect->top : 0; + dstRect.ymax = pDestRect ? pDestRect->bottom : dstSlice->m_ySize; + + GLenum filterGL = 0; + switch(Filter) + { + case D3DTEXF_NONE: + case D3DTEXF_POINT: + filterGL = GL_NEAREST; + break; + + case D3DTEXF_LINEAR: + filterGL = GL_LINEAR; + break; + + default: // D3DTEXF_ANISOTROPIC + Assert(!"Impl aniso stretch"); + break; + } + + if (useFastBlit) + { + m_ctx->Blit2( srcTex, &srcRect, pSourceSurface->m_face, pSourceSurface->m_mip, + dstTex, &dstRect, pDestSurface->m_face, pDestSurface->m_mip, + filterGL + ); + } + else + { + m_ctx->BlitTex( srcTex, &srcRect, pSourceSurface->m_face, pSourceSurface->m_mip, + dstTex, &dstRect, pDestSurface->m_face, pDestSurface->m_mip, + filterGL + ); + } + + return S_OK; +} + + +// This totally sucks, but this information can't be gleaned any +// other way when translating from D3D to GL at this level +// +// This returns a mask, since multiple GLSL "varyings" can be tagged with centroid +static uint32 CentroidMaskFromName( bool bPixelShader, const char *pName ) +{ + // Important note: This code has been customized for TF2 - don't blindly merge it into other branches! + if ( !pName ) + return 0; + + // Important: The centroid bitflags must match between all linked vertex/pixel shaders! + if ( bPixelShader ) + { + if ( V_stristr( pName, "lightmappedgeneric_ps" ) || V_strstr( pName, "worldtwotextureblend_ps" ) ) + { + return (0x01 << 2) | (0x01 << 3); // iterators 2 and 3 + } + else if ( V_stristr( pName, "lightmappedreflective_ps" ) ) + { + return (0x01 << 6) | (0x01 << 7); // iterators 6 and 7 + } + else if ( V_stristr( pName, "water_ps" ) ) + { + return 0xC0; + } + else if ( V_stristr( pName, "shadow_ps" ) ) + { + return 0x1F; + } + else if ( V_stristr( pName, "ShatteredGlass_ps" ) ) + { + return 0xC; + } + else if ( V_stristr( pName, "WorldVertexAlpha_ps" ) || V_stristr( pName, "WorldVertexTransition_ps" ) ) + { + // These pixel shaders want centroid but shouldn't be used + Assert(0); + return 0; + } + else if ( V_stristr( pName, "flashlight_ps" ) ) + { + return 0xC; + } + } + else // vertex shader + { + // Vertex shaders also + if ( V_stristr( pName, "lightmappedgeneric_vs" ) ) + { + return (0x01 << 2) | (0x01 << 3); // iterators 2 and 3 + } + else if ( V_stristr( pName, "lightmappedreflective_vs" ) ) + { + return (0x01 << 6) | (0x01 << 7); // iterators 6 and 7 + } + else if ( V_stristr( pName, "water_vs" ) ) + { + return 0xC0; + } + else if ( V_stristr( pName, "shadow_vs" ) ) + { + return 0x1F; + } + else if ( V_stristr( pName, "ShatteredGlass_vs" ) ) + { + return 0xC; + } + else if ( V_stristr( pName, "flashlight_vs" ) ) + { + return 0xC; + } + } + + // This shader doesn't have any centroid iterators + return 0; +} + + +// This totally sucks, but this information can't be gleaned any +// other way when translating from D3D to GL at this level +static int ShadowDepthSamplerMaskFromName( const char *pName ) +{ + if ( !pName ) + return 0; + + if ( V_stristr( pName, "water_ps" ) ) + { + return (1<<7); + } + else if ( V_stristr( pName, "infected_ps" ) ) + { + return (1<<1); + } + else if ( V_stristr( pName, "phong_ps" ) ) + { + return (1<<4) | (1<<15); + } + else if ( V_stristr( pName, "vertexlit_and_unlit_generic_bump_ps" ) ) + { + return (1<<8) | (1<<15); + } + else if ( V_stristr( pName, "vertexlit_and_unlit_generic_ps" ) ) + { + return (1<<8) | (1<<15); + } + else if ( V_stristr( pName, "eye_refract_ps" ) ) + { + return (1<<6); + } + else if ( V_stristr( pName, "eyes_flashlight_ps" ) ) + { + return (1<<4); + } + else if ( V_stristr( pName, "worldtwotextureblend_ps" ) ) + { + return (1<<7); + } + else if ( V_stristr( pName, "teeth_flashlight_ps" ) ) + { + return (1<<2); + } + else if ( V_stristr( pName, "flashlight_ps" ) ) // substring of above, make sure this comes last!! + { + return (1<<7); + } + else if ( V_stristr( pName, "lightmappedgeneric_ps" ) ) + { + return (1<<15); + } + else if ( V_stristr( pName, "deferred_global_light_ps" ) ) + { + return (1<<14); + } + else if ( V_stristr( pName, "global_lit_simple_ps" ) ) + { + return (1<<14); + } + else if ( V_stristr( pName, "lightshafts_ps" ) ) + { + return (1<<1); + } + else if ( V_stristr( pName, "multiblend_combined_ps" ) ) + { + return (1<<14); + } + else if ( V_stristr( pName, "multiblend_ps" ) ) + { + return (1<<14); + } + else if ( V_stristr( pName, "customhero_ps" ) ) + { + return (1<<14); + } + + // This shader doesn't have a shadow depth map sampler + return 0; +} + +#ifdef OSX + +#pragma mark ----- Pixel Shaders - (IDirect3DDevice9) + +#endif + +HRESULT IDirect3DDevice9::CreatePixelShader(CONST DWORD* pFunction,IDirect3DPixelShader9** ppShader, const char *pShaderName, char *pDebugLabel, const uint32 *pCentroidMask ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + HRESULT result = D3DERR_INVALIDCALL; + *ppShader = NULL; + + int nShadowDepthSamplerMask = ShadowDepthSamplerMaskFromName( pShaderName ); + uint nCentroidMask = CentroidMaskFromName( true, pShaderName ); + + if ( pCentroidMask ) + { + if ( *pCentroidMask != nCentroidMask ) + { + GLMDebugPrintf( "IDirect3DDevice9::CreatePixelShader: shaderapi's centroid mask (0x%08X) differs from mask derived from shader name (0x%08X) for shader %s\n", *pCentroidMask, nCentroidMask, pDebugLabel ); + } + // It would be great if we could use these centroid masks passed in from shaderapi - but unfortunately they're only available for pixel shaders, and we also need to compute matching masks for vertex shaders! + //nCentroidMask = *pCentroidMask; + } + + { + int numTranslations = 1; + + bool bVertexShader = false; + + // we can do one or two translated forms. they go together in a single buffer with some markers to allow GLM to break it up. + // this also lets us mirror each set of translations to disk with a single file making it easier to view and edit side by side. + + int maxTranslationSize = 50000; // size of any one translation + + CUtlBuffer transbuf( 9000, numTranslations * maxTranslationSize, CUtlBuffer::TEXT_BUFFER ); + CUtlBuffer tempbuf( 9000, maxTranslationSize, CUtlBuffer::TEXT_BUFFER ); + + // note the GLSL translator wants its own buffer + tempbuf.EnsureCapacity( maxTranslationSize ); + + uint glslPixelShaderOptions = D3DToGL_OptionUseEnvParams;// | D3DToGL_OptionAllowStaticControlFlow; + + + // Fake SRGB mode - needed on R500, probably indefinitely. + // Do this stuff if caps show m_needsFakeSRGB=true and the sRGBWrite state is true + // (but not if it's engine_post which is special) + + if (!m_ctx->Caps().m_hasGammaWrites) + { + if ( pShaderName ) + { + if ( !V_stristr( pShaderName, "engine_post" ) ) + { + glslPixelShaderOptions |= D3DToGL_OptionSRGBWriteSuffix; + } + } + } + + g_D3DToOpenGLTranslatorGLSL.TranslateShader( (uint32 *) pFunction, &tempbuf, &bVertexShader, glslPixelShaderOptions, nShadowDepthSamplerMask, nCentroidMask, pDebugLabel ); + + transbuf.PutString( (char*)tempbuf.Base() ); + transbuf.PutString( "\n\n" ); // whitespace + + if ( bVertexShader ) + { + // don't cross the streams + Assert(!"Can't accept vertex shader in CreatePixelShader"); + result = D3DERR_INVALIDCALL; + } + else + { + m_ObjectStats.m_nTotalPixelShaders++; + + IDirect3DPixelShader9 *newprog = new IDirect3DPixelShader9; + + newprog->m_pixHighWater = 0; + newprog->m_pixSamplerMask = 0; + newprog->m_pixSamplerTypes = 0; + + newprog->m_pixProgram = m_ctx->NewProgram( kGLMFragmentProgram, (char *)transbuf.Base(), pShaderName ? pShaderName : "?" ) ; + newprog->m_pixProgram->m_nCentroidMask = nCentroidMask; + newprog->m_pixProgram->m_nShadowDepthSamplerMask = nShadowDepthSamplerMask; + + newprog->m_pixProgram->m_bTranslatedProgram = true; + newprog->m_pixProgram->m_maxVertexAttrs = 0; + + newprog->m_device = this; + + //------ find the frag program metadata and extract it.. + + + { + // find the highwater mark + char *highWaterPrefix = "//HIGHWATER-"; // try to arrange this so it can work with pure GLSL if needed + char *highWaterStr = strstr( (char *)transbuf.Base(), highWaterPrefix ); + if (highWaterStr) + { + char *highWaterActualData = highWaterStr + strlen( highWaterPrefix ); + + int value = -1; + sscanf( highWaterActualData, "%d", &value ); + + newprog->m_pixHighWater = value; + newprog->m_pixProgram->m_descs[kGLMGLSL].m_highWater = value; + } + else + { + Assert(!"couldn't find sampler map in pixel shader"); + } + } + + { + // find the sampler map + char *samplerMaskPrefix = "//SAMPLERMASK-"; // try to arrange this so it can work with pure GLSL if needed + + char *samplerMaskStr = strstr( (char *)transbuf.Base(), samplerMaskPrefix ); + if (samplerMaskStr) + { + char *samplerMaskActualData = samplerMaskStr + strlen( samplerMaskPrefix ); + + int value = -1; + sscanf( samplerMaskActualData, "%04x", &value ); + + newprog->m_pixSamplerMask = value; + newprog->m_pixProgram->m_samplerMask = value; // helps GLM maintain a better linked pair cache even when SRGB sampler state changes + + int nMaxReg; + for ( nMaxReg = 31; nMaxReg >= 0; --nMaxReg ) + if ( value & ( 1 << nMaxReg ) ) + break; + + newprog->m_pixProgram->m_maxSamplers = nMaxReg + 1; + + int nNumUsedSamplers = 0; + for ( int i = 31; i >= 0; --i) + if ( value & ( 1 << i ) ) + nNumUsedSamplers++; + newprog->m_pixProgram->m_nNumUsedSamplers = nNumUsedSamplers; + } + else + { + Assert(!"couldn't find sampler map in pixel shader"); + } + } + + { + // find the sampler map + char *samplerTypesPrefix = "//SAMPLERTYPES-"; // try to arrange this so it can work with pure GLSL if needed + + char *samplerTypesStr = strstr( (char *)transbuf.Base(), samplerTypesPrefix ); + if (samplerTypesStr) + { + char *samplerTypesActualData = samplerTypesStr + strlen( samplerTypesPrefix ); + + int value = -1; + sscanf( samplerTypesActualData, "%08x", &value ); + + newprog->m_pixSamplerTypes = value; + newprog->m_pixProgram->m_samplerTypes = value; // helps GLM maintain a better linked pair cache even when SRGB sampler state changes + } + else + { + Assert(!"couldn't find sampler types in pixel shader"); + } + } + + { + // find the fb outputs used by this shader/combo + const GLenum buffers[] = { GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3 }; + + char *fragDataMaskPrefix = "//FRAGDATAMASK-"; + + char *fragDataMaskStr = strstr( (char *)transbuf.Base(), fragDataMaskPrefix ); + if ( fragDataMaskStr ) + { + char *fragDataActualData = fragDataMaskStr + strlen( fragDataMaskPrefix ); + + int value = -1; + sscanf( fragDataActualData, "%04x", &value ); + + newprog->m_pixFragDataMask = value; + newprog->m_pixProgram->m_fragDataMask = value; + + newprog->m_pixProgram->m_numDrawBuffers = 0; + for( int i = 0; i < 4; i++ ) + { + if( newprog->m_pixProgram->m_fragDataMask & ( 1 << i ) ) + { + newprog->m_pixProgram->m_drawBuffers[ newprog->m_pixProgram->m_numDrawBuffers ] = buffers[ i ]; + newprog->m_pixProgram->m_numDrawBuffers++; + } + } + + if( newprog->m_pixProgram->m_numDrawBuffers == 0 ) + { + Assert(!"couldn't find fragment output in pixel shader"); + newprog->m_pixProgram->m_drawBuffers[ 0 ] = buffers[ 0 ]; + newprog->m_pixProgram->m_numDrawBuffers = 1; + } + } + else + { + newprog->m_pixFragDataMask = 0; + newprog->m_pixProgram->m_fragDataMask = 0; + } + + } + + *ppShader = newprog; + + result = S_OK; + } + } + + + return result; +} + +IDirect3DPixelShader9::~IDirect3DPixelShader9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF(( ">-A- ~IDirect3DPixelShader9" )); + + if (m_device) + { + m_device->ReleasedPixelShader( this ); + + if (m_pixProgram) + { + m_pixProgram->m_ctx->DelProgram( m_pixProgram ); + m_pixProgram = NULL; + } + m_device = NULL; + } + + GLMPRINTF(( "<-A- ~IDirect3DPixelShader9" )); +} + + +HRESULT IDirect3DDevice9::SetPixelShaderNonInline(IDirect3DPixelShader9* pShader) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + + m_ctx->SetFragmentProgram( pShader ? pShader->m_pixProgram : NULL ); + m_pixelShader = pShader; + + return S_OK; +} + +HRESULT IDirect3DDevice9::SetPixelShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + TOGL_NULL_DEVICE_CHECK; +#if 0 + const uint nRegToWatch = 3; + if ( ( ( StartRegister + Vector4fCount ) > nRegToWatch ) && ( StartRegister <= nRegToWatch ) ) + { + GLMDebugPrintf( "-- %f %f %f %f\n", pConstantData[(nRegToWatch - StartRegister)*4+0], pConstantData[(nRegToWatch - StartRegister)*4+1], pConstantData[(nRegToWatch - StartRegister)*4+2], pConstantData[(nRegToWatch - StartRegister)*4+3] ); + } +#endif + m_ctx->SetProgramParametersF( kGLMFragmentProgram, StartRegister, (float *)pConstantData, Vector4fCount ); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetPixelShaderConstantB(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + TOGL_NULL_DEVICE_CHECK; + m_ctx->SetProgramParametersB( kGLMFragmentProgram, StartRegister, (int *)pConstantData, BoolCount ); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetPixelShaderConstantI(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + TOGL_NULL_DEVICE_CHECK; + GLMPRINTF(("-X- Ignoring IDirect3DDevice9::SetPixelShaderConstantI call, count was %d", Vector4iCount )); +// m_ctx->SetProgramParametersI( kGLMFragmentProgram, StartRegister, pConstantData, Vector4iCount ); + return S_OK; +} + + +#ifdef OSX + +#pragma mark ----- Vertex Shaders - (IDirect3DDevice9) + +#endif + +HRESULT IDirect3DDevice9::CreateVertexShader(CONST DWORD* pFunction, IDirect3DVertexShader9** ppShader, const char *pShaderName, char *pDebugLabel) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + HRESULT result = D3DERR_INVALIDCALL; + *ppShader = NULL; + + uint32 nCentroidMask = CentroidMaskFromName( false, pShaderName ); + + { + int numTranslations = 1; + + bool bVertexShader = false; + + // we can do one or two translated forms. they go together in a single buffer with some markers to allow GLM to break it up. + // this also lets us mirror each set of translations to disk with a single file making it easier to view and edit side by side. + + int maxTranslationSize = 500000; // size of any one translation + + CUtlBuffer transbuf( 5000, numTranslations * maxTranslationSize, CUtlBuffer::TEXT_BUFFER ); + CUtlBuffer tempbuf( 5000, maxTranslationSize, CUtlBuffer::TEXT_BUFFER ); + + // note the GLSL translator wants its own buffer + tempbuf.EnsureCapacity( maxTranslationSize ); + + uint glslVertexShaderOptions = D3DToGL_OptionUseEnvParams | D3DToGL_OptionDoFixupZ | D3DToGL_OptionDoFixupY; + + if ( m_ctx->Caps().m_hasNativeClipVertexMode ) + { + // note the matched trickery over in IDirect3DDevice9::FlushStates - + // if on a chipset that does no have native gl_ClipVertex support, then + // omit writes to gl_ClipVertex, and instead submit plane equations that have been altered, + // and clipping will take place in GL space using gl_Position instead of gl_ClipVertex. + + // note that this is very much a hack to mate up with ATI R5xx hardware constraints, and with older + // drivers even for later ATI parts like r6xx/r7xx. And it doesn't work on NV parts, so you really + // do have to choose the right way to go. + + glslVertexShaderOptions |= D3DToGL_OptionDoUserClipPlanes; + } + + if ( !CommandLine()->CheckParm("-disableboneuniformbuffers") ) + { + // If using GLSL, enabling a uniform buffer specifically for bone registers. (Not currently supported with ARB shaders, which are not optimized at all anyway.) + glslVertexShaderOptions |= D3DToGL_OptionGenerateBoneUniformBuffer; + } + + g_D3DToOpenGLTranslatorGLSL.TranslateShader( (uint32 *) pFunction, &tempbuf, &bVertexShader, glslVertexShaderOptions, -1, nCentroidMask, pDebugLabel ); + + transbuf.PutString( (char*)tempbuf.Base() ); + transbuf.PutString( "\n\n" ); // whitespace + + if ( !bVertexShader ) + { + // don't cross the streams + Assert(!"Can't accept pixel shader in CreateVertexShader"); + result = D3DERR_INVALIDCALL; + } + else + { + m_ObjectStats.m_nTotalVertexShaders++; + + IDirect3DVertexShader9 *newprog = new IDirect3DVertexShader9; + + newprog->m_device = this; + + newprog->m_vtxProgram = m_ctx->NewProgram( kGLMVertexProgram, (char *)transbuf.Base(), pShaderName ? pShaderName : "?" ) ; + newprog->m_vtxProgram->m_nCentroidMask = nCentroidMask; + + newprog->m_vtxProgram->m_bTranslatedProgram = true; + newprog->m_vtxProgram->m_maxVertexAttrs = 0; + newprog->m_maxVertexAttrs = 0; + + // find the highwater mark.. + + char *highWaterPrefix = "//HIGHWATER-"; // try to arrange this so it can work with pure GLSL if needed + char *highWaterStr = strstr( (char *)transbuf.Base(), highWaterPrefix ); + if (highWaterStr) + { + char *highWaterActualData = highWaterStr + strlen( highWaterPrefix ); + + int value = -1; + sscanf( highWaterActualData, "%d", &value ); + + newprog->m_vtxHighWater = value; + newprog->m_vtxProgram->m_descs[kGLMGLSL].m_highWater = value; + } + else + { + Assert(!"couldn't find highwater mark in vertex shader"); + } + + char *highWaterBonePrefix = "//HIGHWATERBONE-"; // try to arrange this so it can work with pure GLSL if needed + char *highWaterBoneStr = strstr( (char *)transbuf.Base(), highWaterBonePrefix ); + if (highWaterBoneStr) + { + char *highWaterActualData = highWaterBoneStr + strlen( highWaterBonePrefix ); + + int value = -1; + sscanf( highWaterActualData, "%d", &value ); + + newprog->m_vtxHighWaterBone = value; + newprog->m_vtxProgram->m_descs[kGLMGLSL].m_VSHighWaterBone = value; + } + else + { + newprog->m_vtxHighWaterBone = 0; + newprog->m_vtxProgram->m_descs[kGLMGLSL].m_VSHighWaterBone = 0; + } + + // find the attrib map.. + char *attribMapPrefix = "//ATTRIBMAP-"; // try to arrange this so it can work with pure GLSL if needed + char *attribMapStr = strstr( (char *)transbuf.Base(), attribMapPrefix ); + + if (attribMapStr) + { + char *attribMapActualData = attribMapStr + strlen( attribMapPrefix ); + uint nMaxVertexAttribs = 0; + for( int i=0; i<16; i++) + { + int value = -1; + char *dataItem = attribMapActualData + (i*3); + sscanf( dataItem, "%02x", &value ); + if (value >=0) + { + // make sure it's not a terminator + if (value == 0xBB) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + } + else + { + // probably an 'xx'... check + if ( (dataItem[0] != 'x') || (dataItem[1] != 'x') ) + { + DXABSTRACT_BREAK_ON_ERROR(); // bad news + } + else + { + value = 0xBB; // not likely to see one of these... "fog with usage index 11" + } + } + + if ( value != 0xBB ) + nMaxVertexAttribs = i; + + newprog->m_vtxAttribMap[i] = value; + } + + newprog->m_vtxProgram->m_maxVertexAttrs = nMaxVertexAttribs + 1; + newprog->m_maxVertexAttrs = nMaxVertexAttribs + 1; + } + else + { + DXABSTRACT_BREAK_ON_ERROR(); // that's bad... + } + + *ppShader = newprog; + + result = S_OK; + } + } + + return result; +} + +IDirect3DVertexShader9::~IDirect3DVertexShader9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF(( ">-A- ~IDirect3DVertexShader9" )); + + if (m_device) + { + m_device->ReleasedVertexShader( this ); + + if (m_vtxProgram) + { + m_vtxProgram->m_ctx->DelProgram( m_vtxProgram ); + m_vtxProgram = NULL; + } + m_device = NULL; + } + else + { + } + + + GLMPRINTF(( "<-A- ~IDirect3DVertexShader9" )); +} + +HRESULT IDirect3DDevice9::SetVertexShaderNonInline(IDirect3DVertexShader9* pShader) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + m_ctx->SetVertexProgram( pShader ? pShader->m_vtxProgram : NULL ); + m_vertexShader = pShader; + return S_OK; +} + +HRESULT IDirect3DDevice9::SetVertexShaderConstantFNonInline(UINT StartRegister,CONST float* pConstantData,UINT Vector4fCount) // groups of 4 floats! +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + TOGL_NULL_DEVICE_CHECK; + m_ctx->SetProgramParametersF( kGLMVertexProgram, StartRegister, (float *)pConstantData, Vector4fCount ); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetVertexShaderConstantBNonInline(UINT StartRegister,CONST BOOL* pConstantData,UINT BoolCount) // individual bool count! +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + TOGL_NULL_DEVICE_CHECK; + m_ctx->SetProgramParametersB( kGLMVertexProgram, StartRegister, (int *)pConstantData, BoolCount ); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetVertexShaderConstantINonInline(UINT StartRegister,CONST int* pConstantData,UINT Vector4iCount) // groups of 4 ints! +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + TOGL_NULL_DEVICE_CHECK; + m_ctx->SetProgramParametersI( kGLMVertexProgram, StartRegister, (int *)pConstantData, Vector4iCount ); + return S_OK; +} + +#ifdef OSX + +#pragma mark ----- Shader Pairs - (IDirect3DDevice9) + +#endif + +// callers need to ifdef POSIX this, because this method does not exist on real DX9 +HRESULT IDirect3DDevice9::LinkShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps ) +{ + GL_BATCH_PERF_CALL_TIMER; + // these are really GLSL "shaders" not "programs" but the old reference to "program" persists due to the assembler heritage + if (vs->m_vtxProgram && ps->m_pixProgram) + { + m_ctx->LinkShaderPair( vs->m_vtxProgram, ps->m_pixProgram ); + } + return S_OK; +} + +HRESULT IDirect3DDevice9::ValidateShaderPair( IDirect3DVertexShader9* vs, IDirect3DPixelShader9* ps ) +{ + GL_BATCH_PERF_CALL_TIMER; + // these are really GLSL "shaders" not "programs" but the old reference to "program" persists due to the assembler heritage + if (vs->m_vtxProgram && ps->m_pixProgram) + { + m_ctx->ValidateShaderPair( vs->m_vtxProgram, ps->m_pixProgram ); + } + return S_OK; +} + +// callers need to ifdef POSIX this, because this method does not exist on real DX9 +// +HRESULT IDirect3DDevice9::QueryShaderPair( int index, GLMShaderPairInfo *infoOut ) +{ + GL_BATCH_PERF_CALL_TIMER; + // these are really GLSL "shaders" not "programs" ... + + m_ctx->QueryShaderPair( index, infoOut ); + + return S_OK; +} + + +#ifdef OSX + +#pragma mark ----- Vertex Buffers and Vertex Declarations - (IDirect3DDevice9) + +#endif + +HRESULT IDirect3DDevice9::CreateVertexDeclaration(CONST D3DVERTEXELEMENT9* pVertexElements,IDirect3DVertexDeclaration9** ppDecl) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + *ppDecl = NULL; + + // the goal here is to arrive at something which lets us quickly generate GLMVertexSetups. + + // the information we don't have, that must be inferred from the decls, is: + // -> how many unique streams (buffers) are used - pure curiosity + // -> what the stride and offset is for each decl. Size you can figure out on the spot, stride requires surveying all the components in each stream first. + // so init an array of per-stream offsets to 0. + // each one is a cursor that gets bumped by decls. + uint streamOffsets[ D3D_MAX_STREAMS ]; + uint streamCount = 0; + + uint attribMap[16]; + uint attribMapIndex = 0; + memset( attribMap, 0xFF, sizeof( attribMap ) ); + + memset( streamOffsets, 0, sizeof( streamOffsets ) ); + + m_ObjectStats.m_nTotalVertexDecls++; + + IDirect3DVertexDeclaration9 *decl9 = new IDirect3DVertexDeclaration9; + decl9->m_device = this; + + decl9->m_elemCount = 0; + + for (const D3DVERTEXELEMENT9 *src = pVertexElements; (src->Stream != 0xFF); src++) + { + // element + D3DVERTEXELEMENT9_GL *elem = &decl9->m_elements[ decl9->m_elemCount++ ]; + + // copy the D3D decl wholesale. + elem->m_dxdecl = *src; + + // latch current offset in this stream. + elem->m_gldecl.m_offset = streamOffsets[ elem->m_dxdecl.Stream ]; + + // figure out size of this attr and move the cursor + // if cursor was on zero, bump the active stream count + + if (!streamOffsets[ elem->m_dxdecl.Stream ]) + streamCount++; + + int bytes = 0; + switch( elem->m_dxdecl.Type ) + { + case D3DDECLTYPE_FLOAT1: elem->m_gldecl.m_nCompCount = 1; elem->m_gldecl.m_datatype = GL_FLOAT; elem->m_gldecl.m_normalized=0; bytes = 4; break; + case D3DDECLTYPE_FLOAT2: elem->m_gldecl.m_nCompCount = 2; elem->m_gldecl.m_datatype = GL_FLOAT; elem->m_gldecl.m_normalized=0; bytes = 8; break; + + //case D3DVSDT_FLOAT3: + case D3DDECLTYPE_FLOAT3: elem->m_gldecl.m_nCompCount = 3; elem->m_gldecl.m_datatype = GL_FLOAT; elem->m_gldecl.m_normalized=0; bytes = 12; break; + + //case D3DVSDT_FLOAT4: + case D3DDECLTYPE_FLOAT4: elem->m_gldecl.m_nCompCount = 4; elem->m_gldecl.m_datatype = GL_FLOAT; elem->m_gldecl.m_normalized=0; bytes = 16; break; + + // case D3DVSDT_UBYTE4: + case D3DDECLTYPE_D3DCOLOR: + case D3DDECLTYPE_UBYTE4: + case D3DDECLTYPE_UBYTE4N: + + // Force this path since we're on 10.6.2 and can't rely on EXT_vertex_array_bgra + if ( 1 ) + { + // pass 4 UB's but we know this is out of order compared to D3DCOLOR data + elem->m_gldecl.m_nCompCount = 4; elem->m_gldecl.m_datatype = GL_UNSIGNED_BYTE; + } + else + { + // pass a GL BGRA color courtesy of http://www.opengl.org/registry/specs/ARB/vertex_array_bgra.txt + elem->m_gldecl.m_nCompCount = GL_BGRA; elem->m_gldecl.m_datatype = GL_UNSIGNED_BYTE; + } + + elem->m_gldecl.m_normalized = ( (elem->m_dxdecl.Type == D3DDECLTYPE_D3DCOLOR) || + (elem->m_dxdecl.Type == D3DDECLTYPE_UBYTE4N) ); + + bytes = 4; + break; + + case D3DDECLTYPE_SHORT2: + // pass 2 US's but we know this is out of order compared to D3DCOLOR data + elem->m_gldecl.m_nCompCount = 2; elem->m_gldecl.m_datatype = GL_SHORT; + + elem->m_gldecl.m_normalized = 0; + bytes = 4; + break; + + default: DXABSTRACT_BREAK_ON_ERROR(); return D3DERR_INVALIDCALL; break; + + /* + typedef enum _D3DDECLTYPE + { + D3DDECLTYPE_FLOAT1 = 0, // 1D float expanded to (value, 0., 0., 1.) + D3DDECLTYPE_FLOAT2 = 1, // 2D float expanded to (value, value, 0., 1.) + D3DDECLTYPE_FLOAT3 = 2, // 3D float expanded to (value, value, value, 1.) + D3DDECLTYPE_FLOAT4 = 3, // 4D float + D3DDECLTYPE_D3DCOLOR = 4, // 4D packed unsigned bytes mapped to 0. to 1. range + // Input is in D3DCOLOR format (ARGB) expanded to (R, G, B, A) + D3DDECLTYPE_UBYTE4 = 5, // 4D unsigned byte + D3DDECLTYPE_SHORT2 = 6, // 2D signed short expanded to (value, value, 0., 1.) + D3DDECLTYPE_SHORT4 = 7, // 4D signed short + + // The following types are valid only with vertex shaders >= 2.0 + + + D3DDECLTYPE_UBYTE4N = 8, // Each of 4 bytes is normalized by dividing to 255.0 + D3DDECLTYPE_SHORT2N = 9, // 2D signed short normalized (v[0]/32767.0,v[1]/32767.0,0,1) + D3DDECLTYPE_SHORT4N = 10, // 4D signed short normalized (v[0]/32767.0,v[1]/32767.0,v[2]/32767.0,v[3]/32767.0) + D3DDECLTYPE_USHORT2N = 11, // 2D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,0,1) + D3DDECLTYPE_USHORT4N = 12, // 4D unsigned short normalized (v[0]/65535.0,v[1]/65535.0,v[2]/65535.0,v[3]/65535.0) + D3DDECLTYPE_UDEC3 = 13, // 3D unsigned 10 10 10 format expanded to (value, value, value, 1) + D3DDECLTYPE_DEC3N = 14, // 3D signed 10 10 10 format normalized and expanded to (v[0]/511.0, v[1]/511.0, v[2]/511.0, 1) + D3DDECLTYPE_FLOAT16_2 = 15, // Two 16-bit floating point values, expanded to (value, value, 0, 1) + D3DDECLTYPE_FLOAT16_4 = 16, // Four 16-bit floating point values + D3DDECLTYPE_UNUSED = 17, // When the type field in a decl is unused. + } D3DDECLTYPE; + */ + } + + // write the offset and move the cursor + elem->m_gldecl.m_offset = streamOffsets[elem->m_dxdecl.Stream]; + streamOffsets[ elem->m_dxdecl.Stream ] += bytes; + + // cannot write m_stride yet, so zero it + elem->m_gldecl.m_stride = 0; + + elem->m_gldecl.m_pBuffer = NULL; // must be filled in at draw time.. + + // elem count was already bumped. + + // update attrib map + attribMap[ attribMapIndex++ ] = (elem->m_dxdecl.Usage << 4) | (elem->m_dxdecl.UsageIndex); + } + // the loop is done, we now know how many active streams there are, how many atribs are active in the declaration, + // and how big each one is in terms of stride. + + // all that is left is to go back and write the strides - the stride comes from the stream offset cursors accumulated earlier. + for( uint j=0; j< decl9->m_elemCount; j++) + { + D3DVERTEXELEMENT9_GL *elem = &decl9->m_elements[ j ]; + + elem->m_gldecl.m_stride = streamOffsets[ elem->m_dxdecl.Stream ]; + } + + memset( decl9->m_VertexAttribDescToStreamIndex, 0xFF, sizeof( decl9->m_VertexAttribDescToStreamIndex ) ); + D3DVERTEXELEMENT9_GL *pDeclElem = decl9->m_elements; + for( uint j = 0; j < decl9->m_elemCount; j++, pDeclElem++) + { + uint nPackedVertexAttribDesc = ( pDeclElem->m_dxdecl.Usage << 4 ) | pDeclElem->m_dxdecl.UsageIndex; + if ( nPackedVertexAttribDesc == 0xBB ) + { + // 0xBB is a reserved packed vertex attrib value - shouldn't encounter in practice + DXABSTRACT_BREAK_ON_ERROR(); + } + decl9->m_VertexAttribDescToStreamIndex[ nPackedVertexAttribDesc ] = j; + } + + *ppDecl = decl9; + + return S_OK; +} + +IDirect3DVertexDeclaration9::~IDirect3DVertexDeclaration9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF(("-A- ~IDirect3DVertexDeclaration9 signpost")); + + m_device->ReleasedVertexDeclaration( this ); +} + +HRESULT IDirect3DDevice9::SetVertexDeclarationNonInline(IDirect3DVertexDeclaration9* pDecl) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + m_pVertDecl = pDecl; + return S_OK; +} + +HRESULT IDirect3DDevice9::SetFVF(DWORD FVF) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DDevice9::GetFVF(DWORD* pFVF) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + + +#ifdef OSX + +#pragma mark ----- Vertex Buffers and Streams - (IDirect3DDevice9) + +#pragma mark ----- Create function moved to be adjacent to other buffer methods + +#endif + +HRESULT IDirect3DDevice9::SetStreamSourceNonInline(UINT StreamNumber,IDirect3DVertexBuffer9* pStreamData,UINT OffsetInBytes,UINT Stride) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + Assert( StreamNumber < D3D_MAX_STREAMS ); + Assert( ( Stride & 3 ) == 0 ); // we support non-DWORD aligned strides, but on some drivers (like AMD's) perf goes off a cliff + + // perfectly legal to see a vertex buffer of NULL get passed in here. + // so we need an array to track these. + // OK, we are being given the stride, we don't need to calc it.. + + GLMPRINTF(("-X- IDirect3DDevice9::SetStreamSource setting stream #%d to D3D buf %p (GL name %d); offset %d, stride %d", StreamNumber, pStreamData, (pStreamData) ? pStreamData->m_vtxBuffer->m_nHandle: -1, OffsetInBytes, Stride)); + + if ( !pStreamData ) + { + OffsetInBytes = 0; + Stride = 0; + + m_vtx_buffers[ StreamNumber ] = m_pDummy_vtx_buffer; + } + else + { + // We do not support strides of 0 + Assert( Stride > 0 ); + m_vtx_buffers[ StreamNumber ] = pStreamData->m_vtxBuffer; + } + + m_streams[ StreamNumber ].m_vtxBuffer = pStreamData; + m_streams[ StreamNumber ].m_offset = OffsetInBytes; + m_streams[ StreamNumber ].m_stride = Stride; + + return S_OK; +} + +#ifdef OSX + +#pragma mark ----- Index Buffers - (IDirect3DDevice9) +#pragma mark ----- Creatue function relocated to be adjacent to the rest of the index buffer methods + +#endif + +HRESULT IDirect3DDevice9::SetIndicesNonInline(IDirect3DIndexBuffer9* pIndexData) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + // just latch it. + m_indices.m_idxBuffer = pIndexData; + + return S_OK; +} + + +#ifdef OSX + +#pragma mark ----- Release Handlers - (IDirect3DDevice9) + +#endif + +void IDirect3DDevice9::ReleasedVertexDeclaration( IDirect3DVertexDeclaration9 *pDecl ) +{ + m_ctx->ClearCurAttribs(); + + Assert( m_ObjectStats.m_nTotalVertexDecls >= 1 ); + m_ObjectStats.m_nTotalVertexDecls--; +} + +void IDirect3DDevice9::ReleasedTexture( IDirect3DBaseTexture9 *baseTex ) +{ + GL_BATCH_PERF_CALL_TIMER; + TOGL_NULL_DEVICE_CHECK_RET_VOID; + + // see if this texture is referenced in any of the texture units and scrub it if so. + for( int i=0; i< GLM_SAMPLER_COUNT; i++) + { + if (m_textures[i] == baseTex) + { + m_textures[i] = NULL; + m_ctx->SetSamplerTex( i, NULL ); // texture sets go straight through to GLM, no dirty bit + } + } +} + +void IDirect3DDevice9::ReleasedCGLMTex( CGLMTex *pTex) +{ + GL_BATCH_PERF_CALL_TIMER; + TOGL_NULL_DEVICE_CHECK_RET_VOID; + + ScrubFBOMap( pTex ); + if ( pTex->m_layout ) + { + if ( pTex->m_layout->m_key.m_texFlags & kGLMTexRenderable ) + { + Assert( m_ObjectStats.m_nTotalRenderTargets >= 1 ); + m_ObjectStats.m_nTotalRenderTargets--; + } + } +} +void IDirect3DDevice9::ReleasedSurface( IDirect3DSurface9 *pSurface ) +{ + for( int i = 0; i < 4; i++ ) + { + if ( m_pRenderTargets[i] == pSurface ) + { + // this was a surprise release... scrub it + m_pRenderTargets[i] = NULL; + m_bFBODirty = true; + GLMPRINTF(( "-A- Scrubbed pSurface %08x from m_pRenderTargets[%d]", pSurface, i )); + } + } + + if ( m_pDepthStencil == pSurface ) + { + m_pDepthStencil = NULL; + m_bFBODirty = true; + GLMPRINTF(( "-A- Scrubbed pSurface %08x from m_pDepthStencil", pSurface )); + } + + if ( m_pDefaultColorSurface == pSurface ) + { + m_pDefaultColorSurface = NULL; + GLMPRINTF(( "-A- Scrubbed pSurface %08x from m_pDefaultColorSurface", pSurface )); + } + + if ( m_pDefaultDepthStencilSurface == pSurface ) + { + m_pDefaultDepthStencilSurface = NULL; + GLMPRINTF(( "-A- Scrubbed pSurface %08x from m_pDefaultDepthStencilSurface", pSurface )); + } + + Assert( m_ObjectStats.m_nTotalSurfaces >= 1 ); + m_ObjectStats.m_nTotalSurfaces--; +} + +void IDirect3DDevice9::ReleasedPixelShader( IDirect3DPixelShader9 *pixelShader ) +{ + if ( m_pixelShader == pixelShader ) + { + m_pixelShader = NULL; + GLMPRINTF(( "-A- Scrubbed pixel shader %08x from m_pixelShader", pixelShader )); + } + m_ctx->ReleasedShader(); + + Assert( m_ObjectStats.m_nTotalPixelShaders >= 1 ); + m_ObjectStats.m_nTotalPixelShaders--; +} + +void IDirect3DDevice9::ReleasedVertexShader( IDirect3DVertexShader9 *vertexShader ) +{ + if ( m_vertexShader == vertexShader ) + { + m_vertexShader = NULL; + GLMPRINTF(( "-A- Scrubbed vertex shader %08x from m_vertexShader", vertexShader )); + } + m_ctx->ClearCurAttribs(); + m_ctx->ReleasedShader(); + + Assert( m_ObjectStats.m_nTotalVertexShaders >= 1 ); + m_ObjectStats.m_nTotalVertexShaders--; +} + +void IDirect3DDevice9::ReleasedVertexBuffer( IDirect3DVertexBuffer9 *vertexBuffer ) +{ + for (int i=0; i< D3D_MAX_STREAMS; i++) + { + if ( m_streams[i].m_vtxBuffer == vertexBuffer ) + { + m_streams[i].m_vtxBuffer = NULL; + m_vtx_buffers[i] = m_pDummy_vtx_buffer; + + GLMPRINTF(( "-A- Scrubbed vertex buffer %08x from m_streams[%d]", vertexBuffer, i )); + } + } + m_ctx->ClearCurAttribs(); + + Assert( m_ObjectStats.m_nTotalVertexBuffers >= 1 ); + m_ObjectStats.m_nTotalVertexBuffers--; +} + +void IDirect3DDevice9::ReleasedIndexBuffer( IDirect3DIndexBuffer9 *indexBuffer ) +{ + if ( m_indices.m_idxBuffer == indexBuffer ) + { + m_indices.m_idxBuffer = NULL; + GLMPRINTF(( "-A- Scrubbed index buffer %08x from m_indices", indexBuffer )); + } + + Assert( m_ObjectStats.m_nTotalIndexBuffers >= 1 ); + m_ObjectStats.m_nTotalIndexBuffers--; +} + + +void IDirect3DDevice9::ReleasedQuery( IDirect3DQuery9 *query ) +{ + Assert( m_ObjectStats.m_nTotalQueries >= 1 ); + m_ObjectStats.m_nTotalQueries--; +} + +#ifdef OSX + +#pragma mark ----- Queries - (IDirect3DDevice9) + +#endif + +// note that detection of whether queries are supported is done by trying to create one. +// so for GL, be observant here of whether we have that capability or not. +// pretty much have this everywhere but i950. + +HRESULT IDirect3DDevice9::CreateQuery(D3DQUERYTYPE Type,IDirect3DQuery9** ppQuery) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + if (m_ctx->Caps().m_hasOcclusionQuery) + { + m_ObjectStats.m_nTotalQueries++; + + IDirect3DQuery9 *newquery = new IDirect3DQuery9; + + newquery->m_device = this; + + newquery->m_type = Type; + newquery->m_ctx = m_ctx; + newquery->m_nIssueStartThreadID = 0; + newquery->m_nIssueEndThreadID = 0; + newquery->m_nIssueStartDrawCallIndex = 0; + newquery->m_nIssueEndDrawCallIndex = 0; + + GLMQueryParams params; + memset( ¶ms, 0, sizeof(params) ); + + //bool known = false; + switch(newquery->m_type) + { + case D3DQUERYTYPE_OCCLUSION: /* D3DISSUE_BEGIN, D3DISSUE_END */ + // create an occlusion query + params.m_type = EOcclusion; + break; + + case D3DQUERYTYPE_EVENT: /* D3DISSUE_END */ + params.m_type = EFence; + break; + + case D3DQUERYTYPE_RESOURCEMANAGER: /* D3DISSUE_END */ + case D3DQUERYTYPE_TIMESTAMP: /* D3DISSUE_END */ + case D3DQUERYTYPE_TIMESTAMPFREQ: /* D3DISSUE_END */ + case D3DQUERYTYPE_INTERFACETIMINGS: /* D3DISSUE_BEGIN, D3DISSUE_END */ + case D3DQUERYTYPE_PIXELTIMINGS: /* D3DISSUE_BEGIN, D3DISSUE_END */ + case D3DQUERYTYPE_CACHEUTILIZATION: /* D3DISSUE_BEGIN, D3DISSUE_END */ + Assert( !"Un-implemented query type" ); + break; + + default: + Assert( !"Unknown query type" ); + break; + } + newquery->m_query = m_ctx->NewQuery( ¶ms ); + + *ppQuery = newquery; + return S_OK; + } + else + { + *ppQuery = NULL; + return -1; // failed + } + +} + +IDirect3DQuery9::~IDirect3DQuery9() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( m_device ); + GLMPRINTF((">-A- ~IDirect3DQuery9")); + + if (m_device) + { + m_device->ReleasedQuery( this ); + + if (m_query) + { + GLMPRINTF((">-A- ~IDirect3DQuery9 freeing m_query")); + + m_query->m_ctx->DelQuery( m_query ); + m_query = NULL; + + GLMPRINTF(("<-A- ~IDirect3DQuery9 freeing m_query done")); + } + m_device = NULL; + } + + GLMPRINTF(("<-A- ~IDirect3DQuery9")); +} + +#ifdef OSX + +#pragma mark ----- Render States - (IDirect3DDevice9) + +#endif + +#define D3DRS_VALUE_LIMIT 210 + +struct D3D_RSINFO +{ + int m_class; + D3DRENDERSTATETYPE m_state; + DWORD m_defval; + // m_class runs 0-3. + // 3 = must implement - fully general - "obey" + // 2 = implement setup to the default value (it has a GL effect but does not change later) "obey once" + // 1 = "fake implement" setup to the default value no GL effect, debug break if anything but default value comes through - "ignore" + // 0 = game never ever sets this one, break if someone even tries. "complain" +}; + +D3D_RSINFO g_D3DRS_INFO_unpacked[ D3DRS_VALUE_LIMIT+1 ]; + +#ifdef D3D_RSI + #error macro collision... rename this +#else + #define D3D_RSI(nclass,nstate,ndefval) { nclass, nstate, ndefval } +#endif + +// FP conversions to hex courtesy of http://babbage.cs.qc.cuny.edu/IEEE-754/Decimal.html +#define CONST_DZERO 0x00000000 +#define CONST_DONE 0x3F800000 +#define CONST_D64 0x42800000 +#define DONT_KNOW_YET 0x31415926 + + +// see http://www.toymaker.info/Games/html/render_states.html + +D3D_RSINFO g_D3DRS_INFO_packed[] = +{ + // these do not have to be in any particular order. they get unpacked into the empty array above for direct indexing. + + D3D_RSI( 3, D3DRS_ZENABLE, DONT_KNOW_YET ), // enable Z test (or W buffering) + D3D_RSI( 3, D3DRS_ZWRITEENABLE, DONT_KNOW_YET ), // enable Z write + D3D_RSI( 3, D3DRS_ZFUNC, DONT_KNOW_YET ), // select Z func + + D3D_RSI( 3, D3DRS_COLORWRITEENABLE, TRUE ), // see transitiontable.cpp "APPLY_RENDER_STATE_FUNC( D3DRS_COLORWRITEENABLE, ColorWriteEnable )" + + D3D_RSI( 3, D3DRS_CULLMODE, D3DCULL_CCW ), // backface cull control + + D3D_RSI( 3, D3DRS_ALPHABLENDENABLE, DONT_KNOW_YET ), // ->CTransitionTable::ApplySeparateAlphaBlend and ApplyAlphaBlend + D3D_RSI( 3, D3DRS_BLENDOP, D3DBLENDOP_ADD ), + D3D_RSI( 3, D3DRS_SRCBLEND, DONT_KNOW_YET ), + D3D_RSI( 3, D3DRS_DESTBLEND, DONT_KNOW_YET ), + + D3D_RSI( 1, D3DRS_SEPARATEALPHABLENDENABLE, FALSE ), // hit in CTransitionTable::ApplySeparateAlphaBlend + D3D_RSI( 1, D3DRS_SRCBLENDALPHA, D3DBLEND_ONE ), // going to demote these to class 1 until I figure out if they are implementable + D3D_RSI( 1, D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO ), + D3D_RSI( 1, D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD ), + + // what is the deal with alpha test... looks like it is inited to off. + D3D_RSI( 3, D3DRS_ALPHATESTENABLE, 0 ), + D3D_RSI( 3, D3DRS_ALPHAREF, 0 ), + D3D_RSI( 3, D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL ), + + D3D_RSI( 3, D3DRS_STENCILENABLE, FALSE ), + D3D_RSI( 3, D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP ), + D3D_RSI( 3, D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP ), + D3D_RSI( 3, D3DRS_STENCILPASS, D3DSTENCILOP_KEEP ), + D3D_RSI( 3, D3DRS_STENCILFUNC, D3DCMP_ALWAYS ), + D3D_RSI( 3, D3DRS_STENCILREF, 0 ), + D3D_RSI( 3, D3DRS_STENCILMASK, 0xFFFFFFFF ), + D3D_RSI( 3, D3DRS_STENCILWRITEMASK, 0xFFFFFFFF ), + + D3D_RSI( 3, D3DRS_TWOSIDEDSTENCILMODE, FALSE ), + D3D_RSI( 3, D3DRS_CCW_STENCILFAIL, D3DSTENCILOP_KEEP ), + D3D_RSI( 3, D3DRS_CCW_STENCILZFAIL, D3DSTENCILOP_KEEP ), + D3D_RSI( 3, D3DRS_CCW_STENCILPASS, D3DSTENCILOP_KEEP ), + D3D_RSI( 3, D3DRS_CCW_STENCILFUNC, D3DCMP_ALWAYS ), + + D3D_RSI( 3, D3DRS_FOGENABLE, FALSE ), // see CShaderAPIDx8::FogMode and friends - be ready to do the ARB fog linear option madness + D3D_RSI( 3, D3DRS_FOGCOLOR, 0 ), + D3D_RSI( 3, D3DRS_FOGTABLEMODE, D3DFOG_NONE ), + D3D_RSI( 3, D3DRS_FOGSTART, CONST_DZERO ), + D3D_RSI( 3, D3DRS_FOGEND, CONST_DONE ), + D3D_RSI( 3, D3DRS_FOGDENSITY, CONST_DZERO ), + D3D_RSI( 3, D3DRS_RANGEFOGENABLE, FALSE ), + D3D_RSI( 3, D3DRS_FOGVERTEXMODE, D3DFOG_NONE ), // watch out for CShaderAPIDx8::CommitPerPassFogMode.... + + D3D_RSI( 3, D3DRS_MULTISAMPLEANTIALIAS, TRUE ), + D3D_RSI( 3, D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF ), + + D3D_RSI( 3, D3DRS_SCISSORTESTENABLE, FALSE ), // heed IDirect3DDevice9::SetScissorRect + + D3D_RSI( 3, D3DRS_DEPTHBIAS, CONST_DZERO ), + D3D_RSI( 3, D3DRS_SLOPESCALEDEPTHBIAS, CONST_DZERO ), + + D3D_RSI( 3, D3DRS_COLORWRITEENABLE1, 0x0000000f ), + D3D_RSI( 3, D3DRS_COLORWRITEENABLE2, 0x0000000f ), + D3D_RSI( 3, D3DRS_COLORWRITEENABLE3, 0x0000000f ), + + D3D_RSI( 3, D3DRS_SRGBWRITEENABLE, 0 ), // heeded but ignored.. + + D3D_RSI( 2, D3DRS_CLIPPING, TRUE ), // um, yeah, clipping is enabled (?) + D3D_RSI( 3, D3DRS_CLIPPLANEENABLE, 0 ), // mask 1<m_class >= 0; packed++ ) + { + if ( (packed->m_state <0) || (packed->m_state >= D3DRS_VALUE_LIMIT) ) + { + // bad + DXABSTRACT_BREAK_ON_ERROR(); + } + else + { + // dispatch it to the unpacked array + g_D3DRS_INFO_unpacked[ packed->m_state ] = *packed; + } + } +} + +// convenience functions + +#ifdef OSX + +#pragma mark ----- Sampler States - (IDirect3DDevice9) + +#endif + +void IDirect3DDevice9::FlushClipPlaneEquation() +{ + for( int x=0; xCaps().m_hasNativeClipVertexMode ) + { + // hacked coeffs = { src->x, -src->y, 0.5f * src->z, src->w + (0.5f * src->z) }; + // Antonio's trick - so we can use gl_Position as the clippee, not gl_ClipVertex. + + GLClipPlaneEquation_t *equ = &gl.m_ClipPlaneEquation[x]; + + ///////////////// temp1 + temp1.x = equ->x; + temp1.y = equ->y * -1.0; + temp1.z = equ->z * 0.5; + temp1.w = equ->w + (equ->z * 0.5); + + + //////////////// temp2 + VMatrix mat1( 1, 0, 0, 0, + 0, -1, 0, 0, + 0, 0, 2, -1, + 0, 0, 0, 1 + ); + //mat1 = mat1.Transpose(); + + VMatrix mat2; + bool success = mat1.InverseGeneral( mat2 ); + + if (success) + { + VMatrix mat3; + mat3 = mat2.Transpose(); + + VPlane origPlane( Vector( equ->x, equ->y, equ->z ), equ->w ); + VPlane newPlane; + + newPlane = mat3 * origPlane /* * mat3 */; + + VPlane finalPlane = newPlane; + + temp2.x = newPlane.m_Normal.x; + temp2.y = newPlane.m_Normal.y; + temp2.z = newPlane.m_Normal.z; + temp2.w = newPlane.m_Dist; + } + else + { + temp2.x = 0; + temp2.y = 0; + temp2.z = 0; + temp2.w = 0; + } + } + else + { + temp1 = temp2 = gl.m_ClipPlaneEquation[x]; + } + + if (1) //GLMKnob("caps-key",NULL)==0.0) + { + m_ctx->WriteClipPlaneEquation( &temp1, x ); // no caps lock = Antonio or classic + + /* + if (x<1) + { + GLMPRINTF(( " plane %d √vers1[ %5.2f %5.2f %5.2f %5.2f ] vers2[ %5.2f %5.2f %5.2f %5.2f ]", + x, + temp1.x,temp1.y,temp1.z,temp1.w, + temp2.x,temp2.y,temp2.z,temp2.w + )); + } + */ + } + else + { + m_ctx->WriteClipPlaneEquation( &temp2, x ); // caps = our way or classic + + /* + if (x<1) + { + GLMPRINTF(( " plane %d vers1[ %5.2f %5.2f %5.2f %5.2f ] √vers2[ %5.2f %5.2f %5.2f %5.2f ]", + x, + temp1.x,temp1.y,temp1.z,temp1.w, + temp2.x,temp2.y,temp2.z,temp2.w + )); + } + */ + } + } +} + +void IDirect3DDevice9::InitStates() +{ + m_ctx->m_AlphaTestEnable.Read( &gl.m_AlphaTestEnable, 0 ); + m_ctx->m_AlphaTestFunc.Read( &gl.m_AlphaTestFunc, 0 ); + m_ctx->m_CullFaceEnable.Read( &gl.m_CullFaceEnable, 0 ); + m_ctx->m_DepthBias.Read( &gl.m_DepthBias, 0 ); + m_ctx->m_ScissorEnable.Read( &gl.m_ScissorEnable, 0 ); + m_ctx->m_ScissorBox.Read( &gl.m_ScissorBox, 0 ); + m_ctx->m_ViewportBox.Read( &gl.m_ViewportBox, 0 ); + m_ctx->m_ViewportDepthRange.Read( &gl.m_ViewportDepthRange, 0 ); + + for( int x=0; xm_ClipPlaneEnable.ReadIndex( &gl.m_ClipPlaneEnable[x], x, 0 ); + + m_ctx->m_PolygonMode.Read( &gl.m_PolygonMode, 0 ); + m_ctx->m_CullFrontFace.Read( &gl.m_CullFrontFace, 0 ); + m_ctx->m_AlphaToCoverageEnable.Read( &gl.m_AlphaToCoverageEnable, 0 ); + m_ctx->m_BlendEquation.Read( &gl.m_BlendEquation, 0 ); + m_ctx->m_BlendColor.Read( &gl.m_BlendColor, 0 ); + + for( int x=0; xm_ClipPlaneEquation.ReadIndex( &gl.m_ClipPlaneEquation[x], x, 0 ); + + m_ctx->m_ColorMaskSingle.Read( &gl.m_ColorMaskSingle, 0 ); + + m_ctx->m_BlendEnable.Read( &gl.m_BlendEnable, 0 ); + m_ctx->m_BlendFactor.Read( &gl.m_BlendFactor, 0 ); + m_ctx->m_BlendEnableSRGB.Read( &gl.m_BlendEnableSRGB, 0 ); + m_ctx->m_DepthTestEnable.Read( &gl.m_DepthTestEnable, 0 ); + m_ctx->m_DepthFunc.Read( &gl.m_DepthFunc, 0 ); + m_ctx->m_DepthMask.Read( &gl.m_DepthMask, 0 ); + m_ctx->m_StencilTestEnable.Read( &gl.m_StencilTestEnable, 0 ); + m_ctx->m_StencilFunc.Read( &gl.m_StencilFunc, 0 ); + + m_ctx->m_StencilOp.ReadIndex( &gl.m_StencilOp, 0, 0 ); + m_ctx->m_StencilOp.ReadIndex( &gl.m_StencilOp, 1, 0 ); + + m_ctx->m_StencilWriteMask.Read( &gl.m_StencilWriteMask, 0 ); + m_ctx->m_ClearColor.Read( &gl.m_ClearColor, 0 ); + m_ctx->m_ClearDepth.Read( &gl.m_ClearDepth, 0 ); + m_ctx->m_ClearStencil.Read( &gl.m_ClearStencil, 0 ); +} + +void IDirect3DDevice9::FullFlushStates() +{ + m_ctx->WriteAlphaTestEnable( &gl.m_AlphaTestEnable ); + m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc ); + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteDepthBias( &gl.m_DepthBias ); + m_ctx->WriteScissorEnable( &gl.m_ScissorEnable ); + m_ctx->WriteScissorBox( &gl.m_ScissorBox ); + m_ctx->WriteViewportBox( &gl.m_ViewportBox ); + m_ctx->WriteViewportDepthRange( &gl.m_ViewportDepthRange ); + + for( int x=0; xWriteClipPlaneEnable( &gl.m_ClipPlaneEnable[x], x ); + + m_ctx->WritePolygonMode( &gl.m_PolygonMode ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + m_ctx->WriteAlphaToCoverageEnable( &gl.m_AlphaToCoverageEnable ); + m_ctx->WriteBlendEquation( &gl.m_BlendEquation ); + m_ctx->WriteBlendColor( &gl.m_BlendColor ); + FlushClipPlaneEquation(); + m_ctx->WriteColorMaskSingle( &gl.m_ColorMaskSingle ); + + m_ctx->WriteBlendEnable( &gl.m_BlendEnable ); + m_ctx->WriteBlendFactor( &gl.m_BlendFactor ); + m_ctx->WriteBlendEnableSRGB( &gl.m_BlendEnableSRGB ); + m_ctx->WriteDepthTestEnable( &gl.m_DepthTestEnable ); + m_ctx->WriteDepthFunc( &gl.m_DepthFunc ); + m_ctx->WriteDepthMask( &gl.m_DepthMask ); + m_ctx->WriteStencilTestEnable( &gl.m_StencilTestEnable ); + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + + m_ctx->WriteStencilWriteMask( &gl.m_StencilWriteMask ); + m_ctx->WriteClearColor( &gl.m_ClearColor ); + m_ctx->WriteClearDepth( &gl.m_ClearDepth ); + m_ctx->WriteClearStencil( &gl.m_ClearStencil ); +} + +HRESULT IDirect3DDevice9::DrawPrimitive(D3DPRIMITIVETYPE PrimitiveType,UINT StartVertex,UINT PrimitiveCount) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +// 7LS - TODO +#ifndef DX_TO_GL_ABSTRACTION +HRESULT IDirect3DDevice9::DrawPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT PrimitiveCountx,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) +{ +// 7LS + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} +#endif + +// Type +// [in] Member of the D3DPRIMITIVETYPE enumerated type, describing the type of primitive to render. D3DPT_POINTLIST is not supported with this method. See Remarks. + +// BaseVertexIndex +// [in] Offset from the start of the vertex buffer to the first vertex. See Scenario 4. + +// MinIndex +// [in] Minimum vertex index for vertices used during this call. This is a zero based index relative to BaseVertexIndex. + +// NumVertices +// [in] Number of vertices used during this call. The first vertex is located at index: BaseVertexIndex + MinIndex. + +// StartIndex +// [in] Index of the first index to use when accessing the index buffer. + +// PrimitiveCount +// [in] Number of primitives to render. The number of vertices used is a function of the primitive count and the primitive type. The maximum number of primitives allowed is determined by checking the MaxPrimitiveCount member of the D3DCAPS9 structure. + +// BE VERY CAREFUL what you do in this function. It's extremely hot, and calling the wrong GL API's in here will crush perf. on NVidia threaded drivers. +#ifndef OSX + +HRESULT IDirect3DDevice9::DrawIndexedPrimitive( D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount ) +{ + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "%s", __FUNCTION__ ); + Assert( m_ctx->m_nCurOwnerThreadId == ThreadGetCurrentId() ); + + TOGL_NULL_DEVICE_CHECK; + if ( m_bFBODirty ) + { + UpdateBoundFBO(); + } + + g_nTotalDrawsOrClears++; + +#if GL_BATCH_PERF_ANALYSIS + m_nTotalPrims += primCount; + CFastTimer tm; + CFlushDrawStatesStats& flushStats = m_ctx->m_FlushStats; + tm.Start(); + flushStats.Clear(); +#endif + +#if GLMDEBUG + if ( gl.m_FogEnable ) + { + GLMPRINTF(("-D- IDirect3DDevice9::DrawIndexedPrimitive is seeing enabled fog...")); + } +#endif + + if ( ( !m_indices.m_idxBuffer ) || ( !m_vertexShader ) ) + goto draw_failed; + + { + GL_BATCH_PERF_CALL_TIMER; + + m_ctx->FlushDrawStates( MinVertexIndex, MinVertexIndex + NumVertices - 1, BaseVertexIndex ); + + { +#if !GL_TELEMETRY_ZONES && GL_BATCH_TELEMETRY_ZONES + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "glDrawRangeElements %u", primCount ); +#endif + Assert( ( D3DPT_LINELIST == 2 ) && ( D3DPT_TRIANGLELIST == 4 ) && ( D3DPT_TRIANGLESTRIP == 5 ) ); + + static const struct prim_t + { + GLenum m_nType; + uint m_nPrimMul; + uint m_nPrimAdd; + } s_primTypes[6] = + { + { 0, 0, 0 }, // 0 + { 0, 0, 0 }, // 1 + { GL_LINES, 2, 0 }, // 2 D3DPT_LINELIST + { 0, 0, 0 }, // 3 + { GL_TRIANGLES, 3, 0 }, // 4 D3DPT_TRIANGLELIST + { GL_TRIANGLE_STRIP, 1, 2 } // 5 D3DPT_TRIANGLESTRIP + }; + + if ( Type <= D3DPT_TRIANGLESTRIP ) + { + const prim_t& p = s_primTypes[Type]; + Assert( p.m_nType ); + Assert( NumVertices >= 1 ); + + m_ctx->DrawRangeElements( p.m_nType, (GLuint)MinVertexIndex, (GLuint)( MinVertexIndex + NumVertices - 1 ), (GLsizei)p.m_nPrimAdd + primCount * p.m_nPrimMul, (GLenum)GL_UNSIGNED_SHORT, (const GLvoid *)( startIndex * sizeof(short) ), BaseVertexIndex, m_indices.m_idxBuffer->m_idxBuffer ); + } + } + } + +#if GL_BATCH_PERF_ANALYSIS + if ( s_rdtsc_to_ms == 0.0f ) + { + TmU64 t0 = Plat_Rdtsc(); + double d0 = Plat_FloatTime(); + + ThreadSleep( 1000 ); + + TmU64 t1 = Plat_Rdtsc(); + double d1 = Plat_FloatTime(); + + s_rdtsc_to_ms = ( 1000.0f * ( d1 - d0 ) ) / ( t1 - t0 ); + } + +#if GL_BATCH_PERF_ANALYSIS_WRITE_PNGS + if ( m_pBatch_vis_bitmap && m_pBatch_vis_bitmap->is_valid() ) + { + double t = tm.GetDurationInProgress().GetMillisecondsF(); + + uint h = 1; + if ( gl_batch_vis_y_scale.GetFloat() > 0.0f) + { + h = ceil( t / gl_batch_vis_y_scale.GetFloat() ); + h = MAX(h, 1); + } + + // Total time spent inside any and all our "D3D9" calls + double flTotalD3DTime = g_nTotalD3DCycles * s_rdtsc_to_ms; + m_pBatch_vis_bitmap->fill_box(0, m_nBatchVisY, (uint)(.5f + flTotalD3DTime / gl_batch_vis_abs_scale.GetFloat() * m_pBatch_vis_bitmap->width()), h, 150, 150, 150); + + // Total total spent processing just DrawIndexedPrimitive() for this batch. + m_pBatch_vis_bitmap->fill_box(0, m_nBatchVisY, (uint)(.5f + t / gl_batch_vis_abs_scale.GetFloat() * m_pBatch_vis_bitmap->width()), h, 70, 70, 70); + + double flTotalGLMS = gGL->m_nTotalGLCycles * s_rdtsc_to_ms; + + // Total time spent inside of all OpenGL calls + m_pBatch_vis_bitmap->additive_fill_box(0, m_nBatchVisY, (uint)(.5f + flTotalGLMS / gl_batch_vis_abs_scale.GetFloat() * m_pBatch_vis_bitmap->width()), h, 0, 0, 64); + + if (flushStats.m_nNewVS) m_pBatch_vis_bitmap->additive_fill_box(80-16, m_nBatchVisY, 8, h, 0, 110, 0); + if (flushStats.m_nNewPS) m_pBatch_vis_bitmap->additive_fill_box(80-8, m_nBatchVisY, 8, h, 110, 0, 110); + + int lm = 80; + m_pBatch_vis_bitmap->fill_box(lm+0+flushStats.m_nFirstVSConstant, m_nBatchVisY, flushStats.m_nNumVSConstants, h, 64, 255, 255); + m_pBatch_vis_bitmap->fill_box(lm+64, m_nBatchVisY, flushStats.m_nNumVSBoneConstants, h, 255, 64, 64); + m_pBatch_vis_bitmap->fill_box(lm+64+256+flushStats.m_nFirstPSConstant, m_nBatchVisY, flushStats.m_nNumPSConstants, h, 64, 64, 255); + + m_pBatch_vis_bitmap->fill_box(lm+64+256+32, m_nBatchVisY, flushStats.m_nNumChangedSamplers, h, 255, 255, 255); + m_pBatch_vis_bitmap->fill_box(lm+64+256+32+16, m_nBatchVisY, flushStats.m_nNumSamplingParamsChanged, h, 92, 128, 255); + + if ( flushStats.m_nVertexBufferChanged ) m_pBatch_vis_bitmap->fill_box(lm+64+256+32+16+64, m_nBatchVisY, 16, h, 128, 128, 128); + if ( flushStats.m_nIndexBufferChanged ) m_pBatch_vis_bitmap->fill_box(lm+64+256+32+16+64+16, m_nBatchVisY, 16, h, 128, 128, 255); + + m_pBatch_vis_bitmap->fill_box(lm+64+256+32+16+64+16+16, m_nBatchVisY, ( ( g_nTotalVBLockBytes + g_nTotalIBLockBytes ) * 64 + 2047 ) / 2048, h, 120, 120, 120 ); + m_pBatch_vis_bitmap->additive_fill_box(lm+64+256+32+16+64+16+16, m_nBatchVisY, ( g_nTotalVBLockBytes * 64 + 2047 ) / 2048, h, 120, 0, 0); + + m_nBatchVisY += h; + } +#endif + + m_nNumProgramChanges += ((flushStats.m_nNewVS + flushStats.m_nNewPS) != 0); + + m_flTotalD3DTime += g_nTotalD3DCycles * s_rdtsc_to_ms; + m_nTotalD3DCalls += g_nTotalD3DCalls; + g_nTotalD3DCycles = 0; + g_nTotalD3DCalls = 0; + + m_flTotalGLTime += gGL->m_nTotalGLCycles * s_rdtsc_to_ms; + m_nTotalGLCalls += gGL->m_nTotalGLCalls; + gGL->m_nTotalGLCycles = 0; + gGL->m_nTotalGLCalls = 0; + + g_nTotalVBLockBytes = 0; + g_nTotalIBLockBytes = 0; +#endif + + return S_OK; + +draw_failed: + Assert( 0 ); + return E_FAIL; +} + +#else + +// OSX 10.6 support + +HRESULT IDirect3DDevice9::FlushIndexBindings( void ) +{ + // push index buffer state + m_ctx->SetIndexBuffer( m_indices.m_idxBuffer->m_idxBuffer ); + return S_OK; +} + +HRESULT IDirect3DDevice9::FlushVertexBindings( uint baseVertexIndex ) +{ + // push vertex buffer state for the current vertex decl + // in this variant we just walk the attrib map in the VS and do a pull for each one. + // if we can't find a match in the vertex decl, we may fall back to the secret 'dummy' VBO that GLM maintains + + GLMVertexSetup setup; + memset( &setup, 0, sizeof( setup ) ); + + IDirect3DVertexDeclaration9 *vxdecl = m_pVertDecl; + unsigned char *vshAttribMap = m_vertexShader->m_vtxAttribMap; + + // this loop could be tightened if we knew the number of live entries in the shader attrib map. + // which of course would be easy to do in the create shader function or even in the translator. + + GLMVertexAttributeDesc *dstAttr = setup.m_attrs; + for( int i=0; i<16; i++,dstAttr++ ) + { + unsigned char vshattrib = vshAttribMap[ i ]; + if (vshattrib != 0xBB) + { + // try to find the match in the decl. + // idea: put some inverse table in the decl which could accelerate this search. + + D3DVERTEXELEMENT9_GL *elem = m_pVertDecl->m_elements; + for( int j=0; j< m_pVertDecl->m_elemCount; j++,elem++) + { + // if it matches, install it, change vshattrib so the code below does not trigger, then end the loop + if ( ((vshattrib>>4) == elem->m_dxdecl.Usage) && ((vshattrib & 0x0F) == elem->m_dxdecl.UsageIndex) ) + { + // targeting attribute #i in the setup with element data #j from the decl + + *dstAttr = elem->m_gldecl; + + // then fix buffer, stride, offset - note that we honor the base vertex index here by fiddling the offset + int streamIndex = elem->m_dxdecl.Stream; + dstAttr->m_pBuffer = m_streams[ streamIndex ].m_vtxBuffer->m_vtxBuffer; + dstAttr->m_stride = m_streams[ streamIndex ].m_stride; + dstAttr->m_offset += m_streams[ streamIndex ].m_offset + (baseVertexIndex * dstAttr->m_stride); + + // set mask + setup.m_attrMask |= (1 << i); + + // end loop + vshattrib = 0xBB; + j = 999; + } + } + + // if vshattrib is not 0xBB here, that means we could not find a source in the decl for it + if (vshattrib != 0xBB) + { + // fill out attr the same way as usual, we just pass NULL for the buffer and ask GLM to have mercy on us + + dstAttr->m_pBuffer = NULL; + dstAttr->m_stride = 0; + dstAttr->m_offset = 0; + + // only implement certain usages... if we haven't seen it before, stop. + switch (vshattrib >> 4) // aka usage + { + case D3DDECLUSAGE_POSITION: + case D3DDECLUSAGE_BLENDWEIGHT: + case D3DDECLUSAGE_BLENDINDICES: + Debugger(); + break; + + case D3DDECLUSAGE_NORMAL: + dstAttr->m_nCompCount = 3; + dstAttr->m_datatype = GL_FLOAT; + dstAttr->m_normalized = false; + break; + + case D3DDECLUSAGE_PSIZE: + Debugger(); + break; + + case D3DDECLUSAGE_TEXCOORD: + dstAttr->m_nCompCount = 3; + dstAttr->m_datatype = GL_FLOAT; + dstAttr->m_normalized = false; + break; + + case D3DDECLUSAGE_TANGENT: + case D3DDECLUSAGE_BINORMAL: + case D3DDECLUSAGE_TESSFACTOR: + case D3DDECLUSAGE_PLUGH: + Debugger(); + break; + + case D3DDECLUSAGE_COLOR: + dstAttr->m_nCompCount = 4; + dstAttr->m_datatype = GL_UNSIGNED_BYTE; + dstAttr->m_normalized = true; + break; + + case D3DDECLUSAGE_FOG: + case D3DDECLUSAGE_DEPTH: + case D3DDECLUSAGE_SAMPLE: + Debugger(); + break; + } + } + } + } + + // copy active program's vertex attrib map into the vert setup info + memcpy(&setup.m_vtxAttribMap, m_vertexShader->m_vtxAttribMap, sizeof(m_vertexShader->m_vtxAttribMap)); + + m_ctx->SetVertexAttributes(&setup); + return S_OK; +} + + +// OSX path offering support for 10.6 (we do not have support for glDrawRangeElementsBaseVertex) +HRESULT IDirect3DDevice9::DrawIndexedPrimitive( D3DPRIMITIVETYPE Type,INT BaseVertexIndex,UINT MinVertexIndex,UINT NumVertices,UINT startIndex,UINT primCount ) +{ + Assert( m_ctx->m_nCurOwnerThreadId == ThreadGetCurrentId() ); + + TOGL_NULL_DEVICE_CHECK; + if ( m_bFBODirty ) + { + UpdateBoundFBO(); + } + + g_nTotalDrawsOrClears++; + +#if GL_BATCH_PERF_ANALYSIS + m_nTotalPrims += primCount; + CFastTimer tm; + CFlushDrawStatesStats& flushStats = m_ctx->m_FlushStats; + tm.Start(); + flushStats.Clear(); +#endif + +#if GLMDEBUG + if ( gl.m_FogEnable ) + { + GLMPRINTF(("-D- IDirect3DDevice9::DrawIndexedPrimitive is seeing enabled fog...")); + } +#endif + + if ( ( !m_indices.m_idxBuffer ) || ( !m_vertexShader ) ) + goto draw_failed; + + this->FlushIndexBindings( ); + this->FlushVertexBindings( BaseVertexIndex ); + m_ctx->FlushDrawStates( MinVertexIndex, MinVertexIndex + NumVertices - 1, 0 ); + + if (gl.m_FogEnable) + { + GLMPRINTF(("-D- IDirect3DDevice9::DrawIndexedPrimitive is seeing enabled fog...")); + } + + switch(Type) + { + case D3DPT_POINTLIST: + Debugger(); + break; + + case D3DPT_LINELIST: + GLMPRINTF(("-X- IDirect3DDevice9::DrawIndexedPrimitive( D3DPT_LINELIST ) - ignored.")); + // Debugger(); + m_ctx->DrawRangeElements( (GLenum)GL_LINES, (GLuint)MinVertexIndex, (GLuint)(MinVertexIndex + NumVertices), (GLsizei)primCount*2, (GLenum)GL_UNSIGNED_SHORT, (const GLvoid *)(startIndex * sizeof(short)), m_indices.m_idxBuffer->m_idxBuffer ); + break; + + case D3DPT_TRIANGLELIST: + m_ctx->DrawRangeElements(GL_TRIANGLES, (GLuint)MinVertexIndex, (GLuint)(MinVertexIndex + NumVertices), (GLsizei)primCount*3, (GLenum)GL_UNSIGNED_SHORT, (const GLvoid *)(startIndex * sizeof(short)), m_indices.m_idxBuffer->m_idxBuffer ); + break; + + case D3DPT_TRIANGLESTRIP: + // enabled... Debugger(); + m_ctx->DrawRangeElements(GL_TRIANGLE_STRIP, (GLuint)MinVertexIndex, (GLuint)(MinVertexIndex + NumVertices), (GLsizei)(2+primCount), (GLenum)GL_UNSIGNED_SHORT, (const GLvoid *)(startIndex * sizeof(short)), m_indices.m_idxBuffer->m_idxBuffer ); + break; + } + + return S_OK; + +draw_failed: + Assert( 0 ); + return E_FAIL; +} + +#endif // #ifndef OSX + +HRESULT IDirect3DDevice9::DrawIndexedPrimitiveUP(D3DPRIMITIVETYPE PrimitiveType,UINT MinVertexIndex,UINT NumVertices,UINT PrimitiveCount,CONST void* pIndexData,D3DFORMAT IndexDataFormat,CONST void* pVertexStreamZeroData,UINT VertexStreamZeroStride) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +BOOL IDirect3DDevice9::ShowCursor(BOOL bShow) +{ + // FIXME NOP + //DXABSTRACT_BREAK_ON_ERROR(); + return TRUE; +} + +void d3drect_to_glmbox( D3DRECT *src, GLScissorBox_t *dst ) +{ + // to convert from a d3d rect to a GL rect you have to fix up the vertical axis, since D3D Y=0 is the top, but GL Y=0 is the bottom. + // you can't fix it without knowing the height. + + dst->width = src->x2 - src->x1; + dst->x = src->x1; // left edge + + dst->height = src->y2 - src->y1; + dst->y = src->y1; // bottom edge - take large Y from d3d and subtract from surf height. +} + +HRESULT IDirect3DDevice9::Clear(DWORD Count,CONST D3DRECT* pRects,DWORD Flags,D3DCOLOR Color,float Z,DWORD Stencil) +{ + GL_BATCH_PERF_CALL_TIMER; + + if ( m_bFBODirty ) + { + UpdateBoundFBO(); + } + + g_nTotalDrawsOrClears++; + + m_ctx->FlushDrawStatesNoShaders(); + + + //debugging Color = (rand() | 0xFF0000FF) & 0xFF3F3FFF; + if (!Count) + { + // run clear with no added rectangle + m_ctx->Clear( (Flags&D3DCLEAR_TARGET)!=0, Color, + (Flags&D3DCLEAR_ZBUFFER)!=0, Z, + (Flags&D3DCLEAR_STENCIL)!=0, Stencil, + NULL + ); + } + else + { + GLScissorBox_t tempbox; + + // do the rects one by one and convert each one to GL form + for( uint i=0; iClear( (Flags&D3DCLEAR_TARGET)!=0, Color, + (Flags&D3DCLEAR_ZBUFFER)!=0, Z, + (Flags&D3DCLEAR_STENCIL)!=0, Stencil, + &tempbox + ); + } + } + + return S_OK; +} + +HRESULT IDirect3DDevice9::SetTransform(D3DTRANSFORMSTATETYPE State,CONST D3DMATRIX* pMatrix) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetTextureStageState(DWORD Stage,D3DTEXTURESTAGESTATETYPE Type,DWORD Value) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DDevice9::ValidateDevice(DWORD* pNumPasses) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetMaterial(CONST D3DMATERIAL9* pMaterial) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + GLMPRINTF(("-X- IDirect3DDevice9::SetMaterial - ignored.")); +// DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + + +HRESULT IDirect3DDevice9::LightEnable(DWORD Index,BOOL Enable) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetScissorRect(CONST RECT* pRect) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + //int nSurfaceHeight = m_ctx->m_drawingFBO->m_attach[ kAttColor0 ].m_tex->m_layout->m_key.m_ySize; + + GLScissorBox_t newScissorBox = { pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top }; + gl.m_ScissorBox = newScissorBox; + m_ctx->WriteScissorBox( &gl.m_ScissorBox ); + return S_OK; +} + +HRESULT IDirect3DDevice9::GetDeviceCaps(D3DCAPS9* pCaps) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + + // "Adapter" is used to index amongst the set of fake-adapters maintained in the display DB + GLMDisplayDB *db = GetDisplayDB(); + int glmRendererIndex = -1; + int glmDisplayIndex = -1; + + GLMRendererInfoFields glmRendererInfo; + GLMDisplayInfoFields glmDisplayInfo; + + bool result = db->GetFakeAdapterInfo( m_params.m_adapter, &glmRendererIndex, &glmDisplayIndex, &glmRendererInfo, &glmDisplayInfo ); (void)result; + Assert (!result); + // just leave glmRendererInfo filled out for subsequent code to look at as needed. + + FillD3DCaps9( glmRendererInfo, pCaps ); + + return S_OK; +} + + +HRESULT IDirect3DDevice9::TestCooperativeLevel() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + // game calls this to see if device was lost. + // last I checked the device was still attached to the computer. + // so, return OK. + + return S_OK; +} + +HRESULT IDirect3DDevice9::SetClipPlane(DWORD Index,CONST float* pPlane) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + Assert(Index<2); + + // We actually push the clip plane coeffs to two places + // - into a shader param for ARB mode + // - and into the API defined clip plane slots for GLSL mode. + + // if ARB mode... THIS NEEDS TO GO... it's messing up the dirty ranges.. + { + // this->SetVertexShaderConstantF( DXABSTRACT_VS_CLIP_PLANE_BASE+Index, pPlane, 1 ); // stash the clip plane values into shader param - translator knows where to look + } + + // if GLSL mode... latch it and let FlushStates push it out + { + GLClipPlaneEquation_t peq; + peq.x = pPlane[0]; + peq.y = pPlane[1]; + peq.z = pPlane[2]; + peq.w = pPlane[3]; + + gl.m_ClipPlaneEquation[ Index ] = peq; + FlushClipPlaneEquation(); + + // m_ctx->WriteClipPlaneEquation( &peq, Index ); + } + + return S_OK; +} + +HRESULT IDirect3DDevice9::EvictManagedResources() +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + GLMPRINTF(("-X- IDirect3DDevice9::EvictManagedResources --> IGNORED")); + return S_OK; +} + +HRESULT IDirect3DDevice9::SetLight(DWORD Index,CONST D3DLIGHT9*) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +void IDirect3DDevice9::SetGammaRamp(UINT iSwapChain,DWORD Flags,CONST D3DGAMMARAMP* pRamp) +{ + GL_BATCH_PERF_CALL_TIMER; + Assert( GetCurrentOwnerThreadId() == ThreadGetCurrentId() ); + + if ( g_pLauncherMgr ) + { + g_pLauncherMgr->SetGammaRamp( pRamp->red, pRamp->green, pRamp->blue ); + } +} + +void TOGLMETHODCALLTYPE IDirect3DDevice9::SaveGLState() +{ +} + +void TOGLMETHODCALLTYPE IDirect3DDevice9::RestoreGLState() +{ + m_ctx->ForceFlushStates(); + + m_bFBODirty = true; +} + +void IDirect3DDevice9::AcquireThreadOwnership( ) +{ + GL_BATCH_PERF_CALL_TIMER; + m_ctx->MakeCurrent( true ); +} + + +void IDirect3DDevice9::ReleaseThreadOwnership( ) +{ + GL_BATCH_PERF_CALL_TIMER; + m_ctx->ReleaseCurrent( true ); +} + +void IDirect3DDevice9::SetMaxUsedVertexShaderConstantsHintNonInline( uint nMaxReg ) +{ + GL_BATCH_PERF_CALL_TIMER; + m_ctx->SetMaxUsedVertexShaderConstantsHint( nMaxReg ); +} + +HRESULT IDirect3DDevice9::SetRenderState( D3DRENDERSTATETYPE State, DWORD Value ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + TOGL_NULL_DEVICE_CHECK; + +#if GLMDEBUG + // None of this is needed normally. + char rsSpew = 1; + char ignored = 0; + + if (State >= D3DRS_VALUE_LIMIT) + { + DXABSTRACT_BREAK_ON_ERROR(); // bad + return S_OK; + } + + const D3D_RSINFO *info = &g_D3DRS_INFO_unpacked[ State ]; + if (info->m_state != State) + { + DXABSTRACT_BREAK_ON_ERROR(); // bad - we never set up that state in our list + return S_OK; + } + + if (rsSpew) + { + GLMPRINTF(("-X- IDirect3DDevice9::SetRenderState: set %s(%d) to %d(0x%08x) ( class %d, defval is %d(0x%08x) )", GLMDecode( eD3D_RSTATE,State),State, Value,Value, info->m_class, info->m_defval,info->m_defval )); + } + + switch( info->m_class ) + { + case 0: // just ignore quietly. example: D3DRS_LIGHTING + ignored = 1; + break; + + case 1: + { + // no GL response - and no error as long as the write value matches the default + if (Value != info->m_defval) + { + static char stop_here_1 = 0; + if (stop_here_1) + DXABSTRACT_BREAK_ON_ERROR(); + } + break; + } + + case 2: + { + // provide GL response, but only support known default value + if (Value != info->m_defval) + { + static char stop_here_2 = 0; + if (stop_here_2) + DXABSTRACT_BREAK_ON_ERROR(); + } + // fall through to mode 3 + } + case 3: + // normal case - the switch statement below will handle this + break; + } +#endif + + switch (State) + { + case D3DRS_ZENABLE: // kGLDepthTestEnable + { + gl.m_DepthTestEnable.enable = Value; + m_ctx->WriteDepthTestEnable( &gl.m_DepthTestEnable ); + break; + } + case D3DRS_ZWRITEENABLE: // kGLDepthMask + { + gl.m_DepthMask.mask = Value; + m_ctx->WriteDepthMask( &gl.m_DepthMask ); + break; + } + case D3DRS_ZFUNC: + { + // kGLDepthFunc + GLenum func = D3DCompareFuncToGL( Value ); + gl.m_DepthFunc.func = func; + m_ctx->WriteDepthFunc( &gl.m_DepthFunc ); + break; + } + + case D3DRS_COLORWRITEENABLE: // kGLColorMaskSingle + { + gl.m_ColorMaskSingle.r = ((Value & D3DCOLORWRITEENABLE_RED) != 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.g = ((Value & D3DCOLORWRITEENABLE_GREEN)!= 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.b = ((Value & D3DCOLORWRITEENABLE_BLUE) != 0) ? 0xFF : 0x00; + gl.m_ColorMaskSingle.a = ((Value & D3DCOLORWRITEENABLE_ALPHA)!= 0) ? 0xFF : 0x00; + m_ctx->WriteColorMaskSingle( &gl.m_ColorMaskSingle ); + break; + } + + case D3DRS_CULLMODE: // kGLCullFaceEnable / kGLCullFrontFace + { + switch (Value) + { + case D3DCULL_NONE: + { + gl.m_CullFaceEnable.enable = false; + gl.m_CullFrontFace.value = GL_CCW; //doesn't matter + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + + case D3DCULL_CW: + { + gl.m_CullFaceEnable.enable = true; + gl.m_CullFrontFace.value = GL_CW; //origGL_CCW; + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + case D3DCULL_CCW: + { + gl.m_CullFaceEnable.enable = true; + gl.m_CullFrontFace.value = GL_CCW; //origGL_CW; + + m_ctx->WriteCullFaceEnable( &gl.m_CullFaceEnable ); + m_ctx->WriteCullFrontFace( &gl.m_CullFrontFace ); + break; + } + default: + { + DXABSTRACT_BREAK_ON_ERROR(); + break; + } + } + break; + } + + //-------------------------------------------------------------------------------------------- alphablend stuff + + case D3DRS_ALPHABLENDENABLE: // kGLBlendEnable + { + gl.m_BlendEnable.enable = Value; + m_ctx->WriteBlendEnable( &gl.m_BlendEnable ); + break; + } + + case D3DRS_BLENDOP: // kGLBlendEquation // D3D blend-op ==> GL blend equation + { + GLenum equation = D3DBlendOperationToGL( Value ); + gl.m_BlendEquation.equation = equation; + m_ctx->WriteBlendEquation( &gl.m_BlendEquation ); + break; + } + + case D3DRS_SRCBLEND: // kGLBlendFactor // D3D blend-factor ==> GL blend factor + case D3DRS_DESTBLEND: // kGLBlendFactor + { + GLenum factor = D3DBlendFactorToGL( Value ); + + if (State==D3DRS_SRCBLEND) + { + gl.m_BlendFactor.srcfactor = factor; + } + else + { + gl.m_BlendFactor.dstfactor = factor; + } + m_ctx->WriteBlendFactor( &gl.m_BlendFactor ); + break; + } + + case D3DRS_SRGBWRITEENABLE: // kGLBlendEnableSRGB + { + gl.m_BlendEnableSRGB.enable = Value; + m_ctx->WriteBlendEnableSRGB( &gl.m_BlendEnableSRGB ); + break; + } + + //-------------------------------------------------------------------------------------------- alphatest stuff + + case D3DRS_ALPHATESTENABLE: + { + gl.m_AlphaTestEnable.enable = Value; + m_ctx->WriteAlphaTestEnable( &gl.m_AlphaTestEnable ); + break; + } + + case D3DRS_ALPHAREF: + { + gl.m_AlphaTestFunc.ref = Value / 255.0f; + m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc ); + break; + } + + case D3DRS_ALPHAFUNC: + { + GLenum func = D3DCompareFuncToGL( Value );; + gl.m_AlphaTestFunc.func = func; + m_ctx->WriteAlphaTestFunc( &gl.m_AlphaTestFunc ); + break; + } + + //-------------------------------------------------------------------------------------------- stencil stuff + + case D3DRS_STENCILENABLE: // GLStencilTestEnable_t + { + gl.m_StencilTestEnable.enable = Value; + m_ctx->WriteStencilTestEnable( &gl.m_StencilTestEnable ); + break; + } + + case D3DRS_STENCILFAIL: // GLStencilOp_t "what do you do if stencil test fails" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.sfail = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + + case D3DRS_STENCILZFAIL: // GLStencilOp_t "what do you do if stencil test passes *but* depth test fails, if depth test happened" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.dpfail = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + + case D3DRS_STENCILPASS: // GLStencilOp_t "what do you do if stencil test and depth test both pass" + { + GLenum stencilop = D3DStencilOpToGL( Value ); + gl.m_StencilOp.dppass = stencilop; + + m_ctx->WriteStencilOp( &gl.m_StencilOp,0 ); + m_ctx->WriteStencilOp( &gl.m_StencilOp,1 ); // ********* need to recheck this + break; + } + + case D3DRS_STENCILFUNC: // GLStencilFunc_t + { + GLenum stencilfunc = D3DCompareFuncToGL( Value ); + gl.m_StencilFunc.frontfunc = gl.m_StencilFunc.backfunc = stencilfunc; + + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + + case D3DRS_STENCILREF: // GLStencilFunc_t + { + gl.m_StencilFunc.ref = Value; + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + + case D3DRS_STENCILMASK: // GLStencilFunc_t + { + gl.m_StencilFunc.mask = Value; + m_ctx->WriteStencilFunc( &gl.m_StencilFunc ); + break; + } + + case D3DRS_STENCILWRITEMASK: // GLStencilWriteMask_t + { + gl.m_StencilWriteMask.mask = Value; + m_ctx->WriteStencilWriteMask( &gl.m_StencilWriteMask ); + break; + } + + case D3DRS_FOGENABLE: // none of these are implemented yet... erk + { + gl.m_FogEnable = (Value != 0); + GLMPRINTF(("-D- fogenable = %d",Value )); + break; + } + + case D3DRS_SCISSORTESTENABLE: // kGLScissorEnable + { + gl.m_ScissorEnable.enable = Value; + m_ctx->WriteScissorEnable( &gl.m_ScissorEnable ); + break; + } + + case D3DRS_DEPTHBIAS: // kGLDepthBias + { + // the value in the dword is actually a float + float fvalue = *(float*)&Value; + gl.m_DepthBias.units = fvalue; + + m_ctx->WriteDepthBias( &gl.m_DepthBias ); + break; + } + + // good ref on these: http://aras-p.info/blog/2008/06/12/depth-bias-and-the-power-of-deceiving-yourself/ + case D3DRS_SLOPESCALEDEPTHBIAS: + { + // the value in the dword is actually a float + float fvalue = *(float*)&Value; + gl.m_DepthBias.factor = fvalue; + + m_ctx->WriteDepthBias( &gl.m_DepthBias ); + break; + } + + // Alpha to coverage + case D3DRS_ADAPTIVETESS_Y: + { + gl.m_AlphaToCoverageEnable.enable = Value; + m_ctx->WriteAlphaToCoverageEnable( &gl.m_AlphaToCoverageEnable ); + break; + } + + case D3DRS_CLIPPLANEENABLE: // kGLClipPlaneEnable + { + // d3d packs all the enables into one word. + // we break that out so we don't do N glEnable calls to sync - + // GLM is tracking one unique enable per plane. + for( int i=0; iWriteClipPlaneEnable( &gl.m_ClipPlaneEnable[x], x ); + break; + } + + //-------------------------------------------------------------------------------------------- polygon/fill mode + + case D3DRS_FILLMODE: + { + GLuint mode = 0; + switch(Value) + { + case D3DFILL_POINT: mode = GL_POINT; break; + case D3DFILL_WIREFRAME: mode = GL_LINE; break; + case D3DFILL_SOLID: mode = GL_FILL; break; + default: DXABSTRACT_BREAK_ON_ERROR(); break; + } + gl.m_PolygonMode.values[0] = gl.m_PolygonMode.values[1] = mode; + m_ctx->WritePolygonMode( &gl.m_PolygonMode ); + break; + } + +#if GLMDEBUG + case D3DRS_MULTISAMPLEANTIALIAS: + case D3DRS_MULTISAMPLEMASK: + case D3DRS_FOGCOLOR: + case D3DRS_FOGTABLEMODE: + case D3DRS_FOGSTART: + case D3DRS_FOGEND: + case D3DRS_FOGDENSITY: + case D3DRS_RANGEFOGENABLE: + case D3DRS_FOGVERTEXMODE: + case D3DRS_COLORWRITEENABLE1: // kGLColorMaskMultiple + case D3DRS_COLORWRITEENABLE2: // kGLColorMaskMultiple + case D3DRS_COLORWRITEENABLE3: // kGLColorMaskMultiple + case D3DRS_SEPARATEALPHABLENDENABLE: + case D3DRS_BLENDOPALPHA: + case D3DRS_SRCBLENDALPHA: + case D3DRS_DESTBLENDALPHA: + case D3DRS_TWOSIDEDSTENCILMODE: // -> GL_STENCIL_TEST_TWO_SIDE_EXT... not yet implemented ? + case D3DRS_CCW_STENCILFAIL: // GLStencilOp_t + case D3DRS_CCW_STENCILZFAIL: // GLStencilOp_t + case D3DRS_CCW_STENCILPASS: // GLStencilOp_t + case D3DRS_CCW_STENCILFUNC: // GLStencilFunc_t + case D3DRS_CLIPPING: // ???? is clipping ever turned off ?? + case D3DRS_LASTPIXEL: + case D3DRS_DITHERENABLE: + case D3DRS_SHADEMODE: + default: + ignored = 1; + break; +#endif + } + +#if GLMDEBUG + if (rsSpew && ignored) + { + GLMPRINTF(("-X- (ignored)")); + } +#endif + + return S_OK; +} + +HRESULT IDirect3DDevice9::SetSamplerStateNonInline( DWORD Sampler, D3DSAMPLERSTATETYPE Type, DWORD Value ) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + + Assert( Sampler < GLM_SAMPLER_COUNT ); + + m_ctx->SetSamplerDirty( Sampler ); + + switch( Type ) + { + case D3DSAMP_ADDRESSU: + m_ctx->SetSamplerAddressU( Sampler, Value ); + break; + case D3DSAMP_ADDRESSV: + m_ctx->SetSamplerAddressV( Sampler, Value ); + break; + case D3DSAMP_ADDRESSW: + m_ctx->SetSamplerAddressW( Sampler, Value ); + break; + case D3DSAMP_BORDERCOLOR: + m_ctx->SetSamplerBorderColor( Sampler, Value ); + break; + case D3DSAMP_MAGFILTER: + m_ctx->SetSamplerMagFilter( Sampler, Value ); + break; + case D3DSAMP_MIPFILTER: + m_ctx->SetSamplerMipFilter( Sampler, Value ); + break; + case D3DSAMP_MINFILTER: + m_ctx->SetSamplerMinFilter( Sampler, Value ); + break; + case D3DSAMP_MIPMAPLODBIAS: + m_ctx->SetSamplerMipMapLODBias( Sampler, Value ); + break; + case D3DSAMP_MAXMIPLEVEL: + m_ctx->SetSamplerMaxMipLevel( Sampler, Value); + break; + case D3DSAMP_MAXANISOTROPY: + m_ctx->SetSamplerMaxAnisotropy( Sampler, Value); + break; + case D3DSAMP_SRGBTEXTURE: + //m_samplers[ Sampler ].m_srgb = Value; + m_ctx->SetSamplerSRGBTexture(Sampler, Value); + break; + case D3DSAMP_SHADOWFILTER: + m_ctx->SetShadowFilter(Sampler, Value); + break; + + default: DXABSTRACT_BREAK_ON_ERROR(); break; + } + + return S_OK; +} + +void IDirect3DDevice9::SetSamplerStatesNonInline( + DWORD Sampler, DWORD AddressU, DWORD AddressV, DWORD AddressW, + DWORD MinFilter, DWORD MagFilter, DWORD MipFilter, + DWORD MinLod, float LodBias) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + + Assert( Sampler < GLM_SAMPLER_COUNT); + + m_ctx->SetSamplerDirty( Sampler ); + + m_ctx->SetSamplerStates( Sampler, AddressU, AddressV, AddressW, MinFilter, MagFilter, MipFilter, MinLod, LodBias ); +} + +HRESULT IDirect3DDevice9::SetTextureNonInline(DWORD Stage,IDirect3DBaseTexture9* pTexture) +{ + GL_BATCH_PERF_CALL_TIMER; + GL_PUBLIC_ENTRYPOINT_CHECKS( this ); + Assert( Stage < GLM_SAMPLER_COUNT ); + m_textures[Stage] = pTexture; + m_ctx->SetSamplerTex( Stage, pTexture ? pTexture->m_tex : NULL ); + return S_OK; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +void* ID3DXBuffer::GetBufferPointer() +{ + GL_BATCH_PERF_CALL_TIMER; + DXABSTRACT_BREAK_ON_ERROR(); + return NULL; +} + +DWORD ID3DXBuffer::GetBufferSize() +{ + GL_BATCH_PERF_CALL_TIMER; + DXABSTRACT_BREAK_ON_ERROR(); + return 0; +} + + + +#ifndef _MSC_VER +#pragma mark ----- More D3DX stuff +#endif + +// ------------------------------------------------------------------------------------------------------------------------------ // +// D3DX stuff. +// ------------------------------------------------------------------------------------------------------------------------------ // + +// matrix stack... + +HRESULT D3DXCreateMatrixStack( DWORD Flags, LPD3DXMATRIXSTACK* ppStack) +{ + + *ppStack = new ID3DXMatrixStack; + + (*ppStack)->Create(); + + return S_OK; +} + +ID3DXMatrixStack::ID3DXMatrixStack( void ) +{ + m_refcount[0] = 1; + m_refcount[1] = 0; +}; + +void ID3DXMatrixStack::AddRef( int which, char *comment ) +{ + Assert( which >= 0 ); + Assert( which < 2 ); + m_refcount[which]++; +}; + +ULONG ID3DXMatrixStack::Release( int which, char *comment ) +{ + Assert( which >= 0 ); + Assert( which < 2 ); + + bool deleting = false; + + m_refcount[which]--; + if ( (!m_refcount[0]) && (!m_refcount[1]) ) + { + deleting = true; + } + + if (deleting) + { + if (m_mark) + { + GLMPRINTF(("")) ; // place to hang a breakpoint + } + delete this; + return 0; + } + else + { + return m_refcount[0]; + } +}; + + +HRESULT ID3DXMatrixStack::Create() +{ + m_stack.EnsureCapacity( 16 ); // 1KB ish + m_stack.AddToTail(); + m_stackTop = 0; // top of stack is at index 0 currently + + LoadIdentity(); + + return S_OK; +} + +D3DXMATRIX* ID3DXMatrixStack::GetTop() +{ + return (D3DXMATRIX*)&m_stack[ m_stackTop ]; +} + +void ID3DXMatrixStack::Push() +{ + D3DMATRIX temp = m_stack[ m_stackTop ]; + m_stack.AddToTail( temp ); + m_stackTop ++; +} + +void ID3DXMatrixStack::Pop() +{ + int elem = m_stackTop--; + m_stack.Remove( elem ); +} + +void ID3DXMatrixStack::LoadIdentity() +{ + D3DXMATRIX *mat = GetTop(); + + D3DXMatrixIdentity( mat ); +} + +void ID3DXMatrixStack::LoadMatrix( const D3DXMATRIX *pMat ) +{ + *(GetTop()) = *pMat; +} + + +void ID3DXMatrixStack::MultMatrix( const D3DXMATRIX *pMat ) +{ + + // http://msdn.microsoft.com/en-us/library/bb174057(VS.85).aspx + // This method right-multiplies the given matrix to the current matrix + // (transformation is about the current world origin). + // m_pstack[m_currentPos] = m_pstack[m_currentPos] * (*pMat); + // This method does not add an item to the stack, it replaces the current + // matrix with the product of the current matrix and the given matrix. + + + DXABSTRACT_BREAK_ON_ERROR(); +} + +void ID3DXMatrixStack::MultMatrixLocal( const D3DXMATRIX *pMat ) +{ + // http://msdn.microsoft.com/en-us/library/bb174058(VS.85).aspx + // This method left-multiplies the given matrix to the current matrix + // (transformation is about the local origin of the object). + // m_pstack[m_currentPos] = (*pMat) * m_pstack[m_currentPos]; + // This method does not add an item to the stack, it replaces the current + // matrix with the product of the given matrix and the current matrix. + + + DXABSTRACT_BREAK_ON_ERROR(); +} + +HRESULT ID3DXMatrixStack::ScaleLocal(FLOAT x, FLOAT y, FLOAT z) +{ + // http://msdn.microsoft.com/en-us/library/bb174066(VS.85).aspx + // Scale the current matrix about the object origin. + // This method left-multiplies the current matrix with the computed + // scale matrix. The transformation is about the local origin of the object. + // + // D3DXMATRIX tmp; + // D3DXMatrixScaling(&tmp, x, y, z); + // m_stack[m_currentPos] = tmp * m_stack[m_currentPos]; + + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + + +HRESULT ID3DXMatrixStack::RotateAxisLocal(CONST D3DXVECTOR3* pV, FLOAT Angle) +{ + // http://msdn.microsoft.com/en-us/library/bb174062(VS.85).aspx + // Left multiply the current matrix with the computed rotation + // matrix, counterclockwise about the given axis with the given angle. + // (rotation is about the local origin of the object) + + // D3DXMATRIX tmp; + // D3DXMatrixRotationAxis( &tmp, pV, angle ); + // m_stack[m_currentPos] = tmp * m_stack[m_currentPos]; + // Because the rotation is left-multiplied to the matrix stack, the rotation + // is relative to the object's local coordinate space. + + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + +HRESULT ID3DXMatrixStack::TranslateLocal(FLOAT x, FLOAT y, FLOAT z) +{ + // http://msdn.microsoft.com/en-us/library/bb174068(VS.85).aspx + // Left multiply the current matrix with the computed translation + // matrix. (transformation is about the local origin of the object) + + // D3DXMATRIX tmp; + // D3DXMatrixTranslation( &tmp, x, y, z ); + // m_stack[m_currentPos] = tmp * m_stack[m_currentPos]; + + DXABSTRACT_BREAK_ON_ERROR(); + return S_OK; +} + + + + +const char* D3DXGetPixelShaderProfile( IDirect3DDevice9 *pDevice ) +{ + DXABSTRACT_BREAK_ON_ERROR(); + return ""; +} + +#ifdef _MSC_VER +#pragma warning (push) +#pragma warning (disable:4701) // potentially uninitialized local variable 'temp' used +#endif +D3DXMATRIX* D3DXMatrixMultiply( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM1, CONST D3DXMATRIX *pM2 ) +{ + D3DXMATRIX temp; + + for( int i=0; i<4; i++) + { + for( int j=0; j<4; j++) + { + temp.m[i][j] = (pM1->m[ i ][ 0 ] * pM2->m[ 0 ][ j ]) + + (pM1->m[ i ][ 1 ] * pM2->m[ 1 ][ j ]) + + (pM1->m[ i ][ 2 ] * pM2->m[ 2 ][ j ]) + + (pM1->m[ i ][ 3 ] * pM2->m[ 3 ][ j ]); + } + } + *pOut = temp; + return pOut; +} +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// Transform a 3D vector by a given matrix, projecting the result back into w = 1 +// http://msdn.microsoft.com/en-us/library/ee417622(VS.85).aspx +D3DXVECTOR3* D3DXVec3TransformCoord(D3DXVECTOR3 *pOut, CONST D3DXVECTOR3 *pV, CONST D3DXMATRIX *pM) +{ + D3DXVECTOR3 vOut; + + float norm = (pM->m[0][3] * pV->x) + (pM->m[1][3] * pV->y) + (pM->m[2][3] *pV->z) + pM->m[3][3]; + if ( norm ) + { + float norm_inv = 1.0f / norm; + vOut.x = (pM->m[0][0] * pV->x + pM->m[1][0] * pV->y + pM->m[2][0] * pV->z + pM->m[3][0]) * norm_inv; + vOut.y = (pM->m[0][1] * pV->x + pM->m[1][1] * pV->y + pM->m[2][1] * pV->z + pM->m[3][1]) * norm_inv; + vOut.z = (pM->m[0][2] * pV->x + pM->m[1][2] * pV->y + pM->m[2][2] * pV->z + pM->m[3][2]) * norm_inv; + } + else + { + vOut.x = vOut.y = vOut.z = 0.0f; + } + + *pOut = vOut; + + return pOut; +} + + +void D3DXMatrixIdentity( D3DXMATRIX *mat ) +{ + for( int i=0; i<4; i++) + { + for( int j=0; j<4; j++) + { + mat->m[i][j] = (i==j) ? 1.0f : 0.0f; // 1's on the diagonal. + } + } +} + +D3DXMATRIX* D3DXMatrixTranslation( D3DXMATRIX *pOut, FLOAT x, FLOAT y, FLOAT z ) +{ + D3DXMatrixIdentity( pOut ); + pOut->m[3][0] = x; + pOut->m[3][1] = y; + pOut->m[3][2] = z; + return pOut; +} + +D3DXMATRIX* D3DXMatrixInverse( D3DXMATRIX *pOut, FLOAT *pDeterminant, CONST D3DXMATRIX *pM ) +{ + Assert( sizeof( D3DXMATRIX ) == (16 * sizeof(float) ) ); + Assert( sizeof( VMatrix ) == (16 * sizeof(float) ) ); + Assert( pDeterminant == NULL ); // homey don't play that + + VMatrix *origM = (VMatrix*)pM; + VMatrix *destM = (VMatrix*)pOut; + + bool success = MatrixInverseGeneral( *origM, *destM ); (void)success; + Assert( success ); + + return pOut; +} + + +D3DXMATRIX* D3DXMatrixTranspose( D3DXMATRIX *pOut, CONST D3DXMATRIX *pM ) +{ + if (pOut != pM) + { + for( int i=0; i<4; i++) + { + for( int j=0; j<4; j++) + { + pOut->m[i][j] = pM->m[j][i]; + } + } + } + else + { + D3DXMATRIX temp = *pM; + D3DXMatrixTranspose( pOut, &temp ); + } + + return NULL; +} + + +D3DXPLANE* D3DXPlaneNormalize( D3DXPLANE *pOut, CONST D3DXPLANE *pP) +{ + // not very different from normalizing a vector. + // figure out the square root of the sum-of-squares of the x,y,z components + // make sure that's non zero + // then divide all four components by that value + // or return some dummy plane like 0,0,1,0 if it fails + + float len = sqrt( (pP->a * pP->a) + (pP->b * pP->b) + (pP->c * pP->c) ); + if (len > 1e-10) //FIXME need a real epsilon here ? + { + pOut->a = pP->a / len; pOut->b = pP->b / len; pOut->c = pP->c / len; pOut->d = pP->d / len; + } + else + { + pOut->a = 0.0f; pOut->b = 0.0f; pOut->c = 1.0f; pOut->d = 0.0f; + } + return pOut; +} + + +D3DXVECTOR4* D3DXVec4Transform( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV, CONST D3DXMATRIX *pM ) +{ + VMatrix *mat = (VMatrix*)pM; + Vector4D *vIn = (Vector4D*)pV; + Vector4D *vOut = (Vector4D*)pOut; + + Vector4DMultiplyTranspose( *mat, *vIn, *vOut ); + + return pOut; +} + + + +D3DXVECTOR4* D3DXVec4Normalize( D3DXVECTOR4 *pOut, CONST D3DXVECTOR4 *pV ) +{ + Vector4D *vIn = (Vector4D*) pV; + Vector4D *vOut = (Vector4D*) pOut; + + *vOut = *vIn; + Vector4DNormalize( *vOut ); + + return pOut; +} + + +D3DXMATRIX* D3DXMatrixOrthoOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn,FLOAT zf ) +{ + DXABSTRACT_BREAK_ON_ERROR(); + return NULL; +} + + +D3DXMATRIX* D3DXMatrixPerspectiveRH( D3DXMATRIX *pOut, FLOAT w, FLOAT h, FLOAT zn, FLOAT zf ) +{ + DXABSTRACT_BREAK_ON_ERROR(); + return NULL; +} + + +D3DXMATRIX* D3DXMatrixPerspectiveOffCenterRH( D3DXMATRIX *pOut, FLOAT l, FLOAT r, FLOAT b, FLOAT t, FLOAT zn, FLOAT zf ) +{ + DXABSTRACT_BREAK_ON_ERROR(); + return NULL; +} + + +D3DXPLANE* D3DXPlaneTransform( D3DXPLANE *pOut, CONST D3DXPLANE *pP, CONST D3DXMATRIX *pM ) +{ + float *out = &pOut->a; + + // dot dot dot + for( int x=0; x<4; x++ ) + { + out[x] = (pM->m[0][x] * pP->a) + + (pM->m[1][x] * pP->b) + + (pM->m[2][x] * pP->c) + + (pM->m[3][x] * pP->d); + } + + return pOut; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +IDirect3D9 *Direct3DCreate9(UINT SDKVersion) +{ + GLMPRINTF(( "-X- Direct3DCreate9: %d", SDKVersion )); + + return new IDirect3D9; +} + +// ------------------------------------------------------------------------------------------------------------------------------ // + +void D3DPERF_SetOptions( DWORD dwOptions ) +{ +} + + +HRESULT D3DXCompileShader( + LPCSTR pSrcData, + UINT SrcDataLen, + CONST D3DXMACRO* pDefines, + LPD3DXINCLUDE pInclude, + LPCSTR pFunctionName, + LPCSTR pProfile, + DWORD Flags, + LPD3DXBUFFER* ppShader, + LPD3DXBUFFER* ppErrorMsgs, + LPD3DXCONSTANTTABLE* ppConstantTable) +{ + DXABSTRACT_BREAK_ON_ERROR(); // is anyone calling this ? + return S_OK; +} + +#if defined(DX_TO_GL_ABSTRACTION) +void toglGetClientRect( void *hWnd, RECT *destRect ) +{ + // the only useful answer this call can offer, is the size of the canvas. + // actually getting the window bounds is not useful. + // so, see if a D3D device is up and running, and if so, + // dig in and find out its backbuffer size and use that. + + uint width, height; + g_pLauncherMgr->RenderedSize( width, height, false ); // false = get them, don't set them + Assert( width!=0 && height!=0 ); + + destRect->left = 0; + destRect->top = 0; + destRect->right = width; + destRect->bottom = height; + + //GLMPRINTF(( "-D- GetClientRect returning rect of (0,0, %d,%d)",width,height )); + + return; +} + +#endif + +#endif diff --git a/togles/linuxwin/glentrypoints.cpp b/togles/linuxwin/glentrypoints.cpp new file mode 100644 index 00000000..394f4f99 --- /dev/null +++ b/togles/linuxwin/glentrypoints.cpp @@ -0,0 +1,516 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glentrypoints.cpp +// +//=============================================================================// +// Immediately include gl.h, etc. here to avoid compilation warnings. + +#include "togles/rendermechanism.h" + +#include "appframework/AppFramework.h" +#include "appframework/IAppSystemGroup.h" +#include "tier0/dbg.h" +#include "tier0/icommandline.h" +#include "tier0/platform.h" +#include "interface.h" +#include "filesystem.h" +#include "filesystem_init.h" +#include "tier1/convar.h" +#include "vstdlib/cvar.h" +#include "inputsystem/ButtonCode.h" +#include "tier1.h" +#include "tier2/tier2.h" + +#if defined(_LINUX) && !defined(__ANDROID__) +#include +#endif + +// NOTE: This has to be the last file included! +#include "tier0/memdbgon.h" + +#if !defined(DX_TO_GL_ABSTRACTION) +#error +#endif + +#if defined(OSX) || defined(LINUX) || (defined (WIN32) && defined( DX_TO_GL_ABSTRACTION )) + #include "appframework/ilaunchermgr.h" + ILauncherMgr *g_pLauncherMgr = NULL; +#endif + +#define DEBUG_ALL_GLCALLS 0 + +#if DEBUG_ALL_GLCALLS +bool g_bDebugOpenGLCalls = true; +bool g_bPrintOpenGLCalls = false; + +#define GL_EXT(x,glmajor,glminor) +#define GL_FUNC(ext,req,ret,fn,arg,call) \ + static ret (*fn##_gldebugptr) arg = NULL; \ + static ret fn##_gldebug arg { \ + if (!g_bDebugOpenGLCalls) { return fn##_gldebugptr call; } \ + if (g_bPrintOpenGLCalls) { \ + printf("Calling %s ... ", #fn); \ + fflush(stdout); \ + } \ + ret retval = fn##_gldebugptr call; \ + if (g_bPrintOpenGLCalls) { \ + printf("%s returned!\n", #fn); \ + fflush(stdout); \ + } \ + const GLenum err = glGetError_gldebugptr(); \ + if ( err == GL_INVALID_FRAMEBUFFER_OPERATION ) { \ + const GLenum fberr = gGL->glCheckFramebufferStatus( GL_FRAMEBUFFER ); \ + printf("%s triggered error GL_INVALID_FRAMEBUFFER_OPERATION! (0x%X)\n\n\n", #fn, (int) fberr); \ + fflush(stdout); \ + __asm__ __volatile__ ( "int $3\n\t" ); \ + } else if (err != GL_NO_ERROR) { \ + printf("%s triggered error 0x%X!\n\n\n", #fn, (int) err); \ + fflush(stdout); \ + __asm__ __volatile__ ( "int $3\n\t" ); \ + } \ + return retval; \ +} + +#define GL_FUNC_VOID(ext,req,fn,arg,call) \ + static void (*fn##_gldebugptr) arg = NULL; \ + static void fn##_gldebug arg { \ + if (!g_bDebugOpenGLCalls) { fn##_gldebugptr call; return; } \ + if (g_bPrintOpenGLCalls) { \ + printf("Calling %s ... ", #fn); \ + fflush(stdout); \ + } \ + fn##_gldebugptr call; \ + if (g_bPrintOpenGLCalls) { \ + printf("%s returned!\n", #fn); \ + fflush(stdout); \ + } \ + const GLenum err = glGetError_gldebugptr(); \ + if ( err == GL_INVALID_FRAMEBUFFER_OPERATION ) { \ + const GLenum fberr = gGL->glCheckFramebufferStatus( GL_FRAMEBUFFER ); \ + printf("%s triggered error GL_INVALID_FRAMEBUFFER_OPERATION! (0x%X)\n\n\n", #fn, (int) fberr); \ + fflush(stdout); \ + __asm__ __volatile__ ( "int $3\n\t" ); \ + } else if (err != GL_NO_ERROR) { \ + printf("%s triggered error 0x%X!\n\n\n", #fn, (int) err); \ + fflush(stdout); \ + __asm__ __volatile__ ( "int $3\n\t" ); \ + } \ +} + +#include "togles/glfuncs.inl" +#undef GL_FUNC_VOID +#undef GL_FUNC +#undef GL_EXT +#endif + +COpenGLEntryPoints *gGL = NULL; +GL_GetProcAddressCallbackFunc_t gGL_GetProcAddressCallback = NULL; + +void *VoidFnPtrLookup_GlMgr(const char *fn, bool &okay, const bool bRequired, void *fallback) +{ + void *retval = NULL; + if ((!okay) && (!bRequired)) // always look up if required (so we get a complete list of crucial missing symbols). + return NULL; + + // SDL does the right thing, so we never need to use tier0 in this case. + retval = (*gGL_GetProcAddressCallback)(fn, okay, bRequired, fallback); + //printf("CDynamicFunctionOpenGL: SDL_GL_GetProcAddress(\"%s\") returned %p\n", fn, retval); + if ((retval == NULL) && (fallback != NULL)) + { + //printf("CDynamicFunctionOpenGL: Using fallback %p for \"%s\"\n", fallback, fn); + retval = fallback; + } + + // Note that a non-NULL response doesn't mean it's safe to call the function! + // You always have to check that the extension is supported; + // an implementation MAY return NULL in this case, but it doesn't have to (and doesn't, with the DRI drivers). + okay = (okay && (retval != NULL)); + if (bRequired && !okay) + fprintf(stderr, "Could not find required OpenGL entry point '%s'!\n", fn); + + return retval; +} + +COpenGLEntryPoints *GetOpenGLEntryPoints(GL_GetProcAddressCallbackFunc_t callback) +{ + if (gGL == NULL) + { + gGL_GetProcAddressCallback = callback; + gGL = new COpenGLEntryPoints(); + if (!gGL->m_bHave_OpenGL) + Error( "Missing basic required OpenGL functionality." ); + + } + return gGL; +} + +void ClearOpenGLEntryPoints() +{ + if ( gGL ) + { + gGL->ClearEntryPoints(); + } +} +COpenGLEntryPoints *ToGLConnectLibraries( CreateInterfaceFn factory ) +{ + ConnectTier1Libraries( &factory, 1 ); + ConVar_Register(); + ConnectTier2Libraries( &factory, 1 ); + + if ( !g_pFullFileSystem ) + { + Warning( "ToGL was unable to access the required interfaces!\n" ); + } + + // NOTE! : Overbright is 1.0 so that Hammer will work properly with the white bumped and unbumped lightmaps. + MathLib_Init( 2.2f, 2.2f, 0.0f, 2.0f ); + + #if defined( USE_SDL ) + g_pLauncherMgr = (ILauncherMgr *)factory( SDLMGR_INTERFACE_VERSION, NULL ); + #endif + + return gGL; +} + +void ToGLDisconnectLibraries() +{ + DisconnectTier2Libraries(); + ConVar_Unregister(); + DisconnectTier1Libraries(); +} + +#define GLVERNUM(Major, Minor, Patch) (((Major) * 100000) + ((Minor) * 1000) + (Patch)) + +static void GetOpenGLVersion(int *major, int *minor, int *patch) +{ + *major = *minor = *patch = 0; + static CDynamicFunctionOpenGL< true, const GLubyte *( APIENTRY *)(GLenum name), const GLubyte * > glGetString("glGetString"); + if (glGetString) + { + const char *version = (const char *) glGetString(GL_VERSION); + if (version) + { + sscanf( version, "%d.%d.%d", major, minor, patch ); + } + } +} + +static int GetOpenGLVersionMajor() +{ + int major, minor, patch; + GetOpenGLVersion(&major, &minor, &patch); + return major; +} + +static int GetOpenGLVersionMinor() +{ + int major, minor, patch; + GetOpenGLVersion(&major, &minor, &patch); + return minor; +} + +static int GetOpenGLVersionPatch() +{ + int major, minor, patch; + GetOpenGLVersion(&major, &minor, &patch); + return patch; +} + +static bool CheckBaseOpenGLVersion() +{ + const int NEED_MAJOR = 2; + const int NEED_MINOR = 0; + const int NEED_PATCH = 0; + + int major, minor, patch; + GetOpenGLVersion(&major, &minor, &patch); + + const int need = GLVERNUM(NEED_MAJOR, NEED_MINOR, NEED_PATCH); + const int have = GLVERNUM(major, minor, patch); + if (have < need) + { + fprintf(stderr, "PROBLEM: You appear to have OpenGL %d.%d.%d, but we need at least %d.%d.%d!\n", + major, minor, patch, NEED_MAJOR, NEED_MINOR, NEED_PATCH); + return false; + } + return true; +} + +static bool CheckOpenGLExtension_internal(const char *ext, const int coremajor, const int coreminor) +{ + if ((coremajor >= 0) && (coreminor >= 0)) // we know that this extension is part of the base spec as of GL_VERSION coremajor.coreminor. + { + int major, minor, patch; + GetOpenGLVersion(&major, &minor, &patch); + const int need = GLVERNUM(coremajor, coreminor, 0); + const int have = GLVERNUM(major, minor, patch); + if (have >= need) + return true; // we definitely have access to this "extension," as it is part of this version of the GL's core functionality. + } + + // okay, see if the GL_EXTENSIONS string reports it. + static CDynamicFunctionOpenGL< true, const GLubyte *( APIENTRY *)(GLenum name), const GLubyte * > glGetString("glGetString"); + if (!glGetString) + return false; + + // hacky scanning of this string, because I don't want to spend time breaking it into a vector like I should have. + const char *extensions = (const char *) glGetString(GL_EXTENSIONS); + const size_t extlen = strlen(ext); + while ((extensions) && (*extensions)) + { + const char *ptr = strstr(extensions, ext); +#if _WIN32 + if (!ptr) + { + static CDynamicFunctionOpenGL< true, const char *( APIENTRY *)( ), const char * > wglGetExtensionsStringEXT("wglGetExtensionsStringEXT"); + if (wglGetExtensionsStringEXT) + { + extensions = wglGetExtensionsStringEXT(); + ptr = strstr(extensions, ext); + } + + if (!ptr) + { + return false; + } + } + +#elif !defined ( OSX ) && !defined( __ANDROID__ ) +/* + if (!ptr) + { + static CDynamicFunctionOpenGL< true, Display *( APIENTRY *)( ), Display* > glXGetCurrentDisplay("glXGetCurrentDisplay"); + static CDynamicFunctionOpenGL< true, const char *( APIENTRY *)( Display*, int ), const char * > glXQueryExtensionsString("glXQueryExtensionsString"); + if (glXQueryExtensionsString && glXGetCurrentDisplay) + { + extensions = glXQueryExtensionsString(glXGetCurrentDisplay(), 0); + ptr = strstr(extensions, ext); + } + }*/ +#endif + + if (!ptr) + return false; + + // make sure this matches the entire string, and isn't a substring match of some other extension. + // if ( ( (string is at start of extension list) or (the char before the string is a space) ) and + // (the next char after the string is a space or a null terminator) ) + if ( ((ptr == extensions) || (ptr[-1] == ' ')) && + ((ptr[extlen] == ' ') || (ptr[extlen] == '\0')) ) + return true; // found it! + + extensions = ptr + extlen; // skip ahead, search again. + } + return false; +} + +static bool CheckOpenGLExtension(const char *ext, const int coremajor, const int coreminor) +{ + const bool retval = CheckOpenGLExtension_internal(ext, coremajor, coreminor); + printf("This system %s the OpenGL extension %s.\n", retval ? "supports" : "DOES NOT support", ext); + return retval; +} + +extern bool g_bUsePseudoBufs; +extern bool g_bDisableStaticBuffer; + +// The GL context you want entry points for must be current when you hit this constructor! +COpenGLEntryPoints::COpenGLEntryPoints() + : m_nTotalGLCycles(0) + , m_nTotalGLCalls(0) + , m_nOpenGLVersionMajor(GetOpenGLVersionMajor()) + , m_nOpenGLVersionMinor(GetOpenGLVersionMinor()) + , m_nOpenGLVersionPatch(GetOpenGLVersionPatch()) + , m_bHave_OpenGL(CheckBaseOpenGLVersion()) // may reset to false as these lookups happen. +#define GL_EXT(x,glmajor,glminor) , m_bHave_##x(CheckOpenGLExtension(#x, glmajor, glminor)) +#define GL_FUNC(ext,req,ret,fn,arg,call) , fn(#fn, m_bHave_##ext) +#define GL_FUNC_VOID(ext,req,fn,arg,call) , fn(#fn, m_bHave_##ext) +#include "togles/glfuncs.inl" +#undef GL_FUNC_VOID +#undef GL_FUNC +#undef GL_EXT +{ + // Locally cache the copy of the GL device strings, to avoid needing to call these glGet's (which can be extremely slow) more than once. + const char *pszString = ( const char * )glGetString(GL_VENDOR); + m_pGLDriverStrings[cGLVendorString] = strdup( pszString ? pszString : "" ); + + m_nDriverProvider = cGLDriverProviderUnknown; + if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "nvidia" ) ) + m_nDriverProvider = cGLDriverProviderNVIDIA; + else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "amd" ) || V_stristr( m_pGLDriverStrings[cGLVendorString], "ati" ) ) + m_nDriverProvider = cGLDriverProviderAMD; + else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "intel" ) ) + m_nDriverProvider = cGLDriverProviderIntelOpenSource; + else if ( V_stristr( m_pGLDriverStrings[cGLVendorString], "apple" ) ) + m_nDriverProvider = cGLDriverProviderApple; + + pszString = ( const char * )glGetString(GL_RENDERER); + m_pGLDriverStrings[cGLRendererString] = strdup( pszString ? pszString : "" ); + + pszString = ( const char * )glGetString(GL_VERSION); + m_pGLDriverStrings[cGLVersionString] = strdup( pszString ? pszString : "" ); + + pszString = ( const char * )glGetString(GL_EXTENSIONS); + m_pGLDriverStrings[cGLExtensionsString] = strdup( pszString ? pszString : "" ); + + printf( "OpenGL: %s %s (%d.%d.%d)\n", m_pGLDriverStrings[ cGLRendererString ], m_pGLDriverStrings[ cGLVersionString ], + m_nOpenGLVersionMajor, m_nOpenGLVersionMinor, m_nOpenGLVersionPatch ); + + // !!! FIXME: Alfred says the original GL_APPLE_fence code only exists to + // !!! FIXME: hint Apple's drivers and not because we rely on the + // !!! FIXME: functionality. If so, just remove this check (and the + // !!! FIXME: GL_NV_fence code entirely). + + // GL_ARB_framebuffer_object is a superset of GL_EXT_framebuffer_object, + // (etc) but if you don't call in through the ARB entry points, you won't + // get the relaxed restrictions on mismatched attachment dimensions. +// if (m_bHave_GL_ARB_framebuffer_object) + { + m_bHave_GL_EXT_framebuffer_object = true; + m_bHave_GL_EXT_framebuffer_blit = true; + m_bHave_GL_ARB_map_buffer_range = true; + m_bHave_GL_EXT_direct_state_access = false; + m_bHave_GL_ARB_occlusion_query = true; + m_bHave_GL_EXT_buffer_storage = false; + m_bHave_GL_ARB_vertex_buffer_object = true; + m_bHave_GL_ARB_debug_output = true; + m_bHave_GL_ARB_sync = true; + + // m_bHave_GL_EXT_texture_sRGB_decode = true; + + if( CommandLine()->FindParm( "-gl_enable_pseudobufs" ) ) + g_bUsePseudoBufs = true; + if( CommandLine()->FindParm( "-gl_enable_static_buffer" ) ) + g_bDisableStaticBuffer = false; + if( CommandLine()->FindParm( "-gl_enable_buffer_storage" ) ) + m_bHave_GL_EXT_buffer_storage = true; + +#if 0 + glBindFramebuffer.Force(glBindFramebuffer.Pointer()); + glBindRenderbuffer.Force(glBindRenderbuffer.Pointer()); + glCheckFramebufferStatus.Force(glCheckFramebufferStatus.Pointer()); + glDeleteRenderbuffers.Force(glDeleteRenderbuffers.Pointer()); + glFramebufferRenderbuffer.Force(glFramebufferRenderbuffer.Pointer()); + glFramebufferTexture2D.Force(glFramebufferTexture2D.Pointer()); + glFramebufferTexture3D.Force(glFramebufferTexture3D.Pointer()); + glGenFramebuffers.Force(glGenFramebuffers.Pointer()); + glGenRenderbuffers.Force(glGenRenderbuffers.Pointer()); + glDeleteFramebuffers.Force(glDeleteFramebuffers.Pointer()); + glBlitFramebuffer.Force(glBlitFramebuffer.Pointer()); + glRenderbufferStorageMultisample.Force(glRenderbufferStorageMultisample.Pointer()); +#endif + } + +#if DEBUG_ALL_GLCALLS + // push all GL calls through the debug wrappers. +#define GL_EXT(x,glmajor,glminor) +#define GL_FUNC(ext,req,ret,fn,arg,call) \ + fn##_gldebugptr = this->fn; \ +// this->fn.Force(fn##_gldebug); +#define GL_FUNC_VOID(ext,req,fn,arg,call) \ + fn##_gldebugptr = this->fn; \ +// this->fn.Force(fn##_gldebug); +#include "togles/glfuncs.inl" +#undef GL_FUNC_VOID +#undef GL_FUNC +#undef GL_EXT +#endif + +#ifdef OSX + m_bHave_GL_NV_bindless_texture = false; + m_bHave_GL_AMD_pinned_memory = false; +#else + if ( ( m_bHave_GL_NV_bindless_texture ) && ( !CommandLine()->CheckParm( "-gl_nv_bindless_texturing" ) ) ) + { + m_bHave_GL_NV_bindless_texture = false; +#if 0 + glGetTextureHandleNV.Force( NULL ); + glGetTextureSamplerHandleNV.Force( NULL ); + glMakeTextureHandleResidentNV.Force( NULL ); + glMakeTextureHandleNonResidentNV.Force( NULL ); + glUniformHandleui64NV.Force( NULL ); + glUniformHandleui64vNV.Force( NULL ); + glProgramUniformHandleui64NV.Force( NULL ); + glProgramUniformHandleui64vNV.Force( NULL ); + glIsTextureHandleResidentNV.Force( NULL ); +#endif + } + + if ( !CommandLine()->CheckParm( "-gl_amd_pinned_memory" ) ) + { + m_bHave_GL_AMD_pinned_memory = false; + } +#endif // !OSX + + // Getting reports of black screens, etc. with ARB_buffer_storage and AMD drivers. This type of thing: + // http://forums.steampowered.com/forums/showthread.php?t=3266806 + // So disable it for now. + if ( ( m_nDriverProvider == cGLDriverProviderAMD ) || CommandLine()->CheckParm( "-gl_disable_arb_buffer_storage" ) ) + { + m_bHave_GL_EXT_buffer_storage = false; + } + + printf( "GL_NV_bindless_texture: %s\n", m_bHave_GL_NV_bindless_texture ? "ENABLED" : "DISABLED" ); + printf( "GL_AMD_pinned_memory: %s\n", m_bHave_GL_AMD_pinned_memory ? "ENABLED" : "DISABLED" ); + printf( "GL_EXT_buffer_storage: %s\n", m_bHave_GL_EXT_buffer_storage ? "AVAILABLE" : "NOT AVAILABLE" ); + printf( "GL_EXT_texture_sRGB_decode: %s\n", m_bHave_GL_EXT_texture_sRGB_decode ? "AVAILABLE" : "NOT AVAILABLE" ); + +#ifdef OSX + if ( CommandLine()->FindParm( "-glmnosrgbdecode" ) ) + { + Msg( "Forcing m_bHave_GL_EXT_texture_sRGB_decode off.\n" ); + m_bHave_GL_EXT_texture_sRGB_decode = false; + } +#endif + +#ifndef OSX + if ( !m_bHave_GL_EXT_texture_sRGB_decode ) + { + Error( "Required OpenGL extension \"GL_EXT_texture_sRGB_decode\" is not supported. Please update your OpenGL driver.\n" ); + } +#endif +} + +COpenGLEntryPoints::~COpenGLEntryPoints() +{ + for ( uint i = 0; i < cGLTotalDriverProviders; ++i ) + { + free( m_pGLDriverStrings[i] ); + m_pGLDriverStrings[i] = NULL; + } +} + +void COpenGLEntryPoints::ClearEntryPoints() +{ + #define GL_EXT(x,glmajor,glminor) + #define GL_FUNC(ext,req,ret,fn,arg,call) fn.Force( NULL ); + #define GL_FUNC_VOID(ext,req,fn,arg,call) fn.Force( NULL ); + #include "togles/glfuncs.inl" + #undef GL_FUNC_VOID + #undef GL_FUNC + #undef GL_EXT +} +// Turn off memdbg macros (turned on up top) since this is included like a header +#include "tier0/memdbgoff.h" diff --git a/togles/linuxwin/glmgr.cpp b/togles/linuxwin/glmgr.cpp new file mode 100644 index 00000000..2e523cf9 --- /dev/null +++ b/togles/linuxwin/glmgr.cpp @@ -0,0 +1,5937 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glmgr.cpp +// +//=============================================================================== +#include "togles/rendermechanism.h" + +#include "tier0/icommandline.h" + +#include "tier0/vprof.h" +#include "glmtexinlines.h" + +#include "materialsystem/IShader.h" +#include "appframework/ilaunchermgr.h" + +#include "convar.h" + +#include "glmgr_flush.inl" + +#ifdef OSX +#include +#include "intelglmallocworkaround.h" +#endif + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + + +// Whether the code should use gl_arb_debug_output. This causes error messages to be streamed, via callback, to the application. +// It is much friendlier to the MTGL driver. +// NOTE: This can be turned off after launch, but it cannot be turned on after launch--it implies a context-creation-time +// behavior. +ConVar gl_debug_output( "gl_debug_output", "1" ); + + +// Whether or not we should batch up our creation and deletion behavior. +ConVar gl_batch_tex_creates( "gl_batch_tex_creates", "0" ); +ConVar gl_batch_tex_destroys( "gl_batch_tex_destroys", "0" ); + +//=============================================================================== + +// g_nTotalDrawsOrClears is reset to 0 in Present() +uint g_nTotalDrawsOrClears, g_nTotalVBLockBytes, g_nTotalIBLockBytes; + +#if GL_TELEMETRY_GPU_ZONES +TelemetryGPUStats_t g_TelemetryGPUStats; +#endif + +const int kGLMInitialTexCount = 4096; +const int kGLMReUpTexCount = 1024; +const int kGLMHighWaterUndeleted = 2048; +const int kDeletedTextureDim = 4; +const uint32 g_garbageTextureBits[ 4 * kDeletedTextureDim * kDeletedTextureDim ] = { 0 }; + +char g_nullFragmentProgramText [] = +{ + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 _gl_FragColor;\n" + "void main()\n" + "{\n" + "_gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n" + "}\n" +}; + +// make dummy programs for doing texture preload via dummy draw +char g_preloadTexVertexProgramText[] = // Гроб гроб кладбище пидор +{ + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 otex;\n" + "void main() \n" + "{\n" + "vec4 pos = vec4( 0.1, 0.1, 0.1, 0.1 );\n" + "vec4 tex = vec4( 0.0, 0.0, 0.0, 0.0 );\n" + "\n" + "gl_Position = pos;\n" + "otex = tex; \n" + "} \n" +}; + +char g_preload2DTexFragmentProgramText[] = +{ + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 _gl_FragColor;\n" + "in vec4 otex;\n" + "//SAMPLERMASK-8000 // may not be needed \n" + "//HIGHWATER-30 // may not be needed \n" + " \n" + "uniform vec4 pc[31]; \n" + "uniform sampler2D sampler15; \n" + " \n" + "void main() \n" + "{ \n" + "vec4 r0; \n" + "r0 = texture( sampler15, otex.xy ); \n" + "_gl_FragColor = r0; //discard; \n" + "} \n" +}; + +char g_preload3DTexFragmentProgramText[] = +{ + "#version 300 es\n" + "precision mediump float;\n" + "out vec4 _gl_FragColor;\n" + "in vec4 otex;\n" + "//SAMPLERMASK-8000 // may not be needed \n" + "//HIGHWATER-30 // may not be needed \n" + " \n" + "precision mediump sampler3D;\n" + "uniform vec4 pc[31]; \n" + "uniform sampler3D sampler15; \n" + " \n" + "void main() \n" + "{ \n" + "vec4 r0; \n" + "r0 = texture( sampler15, otex.xyz ); \n" + "_gl_FragColor = vec4(0,0,0,0); //discard; \n" + "} \n" +}; + +char g_preloadCubeTexFragmentProgramText[] = +{ + "#version 300 es\n" + "precision mediump float;\n" + "in vec4 otex;\n" + "out vec4 _gl_FragColor;\n" + "//SAMPLERMASK-8000 // may not be needed \n" + "//HIGHWATER-30 // may not be needed \n" + " \n" + "uniform vec4 pc[31]; \n" + "uniform samplerCube sampler15; \n" + " \n" + "void main() \n" + "{ \n" + "vec4 r0; \n" + "r0 = texture( sampler15, otex.xyz ); \n" + "_gl_FragColor = r0; //discard; \n" + "} \n" +}; + +const char* glSourceToString(GLenum source) +{ + switch (source) + { + case GL_DEBUG_SOURCE_API_ARB: return "API"; + case GL_DEBUG_SOURCE_WINDOW_SYSTEM_ARB: return "WINDOW_SYSTEM"; + case GL_DEBUG_SOURCE_SHADER_COMPILER_ARB: return "SHADER_COMPILER"; + case GL_DEBUG_SOURCE_THIRD_PARTY_ARB: return "THIRD_PARTY"; + case GL_DEBUG_SOURCE_APPLICATION_ARB: return "APPLICATION"; + case GL_DEBUG_SOURCE_OTHER_ARB: return "OTHER"; + default: break; + } + return "UNKNOWN"; +} + +const char* glTypeToString(GLenum type) +{ + switch (type) + { + case GL_DEBUG_TYPE_ERROR_ARB: return "ERROR"; + case GL_DEBUG_TYPE_DEPRECATED_BEHAVIOR_ARB: return "DEPRECATION"; + case GL_DEBUG_TYPE_UNDEFINED_BEHAVIOR_ARB: return "UNDEFINED_BEHAVIOR"; + case GL_DEBUG_TYPE_PORTABILITY_ARB: return "PORTABILITY"; + case GL_DEBUG_TYPE_PERFORMANCE_ARB: return "PERFORMANCE"; + case GL_DEBUG_TYPE_OTHER_ARB: return "OTHER"; + default: break; + } + return "UNKNOWN"; +} + +const char* glSeverityToString(GLenum severity) +{ + switch (severity) + { + case GL_DEBUG_SEVERITY_HIGH_ARB: return "HIGH"; + case GL_DEBUG_SEVERITY_MEDIUM_ARB: return "MEDIUM"; + case GL_DEBUG_SEVERITY_LOW_ARB: return "LOW"; + default: break; + } + return "UNKNOWN"; +} + +bool g_bDebugOutputBreakpoints = true; + +void APIENTRY GL_Debug_Output_Callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, GLvoid* userParam) +{ + const char *sSource = glSourceToString(source), + *sType = glTypeToString(type), + *sSeverity = glSeverityToString(severity); + + // According to NVidia, this error is a bug in the driver and not really an error (it's a warning in newer drivers): "Texture X is base level inconsistent. Check texture size" + if ( ( type == GL_DEBUG_TYPE_ERROR_ARB ) && strstr( message, "base level inconsistent" ) ) + { + return; + } + + if ( gl_debug_output.GetBool() || type == GL_DEBUG_TYPE_ERROR_ARB ) + { + Msg( "GL: [%s][%s][%s][%d]: %s\n", sSource, sType, sSeverity, id, message ); + } + +#ifdef WIN32 + OutputDebugStringA( message ); +#endif + + if ( ( type == GL_DEBUG_TYPE_ERROR_ARB ) && ( g_bDebugOutputBreakpoints ) ) + { +// DebuggerBreak(); + } +} + +void GLMDebugPrintf( const char *pMsg, ... ) +{ + //$ TODO: Should this call Warning()? + //$ TODO: Should replace call these calls with Warning() / Msg() / DevMsg()? + + va_list args; + va_start( args, pMsg ); + vprintf( pMsg, args ); + va_end( args ); +} + +//=============================================================================== +// functions that are dependant on g_pLauncherMgr + +inline bool MakeContextCurrent( PseudoGLContextPtr hContext ) +{ + return g_pLauncherMgr->MakeContextCurrent( hContext ); +} + +inline PseudoGLContextPtr GetMainContext() +{ + return g_pLauncherMgr->GetMainContext(); +} + +inline PseudoGLContextPtr GetGLContextForWindow( void* windowref ) +{ + return g_pLauncherMgr->GetGLContextForWindow( windowref ); +} + +inline void IncrementWindowRefCount() +{ + g_pLauncherMgr->IncWindowRefCount(); +} +inline void DecrementWindowRefCount() +{ + g_pLauncherMgr->DecWindowRefCount(); +} +inline void ShowPixels( CShowPixelsParams *params ) +{ + g_pLauncherMgr->ShowPixels(params); +} + +inline void DisplayedSize( uint &width, uint &height ) +{ + g_pLauncherMgr->DisplayedSize( width, height ); +} + +inline void GetDesiredPixelFormatAttribsAndRendererInfo( uint **ptrOut, uint *countOut, GLMRendererInfoFields *rendInfoOut ) +{ + g_pLauncherMgr->GetDesiredPixelFormatAttribsAndRendererInfo( ptrOut, countOut, rendInfoOut ); +} + +inline void GetStackCrawl( CStackCrawlParams *params ) +{ + g_pLauncherMgr->GetStackCrawl(params); +} + +#if GLMDEBUG +inline void PumpWindowsMessageLoop() +{ + g_pLauncherMgr->PumpWindowsMessageLoop(); +} +inline int GetEvents( CCocoaEvent *pEvents, int nMaxEventsToReturn, bool debugEvents = false ) +{ + return g_pLauncherMgr->GetEvents( pEvents, nMaxEventsToReturn, debugEvents ); +} +#endif + +//=============================================================================== +// helper routines for debug + +static bool hasnonzeros( float *values, int count ) +{ + for( int i=0; i [ %10.5f %10.5f %10.5f %10.5f ]", + baseSlotNumber+islot, + row[0],row[1],row[2],row[3], + col[0],col[1],col[2],col[3] + )); + } + else + { + if (islot<3) + { + GLMPRINTF(( "-D- %03d: [ %10.5f %10.5f %10.5f %10.5f ] T=> [ %10.5f %10.5f %10.5f ]", + baseSlotNumber+islot, + row[0],row[1],row[2],row[3], + col[0],col[1],col[2] + )); + } + else + { + GLMPRINTF(( "-D- %03d: T=> [ %10.5f %10.5f %10.5f ]", + baseSlotNumber+islot, + col[0],col[1],col[2] + )); + } + } + } + GLMPRINTSTR(("-D-")); + } + else + { + GLMPRINTF(("-D- %s - (all 0.0)", label )); + } + +} + + +static void transform_dp4( float *in4, float *m00, int slots, float *out4 ) +{ + // m00 points to a column. + // each DP is one column of the matrix ( m00[4*n] + // if we are passed a three slot matrix, this is three columns, the source W plays into all three columns, but we must set the final output W to 1 ? + for( int n=0; nm_nCurOwnerThreadId = ThreadGetCurrentId(); + if ( !MakeContextCurrent( context->m_ctx ) ) + { + // give up + GLMStop(); + } + Assert( 0 ); +#endif +} + +GLMContext *GLMgr::GetCurrentContext( void ) +{ +#if defined( USE_SDL ) + PseudoGLContextPtr context = GetMainContext(); + return (GLMContext*) context; +#else + Assert( 0 ); + return NULL; +#endif +} + + +// #define CHECK_THREAD_USAGE 1 + + +//=============================================================================== +// GLMContext public methods +void GLMContext::MakeCurrent( bool bRenderThread ) +{ + tmZone( TELEMETRY_LEVEL0, 0, "GLMContext::MakeCurrent" ); + Assert( m_nCurOwnerThreadId == 0 || m_nCurOwnerThreadId == ThreadGetCurrentId() ); + +#if defined( USE_SDL ) + +#ifndef CHECK_THREAD_USAGE + if ( bRenderThread ) + { +// Msg( "******************************************** %08x Acquiring Context\n", ThreadGetCurrentId() ); + m_nCurOwnerThreadId = ThreadGetCurrentId(); + bool bSuccess = MakeContextCurrent( m_ctx ); + if ( !bSuccess ) + { + Assert( 0 ); + } + } +#else + uint32 dwThreadId = ThreadGetCurrentId(); + + if ( bRenderThread || dwThreadId == m_dwRenderThreadId ) + { + m_nCurOwnerThreadId = ThreadGetCurrentId(); + m_dwRenderThreadId = dwThreadId; + MakeContextCurrent( m_ctx ); + m_bIsThreading = true; + } + else if ( !m_bIsThreading ) + { + m_nCurOwnerThreadId = ThreadGetCurrentId(); + MakeContextCurrent( m_ctx ); + } + else + { + Assert( 0 ); + } +#endif + +#else + Assert( 0 ); +#endif +} + + +void GLMContext::ReleaseCurrent( bool bRenderThread ) +{ + tmZone( TELEMETRY_LEVEL0, 0, "GLMContext::ReleaseCurrent" ); + Assert( m_nCurOwnerThreadId == ThreadGetCurrentId() ); + +#if defined( USE_SDL ) + +#ifndef CHECK_THREAD_USAGE + if ( bRenderThread ) + { +// Msg( "******************************************** %08x Releasing Context\n", ThreadGetCurrentId() ); + m_nCurOwnerThreadId = 0; + m_nThreadOwnershipReleaseCounter++; + MakeContextCurrent( NULL ); + } +#else + m_nCurOwnerThreadId = 0; + m_nThreadOwnershipReleaseCounter++; + MakeContextCurrent( NULL ); + if ( bRenderThread ) + { + m_bIsThreading = false; + } +#endif + +#else + Assert( 0 ); +#endif +} + + +// This function forces all GL state to be re-sent to the context. Some state will only be set on the next batch flush. +void GLMContext::ForceFlushStates() +{ + // Flush various render states + m_AlphaTestEnable.Flush(); + m_AlphaTestFunc.Flush(); + + m_DepthBias.Flush(); + + m_ScissorEnable.Flush(); + m_ScissorBox.Flush(); + + m_ViewportBox.Flush(); + m_ViewportDepthRange.Flush(); + + m_ColorMaskSingle.Flush(); + + m_BlendEnable.Flush(); + m_BlendFactor.Flush(); + + m_BlendEnableSRGB.Flush(); + + m_DepthTestEnable.Flush(); + m_DepthFunc.Flush(); + m_DepthMask.Flush(); + + m_StencilTestEnable.Flush(); + m_StencilFunc.Flush(); + m_StencilOp.Flush(); + m_StencilWriteMask.Flush(); + + m_ClearColor.Flush(); + m_ClearDepth.Flush(); + m_ClearStencil.Flush(); + + m_ClipPlaneEnable.Flush(); // always push clip state + m_ClipPlaneEquation.Flush(); + + m_CullFaceEnable.Flush(); + + m_CullFrontFace.Flush(); + + m_PolygonMode.Flush(); + + m_AlphaToCoverageEnable.Flush(); + m_ColorMaskMultiple.Flush(); + m_BlendEquation.Flush(); + m_BlendColor.Flush(); + // Reset various things so they get reset on the next batch flush + m_activeTexture = -1; + + for ( int i = 0; i < GLM_SAMPLER_COUNT; i++ ) + { + SetSamplerTex( i, m_samplers[i].m_pBoundTex ); + SetSamplerDirty( i ); + } + + // Attributes/vertex attribs + ClearCurAttribs(); + + m_lastKnownVertexAttribMask = 0; + m_nNumSetVertexAttributes = 16; + memset( &m_boundVertexAttribs[0], 0xFF, sizeof( m_boundVertexAttribs ) ); + for( int index=0; index < kGLMVertexAttributeIndexMax; index++ ) + gGL->glDisableVertexAttribArray( index ); + + // Program + NullProgram(); + + // FBO + BindFBOToCtx( m_boundReadFBO, GL_READ_FRAMEBUFFER ); + BindFBOToCtx( m_boundDrawFBO, GL_DRAW_FRAMEBUFFER ); + + // Current VB/IB/pinned memory buffers + gGL->glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, m_nBoundGLBuffer[ kGLMIndexBuffer] ); + gGL->glBindBuffer( GL_ARRAY_BUFFER, m_nBoundGLBuffer[ kGLMVertexBuffer] ); +} + +const GLMRendererInfoFields& GLMContext::Caps( void ) +{ + return m_caps; +} + +void GLMContext::DumpCaps( void ) +{ + /* + #define dumpfield( fff ) printf( "\n "#fff" : %d", (int) m_caps.fff ) + #define dumpfield_hex( fff ) printf( "\n "#fff" : 0x%08x", (int) m_caps.fff ) + #define dumpfield_str( fff ) printf( "\n "#fff" : %s", m_caps.fff ) + */ + + #define dumpfield( fff ) printf( "\n %-30s : %d", #fff, (int) m_caps.fff ) + #define dumpfield_hex( fff ) printf( "\n %-30s : 0x%08x", #fff, (int) m_caps.fff ) + #define dumpfield_str( fff ) printf( "\n %-30s : %s", #fff, m_caps.fff ) + + printf("\n-------------------------------- context caps for context %08x", (uint)this); + + dumpfield( m_fullscreen ); + dumpfield( m_accelerated ); + dumpfield( m_windowed ); + dumpfield_hex( m_rendererID ); + dumpfield( m_displayMask ); + dumpfield( m_bufferModes ); + dumpfield( m_colorModes ); + dumpfield( m_accumModes ); + dumpfield( m_depthModes ); + dumpfield( m_stencilModes ); + dumpfield( m_maxAuxBuffers ); + dumpfield( m_maxSampleBuffers ); + dumpfield( m_maxSamples ); + dumpfield( m_sampleModes ); + dumpfield( m_sampleAlpha ); + dumpfield_hex( m_vidMemory ); + dumpfield_hex( m_texMemory ); + + dumpfield_hex( m_pciVendorID ); + dumpfield_hex( m_pciDeviceID ); + dumpfield_str( m_pciModelString ); + dumpfield_str( m_driverInfoString ); + + printf( "\n m_osComboVersion: 0x%08x (%d.%d.%d)", m_caps.m_osComboVersion, (m_caps.m_osComboVersion>>16)&0xFF, (m_caps.m_osComboVersion>>8)&0xFF, (m_caps.m_osComboVersion)&0xFF ); + + dumpfield( m_ati ); + if (m_caps.m_ati) + { + dumpfield( m_atiR5xx ); + dumpfield( m_atiR6xx ); + dumpfield( m_atiR7xx ); + dumpfield( m_atiR8xx ); + dumpfield( m_atiNewer ); + } + + dumpfield( m_intel ); + if (m_caps.m_intel) + { + dumpfield( m_intel95x ); + dumpfield( m_intel3100 ); + dumpfield( m_intelHD4000 ); + } + + dumpfield( m_nv ); + if (m_caps.m_nv) + { + //dumpfield( m_nvG7x ); + dumpfield( m_nvG8x ); + dumpfield( m_nvNewer ); + } + + dumpfield( m_hasGammaWrites ); + dumpfield( m_hasMixedAttachmentSizes ); + dumpfield( m_hasBGRA ); + dumpfield( m_hasNewFullscreenMode ); + dumpfield( m_hasNativeClipVertexMode ); + dumpfield( m_maxAniso ); + + dumpfield( m_hasBindableUniforms ); + dumpfield( m_maxVertexBindableUniforms ); + dumpfield( m_maxFragmentBindableUniforms ); + dumpfield( m_maxBindableUniformSize ); + + dumpfield( m_hasUniformBuffers ); + dumpfield( m_hasPerfPackage1 ); + + dumpfield( m_cantBlitReliably ); + dumpfield( m_cantAttachSRGB ); + dumpfield( m_cantResolveFlipped ); + dumpfield( m_cantResolveScaled ); + dumpfield( m_costlyGammaFlips ); + dumpfield( m_badDriver1064NV ); + dumpfield( m_badDriver108Intel ); + + printf("\n--------------------------------"); + + #undef dumpfield + #undef dumpfield_hex + #undef dumpfield_str +} + +CGLMTex *GLMContext::NewTex( GLMTexLayoutKey *key, uint levels, const char *debugLabel ) +{ + // get a layout based on the key + GLMTexLayout *layout = m_texLayoutTable->NewLayoutRef( key ); + + CGLMTex *tex = new CGLMTex( this, layout, levels, debugLabel ); + + return tex; +} + +void GLMContext::DelTex( CGLMTex * tex ) +{ + //Queue the texture for deletion in ProcessTextureDeletes + //when we are sure we will hold the context. + m_DeleteTextureQueue.PushItem(tex); +} + +void GLMContext::ProcessTextureDeletes() +{ +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmEvent( "GLMContext::ProcessTextureDeletes" ); +#endif + + CGLMTex* tex = nullptr; + while ( m_DeleteTextureQueue.PopItem( &tex ) ) + { + for( int i = 0; i < GLM_SAMPLER_COUNT; i++) + { + if ( m_samplers[i].m_pBoundTex == tex ) + { + BindTexToTMU( NULL, i ); + } + } + + if ( tex->m_rtAttachCount != 0 ) + { + // RG - huh? wtf? TODO: fix this code which seems to be purposely leaking + // leak it and complain - we may have to implement a deferred-delete system for tex like these + + GLMDebugPrintf("GLMContext::DelTex: Leaking tex %08x [ %s ] - was attached for drawing at time of delete",tex, tex->m_layout->m_layoutSummary ); + + #if 0 + // can't actually do this yet as the draw calls will tank + FOR_EACH_VEC( m_fboTable, i ) + { + CGLMFBO *fbo = m_fboTable[i]; + fbo->TexScrub( tex ); + } + tex->m_rtAttachCount = 0; + #endif + } + else + { + delete tex; + } + } +} + +// push and pop attrib when blit has mixed srgb source and dest? +ConVar gl_radar7954721_workaround_mixed ( "gl_radar7954721_workaround_mixed", "1" ); + +// push and pop attrib on any blit? +ConVar gl_radar7954721_workaround_all ( "gl_radar7954721_workaround_all", "0" ); + +// what attrib mask to use ? +ConVar gl_radar7954721_workaround_maskval ( "gl_radar7954721_workaround_maskval", "0" ); + +enum eBlitFormatClass +{ + eColor, + eDepth, // may not get used. not sure.. + eDepthStencil +}; + +uint glAttachFromClass[ 3 ] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, GL_DEPTH_STENCIL_ATTACHMENT }; + +void glScrubFBO ( GLenum target ) +{ + gGL->glFramebufferRenderbuffer ( target, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0); + gGL->glFramebufferRenderbuffer ( target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + gGL->glFramebufferRenderbuffer ( target, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + + gGL->glFramebufferTexture2D ( target, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0 ); + gGL->glFramebufferTexture2D ( target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0 ); + gGL->glFramebufferTexture2D ( target, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0 ); +} + +void glAttachRBOtoFBO ( GLenum target, eBlitFormatClass formatClass, uint rboName ) +{ + switch( formatClass ) + { + case eColor: + gGL->glFramebufferRenderbuffer ( target, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rboName); + break; + + case eDepth: + gGL->glFramebufferRenderbuffer ( target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboName); + break; + + case eDepthStencil: + gGL->glFramebufferRenderbuffer ( target, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rboName); + gGL->glFramebufferRenderbuffer ( target, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rboName); + break; + } +} + +void glAttachTex2DtoFBO ( GLenum target, eBlitFormatClass formatClass, uint texName, uint texMip ) +{ + switch( formatClass ) + { + case eColor: + gGL->glFramebufferTexture2D ( target, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texName, texMip ); + break; + + case eDepth: + gGL->glFramebufferTexture2D ( target, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, texName, texMip ); + break; + + case eDepthStencil: + gGL->glFramebufferTexture2D ( target, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, texName, texMip ); + break; + } +} + +ConVar gl_can_resolve_flipped("gl_can_resolve_flipped", "0" ); +ConVar gl_cannot_resolve_flipped("gl_cannot_resolve_flipped", "0" ); + +// these are only consulted if the m_cant_resolve_scaled cap bool is false. + +ConVar gl_minify_resolve_mode("gl_minify_resolve_mode", "1" ); // if scaled resolve available, for downscaled resolve blits only (i.e. internal blits) +ConVar gl_magnify_resolve_mode("gl_magnify_resolve_mode", "2" ); // if scaled resolve available, for upscaled resolve blits only + + // 0 == old style, two steps + // 1 == faster, one step blit aka XGL_SCALED_RESOLVE_FASTEST_EXT - if available. + // 2 == faster, one step blit aka XGL_SCALED_RESOLVE_NICEST_EXT - if available. + +void GLMContext::SaveColorMaskAndSetToDefault() +{ + // NVidia's driver doesn't ignore the colormask during blitframebuffer calls, so we need to save/restore it: + // “The bug here is that our driver fails to ignore colormask for BlitFramebuffer calls. This was unclear in the original spec, but we resolved it in Khronos last year (https://cvs.khronos.org/bugzilla/show_bug.cgi?id=7969).†+ m_ColorMaskSingle.Read( &m_SavedColorMask, 0 ); + + GLColorMaskSingle_t newColorMask; + newColorMask.r = newColorMask.g = newColorMask.b = newColorMask.a = -1; + m_ColorMaskSingle.Write( &newColorMask ); +} + +void GLMContext::RestoreSavedColorMask() +{ + m_ColorMaskSingle.Write( &m_SavedColorMask ); +} + +void GLMContext::Blit2( CGLMTex *srcTex, GLMRect *srcRect, int srcFace, int srcMip, CGLMTex *dstTex, GLMRect *dstRect, int dstFace, int dstMip, uint filter ) +{ +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmPIXEvent( "Blit2" ); + g_TelemetryGPUStats.m_nTotalBlit2++; +#endif + + SaveColorMaskAndSetToDefault(); + + Assert( srcFace == 0 ); + Assert( dstFace == 0 ); + + //----------------------------------------------------------------- format assessment + + eBlitFormatClass formatClass = eColor; + uint blitMask= 0; + + switch( srcTex->m_layout->m_format->m_glDataFormat ) + { + case GL_RED: case GL_BGRA: case GL_RGB: case GL_RGBA: case GL_ALPHA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: + formatClass = eColor; + blitMask = GL_COLOR_BUFFER_BIT; + break; + + case GL_DEPTH_COMPONENT: + formatClass = eDepth; + blitMask = GL_DEPTH_BUFFER_BIT; + break; + + case GL_DEPTH_STENCIL: + formatClass = eDepthStencil; + blitMask = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + break; + + default: + Assert(!"Unsupported format for blit" ); + GLMStop(); + break; + } + + //----------------------------------------------------------------- blit assessment + + + bool blitResolves = srcTex->m_rboName != 0; + bool blitScales = ((srcRect->xmax - srcRect->xmin) != (dstRect->xmax - dstRect->xmin)) || ((srcRect->ymax - srcRect->ymin) != (dstRect->ymax - dstRect->ymin)); + + bool blitToBack = (dstTex == NULL); + bool blitFlips = blitToBack; // implicit y-flip upon blit to GL_BACK supplied + + //should we support blitFromBack ? + + bool srcGamma = srcTex && ((srcTex->m_layout->m_key.m_texFlags & kGLMTexSRGB) != 0); + bool dstGamma = dstTex && ((dstTex->m_layout->m_key.m_texFlags & kGLMTexSRGB) != 0); + + //----------------------------------------------------------------- figure out the plan + + bool blitTwoStep = false; // think positive + + // each subsequent segment here can only set blitTwoStep, not clear it. + // the common case where these get hit is resolve out to presentation + // there may be GL extensions or driver revisions which start doing these safely. + // ideally many blits internally resolve without scaling and can thus go direct without using the scratch tex. + + if (blitResolves && (blitFlips||blitToBack)) // flips, blit to back, same thing (for now) + { + if( gl_cannot_resolve_flipped.GetInt() ) + { + blitTwoStep = true; + } + else if (!gl_can_resolve_flipped.GetInt()) + { + blitTwoStep = blitTwoStep || m_caps.m_cantResolveFlipped; // if neither convar renders an opinion, fall back to the caps to decide if we have to two-step. + } + } + + // only consider trying to use the scaling resolve filter, + // if we are confident we are not headed for two step mode already. + if (!blitTwoStep) + { + if (blitResolves && blitScales) + { + if (m_caps.m_cantResolveScaled) + { + // filter is unchanged, two step mode switches on + blitTwoStep = true; + } + else + { + bool blitScalesDown = ((srcRect->xmax - srcRect->xmin) > (dstRect->xmax - dstRect->xmin)) || ((srcRect->ymax - srcRect->ymin) > (dstRect->ymax - dstRect->ymin)); + int mode = (blitScalesDown) ? gl_minify_resolve_mode.GetInt() : gl_magnify_resolve_mode.GetInt(); + + // roughly speaking, resolve blits that minify represent setup for special effects ("copy framebuffer to me") + // resolve blits that magnify are almost always on the final present in the case where remder size < display size + + switch( mode ) + { + case 0: + default: + // filter is unchanged, two step mode + blitTwoStep = true; + break; + + case 1: + // filter goes to fastest, one step mode + blitTwoStep = false; + filter = XGL_SCALED_RESOLVE_FASTEST_EXT; + break; + + case 2: + // filter goes to nicest, one step mode + blitTwoStep = false; + filter = XGL_SCALED_RESOLVE_NICEST_EXT; + break; + } + } + } + } + + //----------------------------------------------------------------- save old scissor state and disable scissor + GLScissorEnable_t oldsciss,newsciss; + m_ScissorEnable.Read( &oldsciss, 0 ); + + if (oldsciss.enable) + { + // turn off scissor + newsciss.enable = false; + m_ScissorEnable.Write( &newsciss ); + } + + //----------------------------------------------------------------- fork in the road, depending on two-step or not + if (blitTwoStep) + { + // a resolve that can't be done directly due to constraints on scaling or flipping. + + // bind scratch FBO0 to read, scrub it, attach RBO + BindFBOToCtx ( m_scratchFBO[0], GL_READ_FRAMEBUFFER ); + glScrubFBO ( GL_READ_FRAMEBUFFER ); + glAttachRBOtoFBO ( GL_READ_FRAMEBUFFER, formatClass, srcTex->m_rboName ); + + // bind scratch FBO1 to write, scrub it, attach scratch tex + BindFBOToCtx ( m_scratchFBO[1], GL_DRAW_FRAMEBUFFER ); + glScrubFBO ( GL_DRAW_FRAMEBUFFER ); + glAttachTex2DtoFBO ( GL_DRAW_FRAMEBUFFER, formatClass, srcTex->m_texName, 0 ); + + // set read and draw buffers appropriately + gGL->glReadBuffer( glAttachFromClass[formatClass] ); + gGL->glDrawBuffers( 1, &glAttachFromClass[formatClass] ); + + // blit#1 - to resolve to scratch + // implicitly means no scaling, thus will be done with NEAREST sampling + + GLenum resolveFilter = GL_NEAREST; + + gGL->glBlitFramebuffer( 0, 0, srcTex->m_layout->m_key.m_xSize, srcTex->m_layout->m_key.m_ySize, + 0, 0, srcTex->m_layout->m_key.m_xSize, srcTex->m_layout->m_key.m_ySize, // same source and dest rect, whole surface + blitMask, resolveFilter ); + + // FBO1 now holds the interesting content. + // scrub FBO0, bind FBO1 to READ, fall through to next stage of blit where 1 goes onto 0 (or BACK) + + glScrubFBO ( GL_READ_FRAMEBUFFER ); // zap FBO0 + BindFBOToCtx ( m_scratchFBO[1], GL_READ_FRAMEBUFFER ); + + srcTex->ForceRBONonDirty(); + } + else + { +#if 1 + if (srcTex->m_pBlitSrcFBO == NULL) + { + srcTex->m_pBlitSrcFBO = NewFBO(); + BindFBOToCtx( srcTex->m_pBlitSrcFBO, GL_READ_FRAMEBUFFER ); + if (blitResolves) + { + glAttachRBOtoFBO( GL_READ_FRAMEBUFFER, formatClass, srcTex->m_rboName ); + } + else + { + glAttachTex2DtoFBO( GL_READ_FRAMEBUFFER, formatClass, srcTex->m_texName, srcMip ); + } + } + else + { + BindFBOToCtx ( srcTex->m_pBlitSrcFBO, GL_READ_FRAMEBUFFER ); + // GLMCheckError(); + } +#else + // arrange source surface on FBO1 for blit directly to dest (which could be FBO0 or BACK) + BindFBOToCtx( m_scratchFBO[1], GL_READ_FRAMEBUFFER ); + glScrubFBO( GL_READ_FRAMEBUFFER ); + GLMCheckError(); + if (blitResolves) + { + glAttachRBOtoFBO( GL_READ_FRAMEBUFFER, formatClass, srcTex->m_rboName ); + } + else + { + glAttachTex2DtoFBO( GL_READ_FRAMEBUFFER, formatClass, srcTex->m_texName, srcMip ); + } +#endif + + gGL->glReadBuffer( glAttachFromClass[formatClass] ); + } + + //----------------------------------------------------------------- zero or one blits may have happened above, whichever took place, FBO1 is now on read + + bool yflip = false; + if (blitToBack) + { + // backbuffer is special - FBO0 is left out (either scrubbed already, or not used) + + BindFBOToCtx( NULL, GL_DRAW_FRAMEBUFFER ); + + GLenum bufs = GL_BACK; + gGL->glDrawBuffers( 1, &bufs ); + + yflip = true; + } + else + { + // not going to GL_BACK - use FBO0. set up dest tex or RBO on it. i.e. it's OK to blit from MSAA to MSAA if needed, though unlikely. + Assert( dstTex != NULL ); +#if 1 + if (dstTex->m_pBlitDstFBO == NULL) + { + dstTex->m_pBlitDstFBO = NewFBO(); + BindFBOToCtx( dstTex->m_pBlitDstFBO, GL_DRAW_FRAMEBUFFER ); + if (dstTex->m_rboName) + { + glAttachRBOtoFBO( GL_DRAW_FRAMEBUFFER, formatClass, dstTex->m_rboName ); + } + else + { + glAttachTex2DtoFBO( GL_DRAW_FRAMEBUFFER, formatClass, dstTex->m_texName, dstMip ); + } + } + else + { + BindFBOToCtx( dstTex->m_pBlitDstFBO, GL_DRAW_FRAMEBUFFER ); + } +#else + BindFBOToCtx( m_scratchFBO[0], GL_DRAW_FRAMEBUFFER ); GLMCheckError(); + glScrubFBO( GL_DRAW_FRAMEBUFFER ); + + if (dstTex->m_rboName) + { + glAttachRBOtoFBO( GL_DRAW_FRAMEBUFFER, formatClass, dstTex->m_rboName ); + } + else + { + glAttachTex2DtoFBO( GL_DRAW_FRAMEBUFFER, formatClass, dstTex->m_texName, dstMip ); + } + + gGL->glDrawBuffer ( glAttachFromClass[formatClass] ); GLMCheckError(); +#endif + } + + // final blit + + // i think in general, if we are blitting same size, gl_nearest is the right filter to pass. + // this re-steering won't kick in if there is scaling or a special scaled resolve going on. + if (!blitScales) + { + // steer it + filter = GL_NEAREST; + } + + // this is blit #1 or #2 depending on what took place above. + if (yflip) + { + gGL->glBlitFramebuffer( srcRect->xmin, srcRect->ymin, srcRect->xmax, srcRect->ymax, + dstRect->xmin, dstRect->ymax, dstRect->xmax, dstRect->ymin, // note dest Y's are flipped + blitMask, filter ); + } + else + { + gGL->glBlitFramebuffer( srcRect->xmin, srcRect->ymin, srcRect->xmax, srcRect->ymax, + dstRect->xmin, dstRect->ymin, dstRect->xmax, dstRect->ymax, + blitMask, filter ); + } + + //----------------------------------------------------------------- scrub READ and maybe DRAW FBO, and unbind + +// glScrubFBO ( GL_READ_FRAMEBUFFER ); + BindFBOToCtx ( NULL, GL_READ_FRAMEBUFFER ); + if (!blitToBack) + { +// glScrubFBO ( GL_DRAW_FRAMEBUFFER ); + BindFBOToCtx ( NULL, GL_DRAW_FRAMEBUFFER ); + } + + //----------------------------------------------------------------- restore GLM's drawing FBO + + // restore GLM drawing FBO + BindFBOToCtx( m_drawingFBO, GL_FRAMEBUFFER ); + + //----------------------------------------------------------------- restore old scissor state + if (oldsciss.enable) + { + m_ScissorEnable.Write( &oldsciss ); + } + + RestoreSavedColorMask(); +} + + +void GLMContext::BlitTex( CGLMTex *srcTex, GLMRect *srcRect, int srcFace, int srcMip, CGLMTex *dstTex, GLMRect *dstRect, int dstFace, int dstMip, GLenum filter, bool useBlitFB ) +{ + // This path doesn't work anymore (or did it ever work in the L4D2 Linux branch?) + DXABSTRACT_BREAK_ON_ERROR(); + return; + + SaveColorMaskAndSetToDefault(); + + switch( srcTex->m_layout->m_format->m_glDataFormat ) + { + case GL_BGRA: + case GL_RGB: + case GL_RGBA: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + #if 0 + if (GLMKnob("caps-key",NULL) > 0.0) + { + useBlitFB = false; + } + #endif + + if ( m_caps.m_cantBlitReliably ) // this is referring to a problem with the x3100.. + { + useBlitFB = false; + } + break; + } + + if (0) + { + GLMPRINTF(("-D- Blit from %d %d %d %d to %d %d %d %d", + srcRect->xmin, srcRect->ymin, srcRect->xmax, srcRect->ymax, + dstRect->xmin, dstRect->ymin, dstRect->xmax, dstRect->ymax + )); + + GLMPRINTF(( "-D- src tex layout is %s", srcTex->m_layout->m_layoutSummary )); + GLMPRINTF(( "-D- dst tex layout is %s", dstTex->m_layout->m_layoutSummary )); + } + + if (useBlitFB) + { + // state we need to save + // current setting of scissor + // current setting of the drawing fbo (no explicit save, it's in the context) + GLScissorEnable_t oldsciss,newsciss; + m_ScissorEnable.Read( &oldsciss, 0 ); + + // remember to restore m_drawingFBO at end of effort + + // setup + // turn off scissor + newsciss.enable = false; + m_ScissorEnable.Write( &newsciss ); + + // select which attachment enum we're going to use for the blit + // default to color0, unless it's a depth or stencil flava + + Assert( srcTex->m_layout->m_format->m_glDataFormat == dstTex->m_layout->m_format->m_glDataFormat ); + + EGLMFBOAttachment attachIndex = (EGLMFBOAttachment)0; + GLenum attachIndexGL = 0; + GLuint blitMask = 0; + switch( srcTex->m_layout->m_format->m_glDataFormat ) + { + case GL_BGRA: + case GL_RGB: + case GL_RGBA: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + attachIndex = kAttColor0; + attachIndexGL = GL_COLOR_ATTACHMENT0; + blitMask = GL_COLOR_BUFFER_BIT; + break; + + case GL_DEPTH_COMPONENT: + attachIndex = kAttDepth; + attachIndexGL = GL_DEPTH_ATTACHMENT; + blitMask = GL_DEPTH_BUFFER_BIT; + break; + + case GL_DEPTH_STENCIL: + attachIndex = kAttDepthStencil; + attachIndexGL = GL_DEPTH_STENCIL_ATTACHMENT; + blitMask = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + break; + + default: + Assert(0); + break; + } + + // set the read fb, attach read tex at appropriate attach point, set read buffer + BindFBOToCtx( m_blitReadFBO, GL_READ_FRAMEBUFFER ); + + GLMFBOTexAttachParams attparams; + attparams.m_tex = srcTex; + attparams.m_face = srcFace; + attparams.m_mip = srcMip; + attparams.m_zslice = 0; + m_blitReadFBO->TexAttach( &attparams, attachIndex, GL_READ_FRAMEBUFFER ); + + gGL->glReadBuffer( attachIndexGL ); + + // set the write fb and buffer, and attach write tex + BindFBOToCtx( m_blitDrawFBO, GL_DRAW_FRAMEBUFFER ); + + attparams.m_tex = dstTex; + attparams.m_face = dstFace; + attparams.m_mip = dstMip; + attparams.m_zslice = 0; + m_blitDrawFBO->TexAttach( &attparams, attachIndex, GL_DRAW_FRAMEBUFFER ); + + gGL->glDrawBuffers( 1, &attachIndexGL ); + + // do the blit + gGL->glBlitFramebuffer( srcRect->xmin, srcRect->ymin, srcRect->xmax, srcRect->ymax, + dstRect->xmin, dstRect->ymin, dstRect->xmax, dstRect->ymax, + blitMask, filter ); + + // cleanup + // unset the read fb and buffer, detach read tex + // unset the write fb and buffer, detach write tex + + m_blitReadFBO->TexDetach( attachIndex, GL_READ_FRAMEBUFFER ); + + m_blitDrawFBO->TexDetach( attachIndex, GL_DRAW_FRAMEBUFFER ); + + // put the original FB back in place (both read and draw) + // this bind will hit both read and draw bindings + BindFBOToCtx( m_drawingFBO, GL_FRAMEBUFFER ); + + // set the read and write buffers back to... what ? does it matter for anything but copies ? don't worry about it + + // restore the scissor state + m_ScissorEnable.Write( &oldsciss ); + } + else + { + // textured quad style + + // we must attach the dest tex as the color buffer on the blit draw FBO + // so that means we need to re-set the drawing FBO on exit + + EGLMFBOAttachment attachIndex = (EGLMFBOAttachment)0; + GLenum attachIndexGL = 0; + switch( srcTex->m_layout->m_format->m_glDataFormat ) + { + case GL_BGRA: + case GL_RGB: + case GL_RGBA: + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + attachIndex = kAttColor0; + attachIndexGL = GL_COLOR_ATTACHMENT0; + break; + + default: + Assert(!"Can't blit that format"); + break; + } + + BindFBOToCtx( m_blitDrawFBO, GL_DRAW_FRAMEBUFFER ); + + GLMFBOTexAttachParams attparams; + attparams.m_tex = dstTex; + attparams.m_face = dstFace; + attparams.m_mip = dstMip; + attparams.m_zslice = 0; + m_blitDrawFBO->TexAttach( &attparams, attachIndex, GL_DRAW_FRAMEBUFFER ); + + gGL->glDrawBuffers( 1, &attachIndexGL ); + + // attempt to just set states directly the way we want them, then use the latched states to repair them afterward. + NullProgram(); // out of program mode + + gGL->glDisable ( GL_ALPHA_TEST ); + gGL->glDisable ( GL_CULL_FACE ); + gGL->glDisable ( GL_POLYGON_OFFSET_FILL ); + gGL->glDisable ( GL_SCISSOR_TEST ); + + gGL->glDisable ( GL_CLIP_PLANE0 ); + gGL->glDisable ( GL_CLIP_PLANE1 ); + + gGL->glColorMask( GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE ); + gGL->glDisable ( GL_BLEND ); + + gGL->glDepthMask ( GL_FALSE ); + gGL->glDisable ( GL_DEPTH_TEST ); + + gGL->glDisable ( GL_STENCIL_TEST ); + gGL->glStencilMask ( GL_FALSE ); + + + // now do the unlit textured quad... + gGL->glActiveTexture( GL_TEXTURE0 ); + gGL->glBindTexture( GL_TEXTURE_2D, srcTex->m_texName ); + + gGL->glEnable(GL_TEXTURE_2D); + + // immediate mode is fine + +#if 0 // Does it needed? + const float topv = 1.0; + const float botv = 0.0; + + const float verts[] = {-1.f, -1.f, 1.f, -1.f, 1.f, 1.f, -1.f, 1.f}; + const float verts_tex[] = {0.f, botv, 1.f, botv, 1.f, topv, 0.f, topv}; + + gGL->glVertexPointer(2, GL_FLOAT, 0, verts); + gGL->glTexCoordPointer(2, GL_FLOAT, 0, verts_tex); + + gGL->glDrawArrays(GL_TRIANGLE_FAN, 0, 4); + + gGL->glDisableClientState(GL_VERTEX_ARRAY); + gGL->glDisableClientState(GL_TEXTURE_COORD_ARRAY); +#endif + + gGL->glBindTexture( GL_TEXTURE_2D, 0 ); + + gGL->glDisable(GL_TEXTURE_2D); + + BindTexToTMU( m_samplers[0].m_pBoundTex, 0 ); + + // leave active program empty - flush draw states will fix + + // then restore states using the scoreboard + + m_AlphaTestEnable.Flush(); + m_AlphaToCoverageEnable.Flush(); + m_CullFaceEnable.Flush(); + m_DepthBias.Flush(); + m_ScissorEnable.Flush(); + + m_ClipPlaneEnable.FlushIndex( 0 ); + m_ClipPlaneEnable.FlushIndex( 1 ); + + m_ColorMaskSingle.Flush(); + m_BlendEnable.Flush(); + + m_DepthMask.Flush(); + m_DepthTestEnable.Flush(); + + m_StencilWriteMask.Flush(); + m_StencilTestEnable.Flush(); + + // unset the write fb and buffer, detach write tex + + m_blitDrawFBO->TexDetach( attachIndex, GL_DRAW_FRAMEBUFFER ); + + // put the original FB back in place (both read and draw) + BindFBOToCtx( m_drawingFBO, GL_FRAMEBUFFER ); + } + + RestoreSavedColorMask(); +} + +void GLMContext::ResolveTex( CGLMTex *tex, bool forceDirty ) +{ +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmPIXEvent( "ResolveTex" ); + g_TelemetryGPUStats.m_nTotalResolveTex++; +#endif + + // only run resolve if it's (a) possible and (b) dirty or force-dirtied + if ( ( tex->m_rboName ) && ( tex->IsRBODirty() || forceDirty ) ) + { + // state we need to save + // current setting of scissor + // current setting of the drawing fbo (no explicit save, it's in the context) + GLScissorEnable_t oldsciss,newsciss; + m_ScissorEnable.Read( &oldsciss, 0 ); + + // remember to restore m_drawingFBO at end of effort + + // setup + // turn off scissor + newsciss.enable = false; + m_ScissorEnable.Write( &newsciss ); + + // select which attachment enum we're going to use for the blit + // default to color0, unless it's a depth or stencil flava + + // for resolve, only handle a modest subset of the possible formats + EGLMFBOAttachment attachIndex = (EGLMFBOAttachment)0; + GLenum attachIndexGL = 0; + GLuint blitMask = 0; + switch( tex->m_layout->m_format->m_glDataFormat ) + { + case GL_BGRA: + case GL_RGB: + case GL_RGBA: + // case GL_ALPHA: + // case GL_LUMINANCE: + // case GL_LUMINANCE_ALPHA: + attachIndex = kAttColor0; + attachIndexGL = GL_COLOR_ATTACHMENT0; + blitMask = GL_COLOR_BUFFER_BIT; + break; + + // case GL_DEPTH_COMPONENT: + // attachIndex = kAttDepth; + // attachIndexGL = GL_DEPTH_ATTACHMENT; + // blitMask = GL_DEPTH_BUFFER_BIT; + // break; + + case GL_DEPTH_STENCIL: + attachIndex = kAttDepthStencil; + attachIndexGL = GL_DEPTH_STENCIL_ATTACHMENT; + blitMask = GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT; + break; + + default: + Assert(!"Unsupported format for MSAA resolve" ); + break; + } + + + // set the read fb, attach read RBO at appropriate attach point, set read buffer + BindFBOToCtx( m_blitReadFBO, GL_READ_FRAMEBUFFER ); + + // going to avoid the TexAttach / TexDetach calls due to potential confusion, implement it directly here + + //----------------------------------------------------------------------------------- + // put tex->m_rboName on the read FB's attachment + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + // you have to attach it both places... + // http://www.opengl.org/wiki/GL_EXT_framebuffer_object + + // bind the RBO to the GL_RENDERBUFFER target - is this extraneous ? + //glBindRenderbufferEXT( GL_RENDERBUFFER, tex->m_rboName ); + + // attach the GL_RENDERBUFFER target to the depth and stencil attach points + gGL->glFramebufferRenderbuffer( GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, tex->m_rboName); + + gGL->glFramebufferRenderbuffer( GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, tex->m_rboName); + + // no need to leave the RBO hanging on + //glBindRenderbufferEXT( GL_RENDERBUFFER, 0 ); + } + else + { + //glBindRenderbufferEXT( GL_RENDERBUFFER, tex->m_rboName ); + + gGL->glFramebufferRenderbuffer( GL_READ_FRAMEBUFFER, attachIndexGL, GL_RENDERBUFFER, tex->m_rboName); + + //glBindRenderbufferEXT( GL_RENDERBUFFER, 0 ); + } + + gGL->glReadBuffer( attachIndexGL ); + + //----------------------------------------------------------------------------------- + // put tex->m_texName on the draw FBO attachment + + // set the write fb and buffer, and attach write tex + BindFBOToCtx( m_blitDrawFBO, GL_DRAW_FRAMEBUFFER ); + + // regular path - attaching a texture2d + + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + gGL->glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, tex->m_texName, 0 ); + + gGL->glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, tex->m_texName, 0 ); + } + else + { + gGL->glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, attachIndexGL, GL_TEXTURE_2D, tex->m_texName, 0 ); + } + + gGL->glDrawBuffers( 1, &attachIndexGL ); + + //----------------------------------------------------------------------------------- + + // blit + gGL->glBlitFramebuffer( 0, 0, tex->m_layout->m_key.m_xSize, tex->m_layout->m_key.m_ySize, + 0, 0, tex->m_layout->m_key.m_xSize, tex->m_layout->m_key.m_ySize, + blitMask, GL_NEAREST ); + // or should it be GL_LINEAR? does it matter ? + + //----------------------------------------------------------------------------------- + // cleanup + //----------------------------------------------------------------------------------- + + + // unset the read fb and buffer, detach read RBO + //glBindRenderbufferEXT( GL_RENDERBUFFER, 0 ); + + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + // detach the GL_RENDERBUFFER target from the depth and stencil attach points + gGL->glFramebufferRenderbuffer( GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0); + gGL->glFramebufferRenderbuffer( GL_READ_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, 0); + } + else + { + gGL->glFramebufferRenderbuffer( GL_READ_FRAMEBUFFER, attachIndexGL, GL_RENDERBUFFER, 0); + } + + //----------------------------------------------------------------------------------- + // unset the write fb and buffer, detach write tex + + + if (attachIndexGL==GL_DEPTH_STENCIL_ATTACHMENT) + { + gGL->glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, 0, 0 ); + + gGL->glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0 ); + } + else + { + gGL->glFramebufferTexture2D( GL_DRAW_FRAMEBUFFER, attachIndexGL, GL_TEXTURE_2D, 0, 0 ); + } + + // put the original FB back in place (both read and draw) + // this bind will hit both read and draw bindings + BindFBOToCtx( m_drawingFBO, GL_FRAMEBUFFER ); + + // set the read and write buffers back to... what ? does it matter for anything but copies ? don't worry about it + + // restore the scissor state + m_ScissorEnable.Write( &oldsciss ); + + // mark the RBO clean on the resolved tex + tex->ForceRBONonDirty(); + } +} + +void GLMContext::PreloadTex( CGLMTex *tex, bool force ) +{ + // if conditions allow (i.e. a drawing surface is active) + // bind the texture on TMU 15 + // set up a dummy program to sample it but not write (use 'discard') + // draw a teeny little triangle that won't generate a lot of fragments + if (!m_pairCache) + return; + + if (!m_drawingFBO) + return; + + if (tex->m_texPreloaded && !force) // only do one preload unless forced to re-do + { + //printf("\nnot-preloading %s", tex->m_debugLabel ? tex->m_debugLabel : "(unknown)"); + return; + } + + //printf("\npreloading %s", tex->m_debugLabel ? tex->m_debugLabel : "(unknown)"); + + CGLMProgram *vp = m_preloadTexVertexProgram; + CGLMProgram *fp = NULL; + switch(tex->m_layout->m_key.m_texGLTarget) + { + case GL_TEXTURE_2D: fp = m_preload2DTexFragmentProgram; + break; + + case GL_TEXTURE_3D: fp = m_preload3DTexFragmentProgram; + break; + + case GL_TEXTURE_CUBE_MAP: fp = m_preloadCubeTexFragmentProgram; + break; + } + if (!fp) + return; + + CGLMShaderPair *preloadPair = m_pairCache->SelectShaderPair( vp, fp, 0 ); + if (!preloadPair) + return; + + if ( !preloadPair->m_valid ) + { + if ( !preloadPair->ValidateProgramPair() ) + return; + } + + gGL->glUseProgram( (GLuint)preloadPair->m_program ); + + m_pBoundPair = preloadPair; + m_bDirtyPrograms = true; + + // almost ready to draw... + + //int tmuForPreload = 15; + + // shut down all the generic attribute arrays on the detention level - next real draw will activate them again + m_lastKnownVertexAttribMask = 0; + m_nNumSetVertexAttributes = 16; + memset( &m_boundVertexAttribs[0], 0xFF, sizeof( m_boundVertexAttribs ) ); + + // Force the next flush to reset the attributes. + ClearCurAttribs(); + + for( int index=0; index < kGLMVertexAttributeIndexMax; index++ ) + { + gGL->glDisableVertexAttribArray( index ); + } + + // bind texture and sampling params + CGLMTex *pPrevTex = m_samplers[15].m_pBoundTex; + +#ifndef OSX // 10.6 + if ( m_bUseSamplerObjects ) + { + gGL->glBindSampler( 15, 0 ); + } +#endif // !OSX + + BindTexToTMU( tex, 15 ); + + // unbind vertex/index buffers + BindBufferToCtx( kGLMVertexBuffer, NULL ); + BindBufferToCtx( kGLMIndexBuffer, NULL ); + + // draw + static float posns[] = { 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f, + 0.0f, 0.0f, 0.0f }; + + static int indices[] = { 0, 1, 2 }; + + + gGL->glEnableVertexAttribArray( 0 ); + + gGL->glVertexAttribPointer( 0, 3, GL_FLOAT, 0, 0, posns ); + + gGL->glDrawRangeElements( GL_TRIANGLES, 0, 2, 3, GL_UNSIGNED_INT, indices); + + gGL->glDisableVertexAttribArray( 0 ); + + SetSamplerDirty( 15 ); + + BindTexToTMU( pPrevTex, 15 ); + + tex->m_texPreloaded = true; +} + + + +CGLMFBO *GLMContext::NewFBO( void ) +{ + GLM_FUNC; + + CGLMFBO *fbo = new CGLMFBO( this ); + + m_fboTable.AddToTail( fbo ); + + return fbo; +} + +void GLMContext::DelFBO( CGLMFBO *fbo ) +{ + GLM_FUNC; + + if (m_drawingFBO == fbo) + { + m_drawingFBO = NULL; //poof! + } + + if (m_boundReadFBO == fbo ) + { + BindFBOToCtx( NULL, GL_READ_FRAMEBUFFER ); + m_boundReadFBO = NULL; + } + + if (m_boundDrawFBO == fbo ) + { + BindFBOToCtx( NULL, GL_DRAW_FRAMEBUFFER ); + m_boundDrawFBO = NULL; + } + + int idx = m_fboTable.Find( fbo ); + Assert( idx >= 0 ); + if ( idx >= 0 ) + { + m_fboTable.FastRemove( idx ); + } + + delete fbo; +} + +//=============================================================================== + +CGLMProgram *GLMContext::NewProgram( EGLMProgramType type, char *progString, const char *pShaderName ) +{ + //hushed GLM_FUNC; + + CGLMProgram *prog = new CGLMProgram( this, type ); + + prog->SetProgramText( progString ); + prog->SetShaderName( pShaderName ); + prog->CompileActiveSources(); + + return prog; +} + +void GLMContext::DelProgram( CGLMProgram *pProg ) +{ + GLM_FUNC; + + if ( m_drawingProgram[ pProg->m_type ] == pProg ) + { + SetProgram( pProg->m_type, ( pProg->m_type == kGLMFragmentProgram ) ? m_pNullFragmentProgram : NULL ); + } + + // make sure to eliminate any cached pairs using this shader + bool purgeResult = m_pairCache->PurgePairsWithShader( pProg ); + (void)purgeResult; + Assert( !purgeResult ); // very unlikely to trigger + + NullProgram(); + + delete pProg; +} + +void GLMContext::NullProgram( void ) +{ + gGL->glUseProgram( 0 ); + m_pBoundPair = NULL; + m_bDirtyPrograms = true; +} + +void GLMContext::SetDrawingLang( EGLMProgramLang lang, bool immediate ) +{ + if ( !m_caps.m_hasDualShaders ) return; // ignore attempts to change language when -glmdualshaders is not engaged + + m_drawingLangAtFrameStart = lang; + if (immediate) + { + NullProgram(); + + m_drawingLang = m_drawingLangAtFrameStart; + } +} + +void GLMContext::LinkShaderPair( CGLMProgram *vp, CGLMProgram *fp ) +{ + if ( (m_pairCache) && (m_drawingLang==kGLMGLSL) && (vp) && (fp) ) + { + CGLMShaderPair *pair = m_pairCache->SelectShaderPair( vp, fp, 0 ); + (void)pair; + + Assert( pair != NULL ); + + NullProgram(); // clear out any binds that were done - next draw will set it right + } +} + +void GLMContext::ValidateShaderPair( CGLMProgram *vp, CGLMProgram *fp ) +{ + if ((m_pairCache) && (m_drawingLang == kGLMGLSL) && (vp) && (fp)) + { + CGLMShaderPair *pair = m_pairCache->SelectShaderPair( vp, fp, 0 ); + Assert( pair != NULL ); + pair->ValidateProgramPair(); + + NullProgram(); // clear out any binds that were done - next draw will set it right + } +} + +void GLMContext::ClearShaderPairCache( void ) +{ + if (m_pairCache) + { + NullProgram(); + m_pairCache->Purge(); // bye bye all linked pairs + NullProgram(); + } +} + +void GLMContext::QueryShaderPair( int index, GLMShaderPairInfo *infoOut ) +{ + if (m_pairCache) + { + m_pairCache->QueryShaderPair( index, infoOut ); + } + else + { + memset( infoOut, 0, sizeof( *infoOut ) ); + infoOut->m_status = -1; + } +} + +CGLMBuffer *GLMContext::NewBuffer( EGLMBufferType type, uint size, uint options ) +{ + //hushed GLM_FUNC; + + CGLMBuffer *prog = new CGLMBuffer( this, type, size, options ); + + return prog; +} + +void GLMContext::DelBuffer( CGLMBuffer *buff ) +{ + GLM_FUNC; + + for( int index = 0; index < kGLMVertexAttributeIndexMax; index++ ) + { + if ( m_drawVertexSetup.m_attrs[index].m_pBuffer == buff ) + { + // just clear the enable mask - this will force all the attrs to get re-sent on next sync + m_drawVertexSetup.m_attrMask = 0; + } + } + + BindGLBufferToCtx( buff->m_buffGLTarget, NULL, false ); + + delete buff; +} + +GLMVertexSetup g_blank_setup; + +void GLMContext::Clear( bool color, unsigned long colorValue, bool depth, float depthValue, bool stencil, unsigned int stencilValue, GLScissorBox_t *box ) +{ + GLM_FUNC; + + ++m_nBatchCounter; + +#if GLMDEBUG + GLMDebugHookInfo info; + memset( &info, 0, sizeof(info) ); + info.m_caller = eClear; + + do + { +#endif + uint mask = 0; + + GLClearColor_t clearcol; + GLClearDepth_t cleardep = { depthValue }; + GLClearStencil_t clearsten = { (GLint)stencilValue }; + + // depth write mask must be saved&restored + GLDepthMask_t olddepthmask; + GLDepthMask_t newdepthmask = { true }; + + // stencil write mask must be saved and restored + GLStencilWriteMask_t oldstenmask; + GLStencilWriteMask_t newstenmask = { (GLint)0xFFFFFFFF }; + + GLColorMaskSingle_t oldcolormask; + GLColorMaskSingle_t newcolormask = { -1,-1,-1,-1 }; // D3D clears do not honor color mask, so force it + + if (color) + { + // #define D3DCOLOR_ARGB(a,r,g,b) ((D3DCOLOR)((((a)&0xff)<<24)|(((r)&0xff)<<16)|(((g)&0xff)<<8)|((b)&0xff))) + + clearcol.r = ((colorValue >> 16) & 0xFF) / 255.0f; //R + clearcol.g = ((colorValue >> 8) & 0xFF) / 255.0f; //G + clearcol.b = ((colorValue ) & 0xFF) / 255.0f; //B + clearcol.a = ((colorValue >> 24) & 0xFF) / 255.0f; //A + + m_ClearColor.Write( &clearcol ); // no check, no wait + mask |= GL_COLOR_BUFFER_BIT; + + // save and set color mask + m_ColorMaskSingle.Read( &oldcolormask, 0 ); + m_ColorMaskSingle.Write( &newcolormask ); + } + + if (depth) + { + // get old depth write mask + m_DepthMask.Read( &olddepthmask, 0 ); + m_DepthMask.Write( &newdepthmask ); + m_ClearDepth.Write( &cleardep ); // no check, no wait + mask |= GL_DEPTH_BUFFER_BIT; + } + + if (stencil) + { + m_ClearStencil.Write( &clearsten ); // no check, no wait + mask |= GL_STENCIL_BUFFER_BIT; + + // save and set sten mask + m_StencilWriteMask.Read( &oldstenmask, 0 ); + m_StencilWriteMask.Write( &newstenmask ); + } + + bool subrect = (box != NULL); + GLScissorEnable_t scissorEnableSave; + GLScissorEnable_t scissorEnableNew = { true }; + + GLScissorBox_t scissorBoxSave; + GLScissorBox_t scissorBoxNew; + + if (subrect) + { + // save current scissorbox and enable + m_ScissorEnable.Read( &scissorEnableSave, 0 ); + m_ScissorBox.Read( &scissorBoxSave, 0 ); + + if(0) + { + // calc new scissorbox as intersection against *box + + // max of the mins + scissorBoxNew.x = MAX(scissorBoxSave.x, box->x); + scissorBoxNew.y = MAX(scissorBoxSave.y, box->y); + + // min of the maxes + scissorBoxNew.width = ( MIN(scissorBoxSave.x+scissorBoxSave.width, box->x+box->width)) - scissorBoxNew.x; + + // height is just min of the max y's, minus the new base Y + scissorBoxNew.height = ( MIN(scissorBoxSave.y+scissorBoxSave.height, box->y+box->height)) - scissorBoxNew.y; + } + else + { + // ignore old scissor box completely. + scissorBoxNew = *box; + } + // set new box and enable + m_ScissorEnable.Write( &scissorEnableNew ); + m_ScissorBox.Write( &scissorBoxNew ); + } + + gGL->glClear( mask ); + + if (subrect) + { + // put old scissor box and enable back + m_ScissorEnable.Write( &scissorEnableSave ); + m_ScissorBox.Write( &scissorBoxSave ); + } + + if (depth) + { + // put old depth write mask + m_DepthMask.Write( &olddepthmask ); + } + + if (color) + { + // put old color write mask + m_ColorMaskSingle.Write( &oldcolormask ); + } + + if (stencil) + { + // put old sten mask + m_StencilWriteMask.Write( &oldstenmask ); + } + +#if GLMDEBUG + DebugHook( &info ); + } while (info.m_loop); +#endif +} + + +// stolen from glmgrbasics.cpp +extern "C" uint GetCurrentKeyModifiers( void ); +enum ECarbonModKeyIndex +{ + EcmdKeyBit = 8, /* command key down?*/ + EshiftKeyBit = 9, /* shift key down?*/ + EalphaLockBit = 10, /* alpha lock down?*/ + EoptionKeyBit = 11, /* option key down?*/ + EcontrolKeyBit = 12 /* control key down?*/ +}; + +enum ECarbonModKeyMask +{ + EcmdKey = 1 << EcmdKeyBit, + EshiftKey = 1 << EshiftKeyBit, + EalphaLock = 1 << EalphaLockBit, + EoptionKey = 1 << EoptionKeyBit, + EcontrolKey = 1 << EcontrolKeyBit +}; + +static ConVar gl_flushpaircache ("gl_flushpaircache", "0"); +static ConVar gl_paircachestats ("gl_paircachestats", "0"); +static ConVar gl_mtglflush_at_tof ("gl_mtglflush_at_tof", "0"); +static ConVar gl_texlayoutstats ("gl_texlayoutstats", "0" ); + +void GLMContext::BeginFrame( void ) +{ + GLM_FUNC; + + m_debugFrameIndex++; + + // check for lang change at TOF + if (m_caps.m_hasDualShaders) + { + if (m_drawingLang != m_drawingLangAtFrameStart) + { + // language change. unbind everything.. + NullProgram(); + + m_drawingLang = m_drawingLangAtFrameStart; + } + } + + // scrub some critical shock absorbers + for( int i=0; i< 16; i++) + { + gGL->glDisableVertexAttribArray( i ); // enable GLSL attribute- this is just client state - will be turned back off + } + m_lastKnownVertexAttribMask = 0; + m_nNumSetVertexAttributes = 0; + + //FIXME should we also zap the m_lastKnownAttribs array ? (worst case it just sets them all again on first batch) + + BindBufferToCtx( kGLMVertexBuffer, NULL, true ); + BindBufferToCtx( kGLMIndexBuffer, NULL, true ); + + if (gl_flushpaircache.GetInt()) + { + // do the flush and then set back to zero + ClearShaderPairCache(); + + printf("\n\n##### shader pair cache cleared\n\n"); + gl_flushpaircache.SetValue( 0 ); + } + + if (gl_paircachestats.GetInt()) + { + // do the flush and then set back to zero + m_pairCache->DumpStats(); + + gl_paircachestats.SetValue( 0 ); + } + + if (gl_texlayoutstats.GetInt()) + { + m_texLayoutTable->DumpStats(); + + gl_texlayoutstats.SetValue( 0 ); + } + + if (gl_mtglflush_at_tof.GetInt()) + { + gGL->glFlush(); // TOF flush - skip this if benchmarking, enable it if human playing (smoothness) + } + +#if GLMDEBUG + // init debug hook information + GLMDebugHookInfo info; + memset( &info, 0, sizeof(info) ); + info.m_caller = eBeginFrame; + + do + { + DebugHook( &info ); + } while (info.m_loop); + +#endif + +} + +void GLMContext::EndFrame( void ) +{ + GLM_FUNC; + +#if GLMDEBUG + // init debug hook information + GLMDebugHookInfo info; + memset( &info, 0, sizeof(info) ); + info.m_caller = eEndFrame; + + do + { + DebugHook( &info ); + } while (info.m_loop); +#endif +} + +//=============================================================================== + +CGLMQuery *GLMContext::NewQuery( GLMQueryParams *params ) +{ + CGLMQuery *query = new CGLMQuery( this, params ); + + return query; +} + +void GLMContext::DelQuery( CGLMQuery *query ) +{ + // may want to do some finish/ + delete query; +} + +static ConVar mat_vsync( "mat_vsync", "0", 0, "Force sync to vertical retrace", true, 0.0, true, 1.0 ); + +//=============================================================================== + +ConVar glm_nullrefresh_capslock( "glm_nullrefresh_capslock", "0" ); +ConVar glm_literefresh_capslock( "glm_literefresh_capslock", "0" ); + +extern ConVar gl_blitmode; + +void GLMContext::Present( CGLMTex *tex ) +{ + GLM_FUNC; + + { +#if GL_TELEMETRY_GPU_ZONES + CScopedGLMPIXEvent glmPIXEvent( "GLMContext::Present" ); + g_TelemetryGPUStats.m_nTotalPresent++; +#endif + + ProcessTextureDeletes(); + + bool newRefreshMode = false; + // two ways to go: + + // old school, do the resolve, had the tex down to cocoamgr to actually blit. + // that way is required if you are not in one-context mode (10.5.8) + + if ( (gl_blitmode.GetInt() != 0) ) + { + newRefreshMode = true; + } + + // this is the path whether full screen or windowed... we always blit. + CShowPixelsParams showparams; + memset( &showparams, 0, sizeof(showparams) ); + + showparams.m_srcTexName = tex->m_texName; + showparams.m_width = tex->m_layout->m_key.m_xSize; + showparams.m_height = tex->m_layout->m_key.m_ySize; + showparams.m_vsyncEnable = m_displayParams.m_vsyncEnable = mat_vsync.GetBool(); + showparams.m_fsEnable = m_displayParams.m_fsEnable; + showparams.m_useBlit = m_caps.m_hasFramebufferBlit; + + // we call showpixels once with the "only sync view" arg set, so we know what the latest surface size is, before trying to do our own blit ! + showparams.m_onlySyncView = true; + ShowPixels(&showparams); // doesn't actually show anything, just syncs window/fs state (would make a useful separate call) + showparams.m_onlySyncView = false; + + bool refresh = true; + #ifdef OSX + if ( (glm_nullrefresh_capslock.GetInt()) && (GetCurrentKeyModifiers() & EalphaLock) ) + { + refresh = false; + } + #endif + static int counter; + counter ++; + + #ifdef OSX + if ( (glm_literefresh_capslock.GetInt()) && (GetCurrentKeyModifiers() & EalphaLock) && (counter & 127) ) + { + // just show every 128th frame + refresh = false; + } + #endif + + if (refresh) + { + if (newRefreshMode) + { + // blit to GL_BACK done here, not in CocoaMgr, this lets us do resolve directly if conditions are right + + GLMRect srcRect, dstRect; + + uint dstWidth,dstHeight; + DisplayedSize( dstWidth,dstHeight ); + + srcRect.xmin = 0; + srcRect.ymin = 0; + srcRect.xmax = showparams.m_width; + srcRect.ymax = showparams.m_height; + + dstRect.xmin = 0; + dstRect.ymin = 0; + dstRect.xmax = dstWidth; + dstRect.ymax = dstHeight; + + // do not ask for LINEAR if blit is unscaled + // NULL means targeting GL_BACK. Blit2 will break it down into two steps if needed, and will handle resolve, scale, flip. + bool blitScales = (showparams.m_width != static_cast(dstWidth)) || (showparams.m_height != static_cast(dstHeight)); + Blit2( tex, &srcRect, 0,0, + NULL, &dstRect, 0,0, + blitScales ? GL_LINEAR : GL_NEAREST ); + + // we set showparams.m_noBlit, and just let CocoaMgr handle the swap (flushbuffer / page flip) + showparams.m_noBlit = true; + + BindFBOToCtx( NULL, GL_FRAMEBUFFER ); + } + else + { + ResolveTex( tex, true ); // dxabstract used to do this unconditionally.we still do if new refresh mode doesn't engage. + + BindFBOToCtx( NULL, GL_FRAMEBUFFER ); + + // showparams.m_noBlit is left set to 0. CocoaMgr does the blit. + } + + ShowPixels(&showparams); + } + + // put the original FB back in place (both read and draw) + // this bind will hit both read and draw bindings + BindFBOToCtx( m_drawingFBO, GL_FRAMEBUFFER ); + + // put em back !! + m_ScissorEnable.Flush(); + m_ScissorBox.Flush(); + m_ViewportBox.Flush(); + } + + m_nCurFrame++; + +#if GL_BATCH_PERF_ANALYSIS + tmMessage( TELEMETRY_LEVEL2, TMMF_ICON_EXCLAMATION, "VS Uniform Calls: %u, VS Uniforms: %u|VS Uniform Bone Calls: %u, VS Bone Uniforms: %u|PS Uniform Calls: %u, PS Uniforms: %u", m_nTotalVSUniformCalls, m_nTotalVSUniformsSet, m_nTotalVSUniformBoneCalls, m_nTotalVSUniformsBoneSet, m_nTotalPSUniformCalls, m_nTotalPSUniformsSet ); + m_nTotalVSUniformCalls = 0, m_nTotalVSUniformBoneCalls = 0, m_nTotalVSUniformsSet = 0, m_nTotalVSUniformsBoneSet = 0, m_nTotalPSUniformCalls = 0, m_nTotalPSUniformsSet = 0; +#endif +} + +//=============================================================================== +// GLMContext protected methods + +// a naive implementation of this would just clear-drawable on the context at entry, +// and then capture and set fullscreen if requested. +// however that would glitch thescreen every time the user changed resolution while staying in full screen. +// but in windowed mode there's really not much to do in here. Yeah, this routine centers around obtaining +// drawables for fullscreen mode, and/or dropping those drawables if we're going back to windowed. + +// um, are we expected to re-make the standard surfaces (color, depthstencil) if the res changes? is that now this routine's job ? + +// so, kick it off with an assessment of whather we were FS previously or not. +// if there was no prior display params latched, then it wasn't. + +// changes in here take place immediately. If you want to defer display changes then that's going to be a different method. +// common assumption is that there will be two places that call this: context create and the implementation of the DX9 Reset method. +// in either case the client code is aware of what it signed up for. + +bool GLMContext::SetDisplayParams( GLMDisplayParams *params ) +{ + m_displayParams = *params; // latch em + m_displayParamsValid = true; + + return true; +} + + +ConVar gl_can_query_fast("gl_can_query_fast", "0"); + +static uint gPersistentBufferSize[kGLMNumBufferTypes] = +{ + 2 * 1024 * 1024, // kGLMVertexBuffer + 1 * 1024 * 1024, // kGLMIndexBuffer + 0, // kGLMUniformBuffer + 0, // kGLMPixelBuffer +}; + +GLMContext::GLMContext( IDirect3DDevice9 *pDevice, GLMDisplayParams *params ) +{ +// m_bUseSamplerObjects = true; +// +// // On most AMD drivers (like the current latest, 12.10 Windows), the PCF depth comparison mode doesn't work on sampler objects, so just punt them. +// if ( gGL->m_nDriverProvider == cGLDriverProviderAMD ) +// { +// m_bUseSamplerObjects = false; +// } + +// if ( CommandLine()->CheckParm( "-gl_disablesamplerobjects" ) ) +// { + // Disable sampler object usage for now since ScaleForm isn't aware of them + // and doesn't know how to push/pop their binding state. It seems we don't + // really use them in this codebase anyhow, except to preload textures. + m_bUseSamplerObjects = false; + if ( CommandLine()->CheckParm( "-gl_enablesamplerobjects" ) ) + m_bUseSamplerObjects = true; + + // Try to get some more free memory by relying on driver host copies instead of ours. + // In some cases the driver will be able to discard their own host copy and rely on GPU + // memory, reducing memory usage. + // Sadly, we have to enable tex client storage for srgb decoding. This should only happen + // on Macs w/ OSX 10.6. + m_bTexClientStorage = !gGL->m_bHave_GL_EXT_texture_sRGB_decode; + if ( CommandLine()->CheckParm( "-gl_texclientstorage" ) ) + m_bTexClientStorage = true; + + GLMDebugPrintf( "GL sampler object usage: %s\n", m_bUseSamplerObjects ? "ENABLED" : "DISABLED" ); + + m_nCurOwnerThreadId = ThreadGetCurrentId(); + m_nThreadOwnershipReleaseCounter = 0; + + m_pDevice = pDevice; + m_nCurFrame = 0; + m_nBatchCounter = 0; + + ClearCurAttribs(); + + m_nCurPersistentBuffer = 0; + if ( gGL->m_bHave_GL_EXT_buffer_storage ) + { + for ( uint lpType = 0; lpType < kGLMNumBufferTypes; ++lpType ) + { + for ( uint lpNum = 0; lpNum < cNumPersistentBuffers; ++lpNum ) + { + m_persistentBuffer[lpNum][lpType].Init( (EGLMBufferType)lpType, gPersistentBufferSize[lpType] ); + } + } + } + + m_bUseBoneUniformBuffers = true; + if (CommandLine()->CheckParm("-disableboneuniformbuffers")) + { + m_bUseBoneUniformBuffers = false; + } + + m_nMaxUsedVertexProgramConstantsHint = 256; + + // flag our copy of display params as blank + m_displayParamsValid = false; + + // peek at any CLI options + m_slowAssertEnable = CommandLine()->FindParm("-glmassertslow") != 0; + m_slowSpewEnable = CommandLine()->FindParm("-glmspewslow") != 0; + m_checkglErrorsAfterEveryBatch = CommandLine()->FindParm("-glcheckerrors") != 0; + m_slowCheckEnable = m_slowAssertEnable || m_slowSpewEnable || m_checkglErrorsAfterEveryBatch; + + m_drawingLangAtFrameStart = m_drawingLang = kGLMGLSL; // default to GLSL + + // this affects FlushDrawStates which will route program bindings, uniform delivery, sampler setup, and enables accordingly. + + if ( CommandLine()->FindParm("-glslmode") ) + { + m_drawingLangAtFrameStart = m_drawingLang = kGLMGLSL; + } + if ( CommandLine()->FindParm("-arbmode") && !CommandLine()->FindParm("-glslcontrolflow") ) + { + m_drawingLangAtFrameStart = m_drawingLang = kGLMARB; + } + + // proceed with rest of init + + m_dwRenderThreadId = 0; + m_bIsThreading = false; + + m_nsctx = NULL; + m_ctx = NULL; + + int *selAttribs = NULL; + uint selWords = 0; + + memset( &m_caps, 0, sizeof( m_caps ) ); + GetDesiredPixelFormatAttribsAndRendererInfo( (uint**)&selAttribs, &selWords, &m_caps ); + uint selBytes = selWords * sizeof( uint ); selBytes; + +#if defined( USE_SDL ) + m_ctx = (SDL_GLContext)GetGLContextForWindow( params ? (void*)params->m_focusWindow : NULL ); + MakeCurrent( true ); +#else +#error +#endif + IncrementWindowRefCount(); + + // If we're using GL_ARB_debug_output, go ahead and setup the callback here. + if ( CommandLine()->FindParm( "-gl_debug" ) ) + { +//#if GLMDEBUG + // Turning this on is a perf loss, but it ensures that you can (at least) swap to the other + // threads to see what call is currently being made. + // Note that if the driver is in multithreaded mode, you can put it back into singlethreaded mode + // and get a real stack for the offending gl call. + gGL->glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB); + +#ifdef WIN32 + // This happens early enough during init that DevMsg() does nothing. + OutputDebugStringA( "GLMContext::GLMContext: GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB enabled!\n" ); +#else + printf( "GLMContext::GLMContext: GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB enabled!\n" ); +#endif + + // TODO(nillerusr): rewrite me!!! + // This should be there if we get in here--make sure. + gGL->glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, (const GLuint *)NULL, GL_TRUE); + + // Gonna filter these out, they're "chatty". + gGL->glDebugMessageControl(GL_DEBUG_SOURCE_API_ARB, GL_DEBUG_TYPE_OTHER_ARB, GL_DEBUG_SEVERITY_LOW_ARB, 0, (const GLuint *)NULL, GL_FALSE); + gGL->glDebugMessageCallback(GL_Debug_Output_Callback, (void*)NULL); + + GLMDebugPrintf( "GLMContext::GLMContext: Debug output (gl_arb_debug_output) enabled!\n" ); +//#endif + } + + + if (CommandLine()->FindParm("-glmspewcaps")) + { + DumpCaps(); + } + + SetDisplayParams( params ); + + m_texLayoutTable = new CGLMTexLayoutTable; + +#ifndef OSX + if ( m_bUseSamplerObjects ) + { + memset( m_samplerObjectHash, 0, sizeof( m_samplerObjectHash ) ); + m_nSamplerObjectHashNumEntries = 0; + + for ( uint i = 0; i < cSamplerObjectHashSize; ++i ) + { + gGL->glGenSamplers( 1, &m_samplerObjectHash[i].m_samplerObject ); + } + } +#endif // !OSX + + memset( m_samplers, 0, sizeof( m_samplers ) ); + for( int i=0; i< GLM_SAMPLER_COUNT; i++) + { + GLMTexSamplingParams ¶ms = m_samplers[i].m_samp; + params.m_packed.m_addressU = D3DTADDRESS_WRAP; + params.m_packed.m_addressV = D3DTADDRESS_WRAP; + params.m_packed.m_addressW = D3DTADDRESS_WRAP; + params.m_packed.m_minFilter = D3DTEXF_POINT; + params.m_packed.m_magFilter = D3DTEXF_POINT; + params.m_packed.m_mipFilter = D3DTEXF_NONE; + params.m_packed.m_maxAniso = 1; + params.m_packed.m_isValid = true; + params.m_packed.m_compareMode = 0; + } + + MarkAllSamplersDirty(); + + m_activeTexture = -1; + + m_texLocks.EnsureCapacity( 16 ); // should be sufficient + + // FIXME need a texture tracking table so we can reliably delete CGLMTex objects at context teardown + + m_boundReadFBO = NULL; + m_boundDrawFBO = NULL; + m_drawingFBO = NULL; + + memset( m_drawingProgram, 0, sizeof( m_drawingProgram ) ); + m_bDirtyPrograms = true; + memset( m_programParamsF , 0, sizeof( m_programParamsF ) ); + memset( m_programParamsB , 0, sizeof( m_programParamsB ) ); + memset( m_programParamsI , 0, sizeof( m_programParamsI ) ); + + for (uint i = 0; i < ARRAYSIZE(m_programParamsF); i++) + { + m_programParamsF[i].m_firstDirtySlotNonBone = 256; + m_programParamsF[i].m_dirtySlotHighWaterNonBone = 0; + + m_programParamsF[i].m_dirtySlotHighWaterBone = 0; + } + + m_paramWriteMode = eParamWriteDirtySlotRange; // default to fastest mode + + if (CommandLine()->FindParm("-glmwriteallslots")) m_paramWriteMode = eParamWriteAllSlots; + if (CommandLine()->FindParm("-glmwriteshaderslots")) m_paramWriteMode = eParamWriteShaderSlots; + if (CommandLine()->FindParm("-glmwriteshaderslotsoptional")) m_paramWriteMode = eParamWriteShaderSlotsOptional; + if (CommandLine()->FindParm("-glmwritedirtyslotrange")) m_paramWriteMode = eParamWriteDirtySlotRange; + + m_attribWriteMode = eAttribWriteDirty; + + if (CommandLine()->FindParm("-glmwriteallattribs")) m_attribWriteMode = eAttribWriteAll; + if (CommandLine()->FindParm("-glmwritedirtyattribs")) m_attribWriteMode = eAttribWriteDirty; + + m_pairCache = new CGLMShaderPairCache( this ); + m_pBoundPair = NULL; + + m_fragDataMask = 0; + + memset( m_nBoundGLBuffer, 0xFF, sizeof( m_nBoundGLBuffer ) ); + + memset( m_boundVertexAttribs, 0xFF, sizeof(m_boundVertexAttribs) ); + m_lastKnownVertexAttribMask = 0; + m_nNumSetVertexAttributes = 16; + + // make a null program for use when client asks for NULL FP + m_pNullFragmentProgram = NewProgram(kGLMFragmentProgram, g_nullFragmentProgramText, "null" ); + SetProgram( kGLMFragmentProgram, m_pNullFragmentProgram ); + + // make dummy programs for doing texture preload via dummy draw + m_preloadTexVertexProgram = NewProgram(kGLMVertexProgram, g_preloadTexVertexProgramText, "preloadTex" ); + m_preload2DTexFragmentProgram = NewProgram(kGLMFragmentProgram, g_preload2DTexFragmentProgramText, "preload2DTex" ); + m_preload3DTexFragmentProgram = NewProgram(kGLMFragmentProgram, g_preload3DTexFragmentProgramText, "preload3DTex" ); + m_preloadCubeTexFragmentProgram = NewProgram(kGLMFragmentProgram, g_preloadCubeTexFragmentProgramText, "preloadCube" ); + + //memset( &m_drawVertexSetup, 0, sizeof(m_drawVertexSetup) ); + SetVertexAttributes( NULL ); // will set up all the entries in m_drawVertexSetup + + m_debugFontTex = NULL; + + // debug state + m_debugFrameIndex = -1; + +#if GLMDEBUG + // ####################################################################################### + + // DebugHook state - we could set these to more interesting values in response to a CLI arg like "startpaused" or something if desired + //m_paused = false; + m_holdFrameBegin = -1; + m_holdFrameEnd = -1; + m_holdBatch = m_holdBatchFrame = -1; + + m_debugDelayEnable = false; + m_debugDelay = 1<<19; // ~0.5 sec delay + + m_autoClearColor = m_autoClearDepth = m_autoClearStencil = false; + m_autoClearColorValues[0] = 0.0; //red + m_autoClearColorValues[1] = 1.0; //green + m_autoClearColorValues[2] = 0.0; //blue + m_autoClearColorValues[3] = 1.0; //alpha + + m_selKnobIndex = 0; + m_selKnobMinValue = -10.0f; + + m_selKnobMaxValue = 10.0f; + m_selKnobIncrement = 1/256.0f; + + // ####################################################################################### +#endif + + // make two scratch FBO's for blit purposes + m_blitReadFBO = NewFBO(); + m_blitDrawFBO = NewFBO(); + + for( int i=0; iglGenBuffers( 1, &m_destroyPBO ); + gGL->glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_destroyPBO ); + gGL->glBufferData( GL_PIXEL_UNPACK_BUFFER, sizeof( g_garbageTextureBits ), g_garbageTextureBits, GL_STREAM_DRAW ); + gGL->glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_nBoundGLBuffer[ kGLMPixelBuffer ] ); + + // Create a bunch of texture names for us to use forever and ever ramen. + FillTexCache( false, kGLMInitialTexCount ); + +#ifdef OSX + bool new_mtgl = m_caps.m_hasPerfPackage1; // i.e. 10.6.4 plus new driver + + if ( CommandLine()->FindParm("-glmenablemtgl2") ) + { + new_mtgl = true; + } + + if ( CommandLine()->FindParm("-glmdisablemtgl2") ) + { + new_mtgl = false; + } + + bool mtgl_on = params->m_mtgl; + if (CommandLine()->FindParm("-glmenablemtgl")) + { + mtgl_on = true; + } + + if (CommandLine()->FindParm("-glmdisablemtgl")) + { + mtgl_on = false; + } + + CGLError result = (CGLError)0; + if (mtgl_on) + { + bool ready = false; + CGLContextObj context = GetCGLContextFromNSGL(m_ctx); + if (new_mtgl) + { + // afterburner + CGLContextEnable kCGLCPGCDMPEngine = ((CGLContextEnable)1314); + result = CGLEnable( context, kCGLCPGCDMPEngine ); + if (!result) + { + ready = true; // succeeded - no need to try non-MTGL + printf("\nMTGL detected.\n"); + } + else + { + printf("\nMTGL *not* detected, falling back.\n"); + } + } + + if (!ready) + { + // try old MTGL + result = CGLEnable( context, kCGLCEMPEngine ); + if (!result) + { + printf("\nMTGL has been detected.\n"); + ready = true; // succeeded - no need to try non-MTGL + } + } + } + + if ( m_caps.m_badDriver108Intel ) + { + // this way we have something to look for in terminal spew if users report issues related to this in the future. + printf( "\nEnabling GLSL compiler `malloc' workaround.\n" ); + if ( !IntelGLMallocWorkaround::Get()->Enable() ) + { + Warning( "Unable to enable OSX 10.8 / Intel HD4000 workaround, there might be crashes.\n" ); + } + } + +#endif + // also, set the remote convar "gl_can_query_fast" to 1 if perf package present, else 0. + gl_can_query_fast.SetValue( m_caps.m_hasPerfPackage1?1:0 ); + +#if GL_BATCH_PERF_ANALYSIS + m_nTotalVSUniformCalls = 0; + m_nTotalVSUniformBoneCalls = 0; + m_nTotalVSUniformsSet = 0; + m_nTotalVSUniformsBoneSet = 0; + m_nTotalPSUniformCalls = 0; + m_nTotalPSUniformsSet = 0; +#endif + + // See g_D3DRS_INFO_packed in dxabstract.cpp; dithering is a non-managed + // piece of state that we consider off by default. However it is actually + // enabled by default in the GL spec, so account for that here. + // See: https://bugs.freedesktop.org/show_bug.cgi?id=74700 + gGL->glDisable( GL_DITHER ); +} + +void GLMContext::Reset() +{ +} + +GLMContext::~GLMContext () +{ + if (m_debugFontTex) + { + DelTex( m_debugFontTex ); + m_debugFontTex = NULL; + } + + ProcessTextureDeletes(); + + if ( m_pNullFragmentProgram ) + { + DelProgram( m_pNullFragmentProgram ); + m_pNullFragmentProgram = NULL; + } + + // walk m_fboTable and free them up.. + FOR_EACH_VEC( m_fboTable, i ) + { + CGLMFBO *fbo = m_fboTable[i]; + DelFBO( fbo ); + } + m_fboTable.SetSize( 0 ); + + if (m_pairCache) + { + delete m_pairCache; + m_pairCache = NULL; + } + + // we need a m_texTable I think.. + + // m_texLayoutTable can be scrubbed once we know that all the tex are freed + + gGL->glDeleteBuffers( 1, &m_destroyPBO ); + + PurgeTexCache(); + + DecrementWindowRefCount(); +} + +// This method must call SelectTMU()/glActiveTexture() (it's expected as a side effect). +// This method is no longer called from any performance sensitive code paths. +void GLMContext::BindTexToTMU( CGLMTex *pTex, int tmu ) +{ +#if GLMDEBUG + GLM_FUNC; +#endif + + GLMPRINTF(("--- GLMContext::BindTexToTMU tex %p GL name %d -> TMU %d ", pTex, pTex ? pTex->m_texName : -1, tmu )); + + CheckCurrent(); + + SelectTMU( tmu ); + + if ( !pTex ) + { + gGL->glBindTexture( GL_TEXTURE_2D, 0 ); + gGL->glBindTexture( GL_TEXTURE_3D, 0 ); + gGL->glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); + } + else + { + const GLenum texGLTarget = pTex->m_texGLTarget; + if ( texGLTarget != GL_TEXTURE_2D ) gGL->glBindTexture( GL_TEXTURE_2D, 0 ); + if ( texGLTarget != GL_TEXTURE_3D ) gGL->glBindTexture( GL_TEXTURE_3D, 0 ); + if ( texGLTarget != GL_TEXTURE_CUBE_MAP ) gGL->glBindTexture( GL_TEXTURE_CUBE_MAP, 0 ); + gGL->glBindTexture( texGLTarget, pTex->m_texName ); + } + + m_samplers[tmu].m_pBoundTex = pTex; +} + +void GLMContext::BindFBOToCtx( CGLMFBO *fbo, GLenum bindPoint ) +{ +#if GLMDEBUG + GLM_FUNC; +#endif + GLMPRINTF(( "--- GLMContext::BindFBOToCtx fbo %p, GL name %d", fbo, (fbo) ? fbo->m_name : -1 )); + + CheckCurrent(); + + if ( bindPoint == GL_FRAMEBUFFER ) + { + gGL->glBindFramebuffer( GL_FRAMEBUFFER, fbo ? fbo->m_name : 0 ); + m_boundReadFBO = fbo; + m_boundDrawFBO = fbo; + return; + } + + bool targetRead = (bindPoint==GL_READ_FRAMEBUFFER); + bool targetDraw = (bindPoint==GL_DRAW_FRAMEBUFFER); + + if (targetRead) + { + if (fbo) // you can pass NULL to go back to no-FBO + { + gGL->glBindFramebuffer( GL_READ_FRAMEBUFFER, fbo->m_name ); + + m_boundReadFBO = fbo; + //dontcare fbo->m_bound = true; + } + else + { + gGL->glBindFramebuffer( GL_READ_FRAMEBUFFER, 0 ); + + m_boundReadFBO = NULL; + } + } + + if (targetDraw) + { + if (fbo) // you can pass NULL to go back to no-FBO + { + gGL->glBindFramebuffer( GL_DRAW_FRAMEBUFFER, fbo->m_name ); + + m_boundDrawFBO = fbo; + //dontcare fbo->m_bound = true; + } + else + { + gGL->glBindFramebuffer( GL_DRAW_FRAMEBUFFER, 0 ); + + m_boundDrawFBO = NULL; + } + } +} + +void GLMContext::BindBufferToCtx( EGLMBufferType type, CGLMBuffer *pBuff, bool bForce ) +{ +#if GLMDEBUG + GLM_FUNC; +#endif + GLMPRINTF(( "--- GLMContext::BindBufferToCtx buff %p, GL name %d", pBuff, (pBuff) ? pBuff->m_nHandle : -1 )); + + CheckCurrent(); + + GLuint nGLName = pBuff ? pBuff->GetHandle() : 0; + if ( !bForce ) + { + if ( m_nBoundGLBuffer[type] == nGLName ) + return; + } + + GLenum target = 0; + switch( type ) + { + case kGLMVertexBuffer: target = GL_ARRAY_BUFFER; break; + case kGLMIndexBuffer: target = GL_ELEMENT_ARRAY_BUFFER; break; + case kGLMUniformBuffer: target = GL_UNIFORM_BUFFER; break; + case kGLMPixelBuffer: target = GL_PIXEL_UNPACK_BUFFER; break; + default: Assert(!"Unknown buffer type" ); + } + + Assert( !pBuff || ( pBuff->m_buffGLTarget == target ) ); + + m_nBoundGLBuffer[type] = nGLName; + gGL->glBindBuffer( target, nGLName ); +} + + +GLuint GLMContext::CreateTex( GLenum texBind, GLenum internalFormat ) +{ + GLM_FUNC; + + // If we're not doing batch create, just return one here. + if ( !gl_batch_tex_creates.GetBool() ) + { + GLuint tex = 0; + gGL->glGenTextures( 1, &tex ); + return tex; + } + + FOR_EACH_VEC( m_availableTextures, i ) + { + TextureEntry_t& tex = m_availableTextures[ i ]; + if ( ( tex.m_nTexBind == GL_NONE || tex.m_nTexBind == texBind ) + && ( tex.m_nInternalFormat == GL_NONE || tex.m_nInternalFormat == internalFormat ) ) + { + // Hit! + GLuint retVal = tex.m_nTexName; + m_availableTextures.Remove( i ); + return retVal; + } + } + + if ( m_availableTextures.Count() >= kGLMHighWaterUndeleted ) + { + PurgeTexCache(); + } + + return FillTexCache( true, kGLMReUpTexCount ); +} + +void GLMContext::CleanupTex( GLenum texBind, GLMTexLayout* pLayout, GLuint tex ) +{ + // If the total + if ( pLayout->m_storageTotalSize <= ( kDeletedTextureDim * kDeletedTextureDim * sizeof( uint32 ) ) ) + return; + + const GLuint oldPBO = m_nBoundGLBuffer[ kGLMPixelBuffer ]; + const GLuint oldTex = ( m_samplers[ m_activeTexture ].m_pBoundTex != NULL ) ? m_samplers[ m_activeTexture ].m_pBoundTex->GetTexName() : 0; + + gGL->glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_destroyPBO ); + gGL->glBindTexture( texBind, tex ); + + // Clear out old data. + for ( int i = 0; i < pLayout->m_mipCount; ++i ) + { + int mipDim = ( i == 0 ) ? kDeletedTextureDim : 0; + if ( pLayout->m_format->m_chunkSize != 1 ) + { + const int chunks = ( mipDim + ( pLayout->m_format->m_chunkSize - 1 ) ) / pLayout->m_format->m_chunkSize; + const int dataSize = ( chunks * chunks ) * pLayout->m_format->m_bytesPerSquareChunk; + Assert( dataSize <= ( sizeof( uint32) * ARRAYSIZE( g_garbageTextureBits ) ) ); + + CompressedTexImage2D( texBind, i, pLayout->m_format->m_glIntFormat, mipDim, mipDim, 0, dataSize, 0 ); + } + else + { + TexImage2D( texBind, i, pLayout->m_format->m_glIntFormat, mipDim, mipDim, 0, pLayout->m_format->m_glDataFormat, pLayout->m_format->m_glDataType, 0 ); + } + } + + gGL->glBindTexture( texBind, oldTex ); + gGL->glBindBuffer( GL_PIXEL_UNPACK_BUFFER, oldPBO ); +} + +void GLMContext::DestroyTex( GLenum texBind, GLMTexLayout* pLayout, GLuint tex ) +{ + GLM_FUNC; + + // Code only handles 2D for now. + if ( texBind != GL_TEXTURE_2D || !gl_batch_tex_destroys.GetBool() ) + { + gGL->glDeleteTextures( 1, &tex ); + return; + } + + CleanupTex( texBind, pLayout, tex ); + + TextureEntry_t entry; + entry.m_nTexBind = texBind; + entry.m_nInternalFormat = pLayout->m_format->m_glIntFormat; + entry.m_nTexName = tex; + + m_availableTextures.AddToTail( entry ); +} + +GLuint GLMContext::FillTexCache( bool holdOne, int newTextures ) +{ + // If we aren't doing batch creates, then don't fill the cache. + if ( !gl_batch_tex_creates.GetBool() ) + return 0; + + // If we have to hit the name table, might as well hit it a bunch because this causes + // serialization either way--at least we can do it less often. + GLuint* textures = (GLuint*) stackalloc( newTextures * sizeof( GLuint ) ); + gGL->glGenTextures( newTextures, textures ); + + Assert( textures[ 0 ] ); + + TextureEntry_t entry; + entry.m_nTexBind = GL_NONE; + entry.m_nInternalFormat = GL_NONE; + + // We may return 0, so skip adding it here. + for ( int i = 1; i < newTextures; ++i ) + { + Assert( textures[ i ] ); + if ( textures[ i ] ) + { + // We still add these to the tail because we'd prefer to reuse old textures (rather + // than these new ones). + entry.m_nTexName = textures[ i ]; + m_availableTextures.AddToTail( entry ); + } + } + + if ( holdOne ) + return textures[ 0 ]; + + // If not, stick that last one in the list and return 0. + entry.m_nTexName = textures[ 0 ]; + m_availableTextures.AddToTail( entry ); + + return 0; +} + +void GLMContext::PurgeTexCache() +{ + GLM_FUNC; + + int textureCount = m_availableTextures.Count(); + + if ( textureCount == 0 ) + return; + + GLuint* textures = (GLuint*) stackalloc( textureCount * sizeof( GLuint ) ); + + FOR_EACH_VEC( m_availableTextures, i ) + { + TextureEntry_t& tex = m_availableTextures[ i ]; + textures[ i ] = tex.m_nTexName; + } + + gGL->glDeleteTextures( textureCount, textures ); + + m_availableTextures.RemoveAll(); +} + +#ifdef OSX +// As far as I can tell this stuff is only useful under OSX. +ConVar gl_can_mix_shader_gammas( "gl_can_mix_shader_gammas", 0 ); +ConVar gl_cannot_mix_shader_gammas( "gl_cannot_mix_shader_gammas", 0 ); +#endif + +// ConVar param_write_mode("param_write_mode", "0"); + +void GLMContext::MarkAllSamplersDirty() +{ + m_nNumDirtySamplers = GLM_SAMPLER_COUNT; + for (uint i = 0; i < GLM_SAMPLER_COUNT; i++) + { + m_nDirtySamplerFlags[i] = 0; + m_nDirtySamplers[i] = (uint8)i; + } +} + +void GLMContext::FlushDrawStatesNoShaders( ) +{ + Assert( ( m_drawingFBO == m_boundDrawFBO ) && ( m_drawingFBO == m_boundReadFBO ) ); // this check MUST succeed + + GLM_FUNC; + + GL_BATCH_PERF( m_FlushStats.m_nTotalBatchFlushes++; ) + + NullProgram(); +} + +#if GLMDEBUG + +enum EGLMDebugDumpOptions +{ + eDumpBatchInfo, + eDumpSurfaceInfo, + eDumpStackCrawl, + eDumpShaderLinks, +// eDumpShaderText, // we never use this one + eDumpShaderParameters, + eDumpTextureSetup, + eDumpVertexAttribSetup, + eDumpVertexData, + eOpenShadersForEdit +}; + +enum EGLMVertDumpMode +{ + // options that affect eDumpVertexData above + eDumpVertsNoTransformDump, + eDumpVertsTransformedByViewProj, + eDumpVertsTransformedByModelViewProj, + eDumpVertsTransformedByBoneZeroThenViewProj, + eDumpVertsTransformedByBonesThenViewProj, + eLastDumpVertsMode +}; + +char *g_vertDumpModeNames[] = +{ + "noTransformDump", + "transformedByViewProj", + "transformedByModelViewProj", + "transformedByBoneZeroThenViewProj", + "transformedByBonesThenViewProj" +}; + +static void CopyTilEOL( char *dst, char *src, int dstSize ) +{ + dstSize--; + + int i=0; + while ( (im_caller==eDrawElements); + const char *batchtype = is_draw ? "draw" : "clear"; + + if (options & (1<m_attach[i].m_tex; + if (tex) + { + GLMPRINTF(("-D- bound FBO (%8x) attachment %d = tex %8x (GL %d) (%s)", fbo, i, tex, tex->m_texName, tex->m_layout->m_layoutSummary )); + } + else + { + // warning if no depthstencil attachment + switch(i) + { + case kAttDepth: + case kAttStencil: + case kAttDepthStencil: + GLMPRINTF(("-D- bound FBO (%8x) attachment %d = NULL, warning!", fbo, i )); + break; + } + } + } + } + + if (options & (1<m_text, "#//ATTRIBMAP"); + if (attribmap) + { + CopyTilEOL( attribtemp, attribmap, sizeof(attribtemp) ); + } + else + { + strcpy( attribtemp, "no attrib map" ); + } + + char *trans = strstr(vp->m_text, "#// trans#"); + if (trans) + { + CopyTilEOL( transtemp, trans, sizeof(transtemp) ); + } + else + { + strcpy( transtemp, "no translation info" ); + } + + char *linkpath = "no file link"; + + #if GLMDEBUG + linkpath = vp->m_editable->m_mirror->m_path; + #endif + + GLMPRINTF(("-D-")); + GLMPRINTF(("-D- ARBVP || GL %d || Path %s ", vp->m_descs[kGLMARB].m_object.arb, linkpath )); + GLMPRINTF(("-D- Attribs %s", attribtemp )); + GLMPRINTF(("-D- Trans %s", transtemp )); + + /* + if ( (options & (1<m_string, eDebugDump )); + } + */ + } + else + { + GLMPRINTF(("-D- VP (none)" )); + } + + if (fp) + { + char *trans = strstr(fp->m_text, "#// trans#"); + if (trans) + { + CopyTilEOL( transtemp, trans, sizeof(transtemp) ); + } + else + { + strcpy( transtemp, "no translation info" ); + } + + char *linkpath = "no file link"; + + #if GLMDEBUG + linkpath = fp->m_editable->m_mirror->m_path; + #endif + + GLMPRINTF(("-D-")); + GLMPRINTF(("-D- FP || GL %d || Path %s ", fp->m_descs[kGLMARB].m_object.arb, linkpath )); + GLMPRINTF(("-D- Trans %s", transtemp )); + + /* + if ( (options & (1<m_string, eDebugDump)); + } + */ + } + else + { + GLMPRINTF(("-D- FP (none)" )); + } + } + + if ( (options & (1<m_attrMask & (1<m_vtxAttribMap[index]>>4)== D3DDECLUSAGE_BLENDWEIGHT); + } + if (usesSkinning) + { + upperSlotLimit = 256; + } + + while( slotIndex < upperSlotLimit ) + { + // if slot index is in a masked range, skip it + // if slot index is the start of a matrix, label it, print it, skip ahead 4 slots + for( int maski=0; vmaskranges[maski] >=0; maski+=2) + { + if ( (slotIndex >= vmaskranges[maski]) && (slotIndex <= vmaskranges[maski+1]) ) + { + // that index is masked. set to one past end of range, print a blank line for clarity + slotIndex = vmaskranges[maski+1]+1; + GLMPrintStr("-D- ....."); + } + } + + if (slotIndex < upperSlotLimit) + { + float *values = &m_programParamsF[ kGLMVertexProgram ].m_values[slotIndex][0]; + switch( slotIndex ) + { + case 4: + printmat( "MODELVIEWPROJ", slotIndex, 4, values ); + slotIndex += 4; + break; + + case 8: + printmat( "VIEWPROJ", slotIndex, 4, values ); + slotIndex += 4; + break; + + default: + if (slotIndex>=58) + { + // bone + char bonelabel[100]; + + sprintf(bonelabel, "MODEL_BONE%-2d", (slotIndex-58)/3 ); + printmat( bonelabel, slotIndex, 3, values ); + + slotIndex += 3; + } + else + { + // just print the one slot + GLMPRINTF(("-D- %03d: [ %10.5f %10.5f %10.5f %10.5f ] %s", slotIndex, values[0], values[1], values[2], values[3], label )); + slotIndex++; + } + break; + } + } + } + + // VP stage still, if in GLSL mode, find the bound pair and see if it has live i0, b0-b3 uniforms + if (m_pBoundPair) // should only be non-NULL in GLSL mode + { +#if 0 + if (m_pBoundPair->m_locVertexBool0>=0) + { + GLMPRINTF(("-D- GLSL 'b0': %d", m_programParamsB[kGLMVertexProgram].m_values[0] )); + } + + if (m_pBoundPair->m_locVertexBool1>=0) + { + GLMPRINTF(("-D- GLSL 'b1': %d", m_programParamsB[kGLMVertexProgram].m_values[1] )); + } + + if (m_pBoundPair->m_locVertexBool2>=0) + { + GLMPRINTF(("-D- GLSL 'b2': %d", m_programParamsB[kGLMVertexProgram].m_values[2] )); + } + + if (m_pBoundPair->m_locVertexBool3>=0) + { + GLMPRINTF(("-D- GLSL 'b3': %d", m_programParamsB[kGLMVertexProgram].m_values[3] )); + } + + if (m_pBoundPair->m_locVertexInteger0>=0) + { + GLMPRINTF(("-D- GLSL 'i0': %d", m_programParamsI[kGLMVertexProgram].m_values[0][0] )); + } +#endif + } + + GLMPRINTF(("-D-")); + GLMPRINTF(("-D- FP parameters " )); + + static int fmaskranges[] = { 40,41, -1,-1 }; + + slotIndex = 0; + label = ""; + while(slotIndex < 40) + { + // if slot index is in a masked range, skip it + // if slot index is the start of a matrix, label it, print it, skip ahead 4 slots + for( int maski=0; fmaskranges[maski] >=0; maski+=2) + { + if ( (slotIndex >= fmaskranges[maski]) && (slotIndex <= fmaskranges[maski+1]) ) + { + // that index is masked. set to one past end of range, print a blank line for clarity + slotIndex = fmaskranges[maski+1]+1; + GLMPrintStr("-D- ....."); + } + } + + if (slotIndex < 40) + { + float *values = &m_programParamsF[ kGLMFragmentProgram ].m_values[slotIndex][0]; + switch( slotIndex ) + { + case 0: label = "g_EnvmapTint"; break; + case 1: label = "g_DiffuseModulation"; break; + case 2: label = "g_EnvmapContrast_ShadowTweaks"; break; + case 3: label = "g_EnvmapSaturation_SelfIllumMask (xyz, and w)"; break; + case 4: label = "g_SelfIllumTint_and_BlendFactor (xyz, and w)"; break; + + case 12: label = "g_ShaderControls"; break; + case 13: label = "g_DepthFeatheringConstants"; break; + + case 20: label = "g_EyePos"; break; + case 21: label = "g_FogParams"; break; + case 22: label = "g_FlashlightAttenuationFactors"; break; + case 23: label = "g_FlashlightPos"; break; + case 24: label = "g_FlashlightWorldToTexture"; break; + + case 28: label = "cFlashlightColor"; break; + case 29: label = "g_LinearFogColor"; break; + case 30: label = "cLightScale"; break; + case 31: label = "cFlashlightScreenScale"; break; + + default: + label = ""; + break; + } + + GLMPRINTF(("-D- %03d: [ %10.5f %10.5f %10.5f %10.5f ] %s", slotIndex, values[0], values[1], values[2], values[3], label )); + + slotIndex ++; + } + } + + if (m_pBoundPair->m_locFragmentFakeSRGBEnable) + { + GLMPRINTF(("-D- GLSL 'flEnableSRGBWrite': %f", m_pBoundPair->m_fakeSRGBEnableValue )); + } + } + + if ( (options & (1<m_layout->m_layoutSummary )); + + GLMPRINTF(("-D- addressMode[ %s %s %s ]", + GLMDecode( eGL_ENUM, samp->m_addressModes[0] ), + GLMDecode( eGL_ENUM, samp->m_addressModes[1] ), + GLMDecode( eGL_ENUM, samp->m_addressModes[2] ) + )); + + GLMPRINTF(("-D- magFilter [ %s ]", GLMDecode( eGL_ENUM, samp->m_magFilter ) )); + GLMPRINTF(("-D- minFilter [ %s ]", GLMDecode( eGL_ENUM, samp->m_minFilter ) )); + GLMPRINTF(("-D- srgb [ %s ]", samp->m_srgb ? "T" : "F" )); + GLMPRINTF(("-D- shadowFilter [ %s ]", samp->m_compareMode == GL_COMPARE_R_TO_TEXTURE_ARB ? "T" : "F" )); + + // add more as needed later.. + } + } +#endif + } + + if ( (options & (1<m_attrMask; + for( int index=0; index < kGLMVertexAttributeIndexMax; index++ ) + { + uint mask = 1<m_attrs[index]; + + char sizestr[100]; + if (setdesc->m_nCompCount < 32) + { + sprintf( sizestr, "%d", setdesc->m_nCompCount); + } + else + { + strcpy( sizestr, GLMDecode( eGL_ENUM, setdesc->m_nCompCount ) ); + } + + if (pSetup->m_vtxAttribMap[index] != 0xBB) + { + GLMPRINTF(("-D- attr=%-2d decl=$%s%1d stride=%-2d offset=%-3d buf=%08x size=%s type=%s normalized=%s ", + index, + GLMDecode(eD3D_VTXDECLUSAGE, pSetup->m_vtxAttribMap[index]>>4 ), + pSetup->m_vtxAttribMap[index]&0x0F, + setdesc->m_stride, + setdesc->m_offset, + setdesc->m_pBuffer, + sizestr, + GLMDecode( eGL_ENUM, setdesc->m_datatype), + setdesc->m_normalized?"Y":"N" + )); + } + else + { + // the attrib map is referencing an attribute that is not wired up in the vertex setup... + DebuggerBreak(); + } + } + } + } + + if ( (options & (1<m_drawStart; + int end = info->m_drawEnd; + int endLimit = start + (1<=0) + { + mark += sprintf(mark, "-D- %04d: ", vtxIndex ); + } + + // for transform dumping, we latch values as we spot them + float vtxPos[4]; + int vtxBoneIndices[4]; // only three get used + float vtxBoneWeights[4]; // only three get used and index 2 is synthesized from 0 and 1 + + vtxPos[0] = vtxPos[1] = vtxPos[2] = 0.0; + vtxPos[3] = 1.0; + + vtxBoneIndices[0] = vtxBoneIndices[1] = vtxBoneIndices[2] = vtxBoneIndices[3] = 0; + vtxBoneWeights[0] = vtxBoneWeights[1] = vtxBoneWeights[2] = vtxBoneWeights[3] = 0.0; + + for( int attr = 0; attr < kGLMVertexAttributeIndexMax; attr++ ) + { + if (pSetup->m_attrMask & (1<m_attrs[ attr ]; + + // print that attribute. + + // on OSX, VB's never move unless resized. You can peek at them when unmapped. Safe enough for debug.. + char *bufferBase = (char*)desc->m_pBuffer->m_pLastMappedAddress; + + uint stride = desc->m_stride; + uint fieldoffset = desc->m_offset; + uint baseoffset = vtxIndex * stride; + + char *attrBase = bufferBase + baseoffset + fieldoffset; + + uint usage = pSetup->m_vtxAttribMap[attr]>>4; + uint usageindex = pSetup->m_vtxAttribMap[attr]&0x0F; + + if (vtxIndex <0) + { + mark += sprintf(mark, "[%s%1d @ offs=%04d / strd %03d] ", GLMDecode(eD3D_VTXDECLUSAGE, usage ), usageindex, fieldoffset, stride ); + } + else + { + mark += sprintf(mark, "[%s%1d ", GLMDecode(eD3D_VTXDECLUSAGE, usage ), usageindex ); + + if (desc->m_nCompCount<32) + { + for( uint which = 0; which < desc->m_nCompCount; which++ ) + { + static char *fieldname = "xyzw"; + switch( desc->m_datatype ) + { + case GL_FLOAT: + { + float *floatbase = (float*)attrBase; + mark += sprintf(mark, (usage != D3DDECLUSAGE_TEXCOORD) ? "%c%7.3f " : "%c%.3f", fieldname[which], floatbase[which] ); + + if (usage==D3DDECLUSAGE_POSITION) + { + if (which<4) + { + // latch pos + vtxPos[which] = floatbase[which]; + } + } + + if (usage==D3DDECLUSAGE_BLENDWEIGHT) + { + if (which<4) + { + // latch weight + vtxBoneWeights[which] = floatbase[which]; + } + } + } + break; + + case GL_UNSIGNED_BYTE: + { + unsigned char *unchbase = (unsigned char*)attrBase; + mark += sprintf(mark, "%c$%02X ", fieldname[which], unchbase[which] ); + } + break; + + default: + // hold off on other formats for now + mark += sprintf(mark, "%c????? ", fieldname[which] ); + break; + } + } + } + else // special path for BGRA bytes which are expressed in GL by setting the *size* to GL_BGRA (gross large enum) + { + switch(desc->m_nCompCount) + { + case GL_BGRA: // byte reversed color + { + for( int which = 0; which < 4; which++ ) + { + static const char *fieldname = "BGRA"; + switch( desc->m_datatype ) + { + case GL_UNSIGNED_BYTE: + { + unsigned char *unchbase = (unsigned char*)attrBase; + mark += sprintf(mark, "%c$%02X ", fieldname[which], unchbase[which] ); + + if (usage==D3DDECLUSAGE_BLENDINDICES) + { + if (which<4) + { + // latch index + vtxBoneIndices[which] = unchbase[which]; // ignoring the component reverse which BGRA would inflict, but we also ignore it below so it matches up. + } + } + } + break; + + default: + DebuggerBreak(); + break; + } + } + } + break; + } + } + mark += sprintf(mark, "] " ); + } + } + } + GLMPrintStr( buf, eDebugDump ); + + if (vtxIndex >=0) + { + // if transform dumping requested, and we've reached the actual vert dump phase, do it + float vtxout[4]; + char *translabel = NULL; // NULL means no print... + + switch( g_vertDumpMode ) + { + case eDumpVertsNoTransformDump: break; + + case eDumpVertsTransformedByViewProj: // viewproj is slot 8 + { + float *viewproj = &m_programParamsF[ kGLMVertexProgram ].m_values[8][0]; + transform_dp4( vtxPos, viewproj, 4, vtxout ); + translabel = "post-viewproj"; + } + break; + + case eDumpVertsTransformedByModelViewProj: // modelviewproj is slot 4 + { + float *modelviewproj = &m_programParamsF[ kGLMVertexProgram ].m_values[4][0]; + transform_dp4( vtxPos, modelviewproj, 4, vtxout ); + translabel = "post-modelviewproj"; + } + break; + + case eDumpVertsTransformedByBoneZeroThenViewProj: + { + float postbone[4]; + postbone[3] = 1.0; + + float *bonemat = &m_programParamsF[ kGLMVertexProgram ].m_values[58][0]; + transform_dp4( vtxPos, bonemat, 3, postbone ); + + float *viewproj = &m_programParamsF[ kGLMVertexProgram ].m_values[8][0]; // viewproj is slot 8 + transform_dp4( postbone, viewproj, 4, vtxout ); + + translabel = "post-bone0-viewproj"; + } + break; + + case eDumpVertsTransformedByBonesThenViewProj: + { + //float bone[4][4]; // [bone index][bone member] // members are adjacent + + vtxout[0] = vtxout[1] = vtxout[2] = vtxout[3] = 0; + + // unpack the third weight + vtxBoneWeights[2] = 1.0 - (vtxBoneWeights[0] + vtxBoneWeights[1]); + + for( int ibone=0; ibone<3; ibone++ ) + { + int boneindex = vtxBoneIndices[ ibone ]; + float *bonemat = &m_programParamsF[ kGLMVertexProgram ].m_values[58+(boneindex*3)][0]; + + float boneweight = vtxBoneWeights[ibone]; + + float postbonevtx[4]; + + transform_dp4( vtxPos, bonemat, 3, postbonevtx ); + + // add weighted sum into output + for( int which=0; which<4; which++ ) + { + vtxout[which] += boneweight * postbonevtx[which]; + } + } + + // fix W ? do we care ? check shaders to see what they do... + translabel = "post-skin3bone-viewproj"; + } + break; + } + if(translabel) + { + // for extra credit, do the perspective divide and viewport + + GLMPRINTF(("-D- %-24s: [ %7.4f %7.4f %7.4f %7.4f ]", translabel, vtxout[0],vtxout[1],vtxout[2],vtxout[3] )); + GLMPRINTF(("-D-" )); + } + } + + if (vtxIndex<0) + { + vtxIndex = start-1; // for printing of the data (note it will be incremented at bottom of loop, so bias down by 1) + } + else + { // no more < and > around vert dump lines + //mark += sprintf(mark, "" ); + } + } + } + + if (options & (1<m_editable->OpenInEditor(); + } + + if (m_drawingProgram[ kGLMFragmentProgram ]) + { + m_drawingProgram[ kGLMFragmentProgram ]->m_editable->OpenInEditor(); + } + #endif + } +/* + if (options & (1<<)) + { + } +*/ + // trailer line + GLMPRINTF(("-D- ===================================================================================== end %s %d frame %d", batchtype, m_nBatchCounter, m_debugFrameIndex )); + + GLMSetIndent(oldIndent); +} + +// here is the table that binds knob numbers to names. change at will. +char *g_knobnames[] = +{ +/*0*/ "dummy", + +/*1*/ "FB-SRGB", + #if 0 + /*1*/ "tex-U0-bias", // src left + /*2*/ "tex-V0-bias", // src upper + /*3*/ "tex-U1-bias", // src right + /*4*/ "tex-V1-bias", // src bottom + + /*5*/ "pos-X0-bias", // dst left + /*6*/ "pos-Y0-bias", // dst upper + /*7*/ "pos-X1-bias", // dst right + /*8*/ "pos-Y1-bias", // dst bottom + #endif + +}; +int g_knobcount = sizeof( g_knobnames ) / sizeof( g_knobnames[0] ); + +void GLMContext::DebugHook( GLMDebugHookInfo *info ) +{ + // FIXME: This has seriously bitrotted. + return; + + bool debughook = false; + // debug hook is called after an action has taken place. + // that would be the initial action, or a repeat. + // if paused, we stay inside this function until return. + // when returning, we inform the caller if it should repeat its last action or continue. + // there is no global pause state. The rest of the app runs at the best speed it can. + + // initial stuff we do unconditionally + + // increment iteration + info->m_iteration++; // can be thought of as "number of times the caller's action has now occurred - starting at 1" + + // now set initial state guess for the info block (outcome may change below) + info->m_loop = false; + + // check prior hold-conditions to see if any of them hit. + // note we disarm each trigger once the hold has occurred (one-shot style) + + switch( info->m_caller ) + { + case eBeginFrame: + if (debughook) GLMPRINTF(("-D- Caller: BeginFrame" )); + if ( (m_holdFrameBegin>=0) && (m_holdFrameBegin==m_debugFrameIndex) ) // did we hit a frame breakpoint? + { + if (debughook) GLMPRINTF(("-D- BeginFrame trigger match, clearing m_holdFrameBegin, hold=true" )); + + m_holdFrameBegin = -1; + + info->m_holding = true; + } + break; + + case eClear: + if (debughook) GLMPRINTF(("-D- Caller: Clear" )); + if ( (m_holdBatch>=0) && (m_holdBatchFrame>=0) && ((int)m_holdBatch==(int)m_nBatchCounter) && ((int)m_holdBatchFrame==(int)m_debugFrameIndex) ) + { + if (debughook) GLMPRINTF(("-D- Clear trigger match, clearing m_holdBatch&Frame, hold=true" )); + + m_holdBatch = m_holdBatchFrame = -1; + + info->m_holding = true; + } + break; + + case eDrawElements: + if (debughook) GLMPRINTF(( (info->m_caller==eClear) ? "-D- Caller: Clear" : "-D- Caller: Draw" )); + if ( (m_holdBatch>=0) && (m_holdBatchFrame>=0) && ((int)m_holdBatch==(int)m_nBatchCounter) && ((int)m_holdBatchFrame==(int)m_debugFrameIndex) ) + { + if (debughook) GLMPRINTF(("-D- Draw trigger match, clearing m_holdBatch&Frame, hold=true" )); + + m_holdBatch = m_holdBatchFrame = -1; + + info->m_holding = true; + } + break; + + case eEndFrame: + if (debughook) GLMPRINTF(("-D- Caller: EndFrame" )); + + // check for any expired batch hold req + if ( (m_holdBatch>=0) && (m_holdBatchFrame>=0) && (m_holdBatchFrame==m_debugFrameIndex) ) + { + // you tried to say 'next batch', but there wasn't one in this frame. + // target first batch of next frame instead + if (debughook) GLMPRINTF(("-D- EndFrame noticed an expired draw hold trigger, rolling to next frame, hold=false")); + + m_holdBatch = 0; + m_holdBatchFrame++; + + info->m_holding = false; + } + + // now check for an explicit hold on end of this frame.. + if ( (m_holdFrameEnd>=0) && (m_holdFrameEnd==m_debugFrameIndex) ) + { + if (debughook) GLMPRINTF(("-D- EndFrame trigger match, clearing m_holdFrameEnd, hold=true" )); + + m_holdFrameEnd = -1; + + info->m_holding = true; + } + break; + } + + // spin until event queue is empty *and* hold is false + + int evtcount=0; + + bool refresh = info->m_holding || m_debugDelayEnable; // only refresh once per initial visit (if paused!) or follow up event input + int breakToDebugger = 0; + // 1 = break to GDB + // 2 = break to OpenGL Profiler if attached + + do + { + if (refresh) + { + if (debughook) GLMPRINTF(("-D- pushing pixels" )); + DebugPresent(); // show pixels + + uint minidumpOptions = (1<SyncWithEditable() ) + { + redrawBatch = true; + } + } + + if (m_drawingProgram[ kGLMFragmentProgram ]) + { + if( m_drawingProgram[ kGLMFragmentProgram ]->SyncWithEditable() ) + { + redrawBatch = true; + } + } + + if (redrawBatch) + { + // act as if user pressed the option-\ key + + if (m_drawingLang == kGLMGLSL) + { + // if GLSL mode, force relink - and refresh the pair cache as needed + if (m_pBoundPair) + { + // fix it in place + m_pBoundPair->RefreshProgramPair(); + } + } + + // TODO - need to retest this whole path + FlushDrawStates( 0, 0, 0 ); // this is key, because the linked shader pair may have changed (note call to PurgePairsWithShader in cglmprogram.cpp) + + GLMPRINTF(("-- Shader changed, re-running batch" )); + + m_holdBatch = m_nBatchCounter; + m_holdBatchFrame = m_debugFrameIndex; + m_debugDelayEnable = false; + + info->m_holding = false; + info->m_loop = true; + + eventCheck = false; + } + #endif + + if(eventCheck) + { + PumpWindowsMessageLoop(); + CCocoaEvent evt; + evtcount = GetEvents( &evt, 1, true ); // asking for debug events only. + if (evtcount) + { + // print it + if (debughook) GLMPRINTF(("-D- Received debug key '%c' with modifiers %x", evt.m_UnicodeKeyUnmodified, evt.m_ModifierKeyMask )); + + // flag for refresh if we spin again + refresh = 1; + + switch(evt.m_UnicodeKeyUnmodified) + { + case ' ': // toggle pause + // clear all the holds to be sure + m_holdFrameBegin = m_holdFrameEnd = m_holdBatch = m_holdBatchFrame = -1; + info->m_holding = !info->m_holding; + + if (!info->m_holding) + { + m_debugDelayEnable = false; // coming out of pause means no slow mo + } + + GLMPRINTF((info->m_holding ? "-D- Paused." : "-D- Unpaused." )); + break; + + case 'f': // frame advance + GLMPRINTF(("-D- Command: next frame" )); + m_holdFrameBegin = m_debugFrameIndex+1; // stop at top of next numbered frame + m_debugDelayEnable = false; // get there fast + + info->m_holding = false; + break; + + case ']': // ahead 1 batch + case '}': // ahead ten batches + { + int delta = evt.m_UnicodeKeyUnmodified == ']' ? 1 : 10; + m_holdBatch = m_nBatchCounter+delta; + m_holdBatchFrame = m_debugFrameIndex; + m_debugDelayEnable = false; // get there fast + info->m_holding = false; + GLMPRINTF(("-D- Command: advance %d batches to %d", delta, m_holdBatch )); + } + break; + + case '[': // back one batch + case '{': // back 10 batches + { + int delta = evt.m_UnicodeKeyUnmodified == '[' ? -1 : -10; + m_holdBatch = m_nBatchCounter + delta; + if (m_holdBatch<0) + { + m_holdBatch = 0; + } + m_holdBatchFrame = m_debugFrameIndex+1; // next frame, but prev batch # + m_debugDelayEnable = false; // get there fast + info->m_holding = false; + GLMPRINTF(("-D- Command: rewind %d batches to %d", delta, m_holdBatch )); + } + break; + + case '\\': // batch rerun + + m_holdBatch = m_nBatchCounter; + m_holdBatchFrame = m_debugFrameIndex; + m_debugDelayEnable = false; + info->m_holding = false; + info->m_loop = true; + GLMPRINTF(("-D- Command: re-run batch %d", m_holdBatch )); + break; + + case 'c': // toggle auto color clear + m_autoClearColor = !m_autoClearColor; + GLMPRINTF((m_autoClearColor ? "-D- Auto color clear ON" : "-D- Auto color clear OFF" )); + break; + + case 's': // toggle auto stencil clear + m_autoClearStencil = !m_autoClearStencil; + GLMPRINTF((m_autoClearStencil ? "-D- Auto stencil clear ON" : "-D- Auto stencil clear OFF" )); + break; + + case 'd': // toggle auto depth clear + m_autoClearDepth = !m_autoClearDepth; + GLMPRINTF((m_autoClearDepth ? "-D- Auto depth clear ON" : "-D- Auto depth clear OFF" )); + break; + + case '.': // break to debugger or insta-quit + if (evt.m_ModifierKeyMask & (1<m_holding = true; + info->m_loop = true; // so when you come back from debugger, you get another spin (i.e. you enter paused mode) + } + break; + + case 'g': // break to OGLP and enable OGLP logging of spew + if (GLMDetectOGLP()) // if this comes back true, there will be a breakpoint set on glColor4sv. + { + uint channelMask = GLMDetectAvailableChannels(); // will re-assert whether spew goes to OGLP log + + if (channelMask & (1<m_holding = true; + info->m_loop = true; // so when you come back from debugger, you get another spin (i.e. you enter paused mode) + } + } + break; + + case '_': // toggle slow mo + m_debugDelayEnable = !m_debugDelayEnable; + break; + + case '-': // go slower + if (m_debugDelayEnable) + { + // already in slow mo, so lower speed + m_debugDelay <<= 1; // double delay + if (m_debugDelay > (1<<24)) + { + m_debugDelay = (1<<24); + } + } + else + { + // enter slow mo + m_debugDelayEnable = true; + } + break; + + case '=': // go faster + if (m_debugDelayEnable) + { + // already in slow mo, so raise speed + m_debugDelay >>= 1; // halve delay + if (m_debugDelay < (1<<17)) + { + m_debugDelay = (1<<17); + } + } + else + { + // enter slow mo + m_debugDelayEnable = true; + } + break; + + case 'v': + // open vs in editor (foreground pop) + #if GLMDEBUG + if (m_drawingProgram[ kGLMVertexProgram ]) + { + m_drawingProgram[ kGLMVertexProgram ]->m_editable->OpenInEditor( true ); + } + #endif + break; + + case 'p': + // open fs/ps in editor (foreground pop) + #if GLMDEBUG + if (m_drawingProgram[ kGLMFragmentProgram ]) + { + m_drawingProgram[ kGLMFragmentProgram ]->m_editable->OpenInEditor( true ); + } + #endif + break; + + case '<': // dump fewer verts + case '>': // dump more verts + { + int delta = (evt.m_UnicodeKeyUnmodified=='>') ? 1 : -1; + g_maxVertsToDumpLog2 = MIN( MAX( g_maxVertsToDumpLog2+delta, 0 ), 16 ); + + // just re-dump the verts + DebugDump( info, 1<= eLastDumpVertsMode) + { + // wrap + newmode = eDumpVertsNoTransformDump; + } + g_vertDumpMode = (EGLMVertDumpMode)newmode; + + GLMPRINTF(("-D- New vert dump mode is %s", g_vertDumpModeNames[g_vertDumpMode] )); + } + break; + + case 'u': // more crawl + { + CStackCrawlParams cp; + memset( &cp, 0, sizeof(cp) ); + cp.m_frameLimit = kMaxCrawlFrames; + + GetStackCrawl(&cp); + + GLMPRINTF(("-D-" )); + GLMPRINTF(("-D- extended stack crawl:")); + for( uint i=0; i< cp.m_frameCount; i++) + { + GLMPRINTF(("-D-\t%s", cp.m_crawlNames[i] )); + } + } + + break; + + case 'q': + DebugDump( info, 0xFFFFFFFF, g_vertDumpMode ); + break; + + + case 'H': + case 'h': + { + // toggle drawing language. hold down shift key to do it immediately. + + if (m_caps.m_hasDualShaders) + { + bool immediate; + + immediate = evt.m_UnicodeKeyUnmodified == 'H'; // (evt.m_ModifierKeyMask & (1<=0) && (flavorSelect m_selKnobMaxValue) + { + val = m_selKnobMaxValue; + } + // send new value back to the knob + GLMKnob( g_knobnames[ m_selKnobIndex ], &val ); + } + + if (evt.m_UnicodeKeyUnmodified == 'z') + { + // zero + val = 0.0f; + + // send new value back to the knob + GLMKnob( g_knobnames[ m_selKnobIndex ], &val ); + } + + GLMPRINTF(("-D- Knob # %d (%s) set to %f (%f/1024.0)", m_selKnobIndex, g_knobnames[ m_selKnobIndex ], val, val * 1024.0 )); + + ThreadSleep( 500000 / 1000 ); + + refresh = false; + } + } + break; + + } + } + } + } while( ((evtcount>0) || info->m_holding) && (!breakToDebugger) ); + + if (m_debugDelayEnable) + { + ThreadSleep( m_debugDelay / 1000 ); + } + + if (breakToDebugger) + { + switch (breakToDebugger) + { + case 1: + DebuggerBreak(); + break; + + case 2: + // What the fuck? + break; + } + // re-flush all GLM states so you can fiddle with them in the debugger. then run the batch again and spin.. + ForceFlushStates(); + } +} + +void GLMContext::DebugPresent( void ) +{ + CGLMTex *drawBufferTex = m_drawingFBO->m_attach[kAttColor0].m_tex; + gGL->glFinish(); + Present( drawBufferTex ); +} + +void GLMContext::DebugClear( void ) +{ + // get old clear color + GLClearColor_t clearcol_orig; + m_ClearColor.Read( &clearcol_orig,0 ); + + // new clear color + GLClearColor_t clearcol; + clearcol.r = m_autoClearColorValues[0]; + clearcol.g = m_autoClearColorValues[1]; + clearcol.b = m_autoClearColorValues[2]; + clearcol.a = m_autoClearColorValues[3]; + m_ClearColor.Write( &clearcol ); // don't check, don't defer + + uint mask = 0; + + if (m_autoClearColor) mask |= GL_COLOR_BUFFER_BIT; + if (m_autoClearDepth) mask |= GL_DEPTH_BUFFER_BIT; + if (m_autoClearStencil) mask |= GL_STENCIL_BUFFER_BIT; + + gGL->glClear( mask ); + gGL->glFinish(); + + // put old color back + m_ClearColor.Write( &clearcol_orig ); // don't check, don't defer +} + +#endif + +void GLMContext::CheckNative( void ) +{ + // note that this is available in release. We don't use GLMPRINTF for that reason. + // note we do not get called unless either slow-batch asserting or logging is enabled. +#ifdef OSX + bool gpuProcessing; + GLint fragmentGPUProcessing, vertexGPUProcessing; + + CGLGetParameter (CGLGetCurrentContext(), kCGLCPGPUFragmentProcessing, &fragmentGPUProcessing); + CGLGetParameter(CGLGetCurrentContext(), kCGLCPGPUVertexProcessing, &vertexGPUProcessing); + + // spews then asserts. + // that way you can enable both, get log output on a pair if it's slow, and then the debugger will pop. + if(m_slowSpewEnable) + { + if ( !vertexGPUProcessing ) + { + m_drawingProgram[ kGLMVertexProgram ]->LogSlow( m_drawingLang ); + } + if ( !fragmentGPUProcessing ) + { + m_drawingProgram[ kGLMFragmentProgram ]->LogSlow( m_drawingLang ); + } + } + + if(m_slowAssertEnable) + { + if ( !vertexGPUProcessing || !fragmentGPUProcessing) + { + Assert( !"slow batch" ); + } + } +#else + //Assert( !"impl GLMContext::CheckNative()" ); + + if (m_checkglErrorsAfterEveryBatch) + { + // This is slow, and somewhat redundant (-gldebugoutput uses the GL_ARB_debug_output extension, which can be at least asynchronous), but having a straightforward backup can be useful. + // This is useful for callstack purposes - GL_ARB_debug_output may break in a different thread that the thread triggering the GL error. + //gGL->glFlush(); + GLenum errorcode = (GLenum)gGL->glGetError(); + if ( errorcode != GL_NO_ERROR ) + { + const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); + + char buf[512]; + V_snprintf( buf, sizeof( buf), "\nGL ERROR! %08x = '%s'\n", errorcode, decodedStr ); + + // Make sure the dev sees something, because these errors can happen early enough that DevMsg() does nothing. +#ifdef WIN32 + OutputDebugStringA( buf ); +#else + printf( "%s", buf ); +#endif + } + } + +#endif + +} + + + +// debug font +void GLMContext::GenDebugFontTex( void ) +{ + if(!m_debugFontTex) + { + // make a 128x128 RGBA texture + GLMTexLayoutKey key; + memset( &key, 0, sizeof(key) ); + + key.m_texGLTarget = GL_TEXTURE_2D; + key.m_xSize = 128; + key.m_ySize = 128; + key.m_zSize = 1; + key.m_texFormat = D3DFMT_A8R8G8B8; + key.m_texFlags = 0; + + m_debugFontTex = NewTex( &key, 1, "GLM debug font" ); + + + //----------------------------------------------------- + GLMTexLockParams lockreq; + + lockreq.m_tex = m_debugFontTex; + lockreq.m_face = 0; + lockreq.m_mip = 0; + + GLMTexLayoutSlice *slice = &m_debugFontTex->m_layout->m_slices[ lockreq.m_tex->CalcSliceIndex( lockreq.m_face, lockreq.m_mip ) ]; + + lockreq.m_region.xmin = lockreq.m_region.ymin = lockreq.m_region.zmin = 0; + lockreq.m_region.xmax = slice->m_xSize; + lockreq.m_region.ymax = slice->m_ySize; + lockreq.m_region.zmax = slice->m_zSize; + + lockreq.m_readback = false; + + char *lockAddress; + int yStride; + int zStride; + + m_debugFontTex->Lock( &lockreq, &lockAddress, &yStride, &zStride ); + + //----------------------------------------------------- + // fetch elements of font data and make texels... we're doing the whole slab so we don't really need the stride info + unsigned long *destTexelPtr = (unsigned long *)lockAddress; + + for( int index = 0; index < 16384; index++ ) + { + if (g_glmDebugFontMap[index] == ' ') + { + // clear + *destTexelPtr = 0x00000000; + } + else + { + // opaque white (drawing code can modulate if desired) + *destTexelPtr = 0xFFFFFFFF; + } + destTexelPtr++; + } + + //----------------------------------------------------- + GLMTexLockParams unlockreq; + + unlockreq.m_tex = m_debugFontTex; + unlockreq.m_face = 0; + unlockreq.m_mip = 0; + + // region need not matter for unlocks + unlockreq.m_region.xmin = unlockreq.m_region.ymin = unlockreq.m_region.zmin = 0; + unlockreq.m_region.xmax = unlockreq.m_region.ymax = unlockreq.m_region.zmax = 0; + + unlockreq.m_readback = false; + + m_debugFontTex->Unlock( &unlockreq ); + + //----------------------------------------------------- + // change up the tex sampling on this texture to be "nearest" not linear + + //----------------------------------------------------- + + // don't leave texture bound on the TMU + BindTexToTMU( NULL, 0 ); + + // also make the index and vertex buffers for use - up to 1K indices and 1K verts + + uint indexBufferSize = 1024*2; + + m_debugFontIndices = NewBuffer(kGLMIndexBuffer, indexBufferSize, 0); // two byte indices + + // we go ahead and lock it now, and fill it with indices 0-1023. + char *indices = NULL; + GLMBuffLockParams idxLock; + idxLock.m_nOffset = 0; + idxLock.m_nSize = indexBufferSize; + idxLock.m_bNoOverwrite = false; + idxLock.m_bDiscard = true; + m_debugFontIndices->Lock( &idxLock, &indices ); + for( int i=0; i<1024; i++) + { + unsigned short *idxPtr = &((unsigned short*)indices)[i]; + *idxPtr = i; + } + m_debugFontIndices->Unlock(); + + m_debugFontVertices = NewBuffer(kGLMVertexBuffer, 1024 * 128, 0); // up to 128 bytes per vert + } +} + +#define MAX_DEBUG_CHARS 256 +struct GLMDebugTextVertex +{ + float x,y,z; + float u,v; + char rgba[4]; +}; + +void GLMContext::DrawDebugText( float x, float y, float z, float drawCharWidth, float drawCharHeight, char *string ) +{ + if (!m_debugFontTex) + { + GenDebugFontTex(); + } + + // setup needed to draw text + + // we're assuming that +x goes left to right on screen, no billboarding math in here + // and that +y goes bottom up + // caller knows projection / rectangle so it gets to decide vertex spacing + + // debug font must be bound to TMU 0 + // texturing enabled + // alpha blending enabled + // generate a quad per character + // characters are 6px wide by 11 px high. + // upper left character in tex is 0x20 + // y axis will need to be flipped for display + + // for any character in 0x20 - 0x7F - here are the needed UV's + + // leftU = ((character % 16) * 6.0f / 128.0f) + // rightU = lowU + (6.0 / 128.0); + // topV = ((character - 0x20) * 11.0f / 128.0f) + // bottomV = lowV + (11.0f / 128.0f) + + int stringlen = strlen( string ); + if (stringlen > MAX_DEBUG_CHARS) + { + stringlen = MAX_DEBUG_CHARS; + } + + // lock + char *vertices = NULL; + GLMBuffLockParams vtxLock; + vtxLock.m_nOffset = 0; + vtxLock.m_nSize = 1024 * stringlen; + vtxLock.m_bNoOverwrite = false; + vtxLock.m_bDiscard = false; + m_debugFontVertices->Lock( &vtxLock, &vertices ); + + GLMDebugTextVertex *vtx = (GLMDebugTextVertex*)vertices; + GLMDebugTextVertex *vtxOutPtr = vtx; + + for( int charindex = 0; charindex < stringlen; charindex++ ) + { + float leftU,rightU,topV,bottomV; + + int character = (int)string[charindex]; + character -= 0x20; + if ( (character<0) || (character > 0x7F) ) + { + character = '*' - 0x20; + } + + leftU = ((character & 0x0F) * 6.0f ) / 128.0f; + rightU = leftU + (6.0f / 128.0f); + + topV = ((character >> 4) * 11.0f ) / 128.0f; + bottomV = topV + (11.0f / 128.0f); + + float posx,posy,posz; + + posx = x + (drawCharWidth * (float)charindex); + posy = y; + posz = z; + + // generate four verts + // first vert will be upper left of displayed quad (low X, high Y) then we go clockwise + for( int quadvert = 0; quadvert < 4; quadvert++ ) + { + bool isTop = (quadvert <2); // verts 0 and 1 + bool isLeft = (quadvert & 1) == (quadvert >> 1); // verts 0 and 3 + + vtxOutPtr->x = posx + (isLeft ? 0.0f : drawCharWidth); + vtxOutPtr->y = posy + (isTop ? drawCharHeight : 0.0f); + vtxOutPtr->z = posz; + + vtxOutPtr->u = isLeft ? leftU : rightU; + vtxOutPtr->v = isTop ? topV : bottomV; + + vtxOutPtr++; + } + } + + // verts are done. + // unlock... + + m_debugFontVertices->Unlock(); + + // make a vertex setup + GLMVertexSetup vertSetup; + + // position, color, tc = 0, 3, 8 + vertSetup.m_attrMask = (1<glDisable( GL_DEPTH_TEST ); + + gGL->glEnable(GL_TEXTURE_2D); + + SetVertexAttributes( &vertSetup ); + + gGL->glDrawArrays( GL_QUADS, 0, stringlen * 4 ); + + SetVertexAttributes( NULL ); + + gGL->glDisable(GL_TEXTURE_2D); + + BindTexToTMU( pPrevTex, 0 ); +} + +//=============================================================================== + +void GLMgrSelfTests( void ) +{ + return; // until such time as the tests are revised or axed + + GLMDisplayParams glmParams; + glmParams.m_fsEnable = false; + + glmParams.m_vsyncEnable = false; // "The runtime updates the window client area immediately and might do so more + glmParams.m_backBufferWidth = 1024; + glmParams.m_backBufferHeight = 768; + glmParams.m_backBufferFormat = D3DFMT_A8R8G8B8; + glmParams.m_multiSampleCount = 2; + + glmParams.m_enableAutoDepthStencil = true; + glmParams.m_autoDepthStencilFormat = D3DFMT_D24S8; + + glmParams.m_fsRefreshHz = 60; + + glmParams.m_mtgl = true; + glmParams.m_focusWindow = 0; + + // make a new context on renderer 0. + GLMContext *ctx = GLMgr::aGLMgr()->NewContext( NULL, &glmParams ); ////FIXME you can't make contexts this way any more. + if (!ctx) + { + DebuggerBreak(); // no go + return; + } + + // make a test object based on that context. + //int alltests[] = {0,1,2,3, -1}; + //int newtests[] = {3, -1}; + int twotests[] = {2, -1}; + //int notests[] = {-1}; + + int *testlist = twotests; + + GLMTestParams params; + memset( ¶ms, 0, sizeof(params) ); + + params.m_ctx = ctx; + params.m_testList = testlist; + + params.m_glErrToDebugger = true; + params.m_glErrToConsole = true; + + params.m_intlErrToDebugger = true; + params.m_intlErrToConsole = true; + + params.m_frameCount = 1000; + + GLMTester testobj( ¶ms ); + + testobj.RunTests( ); + + GLMgr::aGLMgr()->DelContext( ctx ); +} + +void GLMContext::SetDefaultStates( void ) +{ + GLM_FUNC; + CheckCurrent(); + + m_AlphaTestEnable.Default(); + m_AlphaTestFunc.Default(); + + m_AlphaToCoverageEnable.Default(); + + m_CullFaceEnable.Default(); + m_CullFrontFace.Default(); + + m_PolygonMode.Default(); + m_DepthBias.Default(); + + m_ClipPlaneEnable.Default(); + m_ClipPlaneEquation.Default(); + + m_ScissorEnable.Default(); + m_ScissorBox.Default(); + + m_ViewportBox.Default(); + m_ViewportDepthRange.Default(); + + m_ColorMaskSingle.Default(); + m_ColorMaskMultiple.Default(); + + m_BlendEnable.Default(); + m_BlendFactor.Default(); + m_BlendEquation.Default(); + m_BlendColor.Default(); + //m_BlendEnableSRGB.Default(); // this isn't useful until there is an FBO bound - in fact it will trip a GL error. + + m_DepthTestEnable.Default(); + m_DepthFunc.Default(); + m_DepthMask.Default(); + + m_StencilTestEnable.Default(); + m_StencilFunc.Default(); + m_StencilOp.Default(); + m_StencilWriteMask.Default(); + + m_ClearColor.Default(); + m_ClearDepth.Default(); + m_ClearStencil.Default(); +} + +void GLMContext::VerifyStates ( void ) +{ + GLM_FUNC; + CheckCurrent(); + + // bare bones sanity check, head over to the debugger if our sense of the current context state is not correct + // we should only want to call this after a flush or the checks will flunk. + + if( m_AlphaTestEnable.Check() ) GLMStop(); + if( m_AlphaTestFunc.Check() ) GLMStop(); + + if( m_AlphaToCoverageEnable.Check() ) GLMStop(); + + if( m_CullFaceEnable.Check() ) GLMStop(); + if( m_CullFrontFace.Check() ) GLMStop(); + + if( m_PolygonMode.Check() ) GLMStop(); + if( m_DepthBias.Check() ) GLMStop(); + + if( m_ClipPlaneEnable.Check() ) GLMStop(); + //if( m_ClipPlaneEquation.Check() ) GLMStop(); + + if( m_ScissorEnable.Check() ) GLMStop(); + if( m_ScissorBox.Check() ) GLMStop(); + + + if( m_ViewportBox.Check() ) GLMStop(); + if( m_ViewportDepthRange.Check() ) GLMStop(); + + if( m_ColorMaskSingle.Check() ) GLMStop(); + if( m_ColorMaskMultiple.Check() ) GLMStop(); + + if( m_BlendEnable.Check() ) GLMStop(); + if( m_BlendFactor.Check() ) GLMStop(); + if( m_BlendEquation.Check() ) GLMStop(); + if( m_BlendColor.Check() ) GLMStop(); + + // only do this as caps permit + if (m_caps.m_hasGammaWrites) + { + if( m_BlendEnableSRGB.Check() ) GLMStop(); + } + + if( m_DepthTestEnable.Check() ) GLMStop(); + if( m_DepthFunc.Check() ) GLMStop(); + if( m_DepthMask.Check() ) GLMStop(); + + if( m_StencilTestEnable.Check() ) GLMStop(); + if( m_StencilFunc.Check() ) GLMStop(); + if( m_StencilOp.Check() ) GLMStop(); + if( m_StencilWriteMask.Check() ) GLMStop(); + + if( m_ClearColor.Check() ) GLMStop(); + if( m_ClearDepth.Check() ) GLMStop(); + if( m_ClearStencil.Check() ) GLMStop(); +} + +static inline uint GetDataTypeSizeInBytes( GLenum dataType ) +{ + switch ( dataType ) + { + case GL_BYTE: + case GL_UNSIGNED_BYTE: + return 1; + case GL_SHORT: + case GL_UNSIGNED_SHORT: + case GL_HALF_FLOAT: + return 2; + case GL_INT: + case GL_FLOAT: + return 4; + default: + Assert( 0 ); + break; + } + return 0; +} + +#ifndef OSX + +void GLMContext::DrawRangeElementsNonInline( GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, uint baseVertex, CGLMBuffer *pIndexBuf ) +{ +#if GLMDEBUG + GLM_FUNC; +#else + //tmZone( TELEMETRY_LEVEL0, TMZF_NONE, "%s %d-%d count:%d mode:%d type:%d", __FUNCTION__, start, end, count, mode, type ); +#endif + + ++m_nBatchCounter; + + SetIndexBuffer( pIndexBuf ); + + void *indicesActual = (void*)indices; + + if ( pIndexBuf->m_bPseudo ) + { + // you have to pass actual address, not offset + indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_pPseudoBuf ); + } + if (pIndexBuf->m_bUsingPersistentBuffer) + { + indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_nPersistentBufferStartOffset ); + } + +#if GL_ENABLE_INDEX_VERIFICATION + // Obviously only for debugging. + if ( !pIndexBuf->IsSpanValid( (uint)indices, count * GetDataTypeSizeInBytes( type ) ) ) + { + // The consumption range crosses more than one lock span, or the lock is trying to consume a bad IB range. + DXABSTRACT_BREAK_ON_ERROR(); + } + + if ( ( type == GL_UNSIGNED_SHORT ) && ( pIndexBuf->m_bPseudo ) ) + { + Assert( start <= end ); + for ( int i = 0; i < count; i++) + { + uint n = ((const uint16*)indicesActual)[i]; + if ( ( n < start ) || ( n > end ) ) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + } + + unsigned char *pVertexShaderAttribMap = m_pDevice->m_vertexShader->m_vtxAttribMap; + const int nMaxVertexAttributesToCheck = m_drawingProgram[ kGLMVertexProgram ]->m_maxVertexAttrs; + + IDirect3DVertexDeclaration9 *pVertDecl = m_pDevice->m_pVertDecl; + const uint8 *pVertexAttribDescToStreamIndex = pVertDecl->m_VertexAttribDescToStreamIndex; + + // FIXME: Having to duplicate all this flush logic is terrible here + for( int nMask = 1, nIndex = 0; nIndex < nMaxVertexAttributesToCheck; ++nIndex, nMask <<= 1 ) + { + uint8 vertexShaderAttrib = pVertexShaderAttribMap[ nIndex ]; + + uint nDeclIndex = pVertexAttribDescToStreamIndex[vertexShaderAttrib]; + if ( nDeclIndex == 0xFF ) + continue; + + D3DVERTEXELEMENT9_GL *pDeclElem = &pVertDecl->m_elements[nDeclIndex]; + + Assert( ( ( vertexShaderAttrib >> 4 ) == pDeclElem->m_dxdecl.Usage ) && ( ( vertexShaderAttrib & 0x0F ) == pDeclElem->m_dxdecl.UsageIndex) ); + + const uint nStreamIndex = pDeclElem->m_dxdecl.Stream; + const D3DStreamDesc *pStream = &m_pDevice->m_streams[ nStreamIndex ]; + + CGLMBuffer *pBuf = m_pDevice->m_vtx_buffers[ nStreamIndex ]; + if ( pBuf == m_pDevice->m_pDummy_vtx_buffer ) + continue; + + Assert( pStream->m_vtxBuffer->m_vtxBuffer == pBuf ); + + int nBufOffset = pDeclElem->m_gldecl.m_offset + pStream->m_offset; + Assert( nBufOffset >= 0 ); + Assert( nBufOffset < (int)pBuf->m_nSize ); + + uint nBufSize = pStream->m_vtxBuffer->m_vtxBuffer->m_nSize; + uint nDataTypeSize = GetDataTypeSizeInBytes( pDeclElem->m_gldecl.m_datatype ); + uint nActualStride = pStream->m_stride ? pStream->m_stride : nDataTypeSize; + uint nStart = nBufOffset + ( start + baseVertex ) * nActualStride; + uint nEnd = nBufOffset + ( end + baseVertex ) * nActualStride + nDataTypeSize; + + if ( nEnd > nBufSize ) + { + DXABSTRACT_BREAK_ON_ERROR(); + } + + if ( !pStream->m_vtxBuffer->m_vtxBuffer->IsSpanValid( nStart, nEnd - nStart ) ) + { + // The draw is trying to consume a range of the bound VB that hasn't been set to valid data! + DXABSTRACT_BREAK_ON_ERROR(); + } + } + } +#endif + + Assert( m_drawingLang == kGLMGLSL ); + + if ( m_pBoundPair ) + { + gGL->glDrawRangeElementsBaseVertex( mode, start, end, count, type, indicesActual, baseVertex ); + +#if GLMDEBUG + if ( m_slowCheckEnable ) + { + CheckNative(); + } +#endif + } +} + +#else + +// support for OSX 10.6 (no support for glDrawRangeElementsBaseVertex) +void GLMContext::DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, CGLMBuffer *pIndexBuf) +{ + GLM_FUNC; + + // CheckCurrent(); + ++m_nBatchCounter; // batch index increments unconditionally on entry + + SetIndexBuffer( pIndexBuf ); + void *indicesActual = (void*)indices; + if ( pIndexBuf->m_bPseudo ) + { + // you have to pass actual address, not offset + indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_pPseudoBuf ); + } + if (pIndexBuf->m_bUsingPersistentBuffer) + { + indicesActual = (void*)( (int)indicesActual + (int)pIndexBuf->m_nPersistentBufferStartOffset ); + } + +#if GLMDEBUG + // init debug hook information + GLMDebugHookInfo info; + memset(&info, 0, sizeof(info)); + info.m_caller = eDrawElements; + + // relay parameters we're operating under + info.m_drawMode = mode; + info.m_drawStart = start; + info.m_drawEnd = end; + info.m_drawCount = count; + info.m_drawType = type; + info.m_drawIndices = indices; + + do + { + // obey global options re pre-draw clear + if (m_autoClearColor || m_autoClearDepth || m_autoClearStencil) + { + GLMPRINTF(("-- DrawRangeElements auto clear")); + this->DebugClear(); + } + + // always sync with editable shader text prior to draw +#if GLMDEBUG + // TODO - fixup OSX 10.6 m_boundProg not used in this version togl (m_pBoundPair) + //FIXME disengage this path if context is in GLSL mode.. + // it will need fixes to get the shader pair re-linked etc if edits happen anyway. + + if (m_boundProgram[kGLMVertexProgram]) + { + m_boundProgram[kGLMVertexProgram]->SyncWithEditable(); + } + else + { + AssertOnce(!"drawing with no vertex program bound"); + } + + if (m_boundProgram[kGLMFragmentProgram]) + { + m_boundProgram[kGLMFragmentProgram]->SyncWithEditable(); + } + else + { + AssertOnce(!"drawing with no fragment program bound"); + } +#endif + + // do the drawing + if ( m_pBoundPair ) + { + gGL->glDrawRangeElements(mode, start, end, count, type, indicesActual); + // GLMCheckError(); + + if (m_slowCheckEnable) + { + CheckNative(); + } + } + this->DebugHook(&info); + } while (info.m_loop); +#else + if ( m_pBoundPair ) + { + gGL->glDrawRangeElements(mode, start, end, count, type, indicesActual); + +#if GLMDEBUG + if ( m_slowCheckEnable ) + { + CheckNative(); + } +#endif + } +#endif +} + +#endif // !OSX + +#if 0 +// helper function to do enable or disable in one step +void glSetEnable( GLenum which, bool enable ) +{ + if (enable) + gGL->glEnable(which); + else + gGL->glDisable(which); +} + +// helper function for int vs enum clarity +void glGetEnumv( GLenum which, GLenum *dst ) +{ + gGL->glGetIntegerv( which, (int*)dst ); +} +#endif + +//=============================================================================== + + +GLMTester::GLMTester(GLMTestParams *params) +{ + m_params = *params; + + m_drawFBO = NULL; + m_drawColorTex = NULL; + m_drawDepthTex = NULL; +} + +GLMTester::~GLMTester() +{ +} + +void GLMTester::StdSetup( void ) +{ + GLMContext *ctx = m_params.m_ctx; + + m_drawWidth = 1024; + m_drawHeight = 768; + + // make an FBO to draw into and activate it. no depth buffer yet + m_drawFBO = ctx->NewFBO(); + + // make color buffer texture + + GLMTexLayoutKey colorkey; + //CGLMTex *colortex; + memset( &colorkey, 0, sizeof(colorkey) ); + + colorkey.m_texGLTarget = GL_TEXTURE_2D; + colorkey.m_xSize = m_drawWidth; + colorkey.m_ySize = m_drawHeight; + colorkey.m_zSize = 1; + + colorkey.m_texFormat = D3DFMT_A8R8G8B8; + colorkey.m_texFlags = kGLMTexRenderable; + + m_drawColorTex = ctx->NewTex( &colorkey ); + + // do not leave that texture bound on the TMU + ctx->BindTexToTMU(NULL, 0 ); + + + // attach color to FBO + GLMFBOTexAttachParams colorParams; + memset( &colorParams, 0, sizeof(colorParams) ); + + colorParams.m_tex = m_drawColorTex; + colorParams.m_face = 0; + colorParams.m_mip = 0; + colorParams.m_zslice= 0; // for clarity.. + + m_drawFBO->TexAttach( &colorParams, kAttColor0 ); + + // check it. + bool ready = m_drawFBO->IsReady(); + InternalError( !ready, "drawing FBO no go"); + + // bind it + ctx->BindFBOToCtx( m_drawFBO, GL_FRAMEBUFFER ); + + gGL->glViewport(0, 0, (GLsizei) m_drawWidth, (GLsizei) m_drawHeight ); + CheckGLError("stdsetup viewport"); + + gGL->glScissor( 0,0, (GLsizei) m_drawWidth, (GLsizei) m_drawHeight ); + CheckGLError("stdsetup scissor"); + + //gGL->glOrtho( -1,1, -1,1, -1,1 ); + CheckGLError("stdsetup ortho"); + + // activate debug font + ctx->GenDebugFontTex(); +} + +void GLMTester::StdCleanup( void ) +{ + GLMContext *ctx = m_params.m_ctx; + + // unbind + ctx->BindFBOToCtx( NULL, GL_FRAMEBUFFER ); + + // del FBO + if (m_drawFBO) + { + ctx->DelFBO( m_drawFBO ); + m_drawFBO = NULL; + } + + // del tex + if (m_drawColorTex) + { + ctx->DelTex( m_drawColorTex ); + m_drawColorTex = NULL; + } + + if (m_drawDepthTex) + { + ctx->DelTex( m_drawDepthTex ); + m_drawDepthTex = NULL; + } +} + + +void GLMTester::Clear( void ) +{ + GLMContext *ctx = m_params.m_ctx; + ctx->MakeCurrent(); + + gGL->glViewport(0, 0, (GLsizei) m_drawWidth, (GLsizei) m_drawHeight ); + gGL->glScissor( 0,0, (GLsizei) m_drawWidth, (GLsizei) m_drawHeight ); + //gGL->glOrtho( -1,1, -1,1, -1,1 ); + CheckGLError("clearing viewport"); + + // clear to black + gGL->glClearColor(0.0f, 0.0f, 0.0, 1.0f); + CheckGLError("clearing color"); + + gGL->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + CheckGLError("clearing"); + + //glFinish(); + //CheckGLError("clear finish"); +} + +void GLMTester::Present( int seed ) +{ + GLMContext *ctx = m_params.m_ctx; + ctx->Present( m_drawColorTex ); +} + +void GLMTester::CheckGLError( const char *comment ) +{ +return; + char errbuf[1024]; + + //borrowed from GLMCheckError.. slightly different + + if (!comment) + { + comment = ""; + } + + GLenum errorcode = (GLenum)gGL->glGetError(); + GLenum errorcode2 = 0; + if ( errorcode != GL_NO_ERROR ) + { + const char *decodedStr = GLMDecode( eGL_ERROR, errorcode ); + const char *decodedStr2 = ""; + + if ( errorcode == GL_INVALID_FRAMEBUFFER_OPERATION ) + { + // dig up the more detailed FBO status + errorcode2 = gGL->glCheckFramebufferStatus( GL_FRAMEBUFFER ); + + decodedStr2 = GLMDecode( eGL_ERROR, errorcode2 ); + + sprintf( errbuf, "\n%s - GL Error %08x/%08x = '%s / %s'\n", comment, errorcode, errorcode2, decodedStr, decodedStr2 ); + } + else + { + sprintf( errbuf, "\n%s - GL Error %08x = '%s'\n", comment, errorcode, decodedStr ); + } + + if ( m_params.m_glErrToConsole ) + { + printf("%s", errbuf ); + } + + if ( m_params.m_glErrToDebugger ) + { + DebuggerBreak(); + } + } +} + +void GLMTester::InternalError( int errcode, char *comment ) +{ + if (errcode) + { + if (m_params.m_intlErrToConsole) + { + printf("%s - error %d\n", comment, errcode ); + } + + if (m_params.m_intlErrToDebugger) + { + DebuggerBreak(); + } + } +} + + +void GLMTester::RunTests( void ) +{ + int *testList = m_params.m_testList; + + while( (*testList >=0) && (*testList < 20) ) + { + RunOneTest( *testList++ ); + } +} + +void GLMTester::RunOneTest( int testindex ) +{ + // this might be better with 'ptmf' style + switch(testindex) + { + case 0: Test0(); break; + case 1: Test1(); break; + case 2: Test2(); break; + case 3: Test3(); break; + + default: + DebuggerBreak(); // unrecognized + } +} + +// ##################################################################################################################### + +// some fixed lists which may be useful to all tests + +D3DFORMAT g_drawTexFormatsGLMT[] = // -1 terminated +{ + D3DFMT_A8R8G8B8, + D3DFMT_A4R4G4B4, + D3DFMT_X8R8G8B8, + D3DFMT_X1R5G5B5, + D3DFMT_A1R5G5B5, + D3DFMT_L8, + D3DFMT_A8L8, + D3DFMT_R8G8B8, + D3DFMT_A8, + D3DFMT_R5G6B5, + D3DFMT_DXT1, + D3DFMT_DXT3, + D3DFMT_DXT5, + D3DFMT_A32B32G32R32F, + D3DFMT_A16B16G16R16, + + (D3DFORMAT)-1 +}; + +D3DFORMAT g_fboColorTexFormatsGLMT[] = // -1 terminated +{ + D3DFMT_A8R8G8B8, + //D3DFMT_A4R4G4B4, //unsupported + D3DFMT_X8R8G8B8, + D3DFMT_X1R5G5B5, + //D3DFMT_A1R5G5B5, //unsupported + D3DFMT_A16B16G16R16F, + D3DFMT_A32B32G32R32F, + D3DFMT_R5G6B5, + + (D3DFORMAT)-1 +}; + +D3DFORMAT g_fboDepthTexFormatsGLMT[] = // -1 terminated, but note 0 for "no depth" mode +{ + (D3DFORMAT)0, + D3DFMT_D16, + D3DFMT_D24X8, + D3DFMT_D24S8, + + (D3DFORMAT)-1 +}; + + +// ##################################################################################################################### + +void GLMTester::Test0( void ) +{ + // make and delete a bunch of textures. + // lock and unlock them. + // use various combos of - + + // √texel format + // √2D | 3D | cube map + // √mipped / not + // √POT / NPOT + // large / small / square / rect + // square / rect + + GLMContext *ctx = m_params.m_ctx; + ctx->MakeCurrent(); + + CUtlVector< CGLMTex* > testTextures; // will hold all the built textures + + // test stage loop + // 0 is creation + // 1 is lock/unlock + // 2 is deletion + + for( int teststage = 0; teststage < 3; teststage++) + { + int innerindex = 0; // increment at stage switch + // format loop + for( D3DFORMAT *fmtPtr = g_drawTexFormatsGLMT; *fmtPtr != ((D3DFORMAT)-1); fmtPtr++ ) + { + // form loop + GLenum forms[] = { GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, (GLenum)-1 }; + + for( GLenum *formPtr = forms; *formPtr != ((GLenum)-1); formPtr++ ) + { + // mip loop + for( int mipped = 0; mipped < 2; mipped++ ) + { + // large / square / pot loop + // &4 == large &2 == square &1 == POT + // NOTE you *have to be square* for cube maps. + + for( int aspect = 0; aspect < 8; aspect++ ) + { + switch( teststage ) + { + case 0: + { + GLMTexLayoutKey key; + memset( &key, 0, sizeof(key) ); + + key.m_texGLTarget = *formPtr; + key.m_texFormat = *fmtPtr; + if (mipped) + key.m_texFlags |= kGLMTexMipped; + + // assume big, square, POT, and 3D, then adjust as needed + key.m_xSize = key.m_ySize = key.m_zSize = 256; + + if ( !(aspect&4) ) // big or little ? + { + // little + key.m_xSize >>= 2; + key.m_ySize >>= 2; + key.m_zSize >>= 2; + } + + if ( key.m_texGLTarget != GL_TEXTURE_CUBE_MAP ) + { + if ( !(aspect & 2) ) // square or rect? + { + // rect + key.m_ySize >>= 1; + key.m_zSize >>= 2; + } + } + + if ( !(aspect&1) ) // POT or NPOT? + { + // NPOT + key.m_xSize += 56; + key.m_ySize += 56; + key.m_zSize += 56; + } + + // 2D, 3D, cube map ? + if (key.m_texGLTarget!=GL_TEXTURE_3D) + { + // 2D or cube map: flatten Z extent to one texel + key.m_zSize = 1; + } + else + { + // 3D: knock down Z quite a bit so our test case does not run out of RAM + key.m_zSize >>= 3; + if (!key.m_zSize) + { + key.m_zSize = 1; + } + } + + CGLMTex *newtex = ctx->NewTex( &key ); + CheckGLError( "tex create test"); + InternalError( newtex==NULL, "tex create test" ); + + testTextures.AddToTail( newtex ); + printf("\n[%5d] created tex %s",innerindex,newtex->m_layout->m_layoutSummary ); + } + break; + + case 1: + { + CGLMTex *ptex = testTextures[innerindex]; + + for( int face=0; face m_layout->m_faceCount; face++) + { + for( int mip=0; mip m_layout->m_mipCount; mip++) + { + GLMTexLockParams lockreq; + + lockreq.m_tex = ptex; + lockreq.m_face = face; + lockreq.m_mip = mip; + + GLMTexLayoutSlice *slice = &ptex->m_layout->m_slices[ ptex->CalcSliceIndex( face, mip ) ]; + + lockreq.m_region.xmin = lockreq.m_region.ymin = lockreq.m_region.zmin = 0; + lockreq.m_region.xmax = slice->m_xSize; + lockreq.m_region.ymax = slice->m_ySize; + lockreq.m_region.zmax = slice->m_zSize; + + char *lockAddress; + int yStride; + int zStride; + + ptex->Lock( &lockreq, &lockAddress, &yStride, &zStride ); + CheckGLError( "tex lock test"); + InternalError( lockAddress==NULL, "null lock address"); + + // write some texels of this flavor: + // red 75% green 40% blue 15% alpha 80% + + GLMGenTexelParams gtp; + + gtp.m_format = ptex->m_layout->m_format->m_d3dFormat; + gtp.m_dest = lockAddress; + gtp.m_chunkCount = (slice->m_xSize * slice->m_ySize * slice->m_zSize) / (ptex->m_layout->m_format->m_chunkSize * ptex->m_layout->m_format->m_chunkSize); + gtp.m_byteCountLimit = slice->m_storageSize; + gtp.r = 0.75; + gtp.g = 0.40; + gtp.b = 0.15; + gtp.a = 0.80; + + GLMGenTexels( >p ); + + InternalError( gtp.m_bytesWritten != gtp.m_byteCountLimit, "byte count mismatch from GLMGenTexels" ); + } + } + + for( int face=0; face m_layout->m_faceCount; face++) + { + for( int mip=0; mip m_layout->m_mipCount; mip++) + { + GLMTexLockParams unlockreq; + + unlockreq.m_tex = ptex; + unlockreq.m_face = face; + unlockreq.m_mip = mip; + + // region need not matter for unlocks + unlockreq.m_region.xmin = unlockreq.m_region.ymin = unlockreq.m_region.zmin = 0; + unlockreq.m_region.xmax = unlockreq.m_region.ymax = unlockreq.m_region.zmax = 0; + + //char *lockAddress; + //int yStride; + //int zStride; + + ptex->Unlock( &unlockreq ); + + CheckGLError( "tex unlock test"); + } + } + printf("\n[%5d] locked/wrote/unlocked tex %s",innerindex, ptex->m_layout->m_layoutSummary ); + } + break; + + case 2: + { + CGLMTex *dtex = testTextures[innerindex]; + + printf("\n[%5d] deleting tex %s",innerindex, dtex->m_layout->m_layoutSummary ); + ctx->DelTex( dtex ); + CheckGLError( "tex delete test"); + } + break; + } // end stage switch + innerindex++; + } // end aspect loop + } // end mip loop + } // end form loop + } // end format loop + } // end stage loop +} + +// ##################################################################################################################### +void GLMTester::Test1( void ) +{ + // FBO exercises + GLMContext *ctx = m_params.m_ctx; + ctx->MakeCurrent(); + + // FBO color format loop + for( D3DFORMAT *colorFmtPtr = g_fboColorTexFormatsGLMT; *colorFmtPtr != ((D3DFORMAT)-1); colorFmtPtr++ ) + { + // FBO depth format loop + for( D3DFORMAT *depthFmtPtr = g_fboDepthTexFormatsGLMT; *depthFmtPtr != ((D3DFORMAT)-1); depthFmtPtr++ ) + { + // mip loop + for( int mipped = 0; mipped < 2; mipped++ ) + { + GLenum forms[] = { GL_TEXTURE_2D, GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, (GLenum)-1 }; + + // form loop + for( GLenum *formPtr = forms; *formPtr != ((GLenum)-1); formPtr++ ) + { + //=============================================== make an FBO + CGLMFBO *fbo = ctx->NewFBO(); + + //=============================================== make a color texture + GLMTexLayoutKey colorkey; + memset( &colorkey, 0, sizeof(colorkey) ); + + switch(*formPtr) + { + case GL_TEXTURE_2D: + colorkey.m_texGLTarget = GL_TEXTURE_2D; + colorkey.m_xSize = 800; + colorkey.m_ySize = 600; + colorkey.m_zSize = 1; + break; + + case GL_TEXTURE_3D: + colorkey.m_texGLTarget = GL_TEXTURE_3D; + colorkey.m_xSize = 800; + colorkey.m_ySize = 600; + colorkey.m_zSize = 32; + break; + + case GL_TEXTURE_CUBE_MAP: + colorkey.m_texGLTarget = GL_TEXTURE_CUBE_MAP; + colorkey.m_xSize = 800; + colorkey.m_ySize = 800; // heh, cube maps have to have square sides... + colorkey.m_zSize = 1; + break; + } + + colorkey.m_texFormat = *colorFmtPtr; + colorkey.m_texFlags = kGLMTexRenderable; + // decide if we want mips + if (mipped) + { + colorkey.m_texFlags |= kGLMTexMipped; + } + + CGLMTex *colorTex = ctx->NewTex( &colorkey ); + // Note that GLM will notice the renderable flag, and force texels to be written + // so the FBO will be complete + + //=============================================== attach color + GLMFBOTexAttachParams colorParams; + memset( &colorParams, 0, sizeof(colorParams) ); + + colorParams.m_tex = colorTex; + colorParams.m_face = (colorkey.m_texGLTarget == GL_TEXTURE_CUBE_MAP) ? 2 : 0; // just steer to an alternate face as a test + + colorParams.m_mip = (colorkey.m_texFlags & kGLMTexMipped) ? 2 : 0; // pick non-base mip slice + + colorParams.m_zslice= (colorkey.m_texGLTarget == GL_TEXTURE_3D) ? 3 : 0; // just steer to an alternate slice as a test; + + fbo->TexAttach( &colorParams, kAttColor0 ); + + + //=============================================== optional depth tex + CGLMTex *depthTex = NULL; + + if (*depthFmtPtr > 0 ) + { + GLMTexLayoutKey depthkey; + memset( &depthkey, 0, sizeof(depthkey) ); + + depthkey.m_texGLTarget = GL_TEXTURE_2D; + depthkey.m_xSize = colorkey.m_xSize >> colorParams.m_mip; // scale depth tex to match color tex + depthkey.m_ySize = colorkey.m_ySize >> colorParams.m_mip; + depthkey.m_zSize = 1; + + depthkey.m_texFormat = *depthFmtPtr; + depthkey.m_texFlags = kGLMTexRenderable | kGLMTexIsDepth; // no mips. + if (depthkey.m_texFormat==D3DFMT_D24S8) + { + depthkey.m_texFlags |= kGLMTexIsStencil; + } + + depthTex = ctx->NewTex( &depthkey ); + + + //=============================================== attach depth + GLMFBOTexAttachParams depthParams; + memset( &depthParams, 0, sizeof(depthParams) ); + + depthParams.m_tex = depthTex; + depthParams.m_face = 0; + depthParams.m_mip = 0; + depthParams.m_zslice= 0; + + EGLMFBOAttachment depthAttachIndex = (depthkey.m_texFlags & kGLMTexIsStencil) ? kAttDepthStencil : kAttDepth; + fbo->TexAttach( &depthParams, depthAttachIndex ); + } + + printf("\n FBO:\n color tex %s\n depth tex %s", + colorTex->m_layout->m_layoutSummary, + depthTex ? depthTex->m_layout->m_layoutSummary : "none" + ); + + // see if FBO is happy + bool ready = fbo->IsReady(); + + printf("\n -> %s\n", ready ? "pass" : "fail" ); + + // unbind + ctx->BindFBOToCtx( NULL, GL_FRAMEBUFFER ); + + // del FBO + ctx->DelFBO(fbo); + + // del texes + ctx->DelTex( colorTex ); + if (depthTex) ctx->DelTex( depthTex ); + } // end form loop + } // end mip loop + } // end depth loop + } // end color loop +} + +// ##################################################################################################################### + +static int selftest2_seed = 0; // inc this every run to force main thread to teardown/reset display view +void GLMTester::Test2( void ) +{ + GLMContext *ctx = m_params.m_ctx; + ctx->MakeCurrent(); + + StdSetup(); // default test case drawing setup + + // draw stuff (loop...) + for( int i=0; iglClearColor(clear_color[0], clear_color[1], clear_color[2], clear_color[3]); + CheckGLError("test2 clear color"); + + gGL->glClear(GL_COLOR_BUFFER_BIT+GL_DEPTH_BUFFER_BIT+GL_STENCIL_BUFFER_BIT); + CheckGLError("test2 clearing"); + + // try out debug text + for( int j=0; j<16; j++) + { + char text[256]; + sprintf(text, "The quick brown fox jumped over the lazy dog %d times", i ); + + float theta = ( (i*0.10f) + (j * 6.28f) ) / 16.0f; + + float posx = cos(theta) * 0.5; + float posy = sin(theta) * 0.5; + + float charwidth = 6.0 * (2.0 / 1024.0); + float charheight = 11.0 * (2.0 / 768.0); + + ctx->DrawDebugText( posx, posy, 0.0f, charwidth, charheight, text ); + } + gGL->glFinish(); + CheckGLError("test2 finish"); + + Present( selftest2_seed ); + } + + StdCleanup(); + + selftest2_seed++; +} + +// ##################################################################################################################### + +static char g_testVertexProgram01 [] = +{ + "!!ARBvp1.0 \n" + "TEMP vertexClip; \n" + "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.position; \n" + "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.position; \n" + "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.position; \n" + "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.position; \n" + "ADD vertexClip.y, vertexClip.x, vertexClip.y; \n" + "MOV result.position, vertexClip; \n" + "MOV result.color, vertex.color; \n" + "MOV result.texcoord[0], vertex.texcoord; \n" + "END \n" +}; + +static char g_testFragmentProgram01 [] = +{ + "!!ARBfp1.0 \n" + "TEMP color; \n" + "MUL color, fragment.texcoord[0].y, 2.0; \n" + "ADD color, 1.0, -color; \n" + "ABS color, color; \n" + "ADD result.color, 1.0, -color; \n" + "MOV result.color.a, 1.0; \n" + "END \n" +}; + + +// generic attrib versions.. + +static char g_testVertexProgram01_GA [] = +{ + "!!ARBvp1.0 \n" + "TEMP vertexClip; \n" + "DP4 vertexClip.x, state.matrix.mvp.row[0], vertex.attrib[0]; \n" + "DP4 vertexClip.y, state.matrix.mvp.row[1], vertex.attrib[0]; \n" + "DP4 vertexClip.z, state.matrix.mvp.row[2], vertex.attrib[0]; \n" + "DP4 vertexClip.w, state.matrix.mvp.row[3], vertex.attrib[0]; \n" + "ADD vertexClip.y, vertexClip.x, vertexClip.y; \n" + "MOV result.position, vertexClip; \n" + "MOV result.color, vertex.attrib[3]; \n" + "MOV result.texcoord[0], vertex.attrib[8]; \n" + "END \n" +}; + +static char g_testFragmentProgram01_GA [] = +{ + "!!ARBfp1.0 \n" + "TEMP color; \n" + "TEX color, fragment.texcoord[0], texture[0], 2D;" + //"MUL color, fragment.texcoord[0].y, 2.0; \n" + //"ADD color, 1.0, -color; \n" + //"ABS color, color; \n" + //"ADD result.color, 1.0, -color; \n" + //"MOV result.color.a, 1.0; \n" + "MOV result.color, color; \n" + "END \n" +}; + + +void GLMTester::Test3( void ) +{ + /************************** + XXXXXXXXXXXXXXXXXXXXXX stale test code until we revise the program interface + + GLMContext *ctx = m_params.m_ctx; + ctx->MakeCurrent(); + + StdSetup(); // default test case drawing setup + + // make vertex&pixel shader + CGLMProgram *vprog = ctx->NewProgram( kGLMVertexProgram, g_testVertexProgram01_GA ); + ctx->BindProgramToCtx( kGLMVertexProgram, vprog ); + + CGLMProgram *fprog = ctx->NewProgram( kGLMFragmentProgram, g_testFragmentProgram01_GA ); + ctx->BindProgramToCtx( kGLMFragmentProgram, fprog ); + + // draw stuff (loop...) + for( int i=0; iDrawDebugText( posx, posy, 0.0f, charwidth, charheight, text ); + } + glFinish(); + CheckGLError("test3 finish"); + + Present( 3333 ); + } + + StdCleanup(); + *****************************/ +} + +#if GLMDEBUG +void GLMTriggerDebuggerBreak() +{ + // we call an obscure GL function which we know has been breakpointed in the OGLP function list + +// What the fuck is that? +// static signed short nada[] = { -1,-1,-1,-1 }; +// gGL->glColor4sv( nada ); +} +#endif diff --git a/togles/linuxwin/glmgr_flush.inl b/togles/linuxwin/glmgr_flush.inl new file mode 100644 index 00000000..6061dfde --- /dev/null +++ b/togles/linuxwin/glmgr_flush.inl @@ -0,0 +1,632 @@ +// BE VERY VERY CAREFUL what you do in these function. They are extremely hot, and calling the wrong GL API's in here will crush perf. (especially on NVidia threaded drivers). + +#include "togles/linuxwin/glmgr.h" + +FORCEINLINE uint32 bitmix32(uint32 a) +{ + a -= (a<<6); + //a ^= (a>>17); + //a -= (a<<9); + a ^= (a<<4); + //a -= (a<<3); + //a ^= (a<<10); + a ^= (a>>15); + return a; +} + +#ifndef OSX + +FORCEINLINE GLuint GLMContext::FindSamplerObject( const GLMTexSamplingParams &desiredParams ) +{ + int h = bitmix32( desiredParams.m_bits + desiredParams.m_borderColor ) & ( cSamplerObjectHashSize - 1 ); + while ( ( m_samplerObjectHash[h].m_params.m_bits != desiredParams.m_bits ) || ( m_samplerObjectHash[h].m_params.m_borderColor != desiredParams.m_borderColor ) ) + { + if ( !m_samplerObjectHash[h].m_params.m_packed.m_isValid ) + break; + if ( ++h >= cSamplerObjectHashSize ) + h = 0; + } + + if ( !m_samplerObjectHash[h].m_params.m_packed.m_isValid ) + { + GLMTexSamplingParams &hashParams = m_samplerObjectHash[h].m_params; + hashParams = desiredParams; + hashParams.SetToSamplerObject( m_samplerObjectHash[h].m_samplerObject ); + if ( ++m_nSamplerObjectHashNumEntries == cSamplerObjectHashSize ) + { + // TODO: Support resizing + Error( "Sampler object hash is full, increase cSamplerObjectHashSize" ); + } + } + + return m_samplerObjectHash[h].m_samplerObject; +} + +#endif // !OSX + +// BE VERY CAREFUL WHAT YOU DO IN HERE. This is called on every batch, even seemingly simple changes can kill perf. +FORCEINLINE void GLMContext::FlushDrawStates( uint nStartIndex, uint nEndIndex, uint nBaseVertex ) // shadersOn = true for draw calls, false for clear calls +{ + Assert( m_drawingLang == kGLMGLSL ); // no support for ARB shaders right now (and NVidia reports that they aren't worth targeting under Windows/Linux for various reasons anyway) + Assert( ( m_drawingFBO == m_boundDrawFBO ) && ( m_drawingFBO == m_boundReadFBO ) ); // this check MUST succeed + Assert( m_pDevice->m_pVertDecl ); + +#if GLMDEBUG + GLM_FUNC; +#endif + + GL_BATCH_PERF( m_FlushStats.m_nTotalBatchFlushes++; ) + +#if GLMDEBUG + bool tex0_srgb = (m_boundDrawFBO[0].m_attach[0].m_tex->m_layout->m_key.m_texFlags & kGLMTexSRGB) != 0; + + // you can only actually use the sRGB FB state on some systems.. check caps + if (m_caps.m_hasGammaWrites) + { + GLBlendEnableSRGB_t writeSRGBState; + m_BlendEnableSRGB.Read( &writeSRGBState, 0 ); // the client set value, not the API-written value yet.. + bool draw_srgb = writeSRGBState.enable != 0; + + if (draw_srgb) + { + if (tex0_srgb) + { + // good - draw mode and color tex agree + } + else + { + // bad + + // Client has asked to write sRGB into a texture that can't do it. + // there is no way to satisfy this unless we change the RT tex and we avoid doing that. + // (although we might consider a ** ONE TIME ** promotion. + // this shouldn't be a big deal if the tex format is one where it doesn't matter like 32F. + + GLMPRINTF(("-Z- srgb-enabled FBO conflict: attached tex %08x [%s] is not SRGB", m_boundDrawFBO[0].m_attach[0].m_tex, m_boundDrawFBO[0].m_attach[0].m_tex->m_layout->m_layoutSummary )); + + // do we shoot down the srgb-write state for this batch? + // I think the runtime will just ignore it. + } + } + else + { + if (tex0_srgb) + { + // odd - client is not writing sRGB into a texture which *can* do it. + //GLMPRINTF(( "-Z- srgb-disabled FBO conflict: attached tex %08x [%s] is SRGB", m_boundFBO[0].m_attach[0].m_tex, m_boundFBO[0].m_attach[0].m_tex->m_layout->m_layoutSummary )); + //writeSRGBState.enable = true; + //m_BlendEnableSRGB.Write( &writeSRGBState ); + } + else + { + // good - draw mode and color tex agree + } + } + } +#endif + + Assert( m_drawingProgram[ kGLMVertexProgram ] ); + Assert( m_drawingProgram[ kGLMFragmentProgram ] ); + + Assert( ( m_drawingProgram[kGLMVertexProgram]->m_type == kGLMVertexProgram ) && ( m_drawingProgram[kGLMFragmentProgram]->m_type == kGLMFragmentProgram ) ); + Assert( m_drawingProgram[ kGLMVertexProgram ]->m_bTranslatedProgram && m_drawingProgram[ kGLMFragmentProgram ]->m_bTranslatedProgram ); + +#if GLMDEBUG + // Depth compare mode check + uint nCurMask = 1, nShaderSamplerMask = m_drawingProgram[kGLMFragmentProgram]->m_samplerMask; + for ( int nSamplerIndex = 0; nSamplerIndex < GLM_SAMPLER_COUNT; ++nSamplerIndex, nCurMask <<= 1 ) + { + if ( !m_samplers[nSamplerIndex].m_pBoundTex ) + continue; + + if ( m_samplers[nSamplerIndex].m_pBoundTex->m_layout->m_mipCount == 1 ) + { + if ( m_samplers[nSamplerIndex].m_samp.m_packed.m_mipFilter == D3DTEXF_LINEAR ) + { + GLMDebugPrintf( "Sampler %u has mipmap filtering enabled on a texture without mipmaps! (texture name: %s, pixel shader: %s)!\n", + nSamplerIndex, + m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel ? m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel : "?", + m_drawingProgram[kGLMFragmentProgram]->m_shaderName ); + } + } + + if ( ( nShaderSamplerMask & nCurMask ) == 0 ) + continue; + + if ( m_samplers[nSamplerIndex].m_pBoundTex->m_layout->m_mipCount == 1 ) + { + if ( m_samplers[nSamplerIndex].m_samp.m_packed.m_mipFilter == D3DTEXF_LINEAR ) + { + // Note this is not always an error - shadow buffer debug visualization shaders purposely want to read shadow depths (and not do the comparison) + GLMDebugPrintf( "Sampler %u has mipmap filtering enabled on a texture without mipmaps! (texture name: %s, pixel shader: %s)!\n", + nSamplerIndex, + m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel ? m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel : "?", + m_drawingProgram[kGLMFragmentProgram]->m_shaderName ); + } + } + + bool bSamplerIsDepth = ( m_samplers[nSamplerIndex].m_pBoundTex->m_layout->m_key.m_texFlags & kGLMTexIsDepth ) != 0; + bool bSamplerShadow = m_samplers[nSamplerIndex].m_samp.m_packed.m_compareMode != 0; + + bool bShaderShadow = ( m_drawingProgram[kGLMFragmentProgram]->m_nShadowDepthSamplerMask & nCurMask ) != 0; + + if ( bShaderShadow ) + { + // Shader expects shadow depth sampling at this sampler index + // Must have a depth texture and compare mode must be enabled + if ( !bSamplerIsDepth || !bSamplerShadow ) + { + // FIXME: This occasionally occurs in L4D2 when CShaderAPIDx8::ExecuteCommandBuffer() sets the TEXTURE_WHITE texture in the flashlight depth texture slot. + GLMDebugPrintf( "Sampler %u's compare mode (%u) or format (depth=%u) is not consistent with pixel shader's compare mode (%u) (texture name: %s, pixel shader: %s)!\n", + nSamplerIndex, bSamplerShadow, bSamplerIsDepth, bShaderShadow, + m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel ? m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel : "?", + m_drawingProgram[kGLMFragmentProgram]->m_shaderName ); + } + } + else + { + // Shader does not expect shadow depth sampling as this sampler index + // We don't care if comparemode is enabled, but we can't have a depth texture in this sampler + if ( bSamplerIsDepth ) + { + GLMDebugPrintf( "Sampler %u is a depth texture but the pixel shader's shadow depth sampler mask does not expect depth here (texture name: %s, pixel shader: %s)!\n", + nSamplerIndex, + m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel ? m_samplers[nSamplerIndex].m_pBoundTex->m_debugLabel : "?", + m_drawingProgram[kGLMFragmentProgram]->m_shaderName ); + } + } + } +#endif + + if ( m_bDirtyPrograms ) + { + m_bDirtyPrograms = false; + + CGLMShaderPair *pNewPair = m_pairCache->SelectShaderPair( m_drawingProgram[ kGLMVertexProgram ], m_drawingProgram[ kGLMFragmentProgram ], 0 ); + + if ( pNewPair != m_pBoundPair ) + { +#if GL_BATCH_TELEMETRY_ZONES + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "NewProgram" ); +#endif + + if ( !pNewPair->m_valid ) + { + if ( !pNewPair->ValidateProgramPair() ) + { + goto flush_error_exit; + } + } + + gGL->glUseProgram( (GLuint)pNewPair->m_program ); + + GL_BATCH_PERF( m_FlushStats.m_nTotalProgramPairChanges++; ) + + if ( !m_pBoundPair ) + { + GL_BATCH_PERF( m_FlushStats.m_nNewPS++; ) + GL_BATCH_PERF( m_FlushStats.m_nNewVS++; ) + } + else + { + GL_BATCH_PERF( if ( pNewPair->m_fragmentProg != m_pBoundPair->m_fragmentProg ) m_FlushStats.m_nNewPS++; ) + GL_BATCH_PERF( if ( pNewPair->m_vertexProg != m_pBoundPair->m_vertexProg ) m_FlushStats.m_nNewVS++; ) + } + +#if GL_BATCH_PERF_ANALYSIS + tmMessage( TELEMETRY_LEVEL2, TMMF_ICON_NOTE, "V:%s (V Regs:%u V Bone Regs:%u) F:%s (F Regs:%u)", + m_drawingProgram[ kGLMVertexProgram ]->m_shaderName, + m_drawingProgram[ kGLMVertexProgram ]->m_descs[kGLMGLSL].m_highWater, + m_drawingProgram[ kGLMVertexProgram ]->m_descs[kGLMGLSL].m_VSHighWaterBone, + m_drawingProgram[ kGLMFragmentProgram ]->m_shaderName, + m_drawingProgram[ kGLMFragmentProgram ]->m_descs[kGLMGLSL].m_highWater ); +#endif + + m_pBoundPair = pNewPair; + + // set the dirty levels appropriately since the program changed and has never seen any of the current values. + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = 0; + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = m_drawingProgram[ kGLMVertexProgram ]->m_descs[kGLMGLSL].m_highWater; + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = m_drawingProgram[ kGLMVertexProgram ]->m_descs[kGLMGLSL].m_VSHighWaterBone; + + m_programParamsF[kGLMFragmentProgram].m_firstDirtySlotNonBone = 0; + m_programParamsF[kGLMFragmentProgram].m_dirtySlotHighWaterNonBone = m_drawingProgram[ kGLMFragmentProgram ]->m_descs[kGLMGLSL].m_highWater; + + // bool and int dirty levels get set to max, we don't have actual high water marks for them + // code which sends the values must clamp on these types. + m_programParamsB[kGLMVertexProgram].m_dirtySlotCount = kGLMProgramParamBoolLimit; + m_programParamsB[kGLMFragmentProgram].m_dirtySlotCount = kGLMProgramParamBoolLimit; + + m_programParamsI[kGLMVertexProgram].m_dirtySlotCount = kGLMProgramParamInt4Limit; + m_programParamsI[kGLMFragmentProgram].m_dirtySlotCount = 0; + + // check fragment buffers used (MRT) + if( pNewPair->m_fragmentProg->m_fragDataMask != m_fragDataMask ) + { + gGL->glDrawBuffers( pNewPair->m_fragmentProg->m_numDrawBuffers, pNewPair->m_fragmentProg->m_drawBuffers ); + m_fragDataMask = pNewPair->m_fragmentProg->m_fragDataMask; + } + } + } + + Assert( m_ViewportBox.GetData().width == (int)( m_ViewportBox.GetData().widthheight & 0xFFFF ) ); + Assert( m_ViewportBox.GetData().height == (int)( m_ViewportBox.GetData().widthheight >> 16 ) ); + + m_pBoundPair->UpdateScreenUniform( m_ViewportBox.GetData().widthheight ); + + GL_BATCH_PERF( m_FlushStats.m_nNumChangedSamplers += m_nNumDirtySamplers ); + +#if !defined( OSX ) // no support for sampler objects in OSX 10.6 (GL 2.1 profile) + if ( m_bUseSamplerObjects) + { + while ( m_nNumDirtySamplers ) + { + const uint nSamplerIndex = m_nDirtySamplers[--m_nNumDirtySamplers]; + Assert( ( nSamplerIndex < GLM_SAMPLER_COUNT ) && ( !m_nDirtySamplerFlags[nSamplerIndex]) ); + + m_nDirtySamplerFlags[nSamplerIndex] = 1; + + gGL->glBindSampler( nSamplerIndex, FindSamplerObject( m_samplers[nSamplerIndex].m_samp ) ); + + GL_BATCH_PERF( m_FlushStats.m_nNumSamplingParamsChanged++ ); + +#if defined( OSX ) // valid for OSX only if using GL 3.3 context + CGLMTex *pTex = m_samplers[nSamplerIndex].m_pBoundTex; + + if( pTex && !( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) ) + { + // see if requested SRGB state differs from the known one + bool texSRGB = ( pTex->m_layout->m_key.m_texFlags & kGLMTexSRGB ) != 0; + bool glSampSRGB = m_samplers[nSamplerIndex].m_samp.m_packed.m_srgb; + + if ( texSRGB != glSampSRGB ) // mismatch + { + pTex->HandleSRGBMismatch( glSampSRGB, pTex->m_srgbFlipCount ); + } + } +#endif + } + } + else +#endif // if !defined( OSX ) + { + while ( m_nNumDirtySamplers ) + { + const uint nSamplerIndex = m_nDirtySamplers[--m_nNumDirtySamplers]; + Assert( ( nSamplerIndex < GLM_SAMPLER_COUNT ) && ( !m_nDirtySamplerFlags[nSamplerIndex]) ); + + m_nDirtySamplerFlags[nSamplerIndex] = 1; + + CGLMTex *pTex = m_samplers[nSamplerIndex].m_pBoundTex; + + if ( ( pTex ) && ( !( pTex->m_SamplingParams == m_samplers[nSamplerIndex].m_samp ) ) ) + { + SelectTMU( nSamplerIndex ); + + m_samplers[nSamplerIndex].m_samp.DeltaSetToTarget( pTex->m_texGLTarget, pTex->m_SamplingParams ); + + pTex->m_SamplingParams = m_samplers[nSamplerIndex].m_samp; + +#if defined( OSX ) + if( pTex && !( gGL->m_bHave_GL_EXT_texture_sRGB_decode ) ) + { + // see if requested SRGB state differs from the known one + bool texSRGB = ( pTex->m_layout->m_key.m_texFlags & kGLMTexSRGB ) != 0; + bool glSampSRGB = m_samplers[nSamplerIndex].m_samp.m_packed.m_srgb; + + if ( texSRGB != glSampSRGB ) // mismatch + { + pTex->HandleSRGBMismatch( glSampSRGB, pTex->m_srgbFlipCount ); + } + } +#endif + } + } + } + + // vertex stage -------------------------------------------------------------------- + if ( m_bUseBoneUniformBuffers ) + { + // vertex stage -------------------------------------------------------------------- + if ( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone ) + { + int firstDirtySlot = m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone; + int dirtySlotHighWater = MIN( m_drawingProgram[kGLMVertexProgram]->m_descs[kGLMGLSL].m_highWater, m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone ); + + GLint vconstLoc = m_pBoundPair->m_locVertexParams; + if ( ( vconstLoc >= 0 ) && ( dirtySlotHighWater > firstDirtySlot ) ) + { +#if GL_BATCH_TELEMETRY_ZONES + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "VSNonBoneUniformUpdate %u %u", firstDirtySlot, dirtySlotHighWater ); +#endif + int numSlots = dirtySlotHighWater - DXABSTRACT_VS_FIRST_BONE_SLOT; + + // consts after the bones (c217 onwards), since we use the concatenated destination array vc[], upload these consts starting from vc[58] + if( numSlots > 0 ) + { + gGL->glUniform4fv( m_pBoundPair->m_UniformBufferParams[kGLMVertexProgram][DXABSTRACT_VS_FIRST_BONE_SLOT], numSlots, &m_programParamsF[kGLMVertexProgram].m_values[(DXABSTRACT_VS_LAST_BONE_SLOT+1)][0] ); + + dirtySlotHighWater = DXABSTRACT_VS_FIRST_BONE_SLOT; + + GL_BATCH_PERF( m_nTotalVSUniformCalls++; ) + GL_BATCH_PERF( m_nTotalVSUniformsSet += numSlots; ) + + GL_BATCH_PERF( m_FlushStats.m_nFirstVSConstant = DXABSTRACT_VS_FIRST_BONE_SLOT; ) + GL_BATCH_PERF( m_FlushStats.m_nNumVSConstants += numSlots; ) + } + + numSlots = dirtySlotHighWater - firstDirtySlot; + + // consts before the bones (c0-c57) + if( numSlots > 0 ) + { + gGL->glUniform4fv( m_pBoundPair->m_UniformBufferParams[kGLMVertexProgram][firstDirtySlot], dirtySlotHighWater - firstDirtySlot, &m_programParamsF[kGLMVertexProgram].m_values[firstDirtySlot][0] ); + + GL_BATCH_PERF( m_nTotalVSUniformCalls++; ) + GL_BATCH_PERF( m_nTotalVSUniformsSet += dirtySlotHighWater - firstDirtySlot; ) + + GL_BATCH_PERF( m_FlushStats.m_nFirstVSConstant = firstDirtySlot; ) + GL_BATCH_PERF( m_FlushStats.m_nNumVSConstants += (dirtySlotHighWater - firstDirtySlot); ) + } + } + + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = 256; + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = 0; + } + + if ( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone ) + { + const GLint vconstBoneLoc = m_pBoundPair->m_locVertexBoneParams; + if ( vconstBoneLoc >= 0 ) + { + int shaderSlotsBone = 0; + if ( ( m_drawingProgram[kGLMVertexProgram]->m_descs[kGLMGLSL].m_VSHighWaterBone > 0 ) && ( m_nMaxUsedVertexProgramConstantsHint > DXABSTRACT_VS_FIRST_BONE_SLOT ) ) + { + shaderSlotsBone = MIN( m_drawingProgram[kGLMVertexProgram]->m_descs[kGLMGLSL].m_VSHighWaterBone, m_nMaxUsedVertexProgramConstantsHint - DXABSTRACT_VS_FIRST_BONE_SLOT ); + } + + int dirtySlotHighWaterBone = MIN( shaderSlotsBone, m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone ); + if ( dirtySlotHighWaterBone ) + { + uint nNumBoneRegs = dirtySlotHighWaterBone; + +#if GL_BATCH_TELEMETRY_ZONES + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "VSBoneUniformUpdate %u", nNumBoneRegs ); +#endif + + gGL->glUniform4fv( vconstBoneLoc, nNumBoneRegs, &m_programParamsF[kGLMVertexProgram].m_values[DXABSTRACT_VS_FIRST_BONE_SLOT][0] ); + + GL_BATCH_PERF( m_nTotalVSUniformBoneCalls++; ) + GL_BATCH_PERF( m_nTotalVSUniformsBoneSet += nNumBoneRegs; ) + GL_BATCH_PERF( m_FlushStats.m_nNumVSBoneConstants += nNumBoneRegs; ) + } + + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterBone = 0; + } + } + + } + else + { + if ( m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone ) + { + const int nMaxUsedShaderSlots = m_drawingProgram[kGLMVertexProgram]->m_descs[kGLMGLSL].m_highWater; + + int firstDirtySlot = m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone; + int dirtySlotHighWater = MIN( nMaxUsedShaderSlots, m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone ); + + GLint vconstLoc = m_pBoundPair->m_locVertexParams; + if ( ( vconstLoc >= 0 ) && ( dirtySlotHighWater > firstDirtySlot ) ) + { + #if GL_BATCH_TELEMETRY_ZONES + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "VSNonBoneUniformUpdate %u %u", firstDirtySlot, dirtySlotHighWater ); + #endif + gGL->glUniform4fv( m_pBoundPair->m_UniformBufferParams[kGLMVertexProgram][firstDirtySlot], dirtySlotHighWater - firstDirtySlot, &m_programParamsF[kGLMVertexProgram].m_values[firstDirtySlot][0] ); + + GL_BATCH_PERF( m_nTotalVSUniformCalls++; ) + GL_BATCH_PERF( m_nTotalVSUniformsSet += dirtySlotHighWater - firstDirtySlot; ) + + GL_BATCH_PERF( m_FlushStats.m_nFirstVSConstant = firstDirtySlot; ) + GL_BATCH_PERF( m_FlushStats.m_nNumVSConstants += (dirtySlotHighWater - firstDirtySlot); ) + } + + m_programParamsF[kGLMVertexProgram].m_firstDirtySlotNonBone = 256; + m_programParamsF[kGLMVertexProgram].m_dirtySlotHighWaterNonBone = 0; + } + } + + // see if VS uses i0, b0, b1, b2, b3. + // use a glUniform1i to set any one of these if active. skip all of them if no dirties reported. + // my kingdom for the UBO extension! + + // ------- bools ---------- // + if ( m_pBoundPair->m_bHasBoolOrIntUniforms ) + { + if ( m_programParamsB[kGLMVertexProgram].m_dirtySlotCount ) // optimize this later after the float param pushes are proven out + { + const uint nLimit = MIN( CGLMShaderPair::cMaxVertexShaderBoolUniforms, m_programParamsB[kGLMVertexProgram].m_dirtySlotCount ); + for ( uint i = 0; i < nLimit; ++i ) + { + GLint constBoolLoc = m_pBoundPair->m_locVertexBool[i]; + if ( constBoolLoc >= 0 ) + gGL->glUniform1i( constBoolLoc, m_programParamsB[kGLMVertexProgram].m_values[i] ); + } + + m_programParamsB[kGLMVertexProgram].m_dirtySlotCount = 0; + } + + if ( m_programParamsB[kGLMFragmentProgram].m_dirtySlotCount ) // optimize this later after the float param pushes are proven out + { + const uint nLimit = MIN( CGLMShaderPair::cMaxFragmentShaderBoolUniforms, m_programParamsB[kGLMFragmentProgram].m_dirtySlotCount ); + for ( uint i = 0; i < nLimit; ++i ) + { + GLint constBoolLoc = m_pBoundPair->m_locFragmentBool[i]; + if ( constBoolLoc >= 0 ) + gGL->glUniform1i( constBoolLoc, m_programParamsB[kGLMFragmentProgram].m_values[i] ); + } + + m_programParamsB[kGLMFragmentProgram].m_dirtySlotCount = 0; + } + + if ( m_programParamsI[kGLMVertexProgram].m_dirtySlotCount ) + { + GLint vconstInt0Loc = m_pBoundPair->m_locVertexInteger0; //glGetUniformLocationARB( prog, "i0"); + if ( vconstInt0Loc >= 0 ) + { + gGL->glUniform1i( vconstInt0Loc, m_programParamsI[kGLMVertexProgram].m_values[0][0] ); //FIXME magic number + } + m_programParamsI[kGLMVertexProgram].m_dirtySlotCount = 0; + } + } + + + if( m_pBoundPair->m_locAlphaRef ) + { + if( !m_AlphaTestEnable.GetData().enable ) + gGL->glUniform1f( m_pBoundPair->m_locAlphaRef, 0.0 ); + else + gGL->glUniform1f( m_pBoundPair->m_locAlphaRef, m_AlphaTestFunc.GetData().ref ); + } + + Assert( ( m_pDevice->m_streams[0].m_vtxBuffer && ( m_pDevice->m_streams[0].m_vtxBuffer->m_vtxBuffer == m_pDevice->m_vtx_buffers[0] ) ) || ( ( !m_pDevice->m_streams[0].m_vtxBuffer ) && ( m_pDevice->m_vtx_buffers[0] == m_pDevice->m_pDummy_vtx_buffer ) ) ); + Assert( ( m_pDevice->m_streams[1].m_vtxBuffer && ( m_pDevice->m_streams[1].m_vtxBuffer->m_vtxBuffer == m_pDevice->m_vtx_buffers[1] ) ) || ( ( !m_pDevice->m_streams[1].m_vtxBuffer ) && ( m_pDevice->m_vtx_buffers[1] == m_pDevice->m_pDummy_vtx_buffer ) ) ); + Assert( ( m_pDevice->m_streams[2].m_vtxBuffer && ( m_pDevice->m_streams[2].m_vtxBuffer->m_vtxBuffer == m_pDevice->m_vtx_buffers[2] ) ) || ( ( !m_pDevice->m_streams[2].m_vtxBuffer ) && ( m_pDevice->m_vtx_buffers[2] == m_pDevice->m_pDummy_vtx_buffer ) ) ); + Assert( ( m_pDevice->m_streams[3].m_vtxBuffer && ( m_pDevice->m_streams[3].m_vtxBuffer->m_vtxBuffer == m_pDevice->m_vtx_buffers[3] ) ) || ( ( !m_pDevice->m_streams[3].m_vtxBuffer ) && ( m_pDevice->m_vtx_buffers[3] == m_pDevice->m_pDummy_vtx_buffer ) ) ); + + uint nCurTotalBufferRevision; + nCurTotalBufferRevision = m_pDevice->m_vtx_buffers[0]->m_nRevision + m_pDevice->m_vtx_buffers[1]->m_nRevision + m_pDevice->m_vtx_buffers[2]->m_nRevision + m_pDevice->m_vtx_buffers[3]->m_nRevision; + + // If any of these inputs have changed, we need to enumerate through all of the expected GL vertex attribs and modify anything in the GL layer that have changed. + // This is not always a win, but it is a net win on NVidia (by 1-4.8% depending on whether driver threading is enabled). + if ( ( nCurTotalBufferRevision != m_CurAttribs.m_nTotalBufferRevision ) || + ( m_CurAttribs.m_pVertDecl != m_pDevice->m_pVertDecl ) || + ( m_CurAttribs.m_vtxAttribMap[0] != reinterpret_cast(m_pDevice->m_vertexShader->m_vtxAttribMap)[0] ) || + ( m_CurAttribs.m_vtxAttribMap[1] != reinterpret_cast(m_pDevice->m_vertexShader->m_vtxAttribMap)[1] ) || + ( memcmp( m_CurAttribs.m_streams, m_pDevice->m_streams, sizeof( m_pDevice->m_streams ) ) != 0 ) ) + { + // This branch is taken 52.2% of the time in the L4D2 test1 (long) timedemo. + +#if GL_BATCH_TELEMETRY_ZONES + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "SetVertexAttribs" ); +#endif + + m_CurAttribs.m_nTotalBufferRevision = nCurTotalBufferRevision; + m_CurAttribs.m_pVertDecl = m_pDevice->m_pVertDecl; + m_CurAttribs.m_vtxAttribMap[0] = reinterpret_cast(m_pDevice->m_vertexShader->m_vtxAttribMap)[0]; + m_CurAttribs.m_vtxAttribMap[1] = reinterpret_cast(m_pDevice->m_vertexShader->m_vtxAttribMap)[1]; + memcpy( m_CurAttribs.m_streams, m_pDevice->m_streams, sizeof( m_pDevice->m_streams ) ); + + unsigned char *pVertexShaderAttribMap = m_pDevice->m_vertexShader->m_vtxAttribMap; + const int nMaxVertexAttributesToCheck = m_drawingProgram[ kGLMVertexProgram ]->m_maxVertexAttrs; + + IDirect3DVertexDeclaration9 *pVertDecl = m_pDevice->m_pVertDecl; + const uint8 *pVertexAttribDescToStreamIndex = pVertDecl->m_VertexAttribDescToStreamIndex; + + for( int nMask = 1, nIndex = 0; nIndex < nMaxVertexAttributesToCheck; ++nIndex, nMask <<= 1 ) + { + uint8 vertexShaderAttrib = pVertexShaderAttribMap[ nIndex ]; + + uint nDeclIndex = pVertexAttribDescToStreamIndex[vertexShaderAttrib]; + if ( nDeclIndex == 0xFF ) + { + // Not good - the vertex shader has an attribute which can't be located in the decl! + // The D3D9 debug runtime is also going to complain. + Assert( 0 ); + + if ( m_lastKnownVertexAttribMask & nMask ) + { + m_lastKnownVertexAttribMask &= ~nMask; + gGL->glDisableVertexAttribArray( nIndex ); + } + continue; + } + + D3DVERTEXELEMENT9_GL *pDeclElem = &pVertDecl->m_elements[nDeclIndex]; + + Assert( ( ( vertexShaderAttrib >> 4 ) == pDeclElem->m_dxdecl.Usage ) && ( ( vertexShaderAttrib & 0x0F ) == pDeclElem->m_dxdecl.UsageIndex) ); + + const uint nStreamIndex = pDeclElem->m_dxdecl.Stream; + const D3DStreamDesc *pStream = &m_pDevice->m_streams[ nStreamIndex ]; + + CGLMBuffer *pBuf = m_pDevice->m_vtx_buffers[ nStreamIndex ]; + if ( pBuf == m_pDevice->m_pDummy_vtx_buffer ) + { + Assert( pStream->m_vtxBuffer == NULL ); + + // this shader doesn't use that pair. + if ( m_lastKnownVertexAttribMask & nMask ) + { + m_lastKnownVertexAttribMask &= ~nMask; + gGL->glDisableVertexAttribArray( nIndex ); + } + continue; + } + Assert( pStream->m_vtxBuffer->m_vtxBuffer == pBuf ); + + int nBufOffset = pDeclElem->m_gldecl.m_offset + pStream->m_offset; + Assert( nBufOffset >= 0 ); + Assert( nBufOffset < (int)pBuf->m_nSize ); + if ( pBuf->m_bUsingPersistentBuffer ) + { + nBufOffset += pBuf->m_nPersistentBufferStartOffset; + } + + SetBufAndVertexAttribPointer( nIndex, pBuf->GetHandle(), + pStream->m_stride, pDeclElem->m_gldecl.m_datatype, pDeclElem->m_gldecl.m_normalized, pDeclElem->m_gldecl.m_nCompCount, + reinterpret_cast< const GLvoid * >( reinterpret_cast< int >( pBuf->m_pPseudoBuf ) + nBufOffset ), + pBuf->m_nRevision ); + + if ( !( m_lastKnownVertexAttribMask & nMask ) ) + { + m_lastKnownVertexAttribMask |= nMask; + gGL->glEnableVertexAttribArray( nIndex ); + } + } + + for( int nIndex = nMaxVertexAttributesToCheck; nIndex < m_nNumSetVertexAttributes; nIndex++ ) + { + gGL->glDisableVertexAttribArray( nIndex ); + m_lastKnownVertexAttribMask &= ~(1 << nIndex); + } + + m_nNumSetVertexAttributes = nMaxVertexAttributesToCheck; + } + + // fragment stage -------------------------------------------------------------------- + if ( m_programParamsF[kGLMFragmentProgram].m_dirtySlotHighWaterNonBone ) + { + GLint fconstLoc; + fconstLoc = m_pBoundPair->m_locFragmentParams; + if ( fconstLoc >= 0 ) + { + const int nMaxUsedShaderSlots = m_drawingProgram[kGLMFragmentProgram]->m_descs[kGLMGLSL].m_highWater; + + int firstDirtySlot = m_programParamsF[kGLMFragmentProgram].m_firstDirtySlotNonBone; + int dirtySlotHighWater = MIN( nMaxUsedShaderSlots, m_programParamsF[kGLMFragmentProgram].m_dirtySlotHighWaterNonBone ); + + if ( dirtySlotHighWater > firstDirtySlot ) + { +#if GL_BATCH_TELEMETRY_ZONES + tmZone( TELEMETRY_LEVEL2, TMZF_NONE, "PSUniformUpdate %u %u", firstDirtySlot, dirtySlotHighWater ); +#endif + + gGL->glUniform4fv( m_pBoundPair->m_UniformBufferParams[kGLMFragmentProgram][firstDirtySlot], dirtySlotHighWater - firstDirtySlot, &m_programParamsF[kGLMFragmentProgram].m_values[firstDirtySlot][0] ); + + GL_BATCH_PERF( m_nTotalPSUniformCalls++; ) + GL_BATCH_PERF( m_nTotalPSUniformsSet += dirtySlotHighWater - firstDirtySlot; ) + + GL_BATCH_PERF( m_FlushStats.m_nFirstPSConstant = firstDirtySlot; ) + GL_BATCH_PERF( m_FlushStats.m_nNumPSConstants += (dirtySlotHighWater - firstDirtySlot); ) + } + m_programParamsF[kGLMFragmentProgram].m_firstDirtySlotNonBone = 256; + m_programParamsF[kGLMFragmentProgram].m_dirtySlotHighWaterNonBone = 0; + } + } + + return; + +flush_error_exit: + m_pBoundPair = NULL; + m_bDirtyPrograms = true; + return; +} diff --git a/togles/linuxwin/glmgrbasics.cpp b/togles/linuxwin/glmgrbasics.cpp new file mode 100644 index 00000000..fb408dda --- /dev/null +++ b/togles/linuxwin/glmgrbasics.cpp @@ -0,0 +1,4073 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// glmgrbasics.cpp +// +//=============================================================================== + +#include "togles/rendermechanism.h" + +#include "tier0/icommandline.h" +#include "tier1/utlhash.h" +#include "tier1/utlmap.h" +#include "tier0/vprof.h" + +#ifdef OSX +#include +#ifdef CGLPROFILER_ENABLE +#include +#endif +#endif + +#include "tier0/valve_minmax_off.h" +#include + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + +//=============================================================================== +// decoding tables for debug + +typedef struct +{ + unsigned long value; + const char *name; +} GLMValueEntry_t; + +#define TERMVALUE 0x31415926 + // terminator for value tables + +#define VE( x ) { x, #x } + // "value entry" + +const GLMValueEntry_t g_d3d_devtypes[] = +{ + VE( D3DDEVTYPE_HAL ), + VE( D3DDEVTYPE_REF ), + + VE( TERMVALUE ) +}; + +const GLMValueEntry_t g_d3d_formats[] = +{ + VE( D3DFMT_INDEX16 ), + VE( D3DFMT_D16 ), + VE( D3DFMT_D24S8 ), + VE( D3DFMT_A8R8G8B8 ), + VE( D3DFMT_A4R4G4B4 ), + VE( D3DFMT_X8R8G8B8 ), + VE( D3DFMT_R5G6R5 ), + VE( D3DFMT_X1R5G5B5 ), + VE( D3DFMT_A1R5G5B5 ), + VE( D3DFMT_L8 ), + VE( D3DFMT_A8L8 ), + VE( D3DFMT_A ), + VE( D3DFMT_DXT1 ), + VE( D3DFMT_DXT3 ), + VE( D3DFMT_DXT5 ), + VE( D3DFMT_V8U8 ), + VE( D3DFMT_Q8W8V8U8 ), + VE( D3DFMT_X8L8V8U8 ), + VE( D3DFMT_A16B16G16R16F ), + VE( D3DFMT_A16B16G16R16 ), + VE( D3DFMT_R32F ), + VE( D3DFMT_A32B32G32R32F ), + VE( D3DFMT_R8G8B8 ), + VE( D3DFMT_D24X4S4 ), + VE( D3DFMT_A8 ), + VE( D3DFMT_R5G6B5 ), + VE( D3DFMT_D15S1 ), + VE( D3DFMT_D24X8 ), + VE( D3DFMT_VERTEXDATA ), + VE( D3DFMT_INDEX32 ), + + // vendor specific formats (fourcc's) + VE( D3DFMT_NV_INTZ ), + VE( D3DFMT_NV_RAWZ ), + VE( D3DFMT_NV_NULL ), + VE( D3DFMT_ATI_D16 ), + VE( D3DFMT_ATI_D24S8 ), + VE( D3DFMT_ATI_2N ), + VE( D3DFMT_ATI_1N ), + + VE( D3DFMT_UNKNOWN ), + + VE( TERMVALUE ) +}; + +const GLMValueEntry_t g_d3d_rtypes[] = +{ + VE( D3DRTYPE_SURFACE ), + VE( D3DRTYPE_TEXTURE ), + VE( D3DRTYPE_VOLUMETEXTURE ), + VE( D3DRTYPE_CUBETEXTURE ), + VE( D3DRTYPE_VERTEXBUFFER ), + VE( D3DRTYPE_INDEXBUFFER ), + + VE( TERMVALUE ) +}; + +const GLMValueEntry_t g_d3d_usages[] = +{ + VE( D3DUSAGE_RENDERTARGET ), + VE( D3DUSAGE_DEPTHSTENCIL ), + VE( D3DUSAGE_DYNAMIC ), + VE( D3DUSAGE_AUTOGENMIPMAP ), + //VE( D3DUSAGE_DMAP ), + //VE( D3DUSAGE_QUERY_LEGACYBUMPMAP ), + VE( D3DUSAGE_QUERY_SRGBREAD ), + VE( D3DUSAGE_QUERY_FILTER ), + VE( D3DUSAGE_QUERY_SRGBWRITE ), + VE( D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING ), + VE( D3DUSAGE_QUERY_VERTEXTEXTURE ), + //VE( D3DUSAGE_QUERY_WRAPANDMIP ), + VE( D3DUSAGE_WRITEONLY ), + VE( D3DUSAGE_SOFTWAREPROCESSING ), + VE( D3DUSAGE_DONOTCLIP ), + VE( D3DUSAGE_POINTS ), + VE( D3DUSAGE_RTPATCHES ), + VE( D3DUSAGE_NPATCHES ), + + VE( TERMVALUE ) +}; + +const GLMValueEntry_t g_d3d_rstates[] = +{ + VE( D3DRS_ZENABLE ), + VE( D3DRS_FILLMODE ), + VE( D3DRS_SHADEMODE ), + VE( D3DRS_ZWRITEENABLE ), + VE( D3DRS_ALPHATESTENABLE ), + VE( D3DRS_LASTPIXEL ), + VE( D3DRS_SRCBLEND ), + VE( D3DRS_DESTBLEND ), + VE( D3DRS_CULLMODE ), + VE( D3DRS_ZFUNC ), + VE( D3DRS_ALPHAREF ), + VE( D3DRS_ALPHAFUNC ), + VE( D3DRS_DITHERENABLE ), + VE( D3DRS_ALPHABLENDENABLE ), + VE( D3DRS_FOGENABLE ), + VE( D3DRS_SPECULARENABLE ), + VE( D3DRS_FOGCOLOR ), + VE( D3DRS_FOGTABLEMODE ), + VE( D3DRS_FOGSTART ), + VE( D3DRS_FOGEND ), + VE( D3DRS_FOGDENSITY ), + VE( D3DRS_RANGEFOGENABLE ), + VE( D3DRS_STENCILENABLE ), + VE( D3DRS_STENCILFAIL ), + VE( D3DRS_STENCILZFAIL ), + VE( D3DRS_STENCILPASS ), + VE( D3DRS_STENCILFUNC ), + VE( D3DRS_STENCILREF ), + VE( D3DRS_STENCILMASK ), + VE( D3DRS_STENCILWRITEMASK ), + VE( D3DRS_TEXTUREFACTOR ), + VE( D3DRS_WRAP0 ), + VE( D3DRS_WRAP1 ), + VE( D3DRS_WRAP2 ), + VE( D3DRS_WRAP3 ), + VE( D3DRS_WRAP4 ), + VE( D3DRS_WRAP5 ), + VE( D3DRS_WRAP6 ), + VE( D3DRS_WRAP7 ), + VE( D3DRS_CLIPPING ), + VE( D3DRS_LIGHTING ), + VE( D3DRS_AMBIENT ), + VE( D3DRS_FOGVERTEXMODE ), + VE( D3DRS_COLORVERTEX ), + VE( D3DRS_LOCALVIEWER ), + VE( D3DRS_NORMALIZENORMALS ), + VE( D3DRS_DIFFUSEMATERIALSOURCE ), + VE( D3DRS_SPECULARMATERIALSOURCE ), + VE( D3DRS_AMBIENTMATERIALSOURCE ), + VE( D3DRS_EMISSIVEMATERIALSOURCE ), + VE( D3DRS_VERTEXBLEND ), + VE( D3DRS_CLIPPLANEENABLE ), + VE( D3DRS_POINTSIZE ), + VE( D3DRS_POINTSIZE_MIN ), + VE( D3DRS_POINTSPRITEENABLE ), + VE( D3DRS_POINTSCALEENABLE ), + VE( D3DRS_POINTSCALE_A ), + VE( D3DRS_POINTSCALE_B ), + VE( D3DRS_POINTSCALE_C ), + VE( D3DRS_MULTISAMPLEANTIALIAS ), + VE( D3DRS_MULTISAMPLEMASK ), + VE( D3DRS_PATCHEDGESTYLE ), + VE( D3DRS_DEBUGMONITORTOKEN ), + VE( D3DRS_POINTSIZE_MAX ), + VE( D3DRS_INDEXEDVERTEXBLENDENABLE ), + VE( D3DRS_COLORWRITEENABLE ), + VE( D3DRS_TWEENFACTOR ), + VE( D3DRS_BLENDOP ), + VE( D3DRS_POSITIONDEGREE ), + VE( D3DRS_NORMALDEGREE ), + VE( D3DRS_SCISSORTESTENABLE ), + VE( D3DRS_SLOPESCALEDEPTHBIAS ), + VE( D3DRS_ANTIALIASEDLINEENABLE ), + VE( D3DRS_MINTESSELLATIONLEVEL ), + VE( D3DRS_MAXTESSELLATIONLEVEL ), + VE( D3DRS_ADAPTIVETESS_X ), + VE( D3DRS_ADAPTIVETESS_Y ), + VE( D3DRS_ADAPTIVETESS_Z ), + VE( D3DRS_ADAPTIVETESS_W ), + VE( D3DRS_ENABLEADAPTIVETESSELLATION ), + VE( D3DRS_TWOSIDEDSTENCILMODE ), + VE( D3DRS_CCW_STENCILFAIL ), + VE( D3DRS_CCW_STENCILZFAIL ), + VE( D3DRS_CCW_STENCILPASS ), + VE( D3DRS_CCW_STENCILFUNC ), + VE( D3DRS_COLORWRITEENABLE1 ), + VE( D3DRS_COLORWRITEENABLE2 ), + VE( D3DRS_COLORWRITEENABLE3 ), + VE( D3DRS_BLENDFACTOR ), + VE( D3DRS_SRGBWRITEENABLE ), + VE( D3DRS_DEPTHBIAS ), + VE( D3DRS_WRAP8 ), + VE( D3DRS_WRAP9 ), + VE( D3DRS_WRAP10 ), + VE( D3DRS_WRAP11 ), + VE( D3DRS_WRAP12 ), + VE( D3DRS_WRAP13 ), + VE( D3DRS_WRAP14 ), + VE( D3DRS_WRAP15 ), + VE( D3DRS_SEPARATEALPHABLENDENABLE ), + VE( D3DRS_SRCBLENDALPHA ), + VE( D3DRS_DESTBLENDALPHA ), + VE( D3DRS_BLENDOPALPHA ), + + VE( TERMVALUE ) +}; + +const GLMValueEntry_t g_d3d_opcodes[] = +{ + VE( D3DSIO_NOP ), + VE( D3DSIO_PHASE ), + VE( D3DSIO_RET ), + VE( D3DSIO_ELSE ), + VE( D3DSIO_ENDIF ), + VE( D3DSIO_ENDLOOP ), + VE( D3DSIO_ENDREP ), + VE( D3DSIO_BREAK ), + VE( D3DSIO_TEXDEPTH ), + VE( D3DSIO_TEXKILL ), + VE( D3DSIO_BEM ), + VE( D3DSIO_TEXBEM ), + VE( D3DSIO_TEXBEML ), + VE( D3DSIO_TEXDP3 ), + VE( D3DSIO_TEXDP3TEX ), + VE( D3DSIO_TEXM3x2DEPTH ), + VE( D3DSIO_TEXM3x2TEX ), + VE( D3DSIO_TEXM3x3 ), + VE( D3DSIO_TEXM3x3PAD ), + VE( D3DSIO_TEXM3x3TEX ), + VE( D3DSIO_TEXM3x3VSPEC ), + VE( D3DSIO_TEXREG2AR ), + VE( D3DSIO_TEXREG2GB ), + VE( D3DSIO_TEXREG2RGB ), + VE( D3DSIO_LABEL ), + VE( D3DSIO_CALL ), + VE( D3DSIO_IF ), + VE( D3DSIO_LOOP ), + VE( D3DSIO_REP ), + VE( D3DSIO_BREAKP ), + VE( D3DSIO_DSX ), + VE( D3DSIO_DSY ), + VE( D3DSIO_NRM ), + VE( D3DSIO_MOVA ), + VE( D3DSIO_MOV ), + VE( D3DSIO_RCP ), + VE( D3DSIO_RSQ ), + VE( D3DSIO_EXP ), + VE( D3DSIO_EXPP ), + VE( D3DSIO_LOG ), + VE( D3DSIO_LOGP ), + VE( D3DSIO_FRC ), + VE( D3DSIO_LIT ), + VE( D3DSIO_ABS ), + VE( D3DSIO_TEXM3x3SPEC ), + VE( D3DSIO_M4x4 ), + VE( D3DSIO_M4x3 ), + VE( D3DSIO_M3x4 ), + VE( D3DSIO_M3x3 ), + VE( D3DSIO_M3x2 ), + VE( D3DSIO_CALLNZ ), + VE( D3DSIO_IFC ), + VE( D3DSIO_BREAKC ), + VE( D3DSIO_SETP ), + VE( D3DSIO_TEXLDL ), + VE( D3DSIO_ADD ), + VE( D3DSIO_SUB ), + VE( D3DSIO_MUL ), + VE( D3DSIO_DP3 ), + VE( D3DSIO_DP4 ), + VE( D3DSIO_MIN ), + VE( D3DSIO_MAX ), + VE( D3DSIO_DST ), + VE( D3DSIO_SLT ), + VE( D3DSIO_SGE ), + VE( D3DSIO_CRS ), + VE( D3DSIO_POW ), + VE( D3DSIO_DP2ADD ), + VE( D3DSIO_LRP ), + VE( D3DSIO_SGN ), + VE( D3DSIO_CND ), + VE( D3DSIO_CMP ), + VE( D3DSIO_SINCOS ), + VE( D3DSIO_MAD ), + VE( D3DSIO_TEXLDD ), + VE( D3DSIO_TEXCOORD ), + VE( D3DSIO_TEX ), + VE( D3DSIO_DCL ), + VE( D3DSTT_UNKNOWN ), + VE( D3DSTT_2D ), + VE( D3DSTT_CUBE ), + VE( D3DSTT_VOLUME ), + VE( D3DSIO_DEFB ), + VE( D3DSIO_DEFI ), + VE( D3DSIO_DEF ), + VE( D3DSIO_COMMENT ), + VE( D3DSIO_END ), +}; + + +const GLMValueEntry_t g_d3d_vtxdeclusages[] = +{ + { D3DDECLUSAGE_POSITION ,"POSN" }, // P + { D3DDECLUSAGE_BLENDWEIGHT ,"BLWT" }, // W + { D3DDECLUSAGE_BLENDINDICES ,"BLIX" }, // I + { D3DDECLUSAGE_NORMAL ,"NORM" }, // N + { D3DDECLUSAGE_PSIZE ,"PSIZ" }, // S + { D3DDECLUSAGE_TEXCOORD ,"TEXC" }, // T + { D3DDECLUSAGE_TANGENT ,"TANG" }, // G + { D3DDECLUSAGE_BINORMAL ,"BINO" }, // B + { D3DDECLUSAGE_TESSFACTOR ,"TESS" }, // S + { D3DDECLUSAGE_PLUGH ,"????" }, // ? + { D3DDECLUSAGE_COLOR ,"COLR" }, // C + { D3DDECLUSAGE_FOG ,"FOG " }, // F + { D3DDECLUSAGE_DEPTH ,"DEPT" }, // D + { D3DDECLUSAGE_SAMPLE ,"SAMP" } // M +}; + +const GLMValueEntry_t g_d3d_vtxdeclusages_short[] = +{ + { D3DDECLUSAGE_POSITION ,"P" }, + { D3DDECLUSAGE_BLENDWEIGHT ,"W" }, + { D3DDECLUSAGE_BLENDINDICES ,"I" }, + { D3DDECLUSAGE_NORMAL ,"N" }, + { D3DDECLUSAGE_PSIZE ,"S" }, + { D3DDECLUSAGE_TEXCOORD ,"T" }, + { D3DDECLUSAGE_TANGENT ,"G" }, + { D3DDECLUSAGE_BINORMAL ,"B" }, + { D3DDECLUSAGE_TESSFACTOR ,"S" }, + { D3DDECLUSAGE_PLUGH ,"?" }, + { D3DDECLUSAGE_COLOR ,"C" }, + { D3DDECLUSAGE_FOG ,"F" }, + { D3DDECLUSAGE_DEPTH ,"D" }, + { D3DDECLUSAGE_SAMPLE ,"M" } +}; + +const GLMValueEntry_t g_cgl_rendids[] = // need to mask with 0xFFFFFF00 to match on these (ex: 8800GT == 0x00022608 +{ +#ifdef OSX + VE( kCGLRendererGenericID ), + VE( kCGLRendererGenericFloatID ), + VE( kCGLRendererAppleSWID ), + VE( kCGLRendererATIRage128ID ), + VE( kCGLRendererATIRadeonID ), + VE( kCGLRendererATIRageProID ), + VE( kCGLRendererATIRadeon8500ID ), + VE( kCGLRendererATIRadeon9700ID ), + VE( kCGLRendererATIRadeonX1000ID ), + VE( kCGLRendererATIRadeonX2000ID ), + VE( kCGLRendererGeForce2MXID ), + VE( kCGLRendererGeForce3ID ), + VE( kCGLRendererGeForceFXID ), // also for GF6 and GF7 + VE( kCGLRendererGeForce8xxxID ), + VE( kCGLRendererVTBladeXP2ID ), + VE( kCGLRendererIntel900ID ), + VE( kCGLRendererMesa3DFXID ), +#endif + VE( TERMVALUE ) +}; + +const GLMValueEntry_t g_gl_errors[] = +{ + VE( GL_INVALID_ENUM ), + VE( GL_INVALID_VALUE ), + VE( GL_INVALID_OPERATION ), + VE( GL_STACK_OVERFLOW ), + VE( GL_STACK_UNDERFLOW ), + VE( GL_OUT_OF_MEMORY ), + VE( GL_INVALID_FRAMEBUFFER_OPERATION_EXT ), + VE( GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT ), + VE( GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT ), + VE( GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT ), + VE( GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT ), + VE( GL_FRAMEBUFFER_UNSUPPORTED_EXT ), + VE( GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT ), + VE( GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT ) +}; + +// there are some ARB/EXT dupes in this table but that doesn't matter too much +const GLMValueEntry_t g_gl_enums[] = +{ + { 0x0000, "GL_ZERO" }, + { 0x0001, "GL_ONE" }, + { 0x0004, "GL_TRIANGLES" }, + { 0x0005, "GL_TRIANGLE_STRIP" }, + { 0x0006, "GL_TRIANGLE_FAN" }, + { 0x0007, "GL_QUADS" }, + { 0x0008, "GL_QUAD_STRIP" }, + { 0x0009, "GL_POLYGON" }, + { 0x0200, "GL_NEVER" }, + { 0x0201, "GL_LESS" }, + { 0x0202, "GL_EQUAL" }, + { 0x0203, "GL_LEQUAL" }, + { 0x0204, "GL_GREATER" }, + { 0x0205, "GL_NOTEQUAL" }, + { 0x0206, "GL_GEQUAL" }, + { 0x0207, "GL_ALWAYS" }, + { 0x0300, "GL_SRC_COLOR" }, + { 0x0301, "GL_ONE_MINUS_SRC_COLOR" }, + { 0x0302, "GL_SRC_ALPHA" }, + { 0x0303, "GL_ONE_MINUS_SRC_ALPHA" }, + { 0x0304, "GL_DST_ALPHA" }, + { 0x0305, "GL_ONE_MINUS_DST_ALPHA" }, + { 0x0306, "GL_DST_COLOR" }, + { 0x0307, "GL_ONE_MINUS_DST_COLOR" }, + { 0x0308, "GL_SRC_ALPHA_SATURATE" }, + { 0x0400, "GL_FRONT_LEFT" }, + { 0x0401, "GL_FRONT_RIGHT" }, + { 0x0402, "GL_BACK_LEFT" }, + { 0x0403, "GL_BACK_RIGHT" }, + { 0x0404, "GL_FRONT" }, + { 0x0405, "GL_BACK" }, + { 0x0406, "GL_LEFT" }, + { 0x0407, "GL_RIGHT" }, + { 0x0408, "GL_FRONT_AND_BACK" }, + { 0x0409, "GL_AUX0" }, + { 0x040A, "GL_AUX1" }, + { 0x040B, "GL_AUX2" }, + { 0x040C, "GL_AUX3" }, + { 0x0500, "GL_INVALID_ENUM" }, + { 0x0501, "GL_INVALID_VALUE" }, + { 0x0502, "GL_INVALID_OPERATION" }, + { 0x0503, "GL_STACK_OVERFLOW" }, + { 0x0504, "GL_STACK_UNDERFLOW" }, + { 0x0505, "GL_OUT_OF_MEMORY" }, + { 0x0506, "GL_INVALID_FRAMEBUFFER_OPERATION" }, + { 0x0600, "GL_2D" }, + { 0x0601, "GL_3D" }, + { 0x0602, "GL_3D_COLOR" }, + { 0x0603, "GL_3D_COLOR_TEXTURE" }, + { 0x0604, "GL_4D_COLOR_TEXTURE" }, + { 0x0700, "GL_PASS_THROUGH_TOKEN" }, + { 0x0701, "GL_POINT_TOKEN" }, + { 0x0702, "GL_LINE_TOKEN" }, + { 0x0703, "GL_POLYGON_TOKEN" }, + { 0x0704, "GL_BITMAP_TOKEN" }, + { 0x0705, "GL_DRAW_PIXEL_TOKEN" }, + { 0x0706, "GL_COPY_PIXEL_TOKEN" }, + { 0x0707, "GL_LINE_RESET_TOKEN" }, + { 0x0800, "GL_EXP" }, + { 0x0801, "GL_EXP2" }, + { 0x0900, "GL_CW" }, + { 0x0901, "GL_CCW" }, + { 0x0A00, "GL_COEFF" }, + { 0x0A01, "GL_ORDER" }, + { 0x0A02, "GL_DOMAIN" }, + { 0x0B00, "GL_CURRENT_COLOR" }, + { 0x0B01, "GL_CURRENT_INDEX" }, + { 0x0B02, "GL_CURRENT_NORMAL" }, + { 0x0B03, "GL_CURRENT_TEXTURE_COORDS" }, + { 0x0B04, "GL_CURRENT_RASTER_COLOR" }, + { 0x0B05, "GL_CURRENT_RASTER_INDEX" }, + { 0x0B06, "GL_CURRENT_RASTER_TEXTURE_COORDS" }, + { 0x0B07, "GL_CURRENT_RASTER_POSITION" }, + { 0x0B08, "GL_CURRENT_RASTER_POSITION_VALID" }, + { 0x0B09, "GL_CURRENT_RASTER_DISTANCE" }, + { 0x0B10, "GL_POINT_SMOOTH" }, + { 0x0B11, "GL_POINT_SIZE" }, + { 0x0B12, "GL_POINT_SIZE_RANGE" }, + { 0x0B12, "GL_SMOOTH_POINT_SIZE_RANGE" }, + { 0x0B13, "GL_POINT_SIZE_GRANULARITY" }, + { 0x0B13, "GL_SMOOTH_POINT_SIZE_GRANULARITY" }, + { 0x0B20, "GL_LINE_SMOOTH" }, + { 0x0B21, "GL_LINE_WIDTH" }, + { 0x0B22, "GL_LINE_WIDTH_RANGE" }, + { 0x0B22, "GL_SMOOTH_LINE_WIDTH_RANGE" }, + { 0x0B23, "GL_LINE_WIDTH_GRANULARITY" }, + { 0x0B23, "GL_SMOOTH_LINE_WIDTH_GRANULARITY" }, + { 0x0B24, "GL_LINE_STIPPLE" }, + { 0x0B25, "GL_LINE_STIPPLE_PATTERN" }, + { 0x0B26, "GL_LINE_STIPPLE_REPEAT" }, + { 0x0B30, "GL_LIST_MODE" }, + { 0x0B31, "GL_MAX_LIST_NESTING" }, + { 0x0B32, "GL_LIST_BASE" }, + { 0x0B33, "GL_LIST_INDEX" }, + { 0x0B40, "GL_POLYGON_MODE" }, + { 0x0B41, "GL_POLYGON_SMOOTH" }, + { 0x0B42, "GL_POLYGON_STIPPLE" }, + { 0x0B43, "GL_EDGE_FLAG" }, + { 0x0B44, "GL_CULL_FACE" }, + { 0x0B45, "GL_CULL_FACE_MODE" }, + { 0x0B46, "GL_FRONT_FACE" }, + { 0x0B50, "GL_LIGHTING" }, + { 0x0B51, "GL_LIGHT_MODEL_LOCAL_VIEWER" }, + { 0x0B52, "GL_LIGHT_MODEL_TWO_SIDE" }, + { 0x0B53, "GL_LIGHT_MODEL_AMBIENT" }, + { 0x0B54, "GL_SHADE_MODEL" }, + { 0x0B55, "GL_COLOR_MATERIAL_FACE" }, + { 0x0B56, "GL_COLOR_MATERIAL_PARAMETER" }, + { 0x0B57, "GL_COLOR_MATERIAL" }, + { 0x0B60, "GL_FOG" }, + { 0x0B61, "GL_FOG_INDEX" }, + { 0x0B62, "GL_FOG_DENSITY" }, + { 0x0B63, "GL_FOG_START" }, + { 0x0B64, "GL_FOG_END" }, + { 0x0B65, "GL_FOG_MODE" }, + { 0x0B66, "GL_FOG_COLOR" }, + { 0x0B70, "GL_DEPTH_RANGE" }, + { 0x0B71, "GL_DEPTH_TEST" }, + { 0x0B72, "GL_DEPTH_WRITEMASK" }, + { 0x0B73, "GL_DEPTH_CLEAR_VALUE" }, + { 0x0B74, "GL_DEPTH_FUNC" }, + { 0x0B80, "GL_ACCUM_CLEAR_VALUE" }, + { 0x0B90, "GL_STENCIL_TEST" }, + { 0x0B91, "GL_STENCIL_CLEAR_VALUE" }, + { 0x0B92, "GL_STENCIL_FUNC" }, + { 0x0B93, "GL_STENCIL_VALUE_MASK" }, + { 0x0B94, "GL_STENCIL_FAIL" }, + { 0x0B95, "GL_STENCIL_PASS_DEPTH_FAIL" }, + { 0x0B96, "GL_STENCIL_PASS_DEPTH_PASS" }, + { 0x0B97, "GL_STENCIL_REF" }, + { 0x0B98, "GL_STENCIL_WRITEMASK" }, + { 0x0BA0, "GL_MATRIX_MODE" }, + { 0x0BA1, "GL_NORMALIZE" }, + { 0x0BA2, "GL_VIEWPORT" }, + { 0x0BA3, "GL_MODELVIEW_STACK_DEPTH" }, + { 0x0BA4, "GL_PROJECTION_STACK_DEPTH" }, + { 0x0BA5, "GL_TEXTURE_STACK_DEPTH" }, + { 0x0BA6, "GL_MODELVIEW_MATRIX" }, + { 0x0BA7, "GL_PROJECTION_MATRIX" }, + { 0x0BA8, "GL_TEXTURE_MATRIX" }, + { 0x0BB0, "GL_ATTRIB_STACK_DEPTH" }, + { 0x0BB1, "GL_CLIENT_ATTRIB_STACK_DEPTH" }, + { 0x0BC0, "GL_ALPHA_TEST" }, + { 0x0BC1, "GL_ALPHA_TEST_FUNC" }, + { 0x0BC2, "GL_ALPHA_TEST_REF" }, + { 0x0BD0, "GL_DITHER" }, + { 0x0BE0, "GL_BLEND_DST" }, + { 0x0BE1, "GL_BLEND_SRC" }, + { 0x0BE2, "GL_BLEND" }, + { 0x0BF0, "GL_LOGIC_OP_MODE" }, + { 0x0BF1, "GL_INDEX_LOGIC_OP" }, + { 0x0BF2, "GL_COLOR_LOGIC_OP" }, + { 0x0C00, "GL_AUX_BUFFERS" }, + { 0x0C01, "GL_DRAW_BUFFER" }, + { 0x0C02, "GL_READ_BUFFER" }, + { 0x0C10, "GL_SCISSOR_BOX" }, + { 0x0C11, "GL_SCISSOR_TEST" }, + { 0x0C20, "GL_INDEX_CLEAR_VALUE" }, + { 0x0C21, "GL_INDEX_WRITEMASK" }, + { 0x0C22, "GL_COLOR_CLEAR_VALUE" }, + { 0x0C23, "GL_COLOR_WRITEMASK" }, + { 0x0C30, "GL_INDEX_MODE" }, + { 0x0C31, "GL_RGBA_MODE" }, + { 0x0C32, "GL_DOUBLEBUFFER" }, + { 0x0C33, "GL_STEREO" }, + { 0x0C40, "GL_RENDER_MODE" }, + { 0x0C50, "GL_PERSPECTIVE_CORRECTION_HINT" }, + { 0x0C51, "GL_POINT_SMOOTH_HINT" }, + { 0x0C52, "GL_LINE_SMOOTH_HINT" }, + { 0x0C53, "GL_POLYGON_SMOOTH_HINT" }, + { 0x0C54, "GL_FOG_HINT" }, + { 0x0C60, "GL_TEXTURE_GEN_S" }, + { 0x0C61, "GL_TEXTURE_GEN_T" }, + { 0x0C62, "GL_TEXTURE_GEN_R" }, + { 0x0C63, "GL_TEXTURE_GEN_Q" }, + { 0x0C70, "GL_PIXEL_MAP_I_TO_I" }, + { 0x0C71, "GL_PIXEL_MAP_S_TO_S" }, + { 0x0C72, "GL_PIXEL_MAP_I_TO_R" }, + { 0x0C73, "GL_PIXEL_MAP_I_TO_G" }, + { 0x0C74, "GL_PIXEL_MAP_I_TO_B" }, + { 0x0C75, "GL_PIXEL_MAP_I_TO_A" }, + { 0x0C76, "GL_PIXEL_MAP_R_TO_R" }, + { 0x0C77, "GL_PIXEL_MAP_G_TO_G" }, + { 0x0C78, "GL_PIXEL_MAP_B_TO_B" }, + { 0x0C79, "GL_PIXEL_MAP_A_TO_A" }, + { 0x0CB0, "GL_PIXEL_MAP_I_TO_I_SIZE" }, + { 0x0CB1, "GL_PIXEL_MAP_S_TO_S_SIZE" }, + { 0x0CB2, "GL_PIXEL_MAP_I_TO_R_SIZE" }, + { 0x0CB3, "GL_PIXEL_MAP_I_TO_G_SIZE" }, + { 0x0CB4, "GL_PIXEL_MAP_I_TO_B_SIZE" }, + { 0x0CB5, "GL_PIXEL_MAP_I_TO_A_SIZE" }, + { 0x0CB6, "GL_PIXEL_MAP_R_TO_R_SIZE" }, + { 0x0CB7, "GL_PIXEL_MAP_G_TO_G_SIZE" }, + { 0x0CB8, "GL_PIXEL_MAP_B_TO_B_SIZE" }, + { 0x0CB9, "GL_PIXEL_MAP_A_TO_A_SIZE" }, + { 0x0CF0, "GL_UNPACK_SWAP_BYTES" }, + { 0x0CF1, "GL_UNPACK_LSB_FIRST" }, + { 0x0CF2, "GL_UNPACK_ROW_LENGTH" }, + { 0x0CF3, "GL_UNPACK_SKIP_ROWS" }, + { 0x0CF4, "GL_UNPACK_SKIP_PIXELS" }, + { 0x0CF5, "GL_UNPACK_ALIGNMENT" }, + { 0x0D00, "GL_PACK_SWAP_BYTES" }, + { 0x0D01, "GL_PACK_LSB_FIRST" }, + { 0x0D02, "GL_PACK_ROW_LENGTH" }, + { 0x0D03, "GL_PACK_SKIP_ROWS" }, + { 0x0D04, "GL_PACK_SKIP_PIXELS" }, + { 0x0D05, "GL_PACK_ALIGNMENT" }, + { 0x0D10, "GL_MAP_COLOR" }, + { 0x0D11, "GL_MAP_STENCIL" }, + { 0x0D12, "GL_INDEX_SHIFT" }, + { 0x0D13, "GL_INDEX_OFFSET" }, + { 0x0D14, "GL_RED_SCALE" }, + { 0x0D15, "GL_RED_BIAS" }, + { 0x0D16, "GL_ZOOM_X" }, + { 0x0D17, "GL_ZOOM_Y" }, + { 0x0D18, "GL_GREEN_SCALE" }, + { 0x0D19, "GL_GREEN_BIAS" }, + { 0x0D1A, "GL_BLUE_SCALE" }, + { 0x0D1B, "GL_BLUE_BIAS" }, + { 0x0D1C, "GL_ALPHA_SCALE" }, + { 0x0D1D, "GL_ALPHA_BIAS" }, + { 0x0D1E, "GL_DEPTH_SCALE" }, + { 0x0D1F, "GL_DEPTH_BIAS" }, + { 0x0D30, "GL_MAX_EVAL_ORDER" }, + { 0x0D31, "GL_MAX_LIGHTS" }, + { 0x0D32, "GL_MAX_CLIP_PLANES" }, + { 0x0D33, "GL_MAX_TEXTURE_SIZE" }, + { 0x0D34, "GL_MAX_PIXEL_MAP_TABLE" }, + { 0x0D35, "GL_MAX_ATTRIB_STACK_DEPTH" }, + { 0x0D36, "GL_MAX_MODELVIEW_STACK_DEPTH" }, + { 0x0D37, "GL_MAX_NAME_STACK_DEPTH" }, + { 0x0D38, "GL_MAX_PROJECTION_STACK_DEPTH" }, + { 0x0D39, "GL_MAX_TEXTURE_STACK_DEPTH" }, + { 0x0D3A, "GL_MAX_VIEWPORT_DIMS" }, + { 0x0D3B, "GL_MAX_CLIENT_ATTRIB_STACK_DEPTH" }, + { 0x0D50, "GL_SUBPIXEL_BITS" }, + { 0x0D51, "GL_INDEX_BITS" }, + { 0x0D52, "GL_RED_BITS" }, + { 0x0D53, "GL_GREEN_BITS" }, + { 0x0D54, "GL_BLUE_BITS" }, + { 0x0D55, "GL_ALPHA_BITS" }, + { 0x0D56, "GL_DEPTH_BITS" }, + { 0x0D57, "GL_STENCIL_BITS" }, + { 0x0D58, "GL_ACCUM_RED_BITS" }, + { 0x0D59, "GL_ACCUM_GREEN_BITS" }, + { 0x0D5A, "GL_ACCUM_BLUE_BITS" }, + { 0x0D5B, "GL_ACCUM_ALPHA_BITS" }, + { 0x0D70, "GL_NAME_STACK_DEPTH" }, + { 0x0D80, "GL_AUTO_NORMAL" }, + { 0x0D90, "GL_MAP1_COLOR_4" }, + { 0x0D91, "GL_MAP1_INDEX" }, + { 0x0D92, "GL_MAP1_NORMAL" }, + { 0x0D93, "GL_MAP1_TEXTURE_COORD_1" }, + { 0x0D94, "GL_MAP1_TEXTURE_COORD_2" }, + { 0x0D95, "GL_MAP1_TEXTURE_COORD_3" }, + { 0x0D96, "GL_MAP1_TEXTURE_COORD_4" }, + { 0x0D97, "GL_MAP1_VERTEX_3" }, + { 0x0D98, "GL_MAP1_VERTEX_4" }, + { 0x0DB0, "GL_MAP2_COLOR_4" }, + { 0x0DB1, "GL_MAP2_INDEX" }, + { 0x0DB2, "GL_MAP2_NORMAL" }, + { 0x0DB3, "GL_MAP2_TEXTURE_COORD_1" }, + { 0x0DB4, "GL_MAP2_TEXTURE_COORD_2" }, + { 0x0DB5, "GL_MAP2_TEXTURE_COORD_3" }, + { 0x0DB6, "GL_MAP2_TEXTURE_COORD_4" }, + { 0x0DB7, "GL_MAP2_VERTEX_3" }, + { 0x0DB8, "GL_MAP2_VERTEX_4" }, + { 0x0DD0, "GL_MAP1_GRID_DOMAIN" }, + { 0x0DD1, "GL_MAP1_GRID_SEGMENTS" }, + { 0x0DD2, "GL_MAP2_GRID_DOMAIN" }, + { 0x0DD3, "GL_MAP2_GRID_SEGMENTS" }, + { 0x0DE0, "GL_TEXTURE_1D" }, + { 0x0DE1, "GL_TEXTURE_2D" }, + { 0x0DF0, "GL_FEEDBACK_BUFFER_POINTER" }, + { 0x0DF1, "GL_FEEDBACK_BUFFER_SIZE" }, + { 0x0DF2, "GL_FEEDBACK_BUFFER_TYPE" }, + { 0x0DF3, "GL_SELECTION_BUFFER_POINTER" }, + { 0x0DF4, "GL_SELECTION_BUFFER_SIZE" }, + { 0x1000, "GL_TEXTURE_WIDTH" }, + { 0x1001, "GL_TEXTURE_HEIGHT" }, + { 0x1003, "GL_TEXTURE_INTERNAL_FORMAT" }, + { 0x1004, "GL_TEXTURE_BORDER_COLOR" }, + { 0x1005, "GL_TEXTURE_BORDER" }, + { 0x1100, "GL_DONT_CARE" }, + { 0x1101, "GL_FASTEST" }, + { 0x1102, "GL_NICEST" }, + { 0x1200, "GL_AMBIENT" }, + { 0x1201, "GL_DIFFUSE" }, + { 0x1202, "GL_SPECULAR" }, + { 0x1203, "GL_POSITION" }, + { 0x1204, "GL_SPOT_DIRECTION" }, + { 0x1205, "GL_SPOT_EXPONENT" }, + { 0x1206, "GL_SPOT_CUTOFF" }, + { 0x1207, "GL_CONSTANT_ATTENUATION" }, + { 0x1208, "GL_LINEAR_ATTENUATION" }, + { 0x1209, "GL_QUADRATIC_ATTENUATION" }, + { 0x1300, "GL_COMPILE" }, + { 0x1301, "GL_COMPILE_AND_EXECUTE" }, + { 0x1400, "GL_BYTE " }, + { 0x1401, "GL_UBYTE" }, + { 0x1402, "GL_SHORT" }, + { 0x1403, "GL_USHRT" }, + { 0x1404, "GL_INT " }, + { 0x1405, "GL_UINT " }, + { 0x1406, "GL_FLOAT" }, + { 0x1407, "GL_2_BYTES" }, + { 0x1408, "GL_3_BYTES" }, + { 0x1409, "GL_4_BYTES" }, + { 0x140A, "GL_DOUBLE" }, + { 0x140B, "GL_HALF_FLOAT" }, + { 0x1500, "GL_CLEAR" }, + { 0x1501, "GL_AND" }, + { 0x1502, "GL_AND_REVERSE" }, + { 0x1503, "GL_COPY" }, + { 0x1504, "GL_AND_INVERTED" }, + { 0x1505, "GL_NOOP" }, + { 0x1506, "GL_XOR" }, + { 0x1507, "GL_OR" }, + { 0x1508, "GL_NOR" }, + { 0x1509, "GL_EQUIV" }, + { 0x150A, "GL_INVERT" }, + { 0x150B, "GL_OR_REVERSE" }, + { 0x150C, "GL_COPY_INVERTED" }, + { 0x150D, "GL_OR_INVERTED" }, + { 0x150E, "GL_NAND" }, + { 0x150F, "GL_SET" }, + { 0x1600, "GL_EMISSION" }, + { 0x1601, "GL_SHININESS" }, + { 0x1602, "GL_AMBIENT_AND_DIFFUSE" }, + { 0x1603, "GL_COLOR_INDEXES" }, + { 0x1700, "GL_MODELVIEW" }, + { 0x1700, "GL_MODELVIEW0_ARB" }, + { 0x1701, "GL_PROJECTION" }, + { 0x1702, "GL_TEXTURE" }, + { 0x1800, "GL_COLOR" }, + { 0x1801, "GL_DEPTH" }, + { 0x1802, "GL_STENCIL" }, + { 0x1900, "GL_COLOR_INDEX" }, + { 0x1901, "GL_STENCIL_INDEX" }, + { 0x1902, "GL_DEPTH_COMPONENT" }, + { 0x1903, "GL_RED" }, + { 0x1904, "GL_GREEN" }, + { 0x1905, "GL_BLUE" }, + { 0x1906, "GL_ALPHA" }, + { 0x1907, "GL_RGB" }, + { 0x1908, "GL_RGBA" }, + { 0x1909, "GL_LUMINANCE" }, + { 0x190A, "GL_LUMINANCE_ALPHA" }, + { 0x1A00, "GL_BITMAP" }, + { 0x1B00, "GL_POINT" }, + { 0x1B01, "GL_LINE" }, + { 0x1B02, "GL_FILL" }, + { 0x1C00, "GL_RENDER" }, + { 0x1C01, "GL_FEEDBACK" }, + { 0x1C02, "GL_SELECT" }, + { 0x1D00, "GL_FLAT" }, + { 0x1D01, "GL_SMOOTH" }, + { 0x1E00, "GL_KEEP" }, + { 0x1E01, "GL_REPLACE" }, + { 0x1E02, "GL_INCR" }, + { 0x1E03, "GL_DECR" }, + { 0x1F00, "GL_VENDOR" }, + { 0x1F01, "GL_RENDERER" }, + { 0x1F02, "GL_VERSION" }, + { 0x1F03, "GL_EXTENSIONS" }, + { 0x2000, "GL_S" }, + { 0x2001, "GL_T" }, + { 0x2002, "GL_R" }, + { 0x2003, "GL_Q" }, + { 0x2100, "GL_MODULATE" }, + { 0x2101, "GL_DECAL" }, + { 0x2200, "GL_TEXTURE_ENV_MODE" }, + { 0x2201, "GL_TEXTURE_ENV_COLOR" }, + { 0x2300, "GL_TEXTURE_ENV" }, + { 0x2400, "GL_EYE_LINEAR" }, + { 0x2401, "GL_OBJECT_LINEAR" }, + { 0x2402, "GL_SPHERE_MAP" }, + { 0x2500, "GL_TEXTURE_GEN_MODE" }, + { 0x2501, "GL_OBJECT_PLANE" }, + { 0x2502, "GL_EYE_PLANE" }, + { 0x2600, "GL_NEAREST" }, + { 0x2601, "GL_LINEAR" }, + { 0x2700, "GL_NEAREST_MIPMAP_NEAREST" }, + { 0x2701, "GL_LINEAR_MIPMAP_NEAREST" }, + { 0x2702, "GL_NEAREST_MIPMAP_LINEAR" }, + { 0x2703, "GL_LINEAR_MIPMAP_LINEAR" }, + { 0x2800, "GL_TEXTURE_MAG_FILTER" }, + { 0x2801, "GL_TEXTURE_MIN_FILTER" }, + { 0x2802, "GL_TEXTURE_WRAP_S" }, + { 0x2803, "GL_TEXTURE_WRAP_T" }, + { 0x2900, "GL_CLAMP" }, + { 0x2901, "GL_REPEAT" }, + { 0x2A00, "GL_POLYGON_OFFSET_UNITS" }, + { 0x2A01, "GL_POLYGON_OFFSET_POINT" }, + { 0x2A02, "GL_POLYGON_OFFSET_LINE" }, + { 0x2A10, "GL_R3_G3_B2" }, + { 0x2A20, "GL_V2F" }, + { 0x2A21, "GL_V3F" }, + { 0x2A22, "GL_C4UB_V2F" }, + { 0x2A23, "GL_C4UB_V3F" }, + { 0x2A24, "GL_C3F_V3F" }, + { 0x2A25, "GL_N3F_V3F" }, + { 0x2A26, "GL_C4F_N3F_V3F" }, + { 0x2A27, "GL_T2F_V3F" }, + { 0x2A28, "GL_T4F_V4F" }, + { 0x2A29, "GL_T2F_C4UB_V3F" }, + { 0x2A2A, "GL_T2F_C3F_V3F" }, + { 0x2A2B, "GL_T2F_N3F_V3F" }, + { 0x2A2C, "GL_T2F_C4F_N3F_V3F" }, + { 0x2A2D, "GL_T4F_C4F_N3F_V4F" }, + { 0x3000, "GL_CLIP_PLANE0" }, + { 0x3001, "GL_CLIP_PLANE1" }, + { 0x3002, "GL_CLIP_PLANE2" }, + { 0x3003, "GL_CLIP_PLANE3" }, + { 0x3004, "GL_CLIP_PLANE4" }, + { 0x3005, "GL_CLIP_PLANE5" }, + { 0x4000, "GL_LIGHT0" }, + { 0x4001, "GL_LIGHT1" }, + { 0x4002, "GL_LIGHT2" }, + { 0x4003, "GL_LIGHT3" }, + { 0x4004, "GL_LIGHT4" }, + { 0x4005, "GL_LIGHT5" }, + { 0x4006, "GL_LIGHT6" }, + { 0x4007, "GL_LIGHT7" }, + { 0x8000, "GL_ABGR_EXT" }, + { 0x8001, "GL_CONSTANT_COLOR" }, + { 0x8002, "GL_ONE_MINUS_CONSTANT_COLOR" }, + { 0x8003, "GL_CONSTANT_ALPHA" }, + { 0x8004, "GL_ONE_MINUS_CONSTANT_ALPHA" }, + { 0x8005, "GL_BLEND_COLOR" }, + { 0x8006, "GL_FUNC_ADD" }, + { 0x8007, "GL_MIN" }, + { 0x8008, "GL_MAX" }, + { 0x8009, "GL_BLEND_EQUATION_RGB" }, + { 0x8009, "GL_BLEND_EQUATION" }, + { 0x800A, "GL_FUNC_SUBTRACT" }, + { 0x800B, "GL_FUNC_REVERSE_SUBTRACT" }, + { 0x8010, "GL_CONVOLUTION_1D" }, + { 0x8011, "GL_CONVOLUTION_2D" }, + { 0x8012, "GL_SEPARABLE_2D" }, + { 0x8013, "GL_CONVOLUTION_BORDER_MODE" }, + { 0x8014, "GL_CONVOLUTION_FILTER_SCALE" }, + { 0x8015, "GL_CONVOLUTION_FILTER_BIAS" }, + { 0x8016, "GL_REDUCE" }, + { 0x8017, "GL_CONVOLUTION_FORMAT" }, + { 0x8018, "GL_CONVOLUTION_WIDTH" }, + { 0x8019, "GL_CONVOLUTION_HEIGHT" }, + { 0x801A, "GL_MAX_CONVOLUTION_WIDTH" }, + { 0x801B, "GL_MAX_CONVOLUTION_HEIGHT" }, + { 0x801C, "GL_POST_CONVOLUTION_RED_SCALE" }, + { 0x801D, "GL_POST_CONVOLUTION_GREEN_SCALE" }, + { 0x801E, "GL_POST_CONVOLUTION_BLUE_SCALE" }, + { 0x801F, "GL_POST_CONVOLUTION_ALPHA_SCALE" }, + { 0x8020, "GL_POST_CONVOLUTION_RED_BIAS" }, + { 0x8021, "GL_POST_CONVOLUTION_GREEN_BIAS" }, + { 0x8022, "GL_POST_CONVOLUTION_BLUE_BIAS" }, + { 0x8023, "GL_POST_CONVOLUTION_ALPHA_BIAS" }, + { 0x8024, "GL_HISTOGRAM" }, + { 0x8025, "GL_PROXY_HISTOGRAM" }, + { 0x8026, "GL_HISTOGRAM_WIDTH" }, + { 0x8027, "GL_HISTOGRAM_FORMAT" }, + { 0x8028, "GL_HISTOGRAM_RED_SIZE" }, + { 0x8029, "GL_HISTOGRAM_GREEN_SIZE" }, + { 0x802A, "GL_HISTOGRAM_BLUE_SIZE" }, + { 0x802B, "GL_HISTOGRAM_ALPHA_SIZE" }, + { 0x802C, "GL_HISTOGRAM_LUMINANCE_SIZE" }, + { 0x802D, "GL_HISTOGRAM_SINK" }, + { 0x802E, "GL_MINMAX" }, + { 0x802F, "GL_MINMAX_FORMAT" }, + { 0x8030, "GL_MINMAX_SINK" }, + { 0x8031, "GL_TABLE_TOO_LARGE" }, + { 0x8032, "GL_UNSIGNED_BYTE_3_3_2" }, + { 0x8033, "GL_UNSIGNED_SHORT_4_4_4_4" }, + { 0x8034, "GL_UNSIGNED_SHORT_5_5_5_1" }, + { 0x8035, "GL_UNSIGNED_INT_8_8_8_8" }, + { 0x8036, "GL_UNSIGNED_INT_10_10_10_2" }, + { 0x8037, "GL_POLYGON_OFFSET_FILL" }, + { 0x8038, "GL_POLYGON_OFFSET_FACTOR" }, + { 0x803A, "GL_RESCALE_NORMAL" }, + { 0x803B, "GL_ALPHA4" }, + { 0x803C, "GL_ALPHA8" }, + { 0x803D, "GL_ALPHA12" }, + { 0x803E, "GL_ALPHA16" }, + { 0x803F, "GL_LUMINANCE4" }, + { 0x8040, "GL_LUMINANCE8" }, + { 0x8041, "GL_LUMINANCE12" }, + { 0x8042, "GL_LUMINANCE16" }, + { 0x8043, "GL_LUMINANCE4_ALPHA4" }, + { 0x8044, "GL_LUMINANCE6_ALPHA2" }, + { 0x8045, "GL_LUMINANCE8_ALPHA8" }, + { 0x8046, "GL_LUMINANCE12_ALPHA4" }, + { 0x8047, "GL_LUMINANCE12_ALPHA12" }, + { 0x8048, "GL_LUMINANCE16_ALPHA16" }, + { 0x8049, "GL_INTENSITY" }, + { 0x804A, "GL_INTENSITY4" }, + { 0x804B, "GL_INTENSITY8" }, + { 0x804C, "GL_INTENSITY12" }, + { 0x804D, "GL_INTENSITY16" }, + { 0x804F, "GL_RGB4" }, + { 0x8050, "GL_RGB5" }, + { 0x8051, "GL_RGB8" }, + { 0x8052, "GL_RGB10" }, + { 0x8053, "GL_RGB12" }, + { 0x8054, "GL_RGB16" }, + { 0x8055, "GL_RGBA2" }, + { 0x8056, "GL_RGBA4" }, + { 0x8057, "GL_RGB5_A1" }, + { 0x8058, "GL_RGBA8" }, + { 0x8059, "GL_RGB10_A2" }, + { 0x805A, "GL_RGBA12" }, + { 0x805B, "GL_RGBA16" }, + { 0x805C, "GL_TEXTURE_RED_SIZE" }, + { 0x805D, "GL_TEXTURE_GREEN_SIZE" }, + { 0x805E, "GL_TEXTURE_BLUE_SIZE" }, + { 0x805F, "GL_TEXTURE_ALPHA_SIZE" }, + { 0x8060, "GL_TEXTURE_LUMINANCE_SIZE" }, + { 0x8061, "GL_TEXTURE_INTENSITY_SIZE" }, + { 0x8063, "GL_PROXY_TEXTURE_1D" }, + { 0x8064, "GL_PROXY_TEXTURE_2D" }, + { 0x8066, "GL_TEXTURE_PRIORITY" }, + { 0x8067, "GL_TEXTURE_RESIDENT" }, + { 0x8068, "GL_TEXTURE_BINDING_1D" }, + { 0x8069, "GL_TEXTURE_BINDING_2D" }, + { 0x806A, "GL_TEXTURE_BINDING_3D" }, + { 0x806B, "GL_PACK_SKIP_IMAGES" }, + { 0x806C, "GL_PACK_IMAGE_HEIGHT" }, + { 0x806D, "GL_UNPACK_SKIP_IMAGES" }, + { 0x806E, "GL_UNPACK_IMAGE_HEIGHT" }, + { 0x806F, "GL_TEXTURE_3D" }, + { 0x8070, "GL_PROXY_TEXTURE_3D" }, + { 0x8071, "GL_TEXTURE_DEPTH" }, + { 0x8072, "GL_TEXTURE_WRAP_R" }, + { 0x8073, "GL_MAX_3D_TEXTURE_SIZE" }, + { 0x8074, "GL_VERTEX_ARRAY" }, + { 0x8075, "GL_NORMAL_ARRAY" }, + { 0x8076, "GL_COLOR_ARRAY" }, + { 0x8077, "GL_INDEX_ARRAY" }, + { 0x8078, "GL_TEXTURE_COORD_ARRAY" }, + { 0x8079, "GL_EDGE_FLAG_ARRAY" }, + { 0x807A, "GL_VERTEX_ARRAY_SIZE" }, + { 0x807B, "GL_VERTEX_ARRAY_TYPE" }, + { 0x807C, "GL_VERTEX_ARRAY_STRIDE" }, + { 0x807E, "GL_NORMAL_ARRAY_TYPE" }, + { 0x807F, "GL_NORMAL_ARRAY_STRIDE" }, + { 0x8081, "GL_COLOR_ARRAY_SIZE" }, + { 0x8082, "GL_COLOR_ARRAY_TYPE" }, + { 0x8083, "GL_COLOR_ARRAY_STRIDE" }, + { 0x8085, "GL_INDEX_ARRAY_TYPE" }, + { 0x8086, "GL_INDEX_ARRAY_STRIDE" }, + { 0x8088, "GL_TEXTURE_COORD_ARRAY_SIZE" }, + { 0x8089, "GL_TEXTURE_COORD_ARRAY_TYPE" }, + { 0x808A, "GL_TEXTURE_COORD_ARRAY_STRIDE" }, + { 0x808C, "GL_EDGE_FLAG_ARRAY_STRIDE" }, + { 0x808E, "GL_VERTEX_ARRAY_POINTER" }, + { 0x808F, "GL_NORMAL_ARRAY_POINTER" }, + { 0x8090, "GL_COLOR_ARRAY_POINTER" }, + { 0x8091, "GL_INDEX_ARRAY_POINTER" }, + { 0x8092, "GL_TEXTURE_COORD_ARRAY_POINTER" }, + { 0x8093, "GL_EDGE_FLAG_ARRAY_POINTER" }, + { 0x809D, "GL_MULTISAMPLE_ARB" }, + { 0x809D, "GL_MULTISAMPLE" }, + { 0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE_ARB" }, + { 0x809E, "GL_SAMPLE_ALPHA_TO_COVERAGE" }, + { 0x809F, "GL_SAMPLE_ALPHA_TO_ONE_ARB" }, + { 0x809F, "GL_SAMPLE_ALPHA_TO_ONE" }, + { 0x80A0, "GL_SAMPLE_COVERAGE_ARB" }, + { 0x80A0, "GL_SAMPLE_COVERAGE" }, + { 0x80A0, "GL_SAMPLE_MASK_EXT" }, + { 0x80A1, "GL_1PASS_EXT" }, + { 0x80A2, "GL_2PASS_0_EXT" }, + { 0x80A3, "GL_2PASS_1_EXT" }, + { 0x80A4, "GL_4PASS_0_EXT" }, + { 0x80A5, "GL_4PASS_1_EXT" }, + { 0x80A6, "GL_4PASS_2_EXT" }, + { 0x80A7, "GL_4PASS_3_EXT" }, + { 0x80A8, "GL_SAMPLE_BUFFERS" }, + { 0x80A9, "GL_SAMPLES" }, + { 0x80AA, "GL_SAMPLE_COVERAGE_VALUE" }, + { 0x80AB, "GL_SAMPLE_COVERAGE_INVERT" }, + { 0x80AC, "GL_SAMPLE_PATTERN_EXT" }, + { 0x80B1, "GL_COLOR_MATRIX" }, + { 0x80B2, "GL_COLOR_MATRIX_STACK_DEPTH" }, + { 0x80B3, "GL_MAX_COLOR_MATRIX_STACK_DEPTH" }, + { 0x80B4, "GL_POST_COLOR_MATRIX_RED_SCALE" }, + { 0x80B5, "GL_POST_COLOR_MATRIX_GREEN_SCALE" }, + { 0x80B6, "GL_POST_COLOR_MATRIX_BLUE_SCALE" }, + { 0x80B7, "GL_POST_COLOR_MATRIX_ALPHA_SCALE" }, + { 0x80B8, "GL_POST_COLOR_MATRIX_RED_BIAS" }, + { 0x80B9, "GL_POST_COLOR_MATRIX_GREEN_BIAS" }, + { 0x80BA, "GL_POST_COLOR_MATRIX_BLUE_BIAS" }, + { 0x80BB, "GL_POST_COLOR_MATRIX_ALPHA_BIAS" }, + { 0x80BF, "GL_TEXTURE_COMPARE_FAIL_VALUE_ARB" }, + { 0x80C8, "GL_BLEND_DST_RGB" }, + { 0x80C9, "GL_BLEND_SRC_RGB" }, + { 0x80CA, "GL_BLEND_DST_ALPHA" }, + { 0x80CB, "GL_BLEND_SRC_ALPHA" }, + { 0x80CC, "GL_422_EXT" }, + { 0x80CD, "GL_422_REV_EXT" }, + { 0x80CE, "GL_422_AVERAGE_EXT" }, + { 0x80CF, "GL_422_REV_AVERAGE_EXT" }, + { 0x80D0, "GL_COLOR_TABLE" }, + { 0x80D1, "GL_POST_CONVOLUTION_COLOR_TABLE" }, + { 0x80D2, "GL_POST_COLOR_MATRIX_COLOR_TABLE" }, + { 0x80D3, "GL_PROXY_COLOR_TABLE" }, + { 0x80D4, "GL_PROXY_POST_CONVOLUTION_COLOR_TABLE" }, + { 0x80D5, "GL_PROXY_POST_COLOR_MATRIX_COLOR_TABLE" }, + { 0x80D6, "GL_COLOR_TABLE_SCALE" }, + { 0x80D7, "GL_COLOR_TABLE_BIAS" }, + { 0x80D8, "GL_COLOR_TABLE_FORMAT" }, + { 0x80D9, "GL_COLOR_TABLE_WIDTH" }, + { 0x80DA, "GL_COLOR_TABLE_RED_SIZE" }, + { 0x80DB, "GL_COLOR_TABLE_GREEN_SIZE" }, + { 0x80DC, "GL_COLOR_TABLE_BLUE_SIZE" }, + { 0x80DD, "GL_COLOR_TABLE_ALPHA_SIZE" }, + { 0x80DE, "GL_COLOR_TABLE_LUMINANCE_SIZE" }, + { 0x80DF, "GL_COLOR_TABLE_INTENSITY_SIZE" }, + { 0x80E0, "GL_BGR_EXT" }, + { 0x80E0, "GL_BGR" }, + { 0x80E1, "GL_BGRA_EXT" }, + { 0x80E1, "GL_BGRA" }, + { 0x80E1, "GL_BGRA" }, + { 0x80E2, "GL_COLOR_INDEX1_EXT" }, + { 0x80E3, "GL_COLOR_INDEX2_EXT" }, + { 0x80E4, "GL_COLOR_INDEX4_EXT" }, + { 0x80E5, "GL_COLOR_INDEX8_EXT" }, + { 0x80E6, "GL_COLOR_INDEX12_EXT" }, + { 0x80E7, "GL_COLOR_INDEX16_EXT" }, + { 0x80E8, "GL_MAX_ELEMENTS_VERTICES_EXT" }, + { 0x80E8, "GL_MAX_ELEMENTS_VERTICES" }, + { 0x80E9, "GL_MAX_ELEMENTS_INDICES_EXT" }, + { 0x80E9, "GL_MAX_ELEMENTS_INDICES" }, + { 0x80ED, "GL_TEXTURE_INDEX_SIZE_EXT" }, + { 0x80F0, "GL_CLIP_VOLUME_CLIPPING_HINT_EXT" }, + { 0x8126, "GL_POINT_SIZE_MIN_ARB" }, + { 0x8126, "GL_POINT_SIZE_MIN" }, + { 0x8127, "GL_POINT_SIZE_MAX_ARB" }, + { 0x8127, "GL_POINT_SIZE_MAX" }, + { 0x8128, "GL_POINT_FADE_THRESHOLD_SIZE_ARB" }, + { 0x8128, "GL_POINT_FADE_THRESHOLD_SIZE" }, + { 0x8129, "GL_POINT_DISTANCE_ATTENUATION_ARB" }, + { 0x8129, "GL_POINT_DISTANCE_ATTENUATION" }, + { 0x812D, "GL_CLAMP_TO_BORDER_ARB" }, + { 0x812D, "GL_CLAMP_TO_BORDER" }, + { 0x812F, "GL_CLAMP_TO_EDGE" }, + { 0x813A, "GL_TEXTURE_MIN_LOD" }, + { 0x813B, "GL_TEXTURE_MAX_LOD" }, + { 0x813C, "GL_TEXTURE_BASE_LEVEL" }, + { 0x813D, "GL_TEXTURE_MAX_LEVEL" }, + { 0x8151, "GL_CONSTANT_BORDER" }, + { 0x8153, "GL_REPLICATE_BORDER" }, + { 0x8154, "GL_CONVOLUTION_BORDER_COLOR" }, + { 0x8191, "GL_GENERATE_MIPMAP" }, + { 0x8192, "GL_GENERATE_MIPMAP_HINT" }, + { 0x81A5, "GL_DEPTH_COMPONENT16_ARB" }, + { 0x81A5, "GL_DEPTH_COMPONENT16" }, + { 0x81A6, "GL_DEPTH_COMPONENT24_ARB" }, + { 0x81A6, "GL_DEPTH_COMPONENT24" }, + { 0x81A7, "GL_DEPTH_COMPONENT32_ARB" }, + { 0x81A7, "GL_DEPTH_COMPONENT32" }, + { 0x81A8, "GL_ARRAY_ELEMENT_LOCK_FIRST_EXT" }, + { 0x81A9, "GL_ARRAY_ELEMENT_LOCK_COUNT_EXT" }, + { 0x81AA, "GL_CULL_VERTEX_EXT" }, + { 0x81AB, "GL_CULL_VERTEX_EYE_POSITION_EXT" }, + { 0x81AC, "GL_CULL_VERTEX_OBJECT_POSITION_EXT" }, + { 0x81AD, "GL_IUI_V2F_EXT" }, + { 0x81AE, "GL_IUI_V3F_EXT" }, + { 0x81AF, "GL_IUI_N3F_V2F_EXT" }, + { 0x81B0, "GL_IUI_N3F_V3F_EXT" }, + { 0x81B1, "GL_T2F_IUI_V2F_EXT" }, + { 0x81B2, "GL_T2F_IUI_V3F_EXT" }, + { 0x81B3, "GL_T2F_IUI_N3F_V2F_EXT" }, + { 0x81B4, "GL_T2F_IUI_N3F_V3F_EXT" }, + { 0x81B5, "GL_INDEX_TEST_EXT" }, + { 0x81B6, "GL_INDEX_TEST_FUNC_EXT" }, + { 0x81B7, "GL_INDEX_TEST_REF_EXT" }, + { 0x81B8, "GL_INDEX_MATERIAL_EXT" }, + { 0x81B9, "GL_INDEX_MATERIAL_PARAMETER_EXT" }, + { 0x81BA, "GL_INDEX_MATERIAL_FACE_EXT" }, + { 0x81F8, "GL_LIGHT_MODEL_COLOR_CONTROL_EXT" }, + { 0x81F8, "GL_LIGHT_MODEL_COLOR_CONTROL" }, + { 0x81F9, "GL_SINGLE_COLOR_EXT" }, + { 0x81F9, "GL_SINGLE_COLOR" }, + { 0x81FA, "GL_SEPARATE_SPECULAR_COLOR_EXT" }, + { 0x81FA, "GL_SEPARATE_SPECULAR_COLOR" }, + { 0x81FB, "GL_SHARED_TEXTURE_PALETTE_EXT" }, + { 0x8210, "GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING" }, + { 0x8211, "GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE" }, + { 0x8212, "GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE" }, + { 0x8213, "GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE" }, + { 0x8214, "GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE" }, + { 0x8215, "GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE" }, + { 0x8216, "GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE" }, + { 0x8217, "GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE" }, + { 0x8218, "GL_FRAMEBUFFER_DEFAULT" }, + { 0x8219, "GL_FRAMEBUFFER_UNDEFINED" }, + { 0x821A, "GL_DEPTH_STENCIL_ATTACHMENT" }, + { 0x8225, "GL_COMPRESSED_RED" }, + { 0x8226, "GL_COMPRESSED_RG" }, + { 0x8227, "GL_RG" }, + { 0x8228, "GL_RG_INTEGER" }, + { 0x8229, "GL_R8" }, + { 0x822A, "GL_R16" }, + { 0x822B, "GL_RG8" }, + { 0x822C, "GL_RG16" }, + { 0x822D, "GL_R16F" }, + { 0x822E, "GL_R32F" }, + { 0x822F, "GL_RG16F" }, + { 0x8230, "GL_RG32F" }, + { 0x8231, "GL_R8I" }, + { 0x8232, "GL_R8UI" }, + { 0x8233, "GL_R16I" }, + { 0x8234, "GL_R16UI" }, + { 0x8235, "GL_R32I" }, + { 0x8236, "GL_R32UI" }, + { 0x8237, "GL_RG8I" }, + { 0x8238, "GL_RG8UI" }, + { 0x8239, "GL_RG16I" }, + { 0x823A, "GL_RG16UI" }, + { 0x823B, "GL_RG32I" }, + { 0x823C, "GL_RG32UI" }, + { 0x8330, "GL_PIXEL_TRANSFORM_2D_EXT" }, + { 0x8331, "GL_PIXEL_MAG_FILTER_EXT" }, + { 0x8332, "GL_PIXEL_MIN_FILTER_EXT" }, + { 0x8333, "GL_PIXEL_CUBIC_WEIGHT_EXT" }, + { 0x8334, "GL_CUBIC_EXT" }, + { 0x8335, "GL_AVERAGE_EXT" }, + { 0x8336, "GL_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT" }, + { 0x8337, "GL_MAX_PIXEL_TRANSFORM_2D_STACK_DEPTH_EXT" }, + { 0x8338, "GL_PIXEL_TRANSFORM_2D_MATRIX_EXT" }, + { 0x8349, "GL_FRAGMENT_MATERIAL_EXT" }, + { 0x834A, "GL_FRAGMENT_NORMAL_EXT" }, + { 0x834C, "GL_FRAGMENT_COLOR_EXT" }, + { 0x834D, "GL_ATTENUATION_EXT" }, + { 0x834E, "GL_SHADOW_ATTENUATION_EXT" }, + { 0x834F, "GL_TEXTURE_APPLICATION_MODE_EXT" }, + { 0x8350, "GL_TEXTURE_LIGHT_EXT" }, + { 0x8351, "GL_TEXTURE_MATERIAL_FACE_EXT" }, + { 0x8352, "GL_TEXTURE_MATERIAL_PARAMETER_EXT" }, + { 0x8362, "GL_UNSIGNED_BYTE_2_3_3_REV" }, + { 0x8363, "GL_UNSIGNED_SHORT_5_6_5" }, + { 0x8364, "GL_UNSIGNED_SHORT_5_6_5_REV" }, + { 0x8365, "GL_UNSIGNED_SHORT_4_4_4_4_REV" }, + { 0x8366, "GL_UNSIGNED_SHORT_1_5_5_5_REV" }, + { 0x8367, "GL_UNSIGNED_INT_8_8_8_8_REV" }, + { 0x8368, "GL_UNSIGNED_INT_2_10_10_10_REV" }, + { 0x8370, "GL_MIRRORED_REPEAT_ARB" }, + { 0x8370, "GL_MIRRORED_REPEAT" }, + { 0x83F0, "GL_COMPRESSED_RGB_S3TC_DXT1_EXT" }, + { 0x83F1, "GL_COMPRESSED_RGBA_S3TC_DXT1_EXT" }, + { 0x83F2, "GL_COMPRESSED_RGBA_S3TC_DXT3_EXT" }, + { 0x83F3, "GL_COMPRESSED_RGBA_S3TC_DXT5_EXT" }, + { 0x8439, "GL_TANGENT_ARRAY_EXT" }, + { 0x843A, "GL_BINORMAL_ARRAY_EXT" }, + { 0x843B, "GL_CURRENT_TANGENT_EXT" }, + { 0x843C, "GL_CURRENT_BINORMAL_EXT" }, + { 0x843E, "GL_TANGENT_ARRAY_TYPE_EXT" }, + { 0x843F, "GL_TANGENT_ARRAY_STRIDE_EXT" }, + { 0x8440, "GL_BINORMAL_ARRAY_TYPE_EXT" }, + { 0x8441, "GL_BINORMAL_ARRAY_STRIDE_EXT" }, + { 0x8442, "GL_TANGENT_ARRAY_POINTER_EXT" }, + { 0x8443, "GL_BINORMAL_ARRAY_POINTER_EXT" }, + { 0x8444, "GL_MAP1_TANGENT_EXT" }, + { 0x8445, "GL_MAP2_TANGENT_EXT" }, + { 0x8446, "GL_MAP1_BINORMAL_EXT" }, + { 0x8447, "GL_MAP2_BINORMAL_EXT" }, + { 0x8450, "GL_FOG_COORD_SRC" }, + { 0x8450, "GL_FOG_COORDINATE_SOURCE_EXT" }, + { 0x8450, "GL_FOG_COORDINATE_SOURCE" }, + { 0x8451, "GL_FOG_COORD" }, + { 0x8451, "GL_FOG_COORDINATE_EXT" }, + { 0x8451, "GL_FOG_COORDINATE" }, + { 0x8452, "GL_FRAGMENT_DEPTH_EXT" }, + { 0x8452, "GL_FRAGMENT_DEPTH" }, + { 0x8453 , "GL_CURRENT_FOG_COORD" }, + { 0x8453 , "GL_CURRENT_FOG_COORDINATE" }, + { 0x8453, "GL_CURRENT_FOG_COORDINATE_EXT" }, + { 0x8454, "GL_FOG_COORD_ARRAY_TYPE" }, + { 0x8454, "GL_FOG_COORDINATE_ARRAY_TYPE_EXT" }, + { 0x8454, "GL_FOG_COORDINATE_ARRAY_TYPE" }, + { 0x8455, "GL_FOG_COORD_ARRAY_STRIDE" }, + { 0x8455, "GL_FOG_COORDINATE_ARRAY_STRIDE_EXT" }, + { 0x8455, "GL_FOG_COORDINATE_ARRAY_STRIDE" }, + { 0x8456, "GL_FOG_COORD_ARRAY_POINTER" }, + { 0x8456, "GL_FOG_COORDINATE_ARRAY_POINTER_EXT" }, + { 0x8456, "GL_FOG_COORDINATE_ARRAY_POINTER" }, + { 0x8457, "GL_FOG_COORD_ARRAY" }, + { 0x8457, "GL_FOG_COORDINATE_ARRAY_EXT" }, + { 0x8457, "GL_FOG_COORDINATE_ARRAY" }, + { 0x8458, "GL_COLOR_SUM_ARB" }, + { 0x8458, "GL_COLOR_SUM_EXT" }, + { 0x8458, "GL_COLOR_SUM" }, + { 0x8459, "GL_CURRENT_SECONDARY_COLOR_EXT" }, + { 0x8459, "GL_CURRENT_SECONDARY_COLOR" }, + { 0x845A, "GL_SECONDARY_COLOR_ARRAY_SIZE_EXT" }, + { 0x845A, "GL_SECONDARY_COLOR_ARRAY_SIZE" }, + { 0x845B, "GL_SECONDARY_COLOR_ARRAY_TYPE_EXT" }, + { 0x845B, "GL_SECONDARY_COLOR_ARRAY_TYPE" }, + { 0x845C, "GL_SECONDARY_COLOR_ARRAY_STRIDE_EXT" }, + { 0x845C, "GL_SECONDARY_COLOR_ARRAY_STRIDE" }, + { 0x845D, "GL_SECONDARY_COLOR_ARRAY_POINTER_EXT" }, + { 0x845D, "GL_SECONDARY_COLOR_ARRAY_POINTER" }, + { 0x845E, "GL_SECONDARY_COLOR_ARRAY_EXT" }, + { 0x845E, "GL_SECONDARY_COLOR_ARRAY" }, + { 0x845F, "GL_CURRENT_RASTER_SECONDARY_COLOR" }, + { 0x846D, "GL_ALIASED_POINT_SIZE_RANGE" }, + { 0x846E, "GL_ALIASED_LINE_WIDTH_RANGE" }, + { 0x84C0, "GL_TEXTURE0" }, + { 0x84C1, "GL_TEXTURE1" }, + { 0x84C2, "GL_TEXTURE2" }, + { 0x84C3, "GL_TEXTURE3" }, + { 0x84C4, "GL_TEXTURE4" }, + { 0x84C5, "GL_TEXTURE5" }, + { 0x84C6, "GL_TEXTURE6" }, + { 0x84C7, "GL_TEXTURE7" }, + { 0x84C8, "GL_TEXTURE8" }, + { 0x84C9, "GL_TEXTURE9" }, + { 0x84CA, "GL_TEXTURE10" }, + { 0x84CB, "GL_TEXTURE11" }, + { 0x84CC, "GL_TEXTURE12" }, + { 0x84CD, "GL_TEXTURE13" }, + { 0x84CE, "GL_TEXTURE14" }, + { 0x84CF, "GL_TEXTURE15" }, + { 0x84D0, "GL_TEXTURE16" }, + { 0x84D1, "GL_TEXTURE17" }, + { 0x84D2, "GL_TEXTURE18" }, + { 0x84D3, "GL_TEXTURE19" }, + { 0x84D4, "GL_TEXTURE20" }, + { 0x84D5, "GL_TEXTURE21" }, + { 0x84D6, "GL_TEXTURE22" }, + { 0x84D7, "GL_TEXTURE23" }, + { 0x84D8, "GL_TEXTURE24" }, + { 0x84D9, "GL_TEXTURE25" }, + { 0x84DA, "GL_TEXTURE26" }, + { 0x84DB, "GL_TEXTURE27" }, + { 0x84DC, "GL_TEXTURE28" }, + { 0x84DD, "GL_TEXTURE29" }, + { 0x84DE, "GL_TEXTURE30" }, + { 0x84DF, "GL_TEXTURE31" }, + { 0x84E0, "GL_ACTIVE_TEXTURE" }, + { 0x84E1, "GL_CLIENT_ACTIVE_TEXTURE" }, + { 0x84E2, "GL_MAX_TEXTURE_UNITS" }, + { 0x84E3, "GL_TRANSPOSE_MODELVIEW_MATRIX" }, + { 0x84E4, "GL_TRANSPOSE_PROJECTION_MATRIX" }, + { 0x84E5, "GL_TRANSPOSE_TEXTURE_MATRIX" }, + { 0x84E6, "GL_TRANSPOSE_COLOR_MATRIX" }, + { 0x84E7, "GL_SUBTRACT" }, + { 0x84E8, "GL_MAX_RENDERBUFFER_SIZE" }, + { 0x84E9, "GL_COMPRESSED_ALPHA" }, + { 0x84EA, "GL_COMPRESSED_LUMINANCE" }, + { 0x84EB, "GL_COMPRESSED_LUMINANCE_ALPHA" }, + { 0x84EC, "GL_COMPRESSED_INTENSITY" }, + { 0x84ED, "GL_COMPRESSED_RGB" }, + { 0x84EE, "GL_COMPRESSED_RGBA" }, + { 0x84EF, "GL_TEXTURE_COMPRESSION_HINT" }, + { 0x84F5, "GL_TEXTURE_RECTANGLE_EXT" }, + { 0x84F6, "GL_TEXTURE_BINDING_RECTANGLE_EXT" }, + { 0x84F7, "GL_PROXY_TEXTURE_RECTANGLE_EXT" }, + { 0x84F8, "GL_MAX_RECTANGLE_TEXTURE_SIZE_EXT" }, + { 0x84F9, "GL_DEPTH_STENCIL" }, + { 0x84FA, "GL_UNSIGNED_INT_24_8" }, + { 0x84FD, "GL_MAX_TEXTURE_LOD_BIAS" }, + { 0x84FE, "GL_TEXTURE_MAX_ANISOTROPY_EXT" }, + { 0x84FF, "GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT" }, + { 0x8500, "GL_TEXTURE_FILTER_CONTROL" }, + { 0x8501, "GL_TEXTURE_LOD_BIAS" }, + { 0x8502, "GL_MODELVIEW1_STACK_DEPTH_EXT" }, + { 0x8506, "GL_MODELVIEW_MATRIX1_EXT" }, + { 0x8507, "GL_INCR_WRAP" }, + { 0x8508, "GL_DECR_WRAP" }, + { 0x8509, "GL_VERTEX_WEIGHTING_EXT" }, + { 0x850A, "GL_MODELVIEW1_ARB" }, + { 0x850B, "GL_CURRENT_VERTEX_WEIGHT_EXT" }, + { 0x850C, "GL_VERTEX_WEIGHT_ARRAY_EXT" }, + { 0x850D, "GL_VERTEX_WEIGHT_ARRAY_SIZE_EXT" }, + { 0x850E, "GL_VERTEX_WEIGHT_ARRAY_TYPE_EXT" }, + { 0x850F, "GL_VERTEX_WEIGHT_ARRAY_STRIDE_EXT" }, + { 0x8510, "GL_VERTEX_WEIGHT_ARRAY_POINTER_EXT" }, + { 0x8511, "GL_NORMAL_MAP_ARB" }, + { 0x8511, "GL_NORMAL_MAP_EXT" }, + { 0x8511, "GL_NORMAL_MAP" }, + { 0x8512, "GL_REFLECTION_MAP_ARB" }, + { 0x8512, "GL_REFLECTION_MAP_EXT" }, + { 0x8512, "GL_REFLECTION_MAP" }, + { 0x8513, "GL_TEXTURE_CUBE_MAP_ARB" }, + { 0x8513, "GL_TEXTURE_CUBE_MAP_EXT" }, + { 0x8513, "GL_TEXTURE_CUBE_MAP" }, + { 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP_ARB" }, + { 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP_EXT" }, + { 0x8514, "GL_TEXTURE_BINDING_CUBE_MAP" }, + { 0x8515, "GL_TEXTURE_CUBE_MAP_POSITIVE_X" }, + { 0x8516, "GL_TEXTURE_CUBE_MAP_NEGATIVE_X" }, + { 0x8517, "GL_TEXTURE_CUBE_MAP_POSITIVE_Y" }, + { 0x8518, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Y" }, + { 0x8519, "GL_TEXTURE_CUBE_MAP_POSITIVE_Z" }, + { 0x851A, "GL_TEXTURE_CUBE_MAP_NEGATIVE_Z" }, + { 0x851B, "GL_PROXY_TEXTURE_CUBE_MAP" }, + { 0x851C, "GL_MAX_CUBE_MAP_TEXTURE_SIZE" }, + { 0x851D, "GL_VERTEX_ARRAY_RANGE_APPLE" }, + { 0x851E, "GL_VERTEX_ARRAY_RANGE_LENGTH_APPLE" }, + { 0x851F, "GL_VERTEX_ARRAY_STORAGE_HINT_APPLE" }, + { 0x8520, "GL_MAX_VERTEX_ARRAY_RANGE_ELEMENT_APPLE" }, + { 0x8521, "GL_VERTEX_ARRAY_RANGE_POINTER_APPLE" }, + { 0x8570, "GL_COMBINE_ARB" }, + { 0x8570, "GL_COMBINE_EXT" }, + { 0x8570, "GL_COMBINE" }, + { 0x8571, "GL_COMBINE_RGB_ARB" }, + { 0x8571, "GL_COMBINE_RGB_EXT" }, + { 0x8571, "GL_COMBINE_RGB" }, + { 0x8572, "GL_COMBINE_ALPHA_ARB" }, + { 0x8572, "GL_COMBINE_ALPHA_EXT" }, + { 0x8572, "GL_COMBINE_ALPHA" }, + { 0x8573, "GL_RGB_SCALE_ARB" }, + { 0x8573, "GL_RGB_SCALE_EXT" }, + { 0x8573, "GL_RGB_SCALE" }, + { 0x8574, "GL_ADD_SIGNED_ARB" }, + { 0x8574, "GL_ADD_SIGNED_EXT" }, + { 0x8574, "GL_ADD_SIGNED" }, + { 0x8575, "GL_INTERPOLATE_ARB" }, + { 0x8575, "GL_INTERPOLATE_EXT" }, + { 0x8575, "GL_INTERPOLATE" }, + { 0x8576, "GL_CONSTANT_ARB" }, + { 0x8576, "GL_CONSTANT_EXT" }, + { 0x8576, "GL_CONSTANT" }, + { 0x8577, "GL_PRIMARY_COLOR_ARB" }, + { 0x8577, "GL_PRIMARY_COLOR_EXT" }, + { 0x8577, "GL_PRIMARY_COLOR" }, + { 0x8578, "GL_PREVIOUS_ARB" }, + { 0x8578, "GL_PREVIOUS_EXT" }, + { 0x8578, "GL_PREVIOUS" }, + { 0x8580, "GL_SOURCE0_RGB_ARB" }, + { 0x8580, "GL_SOURCE0_RGB_EXT" }, + { 0x8580, "GL_SOURCE0_RGB" }, + { 0x8580, "GL_SRC0_RGB" }, + { 0x8581, "GL_SOURCE1_RGB_ARB" }, + { 0x8581, "GL_SOURCE1_RGB_EXT" }, + { 0x8581, "GL_SOURCE1_RGB" }, + { 0x8581, "GL_SRC1_RGB" }, + { 0x8582, "GL_SOURCE2_RGB_ARB" }, + { 0x8582, "GL_SOURCE2_RGB_EXT" }, + { 0x8582, "GL_SOURCE2_RGB" }, + { 0x8582, "GL_SRC2_RGB" }, + { 0x8583, "GL_SOURCE3_RGB_ARB" }, + { 0x8583, "GL_SOURCE3_RGB_EXT" }, + { 0x8583, "GL_SOURCE3_RGB" }, + { 0x8583, "GL_SRC3_RGB" }, + { 0x8584, "GL_SOURCE4_RGB_ARB" }, + { 0x8584, "GL_SOURCE4_RGB_EXT" }, + { 0x8584, "GL_SOURCE4_RGB" }, + { 0x8584, "GL_SRC4_RGB" }, + { 0x8585, "GL_SOURCE5_RGB_ARB" }, + { 0x8585, "GL_SOURCE5_RGB_EXT" }, + { 0x8585, "GL_SOURCE5_RGB" }, + { 0x8585, "GL_SRC5_RGB" }, + { 0x8586, "GL_SOURCE6_RGB_ARB" }, + { 0x8586, "GL_SOURCE6_RGB_EXT" }, + { 0x8586, "GL_SOURCE6_RGB" }, + { 0x8586, "GL_SRC6_RGB" }, + { 0x8587, "GL_SOURCE7_RGB_ARB" }, + { 0x8587, "GL_SOURCE7_RGB_EXT" }, + { 0x8587, "GL_SOURCE7_RGB" }, + { 0x8587, "GL_SRC7_RGB" }, + { 0x8588, "GL_SOURCE0_ALPHA_ARB" }, + { 0x8588, "GL_SOURCE0_ALPHA_EXT" }, + { 0x8588, "GL_SOURCE0_ALPHA" }, + { 0x8588, "GL_SRC0_ALPHA" }, + { 0x8589, "GL_SOURCE1_ALPHA_ARB" }, + { 0x8589, "GL_SOURCE1_ALPHA_EXT" }, + { 0x8589, "GL_SOURCE1_ALPHA" }, + { 0x8589, "GL_SRC1_ALPHA" }, + { 0x858A, "GL_SOURCE2_ALPHA_ARB" }, + { 0x858A, "GL_SOURCE2_ALPHA_EXT" }, + { 0x858A, "GL_SOURCE2_ALPHA" }, + { 0x858A, "GL_SRC2_ALPHA" }, + { 0x858B, "GL_SOURCE3_ALPHA_ARB" }, + { 0x858B, "GL_SOURCE3_ALPHA_EXT" }, + { 0x858B, "GL_SOURCE3_ALPHA" }, + { 0x858B, "GL_SRC3_ALPHA" }, + { 0x858C, "GL_SOURCE4_ALPHA_ARB" }, + { 0x858C, "GL_SOURCE4_ALPHA_EXT" }, + { 0x858C, "GL_SOURCE4_ALPHA" }, + { 0x858C, "GL_SRC4_ALPHA" }, + { 0x858D, "GL_SOURCE5_ALPHA_ARB" }, + { 0x858D, "GL_SOURCE5_ALPHA_EXT" }, + { 0x858D, "GL_SOURCE5_ALPHA" }, + { 0x858D, "GL_SRC5_ALPHA" }, + { 0x858E, "GL_SOURCE6_ALPHA_ARB" }, + { 0x858E, "GL_SOURCE6_ALPHA_EXT" }, + { 0x858E, "GL_SOURCE6_ALPHA" }, + { 0x858E, "GL_SRC6_ALPHA" }, + { 0x858F, "GL_SOURCE7_ALPHA_ARB" }, + { 0x858F, "GL_SOURCE7_ALPHA_EXT" }, + { 0x858F, "GL_SOURCE7_ALPHA" }, + { 0x858F, "GL_SRC7_ALPHA" }, + { 0x8590, "GL_OPERAND0_RGB_ARB" }, + { 0x8590, "GL_OPERAND0_RGB_EXT" }, + { 0x8590, "GL_OPERAND0_RGB" }, + { 0x8591, "GL_OPERAND1_RGB_ARB" }, + { 0x8591, "GL_OPERAND1_RGB_EXT" }, + { 0x8591, "GL_OPERAND1_RGB" }, + { 0x8592, "GL_OPERAND2_RGB_ARB" }, + { 0x8592, "GL_OPERAND2_RGB_EXT" }, + { 0x8592, "GL_OPERAND2_RGB" }, + { 0x8593, "GL_OPERAND3_RGB_ARB" }, + { 0x8593, "GL_OPERAND3_RGB_EXT" }, + { 0x8593, "GL_OPERAND3_RGB" }, + { 0x8594, "GL_OPERAND4_RGB_ARB" }, + { 0x8594, "GL_OPERAND4_RGB_EXT" }, + { 0x8594, "GL_OPERAND4_RGB" }, + { 0x8595, "GL_OPERAND5_RGB_ARB" }, + { 0x8595, "GL_OPERAND5_RGB_EXT" }, + { 0x8595, "GL_OPERAND5_RGB" }, + { 0x8596, "GL_OPERAND6_RGB_ARB" }, + { 0x8596, "GL_OPERAND6_RGB_EXT" }, + { 0x8596, "GL_OPERAND6_RGB" }, + { 0x8597, "GL_OPERAND7_RGB_ARB" }, + { 0x8597, "GL_OPERAND7_RGB_EXT" }, + { 0x8597, "GL_OPERAND7_RGB" }, + { 0x8598, "GL_OPERAND0_ALPHA_ARB" }, + { 0x8598, "GL_OPERAND0_ALPHA_EXT" }, + { 0x8598, "GL_OPERAND0_ALPHA" }, + { 0x8599, "GL_OPERAND1_ALPHA_ARB" }, + { 0x8599, "GL_OPERAND1_ALPHA_EXT" }, + { 0x8599, "GL_OPERAND1_ALPHA" }, + { 0x859A, "GL_OPERAND2_ALPHA_ARB" }, + { 0x859A, "GL_OPERAND2_ALPHA_EXT" }, + { 0x859A, "GL_OPERAND2_ALPHA" }, + { 0x859B, "GL_OPERAND3_ALPHA_ARB" }, + { 0x859B, "GL_OPERAND3_ALPHA_EXT" }, + { 0x859B, "GL_OPERAND3_ALPHA" }, + { 0x859C, "GL_OPERAND4_ALPHA_ARB" }, + { 0x859C, "GL_OPERAND4_ALPHA_EXT" }, + { 0x859C, "GL_OPERAND4_ALPHA" }, + { 0x859D, "GL_OPERAND5_ALPHA_ARB" }, + { 0x859D, "GL_OPERAND5_ALPHA_EXT" }, + { 0x859D, "GL_OPERAND5_ALPHA" }, + { 0x859E, "GL_OPERAND6_ALPHA_ARB" }, + { 0x859E, "GL_OPERAND6_ALPHA_EXT" }, + { 0x859E, "GL_OPERAND6_ALPHA" }, + { 0x859F, "GL_OPERAND7_ALPHA_ARB" }, + { 0x859F, "GL_OPERAND7_ALPHA_EXT" }, + { 0x859F, "GL_OPERAND7_ALPHA" }, + { 0x85AE, "GL_PERTURB_EXT" }, + { 0x85AF, "GL_TEXTURE_NORMAL_EXT" }, + { 0x85B4, "GL_STORAGE_CLIENT_APPLE" }, + { 0x85B5, "GL_VERTEX_ARRAY_BINDING_APPLE" }, + { 0x85BD, "GL_STORAGE_PRIVATE_APPLE" }, + { 0x85BE, "GL_STORAGE_CACHED_APPLE" }, + { 0x85BF, "GL_STORAGE_SHARED_APPLE" }, + { 0x8620, "GL_VERTEX_PROGRAM_ARB" }, + { 0x8620, "GL_VERTEX_PROGRAM_NV" }, + { 0x8621, "GL_VERTEX_STATE_PROGRAM_NV" }, + { 0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB" }, + { 0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB" }, + { 0x8622, "GL_VERTEX_ATTRIB_ARRAY_ENABLED" }, + { 0x8623, "GL_ATTRIB_ARRAY_SIZE_NV" }, + { 0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB" }, + { 0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB" }, + { 0x8623, "GL_VERTEX_ATTRIB_ARRAY_SIZE" }, + { 0x8624, "GL_ATTRIB_ARRAY_STRIDE_NV" }, + { 0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB" }, + { 0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB" }, + { 0x8624, "GL_VERTEX_ATTRIB_ARRAY_STRIDE" }, + { 0x8625, "GL_ATTRIB_ARRAY_TYPE_NV" }, + { 0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB" }, + { 0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB" }, + { 0x8625, "GL_VERTEX_ATTRIB_ARRAY_TYPE" }, + { 0x8626, "GL_CURRENT_ATTRIB_NV" }, + { 0x8626, "GL_CURRENT_VERTEX_ATTRIB_ARB" }, + { 0x8626, "GL_CURRENT_VERTEX_ATTRIB_ARB" }, + { 0x8626, "GL_CURRENT_VERTEX_ATTRIB" }, + { 0x8627, "GL_PROGRAM_LENGTH_ARB" }, + { 0x8627, "GL_PROGRAM_LENGTH_NV" }, + { 0x8628, "GL_PROGRAM_STRING_ARB" }, + { 0x8628, "GL_PROGRAM_STRING_NV" }, + { 0x8629, "GL_MODELVIEW_PROJECTION_NV" }, + { 0x862A, "GL_IDENTITY_NV" }, + { 0x862B, "GL_INVERSE_NV" }, + { 0x862C, "GL_TRANSPOSE_NV" }, + { 0x862D, "GL_INVERSE_TRANSPOSE_NV" }, + { 0x862E, "GL_MAX_PROGRAM_MATRIX_STACK_DEPTH_ARB" }, + { 0x862E, "GL_MAX_TRACK_MATRIX_STACK_DEPTH_NV" }, + { 0x862F, "GL_MAX_PROGRAM_MATRICES_ARB" }, + { 0x862F, "GL_MAX_TRACK_MATRICES_NV" }, + { 0x8630, "GL_MATRIX0_NV" }, + { 0x8631, "GL_MATRIX1_NV" }, + { 0x8632, "GL_MATRIX2_NV" }, + { 0x8633, "GL_MATRIX3_NV" }, + { 0x8634, "GL_MATRIX4_NV" }, + { 0x8635, "GL_MATRIX5_NV" }, + { 0x8636, "GL_MATRIX6_NV" }, + { 0x8637, "GL_MATRIX7_NV" }, + { 0x8640, "GL_CURRENT_MATRIX_STACK_DEPTH_ARB" }, + { 0x8640, "GL_CURRENT_MATRIX_STACK_DEPTH_NV" }, + { 0x8641, "GL_CURRENT_MATRIX_ARB" }, + { 0x8641, "GL_CURRENT_MATRIX_NV" }, + { 0x8642, "GL_PROGRAM_POINT_SIZE_EXT" }, + { 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE_ARB" }, + { 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE_ARB" }, + { 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE_NV" }, + { 0x8642, "GL_VERTEX_PROGRAM_POINT_SIZE" }, + { 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE_ARB" }, + { 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE_ARB" }, + { 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE_NV" }, + { 0x8643, "GL_VERTEX_PROGRAM_TWO_SIDE" }, + { 0x8644, "GL_PROGRAM_PARAMETER_NV" }, + { 0x8645, "GL_ATTRIB_ARRAY_POINTER_NV" }, + { 0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB" }, + { 0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER_ARB" }, + { 0x8645, "GL_VERTEX_ATTRIB_ARRAY_POINTER" }, + { 0x8646, "GL_PROGRAM_TARGET_NV" }, + { 0x8647, "GL_PROGRAM_RESIDENT_NV" }, + { 0x8648, "GL_TRACK_MATRIX_NV" }, + { 0x8649, "GL_TRACK_MATRIX_TRANSFORM_NV" }, + { 0x864A, "GL_VERTEX_PROGRAM_BINDING_NV" }, + { 0x864B, "GL_PROGRAM_ERROR_POSITION_ARB" }, + { 0x864B, "GL_PROGRAM_ERROR_POSITION_NV" }, + { 0x8650, "GL_VERTEX_ATTRIB_ARRAY0_NV" }, + { 0x8651, "GL_VERTEX_ATTRIB_ARRAY1_NV" }, + { 0x8652, "GL_VERTEX_ATTRIB_ARRAY2_NV" }, + { 0x8653, "GL_VERTEX_ATTRIB_ARRAY3_NV" }, + { 0x8654, "GL_VERTEX_ATTRIB_ARRAY4_NV" }, + { 0x8655, "GL_VERTEX_ATTRIB_ARRAY5_NV" }, + { 0x8656, "GL_VERTEX_ATTRIB_ARRAY6_NV" }, + { 0x8657, "GL_VERTEX_ATTRIB_ARRAY7_NV" }, + { 0x8658, "GL_VERTEX_ATTRIB_ARRAY8_NV" }, + { 0x8659, "GL_VERTEX_ATTRIB_ARRAY9_NV" }, + { 0x865A, "GL_VERTEX_ATTRIB_ARRAY10_NV" }, + { 0x865B, "GL_VERTEX_ATTRIB_ARRAY11_NV" }, + { 0x865C, "GL_VERTEX_ATTRIB_ARRAY12_NV" }, + { 0x865D, "GL_VERTEX_ATTRIB_ARRAY13_NV" }, + { 0x865E, "GL_VERTEX_ATTRIB_ARRAY14_NV" }, + { 0x865F, "GL_VERTEX_ATTRIB_ARRAY15_NV" }, + { 0x8660, "GL_MAP1_VERTEX_ATTRIB0_4_NV" }, + { 0x8661, "GL_MAP1_VERTEX_ATTRIB1_4_NV" }, + { 0x8662, "GL_MAP1_VERTEX_ATTRIB2_4_NV" }, + { 0x8663, "GL_MAP1_VERTEX_ATTRIB3_4_NV" }, + { 0x8664, "GL_MAP1_VERTEX_ATTRIB4_4_NV" }, + { 0x8665, "GL_MAP1_VERTEX_ATTRIB5_4_NV" }, + { 0x8666, "GL_MAP1_VERTEX_ATTRIB6_4_NV" }, + { 0x8667, "GL_MAP1_VERTEX_ATTRIB7_4_NV" }, + { 0x8668, "GL_MAP1_VERTEX_ATTRIB8_4_NV" }, + { 0x8669, "GL_MAP1_VERTEX_ATTRIB9_4_NV" }, + { 0x866A, "GL_MAP1_VERTEX_ATTRIB10_4_NV" }, + { 0x866B, "GL_MAP1_VERTEX_ATTRIB11_4_NV" }, + { 0x866C, "GL_MAP1_VERTEX_ATTRIB12_4_NV" }, + { 0x866D, "GL_MAP1_VERTEX_ATTRIB13_4_NV" }, + { 0x866E, "GL_MAP1_VERTEX_ATTRIB14_4_NV" }, + { 0x866F, "GL_MAP1_VERTEX_ATTRIB15_4_NV" }, + { 0x8670, "GL_MAP2_VERTEX_ATTRIB0_4_NV" }, + { 0x8671, "GL_MAP2_VERTEX_ATTRIB1_4_NV" }, + { 0x8672, "GL_MAP2_VERTEX_ATTRIB2_4_NV" }, + { 0x8673, "GL_MAP2_VERTEX_ATTRIB3_4_NV" }, + { 0x8674, "GL_MAP2_VERTEX_ATTRIB4_4_NV" }, + { 0x8675, "GL_MAP2_VERTEX_ATTRIB5_4_NV" }, + { 0x8676, "GL_MAP2_VERTEX_ATTRIB6_4_NV" }, + { 0x8677, "GL_MAP2_VERTEX_ATTRIB7_4_NV" }, + { 0x8677, "GL_PROGRAM_BINDING_ARB" }, + { 0x8677, "GL_PROGRAM_NAME_ARB" }, + { 0x8678, "GL_MAP2_VERTEX_ATTRIB8_4_NV" }, + { 0x8679, "GL_MAP2_VERTEX_ATTRIB9_4_NV" }, + { 0x867A, "GL_MAP2_VERTEX_ATTRIB10_4_NV" }, + { 0x867B, "GL_MAP2_VERTEX_ATTRIB11_4_NV" }, + { 0x867C, "GL_MAP2_VERTEX_ATTRIB12_4_NV" }, + { 0x867D, "GL_MAP2_VERTEX_ATTRIB13_4_NV" }, + { 0x867E, "GL_MAP2_VERTEX_ATTRIB14_4_NV" }, + { 0x867F, "GL_MAP2_VERTEX_ATTRIB15_4_NV" }, + { 0x86A0, "GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB" }, + { 0x86A0, "GL_TEXTURE_COMPRESSED_IMAGE_SIZE" }, + { 0x86A1, "GL_TEXTURE_COMPRESSED_ARB" }, + { 0x86A1, "GL_TEXTURE_COMPRESSED" }, + { 0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS_ARB" }, + { 0x86A2, "GL_NUM_COMPRESSED_TEXTURE_FORMATS" }, + { 0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS_ARB" }, + { 0x86A3, "GL_COMPRESSED_TEXTURE_FORMATS" }, + { 0x86A4, "GL_MAX_VERTEX_UNITS_ARB" }, + { 0x86A5, "GL_ACTIVE_VERTEX_UNITS_ARB" }, + { 0x86A6, "GL_WEIGHT_SUM_UNITY_ARB" }, + { 0x86A7, "GL_VERTEX_BLEND_ARB" }, + { 0x86A8, "GL_CURRENT_WEIGHT_ARB" }, + { 0x86A9, "GL_WEIGHT_ARRAY_TYPE_ARB" }, + { 0x86AA, "GL_WEIGHT_ARRAY_STRIDE_ARB" }, + { 0x86AB, "GL_WEIGHT_ARRAY_SIZE_ARB" }, + { 0x86AC, "GL_WEIGHT_ARRAY_POINTER_ARB" }, + { 0x86AD, "GL_WEIGHT_ARRAY_ARB" }, + { 0x86AE, "GL_DOT3_RGB_ARB" }, + { 0x86AE, "GL_DOT3_RGB" }, + { 0x86AF, "GL_DOT3_RGBA_ARB" }, + { 0x86AF, "GL_DOT3_RGBA" }, + { 0x8722, "GL_MODELVIEW2_ARB" }, + { 0x8723, "GL_MODELVIEW3_ARB" }, + { 0x8724, "GL_MODELVIEW4_ARB" }, + { 0x8725, "GL_MODELVIEW5_ARB" }, + { 0x8726, "GL_MODELVIEW6_ARB" }, + { 0x8727, "GL_MODELVIEW7_ARB" }, + { 0x8728, "GL_MODELVIEW8_ARB" }, + { 0x8729, "GL_MODELVIEW9_ARB" }, + { 0x872A, "GL_MODELVIEW10_ARB" }, + { 0x872B, "GL_MODELVIEW11_ARB" }, + { 0x872C, "GL_MODELVIEW12_ARB" }, + { 0x872D, "GL_MODELVIEW13_ARB" }, + { 0x872E, "GL_MODELVIEW14_ARB" }, + { 0x872F, "GL_MODELVIEW15_ARB" }, + { 0x8730, "GL_MODELVIEW16_ARB" }, + { 0x8731, "GL_MODELVIEW17_ARB" }, + { 0x8732, "GL_MODELVIEW18_ARB" }, + { 0x8733, "GL_MODELVIEW19_ARB" }, + { 0x8734, "GL_MODELVIEW20_ARB" }, + { 0x8735, "GL_MODELVIEW21_ARB" }, + { 0x8736, "GL_MODELVIEW22_ARB" }, + { 0x8737, "GL_MODELVIEW23_ARB" }, + { 0x8738, "GL_MODELVIEW24_ARB" }, + { 0x8739, "GL_MODELVIEW25_ARB" }, + { 0x873A, "GL_MODELVIEW26_ARB" }, + { 0x873B, "GL_MODELVIEW27_ARB" }, + { 0x873C, "GL_MODELVIEW28_ARB" }, + { 0x873D, "GL_MODELVIEW29_ARB" }, + { 0x873E, "GL_MODELVIEW30_ARB" }, + { 0x873F, "GL_MODELVIEW31_ARB" }, + { 0x8742, "GL_MIRROR_CLAMP_EXT" }, + { 0x8743, "GL_MIRROR_CLAMP_TO_EDGE_EXT" }, + { 0x8764, "GL_BUFFER_SIZE_ARB" }, + { 0x8764, "GL_BUFFER_SIZE" }, + { 0x8765, "GL_BUFFER_USAGE_ARB" }, + { 0x8765, "GL_BUFFER_USAGE" }, + { 0x8780, "GL_VERTEX_SHADER_EXT" }, + { 0x8781, "GL_VERTEX_SHADER_BINDING_EXT" }, + { 0x8782, "GL_OP_INDEX_EXT" }, + { 0x8783, "GL_OP_NEGATE_EXT" }, + { 0x8784, "GL_OP_DOT3_EXT" }, + { 0x8785, "GL_OP_DOT4_EXT" }, + { 0x8786, "GL_OP_MUL_EXT" }, + { 0x8787, "GL_OP_ADD_EXT" }, + { 0x8788, "GL_OP_MADD_EXT" }, + { 0x8789, "GL_OP_FRAC_EXT" }, + { 0x878A, "GL_OP_MAX_EXT" }, + { 0x878B, "GL_OP_MIN_EXT" }, + { 0x878C, "GL_OP_SET_GE_EXT" }, + { 0x878D, "GL_OP_SET_LT_EXT" }, + { 0x878E, "GL_OP_CLAMP_EXT" }, + { 0x878F, "GL_OP_FLOOR_EXT" }, + { 0x8790, "GL_OP_ROUND_EXT" }, + { 0x8791, "GL_OP_EXP_BASE_2_EXT" }, + { 0x8792, "GL_OP_LOG_BASE_2_EXT" }, + { 0x8793, "GL_OP_POWER_EXT" }, + { 0x8794, "GL_OP_RECIP_EXT" }, + { 0x8795, "GL_OP_RECIP_SQRT_EXT" }, + { 0x8796, "GL_OP_SUB_EXT" }, + { 0x8797, "GL_OP_CROSS_PRODUCT_EXT" }, + { 0x8798, "GL_OP_MULTIPLY_MATRIX_EXT" }, + { 0x8799, "GL_OP_MOV_EXT" }, + { 0x879A, "GL_OUTPUT_VERTEX_EXT" }, + { 0x879B, "GL_OUTPUT_COLOR0_EXT" }, + { 0x879C, "GL_OUTPUT_COLOR1_EXT" }, + { 0x879D, "GL_OUTPUT_TEXTURE_COORD0_EXT" }, + { 0x879E, "GL_OUTPUT_TEXTURE_COORD1_EXT" }, + { 0x879F, "GL_OUTPUT_TEXTURE_COORD2_EXT" }, + { 0x87A0, "GL_OUTPUT_TEXTURE_COORD3_EXT" }, + { 0x87A1, "GL_OUTPUT_TEXTURE_COORD4_EXT" }, + { 0x87A2, "GL_OUTPUT_TEXTURE_COORD5_EXT" }, + { 0x87A3, "GL_OUTPUT_TEXTURE_COORD6_EXT" }, + { 0x87A4, "GL_OUTPUT_TEXTURE_COORD7_EXT" }, + { 0x87A5, "GL_OUTPUT_TEXTURE_COORD8_EXT" }, + { 0x87A6, "GL_OUTPUT_TEXTURE_COORD9_EXT" }, + { 0x87A7, "GL_OUTPUT_TEXTURE_COORD10_EXT" }, + { 0x87A8, "GL_OUTPUT_TEXTURE_COORD11_EXT" }, + { 0x87A9, "GL_OUTPUT_TEXTURE_COORD12_EXT" }, + { 0x87AA, "GL_OUTPUT_TEXTURE_COORD13_EXT" }, + { 0x87AB, "GL_OUTPUT_TEXTURE_COORD14_EXT" }, + { 0x87AC, "GL_OUTPUT_TEXTURE_COORD15_EXT" }, + { 0x87AD, "GL_OUTPUT_TEXTURE_COORD16_EXT" }, + { 0x87AE, "GL_OUTPUT_TEXTURE_COORD17_EXT" }, + { 0x87AF, "GL_OUTPUT_TEXTURE_COORD18_EXT" }, + { 0x87B0, "GL_OUTPUT_TEXTURE_COORD19_EXT" }, + { 0x87B1, "GL_OUTPUT_TEXTURE_COORD20_EXT" }, + { 0x87B2, "GL_OUTPUT_TEXTURE_COORD21_EXT" }, + { 0x87B3, "GL_OUTPUT_TEXTURE_COORD22_EXT" }, + { 0x87B4, "GL_OUTPUT_TEXTURE_COORD23_EXT" }, + { 0x87B5, "GL_OUTPUT_TEXTURE_COORD24_EXT" }, + { 0x87B6, "GL_OUTPUT_TEXTURE_COORD25_EXT" }, + { 0x87B7, "GL_OUTPUT_TEXTURE_COORD26_EXT" }, + { 0x87B8, "GL_OUTPUT_TEXTURE_COORD27_EXT" }, + { 0x87B9, "GL_OUTPUT_TEXTURE_COORD28_EXT" }, + { 0x87BA, "GL_OUTPUT_TEXTURE_COORD29_EXT" }, + { 0x87BB, "GL_OUTPUT_TEXTURE_COORD30_EXT" }, + { 0x87BC, "GL_OUTPUT_TEXTURE_COORD31_EXT" }, + { 0x87BD, "GL_OUTPUT_FOG_EXT" }, + { 0x87BE, "GL_SCALAR_EXT" }, + { 0x87BF, "GL_VECTOR_EXT" }, + { 0x87C0, "GL_MATRIX_EXT" }, + { 0x87C1, "GL_VARIANT_EXT" }, + { 0x87C2, "GL_INVARIANT_EXT" }, + { 0x87C3, "GL_LOCAL_CONSTANT_EXT" }, + { 0x87C4, "GL_LOCAL_EXT" }, + { 0x87C5, "GL_MAX_VERTEX_SHADER_INSTRUCTIONS_EXT" }, + { 0x87C6, "GL_MAX_VERTEX_SHADER_VARIANTS_EXT" }, + { 0x87C7, "GL_MAX_VERTEX_SHADER_INVARIANTS_EXT" }, + { 0x87C8, "GL_MAX_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, + { 0x87C9, "GL_MAX_VERTEX_SHADER_LOCALS_EXT" }, + { 0x87CA, "GL_MAX_OPTIMIZED_VERTEX_SHADER_INSTRUCTIONS_EXT" }, + { 0x87CB, "GL_MAX_OPTIMIZED_VERTEX_SHADER_VARIANTS_EXT" }, + { 0x87CC, "GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, + { 0x87CD, "GL_MAX_OPTIMIZED_VERTEX_SHADER_INVARIANTS_EXT" }, + { 0x87CE, "GL_MAX_OPTIMIZED_VERTEX_SHADER_LOCALS_EXT" }, + { 0x87CF, "GL_VERTEX_SHADER_INSTRUCTIONS_EXT" }, + { 0x87D0, "GL_VERTEX_SHADER_VARIANTS_EXT" }, + { 0x87D1, "GL_VERTEX_SHADER_INVARIANTS_EXT" }, + { 0x87D2, "GL_VERTEX_SHADER_LOCAL_CONSTANTS_EXT" }, + { 0x87D3, "GL_VERTEX_SHADER_LOCALS_EXT" }, + { 0x87D4, "GL_VERTEX_SHADER_OPTIMIZED_EXT" }, + { 0x87D5, "GL_X_EXT" }, + { 0x87D6, "GL_Y_EXT" }, + { 0x87D7, "GL_Z_EXT" }, + { 0x87D8, "GL_W_EXT" }, + { 0x87D9, "GL_NEGATIVE_X_EXT" }, + { 0x87DA, "GL_NEGATIVE_Y_EXT" }, + { 0x87DB, "GL_NEGATIVE_Z_EXT" }, + { 0x87DC, "GL_NEGATIVE_W_EXT" }, + { 0x87DF, "GL_NEGATIVE_ONE_EXT" }, + { 0x87E0, "GL_NORMALIZED_RANGE_EXT" }, + { 0x87E1, "GL_FULL_RANGE_EXT" }, + { 0x87E2, "GL_CURRENT_VERTEX_EXT" }, + { 0x87E3, "GL_MVP_MATRIX_EXT" }, + { 0x87E4, "GL_VARIANT_VALUE_EXT" }, + { 0x87E5, "GL_VARIANT_DATATYPE_EXT" }, + { 0x87E6, "GL_VARIANT_ARRAY_STRIDE_EXT" }, + { 0x87E7, "GL_VARIANT_ARRAY_TYPE_EXT" }, + { 0x87E8, "GL_VARIANT_ARRAY_EXT" }, + { 0x87E9, "GL_VARIANT_ARRAY_POINTER_EXT" }, + { 0x87EA, "GL_INVARIANT_VALUE_EXT" }, + { 0x87EB, "GL_INVARIANT_DATATYPE_EXT" }, + { 0x87EC, "GL_LOCAL_CONSTANT_VALUE_EXT" }, + { 0x87Ed, "GL_LOCAL_CONSTANT_DATATYPE_EXT" }, + { 0x8800, "GL_STENCIL_BACK_FUNC_ATI" }, + { 0x8800, "GL_STENCIL_BACK_FUNC" }, + { 0x8801, "GL_STENCIL_BACK_FAIL_ATI" }, + { 0x8801, "GL_STENCIL_BACK_FAIL" }, + { 0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL_ATI" }, + { 0x8802, "GL_STENCIL_BACK_PASS_DEPTH_FAIL" }, + { 0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS_ATI" }, + { 0x8803, "GL_STENCIL_BACK_PASS_DEPTH_PASS" }, + { 0x8804, "GL_FRAGMENT_PROGRAM_ARB" }, + { 0x8805, "GL_PROGRAM_ALU_INSTRUCTIONS_ARB" }, + { 0x8806, "GL_PROGRAM_TEX_INSTRUCTIONS_ARB" }, + { 0x8807, "GL_PROGRAM_TEX_INDIRECTIONS_ARB" }, + { 0x8808, "GL_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" }, + { 0x8809, "GL_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" }, + { 0x880A, "GL_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" }, + { 0x880B, "GL_MAX_PROGRAM_ALU_INSTRUCTIONS_ARB" }, + { 0x880C, "GL_MAX_PROGRAM_TEX_INSTRUCTIONS_ARB" }, + { 0x880D, "GL_MAX_PROGRAM_TEX_INDIRECTIONS_ARB" }, + { 0x880E, "GL_MAX_PROGRAM_NATIVE_ALU_INSTRUCTIONS_ARB" }, + { 0x880F, "GL_MAX_PROGRAM_NATIVE_TEX_INSTRUCTIONS_ARB" }, + { 0x8810, "GL_MAX_PROGRAM_NATIVE_TEX_INDIRECTIONS_ARB" }, + { 0x8814, "GL_RGBA_FLOAT32_APPLE" }, + { 0x8814, "GL_RGBA_FLOAT32_ATI" }, + { 0x8814, "GL_RGBA32F_ARB" }, + { 0x8815, "GL_RGB_FLOAT32_APPLE" }, + { 0x8815, "GL_RGB_FLOAT32_ATI" }, + { 0x8815, "GL_RGB32F_ARB" }, + { 0x8816, "GL_ALPHA_FLOAT32_APPLE" }, + { 0x8816, "GL_ALPHA_FLOAT32_ATI" }, + { 0x8816, "GL_ALPHA32F_ARB" }, + { 0x8817, "GL_INTENSITY_FLOAT32_APPLE" }, + { 0x8817, "GL_INTENSITY_FLOAT32_ATI" }, + { 0x8817, "GL_INTENSITY32F_ARB" }, + { 0x8818, "GL_LUMINANCE_FLOAT32_APPLE" }, + { 0x8818, "GL_LUMINANCE_FLOAT32_ATI" }, + { 0x8818, "GL_LUMINANCE32F_ARB" }, + { 0x8819, "GL_LUMINANCE_ALPHA_FLOAT32_APPLE" }, + { 0x8819, "GL_LUMINANCE_ALPHA_FLOAT32_ATI" }, + { 0x8819, "GL_LUMINANCE_ALPHA32F_ARB" }, + { 0x881A, "GL_RGBA_FLOAT16_APPLE" }, + { 0x881A, "GL_RGBA_FLOAT16_ATI" }, + { 0x881A, "GL_RGBA16F_ARB" }, + { 0x881B, "GL_RGB_FLOAT16_APPLE" }, + { 0x881B, "GL_RGB_FLOAT16_ATI" }, + { 0x881B, "GL_RGB16F_ARB" }, + { 0x881C, "GL_ALPHA_FLOAT16_APPLE" }, + { 0x881C, "GL_ALPHA_FLOAT16_ATI" }, + { 0x881C, "GL_ALPHA16F_ARB" }, + { 0x881D, "GL_INTENSITY_FLOAT16_APPLE" }, + { 0x881D, "GL_INTENSITY_FLOAT16_ATI" }, + { 0x881D, "GL_INTENSITY16F_ARB" }, + { 0x881E, "GL_LUMINANCE_FLOAT16_APPLE" }, + { 0x881E, "GL_LUMINANCE_FLOAT16_ATI" }, + { 0x881E, "GL_LUMINANCE16F_ARB" }, + { 0x881F, "GL_LUMINANCE_ALPHA_FLOAT16_APPLE" }, + { 0x881F, "GL_LUMINANCE_ALPHA_FLOAT16_ATI" }, + { 0x881F, "GL_LUMINANCE_ALPHA16F_ARB" }, + { 0x8820, "GL_RGBA_FLOAT_MODE_ARB" }, + { 0x8824, "GL_MAX_DRAW_BUFFERS_ARB" }, + { 0x8824, "GL_MAX_DRAW_BUFFERS" }, + { 0x8825, "GL_DRAW_BUFFER0_ARB" }, + { 0x8825, "GL_DRAW_BUFFER0" }, + { 0x8826, "GL_DRAW_BUFFER1_ARB" }, + { 0x8826, "GL_DRAW_BUFFER1" }, + { 0x8827, "GL_DRAW_BUFFER2_ARB" }, + { 0x8827, "GL_DRAW_BUFFER2" }, + { 0x8828, "GL_DRAW_BUFFER3_ARB" }, + { 0x8828, "GL_DRAW_BUFFER3" }, + { 0x8829, "GL_DRAW_BUFFER4_ARB" }, + { 0x8829, "GL_DRAW_BUFFER4" }, + { 0x882A, "GL_DRAW_BUFFER5_ARB" }, + { 0x882A, "GL_DRAW_BUFFER5" }, + { 0x882B, "GL_DRAW_BUFFER6_ARB" }, + { 0x882B, "GL_DRAW_BUFFER6" }, + { 0x882C, "GL_DRAW_BUFFER7_ARB" }, + { 0x882C, "GL_DRAW_BUFFER7" }, + { 0x882D, "GL_DRAW_BUFFER8_ARB" }, + { 0x882D, "GL_DRAW_BUFFER8" }, + { 0x882E, "GL_DRAW_BUFFER9_ARB" }, + { 0x882E, "GL_DRAW_BUFFER9" }, + { 0x882F, "GL_DRAW_BUFFER10_ARB" }, + { 0x882F, "GL_DRAW_BUFFER10" }, + { 0x8830, "GL_DRAW_BUFFER11_ARB" }, + { 0x8830, "GL_DRAW_BUFFER11" }, + { 0x8831, "GL_DRAW_BUFFER12_ARB" }, + { 0x8831, "GL_DRAW_BUFFER12" }, + { 0x8832, "GL_DRAW_BUFFER13_ARB" }, + { 0x8832, "GL_DRAW_BUFFER13" }, + { 0x8833, "GL_DRAW_BUFFER14_ARB" }, + { 0x8833, "GL_DRAW_BUFFER14" }, + { 0x8834, "GL_DRAW_BUFFER15_ARB" }, + { 0x8834, "GL_DRAW_BUFFER15" }, + { 0x883D, "GL_ALPHA_BLEND_EQUATION_ATI" }, + { 0x883D, "GL_BLEND_EQUATION_ALPHA_EXT" }, + { 0x883D, "GL_BLEND_EQUATION_ALPHA" }, + { 0x884A, "GL_TEXTURE_DEPTH_SIZE_ARB" }, + { 0x884A, "GL_TEXTURE_DEPTH_SIZE" }, + { 0x884B, "GL_DEPTH_TEXTURE_MODE_ARB" }, + { 0x884B, "GL_DEPTH_TEXTURE_MODE" }, + { 0x884C, "GL_TEXTURE_COMPARE_MODE_ARB" }, + { 0x884C, "GL_TEXTURE_COMPARE_MODE" }, + { 0x884D, "GL_TEXTURE_COMPARE_FUNC_ARB" }, + { 0x884D, "GL_TEXTURE_COMPARE_FUNC" }, + { 0x884E, "GL_COMPARE_R_TO_TEXTURE_ARB" }, + { 0x884E, "GL_COMPARE_R_TO_TEXTURE" }, + { 0x884E, "GL_COMPARE_REF_DEPTH_TO_TEXTURE_EXT" }, + { 0x8861, "GL_POINT_SPRITE_ARB" }, + { 0x8861, "GL_POINT_SPRITE" }, + { 0x8862, "GL_COORD_REPLACE_ARB" }, + { 0x8862, "GL_COORD_REPLACE" }, + { 0x8864, "GL_QUERY_COUNTER_BITS_ARB" }, + { 0x8864, "GL_QUERY_COUNTER_BITS" }, + { 0x8865, "GL_CURRENT_QUERY_ARB" }, + { 0x8865, "GL_CURRENT_QUERY" }, + { 0x8866, "GL_QUERY_RESULT_ARB" }, + { 0x8866, "GL_QUERY_RESULT" }, + { 0x8867, "GL_QUERY_RESULT_AVAILABLE_ARB" }, + { 0x8867, "GL_QUERY_RESULT_AVAILABLE" }, + { 0x8869, "GL_MAX_VERTEX_ATTRIBS_ARB" }, + { 0x8869, "GL_MAX_VERTEX_ATTRIBS_ARB" }, + { 0x8869, "GL_MAX_VERTEX_ATTRIBS" }, + { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB" }, + { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB" }, + { 0x886A, "GL_VERTEX_ATTRIB_ARRAY_NORMALIZED" }, + { 0x8871, "GL_MAX_TEXTURE_COORDS_ARB" }, + { 0x8871, "GL_MAX_TEXTURE_COORDS_ARB" }, + { 0x8871, "GL_MAX_TEXTURE_COORDS_ARB" }, + { 0x8871, "GL_MAX_TEXTURE_COORDS" }, + { 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" }, + { 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" }, + { 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS_ARB" }, + { 0x8872, "GL_MAX_TEXTURE_IMAGE_UNITS" }, + { 0x8874, "GL_PROGRAM_ERROR_STRING_ARB" }, + { 0x8875, "GL_PROGRAM_FORMAT_ASCII_ARB" }, + { 0x8876, "GL_PROGRAM_FORMAT_ARB" }, + { 0x8890, "GL_DEPTH_BOUNDS_TEST_EXT" }, + { 0x8891, "GL_DEPTH_BOUNDS_EXT" }, + { 0x8892, "GL_ARRAY_BUFFER_ARB" }, + { 0x8892, "GL_ARRAY_BUFFER" }, + { 0x8893, "GL_ELEMENT_ARRAY_BUFFER_ARB" }, + { 0x8893, "GL_ELEMENT_ARRAY_BUFFER" }, + { 0x8894, "GL_ARRAY_BUFFER_BINDING_ARB" }, + { 0x8894, "GL_ARRAY_BUFFER_BINDING" }, + { 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB" }, + { 0x8895, "GL_ELEMENT_ARRAY_BUFFER_BINDING" }, + { 0x8896, "GL_VERTEX_ARRAY_BUFFER_BINDING_ARB" }, + { 0x8896, "GL_VERTEX_ARRAY_BUFFER_BINDING" }, + { 0x8897, "GL_NORMAL_ARRAY_BUFFER_BINDING_ARB" }, + { 0x8897, "GL_NORMAL_ARRAY_BUFFER_BINDING" }, + { 0x8898, "GL_COLOR_ARRAY_BUFFER_BINDING_ARB" }, + { 0x8898, "GL_COLOR_ARRAY_BUFFER_BINDING" }, + { 0x8899, "GL_INDEX_ARRAY_BUFFER_BINDING_ARB" }, + { 0x8899, "GL_INDEX_ARRAY_BUFFER_BINDING" }, + { 0x889A, "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB" }, + { 0x889A, "GL_TEXTURE_COORD_ARRAY_BUFFER_BINDING" }, + { 0x889B, "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING_ARB" }, + { 0x889B, "GL_EDGE_FLAG_ARRAY_BUFFER_BINDING" }, + { 0x889C, "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING_ARB" }, + { 0x889C, "GL_SECONDARY_COLOR_ARRAY_BUFFER_BINDING" }, + { 0x889D, "GL_FOG_COORD_ARRAY_BUFFER_BINDING_ARB" }, + { 0x889D, "GL_FOG_COORD_ARRAY_BUFFER_BINDING" }, + { 0x889D, "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING_ARB" }, + { 0x889D, "GL_FOG_COORDINATE_ARRAY_BUFFER_BINDING" }, + { 0x889E, "GL_WEIGHT_ARRAY_BUFFER_BINDING_ARB" }, + { 0x889E, "GL_WEIGHT_ARRAY_BUFFER_BINDING" }, + { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB" }, + { 0x889F, "GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING" }, + { 0x88A0, "GL_PROGRAM_INSTRUCTIONS_ARB" }, + { 0x88A1, "GL_MAX_PROGRAM_INSTRUCTIONS_ARB" }, + { 0x88A2, "GL_PROGRAM_NATIVE_INSTRUCTIONS_ARB" }, + { 0x88A3, "GL_MAX_PROGRAM_NATIVE_INSTRUCTIONS_ARB" }, + { 0x88A4, "GL_PROGRAM_TEMPORARIES_ARB" }, + { 0x88A5, "GL_MAX_PROGRAM_TEMPORARIES_ARB" }, + { 0x88A6, "GL_PROGRAM_NATIVE_TEMPORARIES_ARB" }, + { 0x88A7, "GL_MAX_PROGRAM_NATIVE_TEMPORARIES_ARB" }, + { 0x88A8, "GL_PROGRAM_PARAMETERS_ARB" }, + { 0x88A9, "GL_MAX_PROGRAM_PARAMETERS_ARB" }, + { 0x88AA, "GL_PROGRAM_NATIVE_PARAMETERS_ARB" }, + { 0x88AB, "GL_MAX_PROGRAM_NATIVE_PARAMETERS_ARB" }, + { 0x88AC, "GL_PROGRAM_ATTRIBS_ARB" }, + { 0x88AD, "GL_MAX_PROGRAM_ATTRIBS_ARB" }, + { 0x88AE, "GL_PROGRAM_NATIVE_ATTRIBS_ARB" }, + { 0x88AF, "GL_MAX_PROGRAM_NATIVE_ATTRIBS_ARB" }, + { 0x88B0, "GL_PROGRAM_ADDRESS_REGISTERS_ARB" }, + { 0x88B1, "GL_MAX_PROGRAM_ADDRESS_REGISTERS_ARB" }, + { 0x88B2, "GL_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" }, + { 0x88B3, "GL_MAX_PROGRAM_NATIVE_ADDRESS_REGISTERS_ARB" }, + { 0x88B4, "GL_MAX_PROGRAM_LOCAL_PARAMETERS_ARB" }, + { 0x88B5, "GL_MAX_PROGRAM_ENV_PARAMETERS_ARB" }, + { 0x88B6, "GL_PROGRAM_UNDER_NATIVE_LIMITS_ARB" }, + { 0x88B7, "GL_TRANSPOSE_CURRENT_MATRIX_ARB" }, + { 0x88B8, "GL_READ_ONLY_ARB" }, + { 0x88B8, "GL_READ_ONLY" }, + { 0x88B9, "GL_WRITE_ONLY_ARB" }, + { 0x88B9, "GL_WRITE_ONLY" }, + { 0x88BA, "GL_READ_WRITE_ARB" }, + { 0x88BA, "GL_READ_WRITE" }, + { 0x88BB, "GL_BUFFER_ACCESS_ARB" }, + { 0x88BB, "GL_BUFFER_ACCESS" }, + { 0x88BC, "GL_BUFFER_MAPPED_ARB" }, + { 0x88BC, "GL_BUFFER_MAPPED" }, + { 0x88BD, "GL_BUFFER_MAP_POINTER_ARB" }, + { 0x88BD, "GL_BUFFER_MAP_POINTER" }, + { 0x88C0, "GL_MATRIX0_ARB" }, + { 0x88C1, "GL_MATRIX1_ARB" }, + { 0x88C2, "GL_MATRIX2_ARB" }, + { 0x88C3, "GL_MATRIX3_ARB" }, + { 0x88C4, "GL_MATRIX4_ARB" }, + { 0x88C5, "GL_MATRIX5_ARB" }, + { 0x88C6, "GL_MATRIX6_ARB" }, + { 0x88C7, "GL_MATRIX7_ARB" }, + { 0x88C8, "GL_MATRIX8_ARB" }, + { 0x88C9, "GL_MATRIX9_ARB" }, + { 0x88CA, "GL_MATRIX10_ARB" }, + { 0x88CB, "GL_MATRIX11_ARB" }, + { 0x88CC, "GL_MATRIX12_ARB" }, + { 0x88CD, "GL_MATRIX13_ARB" }, + { 0x88CE, "GL_MATRIX14_ARB" }, + { 0x88CF, "GL_MATRIX15_ARB" }, + { 0x88D0, "GL_MATRIX16_ARB" }, + { 0x88D1, "GL_MATRIX17_ARB" }, + { 0x88D2, "GL_MATRIX18_ARB" }, + { 0x88D3, "GL_MATRIX19_ARB" }, + { 0x88D4, "GL_MATRIX20_ARB" }, + { 0x88D5, "GL_MATRIX21_ARB" }, + { 0x88D6, "GL_MATRIX22_ARB" }, + { 0x88D7, "GL_MATRIX23_ARB" }, + { 0x88D8, "GL_MATRIX24_ARB" }, + { 0x88D9, "GL_MATRIX25_ARB" }, + { 0x88DA, "GL_MATRIX26_ARB" }, + { 0x88DB, "GL_MATRIX27_ARB" }, + { 0x88DC, "GL_MATRIX28_ARB" }, + { 0x88DD, "GL_MATRIX29_ARB" }, + { 0x88DE, "GL_MATRIX30_ARB" }, + { 0x88DF, "GL_MATRIX31_ARB" }, + { 0x88E0, "GL_STREAM_DRAW_ARB" }, + { 0x88E0, "GL_STREAM_DRAW" }, + { 0x88E1, "GL_STREAM_READ_ARB" }, + { 0x88E1, "GL_STREAM_READ" }, + { 0x88E2, "GL_STREAM_COPY_ARB" }, + { 0x88E2, "GL_STREAM_COPY" }, + { 0x88E4, "GL_STATIC_DRAW_ARB" }, + { 0x88E4, "GL_STATIC_DRAW" }, + { 0x88E5, "GL_STATIC_READ_ARB" }, + { 0x88E5, "GL_STATIC_READ" }, + { 0x88E6, "GL_STATIC_COPY_ARB" }, + { 0x88E6, "GL_STATIC_COPY" }, + { 0x88E8, "GL_DYNAMIC_DRAW_ARB" }, + { 0x88E8, "GL_DYNAMIC_DRAW" }, + { 0x88E9, "GL_DYNAMIC_READ_ARB" }, + { 0x88E9, "GL_DYNAMIC_READ" }, + { 0x88EA, "GL_DYNAMIC_COPY_ARB" }, + { 0x88EA, "GL_DYNAMIC_COPY" }, + { 0x88EB, "GL_PIXEL_PACK_BUFFER_ARB" }, + { 0x88EB, "GL_PIXEL_PACK_BUFFER" }, + { 0x88EC, "GL_PIXEL_UNPACK_BUFFER_ARB" }, + { 0x88EC, "GL_PIXEL_UNPACK_BUFFER" }, + { 0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING_ARB" }, + { 0x88ED, "GL_PIXEL_PACK_BUFFER_BINDING" }, + { 0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING_ARB" }, + { 0x88EF, "GL_PIXEL_UNPACK_BUFFER_BINDING" }, + { 0x88F0, "GL_DEPTH24_STENCIL8_EXT" }, + { 0x88F0, "GL_DEPTH24_STENCIL8" }, + { 0x88F1, "GL_TEXTURE_STENCIL_SIZE_EXT" }, + { 0x88F1, "GL_TEXTURE_STENCIL_SIZE" }, + { 0x88FD, "GL_VERTEX_ATTRIB_ARRAY_INTEGER_EXT" }, + { 0x88FE, "GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB" }, + { 0x88FF, "GL_MAX_ARRAY_TEXTURE_LAYERS_EXT" }, + { 0x8904, "GL_MIN_PROGRAM_TEXEL_OFFSET_EXT" }, + { 0x8905, "GL_MAX_PROGRAM_TEXEL_OFFSET_EXT" }, + { 0x8910, "GL_STENCIL_TEST_TWO_SIDE_EXT" }, + { 0x8911, "GL_ACTIVE_STENCIL_FACE_EXT" }, + { 0x8912, "GL_MIRROR_CLAMP_TO_BORDER_EXT" }, + { 0x8914, "GL_SAMPLES_PASSED_ARB" }, + { 0x8914, "GL_SAMPLES_PASSED" }, + { 0x891A, "GL_CLAMP_VERTEX_COLOR_ARB" }, + { 0x891B, "GL_CLAMP_FRAGMENT_COLOR_ARB" }, + { 0x891C, "GL_CLAMP_READ_COLOR_ARB" }, + { 0x891D, "GL_FIXED_ONLY_ARB" }, + { 0x8920, "GL_FRAGMENT_SHADER_EXT" }, + { 0x896D, "GL_SECONDARY_INTERPOLATOR_EXT" }, + { 0x896E, "GL_NUM_FRAGMENT_REGISTERS_EXT" }, + { 0x896F, "GL_NUM_FRAGMENT_CONSTANTS_EXT" }, + { 0x8A0C, "GL_ELEMENT_ARRAY_APPLE" }, + { 0x8A0D, "GL_ELEMENT_ARRAY_TYPE_APPLE" }, + { 0x8A0E, "GL_ELEMENT_ARRAY_POINTER_APPLE" }, + { 0x8A0F, "GL_COLOR_FLOAT_APPLE" }, + { 0x8A11, "GL_UNIFORM_BUFFER" }, + { 0x8A28, "GL_UNIFORM_BUFFER_BINDING" }, + { 0x8A29, "GL_UNIFORM_BUFFER_START" }, + { 0x8A2A, "GL_UNIFORM_BUFFER_SIZE" }, + { 0x8A2B, "GL_MAX_VERTEX_UNIFORM_BLOCKS" }, + { 0x8A2C, "GL_MAX_GEOMETRY_UNIFORM_BLOCKS" }, + { 0x8A2D, "GL_MAX_FRAGMENT_UNIFORM_BLOCKS" }, + { 0x8A2E, "GL_MAX_COMBINED_UNIFORM_BLOCKS" }, + { 0x8A2F, "GL_MAX_UNIFORM_BUFFER_BINDINGS" }, + { 0x8A30, "GL_MAX_UNIFORM_BLOCK_SIZE" }, + { 0x8A31, "GL_MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS" }, + { 0x8A32, "GL_MAX_COMBINED_GEOMETRY_UNIFORM_COMPONENTS" }, + { 0x8A33, "GL_MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS" }, + { 0x8A34, "GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT" }, + { 0x8A35, "GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH" }, + { 0x8A36, "GL_ACTIVE_UNIFORM_BLOCKS" }, + { 0x8A37, "GL_UNIFORM_TYPE" }, + { 0x8A38, "GL_UNIFORM_SIZE" }, + { 0x8A39, "GL_UNIFORM_NAME_LENGTH" }, + { 0x8A3A, "GL_UNIFORM_BLOCK_INDEX" }, + { 0x8A3B, "GL_UNIFORM_OFFSET" }, + { 0x8A3C, "GL_UNIFORM_ARRAY_STRIDE" }, + { 0x8A3D, "GL_UNIFORM_MATRIX_STRIDE" }, + { 0x8A3E, "GL_UNIFORM_IS_ROW_MAJOR" }, + { 0x8A3F, "GL_UNIFORM_BLOCK_BINDING" }, + { 0x8A40, "GL_UNIFORM_BLOCK_DATA_SIZE" }, + { 0x8A41, "GL_UNIFORM_BLOCK_NAME_LENGTH" }, + { 0x8A42, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORMS" }, + { 0x8A43, "GL_UNIFORM_BLOCK_ACTIVE_UNIFORM_INDICES" }, + { 0x8A44, "GL_UNIFORM_BLOCK_REFERENCED_BY_VERTEX_SHADER" }, + { 0x8A45, "GL_UNIFORM_BLOCK_REFERENCED_BY_GEOMETRY_SHADER" }, + { 0x8A46, "GL_UNIFORM_BLOCK_REFERENCED_BY_FRAGMENT_SHADER" }, + { 0x8B30, "GL_FRAGMENT_SHADER_ARB" }, + { 0x8B30, "GL_FRAGMENT_SHADER" }, + { 0x8B31, "GL_VERTEX_SHADER_ARB" }, + { 0x8B31, "GL_VERTEX_SHADER" }, + { 0x8B40, "GL_PROGRAM_OBJECT_ARB" }, + { 0x8B48, "GL_SHADER_OBJECT_ARB" }, + { 0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB" }, + { 0x8B49, "GL_MAX_FRAGMENT_UNIFORM_COMPONENTS" }, + { 0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS_ARB" }, + { 0x8B4A, "GL_MAX_VERTEX_UNIFORM_COMPONENTS" }, + { 0x8B4B, "GL_MAX_VARYING_COMPONENTS_EXT" }, + { 0x8B4B, "GL_MAX_VARYING_FLOATS_ARB" }, + { 0x8B4B, "GL_MAX_VARYING_FLOATS" }, + { 0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS_ARB" }, + { 0x8B4C, "GL_MAX_VERTEX_TEXTURE_IMAGE_UNITS" }, + { 0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS_ARB" }, + { 0x8B4D, "GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS" }, + { 0x8B4E, "GL_OBJECT_TYPE_ARB" }, + { 0x8B4F, "GL_OBJECT_SUBTYPE_ARB" }, + { 0x8B4F, "GL_SHADER_TYPE" }, + { 0x8B50, "GL_FLOAT_VEC2_ARB" }, + { 0x8B50, "GL_FLOAT_VEC2" }, + { 0x8B51, "GL_FLOAT_VEC3_ARB" }, + { 0x8B51, "GL_FLOAT_VEC3" }, + { 0x8B52, "GL_FLOAT_VEC4_ARB" }, + { 0x8B52, "GL_FLOAT_VEC4" }, + { 0x8B53, "GL_INT_VEC2_ARB" }, + { 0x8B53, "GL_INT_VEC2" }, + { 0x8B54, "GL_INT_VEC3_ARB" }, + { 0x8B54, "GL_INT_VEC3" }, + { 0x8B55, "GL_INT_VEC4_ARB" }, + { 0x8B55, "GL_INT_VEC4" }, + { 0x8B56, "GL_BOOL_ARB" }, + { 0x8B56, "GL_BOOL" }, + { 0x8B57, "GL_BOOL_VEC2_ARB" }, + { 0x8B57, "GL_BOOL_VEC2" }, + { 0x8B58, "GL_BOOL_VEC3_ARB" }, + { 0x8B58, "GL_BOOL_VEC3" }, + { 0x8B59, "GL_BOOL_VEC4_ARB" }, + { 0x8B59, "GL_BOOL_VEC4" }, + { 0x8B5A, "GL_FLOAT_MAT2_ARB" }, + { 0x8B5A, "GL_FLOAT_MAT2" }, + { 0x8B5B, "GL_FLOAT_MAT3_ARB" }, + { 0x8B5B, "GL_FLOAT_MAT3" }, + { 0x8B5C, "GL_FLOAT_MAT4_ARB" }, + { 0x8B5C, "GL_FLOAT_MAT4" }, + { 0x8B5D, "GL_SAMPLER_1D_ARB" }, + { 0x8B5D, "GL_SAMPLER_1D" }, + { 0x8B5E, "GL_SAMPLER_2D_ARB" }, + { 0x8B5E, "GL_SAMPLER_2D" }, + { 0x8B5F, "GL_SAMPLER_3D_ARB" }, + { 0x8B5F, "GL_SAMPLER_3D" }, + { 0x8B60, "GL_SAMPLER_CUBE_ARB" }, + { 0x8B60, "GL_SAMPLER_CUBE" }, + { 0x8B61, "GL_SAMPLER_1D_SHADOW_ARB" }, + { 0x8B61, "GL_SAMPLER_1D_SHADOW" }, + { 0x8B62, "GL_SAMPLER_2D_SHADOW_ARB" }, + { 0x8B62, "GL_SAMPLER_2D_SHADOW" }, + { 0x8B63, "GL_SAMPLER_2D_RECT_ARB" }, + { 0x8B64, "GL_SAMPLER_2D_RECT_SHADOW_ARB" }, + { 0x8B65, "GL_FLOAT_MAT2x3" }, + { 0x8B66, "GL_FLOAT_MAT2x4" }, + { 0x8B67, "GL_FLOAT_MAT3x2" }, + { 0x8B68, "GL_FLOAT_MAT3x4" }, + { 0x8B69, "GL_FLOAT_MAT4x2" }, + { 0x8B6A, "GL_FLOAT_MAT4x3" }, + { 0x8B80, "GL_DELETE_STATUS" }, + { 0x8B80, "GL_OBJECT_DELETE_STATUS_ARB" }, + { 0x8B81, "GL_COMPILE_STATUS" }, + { 0x8B81, "GL_OBJECT_COMPILE_STATUS_ARB" }, + { 0x8B82, "GL_LINK_STATUS" }, + { 0x8B82, "GL_OBJECT_LINK_STATUS_ARB" }, + { 0x8B83, "GL_OBJECT_VALIDATE_STATUS_ARB" }, + { 0x8B83, "GL_VALIDATE_STATUS" }, + { 0x8B84, "GL_INFO_LOG_LENGTH" }, + { 0x8B84, "GL_OBJECT_INFO_LOG_LENGTH_ARB" }, + { 0x8B85, "GL_ATTACHED_SHADERS" }, + { 0x8B85, "GL_OBJECT_ATTACHED_OBJECTS_ARB" }, + { 0x8B86, "GL_ACTIVE_UNIFORMS" }, + { 0x8B86, "GL_OBJECT_ACTIVE_UNIFORMS_ARB" }, + { 0x8B87, "GL_ACTIVE_UNIFORM_MAX_LENGTH" }, + { 0x8B87, "GL_OBJECT_ACTIVE_UNIFORM_MAX_LENGTH_ARB" }, + { 0x8B88, "GL_OBJECT_SHADER_SOURCE_LENGTH_ARB" }, + { 0x8B88, "GL_SHADER_SOURCE_LENGTH" }, + { 0x8B89, "GL_ACTIVE_ATTRIBUTES" }, + { 0x8B89, "GL_OBJECT_ACTIVE_ATTRIBUTES_ARB" }, + { 0x8B8A, "GL_ACTIVE_ATTRIBUTE_MAX_LENGTH" }, + { 0x8B8A, "GL_OBJECT_ACTIVE_ATTRIBUTE_MAX_LENGTH_ARB" }, + { 0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB" }, + { 0x8B8B, "GL_FRAGMENT_SHADER_DERIVATIVE_HINT" }, + { 0x8B8C, "GL_SHADING_LANGUAGE_VERSION_ARB" }, + { 0x8B8C, "GL_SHADING_LANGUAGE_VERSION" }, + { 0x8B8D, "GL_CURRENT_PROGRAM" }, + { 0x8C10, "GL_TEXTURE_RED_TYPE_ARB" }, + { 0x8C10, "GL_TEXTURE_RED_TYPE" }, + { 0x8C11, "GL_TEXTURE_GREEN_TYPE_ARB" }, + { 0x8C11, "GL_TEXTURE_GREEN_TYPE" }, + { 0x8C12, "GL_TEXTURE_BLUE_TYPE_ARB" }, + { 0x8C12, "GL_TEXTURE_BLUE_TYPE" }, + { 0x8C13, "GL_TEXTURE_ALPHA_TYPE_ARB" }, + { 0x8C13, "GL_TEXTURE_ALPHA_TYPE" }, + { 0x8C14, "GL_TEXTURE_LUMINANCE_TYPE_ARB" }, + { 0x8C15, "GL_TEXTURE_INTENSITY_TYPE_ARB" }, + { 0x8C16, "GL_TEXTURE_DEPTH_TYPE_ARB" }, + { 0x8C16, "GL_TEXTURE_DEPTH_TYPE" }, + { 0x8C17, "GL_UNSIGNED_NORMALIZED_ARB" }, + { 0x8C17, "GL_UNSIGNED_NORMALIZED" }, + { 0x8C18, "GL_TEXTURE_1D_ARRAY_EXT" }, + { 0x8C19, "GL_PROXY_TEXTURE_1D_ARRAY_EXT" }, + { 0x8C1A, "GL_TEXTURE_2D_ARRAY_EXT" }, + { 0x8C1B, "GL_PROXY_TEXTURE_2D_ARRAY_EXT" }, + { 0x8C1C, "GL_TEXTURE_BINDING_1D_ARRAY_EXT" }, + { 0x8C1D, "GL_TEXTURE_BINDING_2D_ARRAY_EXT" }, + { 0x8C29, "GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT" }, + { 0x8C3A, "GL_R11F_G11F_B10F_EXT" }, + { 0x8C3B, "GL_UNSIGNED_INT_10F_11F_11F_REV_EXT" }, + { 0x8C3C, "GL_RGBA_SIGNED_COMPONENTS_EXT" }, + { 0x8C3D, "GL_RGB9_E5_EXT" }, + { 0x8C3E, "GL_UNSIGNED_INT_5_9_9_9_REV_EXT" }, + { 0x8C3F, "GL_TEXTURE_SHARED_SIZE_EXT" }, + { 0x8C40, "GL_SRGB_EXT" }, + { 0x8C40, "GL_SRGB" }, + { 0x8C41, "GL_SRGB8_EXT" }, + { 0x8C41, "GL_SRGB8" }, + { 0x8C42, "GL_SRGB_ALPHA_EXT" }, + { 0x8C42, "GL_SRGB_ALPHA" }, + { 0x8C43, "GL_SRGB8_ALPHA8_EXT" }, + { 0x8C43, "GL_SRGB8_ALPHA8" }, + { 0x8C44, "GL_SLUMINANCE_ALPHA_EXT" }, + { 0x8C44, "GL_SLUMINANCE_ALPHA" }, + { 0x8C45, "GL_SLUMINANCE8_ALPHA8_EXT" }, + { 0x8C45, "GL_SLUMINANCE8_ALPHA8" }, + { 0x8C46, "GL_SLUMINANCE_EXT" }, + { 0x8C46, "GL_SLUMINANCE" }, + { 0x8C47, "GL_SLUMINANCE8_EXT" }, + { 0x8C47, "GL_SLUMINANCE8" }, + { 0x8C48, "GL_COMPRESSED_SRGB_EXT" }, + { 0x8C48, "GL_COMPRESSED_SRGB" }, + { 0x8C49, "GL_COMPRESSED_SRGB_ALPHA_EXT" }, + { 0x8C49, "GL_COMPRESSED_SRGB_ALPHA" }, + { 0x8C4A, "GL_COMPRESSED_SLUMINANCE_EXT" }, + { 0x8C4A, "GL_COMPRESSED_SLUMINANCE" }, + { 0x8C4B, "GL_COMPRESSED_SLUMINANCE_ALPHA_EXT" }, + { 0x8C4B, "GL_COMPRESSED_SLUMINANCE_ALPHA" }, + { 0x8C4C, "GL_COMPRESSED_SRGB_S3TC_DXT1_EXT" }, + { 0x8C4D, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT" }, + { 0x8C4E, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT" }, + { 0x8C4F, "GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT" }, + { 0x8C76, "GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH_EXT" }, + { 0x8C7F, "GL_TRANSFORM_FEEDBACK_BUFFER_MODE_EXT" }, + { 0x8C80, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS_EXT" }, + { 0x8C83, "GL_TRANSFORM_FEEDBACK_VARYINGS_EXT" }, + { 0x8C84, "GL_TRANSFORM_FEEDBACK_BUFFER_START_EXT" }, + { 0x8C85, "GL_TRANSFORM_FEEDBACK_BUFFER_SIZE_EXT" }, + { 0x8C87, "GL_PRIMITIVES_GENERATED_EXT" }, + { 0x8C88, "GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN_EXT" }, + { 0x8C89, "GL_RASTERIZER_DISCARD_EXT" }, + { 0x8C8A, "GL_MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS_EXT" }, + { 0x8C8B, "GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS_EXT" }, + { 0x8C8C, "GL_INTERLEAVED_ATTRIBS_EXT" }, + { 0x8C8D, "GL_SEPARATE_ATTRIBS_EXT" }, + { 0x8C8E, "GL_TRANSFORM_FEEDBACK_BUFFER_EXT" }, + { 0x8C8F, "GL_TRANSFORM_FEEDBACK_BUFFER_BINDING_EXT" }, + { 0x8CA0, "GL_POINT_SPRITE_COORD_ORIGIN" }, + { 0x8CA1, "GL_LOWER_LEFT" }, + { 0x8CA2, "GL_UPPER_LEFT" }, + { 0x8CA3, "GL_STENCIL_BACK_REF" }, + { 0x8CA4, "GL_STENCIL_BACK_VALUE_MASK" }, + { 0x8CA5, "GL_STENCIL_BACK_WRITEMASK" }, + { 0x8CA6, "GL_DRAW_FRAMEBUFFER_BINDING_EXT" }, + { 0x8CA6, "GL_FRAMEBUFFER_BINDING_EXT" }, + { 0x8CA6, "GL_FRAMEBUFFER_BINDING" }, + { 0x8CA7, "GL_RENDERBUFFER_BINDING_EXT" }, + { 0x8CA7, "GL_RENDERBUFFER_BINDING" }, + { 0x8CA8, "GL_READ_FRAMEBUFFER_EXT" }, + { 0x8CA8, "GL_READ_FRAMEBUFFER" }, + { 0x8CA9, "GL_DRAW_FRAMEBUFFER_EXT" }, + { 0x8CA9, "GL_DRAW_FRAMEBUFFER" }, + { 0x8CAA, "GL_READ_FRAMEBUFFER_BINDING_EXT" }, + { 0x8CAA, "GL_READ_FRAMEBUFFER_BINDING" }, + { 0x8CAB, "GL_RENDERBUFFER_SAMPLES_EXT" }, + { 0x8CAB, "GL_RENDERBUFFER_SAMPLES" }, + { 0x8CAC, "GL_DEPTH_COMPONENT32F" }, + { 0x8CAD, "GL_DEPTH32F_STENCIL8" }, + { 0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE_EXT" }, + { 0x8CD0, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE" }, + { 0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME_EXT" }, + { 0x8CD1, "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME" }, + { 0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL_EXT" }, + { 0x8CD2, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL" }, + { 0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE_EXT" }, + { 0x8CD3, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE" }, + { 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT" }, + { 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER_EXT" }, + { 0x8CD4, "GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER" }, + { 0x8CD5, "GL_FRAMEBUFFER_COMPLETE_EXT" }, + { 0x8CD5, "GL_FRAMEBUFFER_COMPLETE" }, + { 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT" }, + { 0x8CD6, "GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT" }, + { 0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT" }, + { 0x8CD7, "GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT" }, + { 0x8CD9, "GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT" }, + { 0x8CDA, "GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT" }, + { 0x8CDB, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT" }, + { 0x8CDB, "GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER" }, + { 0x8CDC, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT" }, + { 0x8CDC, "GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER" }, + { 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED_EXT" }, + { 0x8CDD, "GL_FRAMEBUFFER_UNSUPPORTED" }, + { 0x8CDF, "GL_MAX_COLOR_ATTACHMENTS_EXT" }, + { 0x8CDF, "GL_MAX_COLOR_ATTACHMENTS" }, + { 0x8CE0, "GL_COLOR_ATTACHMENT0_EXT" }, + { 0x8CE0, "GL_COLOR_ATTACHMENT0" }, + { 0x8CE1, "GL_COLOR_ATTACHMENT1_EXT" }, + { 0x8CE1, "GL_COLOR_ATTACHMENT1" }, + { 0x8CE2, "GL_COLOR_ATTACHMENT2_EXT" }, + { 0x8CE2, "GL_COLOR_ATTACHMENT2" }, + { 0x8CE3, "GL_COLOR_ATTACHMENT3_EXT" }, + { 0x8CE3, "GL_COLOR_ATTACHMENT3" }, + { 0x8CE4, "GL_COLOR_ATTACHMENT4_EXT" }, + { 0x8CE4, "GL_COLOR_ATTACHMENT4" }, + { 0x8CE5, "GL_COLOR_ATTACHMENT5_EXT" }, + { 0x8CE5, "GL_COLOR_ATTACHMENT5" }, + { 0x8CE6, "GL_COLOR_ATTACHMENT6_EXT" }, + { 0x8CE6, "GL_COLOR_ATTACHMENT6" }, + { 0x8CE7, "GL_COLOR_ATTACHMENT7_EXT" }, + { 0x8CE7, "GL_COLOR_ATTACHMENT7" }, + { 0x8CE8, "GL_COLOR_ATTACHMENT8_EXT" }, + { 0x8CE8, "GL_COLOR_ATTACHMENT8" }, + { 0x8CE9, "GL_COLOR_ATTACHMENT9_EXT" }, + { 0x8CE9, "GL_COLOR_ATTACHMENT9" }, + { 0x8CEA, "GL_COLOR_ATTACHMENT10_EXT" }, + { 0x8CEA, "GL_COLOR_ATTACHMENT10" }, + { 0x8CEB, "GL_COLOR_ATTACHMENT11_EXT" }, + { 0x8CEB, "GL_COLOR_ATTACHMENT11" }, + { 0x8CEC, "GL_COLOR_ATTACHMENT12_EXT" }, + { 0x8CEC, "GL_COLOR_ATTACHMENT12" }, + { 0x8CED, "GL_COLOR_ATTACHMENT13_EXT" }, + { 0x8CED, "GL_COLOR_ATTACHMENT13" }, + { 0x8CEE, "GL_COLOR_ATTACHMENT14_EXT" }, + { 0x8CEE, "GL_COLOR_ATTACHMENT14" }, + { 0x8CEF, "GL_COLOR_ATTACHMENT15_EXT" }, + { 0x8CEF, "GL_COLOR_ATTACHMENT15" }, + { 0x8D00, "GL_DEPTH_ATTACHMENT_EXT" }, + { 0x8D00, "GL_DEPTH_ATTACHMENT" }, + { 0x8D20, "GL_STENCIL_ATTACHMENT_EXT" }, + { 0x8D20, "GL_STENCIL_ATTACHMENT" }, + { 0x8D40, "GL_FRAMEBUFFER_EXT" }, + { 0x8D40, "GL_FRAMEBUFFER" }, + { 0x8D41, "GL_RENDERBUFFER_EXT" }, + { 0x8D41, "GL_RENDERBUFFER" }, + { 0x8D42, "GL_RENDERBUFFER_WIDTH_EXT" }, + { 0x8D42, "GL_RENDERBUFFER_WIDTH" }, + { 0x8D43, "GL_RENDERBUFFER_HEIGHT_EXT" }, + { 0x8D43, "GL_RENDERBUFFER_HEIGHT" }, + { 0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT_EXT" }, + { 0x8D44, "GL_RENDERBUFFER_INTERNAL_FORMAT" }, + { 0x8D46, "GL_STENCIL_INDEX1_EXT" }, + { 0x8D46, "GL_STENCIL_INDEX1" }, + { 0x8D47, "GL_STENCIL_INDEX4_EXT" }, + { 0x8D47, "GL_STENCIL_INDEX4" }, + { 0x8D48, "GL_STENCIL_INDEX8_EXT" }, + { 0x8D48, "GL_STENCIL_INDEX8" }, + { 0x8D49, "GL_STENCIL_INDEX16_EXT" }, + { 0x8D49, "GL_STENCIL_INDEX16" }, + { 0x8D50, "GL_RENDERBUFFER_RED_SIZE_EXT" }, + { 0x8D50, "GL_RENDERBUFFER_RED_SIZE" }, + { 0x8D51, "GL_RENDERBUFFER_GREEN_SIZE_EXT" }, + { 0x8D51, "GL_RENDERBUFFER_GREEN_SIZE" }, + { 0x8D52, "GL_RENDERBUFFER_BLUE_SIZE_EXT" }, + { 0x8D52, "GL_RENDERBUFFER_BLUE_SIZE" }, + { 0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE_EXT" }, + { 0x8D53, "GL_RENDERBUFFER_ALPHA_SIZE" }, + { 0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE_EXT" }, + { 0x8D54, "GL_RENDERBUFFER_DEPTH_SIZE" }, + { 0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE_EXT" }, + { 0x8D55, "GL_RENDERBUFFER_STENCIL_SIZE" }, + { 0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT" }, + { 0x8D56, "GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE" }, + { 0x8D57, "GL_MAX_SAMPLES_EXT" }, + { 0x8D57, "GL_MAX_SAMPLES" }, + { 0x8D70, "GL_RGBA32UI_EXT" }, + { 0x8D71, "GL_RGB32UI_EXT" }, + { 0x8D72, "GL_ALPHA32UI_EXT" }, + { 0x8D73, "GL_INTENSITY32UI_EXT" }, + { 0x8D74, "GL_LUMINANCE32UI_EXT" }, + { 0x8D75, "GL_LUMINANCE_ALPHA32UI_EXT" }, + { 0x8D76, "GL_RGBA16UI_EXT" }, + { 0x8D77, "GL_RGB16UI_EXT" }, + { 0x8D78, "GL_ALPHA16UI_EXT" }, + { 0x8D79, "GL_INTENSITY16UI_EXT" }, + { 0x8D7A, "GL_LUMINANCE16UI_EXT" }, + { 0x8D7B, "GL_LUMINANCE_ALPHA16UI_EXT" }, + { 0x8D7C, "GL_RGBA8UI_EXT" }, + { 0x8D7D, "GL_RGB8UI_EXT" }, + { 0x8D7E, "GL_ALPHA8UI_EXT" }, + { 0x8D7F, "GL_INTENSITY8UI_EXT" }, + { 0x8D80, "GL_LUMINANCE8UI_EXT" }, + { 0x8D81, "GL_LUMINANCE_ALPHA8UI_EXT" }, + { 0x8D82, "GL_RGBA32I_EXT" }, + { 0x8D83, "GL_RGB32I_EXT" }, + { 0x8D84, "GL_ALPHA32I_EXT" }, + { 0x8D85, "GL_INTENSITY32I_EXT" }, + { 0x8D86, "GL_LUMINANCE32I_EXT" }, + { 0x8D87, "GL_LUMINANCE_ALPHA32I_EXT" }, + { 0x8D88, "GL_RGBA16I_EXT" }, + { 0x8D89, "GL_RGB16I_EXT" }, + { 0x8D8A, "GL_ALPHA16I_EXT" }, + { 0x8D8B, "GL_INTENSITY16I_EXT" }, + { 0x8D8C, "GL_LUMINANCE16I_EXT" }, + { 0x8D8D, "GL_LUMINANCE_ALPHA16I_EXT" }, + { 0x8D8E, "GL_RGBA8I_EXT" }, + { 0x8D8F, "GL_RGB8I_EXT" }, + { 0x8D90, "GL_ALPHA8I_EXT" }, + { 0x8D91, "GL_INTENSITY8I_EXT" }, + { 0x8D92, "GL_LUMINANCE8I_EXT" }, + { 0x8D93, "GL_LUMINANCE_ALPHA8I_EXT" }, + { 0x8D94, "GL_RED_INTEGER_EXT" }, + { 0x8D95, "GL_GREEN_INTEGER_EXT" }, + { 0x8D96, "GL_BLUE_INTEGER_EXT" }, + { 0x8D97, "GL_ALPHA_INTEGER_EXT" }, + { 0x8D98, "GL_RGB_INTEGER_EXT" }, + { 0x8D99, "GL_RGBA_INTEGER_EXT" }, + { 0x8D9A, "GL_BGR_INTEGER_EXT" }, + { 0x8D9B, "GL_BGRA_INTEGER_EXT" }, + { 0x8D9C, "GL_LUMINANCE_INTEGER_EXT" }, + { 0x8D9D, "GL_LUMINANCE_ALPHA_INTEGER_EXT" }, + { 0x8D9E, "GL_RGBA_INTEGER_MODE_EXT" }, + { 0x8DA7, "GL_FRAMEBUFFER_ATTACHMENT_LAYERED_EXT" }, + { 0x8DA8, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT" }, + { 0x8DA9, "GL_FRAMEBUFFER_INCOMPLETE_LAYER_COUNT_EXT" }, + { 0x8DAD, "GL_FLOAT_32_UNSIGNED_INT_24_8_REV" }, + { 0x8DB9, "GL_FRAMEBUFFER_SRGB_EXT" }, + { 0x8DBA, "GL_FRAMEBUFFER_SRGB_CAPABLE_EXT" }, + { 0x8DBB, "GL_COMPRESSED_RED_RGTC1" }, + { 0x8DBC, "GL_COMPRESSED_SIGNED_RED_RGTC1" }, + { 0x8DBD, "GL_COMPRESSED_RG_RGTC2" }, + { 0x8DBE, "GL_COMPRESSED_SIGNED_RG_RGTC2" }, + { 0x8DC0, "GL_SAMPLER_1D_ARRAY_EXT" }, + { 0x8DC1, "GL_SAMPLER_2D_ARRAY_EXT" }, + { 0x8DC2, "GL_SAMPLER_BUFFER_EXT" }, + { 0x8DC3, "GL_SAMPLER_1D_ARRAY_SHADOW_EXT" }, + { 0x8DC4, "GL_SAMPLER_2D_ARRAY_SHADOW_EXT" }, + { 0x8DC5, "GL_SAMPLER_CUBE_SHADOW_EXT" }, + { 0x8DC6, "GL_UNSIGNED_INT_VEC2_EXT" }, + { 0x8DC7, "GL_UNSIGNED_INT_VEC3_EXT" }, + { 0x8DC8, "GL_UNSIGNED_INT_VEC4_EXT" }, + { 0x8DC9, "GL_INT_SAMPLER_1D_EXT" }, + { 0x8DCA, "GL_INT_SAMPLER_2D_EXT" }, + { 0x8DCB, "GL_INT_SAMPLER_3D_EXT" }, + { 0x8DCC, "GL_INT_SAMPLER_CUBE_EXT" }, + { 0x8DCD, "GL_INT_SAMPLER_2D_RECT_EXT" }, + { 0x8DCE, "GL_INT_SAMPLER_1D_ARRAY_EXT" }, + { 0x8DCF, "GL_INT_SAMPLER_2D_ARRAY_EXT" }, + { 0x8DD0, "GL_INT_SAMPLER_BUFFER_EXT" }, + { 0x8DD1, "GL_UNSIGNED_INT_SAMPLER_1D_EXT" }, + { 0x8DD2, "GL_UNSIGNED_INT_SAMPLER_2D_EXT" }, + { 0x8DD3, "GL_UNSIGNED_INT_SAMPLER_3D_EXT" }, + { 0x8DD4, "GL_UNSIGNED_INT_SAMPLER_CUBE_EXT" }, + { 0x8DD5, "GL_UNSIGNED_INT_SAMPLER_2D_RECT_EXT" }, + { 0x8DD6, "GL_UNSIGNED_INT_SAMPLER_1D_ARRAY_EXT" }, + { 0x8DD7, "GL_UNSIGNED_INT_SAMPLER_2D_ARRAY_EXT" }, + { 0x8DD8, "GL_UNSIGNED_INT_SAMPLER_BUFFER_EXT" }, + { 0x8DD9, "GL_GEOMETRY_SHADER_EXT" }, + { 0x8DDA, "GL_GEOMETRY_VERTICES_OUT_EXT" }, + { 0x8DDB, "GL_GEOMETRY_INPUT_TYPE_EXT" }, + { 0x8DDC, "GL_GEOMETRY_OUTPUT_TYPE_EXT" }, + { 0x8DDD, "GL_MAX_GEOMETRY_VARYING_COMPONENTS_EXT" }, + { 0x8DDE, "GL_MAX_VERTEX_VARYING_COMPONENTS_EXT" }, + { 0x8DDF, "GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT" }, + { 0x8DE0, "GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT" }, + { 0x8DE1, "GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT" }, + { 0x8DE2, "GL_MAX_VERTEX_BINDABLE_UNIFORMS_EXT" }, + { 0x8DE3, "GL_MAX_FRAGMENT_BINDABLE_UNIFORMS_EXT" }, + { 0x8DE4, "GL_MAX_GEOMETRY_BINDABLE_UNIFORMS_EXT" }, + { 0x8DED, "GL_MAX_BINDABLE_UNIFORM_SIZE_EXT" }, + { 0x8DEE, "GL_UNIFORM_BUFFER_EXT" }, + { 0x8DEF, "GL_UNIFORM_BUFFER_BINDING_EXT" }, + { 0x8E4C, "GL_QUADS_FOLLOW_PROVOKING_VERTEX_CONVENTION_EXT" }, + { 0x8E4D, "GL_FIRST_VERTEX_CONVENTION_EXT" }, + { 0x8E4E, "GL_LAST_VERTEX_CONVENTION_EXT" }, + { 0x8E4F, "GL_PROVOKING_VERTEX_EXT" }, + + VE( TERMVALUE ) +}; + +const GLMValueEntry_t g_gl_renderers[] = +{ + { 0x00020200, "Generic" }, + { 0x00020400, "GenericFloat" }, + { 0x00020600, "AppleSW" }, + { 0x00021000, "ATIRage128" }, + { 0x00021200, "ATIRadeon" }, + { 0x00021400, "ATIRagePro" }, + { 0x00021600, "ATIRadeon8500" }, + { 0x00021800, "ATIRadeon9700" }, + { 0x00021900, "ATIRadeonX1000" }, + { 0x00021A00, "ATIRadeonX2000" }, + { 0x00022000, "NVGeForce2MX" }, + { 0x00022200, "NVGeForce3" }, + { 0x00022400, "NVGeForceFX" }, + { 0x00022600, "NVGeForce8xxx" }, + { 0x00023000, "VTBladeXP2" }, + { 0x00024000, "Intel900" }, + { 0x00024200, "IntelX3100" }, + { 0x00040000, "Mesa3DFX" }, + + VE( TERMVALUE ) +}; + + +//=============================================================================== +// decode helper funcs + +char s_glmStrScratch[65536]; +int s_glmStrCursor = 0; + +const char * GLMDecode( GLMThing_t thingtype, unsigned long value ) +{ + const GLMValueEntry_t *table = NULL; + //char isflags = 0; + + switch( thingtype ) + { + case eD3D_DEVTYPE: table = g_d3d_devtypes; + break; + + case eD3D_FORMAT: table = g_d3d_formats; + break; + + case eD3D_RTYPE: table = g_d3d_rtypes; + break; + + case eD3D_USAGE: table = g_d3d_usages; + break; + + case eD3D_RSTATE: table = g_d3d_rstates; + break; + + case eD3D_SIO: table = g_d3d_opcodes; + break; + + case eD3D_VTXDECLUSAGE: table = g_d3d_vtxdeclusages; + break; + + case eCGL_RENDID: table = g_cgl_rendids; + break; + + case eGL_ERROR: table = g_gl_errors; + break; + + case eGL_ENUM: table = g_gl_enums; + break; + + case eGL_RENDERER: table = g_gl_renderers; + break; + + default: + GLMStop(); + return "UNKNOWNTYPE"; + break; + } + + if (table) + { + while( table->value != TERMVALUE ) + { + if (table->value == value) + { + return table->name; + } + table++; + } + } + return "UNKNOWN"; +} + +const char *GLMDecodeMask( GLMThing_t kind, unsigned long value ) +{ + // if cursor to scratch buffer is within 1K of EOB, rewind + // nobody is going to decode 63K of flag string values in a single call.. + + // this means that strings returned by this function have a short lifetime.. print them and do not save the pointer.. + + if ( (sizeof(s_glmStrScratch) - s_glmStrCursor) < 1000 ) + { + s_glmStrCursor = 0; + } + + char *start = &s_glmStrScratch[ s_glmStrCursor ]; + char *dest = start; + char first = 1; + + DWORD mask = static_cast(1L<<31); + while(mask) + { + if (mask & value) + { + sprintf(dest,"%s%s", (first) ? "" : "|", GLMDecode( kind, value&mask ) ); + first = 0; + + dest += strlen(dest); // leaves dest pointing at the end null + } + mask >>= 1; + } + s_glmStrCursor = (dest - s_glmStrScratch) + 1; // +1 so the next decoded flag set doesn't land on the ending null + return start; + +} + +#undef VE +#undef TERMVALUE + +//=============================================================================== + +bool GLMDetectOGLP( void ) +{ + bool result = false; +#if defined( OSX ) && defined( CGLPROFILER_ENABLE ) + GLint forceFlush; + CGLError error = CGLGetParameter(CGLGetCurrentContext(), kCGLCPEnableForceFlush, &forceFlush); + result = error == 0; + if (result) + { + // enable a breakpoint on color4sv + int oglp_bkpt[3] = { kCGLFEglColor4sv, kCGLProfBreakBefore, 1 }; + + CGLSetOption( kCGLGOEnableBreakpoint, (GLint)oglp_bkpt ); + } + +#endif + return result; +} + + +// from http://blog.timac.org/?p=190 + +#ifndef _WIN32 + #include +#endif +#include +#ifndef _WIN32 + #include +#ifdef LINUX +#include +#else +#include +#endif +#endif + +// From Technical Q&A QA1361 +// Returns true if the current process +// is being debugged (either running +// under the debugger or has a debugger +// attached post facto). + +bool GLMDetectGDB( void ) // aka AmIBeingDebugged() +{ +#ifdef OSX + bool result; + int junk; + int mib[4]; + struct kinfo_proc info; + size_t size; + + // Initialize the flags so that, + // if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info + // we want, in this case we're looking for + // information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + junk = sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, NULL, 0); + + assert(junk == 0); + + // We're being debugged if the P_TRACED + // flag is set. + + result = ( (info.kp_proc.p_flag & P_TRACED) != 0 ); + return result; +#else + return Sys_IsDebuggerPresent(); +#endif +} + + +static uint g_glmDebugChannelMask = 0; // which output channels are available (can be more than one) +static uint g_glmDebugFlavorMask = 0; // which message flavors are enabled for output (can be more than one) + +uint GLMDetectAvailableChannels( void ) +{ + uint result = 0; + + // printf is always available (except maybe in release... ?) + result |= (1 << ePrintf); + + // gdb + if (GLMDetectGDB()) + { + result |= (1 << eDebugger); + printf("\n############# GDB Detected"); + } + + // oglp + if (GLMDetectOGLP()) + { + result |= (1 << eGLProfiler); + printf("\n############# OGLP Detected"); + } + + return result; +} + + +static bool g_debugInitDone = false; + +#if GLMDEBUG + + // following funcs vanish if GLMDEBUG not set + +void GLMDebugInitialize( bool forceReinit ) +{ + if ( !g_debugInitDone || forceReinit ) + { + // detect channels + uint channelMask = GLMDetectAvailableChannels(); + + // see if there are any prohibitions on the commandline + // (also add any other desired reasons, release build say).. + + if ( CommandLine()->FindParm("-noprintconsole") ) + { + channelMask &= ~(1<FindParm("-noprintdebugger") ) + { + channelMask &= ~(1<FindParm("-noprintoglp") ) + { + channelMask &= ~(1<FindParm("-glmspew")) + { + channelMask = 0; + } + + // set the output channel mask + GLMDebugChannelMask( &channelMask ); + + // if any channels are enabled, enable some output + if ( channelMask ) + { + // start mostly quiet unless the -glmbootspew option is there + if ( CommandLine()->FindParm( "-glmbootspew" ) ) + { + g_glmDebugFlavorMask = 0xFFFFFFFF; + } + else + { + g_glmDebugFlavorMask = + (1< < + // | (1<m_bHave_GL_GREMEDY_string_marker) + { + gGL->glStringMarkerGREMEDY(0, string); + } + } +} + +int g_glm_indent = 0; +int g_glm_indent_max = 40; // 40 tabs max + +#ifndef OSX +const char *strnstr( const char *haystack, const char *needle, int len ) +{ + return strstr( haystack, needle ); +} +#endif + +EGLMDebugFlavor GLMAssessFlavor( char *str ) +{ + EGLMDebugFlavor flavor = eDefaultFlavor; + + if (strnstr(str, "-D-", 4)) + { + // debug dump + flavor = eDebugDump; + } + else if (strnstr(str, "-M-", 4)) + { + // matrix data + flavor = eMatrixData; + } + else if (strnstr(str, "-S-", 4)) + { + // shader data + flavor = eShaderData; + } + else if (strnstr(str, "-F-", 4)) + { + // framebuf data + flavor = eFrameBufData; + } + else if (strnstr(str, "-X-", 4)) + { + // DirectX data + flavor = eDXStuff; + } + else if (strnstr(str, "-A-", 4)) + { + // allocation data + flavor = eAllocations; + } + else if (strnstr(str, "-Z-", 4)) + { + // allocation data + flavor = eSlowness; + } + else if (str[0] == '<' || str[0] == '>') + { + // entry/exit (aka tenure) + flavor = eTenure; + } + else if (strnstr(str, "---", 4)) // note we check four chars worth so you can do >-M- and it will indent and be filterable + { + // comment + flavor = eComment; + } + + return flavor; +} + +void GLMPrintfVA( const char *fmt, va_list vargs ) +{ + // if no channels open, return + uint channelMask = GLMDebugChannelMask(); + if (!channelMask) + return; + + // if "all flavors" is off, return + uint flavorMask = GLMDebugFlavorMask(); + if (! ( flavorMask & (1<' - raise indent level after print. + // if first char is a '<' - lower indent level before print. + + char buf[100000]; + + if (fmt[0] == '<') + { + GLMIncIndent( -1 ); + } + + memset( buf, '\t', g_glm_indent ); + vsprintf( buf+g_glm_indent, fmt, vargs ); + GLMStringOut( buf ); + + if (fmt[0] == '>') + { + GLMIncIndent( 1 ); + } +} + +void GLMPrintf( const char *fmt, ... ) +{ + // if no channels open, return + uint channelMask = GLMDebugChannelMask(); + if (!channelMask) + return; + + // if "all flavors" is off, return + uint flavorMask = GLMDebugFlavorMask(); + if (! ( flavorMask & (1<' - raise indent level after print. + // if first char is a '<' - lower indent level before print. + + char buf[64000]; + + if (str[0] == '<') + { + GLMIncIndent( -1 ); + } + + memset( buf, '\t', g_glm_indent ); + + if (strlen(str) < sizeof(buf)-g_glm_indent-1) + { + strcpy( buf + g_glm_indent, str ); + } + else + { + DXABSTRACT_BREAK_ON_ERROR(); + } + + + GLMStringOut( buf ); // single string out with indenting + + if (str[0] == '>') + { + GLMIncIndent( 1 ); + } +} + + +void GLMPrintText( const char *str, EGLMDebugFlavor flavor, uint options ) +{ + // if no channels open, return + uint channelMask = GLMDebugChannelMask(); + if (!channelMask) + return; + + // if "all flavors" is off, return + uint flavorMask = GLMDebugFlavorMask(); + if (! ( flavorMask & (1<0) + { + if (g_glm_indent > g_glm_indent_max) + { + g_glm_indent = g_glm_indent_max; + } + } + else + { + if (g_glm_indent < 0) + { + g_glm_indent = 0; + } + } + return g_glm_indent; +} + +int GLMGetIndent( void ) +{ + return g_glm_indent; +} + +void GLMSetIndent( int indent ) +{ + g_glm_indent = indent; +} + +#endif + +// PIX tracking - you can call these outside of GLMDEBUG=true +char sg_pPIXName[128]; + + +ConVar gl_telemetry_gpu( "gl_telemetry_gpu", "0" ); +static bool g_bPrevTelemetryGPU; + +static uint g_nPIXEventIndex; + +void GLMBeginPIXEvent( const char *str ) +{ + V_strncpy( sg_pPIXName, str, 128 ); + +#if defined( OSX ) && defined( CGLPROFILER_ENABLE ) + CGLSetOption( kCGLGOComment, (GLint)sg_pPIXName ); +#endif + + if ( gGL->m_bHave_GL_GREMEDY_string_marker ) + { + gGL->glStringMarkerGREMEDY( 0, sg_pPIXName ); + } +} + +void GLMEndPIXEvent( void ) +{ +#if defined( OSX ) && defined( CGLPROFILER_ENABLE ) + CGLSetOption( kCGLGOComment, (GLint)sg_pPIXName ); +#endif + + if ( gGL->m_bHave_GL_GREMEDY_string_marker ) + { + gGL->glStringMarkerGREMEDY( 0, sg_pPIXName ); + } + + sg_pPIXName[0] = '\0'; + + tmLeave( TELEMETRY_LEVEL2 ); +} + +//=============================================================================== + +// Knob - hash table mapping string names to float values + + +struct GLMKnobKey +{ + char *m_knobName; +}; + +struct GLMKnobValue +{ + float m_value; +}; + +bool LessFunc_GLMKnobKey( const GLMKnobKey &a, const GLMKnobKey &b ) +{ + // Umm, what should this really be? + //return strcmp( a.m_knobName, b.m_knobName ); + return strcmp( a.m_knobName, b.m_knobName ) < 0; +} + +CUtlMap< GLMKnobKey, GLMKnobValue* > *g_knobMap = NULL; + +// add some special knob-names that just read mod keys +extern "C" uint GetCurrentKeyModifiers( void ); + +enum ECarbonModKeyIndex +{ + EcmdKeyBit = 8, /* command key down?*/ + EshiftKeyBit = 9, /* shift key down?*/ + EalphaLockBit = 10, /* alpha lock down?*/ + EoptionKeyBit = 11, /* option key down?*/ + EcontrolKeyBit = 12 /* control key down?*/ +}; + +enum ECarbonModKeyMask +{ + EcmdKey = 1 << EcmdKeyBit, + EshiftKey = 1 << EshiftKeyBit, + EalphaLock = 1 << EalphaLockBit, + EoptionKey = 1 << EoptionKeyBit, + EcontrolKey = 1 << EcontrolKeyBit +}; + +float GLMKnob( char *knobname, float *setvalue ) +{ +#if GLMDEBUG + float result = 0.0f; + + if (!g_knobMap) + { + g_knobMap = new CUtlMap< GLMKnobKey, GLMKnobValue* >; + g_knobMap->SetLessFunc( LessFunc_GLMKnobKey ); + } + +#ifdef OSX + uint mods = GetCurrentKeyModifiers(); +#else + uint mods = 0; +#endif + // is it a special key name ? + if (!strcmp(knobname,"caps-key")) + { + return (mods & (EalphaLock)) ? 1.0 : 0.0; + } + else if (!strcmp(knobname,"control-key")) + { + return (mods & (EcontrolKey)) ? 1.0 : 0.0; + } + else if (!strcmp(knobname,"shift-key")) + { + return (mods & (EshiftKey)) ? 1.0 : 0.0; + } + else if (!strcmp(knobname,"option-key")) + { + return (mods & (EoptionKey)) ? 1.0 : 0.0; + } + else + { + // does the key exist in the map ? + GLMKnobKey key; + key.m_knobName = knobname; + + GLMKnobValue *knob = NULL; + + unsigned short index = g_knobMap->Find( key ); + if (index != g_knobMap->InvalidIndex()) + { + // found it + knob = (*g_knobMap)[ index ]; + + if (setvalue) + { + knob->m_value = *setvalue; + } + + result = knob->m_value; + } + else + { + // need to make a new one + knob = new GLMKnobValue; + + knob->m_value = (setvalue) ? *setvalue : 0.0f; + + g_knobMap->Insert( key, knob ); + } + + return knob->m_value; + } + +#else + // GLM knobs just return 0.0 all the time when no GLMDEBUG + return 0.0f; +#endif +} + +// for boolean knobs.. +float GLMKnobToggle( char *knobname ) +{ + // if not 0.0, make it 0.0 + // if 0.0, make it 1.0 + + float newValue = 0.0; // assume falling edge + float curValue = GLMKnob( knobname, NULL ); + if (curValue == 0.0) + { + newValue = 1.0; + } + + return GLMKnob( knobname, &newValue ); +} + + +//=============================================================================== + +// helpers for CGLSetOption - no op if no profiler +void GLMProfilerClearTrace( void ) +{ +#if defined( OSX ) && defined( CGLPROFILER_ENABLE ) + CGLSetOption( kCGLGOResetFunctionTrace, 0 ); +#else + Assert( !"impl me" ); +#endif +} + +void GLMProfilerEnableTrace( bool enable ) +{ +#if defined( OSX ) && defined( CGLPROFILER_ENABLE ) + CGLSetOption( kCGLGOEnableFunctionTrace, enable ? GL_TRUE : GL_FALSE ); +#else + Assert( !"impl me" ); +#endif +} + +// helpers for CGLSetParameter - no op if no profiler +void GLMProfilerDumpState( void ) +{ +#if defined( OSX ) && defined( CGLPROFILER_ENABLE ) + CGLContextObj curr = CGLGetCurrentContext(); + CGLSetParameter( curr, kCGLCPDumpState, (const GLint*)1 ); +#else + Assert( !"impl me" ); +#endif +} + + +//=============================================================================== + +CGLMFileMirror::CGLMFileMirror( char *fullpath ) +{ + m_path = strdup( fullpath ); + m_data = (char *)malloc(1); + m_size = 0; + UpdateStatInfo(); + if (m_exists) + { + ReadFile(); + } +} + +CGLMFileMirror::~CGLMFileMirror( ) +{ + if (m_path) + { + free (m_path); + m_path = NULL; + } + + if (m_data) + { + free (m_data); + m_data = NULL; + } +} + +bool CGLMFileMirror::HasData( void ) +{ + return (m_size != 0); +} + + +// return direct pointer to buffer. Will be invalidated if file is re-loaded or if data is written to +void CGLMFileMirror::GetData( char **dataPtr, uint *dataSizePtr ) +{ + *dataPtr = m_data; + *dataSizePtr = m_size; +} + + +void CGLMFileMirror::SetData( char *data, uint dataSize ) +{ + if (m_data) + { + free( m_data ); + m_data = NULL; + } + + m_size = dataSize; + + m_data = (char *)malloc( m_size +1 ); + m_data[ m_size ] = 0; // extra NULL terminator, no charge + + memcpy( m_data, data, m_size ); // copy data in + + WriteFile(); // keep disk copy sync'd +} + +static bool stat_diff( struct stat *a, struct stat *b ) +{ + if (a->st_size != b->st_size) + { + return true; + } + +#ifdef OSX + if (memcmp( &a->st_mtimespec, &b->st_mtimespec, sizeof( struct timespec ) ) ) +#else + if (memcmp( &a->st_mtime, &b->st_mtime, sizeof( time_t ) ) ) +#endif + { + return true; + } + + return false; +} + +bool CGLMFileMirror::PollForChanges( void ) +{ + // snapshot old stat + //bool old_exists = m_exists; + struct stat old_stat = m_stat; + + UpdateStatInfo(); + + if (m_exists) + { + if ( stat_diff( &old_stat, &m_stat ) ) + { + // initial difference detected. continue to poll at 0.1s intervals until it stops changing, then read it. + int stablecount = 0; + do + { + ThreadSleep(100000); + + struct stat last_stat = m_stat; + UpdateStatInfo(); + + if (stat_diff( &last_stat, &m_stat )) + { + stablecount = 0; + } + else + { + stablecount++; + } + } while(stablecount<3); + + // changes have settled down, now re-read it + ReadFile(); + return true; + } + else + { + return false; // no change + } + } + else + { + // file does not exist. remake it. not considered to be a change. + WriteFile(); + return false; + } +} + + + +void CGLMFileMirror::UpdateStatInfo( void ) +{ + // stat the path + struct stat newstat; + memset (&newstat, 0, sizeof(newstat) ); + int result = stat( m_path, &newstat ); + + if (!result) + { + m_exists = true; + m_stat = newstat; + } + else + { + m_exists = false; + memset( &m_stat, 0, sizeof( m_stat ) ); + } +} + + +void CGLMFileMirror::ReadFile( void ) +{ + // unconditional - we discard any old buffer, make a new one, + UpdateStatInfo(); + + if (m_data) + { + free( m_data ); + m_data = NULL; + } + + if (m_exists) + { + FILE *infile = fopen( m_path, "rb" ); + if (infile) + { + // get size from stat + m_size = m_stat.st_size; + + m_data = (char *)malloc( m_size +1 ); + m_data[ m_size ] = 0; // extra NULL terminator, no charge + + fread( m_data, 1, m_size, infile ); + + fclose( infile ); + } + else + { + GLMDebugger(); // ouch + } + + } + else + { + // hmmmmmm + m_data = (char *)malloc(1); + m_data[0] = 0; + m_size = 0; + } +} + + +void CGLMFileMirror::WriteFile( void ) +{ + FILE *outfile = fopen( m_path, "wb" ); + + if (outfile) + { + fwrite( m_data, 1, m_size, outfile ); + fclose( outfile ); + + UpdateStatInfo(); // sets m_stat and m_exists + } + else + { + GLMDebugger(); // ouch + } +} + +void CGLMFileMirror::OpenInEditor( bool foreground ) +{ + char temp[64000]; + + // pass -b if no desire to bring editor to foreground + sprintf(temp,"/usr/bin/bbedit %s %s", foreground ? "" : "-b", m_path ); + system( temp ); +} + + + +CGLMEditableTextItem::CGLMEditableTextItem( char *text, uint size, bool forceOverwrite, char *prefix, char *suffix ) +{ + // clone input text (exact size copy) + m_origSize = size; + m_origText = (char *)malloc( m_origSize ); + memcpy( m_origText, text, m_origSize ); + + // null out munged form til we generate it + m_mungedSize = 0; + m_mungedText = NULL; + + // null out mirror until we create it + m_mirrorBaseName = NULL; + m_mirrorFullPath = NULL; + m_mirror = NULL; + + GenHashOfOrigText(); // will fill out m_origDigest + GenMungedText( false ); + GenBaseNameAndFullPath( prefix, suffix ); // figure out where the mirror will go + + if (!strcmp(m_mirrorBaseName, "96c7e9d2faf76b1148f7274afd684d4b.fsh")) + { + printf("\nhello there\n"); + } + + // make the mirror from the filename. + // see if there was any content on disk + // if so, honor that content *unless* the force-option is set. + m_mirror = new CGLMFileMirror( m_mirrorFullPath ); + + // the logic is simple. + // the only time we will choose the copy on disk, is if + // a - forceOverwrite is false + // AND b - the copy on disk is bigger than 10 bytes. + + bool replaceDiskCopy = true; + + char *mirrorData = NULL; + uint mirrorSize = 0; + + if (!forceOverwrite) + { + if (m_mirror->HasData()) + { + // peek at it, and use it if it is more than some minimum number of bytes. + m_mirror->GetData( &mirrorData, &mirrorSize ); + if (mirrorSize > 10) + { + replaceDiskCopy = false; + } + } + } + + if (replaceDiskCopy) + { + // push our generated data to the mirror - disk copy is overwritten + m_mirror->SetData( m_mungedText, m_mungedSize ); + } + else + { + GenMungedText( true ); + } + +} + +CGLMEditableTextItem::~CGLMEditableTextItem( ) +{ + if (m_origText) + { + free (m_origText); + } + + if (m_mungedText) + { + free (m_mungedText); + } + + if (m_mirrorBaseName) + { + free (m_mirrorBaseName); + } + + if (m_mirrorFullPath) + { + free (m_mirrorFullPath); + } + + if (m_mirror) + { + free( m_mirror ); + } +} + +bool CGLMEditableTextItem::HasData( void ) +{ + return m_mirror->HasData(); +} + +bool CGLMEditableTextItem::PollForChanges( void ) +{ + bool changed = m_mirror->PollForChanges(); + if (changed) + { + // re-gen munged text from mirror (means "copy") + GenMungedText( true ); + } + return changed; +} + +void CGLMEditableTextItem::GetCurrentText( char **textOut, uint *sizeOut ) +{ + if (!m_mungedText) GLMDebugger(); + + *textOut = m_mungedText; + *sizeOut = m_mungedSize; +} + +void CGLMEditableTextItem::OpenInEditor( bool foreground ) +{ + m_mirror->OpenInEditor( foreground ); +} + + +void CGLMEditableTextItem::GenHashOfOrigText( void ) +{ + MD5Context_t md5ctx; + MD5Init( &md5ctx ); + MD5Update( &md5ctx, (unsigned char*)m_origText, m_origSize ); + MD5Final( m_origDigest, &md5ctx ); +} + + +void CGLMEditableTextItem::GenBaseNameAndFullPath( char *prefix, char *suffix ) +{ + // base name is hash digest in hex, plus the suffix. + char temp[5000]; + + Q_binarytohex( m_origDigest, sizeof(m_origDigest), temp, sizeof( temp ) ); + if (suffix) + { + strcat( temp, suffix ); + } + if (m_mirrorBaseName) free(m_mirrorBaseName); + m_mirrorBaseName = strdup( temp ); + + sprintf( temp, "%s%s", prefix, m_mirrorBaseName ); + if (m_mirrorFullPath) free(m_mirrorFullPath); + m_mirrorFullPath = strdup( temp ); +} + + +void CGLMEditableTextItem::GenMungedText( bool fromMirror ) +{ + if (fromMirror) + { + // just import the text as is from the mirror file. + + char *mirrorData = NULL; + uint mirrorSize = 0; + + if (m_mirror->HasData()) + { + // peek at it, and use it if it is more than some minimum number of bytes. + m_mirror->GetData( &mirrorData, &mirrorSize ); + + if (m_mungedText) + { + free( m_mungedText ); + m_mungedText = NULL; + } + + m_mungedText = (char *)malloc( mirrorSize+1 ); + m_mungedText[ mirrorSize ] = 0; + memcpy( m_mungedText, mirrorData, mirrorSize ); + + m_mungedSize = mirrorSize; + } + else + { + GLMDebugger(); + } + } + else + { + #if 1 + // we don't actually clone/munge any more. + if (m_mungedText) + { + free( m_mungedText ); + m_mungedText = NULL; + } + + m_mungedText = (char *)malloc( m_origSize+1 ); + m_mungedText[ m_origSize ] = 0; + memcpy( m_mungedText, m_origText, m_origSize ); + + m_mungedSize = m_origSize; + + #else + // take pure 'orig' text that came in from the engine, and clone it + // do not clone the first line + char temp[100000]; + char *dst = temp; + char *lim = &temp[ sizeof(temp) ]; + + // zero temp + memset( temp, 0, sizeof(temp) ); + + // write orig text to temp + if (m_origSize >= (sizeof(temp)/2) ) + { + GLMDebugger(); + } + + memcpy( dst, m_origText, m_origSize ); + dst += m_origSize; + + // add a newline if the last character wasn't + if ( (*(dst-1)) != '\n' ) + { + *dst++ = '\n'; + } + + // walk orig text again and copy it over, with these caveats + // don't copy the first line + // insert a # before all the other lines. + char *src = temp; + + // walk to end of first line + char *firstNewline = strchr( src, '\n' ); + if (!firstNewline) + { + GLMDebugger(); + } + else + { + // advance 'src' to that newline- we're not copying the !! line + src = firstNewline; + } + + + // now walk the rest - insert a # after each newline + while( (dst < lim) && ((src-temp) < m_origSize) ) + { + switch( *src ) + { + case '\n': + *dst++ = *src++; + *dst++ = '#'; + break; + + default: + *dst++ = *src++; + } + } + if (dst >= lim) + { + GLMDebugger(); + } + + // final newline + *dst++ = '\n'; + + // copyout + if (m_mungedText) + { + free( m_mungedText ); + m_mungedText = NULL; + } + + m_mungedSize = dst - temp; + m_mungedText = (char *)malloc( m_mungedSize ); + memcpy( m_mungedText, temp, m_mungedSize ); + #endif + } +} + +//=============================================================================== + +// class for cracking multi-part text blobs +// sections are demarcated by beginning-of-line markers submitted in a table by the caller +// typically +// asm flavors have first-line rules so we use those tags as is +// !!ARBvp (etc) +// !!ARBfp (etc) +// //!!GLSLF // slashes required +// //!GLSLV + +// maybe also introduce "present but disabled" markers like these +// -!!ARBvp (etc) +// -!!ARBfp (etc) +// -//!!GLSLF +// -//!GLSLV + +// resolved. there is no default section for text that doesn't have a marker in front of it. mark it or miss it. + +CGLMTextSectioner::CGLMTextSectioner( char *text, int textLength, const char **markers ) +{ + // find lines + // for each line, see if it starts with a marker + // if so, open a new section based at that line + + GLMTextSection *curSection = NULL; // no current section until we see a marker + + char *cursor = text; + char *textLimit = text+textLength; + + int foundMarker; + const char **markerCursor; + while( cursor < textLimit ) + { + // top of loop. cursor points to start of a line. + // find the end of the line and keep that handy. + char *eol = strchr( cursor, '\n' ); + int charsInLine = (eol) ? (eol-cursor)+1 : strlen(cursor); + + //see if any of the marker strings is located here. + foundMarker = -1; + markerCursor = markers; + + while( (foundMarker<0) && (*markerCursor!=NULL) ) + { + // see if the n'th marker is a hit + int markerLen = strlen(*markerCursor); + + if (!strncmp( cursor, *markerCursor, markerLen ) ) + { + // hit + foundMarker = markerCursor - markers; + } + markerCursor++; + } + + // outcome is either "marker spotted" or "no". + // if marker seen, open new section using that marker. + // else, grow active section if underway. + // then, move cursor to next line. + + if (foundMarker >= 0) + { + // found marker. start new section. + // no need to do anything special with prior section - it was up to date before seeing this marker. + int index = m_sectionTable.AddToTail(); + curSection = &m_sectionTable[ index ]; + + curSection->m_markerIndex = foundMarker; + curSection->m_textOffset = cursor - text; // text includes the marker + curSection->m_textLength = charsInLine; // this line goes in the tally, later lines add to it + } + else + { + // add this line to current section if live + if (curSection) + { + curSection->m_textLength += charsInLine; + } + } + cursor += charsInLine; + } +} + +CGLMTextSectioner::~CGLMTextSectioner( ) +{ + // not much to do. +} + + +int CGLMTextSectioner::Count( void ) +{ + return m_sectionTable.Count(); +} + +void CGLMTextSectioner::GetSection( int index, uint *offsetOut, uint *lengthOut, int *markerIndexOut ) +{ + Assert( index < m_sectionTable.Count() ); + + GLMTextSection *section = &m_sectionTable[ index ]; + + *offsetOut = section->m_textOffset; + *lengthOut = section->m_textLength; + *markerIndexOut = section->m_markerIndex; +} + +//=============================================================================== + +// how to make a compiled-in font: +// a. type in a matrix of characters in your fav editor +// b. take a screen shot of the characters (128x128 pixels in this case) +// c. export as TIFF raw. +// d. hex dump it +// e. column-copy just the hex data +// f. find and replace: chop out all the spaces and line feeds, change FFFFFF and 000000 to your marker chars of choice. +// g. wrap each line with quotes and a comma. + +unsigned char g_glmDebugFontMap[ 128 * 128 ] = +{ +" * " +" * * * * * " +" * * * * * *** * * ** * * * * * " +" * * * ***** * * * * * * * * * * * * * * * * " +" * * * * * * * * * * * * * *** * * " +" * ***** *** * * * * * * * ***** ***** * " +" * * * * * * * * * * * * * * * " +" * * * * * * * * * * * ** ** * " +" * *** * * ** * * * ** ** * " +" * * * * * " +" * " +" " +" " +" *** * *** *** * ***** *** ***** *** *** * * *** " +"* * ** * * * * ** * * * * * * * ** ** * * * * " +"* ** * * * * * **** **** * * * * * ** ** * ***** * * " +"* * * * * ** * * * * * * *** * * * * * " +"** * * * * ***** * * * * * * **** * ***** * * " +"* * * * * * * * * * * * * * * ** ** * * " +" *** * ***** *** * *** *** * *** *** ** ** * * * " +" * " +" * " +" " +" *** " +"* * *** **** *** **** ***** ***** *** * * * * * * * * * * * *** " +"* * * * * * * * * * * * * * * * * * * * * ** ** ** * * * " +"* * * * * * * * * * * * * * * * * * * * * * * * * * * * " +"*** * ***** **** * * * **** **** * ** ***** * * ** * * * * ** * * " +"* ** * * * * * * * * * * * * * * * * * * * * * * * * * " +"* * * * * * * * * * * * * * * * * * * * * * * * * * * " +"* * * * **** *** **** ***** * *** * * * *** * * ***** * * * * *** " +" *** " +" " +" * " +" ** * ** * " +"**** *** **** *** ***** * * * * * * * * * * ***** * * * * * " +"* * * * * * * * * * * * * * * * * * * * * * * * * " +"* * * * * * * * * * * * * * * * * * * * * " +"**** * * **** *** * * * * * * * * * * * * * * " +"* * * * * * * * * * * * * * * * * * * * " +"* * * * * * * * * * * ** ** * * * * * * * " +"* *** * * *** * *** * * * * * * ***** * * * ****** " +" * ** * ** " +" " +" " +" * " +" * * * ** * * * * * " +" * * * * * * * " +" **** **** *** **** *** *** **** **** * * * * * **** * ** *** " +" * * * * * * * * * * * * * * * * * * * * * * * ** * * * " +" * * * * * * * ***** * * * * * * * *** * * * * * * * * " +" * ** * * * * * * * * * * * * * * * * * * * * * * * " +" ** * **** **** **** **** * **** * * * * * * ** * * * * * *** " +" * * " +" *** ** " +" * " +" ** * ** " +" * * * * ** * " +" * * * * * ** *** " +"**** **** * ** **** **** * * * * * * * * * * * ***** * * * ***** " +"* * * * ** * * * * * * * * * * * * * * * ** * ** ***** " +"* * * * * *** * * * * * * * * * * * * * * * ***** " +"* * * * * * * * ** * * * * * * * * * * * * * *** " +"**** **** * **** ** ** * * * * * * **** ***** * * * " +"* * * ** * ** " +"* * *** * " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +}; + + + + + + + + diff --git a/togles/linuxwin/glmgrcocoa.mm b/togles/linuxwin/glmgrcocoa.mm new file mode 100644 index 00000000..9bd997d8 --- /dev/null +++ b/togles/linuxwin/glmgrcocoa.mm @@ -0,0 +1,34 @@ +//========= Copyright 1996-2009, Valve Corporation, All rights reserved. ============// +// +// Purpose: provide some call-out glue to ObjC from the C++ GLMgr code +// +// $Revision: $ +// $NoKeywords: $ +//=============================================================================// + + +#include +#include +#include +#include + +#undef MIN +#undef MAX +#define DONT_DEFINE_BOOL // Don't define BOOL! +#include "tier0/threadtools.h" +#include "tier1/interface.h" +#include "tier1/strtools.h" +#include "tier1/utllinkedlist.h" +#include "togles/rendermechanism.h" + + + +// ------------------------------------------------------------------------------------ // +// some glue to let GLMgr call into NS/ObjC classes. +// ------------------------------------------------------------------------------------ // + +CGLContextObj GetCGLContextFromNSGL( PseudoNSGLContextPtr nsglCtx ) +{ + return (CGLContextObj)[ (NSOpenGLContext*)nsglCtx CGLContextObj]; +} + diff --git a/togles/linuxwin/glmtexinlines.h b/togles/linuxwin/glmtexinlines.h new file mode 100644 index 00000000..cbdcc546 --- /dev/null +++ b/togles/linuxwin/glmtexinlines.h @@ -0,0 +1,29 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +#ifndef CGLMTEXINLINES_H +#define CGLMTEXINLINES_H + +#pragma once + +#endif // CGLMTEXINLINES_H diff --git a/togles/linuxwin/intelglmallocworkaround.cpp b/togles/linuxwin/intelglmallocworkaround.cpp new file mode 100644 index 00000000..efe0e0ad --- /dev/null +++ b/togles/linuxwin/intelglmallocworkaround.cpp @@ -0,0 +1,71 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +#include "intelglmallocworkaround.h" +#include "mach_override.h" + +// memdbgon -must- be the last include file in a .cpp file. +#include "tier0/memdbgon.h" + +IntelGLMallocWorkaround* IntelGLMallocWorkaround::s_pWorkaround = NULL; + +void *IntelGLMallocWorkaround::ZeroingAlloc(size_t size) +{ + // We call into this pointer that resumes the original malloc. + void *memory = s_pWorkaround->m_pfnMallocReentry(size); + if (size < 96) + { + // Since the Intel driver has an issue with a small allocation + // that's left uninitialized, we use memset to ensure it's zero-initialized. + memset(memory, 0, size); + } + + return memory; +} + +IntelGLMallocWorkaround* IntelGLMallocWorkaround::Get() +{ + if (!s_pWorkaround) + { + s_pWorkaround = new IntelGLMallocWorkaround(); + } + + return s_pWorkaround; +} + +bool IntelGLMallocWorkaround::Enable() +{ + if ( m_pfnMallocReentry != NULL ) + { + return true; + } + + mach_error_t error = mach_override_ptr( (void*)&malloc, (const void*)&ZeroingAlloc, (void**)&m_pfnMallocReentry ); + if ( error == err_cannot_override ) + { + m_pfnMallocReentry = NULL; + return false; + } + + return true; +} \ No newline at end of file diff --git a/togles/linuxwin/intelglmallocworkaround.h b/togles/linuxwin/intelglmallocworkaround.h new file mode 100644 index 00000000..630972d1 --- /dev/null +++ b/togles/linuxwin/intelglmallocworkaround.h @@ -0,0 +1,61 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// TOGL CODE LICENSE +// +// Copyright 2011-2014 Valve Corporation +// All Rights Reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +// intelglmallocworkaround.h +// class responsible for setting up a malloc override that zeroes allocated +// memory of less than 96 bytes. this is to work around a bug +// in the Intel GLSL compiler on Mac OS X 10.8 due to uninitialized memory. +// +// 96 was chosen due to this quote from Apple: +// "I verified that the size of the structure is exactly 64 bytes on 10.8.3, 10.8.4 and will be on 10.8.5." +// +// certain GLSL shaders would (intermittently) cause a crash the first time they +// were drawn, and the bug has supposedly been fixed in 10.9, but is unlikely to +// ever make it to 10.8. +// +//=============================================================================== + +#ifndef INTELGLMALLOCWORKAROUND_H +#define INTELGLMALLOCWORKAROUND_H + +#include + +class IntelGLMallocWorkaround +{ +public: + static IntelGLMallocWorkaround *Get(); + bool Enable(); + +protected: + IntelGLMallocWorkaround() :m_pfnMallocReentry(NULL) {} + ~IntelGLMallocWorkaround() {} + + static IntelGLMallocWorkaround *s_pWorkaround; + static void* ZeroingAlloc(size_t); + + typedef void* (*pfnMalloc_t)(size_t); + pfnMalloc_t m_pfnMallocReentry; +}; + +#endif // INTELGLMALLOCWORKAROUND_H \ No newline at end of file diff --git a/togles/linuxwin/mach_override.c b/togles/linuxwin/mach_override.c new file mode 100644 index 00000000..76302767 --- /dev/null +++ b/togles/linuxwin/mach_override.c @@ -0,0 +1,765 @@ +// mach_override.c semver:1.2.0 +// Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com +// Some rights reserved: http://opensource.org/licenses/mit +// https://github.com/rentzsch/mach_override + +#include "mach_override.h" + +#include +#include +#include +#include +#include +#include + +#include + +/************************** +* +* Constants +* +**************************/ +#pragma mark - +#pragma mark (Constants) + +#define kPageSize 4096 +#if defined(__ppc__) || defined(__POWERPC__) + +long kIslandTemplate[] = { + 0x9001FFFC, // stw r0,-4(SP) + 0x3C00DEAD, // lis r0,0xDEAD + 0x6000BEEF, // ori r0,r0,0xBEEF + 0x7C0903A6, // mtctr r0 + 0x8001FFFC, // lwz r0,-4(SP) + 0x60000000, // nop ; optionally replaced + 0x4E800420 // bctr +}; + +#define kAddressHi 3 +#define kAddressLo 5 +#define kInstructionHi 10 +#define kInstructionLo 11 + +#elif defined(__i386__) + +#define kOriginalInstructionsSize 16 +// On X86 we migh need to instert an add with a 32 bit immediate after the +// original instructions. +#define kMaxFixupSizeIncrease 5 + +unsigned char kIslandTemplate[] = { + // kOriginalInstructionsSize nop instructions so that we + // should have enough space to host original instructions + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + // Now the real jump instruction + 0xE9, 0xEF, 0xBE, 0xAD, 0xDE +}; + +#define kInstructions 0 +#define kJumpAddress kInstructions + kOriginalInstructionsSize + 1 +#elif defined(__x86_64__) + +#define kOriginalInstructionsSize 32 +// On X86-64 we never need to instert a new instruction. +#define kMaxFixupSizeIncrease 0 + +#define kJumpAddress kOriginalInstructionsSize + 6 + +unsigned char kIslandTemplate[] = { + // kOriginalInstructionsSize nop instructions so that we + // should have enough space to host original instructions + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + // Now the real jump instruction + 0xFF, 0x25, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 +}; + +#endif + +/************************** +* +* Data Types +* +**************************/ +#pragma mark - +#pragma mark (Data Types) + +typedef struct { + char instructions[sizeof(kIslandTemplate)]; +} BranchIsland; + +/************************** +* +* Funky Protos +* +**************************/ +#pragma mark - +#pragma mark (Funky Protos) + +static mach_error_t +allocateBranchIsland( + BranchIsland **island, + void *originalFunctionAddress); + + mach_error_t +freeBranchIsland( + BranchIsland *island ); + +#if defined(__ppc__) || defined(__POWERPC__) + mach_error_t +setBranchIslandTarget( + BranchIsland *island, + const void *branchTo, + long instruction ); +#endif + +#if defined(__i386__) || defined(__x86_64__) +mach_error_t +setBranchIslandTarget_i386( + BranchIsland *island, + const void *branchTo, + char* instructions ); +void +atomic_mov64( + uint64_t *targetAddress, + uint64_t value ); + + static Boolean +eatKnownInstructions( + unsigned char *code, + uint64_t *newInstruction, + int *howManyEaten, + char *originalInstructions, + int *originalInstructionCount, + uint8_t *originalInstructionSizes ); + + static void +fixupInstructions( + uint32_t offset, + void *instructionsToFix, + int instructionCount, + uint8_t *instructionSizes ); +#endif + +/******************************************************************************* +* +* Interface +* +*******************************************************************************/ +#pragma mark - +#pragma mark (Interface) + +#if defined(__i386__) || defined(__x86_64__) +mach_error_t makeIslandExecutable(void *address) { + mach_error_t err = err_none; + uintptr_t page = (uintptr_t)address & ~(uintptr_t)(kPageSize-1); + int e = err_none; + e |= mprotect((void *)page, kPageSize, PROT_EXEC | PROT_READ | PROT_WRITE); + e |= msync((void *)page, kPageSize, MS_INVALIDATE ); + if (e) { + err = err_cannot_override; + } + return err; +} +#endif + + mach_error_t +mach_override_ptr( + void *originalFunctionAddress, + const void *overrideFunctionAddress, + void **originalFunctionReentryIsland ) +{ + assert( originalFunctionAddress ); + assert( overrideFunctionAddress ); + + // this addresses overriding such functions as AudioOutputUnitStart() + // test with modified DefaultOutputUnit project +#if defined(__x86_64__) + for(;;){ + if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp qword near [rip+0x????????] + originalFunctionAddress=*(void**)((char*)originalFunctionAddress+6+*(int32_t *)((uint16_t*)originalFunctionAddress+1)); + else break; + } +#elif defined(__i386__) + for(;;){ + if(*(uint16_t*)originalFunctionAddress==0x25FF) // jmp *0x???????? + originalFunctionAddress=**(void***)((uint16_t*)originalFunctionAddress+1); + else break; + } +#endif + + long *originalFunctionPtr = (long*) originalFunctionAddress; + mach_error_t err = err_none; + +#if defined(__ppc__) || defined(__POWERPC__) + // Ensure first instruction isn't 'mfctr'. + #define kMFCTRMask 0xfc1fffff + #define kMFCTRInstruction 0x7c0903a6 + + long originalInstruction = *originalFunctionPtr; + if( !err && ((originalInstruction & kMFCTRMask) == kMFCTRInstruction) ) + err = err_cannot_override; +#elif defined(__i386__) || defined(__x86_64__) + int eatenCount = 0; + int originalInstructionCount = 0; + char originalInstructions[kOriginalInstructionsSize]; + uint8_t originalInstructionSizes[kOriginalInstructionsSize]; + uint64_t jumpRelativeInstruction = 0; // JMP + + Boolean overridePossible = eatKnownInstructions ((unsigned char *)originalFunctionPtr, + &jumpRelativeInstruction, &eatenCount, + originalInstructions, &originalInstructionCount, + originalInstructionSizes ); + if (eatenCount + kMaxFixupSizeIncrease > kOriginalInstructionsSize) { + //printf ("Too many instructions eaten\n"); + overridePossible = false; + } + if (!overridePossible) err = err_cannot_override; + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); +#endif + + // Make the original function implementation writable. + if( !err ) { + err = vm_protect( mach_task_self(), + (vm_address_t) originalFunctionPtr, 8, false, + (VM_PROT_ALL | VM_PROT_COPY) ); + if( err ) + err = vm_protect( mach_task_self(), + (vm_address_t) originalFunctionPtr, 8, false, + (VM_PROT_DEFAULT | VM_PROT_COPY) ); + } + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); + + // Allocate and target the escape island to the overriding function. + BranchIsland *escapeIsland = NULL; + if( !err ) + err = allocateBranchIsland( &escapeIsland, originalFunctionAddress ); + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); + + +#if defined(__ppc__) || defined(__POWERPC__) + if( !err ) + err = setBranchIslandTarget( escapeIsland, overrideFunctionAddress, 0 ); + + // Build the branch absolute instruction to the escape island. + long branchAbsoluteInstruction = 0; // Set to 0 just to silence warning. + if( !err ) { + long escapeIslandAddress = ((long) escapeIsland) & 0x3FFFFFF; + branchAbsoluteInstruction = 0x48000002 | escapeIslandAddress; + } +#elif defined(__i386__) || defined(__x86_64__) + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); + + if( !err ) + err = setBranchIslandTarget_i386( escapeIsland, overrideFunctionAddress, 0 ); + + if (err) fprintf(stderr, "err = %x %s:%d\n", err, __FILE__, __LINE__); + // Build the jump relative instruction to the escape island +#endif + + +#if defined(__i386__) || defined(__x86_64__) + if (!err) { + uint32_t addressOffset = ((char*)escapeIsland - (char*)originalFunctionPtr - 5); + addressOffset = OSSwapInt32(addressOffset); + + jumpRelativeInstruction |= 0xE900000000000000LL; + jumpRelativeInstruction |= ((uint64_t)addressOffset & 0xffffffff) << 24; + jumpRelativeInstruction = OSSwapInt64(jumpRelativeInstruction); + } +#endif + + // Optionally allocate & return the reentry island. This may contain relocated + // jmp instructions and so has all the same addressing reachability requirements + // the escape island has to the original function, except the escape island is + // technically our original function. + BranchIsland *reentryIsland = NULL; + if( !err && originalFunctionReentryIsland ) { + err = allocateBranchIsland( &reentryIsland, escapeIsland); + if( !err ) + *originalFunctionReentryIsland = reentryIsland; + } + +#if defined(__ppc__) || defined(__POWERPC__) + // Atomically: + // o If the reentry island was allocated: + // o Insert the original instruction into the reentry island. + // o Target the reentry island at the 2nd instruction of the + // original function. + // o Replace the original instruction with the branch absolute. + if( !err ) { + int escapeIslandEngaged = false; + do { + if( reentryIsland ) + err = setBranchIslandTarget( reentryIsland, + (void*) (originalFunctionPtr+1), originalInstruction ); + if( !err ) { + escapeIslandEngaged = CompareAndSwap( originalInstruction, + branchAbsoluteInstruction, + (UInt32*)originalFunctionPtr ); + if( !escapeIslandEngaged ) { + // Someone replaced the instruction out from under us, + // re-read the instruction, make sure it's still not + // 'mfctr' and try again. + originalInstruction = *originalFunctionPtr; + if( (originalInstruction & kMFCTRMask) == kMFCTRInstruction) + err = err_cannot_override; + } + } + } while( !err && !escapeIslandEngaged ); + } +#elif defined(__i386__) || defined(__x86_64__) + // Atomically: + // o If the reentry island was allocated: + // o Insert the original instructions into the reentry island. + // o Target the reentry island at the first non-replaced + // instruction of the original function. + // o Replace the original first instructions with the jump relative. + // + // Note that on i386, we do not support someone else changing the code under our feet + if ( !err ) { + uint32_t offset = (uintptr_t)originalFunctionPtr - (uintptr_t)reentryIsland; + fixupInstructions(offset, originalInstructions, + originalInstructionCount, originalInstructionSizes ); + + if( reentryIsland ) + err = setBranchIslandTarget_i386( reentryIsland, + (void*) ((char *)originalFunctionPtr+eatenCount), originalInstructions ); + // try making islands executable before planting the jmp +#if defined(__x86_64__) || defined(__i386__) + if( !err ) + err = makeIslandExecutable(escapeIsland); + if( !err && reentryIsland ) + err = makeIslandExecutable(reentryIsland); +#endif + if ( !err ) + atomic_mov64((uint64_t *)originalFunctionPtr, jumpRelativeInstruction); + } +#endif + + // Clean up on error. + if( err ) { + if( reentryIsland ) + freeBranchIsland( reentryIsland ); + if( escapeIsland ) + freeBranchIsland( escapeIsland ); + } + + return err; +} + +/******************************************************************************* +* +* Implementation +* +*******************************************************************************/ +#pragma mark - +#pragma mark (Implementation) + +static bool jump_in_range(intptr_t from, intptr_t to) { + intptr_t field_value = to - from - 5; + int32_t field_value_32 = field_value; + return field_value == field_value_32; +} + +/******************************************************************************* + Implementation: Allocates memory for a branch island. + + @param island <- The allocated island. + @result <- mach_error_t + + ***************************************************************************/ + +static mach_error_t +allocateBranchIslandAux( + BranchIsland **island, + void *originalFunctionAddress, + bool forward) +{ + assert( island ); + assert( sizeof( BranchIsland ) <= kPageSize ); + + vm_map_t task_self = mach_task_self(); + vm_address_t original_address = (vm_address_t) originalFunctionAddress; + vm_address_t address = original_address; + + for (;;) { + vm_size_t vmsize = 0; + memory_object_name_t object = 0; + kern_return_t kr = 0; + vm_region_flavor_t flavor = VM_REGION_BASIC_INFO; + // Find the region the address is in. +#if __WORDSIZE == 32 + vm_region_basic_info_data_t info; + mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT; + kr = vm_region(task_self, &address, &vmsize, flavor, + (vm_region_info_t)&info, &info_count, &object); +#else + vm_region_basic_info_data_64_t info; + mach_msg_type_number_t info_count = VM_REGION_BASIC_INFO_COUNT_64; + kr = vm_region_64(task_self, &address, &vmsize, flavor, + (vm_region_info_t)&info, &info_count, &object); +#endif + if (kr != KERN_SUCCESS) + return kr; + assert((address & (kPageSize - 1)) == 0); + + // Go to the first page before or after this region + vm_address_t new_address = forward ? address + vmsize : address - kPageSize; +#if __WORDSIZE == 64 + if(!jump_in_range(original_address, new_address)) + break; +#endif + address = new_address; + + // Try to allocate this page. + kr = vm_allocate(task_self, &address, kPageSize, 0); + if (kr == KERN_SUCCESS) { + *island = (BranchIsland*) address; + return err_none; + } + if (kr != KERN_NO_SPACE) + return kr; + } + + return KERN_NO_SPACE; +} + +static mach_error_t +allocateBranchIsland( + BranchIsland **island, + void *originalFunctionAddress) +{ + mach_error_t err = + allocateBranchIslandAux(island, originalFunctionAddress, true); + if (!err) + return err; + return allocateBranchIslandAux(island, originalFunctionAddress, false); +} + + +/******************************************************************************* + Implementation: Deallocates memory for a branch island. + + @param island -> The island to deallocate. + @result <- mach_error_t + + ***************************************************************************/ + + mach_error_t +freeBranchIsland( + BranchIsland *island ) +{ + assert( island ); + assert( (*(long*)&island->instructions[0]) == kIslandTemplate[0] ); + assert( sizeof( BranchIsland ) <= kPageSize ); + return vm_deallocate( mach_task_self(), (vm_address_t) island, + kPageSize ); +} + +/******************************************************************************* + Implementation: Sets the branch island's target, with an optional + instruction. + + @param island -> The branch island to insert target into. + @param branchTo -> The address of the target. + @param instruction -> Optional instruction to execute prior to branch. Set + to zero for nop. + @result <- mach_error_t + + ***************************************************************************/ +#if defined(__ppc__) || defined(__POWERPC__) + mach_error_t +setBranchIslandTarget( + BranchIsland *island, + const void *branchTo, + long instruction ) +{ + // Copy over the template code. + bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); + + // Fill in the address. + ((short*)island->instructions)[kAddressLo] = ((long) branchTo) & 0x0000FFFF; + ((short*)island->instructions)[kAddressHi] + = (((long) branchTo) >> 16) & 0x0000FFFF; + + // Fill in the (optional) instuction. + if( instruction != 0 ) { + ((short*)island->instructions)[kInstructionLo] + = instruction & 0x0000FFFF; + ((short*)island->instructions)[kInstructionHi] + = (instruction >> 16) & 0x0000FFFF; + } + + //MakeDataExecutable( island->instructions, sizeof( kIslandTemplate ) ); + msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); + + return err_none; +} +#endif + +#if defined(__i386__) + mach_error_t +setBranchIslandTarget_i386( + BranchIsland *island, + const void *branchTo, + char* instructions ) +{ + + // Copy over the template code. + bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); + + // copy original instructions + if (instructions) { + bcopy (instructions, island->instructions + kInstructions, kOriginalInstructionsSize); + } + + // Fill in the address. + int32_t addressOffset = (char *)branchTo - (island->instructions + kJumpAddress + 4); + *((int32_t *)(island->instructions + kJumpAddress)) = addressOffset; + + msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); + return err_none; +} + +#elif defined(__x86_64__) +mach_error_t +setBranchIslandTarget_i386( + BranchIsland *island, + const void *branchTo, + char* instructions ) +{ + // Copy over the template code. + bcopy( kIslandTemplate, island->instructions, sizeof( kIslandTemplate ) ); + + // Copy original instructions. + if (instructions) { + bcopy (instructions, island->instructions, kOriginalInstructionsSize); + } + + // Fill in the address. + *((uint64_t *)(island->instructions + kJumpAddress)) = (uint64_t)branchTo; + msync( island->instructions, sizeof( kIslandTemplate ), MS_INVALIDATE ); + + return err_none; +} +#endif + + +#if defined(__i386__) || defined(__x86_64__) +// simplistic instruction matching +typedef struct { + unsigned int length; // max 15 + unsigned char mask[15]; // sequence of bytes in memory order + unsigned char constraint[15]; // sequence of bytes in memory order +} AsmInstructionMatch; + +#if defined(__i386__) +static AsmInstructionMatch possibleInstructions[] = { + { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xE9, 0x00, 0x00, 0x00, 0x00} }, // jmp 0x???????? + { 0x5, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0x55, 0x89, 0xe5, 0xc9, 0xc3} }, // push %ebp; mov %esp,%ebp; leave; ret + { 0x1, {0xFF}, {0x90} }, // nop + { 0x1, {0xFF}, {0x55} }, // push %esp + { 0x2, {0xFF, 0xFF}, {0x89, 0xE5} }, // mov %esp,%ebp + { 0x1, {0xFF}, {0x53} }, // push %ebx + { 0x3, {0xFF, 0xFF, 0x00}, {0x83, 0xEC, 0x00} }, // sub 0x??, %esp + { 0x6, {0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}, {0x81, 0xEC, 0x00, 0x00, 0x00, 0x00} }, // sub 0x??, %esp with 32bit immediate + { 0x1, {0xFF}, {0x57} }, // push %edi + { 0x1, {0xFF}, {0x56} }, // push %esi + { 0x2, {0xFF, 0xFF}, {0x31, 0xC0} }, // xor %eax, %eax + { 0x3, {0xFF, 0x4F, 0x00}, {0x8B, 0x45, 0x00} }, // mov $imm(%ebp), %reg + { 0x3, {0xFF, 0x4C, 0x00}, {0x8B, 0x40, 0x00} }, // mov $imm(%eax-%edx), %reg + { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x8B, 0x4C, 0x24, 0x00} }, // mov $imm(%esp), %ecx + { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00, 0x00} }, // mov $imm, %eax + { 0x6, {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}, {0xE8, 0x00, 0x00, 0x00, 0x00, 0x58} }, // call $imm; pop %eax + { 0x0 } +}; +#elif defined(__x86_64__) +static AsmInstructionMatch possibleInstructions[] = { + { 0x5, {0xFF, 0x00, 0x00, 0x00, 0x00}, {0xE9, 0x00, 0x00, 0x00, 0x00} }, // jmp 0x???????? + { 0x1, {0xFF}, {0x90} }, // nop + { 0x1, {0xF8}, {0x50} }, // push %rX + { 0x3, {0xFF, 0xFF, 0xFF}, {0x48, 0x89, 0xE5} }, // mov %rsp,%rbp + { 0x4, {0xFF, 0xFF, 0xFF, 0x00}, {0x48, 0x83, 0xEC, 0x00} }, // sub 0x??, %rsp + { 0x4, {0xFB, 0xFF, 0x00, 0x00}, {0x48, 0x89, 0x00, 0x00} }, // move onto rbp + { 0x4, {0xFF, 0xFF, 0xFF, 0xFF}, {0x40, 0x0f, 0xbe, 0xce} }, // movsbl %sil, %ecx + { 0x2, {0xFF, 0x00}, {0x41, 0x00} }, // push %rXX + { 0x2, {0xFF, 0x00}, {0x85, 0x00} }, // test %rX,%rX + { 0x5, {0xF8, 0x00, 0x00, 0x00, 0x00}, {0xB8, 0x00, 0x00, 0x00, 0x00} }, // mov $imm, %reg + { 0x3, {0xFF, 0xFF, 0x00}, {0xFF, 0x77, 0x00} }, // pushq $imm(%rdi) + { 0x2, {0xFF, 0xFF}, {0x31, 0xC0} }, // xor %eax, %eax + { 0x2, {0xFF, 0xFF}, {0x89, 0xF8} }, // mov %edi, %eax + + //leaq offset(%rip),%rax + { 0x7, {0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00}, {0x48, 0x8d, 0x05, 0x00, 0x00, 0x00, 0x00} }, + + { 0x0 } +}; +#endif + +static Boolean codeMatchesInstruction(unsigned char *code, AsmInstructionMatch* instruction) +{ + Boolean match = true; + + size_t i; + for (i=0; ilength; i++) { + unsigned char mask = instruction->mask[i]; + unsigned char constraint = instruction->constraint[i]; + unsigned char codeValue = code[i]; + + match = ((codeValue & mask) == constraint); + if (!match) break; + } + + return match; +} + +#if defined(__i386__) || defined(__x86_64__) + static Boolean +eatKnownInstructions( + unsigned char *code, + uint64_t *newInstruction, + int *howManyEaten, + char *originalInstructions, + int *originalInstructionCount, + uint8_t *originalInstructionSizes ) +{ + Boolean allInstructionsKnown = true; + int totalEaten = 0; + unsigned char* ptr = code; + int remainsToEat = 5; // a JMP instruction takes 5 bytes + int instructionIndex = 0; + + if (howManyEaten) *howManyEaten = 0; + if (originalInstructionCount) *originalInstructionCount = 0; + while (remainsToEat > 0) { + Boolean curInstructionKnown = false; + + // See if instruction matches one we know + AsmInstructionMatch* curInstr = possibleInstructions; + do { + if ((curInstructionKnown = codeMatchesInstruction(ptr, curInstr))) break; + curInstr++; + } while (curInstr->length > 0); + + // if all instruction matches failed, we don't know current instruction then, stop here + if (!curInstructionKnown) { + allInstructionsKnown = false; + fprintf(stderr, "mach_override: some instructions unknown! Need to update mach_override.c\n"); + break; + } + + // At this point, we've matched curInstr + int eaten = curInstr->length; + ptr += eaten; + remainsToEat -= eaten; + totalEaten += eaten; + + if (originalInstructionSizes) originalInstructionSizes[instructionIndex] = eaten; + instructionIndex += 1; + if (originalInstructionCount) *originalInstructionCount = instructionIndex; + } + + + if (howManyEaten) *howManyEaten = totalEaten; + + if (originalInstructions) { + Boolean enoughSpaceForOriginalInstructions = (totalEaten < kOriginalInstructionsSize); + + if (enoughSpaceForOriginalInstructions) { + memset(originalInstructions, 0x90 /* NOP */, kOriginalInstructionsSize); // fill instructions with NOP + bcopy(code, originalInstructions, totalEaten); + } else { + // printf ("Not enough space in island to store original instructions. Adapt the island definition and kOriginalInstructionsSize\n"); + return false; + } + } + + if (allInstructionsKnown) { + // save last 3 bytes of first 64bits of codre we'll replace + uint64_t currentFirst64BitsOfCode = *((uint64_t *)code); + currentFirst64BitsOfCode = OSSwapInt64(currentFirst64BitsOfCode); // back to memory representation + currentFirst64BitsOfCode &= 0x0000000000FFFFFFLL; + + // keep only last 3 instructions bytes, first 5 will be replaced by JMP instr + *newInstruction &= 0xFFFFFFFFFF000000LL; // clear last 3 bytes + *newInstruction |= (currentFirst64BitsOfCode & 0x0000000000FFFFFFLL); // set last 3 bytes + } + + return allInstructionsKnown; +} + + static void +fixupInstructions( + uint32_t offset, + void *instructionsToFix, + int instructionCount, + uint8_t *instructionSizes ) +{ + // The start of "leaq offset(%rip),%rax" + static const uint8_t LeaqHeader[] = {0x48, 0x8d, 0x05}; + + int index; + for (index = 0;index < instructionCount;index += 1) + { + if (*(uint8_t*)instructionsToFix == 0xE9) // 32-bit jump relative + { + uint32_t *jumpOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 1); + *jumpOffsetPtr += offset; + } + + // leaq offset(%rip),%rax + if (memcmp(instructionsToFix, LeaqHeader, 3) == 0) { + uint32_t *LeaqOffsetPtr = (uint32_t*)((uintptr_t)instructionsToFix + 3); + *LeaqOffsetPtr += offset; + } + + // 32-bit call relative to the next addr; pop %eax + if (*(uint8_t*)instructionsToFix == 0xE8) + { + // Just this call is larger than the jump we use, so we + // know this is the last instruction. + assert(index == (instructionCount - 1)); + assert(instructionSizes[index] == 6); + + // Insert "addl $offset, %eax" in the end so that when + // we jump to the rest of the function %eax has the + // value it would have if eip had been pushed by the + // call in its original position. + uint8_t *op = (uint8_t*)instructionsToFix; + op += 6; + *op = 0x05; // addl + uint32_t *addImmPtr = (uint32_t*)(op + 1); + *addImmPtr = offset; + } + + instructionsToFix = (void*)((uintptr_t)instructionsToFix + instructionSizes[index]); + } +} +#endif + +#if defined(__i386__) +void atomic_mov64( + uint64_t *targetAddress, + uint64_t value) +{ + while (true) + { + uint64_t old_value = *targetAddress; + if (OSAtomicCompareAndSwap64(old_value, value, (int64_t*)targetAddress)) return; + } +} +#elif defined(__x86_64__) +void atomic_mov64( + uint64_t *targetAddress, + uint64_t value ) +{ + *targetAddress = value; +} +#endif +#endif diff --git a/togles/linuxwin/mach_override.h b/togles/linuxwin/mach_override.h new file mode 100644 index 00000000..ecd319c1 --- /dev/null +++ b/togles/linuxwin/mach_override.h @@ -0,0 +1,76 @@ +// mach_override.h semver:1.2.0 +// Copyright (c) 2003-2012 Jonathan 'Wolf' Rentzsch: http://rentzsch.com +// Some rights reserved: http://opensource.org/licenses/mit +// https://github.com/rentzsch/mach_override + +#ifndef _mach_override_ +#define _mach_override_ + +#include +#include + +#define err_cannot_override (err_local|1) + +__BEGIN_DECLS + +/**************************************************************************************** + Dynamically overrides the function implementation referenced by + originalFunctionAddress with the implentation pointed to by overrideFunctionAddress. + Optionally returns a pointer to a "reentry island" which, if jumped to, will resume + the original implementation. + + @param originalFunctionAddress -> Required address of the function to + override (with overrideFunctionAddress). + @param overrideFunctionAddress -> Required address to the overriding + function. + @param originalFunctionReentryIsland <- Optional pointer to pointer to the + reentry island. Can be NULL. + @result <- err_cannot_override if the original + function's implementation begins with + the 'mfctr' instruction. + + ************************************************************************************/ + + mach_error_t +mach_override_ptr( + void *originalFunctionAddress, + const void *overrideFunctionAddress, + void **originalFunctionReentryIsland ); + +__END_DECLS + +/**************************************************************************************** + If you're using C++ this macro will ease the tedium of typedef'ing, naming, keeping + track of reentry islands and defining your override code. See test_mach_override.cp + for example usage. + + ************************************************************************************/ + +#ifdef __cplusplus +#define MACH_OVERRIDE( ORIGINAL_FUNCTION_RETURN_TYPE, ORIGINAL_FUNCTION_NAME, ORIGINAL_FUNCTION_ARGS, ERR ) \ +{ \ + static ORIGINAL_FUNCTION_RETURN_TYPE (*ORIGINAL_FUNCTION_NAME##_reenter)ORIGINAL_FUNCTION_ARGS; \ + static bool ORIGINAL_FUNCTION_NAME##_overriden = false; \ + class mach_override_class__##ORIGINAL_FUNCTION_NAME { \ + public: \ + static kern_return_t override(void *originalFunctionPtr) { \ + kern_return_t result = err_none; \ + if (!ORIGINAL_FUNCTION_NAME##_overriden) { \ + ORIGINAL_FUNCTION_NAME##_overriden = true; \ + result = mach_override_ptr( (void*)originalFunctionPtr, \ + (void*)mach_override_class__##ORIGINAL_FUNCTION_NAME::replacement, \ + (void**)&ORIGINAL_FUNCTION_NAME##_reenter ); \ + } \ + return result; \ + } \ + static ORIGINAL_FUNCTION_RETURN_TYPE replacement ORIGINAL_FUNCTION_ARGS { + +#define END_MACH_OVERRIDE( ORIGINAL_FUNCTION_NAME ) \ + } \ + }; \ + \ + err = mach_override_class__##ORIGINAL_FUNCTION_NAME::override((void*)ORIGINAL_FUNCTION_NAME); \ +} +#endif + +#endif // _mach_override_ diff --git a/togles/linuxwin/stb_dxt_104.h b/togles/linuxwin/stb_dxt_104.h new file mode 100644 index 00000000..bec72798 --- /dev/null +++ b/togles/linuxwin/stb_dxt_104.h @@ -0,0 +1,624 @@ +// stb_dxt.h - v1.04 - DXT1/DXT5 compressor - public domain +// original by fabian "ryg" giesen - ported to C by stb +// use '#define STB_DXT_IMPLEMENTATION' before including to create the implementation +// +// USAGE: +// call stb_compress_dxt_block() for every block (you must pad) +// source should be a 4x4 block of RGBA data in row-major order; +// A is ignored if you specify alpha=0; you can turn on dithering +// and "high quality" using mode. +// +// version history: +// v1.04 - (ryg) default to no rounding bias for lerped colors (as per S3TC/DX10 spec); +// single color match fix (allow for inexact color interpolation); +// optimal DXT5 index finder; "high quality" mode that runs multiple refinement steps. +// v1.03 - (stb) endianness support +// v1.02 - (stb) fix alpha encoding bug +// v1.01 - (stb) fix bug converting to RGB that messed up quality, thanks ryg & cbloom +// v1.00 - (stb) first release + +#ifndef STB_INCLUDE_STB_DXT_H +#define STB_INCLUDE_STB_DXT_H + +// compression mode (bitflags) +#define STB_DXT_NORMAL 0 +#define STB_DXT_DITHER 1 // use dithering. dubious win. never use for normal maps and the like! +#define STB_DXT_HIGHQUAL 2 // high quality mode, does two refinement steps instead of 1. ~30-40% slower. + +void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode); +#define STB_COMPRESS_DXT_BLOCK + +#ifdef STB_DXT_IMPLEMENTATION + +// configuration options for DXT encoder. set them in the project/makefile or just define +// them at the top. + +// STB_DXT_USE_ROUNDING_BIAS +// use a rounding bias during color interpolation. this is closer to what "ideal" +// interpolation would do but doesn't match the S3TC/DX10 spec. old versions (pre-1.03) +// implicitly had this turned on. +// +// in case you're targeting a specific type of hardware (e.g. console programmers): +// NVidia and Intel GPUs (as of 2010) as well as DX9 ref use DXT decoders that are closer +// to STB_DXT_USE_ROUNDING_BIAS. AMD/ATI, S3 and DX10 ref are closer to rounding with no bias. +// you also see "(a*5 + b*3) / 8" on some old GPU designs. +// #define STB_DXT_USE_ROUNDING_BIAS + +#include +#include +#include // memset + +static unsigned char stb__Expand5[32]; +static unsigned char stb__Expand6[64]; +static unsigned char stb__OMatch5[256][2]; +static unsigned char stb__OMatch6[256][2]; +static unsigned char stb__QuantRBTab[256+16]; +static unsigned char stb__QuantGTab[256+16]; + +static int stb__Mul8Bit(int a, int b) +{ + int t = a*b + 128; + return (t + (t >> 8)) >> 8; +} + +static void stb__From16Bit(unsigned char *out, unsigned short v) +{ + int rv = (v & 0xf800) >> 11; + int gv = (v & 0x07e0) >> 5; + int bv = (v & 0x001f) >> 0; + + out[0] = stb__Expand5[rv]; + out[1] = stb__Expand6[gv]; + out[2] = stb__Expand5[bv]; + out[3] = 0; +} + +static unsigned short stb__As16Bit(int r, int g, int b) +{ + return (stb__Mul8Bit(r,31) << 11) + (stb__Mul8Bit(g,63) << 5) + stb__Mul8Bit(b,31); +} + +// linear interpolation at 1/3 point between a and b, using desired rounding type +static int stb__Lerp13(int a, int b) +{ +#ifdef STB_DXT_USE_ROUNDING_BIAS + // with rounding bias + return a + stb__Mul8Bit(b-a, 0x55); +#else + // without rounding bias + // replace "/ 3" by "* 0xaaab) >> 17" if your compiler sucks or you really need every ounce of speed. + return (2*a + b) / 3; +#endif +} + +// lerp RGB color +static void stb__Lerp13RGB(unsigned char *out, unsigned char *p1, unsigned char *p2) +{ + out[0] = stb__Lerp13(p1[0], p2[0]); + out[1] = stb__Lerp13(p1[1], p2[1]); + out[2] = stb__Lerp13(p1[2], p2[2]); +} + +/****************************************************************************/ + +// compute table to reproduce constant colors as accurately as possible +static void stb__PrepareOptTable(unsigned char *Table,const unsigned char *expand,int size) +{ + int i,mn,mx; + for (i=0;i<256;i++) { + int bestErr = 256; + for (mn=0;mn> 4)]; + ep1[0] = bp[ 0] - dp[ 0]; + dp[ 4] = quant[bp[ 4] + ((7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]) >> 4)]; + ep1[1] = bp[ 4] - dp[ 4]; + dp[ 8] = quant[bp[ 8] + ((7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]) >> 4)]; + ep1[2] = bp[ 8] - dp[ 8]; + dp[12] = quant[bp[12] + ((7*ep1[2] + 5*ep2[3] + ep2[2]) >> 4)]; + ep1[3] = bp[12] - dp[12]; + bp += 16; + dp += 16; + et = ep1, ep1 = ep2, ep2 = et; // swap + } + } +} + +// The color matching function +static unsigned int stb__MatchColorsBlock(unsigned char *block, unsigned char *color,int dither) +{ + unsigned int mask = 0; + int dirr = color[0*4+0] - color[1*4+0]; + int dirg = color[0*4+1] - color[1*4+1]; + int dirb = color[0*4+2] - color[1*4+2]; + int dots[16]; + int stops[4]; + int i; + int c0Point, halfPoint, c3Point; + + for(i=0;i<16;i++) + dots[i] = block[i*4+0]*dirr + block[i*4+1]*dirg + block[i*4+2]*dirb; + + for(i=0;i<4;i++) + stops[i] = color[i*4+0]*dirr + color[i*4+1]*dirg + color[i*4+2]*dirb; + + // think of the colors as arranged on a line; project point onto that line, then choose + // next color out of available ones. we compute the crossover points for "best color in top + // half"/"best in bottom half" and then the same inside that subinterval. + // + // relying on this 1d approximation isn't always optimal in terms of euclidean distance, + // but it's very close and a lot faster. + // http://cbloomrants.blogspot.com/2008/12/12-08-08-dxtc-summary.html + + c0Point = (stops[1] + stops[3]) >> 1; + halfPoint = (stops[3] + stops[2]) >> 1; + c3Point = (stops[2] + stops[0]) >> 1; + + if(!dither) { + // the version without dithering is straightforward + for (i=15;i>=0;i--) { + int dot = dots[i]; + mask <<= 2; + + if(dot < halfPoint) + mask |= (dot < c0Point) ? 1 : 3; + else + mask |= (dot < c3Point) ? 2 : 0; + } + } else { + // with floyd-steinberg dithering + int err[8],*ep1 = err,*ep2 = err+4; + int *dp = dots, y; + + c0Point <<= 4; + halfPoint <<= 4; + c3Point <<= 4; + for(i=0;i<8;i++) + err[i] = 0; + + for(y=0;y<4;y++) + { + int dot,lmask,step; + + dot = (dp[0] << 4) + (3*ep2[1] + 5*ep2[0]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[0] = dp[0] - stops[step]; + lmask = step; + + dot = (dp[1] << 4) + (7*ep1[0] + 3*ep2[2] + 5*ep2[1] + ep2[0]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[1] = dp[1] - stops[step]; + lmask |= step<<2; + + dot = (dp[2] << 4) + (7*ep1[1] + 3*ep2[3] + 5*ep2[2] + ep2[1]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[2] = dp[2] - stops[step]; + lmask |= step<<4; + + dot = (dp[3] << 4) + (7*ep1[2] + 5*ep2[3] + ep2[2]); + if(dot < halfPoint) + step = (dot < c0Point) ? 1 : 3; + else + step = (dot < c3Point) ? 2 : 0; + ep1[3] = dp[3] - stops[step]; + lmask |= step<<6; + + dp += 4; + mask |= lmask << (y*8); + { int *et = ep1; ep1 = ep2; ep2 = et; } // swap + } + } + + return mask; +} + +// The color optimization function. (Clever code, part 1) +static void stb__OptimizeColorsBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16) +{ + int mind = 0x7fffffff,maxd = -0x7fffffff; + unsigned char *minp, *maxp; + double magn; + int v_r,v_g,v_b; + static const int nIterPower = 4; + float covf[6],vfr,vfg,vfb; + + // determine color distribution + int cov[6]; + int mu[3],min[3],max[3]; + int ch,i,iter; + + for(ch=0;ch<3;ch++) + { + const unsigned char *bp = ((const unsigned char *) block) + ch; + int muv,minv,maxv; + + muv = minv = maxv = bp[0]; + for(i=4;i<64;i+=4) + { + muv += bp[i]; + if (bp[i] < minv) minv = bp[i]; + else if (bp[i] > maxv) maxv = bp[i]; + } + + mu[ch] = (muv + 8) >> 4; + min[ch] = minv; + max[ch] = maxv; + } + + // determine covariance matrix + for (i=0;i<6;i++) + cov[i] = 0; + + for (i=0;i<16;i++) + { + int r = block[i*4+0] - mu[0]; + int g = block[i*4+1] - mu[1]; + int b = block[i*4+2] - mu[2]; + + cov[0] += r*r; + cov[1] += r*g; + cov[2] += r*b; + cov[3] += g*g; + cov[4] += g*b; + cov[5] += b*b; + } + + // convert covariance matrix to float, find principal axis via power iter + for(i=0;i<6;i++) + covf[i] = cov[i] / 255.0f; + + vfr = (float) (max[0] - min[0]); + vfg = (float) (max[1] - min[1]); + vfb = (float) (max[2] - min[2]); + + for(iter=0;iter magn) magn = fabs(vfg); + if (fabs(vfb) > magn) magn = fabs(vfb); + + if(magn < 4.0f) { // too small, default to luminance + v_r = 299; // JPEG YCbCr luma coefs, scaled by 1000. + v_g = 587; + v_b = 114; + } else { + magn = 512.0 / magn; + v_r = (int) (vfr * magn); + v_g = (int) (vfg * magn); + v_b = (int) (vfb * magn); + } + + // Pick colors at extreme points + for(i=0;i<16;i++) + { + int dot = block[i*4+0]*v_r + block[i*4+1]*v_g + block[i*4+2]*v_b; + + if (dot < mind) { + mind = dot; + minp = block+i*4; + } + + if (dot > maxd) { + maxd = dot; + maxp = block+i*4; + } + } + + *pmax16 = stb__As16Bit(maxp[0],maxp[1],maxp[2]); + *pmin16 = stb__As16Bit(minp[0],minp[1],minp[2]); +} + +static int stb__sclamp(float y, int p0, int p1) +{ + int x = (int) y; + if (x < p0) return p0; + if (x > p1) return p1; + return x; +} + +// The refinement function. (Clever code, part 2) +// Tries to optimize colors to suit block contents better. +// (By solving a least squares system via normal equations+Cramer's rule) +static int stb__RefineBlock(unsigned char *block, unsigned short *pmax16, unsigned short *pmin16, unsigned int mask) +{ + static const int w1Tab[4] = { 3,0,2,1 }; + static const int prods[4] = { 0x090000,0x000900,0x040102,0x010402 }; + // ^some magic to save a lot of multiplies in the accumulating loop... + // (precomputed products of weights for least squares system, accumulated inside one 32-bit register) + + float frb,fg; + unsigned short oldMin, oldMax, min16, max16; + int i, akku = 0, xx,xy,yy; + int At1_r,At1_g,At1_b; + int At2_r,At2_g,At2_b; + unsigned int cm = mask; + + oldMin = *pmin16; + oldMax = *pmax16; + + if((mask ^ (mask<<2)) < 4) // all pixels have the same index? + { + // yes, linear system would be singular; solve using optimal + // single-color match on average color + int r = 8, g = 8, b = 8; + for (i=0;i<16;++i) { + r += block[i*4+0]; + g += block[i*4+1]; + b += block[i*4+2]; + } + + r >>= 4; g >>= 4; b >>= 4; + + max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0]; + min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1]; + } else { + At1_r = At1_g = At1_b = 0; + At2_r = At2_g = At2_b = 0; + for (i=0;i<16;++i,cm>>=2) { + int step = cm&3; + int w1 = w1Tab[step]; + int r = block[i*4+0]; + int g = block[i*4+1]; + int b = block[i*4+2]; + + akku += prods[step]; + At1_r += w1*r; + At1_g += w1*g; + At1_b += w1*b; + At2_r += r; + At2_g += g; + At2_b += b; + } + + At2_r = 3*At2_r - At1_r; + At2_g = 3*At2_g - At1_g; + At2_b = 3*At2_b - At1_b; + + // extract solutions and decide solvability + xx = akku >> 16; + yy = (akku >> 8) & 0xff; + xy = (akku >> 0) & 0xff; + + frb = 3.0f * 31.0f / 255.0f / (xx*yy - xy*xy); + fg = frb * 63.0f / 31.0f; + + // solve. + max16 = stb__sclamp((At1_r*yy - At2_r*xy)*frb+0.5f,0,31) << 11; + max16 |= stb__sclamp((At1_g*yy - At2_g*xy)*fg +0.5f,0,63) << 5; + max16 |= stb__sclamp((At1_b*yy - At2_b*xy)*frb+0.5f,0,31) << 0; + + min16 = stb__sclamp((At2_r*xx - At1_r*xy)*frb+0.5f,0,31) << 11; + min16 |= stb__sclamp((At2_g*xx - At1_g*xy)*fg +0.5f,0,63) << 5; + min16 |= stb__sclamp((At2_b*xx - At1_b*xy)*frb+0.5f,0,31) << 0; + } + + *pmin16 = min16; + *pmax16 = max16; + return oldMin != min16 || oldMax != max16; +} + +// Color block compression +static void stb__CompressColorBlock(unsigned char *dest, unsigned char *block, int mode) +{ + unsigned int mask; + int i; + int dither; + int refinecount; + unsigned short max16, min16; + unsigned char dblock[16*4],color[4*4]; + + dither = mode & STB_DXT_DITHER; + refinecount = (mode & STB_DXT_HIGHQUAL) ? 2 : 1; + + // check if block is constant + for (i=1;i<16;i++) + if (((unsigned int *) block)[i] != ((unsigned int *) block)[0]) + break; + + if(i == 16) { // constant color + int r = block[0], g = block[1], b = block[2]; + mask = 0xaaaaaaaa; + max16 = (stb__OMatch5[r][0]<<11) | (stb__OMatch6[g][0]<<5) | stb__OMatch5[b][0]; + min16 = (stb__OMatch5[r][1]<<11) | (stb__OMatch6[g][1]<<5) | stb__OMatch5[b][1]; + } else { + // first step: compute dithered version for PCA if desired + if(dither) + stb__DitherBlock(dblock,block); + + // second step: pca+map along principal axis + stb__OptimizeColorsBlock(dither ? dblock : block,&max16,&min16); + if (max16 != min16) { + stb__EvalColors(color,max16,min16); + mask = stb__MatchColorsBlock(block,color,dither); + } else + mask = 0; + + // third step: refine (multiple times if requested) + for (i=0;i> 8); + dest[2] = (unsigned char) (min16); + dest[3] = (unsigned char) (min16 >> 8); + dest[4] = (unsigned char) (mask); + dest[5] = (unsigned char) (mask >> 8); + dest[6] = (unsigned char) (mask >> 16); + dest[7] = (unsigned char) (mask >> 24); +} + +// Alpha block compression (this is easy for a change) +static void stb__CompressAlphaBlock(unsigned char *dest,unsigned char *src,int mode) +{ + int i,dist,bias,dist4,dist2,bits,mask; + + // find min/max color + int mn,mx; + mn = mx = src[3]; + + for (i=1;i<16;i++) + { + if (src[i*4+3] < mn) mn = src[i*4+3]; + else if (src[i*4+3] > mx) mx = src[i*4+3]; + } + + // encode them + ((unsigned char *)dest)[0] = mx; + ((unsigned char *)dest)[1] = mn; + dest += 2; + + // determine bias and emit color indices + // given the choice of mx/mn, these indices are optimal: + // http://fgiesen.wordpress.com/2009/12/15/dxt5-alpha-block-index-determination/ + dist = mx-mn; + dist4 = dist*4; + dist2 = dist*2; + bias = (dist < 8) ? (dist - 1) : (dist/2 + 2); + bias -= mn * 7; + bits = 0,mask=0; + + for (i=0;i<16;i++) { + int a = src[i*4+3]*7 + bias; + int ind,t; + + // select index. this is a "linear scale" lerp factor between 0 (val=min) and 7 (val=max). + t = (a >= dist4) ? -1 : 0; ind = t & 4; a -= dist4 & t; + t = (a >= dist2) ? -1 : 0; ind += t & 2; a -= dist2 & t; + ind += (a >= dist); + + // turn linear scale into DXT index (0/1 are extremal pts) + ind = -ind & 7; + ind ^= (2 > ind); + + // write index + mask |= ind << bits; + if((bits += 3) >= 8) { + *dest++ = mask; + mask >>= 8; + bits -= 8; + } + } +} + +static void stb__InitDXT() +{ + int i; + for(i=0;i<32;i++) + stb__Expand5[i] = (i<<3)|(i>>2); + + for(i=0;i<64;i++) + stb__Expand6[i] = (i<<2)|(i>>4); + + for(i=0;i<256+16;i++) + { + int v = i-8 < 0 ? 0 : i-8 > 255 ? 255 : i-8; + stb__QuantRBTab[i] = stb__Expand5[stb__Mul8Bit(v,31)]; + stb__QuantGTab[i] = stb__Expand6[stb__Mul8Bit(v,63)]; + } + + stb__PrepareOptTable(&stb__OMatch5[0][0],stb__Expand5,32); + stb__PrepareOptTable(&stb__OMatch6[0][0],stb__Expand6,64); +} + +void stb_compress_dxt_block(unsigned char *dest, const unsigned char *src, int alpha, int mode) +{ + static int init=1; + if (init) { + stb__InitDXT(); + init=0; + } + + if (alpha) { + stb__CompressAlphaBlock(dest,(unsigned char*) src,mode); + dest += 8; + } + + stb__CompressColorBlock(dest,(unsigned char*) src,mode); +} +#endif // STB_DXT_IMPLEMENTATION + +#endif // STB_INCLUDE_STB_DXT_H diff --git a/togles/togl.vpc b/togles/togl.vpc new file mode 100644 index 00000000..dadbcd72 --- /dev/null +++ b/togles/togl.vpc @@ -0,0 +1,116 @@ +//----------------------------------------------------------------------------- +// TOGL.VPC +// +// Project Script +//----------------------------------------------------------------------------- + +$Macro SRCDIR ".." [$WIN32] +$Macro SRCDIR ".." [!$WIN32] +$Macro OUTBINDIR $LIBPUBLIC +$Macro OUTBINNAME "togl" +$Macro TOGL_SRCDIR "$SRCDIR/togl/linuxwin" +$Macro TOGL_INCDIR "$SRCDIR/public/togl/linuxwin" + + +$include "$SRCDIR\vpc_scripts\source_dll_base.vpc" + +// Common Configuration +$Configuration +{ + $Compiler + { + $AdditionalIncludeDirectories "$BASE;..\" + $PreprocessorDefinitions "$BASE;TOGL_DLL_EXPORT;PROTECTED_THINGS_ENABLE;strncpy=use_Q_strncpy_instead;_snprintf=use_Q_snprintf_instead" [!$OSXALL] + $PreprocessorDefinitions "$BASE;TOGL_DLL_EXPORT" [$OSXALL] + + } + + $Linker + { + $ImportLibrary "$LIBPUBLIC\$_IMPLIB_PREFIX$OUTBINNAME$_IMPLIB_EXT" [!$X360 && !$OSXALL] + $ImportLibrary "$SRCDIR\lib\$PLATFORM\$_IMPLIB_PREFIX$OUTBINNAME$_IMPLIB_EXT" [$OSXALL] + } + + $Linker [$OSXALL] + { + $SystemFrameworks "Carbon;OpenGL;Quartz;Cocoa;IOKit" + } + + // togl/tier0/vstdlib traditionally used "lib" prefix though nobody else seems to. + $Linker [$POSIX] + { + $OutputFile "$(OBJ_DIR)/$_IMPLIB_PREFIX$OUTBINNAME$_DLL_EXT" + } + + $General [$POSIX] + { + $GameOutputFile "$OUTBINDIR/$_IMPLIB_PREFIX$OUTBINNAME$_DLL_EXT" + } + + $PreLinkEvent [$WINDOWS] + { + $CommandLine "call $SRCDIR\vpc_scripts\valve_p4_edit.cmd $LIBPUBLIC\$(TargetName).lib $SRCDIR" "\n" \ + "$BASE" + } +} + +$Project "togl" +{ + $Folder "Source Files" [$GL] + { + $File "$TOGL_SRCDIR/dx9asmtogl2.cpp" + $File "$TOGL_SRCDIR/dxabstract.cpp" + $File "$TOGL_SRCDIR/glentrypoints.cpp" + $File "$TOGL_SRCDIR/glmgr.cpp" + $File "$TOGL_SRCDIR/glmgrbasics.cpp" + $File "$TOGL_SRCDIR/glmgrcocoa.mm" [$OSXALL] + $File "$TOGL_SRCDIR/intelglmallocworkaround.cpp" [$OSXALL] + $File "$TOGL_SRCDIR/mach_override.c" [$OSXALL] + $File "$TOGL_SRCDIR/cglmtex.cpp" + $File "$TOGL_SRCDIR/cglmfbo.cpp" + $File "$TOGL_SRCDIR/cglmprogram.cpp" + $File "$TOGL_SRCDIR/cglmbuffer.cpp" + $File "$TOGL_SRCDIR/cglmquery.cpp" + $File "$TOGL_SRCDIR/asanstubs.cpp" + } + + $Folder "DirectX Header Files" [$WIN32 && !$GL] + { + } + + $Folder "Header Files" [$GL] + { + $File "$TOGL_SRCDIR/dx9asmtogl2.h" + $File "$TOGL_SRCDIR/glmgr_flush.inl" + $File "$TOGL_SRCDIR/intelglmallocworkaround.h" [$OSXALL] + $File "$TOGL_SRCDIR/mach_override.h" [$OSXALL] + } + + $Folder "Public Header Files" [$GL] + { + $File "$SRCDIR/public/togl/rendermechanism.h" + $File "$TOGL_INCDIR/dxabstract.h" + $File "$TOGL_INCDIR/dxabstract_types.h" + $File "$TOGL_INCDIR/glbase.h" + $File "$TOGL_INCDIR/glentrypoints.h" + $File "$TOGL_INCDIR/glmgr.h" + $File "$TOGL_INCDIR/glmdebug.h" + $File "$TOGL_INCDIR/glmgrbasics.h" + $File "$TOGL_INCDIR/glmgrext.h" + $File "$TOGL_INCDIR/glmdisplay.h" + $File "$TOGL_INCDIR/glmdisplaydb.h" + $File "$TOGL_INCDIR/glfuncs.h" + $File "$TOGL_INCDIR/cglmtex.h" + $File "$TOGL_INCDIR/cglmfbo.h" + $File "$TOGL_INCDIR/cglmprogram.h" + $File "$TOGL_INCDIR/cglmbuffer.h" + $File "$TOGL_INCDIR/cglmquery.h" + } + + $Folder "Link Libraries" + { + $Lib tier2 + $Lib mathlib + } +} + diff --git a/togles/wscript b/togles/wscript new file mode 100755 index 00000000..bc796860 --- /dev/null +++ b/togles/wscript @@ -0,0 +1,63 @@ +#! /usr/bin/env python +# encoding: utf-8 + +from waflib import Utils +import os + +top = '.' +PROJECT_NAME = 'togl' + +def options(opt): + # stub + return + +def configure(conf): + conf.define('TOGL_DLL_EXPORT',1) + conf.env.append_unique('DEFINES',['strncpy=use_Q_strncpy_instead', + '_snprintf=use_Q_snprintf_instead']) + +def build(bld): + source = [ + 'linuxwin/dx9asmtogl2.cpp', + 'linuxwin/dxabstract.cpp', + 'linuxwin/glentrypoints.cpp', + 'linuxwin/glmgr.cpp', + 'linuxwin/glmgrbasics.cpp', + #'linuxwin/glmgrcocoa.mm', [$OSXALL] + #'linuxwin/intelglmallocworkaround.cpp', [$OSXALL] + #'linuxwin/mach_override.c', [$OSXALL] + 'linuxwin/cglmtex.cpp', + 'linuxwin/cglmfbo.cpp', + 'linuxwin/cglmprogram.cpp', + 'linuxwin/cglmbuffer.cpp', + 'linuxwin/cglmquery.cpp', + 'linuxwin/asanstubs.cpp', + 'linuxwin/decompress.c' + ] + + includes = [ + '.', + '../public', + '../public/tier0', + '../public/tier1' + ] + bld.env.INCLUDES_SDL2 + + defines = [] + + libs = ['tier0','tier1','tier2','vstdlib','mathlib'] + + install_path = bld.env.LIBDIR + + bld.shlib( + source = source, + target = PROJECT_NAME, + name = PROJECT_NAME, + features = 'c cxx', + includes = includes, + defines = defines, + use = libs, + install_path = install_path, + subsystem = bld.env.MSVC_SUBSYSTEM, + idx = bld.get_taskgen_count() + ) + diff --git a/vgui2/src/Surface.cpp b/vgui2/src/Surface.cpp index 2f623208..51ad5186 100644 --- a/vgui2/src/Surface.cpp +++ b/vgui2/src/Surface.cpp @@ -388,7 +388,7 @@ private: CUtlDict< IImage *, unsigned short > m_FileTypeImages; - enum { BASE_HEIGHT = 480, BASE_WIDTH = 640 }; + enum { BASE_HEIGHT = 600, BASE_WIDTH = 800 }; bool LoadTGA(Texture *texture, const char *filename); bool LoadBMP(Texture *texture, const char *filename); diff --git a/vgui2/vgui_controls/BuildGroup.cpp b/vgui2/vgui_controls/BuildGroup.cpp index 328b1de6..bef4a3c0 100644 --- a/vgui2/vgui_controls/BuildGroup.cpp +++ b/vgui2/vgui_controls/BuildGroup.cpp @@ -5,7 +5,7 @@ // $NoKeywords: $ // //=============================================================================// - //========= Copyright © 1996-2003, Valve LLC, All rights reserved. ============ + //========= Copyright � 1996-2003, Valve LLC, All rights reserved. ============ // // The copyright to the contents herein is the property of Valve, L.L.C. // The contents may be used and/or copied only with the written permission of diff --git a/vgui2/vgui_controls/Button.cpp b/vgui2/vgui_controls/Button.cpp index cb998607..aa46eda8 100644 --- a/vgui2/vgui_controls/Button.cpp +++ b/vgui2/vgui_controls/Button.cpp @@ -71,7 +71,6 @@ void Button::Init() _keyFocusBorder = NULL; m_bSelectionStateSaved = false; m_bStaySelectedOnClick = false; - m_bStaySelectedOnClick = false; m_bStayArmedOnClick = false; m_sArmedSoundName = UTL_INVAL_SYMBOL; m_sDepressedSoundName = UTL_INVAL_SYMBOL; @@ -140,11 +139,12 @@ void Button::SetSelected( bool state ) InvalidateLayout(false); } - if ( !m_bStayArmedOnClick && state && _buttonFlags.IsFlagSet( ARMED ) ) - { - _buttonFlags.SetFlag( ARMED, false ); - InvalidateLayout(false); - } + // Jusic: idk what is it for + //if (!m_bStayArmedOnClick && state && _buttonFlags.IsFlagSet(ARMED)) + //{ + // _buttonFlags.SetFlag( ARMED, false ); + // InvalidateLayout(false); + //} } void Button::SetBlink( bool state ) @@ -877,7 +877,11 @@ void Button::ApplySettings( KeyValues *inResourceData ) SetReleasedSound(sound); } - _activationType = (ActivationType_t)inResourceData->GetInt( "button_activation_type", ACTIVATE_ONRELEASED ); + int iButtonActivationType = inResourceData->GetInt( "button_activation_type", -1 ); + if (iButtonActivationType != -1) + { + _activationType = (ActivationType_t)iButtonActivationType; + } } diff --git a/vgui2/vgui_controls/Frame.cpp b/vgui2/vgui_controls/Frame.cpp index 35b5d761..eec463a2 100644 --- a/vgui2/vgui_controls/Frame.cpp +++ b/vgui2/vgui_controls/Frame.cpp @@ -1224,12 +1224,24 @@ void Frame::PerformLayout() // move everything into place int wide, tall; GetSize(wide, tall); - + + float scale = 1; + if (IsProportional()) + { + int screenW, screenH; + surface()->GetScreenSize(screenW, screenH); + + int proW, proH; + surface()->GetProportionalBase(proW, proH); + + scale = ((float)(screenH) / (float)(proH)); + } + #if !defined( _X360 ) int DRAGGER_SIZE = GetDraggerSize(); int CORNER_SIZE = GetCornerSize(); int CORNER_SIZE2 = CORNER_SIZE * 2; - int BOTTOMRIGHTSIZE = GetBottomRightSize(); + int BOTTOMRIGHTSIZE = GetBottomRightSize() * scale; _topGrip->SetBounds(CORNER_SIZE, 0, wide - CORNER_SIZE2, DRAGGER_SIZE); _leftGrip->SetBounds(0, CORNER_SIZE, DRAGGER_SIZE, tall - CORNER_SIZE2); @@ -1260,18 +1272,6 @@ void Frame::PerformLayout() _minimizeToSysTrayButton->MoveToFront(); _menuButton->SetBounds(5+2, 5+3, GetCaptionHeight()-5, GetCaptionHeight()-5); #endif - - float scale = 1; - if (IsProportional()) - { - int screenW, screenH; - surface()->GetScreenSize( screenW, screenH ); - - int proW,proH; - surface()->GetProportionalBase( proW, proH ); - - scale = ( (float)( screenH ) / (float)( proH ) ); - } #if !defined( _X360 ) int offset_start = (int)( 20 * scale ); diff --git a/vgui2/vgui_controls/ImagePanel.cpp b/vgui2/vgui_controls/ImagePanel.cpp index 97ceb43d..8173aab9 100644 --- a/vgui2/vgui_controls/ImagePanel.cpp +++ b/vgui2/vgui_controls/ImagePanel.cpp @@ -90,6 +90,21 @@ void ImagePanel::SetImage(const char *imageName) m_pszImageName = new char[ len ]; Q_strncpy(m_pszImageName, imageName, len ); InvalidateLayout(false, true); // force applyschemesettings to run + + if (IsProportional() && m_pImage && !m_bScaleImage) + { + float scale = 1; + int screenW, screenH; + surface()->GetScreenSize(screenW, screenH); + + int proW, proH; + surface()->GetProportionalBase(proW, proH); + + scale = ((float)(screenH) / (float)(proH)); + + m_fScaleAmount = scale; + m_bScaleImage = true; + } } //----------------------------------------------------------------------------- diff --git a/vgui2/vgui_controls/MessageBox.cpp b/vgui2/vgui_controls/MessageBox.cpp index e825e6bc..558ed10f 100644 --- a/vgui2/vgui_controls/MessageBox.cpp +++ b/vgui2/vgui_controls/MessageBox.cpp @@ -145,9 +145,15 @@ void MessageBox::ApplySchemeSettings(IScheme *pScheme) int wide, tall; m_pMessageLabel->GetContentSize(wide, tall); m_pMessageLabel->SetSize(wide, tall); + + int indent = 100; + if (IsProportional()) + { + indent = scheme()->GetProportionalScaledValueEx(GetScheme(), 100); + } - wide += 100; - tall += 100; + wide += indent; + tall += indent; SetSize(wide, tall); if ( m_bShowMessageBoxOverCursor ) @@ -243,7 +249,7 @@ void MessageBox::ShowWindow(Frame *pFrameOver) // Purpose: Put the text and OK buttons in correct place //----------------------------------------------------------------------------- void MessageBox::PerformLayout() -{ +{ int x, y, wide, tall; GetClientArea(x, y, wide, tall); wide += x; @@ -255,38 +261,51 @@ void MessageBox::PerformLayout() int oldWide, oldTall; m_pOkButton->GetSize(oldWide, oldTall); + // calc proportionality scale + float scale = 1; + if (IsProportional()) + { + int screenW, screenH; + surface()->GetScreenSize(screenW, screenH); + + int proW, proH; + surface()->GetProportionalBase(proW, proH); + + scale = ((float)(screenH) / (float)(proH)); + } + int btnWide, btnTall; m_pOkButton->GetContentSize(btnWide, btnTall); - btnWide = max(oldWide, btnWide + 10); - btnTall = max(oldTall, btnTall + 10); + btnWide = max(oldWide, btnWide + 10 * scale); + btnTall = max(oldTall, btnTall + 10 * scale); m_pOkButton->SetSize(btnWide, btnTall); - + int btnWide2 = 0, btnTall2 = 0; if ( m_pCancelButton->IsVisible() ) { m_pCancelButton->GetSize(oldWide, oldTall); m_pCancelButton->GetContentSize(btnWide2, btnTall2); - btnWide2 = max(oldWide, btnWide2 + 10); - btnTall2 = max(oldTall, btnTall2 + 10); - m_pCancelButton->SetSize(btnWide2, btnTall2); + btnWide2 = max(oldWide, btnWide2 + 10 * scale); + btnTall2 = max(oldTall, btnTall2 + 10 * scale); + m_pCancelButton->SetSize(btnWide2, boxTall); } - boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100); - boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30); + boxWidth = max(boxWidth, m_pMessageLabel->GetWide() + 100 * scale); + boxWidth = max(boxWidth, (btnWide + btnWide2) * 2 + 30 * scale); SetSize(boxWidth, boxTall); GetSize(boxWidth, boxTall); - m_pMessageLabel->SetPos((wide/2)-(m_pMessageLabel->GetWide()/2) + x, y + 5 ); + m_pMessageLabel->SetPos((wide/2)-(m_pMessageLabel->GetWide()/2) + x, y + 5 * scale); if ( !m_pCancelButton->IsVisible() ) { - m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15); + m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15 * scale); } else { - m_pOkButton->SetPos((wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15); - m_pCancelButton->SetPos((3*wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15); + m_pOkButton->SetPos((wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15 * scale); + m_pCancelButton->SetPos((3*wide/4)-(m_pOkButton->GetWide()/2) + x, tall - m_pOkButton->GetTall() - 15 * scale); } BaseClass::PerformLayout(); diff --git a/vgui2/vgui_controls/PropertyDialog.cpp b/vgui2/vgui_controls/PropertyDialog.cpp index 568b23e2..e5c193b2 100644 --- a/vgui2/vgui_controls/PropertyDialog.cpp +++ b/vgui2/vgui_controls/PropertyDialog.cpp @@ -115,24 +115,36 @@ void PropertyDialog::PerformLayout() GetClientArea(x, y, wide, tall); _propertySheet->SetBounds(x, y, wide, tall - iBottom); + // calc button size and indent for proportionality + int iBtnWide = 72; + int iBtnTall = 24; + int iWideIndent = 8; + int iTallIndent = 4; + if (IsProportional()) + { + iBtnWide = scheme()->GetProportionalScaledValueEx(GetScheme(), iBtnWide); + iBtnTall = scheme()->GetProportionalScaledValueEx(GetScheme(), iBtnTall); + iWideIndent = scheme()->GetProportionalScaledValueEx(GetScheme(), iWideIndent); + iTallIndent = scheme()->GetProportionalScaledValueEx(GetScheme(), iTallIndent); + } // move the buttons to the bottom-right corner - int xpos = x + wide - 80; - int ypos = tall + y - 28; + int xpos = x + wide - iBtnWide - iWideIndent; + int ypos = tall + y - iBtnTall - iTallIndent; if (_applyButton->IsVisible()) { - _applyButton->SetBounds(xpos, ypos, 72, 24); - xpos -= 80; + _applyButton->SetBounds(xpos, ypos, iBtnWide, iBtnTall); + xpos -= iBtnWide + iWideIndent; } if (_cancelButton->IsVisible()) { - _cancelButton->SetBounds(xpos, ypos, 72, 24); - xpos -= 80; + _cancelButton->SetBounds(xpos, ypos, iBtnWide, iBtnTall); + xpos -= iBtnWide + iWideIndent; } - _okButton->SetBounds(xpos, ypos, 72, 24); + _okButton->SetBounds(xpos, ypos, iBtnWide, iBtnTall); _propertySheet->InvalidateLayout(); // tell the propertysheet to redraw! Repaint(); diff --git a/vgui2/vgui_controls/QueryBox.cpp b/vgui2/vgui_controls/QueryBox.cpp index 44226993..2cf355c4 100644 --- a/vgui2/vgui_controls/QueryBox.cpp +++ b/vgui2/vgui_controls/QueryBox.cpp @@ -9,6 +9,7 @@ //=============================================================================// #include +#include #include #include @@ -89,10 +90,23 @@ void QueryBox::PerformLayout() int oldWide, oldTall; m_pCancelButton->GetSize(oldWide, oldTall); + // calc proportionality scale + float scale = 1; + if (IsProportional()) + { + int screenW, screenH; + surface()->GetScreenSize(screenW, screenH); + + int proW, proH; + surface()->GetProportionalBase(proW, proH); + + scale = ((float)(screenH) / (float)(proH)); + } + int btnWide, btnTall; m_pCancelButton->GetContentSize(btnWide, btnTall); - btnWide = max(oldWide, btnWide + 10); - btnTall = max(oldTall, btnTall + 10); + btnWide = max(oldWide, btnWide + 10 * scale); + btnTall = max(oldTall, btnTall + 10 * scale); m_pCancelButton->SetSize(btnWide, btnTall); //nt boxWidth, boxTall; @@ -100,8 +114,8 @@ void QueryBox::PerformLayout() // wide = max(wide, btnWide * 2 + 100); // SetSize(wide, tall); - m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide())-1 + x, tall - m_pOkButton->GetTall() - 15); - m_pCancelButton->SetPos((wide/2) + x+16, tall - m_pCancelButton->GetTall() - 15); + m_pOkButton->SetPos((wide/2)-(m_pOkButton->GetWide())-1 + x, tall - m_pOkButton->GetTall() - 15 * scale); + m_pCancelButton->SetPos((wide/2) + x+16*scale, tall - m_pCancelButton->GetTall() - 15 * scale); } diff --git a/vgui2/vgui_controls/consoledialog.cpp b/vgui2/vgui_controls/consoledialog.cpp index 908f6aa2..61a257ac 100644 --- a/vgui2/vgui_controls/consoledialog.cpp +++ b/vgui2/vgui_controls/consoledialog.cpp @@ -844,12 +844,24 @@ void CConsolePanel::PerformLayout() if ( !m_bStatusVersion ) { - const int inset = 8; - const int entryHeight = 24; - const int topHeight = 4; - const int entryInset = 4; - const int submitWide = 64; - const int submitInset = 7; // x inset to pull the submit button away from the frame grab + float scale = 1; + if (IsProportional()) + { + int screenW, screenH; + surface()->GetScreenSize(screenW, screenH); + + int proW, proH; + surface()->GetProportionalBase(proW, proH); + + scale = ((float)(screenH) / (float)(proH)); + } + + const int inset = 8 * scale; + const int entryHeight = 24 * scale; + const int topHeight = 4 * scale; + const int entryInset = 4 * scale; + const int submitWide = 64 * scale; + const int submitInset = 7 * scale; // x inset to pull the submit button away from the frame grab m_pHistory->SetPos(inset, inset + topHeight); m_pHistory->SetSize(wide - (inset * 2), tall - (entryInset * 2 + inset * 2 + topHeight + entryHeight)); @@ -931,6 +943,7 @@ void CConsolePanel::ApplySchemeSettings(IScheme *pScheme) m_DPrintColor = GetSchemeColor("Console.DevTextColor", pScheme); m_pHistory->SetFont( pScheme->GetFont( "ConsoleText", IsProportional() ) ); m_pCompletionList->SetFont( pScheme->GetFont( "DefaultSmall", IsProportional() ) ); + m_pEntry->SetFont( pScheme->GetFont( "DefaultSmall", IsProportional() ) ); InvalidateLayout(); } diff --git a/vgui2/vgui_surfacelib/linuxfont.cpp b/vgui2/vgui_surfacelib/linuxfont.cpp index 234480ef..e9170fdb 100644 --- a/vgui2/vgui_surfacelib/linuxfont.cpp +++ b/vgui2/vgui_surfacelib/linuxfont.cpp @@ -418,9 +418,9 @@ char *FindFontAndroid(bool bBold, int italic) else if( italic ) fontFileNamePost = "Italic"; else - fontFileName = "Regular"; + fontFileNamePost = "Regular"; - char dataFile[MAX_PATH]; + static char dataFile[MAX_PATH]; if( fontFileNamePost ) snprintf( dataFile, sizeof dataFile, "/system/fonts/%s-%s.ttf", fontFileName, fontFileNamePost ); @@ -431,7 +431,7 @@ char *FindFontAndroid(bool bBold, int italic) { fontFileNamePost = NULL; fontFileName = "DroidSans"; - if( bBold > 500 ) + if( bBold ) fontFileNamePost = "Bold"; if( fontFileNamePost ) @@ -464,7 +464,7 @@ char *CLinuxFont::GetFontFileName( const char *windowsFontName, int flags ) #ifdef ANDROID char *filename = FindFontAndroid( bBold, italic ); - Msg("Android font: %s", filename); + Msg("Android font: %s\n", filename); if( !filename ) return NULL; return strdup( filename ); #else diff --git a/vguimatsurface/Input.cpp b/vguimatsurface/Input.cpp index a30ff010..03df13d5 100644 --- a/vguimatsurface/Input.cpp +++ b/vguimatsurface/Input.cpp @@ -29,11 +29,13 @@ #ifdef _X360 #include "xbox/xbox_win32stubs.h" #endif +#include "MatSystemSurface.h" // memdbgon must be the last include file in a .cpp file!!! #include "tier0/memdbgon.h" using namespace vgui; +extern CMatSystemSurface g_MatSystemSurface; //----------------------------------------------------------------------------- // Vgui input events @@ -374,7 +376,7 @@ static vgui::MouseCode ButtonCodeToMouseCode( ButtonCode_t buttonCode ) //----------------------------------------------------------------------------- bool InputHandleInputEvent( const InputEvent_t &event ) { - switch( event.m_nType ) + switch( event.m_nType & 0xFFFF ) { case IE_ButtonPressed: { @@ -425,25 +427,35 @@ bool InputHandleInputEvent( const InputEvent_t &event ) break; case IE_FingerDown: { - //g_pIInput->InternalCursorMoved( event.m_nData2, event.m_nData3 ); - g_pIInput->UpdateCursorPosInternal( event.m_nData2, event.m_nData3 ); + int w,h,x,y; g_MatSystemSurface.GetScreenSize(w, h); + uint data = (uint)event.m_nData; + x = w*((double)((data >> 16) & 0xFFFF) / 0xFFFF); + y = h*((double)(data & 0xFFFF) / 0xFFFF); + g_pIInput->UpdateCursorPosInternal( x, y ); g_pIInput->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_PRESSED ); g_pIInput->InternalMousePressed( MOUSE_LEFT ); } return true; case IE_FingerUp: { - g_pIInput->UpdateCursorPosInternal( event.m_nData2, event.m_nData3 ); - g_pIInput->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_RELEASED ); + int w,h,x,y; g_MatSystemSurface.GetScreenSize(w, h); + uint data = (uint)event.m_nData; + x = w*((double)((data >> 16) & 0xFFFF) / 0xFFFF); + y = h*((double)(data & 0xFFFF) / 0xFFFF); + g_pIInput->UpdateCursorPosInternal( x, y ); + g_pIInput->SetMouseCodeState( MOUSE_LEFT, vgui::BUTTON_RELEASED ); g_pIInput->InternalMouseReleased( MOUSE_LEFT ); } return true; case IE_FingerMotion: { - //g_pIInput->UpdateCursorPosInternal( event.m_nData2, event.m_nData3 ); - g_pIInput->InternalCursorMoved( event.m_nData2, event.m_nData3 ); + int w,h,x,y; g_MatSystemSurface.GetScreenSize(w, h); + uint data = (uint)event.m_nData; + x = w*((double)((data >> 16) & 0xFFFF) / 0xFFFF); + y = h*((double)(data & 0xFFFF) / 0xFFFF); + g_pIInput->InternalCursorMoved( x, y ); } - return true; + return true; case IE_ButtonDoubleClicked: { // NOTE: data2 is the virtual key code (data1 contains the scan-code one) diff --git a/wscript b/wscript index ea019053..bbe4e113 100644 --- a/wscript +++ b/wscript @@ -65,7 +65,6 @@ projects={ 'tier1', 'tier2', 'tier3', - 'togl', 'vgui2/matsys_controls', 'vgui2/src', 'vgui2/vgui_controls', @@ -136,6 +135,8 @@ def get_taskgen_count(self): def define_platform(conf): conf.env.DEDICATED = conf.options.DEDICATED + conf.env.TOGLES = conf.options.TOGLES + conf.env.GL = conf.options.GL if conf.options.DEDICATED: conf.options.SDL = False @@ -149,6 +150,10 @@ def define_platform(conf): 'BINK_VIDEO' ]) + if conf.options.TOGLES: + conf.env.append_unique('DEFINES', ['TOGLES']) + + if conf.options.SDL: conf.define('USE_SDL', 1) @@ -205,6 +210,9 @@ def options(opt): grp.add_option('--use-ccache', action = 'store_true', dest = 'CCACHE', default = False, help = 'build using ccache [default: %default]') + grp.add_option('--togles', action = 'store_true', dest = 'TOGLES', default = False, + help = 'build engine with ToGLES [default: %default]') + opt.load('compiler_optimizations subproject') # opt.add_subproject(projects['game']) @@ -228,6 +236,12 @@ def configure(conf): define_platform(conf) + if conf.env.TOGLES: + projects['game'] += ['togles'] + elif conf.env.GL: + projects['game'] += ['togl'] + + if conf.env.DEST_OS in ['win32', 'linux', 'darwin'] and conf.env.DEST_CPU == 'x86_64': conf.env.BIT32_MANDATORY = not conf.options.ALLOW64 if conf.env.BIT32_MANDATORY: @@ -265,15 +279,14 @@ def configure(conf): '-I'+os.path.abspath('.')+'/thirdparty/openal-soft/include/', '-I'+os.path.abspath('.')+'/thirdparty/fontconfig', '-I'+os.path.abspath('.')+'/thirdparty/freetype/include', - '-llog' + '-llog', + '-lz' ] if conf.env.DEST_CPU == 'arm': - flags += ['-fsigned-char', '-mfpu=neon'] + flags += ['-fsigned-char'] - if conf.env.DEST_OS == 'android': - flags += ['-mcpu=cortex-a15', '-mtune=cortex-a15'] - else: + if conf.env.DEST_OS != 'android': flags += ['-march=native', '-mtune=native'] else: flags += ['-march=native','-mtune=native','-mfpmath=sse', '-msse', '-msse2'] @@ -396,4 +409,9 @@ def build(bld): if bld.env.DEDICATED: bld.add_subproject(projects['dedicated']) else: + if bld.env.TOGLES: + projects['game'] += ['togles'] + elif bld.env.GL: + projects['game'] += ['togl'] + bld.add_subproject(projects['game'])