First pass idLib conversion from hex rays4.

This commit is contained in:
Justin Marshall
2026-08-08 13:54:26 -07:00
parent 3d01d735ce
commit 09a4cb91c3
120 changed files with 17718 additions and 0 deletions
@@ -0,0 +1,180 @@
#include "bitblockallocator.h"
#include <algorithm>
#include <cstdlib>
#include <cstring>
idBitBlockAllocator::idBitBlockAllocator(const int blocksWide,
const int blocksHigh)
: width(std::max(0, blocksWide)), height(std::max(0, blocksHigh)),
bits(nullptr) {
const std::size_t count = static_cast<std::size_t>(width)
* static_cast<std::size_t>(height);
if (count != 0) {
bits = static_cast<unsigned char*>(std::calloc((count + 7u) / 8u, 1));
}
}
idBitBlockAllocator::~idBitBlockAllocator() {
std::free(bits);
}
void idBitBlockAllocator::Clear() {
if (bits != nullptr) {
const std::size_t count = static_cast<std::size_t>(width)
* static_cast<std::size_t>(height);
std::memset(bits, 0, (count + 7u) / 8u);
}
}
bool idBitBlockAllocator::Get(const int x, const int y) const {
if (bits == nullptr || x < 0 || y < 0 || x >= width || y >= height) {
return false;
}
const int bit = y * width + x;
return (bits[bit >> 3] & (1u << (bit & 7))) != 0;
}
void idBitBlockAllocator::Set(const int x, const int y) {
if (bits == nullptr || x < 0 || y < 0 || x >= width || y >= height) {
return;
}
const int bit = y * width + x;
bits[bit >> 3] |= static_cast<unsigned char>(1u << (bit & 7));
}
void idBitBlockAllocator::FillBlock(const int x, const int y,
const int w, const int h) {
for (int row = 0; row < h; ++row) {
for (int column = 0; column < w; ++column) {
Set(x + column, y + row);
}
}
}
void idBitBlockAllocator::FillBitBlock(const int x, const int y,
const idBitBlockAllocator& block) {
for (int row = 0; row < block.height; ++row) {
for (int column = 0; column < block.width; ++column) {
if (block.Get(column, row)) {
Set(x + column, y + row);
}
}
}
}
bool idBitBlockAllocator::TestBlock(const int x, const int y, const int w,
const int h, int* const fail) const {
if (w < 0 || h < 0 || x < 0 || y < 0 || x + w > width || y + h > height) {
return false;
}
if (fail != nullptr && fail[0] >= x && fail[0] < x + w
&& fail[1] >= y && fail[1] < y + h) {
return false;
}
for (int row = 0; row < h; ++row) {
for (int column = w - 1; column >= 0; --column) {
if (Get(x + column, y + row)) {
if (fail != nullptr) {
fail[0] = x + column;
fail[1] = y + row;
}
return false;
}
}
}
return true;
}
bool idBitBlockAllocator::TestBitBlock(const int x, const int y,
const idBitBlockAllocator& block) const {
if (x < 0 || y < 0 || x + block.width > width || y + block.height > height) {
return false;
}
for (int row = 0; row < block.height; ++row) {
for (int column = 0; column < block.width; ++column) {
if (block.Get(column, row) && Get(x + column, y + row)) {
return false;
}
}
}
return true;
}
bool idBitBlockAllocator::FindBlockLinear(int& x, int& y, const int w,
const int h) {
int fail[2] = { -1, -1 };
for (y = 0; y <= height - h; ++y) {
for (x = 0; x <= width - w; ++x) {
if (TestBlock(x, y, w, h, fail)) {
FillBlock(x, y, w, h);
return true;
}
}
}
return false;
}
bool idBitBlockAllocator::FindBitBlockLinear(int& x, int& y,
const idBitBlockAllocator& block) {
for (y = 0; y <= height - block.height; ++y) {
for (x = 0; x <= width - block.width; ++x) {
if (TestBitBlock(x, y, block)) {
FillBitBlock(x, y, block);
return true;
}
}
}
return false;
}
void SeparateBits(const int value, int& x, int& y) {
x = 0;
y = 0;
const unsigned int bits = static_cast<unsigned int>(value);
for (unsigned int index = 0; index < 16; ++index) {
x |= static_cast<int>(((bits >> (index * 2)) & 1u) << index);
y |= static_cast<int>(((bits >> (index * 2 + 1)) & 1u) << index);
}
}
void SeparateBits2(const int bits, int& x, int& y) {
SeparateBits(bits, x, y);
}
bool idBitBlockAllocator::FindBlockInterleaved(int& x, int& y, const int w,
const int h, int& searchPoint, const bool naturallyAlign) {
if (w > width || h > height || w < 0 || h < 0) {
return false;
}
if (searchPoint < 0) {
searchPoint = 0;
}
const int count = width * height;
int fail[2] = { -1, -1 };
const auto nextPowerOfTwo = [](const int value) {
int power = 1;
while (power < std::max(1, value)) {
power <<= 1;
}
return power;
};
const int alignX = nextPowerOfTwo(w);
const int alignY = nextPowerOfTwo(h);
for (; searchPoint < count; ++searchPoint) {
const int interleaved = naturallyAlign
? searchPoint
: ((searchPoint >> 1) ^ searchPoint);
SeparateBits2(interleaved, x, y);
if (naturallyAlign
&& (x / alignX != (x + std::max(0, w - 1)) / alignX
|| y / alignY != (y + std::max(0, h - 1)) / alignY)) {
continue;
}
if (TestBlock(x, y, w, h, fail)) {
FillBlock(x, y, w, h);
return true;
}
}
return false;
}