/// Accept patch transfer bool AuthSocket::_HandleXferAccept() { DEBUG_LOG("Entering _HandleXferAccept"); recv_skip(1); InitPatch(); return true; }
/// Resume patch transfer bool AuthSocket::_HandleXferResume() { DEBUG_LOG("Entering _HandleXferResume"); if (recv_len() < 9) return false; recv_skip(1); uint64 start_pos; recv((char*)&start_pos, 8); if (patch_ == ACE_INVALID_HANDLE) { close_connection(); return false; } ACE_OFF_T file_size = ACE_OS::filesize(patch_); if (file_size == -1 || start_pos >= (uint64)file_size) { close_connection(); return false; } if (ACE_OS::lseek(patch_, start_pos, SEEK_SET) == -1) { close_connection(); return false; } InitPatch(); return true; }
//----------------------------------------------------------------------------- // Purpose: // Input : flMinArea - // Output : float //----------------------------------------------------------------------------- void CVRADDispColl::CreateChildPatchesSub( int iParentPatch ) { // Get the parent patch. CPatch *pParentPatch = &g_Patches[iParentPatch]; if ( !pParentPatch ) return; // Calculate the the area of the patch (triangle!). Assert( pParentPatch->winding->numpoints == 3 ); if ( pParentPatch->winding->numpoints != 3 ) return; // Should the patch be subdivided - check the area. float flMaxLength = MAX( m_flSampleWidth, m_flSampleHeight ); float flMinEdgeLength = flMaxLength * dispchop; // Split along the longest edge. Vector vecEdges[3]; vecEdges[0] = pParentPatch->winding->p[1] - pParentPatch->winding->p[0]; vecEdges[1] = pParentPatch->winding->p[2] - pParentPatch->winding->p[0]; vecEdges[2] = pParentPatch->winding->p[2] - pParentPatch->winding->p[1]; // Find the longest edge. float flEdgeLength = 0.0f; int iLongEdge = -1; for ( int iEdge = 0; iEdge < 3; ++iEdge ) { if ( flEdgeLength < vecEdges[iEdge].Length() ) { flEdgeLength = vecEdges[iEdge].Length(); iLongEdge = iEdge; } } // Small enough already, return. if ( flEdgeLength < flMinEdgeLength ) return; // Test area as well so we don't allow slivers. float flMinArea = ( dispchop * flMaxLength ) * ( dispchop * flMaxLength ) * 0.5f; Vector vecNormal = vecEdges[1].Cross( vecEdges[0] ); float flTestArea = VectorNormalize( vecNormal ); flTestArea *= 0.5f; if ( flTestArea < flMinArea ) return; // Create children patchs - 2 of them. Vector vecChildPoints[2][3]; switch ( iLongEdge ) { case 0: { vecChildPoints[0][0] = pParentPatch->winding->p[0]; vecChildPoints[0][1] = ( pParentPatch->winding->p[0] + pParentPatch->winding->p[1] ) * 0.5f; vecChildPoints[0][2] = pParentPatch->winding->p[2]; vecChildPoints[1][0] = ( pParentPatch->winding->p[0] + pParentPatch->winding->p[1] ) * 0.5f; vecChildPoints[1][1] = pParentPatch->winding->p[1]; vecChildPoints[1][2] = pParentPatch->winding->p[2]; break; } case 1: { vecChildPoints[0][0] = pParentPatch->winding->p[0]; vecChildPoints[0][1] = pParentPatch->winding->p[1]; vecChildPoints[0][2] = ( pParentPatch->winding->p[1] + pParentPatch->winding->p[2] ) * 0.5f; vecChildPoints[1][0] = ( pParentPatch->winding->p[1] + pParentPatch->winding->p[2] ) * 0.5f; vecChildPoints[1][1] = pParentPatch->winding->p[2]; vecChildPoints[1][2] = pParentPatch->winding->p[0]; break; } case 2: { vecChildPoints[0][0] = pParentPatch->winding->p[0]; vecChildPoints[0][1] = pParentPatch->winding->p[1]; vecChildPoints[0][2] = ( pParentPatch->winding->p[0] + pParentPatch->winding->p[2] ) * 0.5f; vecChildPoints[1][0] = ( pParentPatch->winding->p[0] + pParentPatch->winding->p[2] ) * 0.5f; vecChildPoints[1][1] = pParentPatch->winding->p[1]; vecChildPoints[1][2] = pParentPatch->winding->p[2]; break; } } // Create and initialize the children patches. int iChildPatch[2] = { 0, 0 }; int nChildIndices[3] = { -1, -1, -1 }; for ( int iChild = 0; iChild < 2; ++iChild ) { iChildPatch[iChild] = g_Patches.AddToTail(); float flArea = 0.0f; if ( !InitPatch( iChildPatch[iChild], iParentPatch, iChild, vecChildPoints[iChild], nChildIndices, flArea ) ) { if ( iChild == 0 ) { pParentPatch->child1 = g_Patches.InvalidIndex(); g_Patches.Remove( iChildPatch[iChild] ); break; } else { pParentPatch->child1 = g_Patches.InvalidIndex(); pParentPatch->child2 = g_Patches.InvalidIndex(); g_Patches.Remove( iChildPatch[iChild] ); g_Patches.Remove( iChildPatch[0] ); } } } // Continue creating children patches. CreateChildPatchesSub( iChildPatch[0] ); CreateChildPatchesSub( iChildPatch[1] ); }
//----------------------------------------------------------------------------- // Purpose: // Input : flMinArea - // Output : float //----------------------------------------------------------------------------- void CVRADDispColl::CreateChildPatches( int iParentPatch, int nLevel ) { // Get the parent patch. CPatch *pParentPatch = &g_Patches[iParentPatch]; if ( !pParentPatch ) return; // The root face is a quad - special case. if ( pParentPatch->winding->numpoints == 4 ) { int iChildPatch[2]; CreateChildPatchesFromRoot( iParentPatch, iChildPatch ); if ( iChildPatch[0] != g_Patches.InvalidIndex() && iChildPatch[1] != g_Patches.InvalidIndex() ) { CreateChildPatches( iChildPatch[0], 0 ); CreateChildPatches( iChildPatch[1], 0 ); } return; } // Calculate the the area of the patch (triangle!). Assert( pParentPatch->winding->numpoints == 3 ); if ( pParentPatch->winding->numpoints != 3 ) return; // Should the patch be subdivided - check the area. float flMaxLength = MAX( m_flSampleWidth, m_flSampleHeight ); float flMinEdgeLength = flMaxLength * dispchop; // Split along the longest edge. Vector vecEdges[3]; vecEdges[0] = pParentPatch->winding->p[1] - pParentPatch->winding->p[0]; vecEdges[1] = pParentPatch->winding->p[2] - pParentPatch->winding->p[0]; vecEdges[2] = pParentPatch->winding->p[2] - pParentPatch->winding->p[1]; // Find the longest edge. float flEdgeLength = 0.0f; int iLongEdge = -1; for ( int iEdge = 0; iEdge < 3; ++iEdge ) { if ( flEdgeLength < vecEdges[iEdge].Length() ) { flEdgeLength = vecEdges[iEdge].Length(); iLongEdge = iEdge; } } // Small enough already, return. if ( flEdgeLength < flMinEdgeLength ) return; // Test area as well so we don't allow slivers. float flMinArea = ( dispchop * flMaxLength ) * ( dispchop * flMaxLength ) * 0.5f; Vector vecNormal = vecEdges[1].Cross( vecEdges[0] ); float flTestArea = VectorNormalize( vecNormal ); flTestArea *= 0.5f; if ( flTestArea < flMinArea ) return; // Check to see if any more displacement verts exist - go to subdivision if not. if ( nLevel >= ( m_nPower * 2 ) ) { CreateChildPatchesSub( iParentPatch ); return; } int nChildIndices[2][3]; int nNewIndex = ( pParentPatch->indices[1] + pParentPatch->indices[0] ) / 2; nChildIndices[0][0] = pParentPatch->indices[2]; nChildIndices[0][1] = pParentPatch->indices[0]; nChildIndices[0][2] = nNewIndex; nChildIndices[1][0] = pParentPatch->indices[1]; nChildIndices[1][1] = pParentPatch->indices[2]; nChildIndices[1][2] = nNewIndex; Vector vecChildPoints[2][3]; for ( int iTri = 0; iTri < 2; ++iTri ) { for ( int iPoint = 0; iPoint < 3; ++iPoint ) { VectorCopy( m_aVerts[nChildIndices[iTri][iPoint]], vecChildPoints[iTri][iPoint] ); } } // Create and initialize the children patches. int iChildPatch[2] = { -1, -1 }; for ( int iChild = 0; iChild < 2; ++iChild ) { iChildPatch[iChild] = g_Patches.AddToTail(); float flArea = 0.0f; if ( !InitPatch( iChildPatch[iChild], iParentPatch, iChild, vecChildPoints[iChild], nChildIndices[iChild], flArea ) ) { if ( iChild == 0 ) { pParentPatch->child1 = g_Patches.InvalidIndex(); g_Patches.Remove( iChildPatch[iChild] ); break; } else { pParentPatch->child1 = g_Patches.InvalidIndex(); pParentPatch->child2 = g_Patches.InvalidIndex(); g_Patches.Remove( iChildPatch[iChild] ); g_Patches.Remove( iChildPatch[0] ); } } } // Continue creating children patches. int nNewLevel = ++nLevel; CreateChildPatches( iChildPatch[0], nNewLevel ); CreateChildPatches( iChildPatch[1], nNewLevel ); }
//----------------------------------------------------------------------------- // Purpose: // Input : iParentPatch - // nLevel - //----------------------------------------------------------------------------- void CVRADDispColl::CreateChildPatchesFromRoot( int iParentPatch, int *pChildPatch ) { // Initialize the child patch indices. pChildPatch[0] = g_Patches.InvalidIndex(); pChildPatch[1] = g_Patches.InvalidIndex(); // Get the number of displacement subdivisions. int nInterval = GetWidth(); // Get the parent patch. CPatch *pParentPatch = &g_Patches[iParentPatch]; if ( !pParentPatch ) return; // Split along the longest edge. Vector vecEdges[4]; vecEdges[0] = pParentPatch->winding->p[1] - pParentPatch->winding->p[0]; vecEdges[1] = pParentPatch->winding->p[2] - pParentPatch->winding->p[1]; vecEdges[2] = pParentPatch->winding->p[3] - pParentPatch->winding->p[2]; vecEdges[3] = pParentPatch->winding->p[3] - pParentPatch->winding->p[0]; // Should the patch be subdivided - check the area. float flMaxLength = MAX( m_flSampleWidth, m_flSampleHeight ); float flMinEdgeLength = flMaxLength * dispchop; // Find the longest edge. float flEdgeLength = 0.0f; int iLongEdge = -1; for ( int iEdge = 0; iEdge < 4; ++iEdge ) { float flLength = vecEdges[iEdge].Length(); if ( flEdgeLength < flLength ) { flEdgeLength = vecEdges[iEdge].Length(); iLongEdge = iEdge; } } // Small enough already, return. if ( flEdgeLength < flMinEdgeLength ) return; // Test area as well so we don't allow slivers. float flMinArea = ( dispchop * flMaxLength ) * ( dispchop * flMaxLength ); Vector vecNormal = vecEdges[3].Cross( vecEdges[0] ); float flTestArea = VectorNormalize( vecNormal ); if ( flTestArea < flMinArea ) return; // Get the points for the first triangle. int iPoints[3]; Vector vecPoints[3]; float flArea; iPoints[0] = ( nInterval * nInterval ) - 1; iPoints[1] = 0; iPoints[2] = nInterval * ( nInterval - 1 ); for ( int iPoint = 0; iPoint < 3; ++iPoint ) { VectorCopy( m_aVerts[iPoints[iPoint]], vecPoints[iPoint] ); } // Create and initialize the patch. pChildPatch[0] = g_Patches.AddToTail(); if ( pChildPatch[0] == g_Patches.InvalidIndex() ) return; if ( !InitPatch( pChildPatch[0], iParentPatch, 0, vecPoints, iPoints, flArea ) ) { g_Patches.Remove( pChildPatch[0] ); pChildPatch[0] = g_Patches.InvalidIndex(); return; } // Get the points for the second triangle. iPoints[0] = 0; iPoints[1] = ( nInterval * nInterval ) - 1; iPoints[2] = nInterval - 1; for ( int iPoint = 0; iPoint < 3; ++iPoint ) { VectorCopy( m_aVerts[iPoints[iPoint]], vecPoints[iPoint] ); } // Create and initialize the patch. pChildPatch[1] = g_Patches.AddToTail(); if ( pChildPatch[1] == g_Patches.InvalidIndex() ) { g_Patches.Remove( pChildPatch[0] ); pChildPatch[0] = g_Patches.InvalidIndex(); return; } if ( !InitPatch( pChildPatch[1], iParentPatch, 1, vecPoints, iPoints, flArea ) ) { g_Patches.Remove( pChildPatch[0] ); pChildPatch[0] = g_Patches.InvalidIndex(); g_Patches.Remove( pChildPatch[1] ); pChildPatch[1] = g_Patches.InvalidIndex(); return; } }
extern PATCH_RET_CODE DoPatch( char *patchname, int doprompt, int dobackup, int printlevel, char *outfilename ) { char buffer[ sizeof( LEVEL ) ]; #ifndef _WPATCH char *target = NULL; #endif PATCH_RET_CODE ret; outfilename=outfilename; PatchName = patchname; DoPrompt = doprompt; DoBackup = dobackup; PrintLevel = printlevel; NewName = tmpnam( NULL ); #ifndef _WPATCH if( access( PatchName, R_OK ) != 0 ) { PatchError( ERR_CANT_FIND, PatchName ); return( PATCH_CANT_FIND_PATCH ); } #endif #if !defined( INSTALL_PROGRAM ) if( PrintLevel ) { GetLevel( PatchName ); if( CurrLevel[ 0 ] == '\0' ) { Message( MSG_NOT_PATCHED, PatchName ); } else { Message( MSG_PATCHED_TO_LEVEL, PatchName, CurrLevel ); } return( PATCH_RET_OKAY ); } #endif _splitpath( PatchName, NULL, NULL, NULL, buffer ); #ifndef _WPATCH ret = InitPatch( &target ); #else ret = InitPatch( &outfilename ); #endif #if defined( INSTALL_PROGRAM ) if( ret != PATCH_RET_OKAY ) { return( ret ); } if( outfilename != NULL ) { strcpy( outfilename, target ); PatchingFile( PatchName, outfilename ); } #endif #ifndef _WPATCH GetLevel( target ); if( stricmp( buffer, CurrLevel ) <= 0 ) { ClosePatch(); #if !defined( INSTALL_PROGRAM ) Message( MSG_ALREADY_PATCHED, target, CurrLevel ); #endif return( PATCH_ALREADY_PATCHED ); } else { #endif ret = Execute(); if( ret != PATCH_RET_OKAY ) { return( ret ); } #ifndef _WPATCH } #endif #if !defined( INSTALL_PROGRAM ) && !defined( _WPATCH ) Message( MSG_SUCCESSFULLY_PATCHED, target, buffer ); #endif return( PATCH_RET_OKAY ); }
PATCH_RET_CODE Execute( byte *dest ) { char *tmp; #else PATCH_RET_CODE Execute( void ) { char tmp[4]; #if defined(__386__) #if defined(_WPATCH) extern MY_FILE NewFile; #define InNew( offset ) ( Input( &NewFile, tmp, offset, \ sizeof(hole)), \ *(hole*)tmp ) #define OutNew( off, x, type ) *(type*)tmp = (x); \ Output( &NewFile, tmp, \ off, sizeof( type ) ); #else extern byte *NewFile; #define OutNew( off, x, type ) *(type*)(NewFile+off) = (x); #define InNew( off ) *(hole*)(NewFile+off) #endif #elif defined(BDUMP) #define InNew( offset ) 1 #define OutNew( off, x, type ) ( x ) #undef Dump #define Dump( x ) printf x #undef DOPROMPT #undef DOBACKUP #define DOPROMPT 0 #define DOBACKUP 0 #else extern MY_FILE NewFile; extern void Input( MY_FILE *file, void *tmp, foff off, size_t len ); #define InNew( offset ) ( Input( &NewFile, tmp, offset, \ sizeof(hole)), \ *(hole*)tmp ) extern void Output( MY_FILE *file, void *tmp, foff off, size_t len ); #define OutNew( off, x, type ) *(type*)tmp = (x); \ Output( &NewFile, tmp, \ off, sizeof( type ) ); #endif #endif patch_cmd cmd; byte next; hole diff; foff size; foff incr; foff iters; foff old_size; foff new_size; foff checksum; foff new_offset; foff old_offset; char ch; int havenew; PATCH_RET_CODE ret; PATCH_RET_CODE ret2; #ifdef BDIFF char *dummy = NULL; #endif havenew = 1; #ifdef BDIFF InitPatch( &dummy ); #endif old_size = InPatch( foff ); new_size = InPatch( foff ); checksum = InPatch( foff ); ret = OpenOld( old_size, DOPROMPT, new_size, checksum ); if( ret != PATCH_RET_OKAY ) goto error1; ret = OpenNew( new_size ); if( ret != PATCH_RET_OKAY ) goto error2; InitHoles(); for( ;; ) { #if defined( INSTALL_PROGRAM ) #if defined( WINNT ) || defined( WIN ) || defined( OS2 ) if( StatusCancelled() ) { ret = PATCH_RET_CANCEL; goto error3; } #endif #endif cmd = InPatch( patch_cmd ); if( cmd == CMD_DONE ) break; switch( cmd ) { case CMD_DIFFS: new_offset = InPatch( foff ); size = InPatch( foff ); Dump(( "Different new-%8.8lx size-%8.8lx\n", new_offset, size )); while( size != 0 ) { OutNew( new_offset, InPatch( byte ), byte ); ++new_offset; --size; } break; case CMD_SAMES: new_offset = InPatch( foff ); old_offset = InPatch( foff ); size = InPatch( foff ); Dump(( "Similar new-%8.8lx old-%8.8lx size-%8.8lx\n", new_offset, old_offset, size)); while( size != 0 ) { OutNew( new_offset, InOld( old_offset ), byte ); ++new_offset; ++old_offset; --size; } break; case CMD_ITER_HOLES: new_offset = InPatch( foff ); diff = InPatch( hole ); iters = InPatch( foff ); incr = InPatch( foff ); ch = InPatch( byte ); Dump(( "IterHole new-%8.8lx diff-%8.8lx iter-%8.8lx inc-%8.8lx\n", new_offset, diff, iters, incr )); while( iters != 0 ) { AddHole( new_offset, diff ); new_offset += incr; --iters; } break; case CMD_HOLES: new_offset = InPatch( foff ); diff = InPatch( hole ); for( ;; ) { Dump(( "Hole new-%8.8lx diff-%8.8lx\n",new_offset,diff)); AddHole( new_offset, diff ); next = InPatch( byte ); if( next == 0 ) break; if( ( next & 0x80 ) == 0 ) { new_offset += (foff)next & 0x7f; } else if( ( next & 0x40 ) == 0 ) { new_offset += ( (foff)next & 0x3f ) << 8; new_offset += (foff)InPatch( byte ); } else { new_offset += ( (foff)next & 0x3f ) << 16; new_offset += (foff)InPatch(byte) << 8; new_offset += (foff)InPatch(byte); } } break; default: PatchError( ERR_BAD_PATCHFILE, PatchName ); ret = PATCH_BAD_PATCH_FILE; goto error3; } } ret = PATCH_RET_OKAY; FlushHoles(); error3: FreeHoleArray(); ret2 = CloseNew( new_size, checksum, &havenew ); if( ret == PATCH_RET_OKAY ) { ret = ret2; } error2: CloseOld( havenew && DOPROMPT, DOBACKUP ); error1: ClosePatch(); return( ret ); }