Add CBitStreamReader

This commit is contained in:
Phillip Stephens 2016-03-19 21:10:29 -07:00
parent 4960f683fd
commit 193e21943d
4 changed files with 92 additions and 12 deletions

View File

@ -77,34 +77,50 @@ CPlayerState::CPlayerState(CBitStreamReader& in)
in.readBytesToBuf(save, 0x3AC);
{
CBitStreamReader stream(save, 0x3AC);
std::string filename = athena::utility::sprintf("Game%i.dat", k + 1);
CBitStreamWriter w{filename};
printf("Game State\n");
for (u32 i = 0; i < 0x80; i++)
printf("%i\n", stream.ReadEncoded(8));
{
u32 tmp = stream.ReadEncoded(8);
printf("%i\n", tmp);
w.WriteEncoded(tmp, 8);
}
s32 tmp = stream.ReadEncoded(32);
w.WriteEncoded(tmp, 0x20);
printf("%i\n", tmp);
tmp = stream.ReadEncoded(1);
w.WriteEncoded(tmp, 1);
printf("%i\n", tmp);
tmp = stream.ReadEncoded(1);
w.WriteEncoded(tmp, 1);
printf("%i\n", tmp);
tmp = stream.ReadEncoded(32);
w.WriteEncoded(tmp, 0x20);
printf("%f\n", *reinterpret_cast<float*>(&tmp));
tmp = stream.ReadEncoded(32);
w.WriteEncoded(tmp, 0x20);
printf("%f\n", *reinterpret_cast<float*>(&tmp));
tmp = stream.ReadEncoded(32);
printf("%x\n", tmp);
w.WriteEncoded(tmp, 0x20);
printf("PlayerState\n");
x4_ = stream.ReadEncoded(0x20);
w.WriteEncoded(x4_, 0x20);
printf("%x\n", tmp);
tmp = stream.ReadEncoded(0x20);
printf("Base health %f\n", *reinterpret_cast<float*>(&tmp));
xc_baseHealth = *reinterpret_cast<float*>(&tmp);
w.WriteEncoded(tmp, 0x20);
x8_ = stream.ReadEncoded(CBitStreamReader::GetBitCount(5));
printf("%i\n", x8_);
w.WriteEncoded(x8_, CBitStreamReader::GetBitCount(5));
x20_ = stream.ReadEncoded(CBitStreamReader::GetBitCount(4));
printf("%i\n", x20_);
w.WriteEncoded(x20_, CBitStreamReader::GetBitCount(4));
x24_powerups.resize(41);
printf("Powerups\n");
for (u32 i = 0; i < x24_powerups.size(); ++i)
@ -114,20 +130,27 @@ CPlayerState::CPlayerState(CBitStreamReader& in)
u32 a = stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxes[i]));
u32 b = stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxes[i]));
w.WriteEncoded(a, CBitStreamReader::GetBitCount(PowerUpMaxes[i]));
w.WriteEncoded(b, CBitStreamReader::GetBitCount(PowerUpMaxes[i]));
x24_powerups[i] = CPowerUp(a, b);
printf("%2i(%15s): a=%i b=%i\n", i, PowerUpNames[i], a, b);
}
for (u32 i = 0; i < 0x34e; i++)
for (u32 i = 0; i < 0x304 * 8; i++)
{
u32 tmp = stream.ReadEncoded(1);
printf("%i\n", tmp);
w.WriteEncoded(tmp, 1);
}
tmp = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
printf("%i\n", tmp);
w.WriteEncoded(tmp, CBitStreamReader::GetBitCount(0x100));
tmp = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
printf("%i\n", tmp);
w.WriteEncoded(tmp, CBitStreamReader::GetBitCount(0x100));
w.save();
}
}
}

View File

@ -29,12 +29,9 @@ s32 CBitStreamReader::ReadEncoded(u32 bitCount)
if (x20_bitOffset != 32)
baseVal = (1 << x20_bitOffset) - 1;
u32 bit = diff & 7;
baseVal &= (x1c_val >> (32 - x20_bitOffset));
baseVal <<= diff;
baseVal = (baseVal & (x1c_val >> (32 - x20_bitOffset))) << diff;
x20_bitOffset = 0;
u32 count = (diff >> 3) + ((-bit | bit) >> 31);
readUBytesToBuf(&x1c_val, count);
readUBytesToBuf(&x1c_val, 4);
/* The game uses Big Endian, which doesn't work for us */
/* Little Endian sucks */
athena::utility::BigUint32(x1c_val);
@ -44,13 +41,47 @@ s32 CBitStreamReader::ReadEncoded(u32 bitCount)
baseVal2 = (1 << diff) - 1;
ret = baseVal | (baseVal2 & (x1c_val >> (32 - diff))) << x20_bitOffset;
x20_bitOffset = (count << 3) - diff;
x20_bitOffset = (4 << 3) - diff;
x1c_val <<= diff;
}
return ret;
}
void CBitStreamWriter::WriteEncoded(u32 val, u32 bitCount)
{
if (x18_bitOffset >= bitCount)
{
int baseVal = -1;
if (bitCount != 32)
baseVal = (1 << bitCount) - 1;
x14_val |= (val & baseVal) << (x18_bitOffset - bitCount);
x18_bitOffset -= bitCount;
}
else
{
u32 diff = bitCount - x18_bitOffset;
u32 baseVal = -1;
if (x18_bitOffset != 32)
baseVal = (1 << x18_bitOffset) - 1;
x14_val |= (val >> diff) & baseVal;
x18_bitOffset = 0;
u32 tmp = x14_val;
athena::utility::BigUint32(tmp);
writeBytes(&tmp, 4);
u32 rem = 32 - diff;
baseVal = -1;
if (diff != 32)
baseVal = (1 << diff) - 1;
x14_val = (val & baseVal) << rem;
x18_bitOffset -= diff;
}
}
class CZipSupport
{
public:

View File

@ -17,12 +17,12 @@ struct CBitStreamReader : athena::io::MemoryCopyReader
u32 x1c_val = 0;
u32 x20_bitOffset = 0;
public:
static s32 GetBitCount(s32 unk)
static s32 GetBitCount(s32 maxVal)
{
s32 ret = 0;
while (unk != 0)
while (maxVal != 0)
{
unk /= 2;
maxVal /= 2;
ret++;
}
@ -49,6 +49,32 @@ public:
s32 ReadEncoded(u32 key);
};
class CBitStreamWriter : public athena::io::MemoryCopyWriter
{
private:
u32 x14_val = 0;
u32 x18_bitOffset = 32;
public:
static inline u32 GetBitCount(u32 maxVal) { return CBitStreamReader::GetBitCount(maxVal); }
CBitStreamWriter(atUint8* data = nullptr, atUint64 length=0x10)
: MemoryCopyWriter(data, length)
{}
CBitStreamWriter(const std::string& filename)
: MemoryCopyWriter(filename)
{}
void writeUBytes(const atUint8 *data, atUint64 len)
{
x14_val = 0;
x18_bitOffset = 0x20;
MemoryCopyWriter::writeUBytes(data, len);
}
void WriteEncoded(u32 val, u32 bitCount);
};
using CMemoryInStream = athena::io::MemoryReader;
class CZipInputStream : public CInputStream

2
hecl

@ -1 +1 @@
Subproject commit e9b881d42b42d0efa0cde85cfc0e029777df18a7
Subproject commit 5a83ba09d46970db3452ab3084ff0b469b746490