bool GeneratorData::CanPlaceRoom( RoomDesc const& roomDesc, glm::vec2 pos ) const { for (int32_t ry = 0; ry < roomDesc.GetCellCount(); ++ry) { for (int32_t rx = 0; rx < roomDesc.GetCellCount(); ++rx) { glm::vec2 relPos = glm::vec2( rx, ry ); glm::vec2 targetPos = pos + relPos; if (roomDesc.IsFilled( relPos )) { if (!IsInBounds( targetPos )) { L1( "%d,%d is out of bounds\n", targetPos.x, targetPos.y ); return false; //cell is out of bounds } if (IsFilled( targetPos )) { L1( "%d,%d is already filled %d\n", targetPos.x, targetPos.x, IsFilled( targetPos ) ); return false; //cell is already filled this room cant be placed } } } } return true; }
void GeneratorData::PlaceRoom( RoomDesc const& roomDesc, glm::vec2 pos ) { for (int32_t ry = 0; ry < roomDesc.GetCellCount(); ++ry) { for (int32_t rx = 0; rx < roomDesc.GetCellCount(); ++rx) { glm::vec2 relPos = glm::vec2( rx, ry ); glm::vec2 targetPos = pos + relPos; if (IsInBounds( targetPos ) && roomDesc.IsFilled( relPos ) && !IsFilled( targetPos )) { auto& cell = GetGCell( targetPos ); cell.mFilled = true; cell.mGRoomDescIndex = mGRoomDescs.size(); L1( "%d,%d is now filled %d\n", targetPos.x, targetPos.y, cell.mFilled ); } } } GRoomDesc gRoomDesc; gRoomDesc.mRoomCoord = pos; gRoomDesc.mRoomDesc = roomDesc; gRoomDesc.mRoomDesc.ClearProperties(); gRoomDesc.mRoomDesc.ClearCellEntrances(); mGRoomDescs.push_back( gRoomDesc ); GenerateGraph(); }
void* Chunk::Allocate(std::size_t blockSize) { if ( IsFilled() ) return NULL; assert((firstAvailableBlock_ * blockSize) / blockSize == firstAvailableBlock_); unsigned char * pResult = pData_ + (firstAvailableBlock_ * blockSize); firstAvailableBlock_ = *pResult; --blocksAvailable_; return pResult; }
bool ASSISTANT::Oval::ContainsPoint(Gdiplus::PointF &ptMouse) { if (!visible) return false; CRect rcObject; GetBoundingBox(rcObject); CRgn rgnElliptic; double dMaxDistance = (double)lineWidth / 2 + 0.5; BOOL bRet = TRUE; if (IsFilled()) { CRgn rgnElliptic; bRet = rgnElliptic.CreateEllipticRgnIndirect(rcObject); if (!bRet) return false; if (rgnElliptic.PtInRegion((int)ptMouse.X, (int)ptMouse.Y)) return true; } else { CRect rcOutside = rcObject; rcOutside.InflateRect(dMaxDistance, dMaxDistance, dMaxDistance, dMaxDistance); bRet = rgnElliptic.CreateEllipticRgnIndirect(rcOutside); if (!bRet) return false; CRgn rgnElliptic2; CRect rcInside = rcObject; rcInside.DeflateRect(dMaxDistance, dMaxDistance, dMaxDistance, dMaxDistance); bRet = rgnElliptic2.CreateEllipticRgnIndirect(rcInside); if (!bRet) return false; rgnElliptic.CombineRgn(&rgnElliptic, &rgnElliptic2, RGN_DIFF); if (rgnElliptic.PtInRegion((int)ptMouse.X, (int)ptMouse.Y)) return true; } return false; }
bool Chunk::IsBlockAvailable( void * p, unsigned char numBlocks, std::size_t blockSize ) const { (void) numBlocks; if ( IsFilled() ) return false; unsigned char * place = static_cast< unsigned char * >( p ); // Alignment check assert( ( place - pData_ ) % blockSize == 0 ); unsigned char blockIndex = static_cast< unsigned char >( ( place - pData_ ) / blockSize ); unsigned char index = firstAvailableBlock_; assert( numBlocks > index ); if ( index == blockIndex ) return true; /* If the bit at index was set in foundBlocks, then the stealth index was found on the linked-list. */ std::bitset< UCHAR_MAX > foundBlocks; unsigned char * nextBlock = NULL; for ( unsigned char cc = 0; ; ) { nextBlock = pData_ + ( index * blockSize ); foundBlocks.set( index, true ); ++cc; if ( cc >= blocksAvailable_ ) // Successfully counted off number of nodes in linked-list. break; index = *nextBlock; if ( index == blockIndex ) return true; assert( numBlocks > index ); assert( !foundBlocks.test( index ) ); } return false; }
bool Chunk::IsCorrupt( unsigned char numBlocks, std::size_t blockSize, bool checkIndexes ) const { if ( numBlocks < blocksAvailable_ ) { // Contents at this Chunk corrupted. This might mean something has // overwritten memory owned by the Chunks container. assert( false ); return true; } if ( IsFilled() ) // Useless to do further corruption checks if all blocks allocated. return false; unsigned char index = firstAvailableBlock_; if ( numBlocks <= index ) { // Contents at this Chunk corrupted. This might mean something has // overwritten memory owned by the Chunks container. assert( false ); return true; } if ( !checkIndexes ) // Caller chose to skip more complex corruption tests. return false; /* If the bit at index was set in foundBlocks, then the stealth index was found on the linked-list. */ std::bitset< UCHAR_MAX > foundBlocks; unsigned char * nextBlock = NULL; /* The loop goes along singly linked-list of stealth indexes and makes sure that each index is within bounds (0 <= index < numBlocks) and that the index was not already found while traversing the linked-list. The linked- list should have exactly blocksAvailable_ nodes, so the for loop will not check more than blocksAvailable_. This loop can't check inside allocated blocks for corruption since such blocks are not within the linked-list. Contents of allocated blocks are not changed by Chunk. Here are the types of corrupted link-lists which can be verified. The corrupt index is shown with asterisks in each example. Type 1: Index is too big. numBlocks == 64 blocksAvailable_ == 7 firstAvailableBlock_ -> 17 -> 29 -> *101* There should be no indexes which are equal to or larger than the total number of blocks. Such an index would refer to a block beyond the Chunk's allocated domain. Type 2: Index is repeated. numBlocks == 64 blocksAvailable_ == 5 firstAvailableBlock_ -> 17 -> 29 -> 53 -> *17* -> 29 -> 53 ... No index should be repeated within the linked-list since that would indicate the presence of a loop in the linked-list. */ for ( unsigned char cc = 0; ; ) { nextBlock = pData_ + ( index * blockSize ); foundBlocks.set( index, true ); ++cc; if ( cc >= blocksAvailable_ ) // Successfully counted off number of nodes in linked-list. break; index = *nextBlock; if ( numBlocks <= index ) { /* This catches Type 1 corruptions as shown in above comments. This implies that a block was corrupted due to a stray pointer or an operation on a nearby block overran the size of the block. */ assert( false ); return true; } if ( foundBlocks.test( index ) ) { /* This catches Type 2 corruptions as shown in above comments. This implies that a block was corrupted due to a stray pointer or an operation on a nearby block overran the size of the block. Or perhaps the program tried to delete a block more than once. */ assert( false ); return true; } } if ( foundBlocks.count() != blocksAvailable_ ) { /* This implies that the singly-linked-list of stealth indexes was corrupted. Ideally, this should have been detected within the loop. */ assert( false ); return true; } return false; }