Initial CPlayerState RE

This commit is contained in:
Phillip Stephens 2016-03-19 12:19:43 -07:00
parent 572b5167fe
commit 62e8066a63
9 changed files with 243 additions and 48 deletions

View File

@ -13,6 +13,27 @@ struct CTweakGame : ITweakGame
DECL_YAML
String<-1> m_worldPrefix;
String<-1> m_ruinsArea; // ????
Value<float> m_fov;
Value<bool> unknown1;
Value<bool> unknown2;
Value<bool> unknown3;
Value<bool> unknown4;
Value<float> unknown5;
Value<float> unknown6;
Value<float> unknown7;
Value<float> unknown8;
Value<float> unknown9;
Value<float> unknown10;
Value<float> unknown11;
Value<float> unknown12;
Value<float> unknown13;
Value<float> unknown14;
Value<float> unknown15;
Value<float> unknown16;
Value<float> unknown17;
Value<float> unknown18;
Value<float> hardmodeDamageMult;
Value<float> hardmodeWeaponMult;
virtual const std::string& GetWorldPrefix() const { return m_worldPrefix; }
CTweakGame(athena::io::IStreamReader& in) { this->read(in); }

View File

@ -5,7 +5,6 @@
#include "Runtime/CGameAllocator.hpp"
#include <functional>
#include "ViewManager.hpp"
#include "Runtime/Particle/CElementGen.hpp"
static logvisor::Module AthenaLog("Athena");
static void AthenaExc(athena::error::Level level, const char* file,

View File

@ -4,7 +4,7 @@
namespace urde
{
CGameState::CGameState(CInputStream& stream)
CGameState::CGameState(CBitStreamReader& stream)
: m_stateFlag(stream.readUint32Big()), m_playerState(stream), m_gameTime(stream.readFloatBig())
{}

View File

@ -19,7 +19,7 @@ class CGameState
CGameOptions m_gameOpts;
public:
CGameState() {}
CGameState(CInputStream& stream);
CGameState(CBitStreamReader& stream);
void SetCurrentWorldId(unsigned int id, const std::string& name);
CWorldTransManager& WorldTransitionManager() {return m_transManager;}
};

View File

@ -1,12 +1,135 @@
#include "CPlayerState.hpp"
#include "IOStreams.hpp"
namespace urde
{
/* TODO: Implement this properly */
/* NOTE: This is only to be used as a reference,
* and is not indicative of how the actual format is structured
* a proper RE is still required!
*/
CPlayerState::CPlayerState(CInputStream& stream)
: m_staticIntf(5)
const u32 CPlayerState::PowerUpMaxes[41] =
{ 1, 1, 1, 1, 250, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 14, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
};
const char* PowerUpNames[41]=
{
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Missiles",
"Unknown",
"Unknown",
"Power Bombs",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Energy Tanks",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
"Unknown",
};
CPlayerState::CPlayerState(CBitStreamReader& in)
: x188_staticIntf(5)
{
x0_24_ = true;
in.readUint32Big();
in.readBool();
in.readBool();
in.readBool();
atInt8 data[0xAE];
in.readBytesToBuf(data, 0xAE);
for (u32 k = 0; k < 3; k++)
{
printf("Game %i\n", k+1);
atInt8 save[0x3AC];
in.readBytesToBuf(save, 0x3AC);
{
CBitStreamReader stream(save, 0x3AC);
printf("Game State\n");
for (u32 i = 0; i < 0x80; i++)
printf("%i\n", stream.ReadEncoded(8));
s32 tmp = stream.ReadEncoded(32);
printf("%i\n", tmp);
tmp = stream.ReadEncoded(1);
printf("%i\n", tmp);
tmp = stream.ReadEncoded(1);
printf("%i\n", tmp);
tmp = stream.ReadEncoded(32);
printf("%f\n", *reinterpret_cast<float*>(&tmp));
tmp = stream.ReadEncoded(32);
printf("%f\n", *reinterpret_cast<float*>(&tmp));
tmp = stream.ReadEncoded(32);
printf("%x\n", tmp);
printf("PlayerState\n");
x4_ = stream.ReadEncoded(0x20);
printf("%x\n", tmp);
tmp = stream.ReadEncoded(0x20);
printf("Base health %f\n", *reinterpret_cast<float*>(&tmp));
xc_baseHealth = *reinterpret_cast<float*>(&tmp);
x8_ = stream.ReadEncoded(CBitStreamReader::GetBitCount(5));
printf("%i\n", x8_);
x20_ = stream.ReadEncoded(CBitStreamReader::GetBitCount(4));
printf("%i\n", x20_);
x24_powerups.resize(41);
printf("Powerups\n");
for (u32 i = 0; i < x24_powerups.size(); ++i)
{
if (PowerUpMaxes[i] == 0)
continue;
u32 a = stream.ReadEncoded(CBitStreamReader::GetBitCount(PowerUpMaxes[i]));
u32 b = stream.ReadEncoded(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++)
{
u32 tmp = stream.ReadEncoded(1);
printf("%i\n", tmp);
}
tmp = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
printf("%i\n", tmp);
tmp = stream.ReadEncoded(CBitStreamReader::GetBitCount(0x100));
printf("%i\n", tmp);
}
}
}
}

View File

@ -5,28 +5,43 @@
#include "CBasics.hpp"
#include "CStaticInterference.hpp"
#include "IOStreams.hpp"
#include "rstl.hpp"
namespace urde
{
class CPlayerState
{
CStaticInterference m_staticIntf;
static const u32 PowerUpMaxes[41];
class CPowerUp
{
int m_a = 0;
int m_b = 0;
int x0_a = 0;
int x4_b = 0;
public:
CPowerUp() {}
CPowerUp(int a, int b) : m_a(a), m_b(b) {}
CPowerUp(int a, int b) : x0_a(a), x4_b(b) {}
};
union
{
struct { bool x0_24_ : 1; bool x0_25_ : 1; bool x0_26_; };
u32 dummy = 0;
};
CPowerUp m_powerups[29];
u32 x4_ = 0;
u32 x8_ = 0;
float xc_baseHealth = 99.f;
float x10_ = 50.f;
u32 x14_ = 0;
u32 x18_ = x14_;
float x1c_ = 0.2f;
u32 x20_ = 0;
rstl::reserved_vector<CPowerUp, 41> x24_powerups;
CStaticInterference x188_staticIntf;
public:
CPlayerState() : m_staticIntf(5) {}
CPlayerState(CInputStream& stream);
CPlayerState() : x188_staticIntf(5) { x0_24_ = true; }
CPlayerState(CBitStreamReader& stream);
};
}
#endif // __PSHAG_CPLAYERSTATE_HPP__

View File

@ -3,42 +3,49 @@
namespace urde
{
s32 DecryptionCtx::DecryptRead(CInputStream& in, s32 key)
/*!
* \brief CBitStreamReader::ReadBit
* Reads and decodes an encoded value from a bitstream.
* \param bitCount How many bits to read
* \return s32 The encoded value
*/
s32 CBitStreamReader::ReadEncoded(u32 bitCount)
{
int ret = 0;
if (x20_encShift >= key)
s32 ret = 0;
if (bitCount < x20_bitOffset)
{
int diff = x20_encShift - 0x20;
int baseVal = -1;
if (x20_encShift != 0x20)
baseVal = 1 << (x20_encShift - 1);
x20_encShift = key - x20_encShift;
ret = baseVal | (x1c_encVal >> diff);
u32 diff = 0x20 - bitCount;
u32 baseVal = -1;
if (x20_bitOffset != 0x20)
baseVal = (1 << bitCount) - 1;
x20_bitOffset -= bitCount;
ret = baseVal & (x1c_val >> diff);
x1c_val <<= bitCount;
}
else
{
int diff = x20_encShift - key;
int rem = x20_encShift - 0x20;
int baseVal1 = -1;
if (x20_encShift != 0x20)
baseVal1 = 1 << (x20_encShift - 1);
u32 diff = bitCount - x20_bitOffset;
u32 baseVal = -1;
if (x20_bitOffset != 32)
baseVal = (1 << x20_bitOffset) - 1;
int bit = diff & 7;
x20_encShift = 0;
int count = (diff >> 3) + ((-bit | bit) >> 31);
int baseVal2 = (baseVal1 & (x1c_encVal >> rem)) << diff;
in.readBytesToBuf(&x1c_encVal, count);
u32 bit = diff & 7;
baseVal &= (x1c_val >> (32 - x20_bitOffset));
baseVal <<= diff;
x20_bitOffset = 0;
u32 count = (diff >> 3) + ((-bit | bit) >> 31);
readUBytesToBuf(&x1c_val, count);
/* The game uses Big Endian, which doesn't work for us */
/* Little Endian sucks */
athena::utility::BigUint32(x1c_val);
int baseVal3 = -1;
if (diff != 0x20)
baseVal3 = 1 << (diff - 1);
u32 baseVal2 = -1;
if (diff != 32)
baseVal2 = (1 << diff) - 1;
int tmpShift = x20_encShift;
x20_encShift = (count << 3);
ret = baseVal2 | (baseVal3 & (x1c_encVal >> (diff - 0x20))) << tmpShift;
x20_encShift = diff - x20_encShift;
x1c_encVal = x1c_encVal >> diff;
ret = baseVal | (baseVal2 & (x1c_val >> (32 - diff))) << x20_bitOffset;
x20_bitOffset = (count << 3) - diff;
x1c_val <<= diff;
}
return ret;

View File

@ -12,11 +12,41 @@ namespace urde
using CInputStream = athena::io::IStreamReader;
using COutputStream = athena::io::IStreamWriter;
struct DecryptionCtx
struct CBitStreamReader : athena::io::MemoryCopyReader
{
s32 x1c_encVal;
s32 x20_encShift;
s32 DecryptRead(CInputStream& in, s32 key);
u32 x1c_val = 0;
u32 x20_bitOffset = 0;
public:
static s32 GetBitCount(s32 unk)
{
s32 ret = 0;
while (unk != 0)
{
unk /= 2;
ret++;
}
return ret;
}
CBitStreamReader(const void* data, atUint64 length)
: MemoryCopyReader(data, length)
{
}
CBitStreamReader(const std::string& filename)
: MemoryCopyReader(filename)
{
}
atUint64 readUBytesToBuf(void *buf, atUint64 len)
{
x20_bitOffset = 0;
atUint64 tmp = MemoryCopyReader::readUBytesToBuf(buf, len);
return tmp;
}
s32 ReadEncoded(u32 key);
};
using CMemoryInStream = athena::io::MemoryReader;

View File

@ -34,14 +34,14 @@ void CTweaks::RegisterTweaks()
std::unique_ptr<CInputStream> strm;
strm.reset(loader.LoadNewResourceSync(IDFromFactory(factory, "Game"), nullptr));
TOneStatic<DNAMP1::CTweakGame> game(*strm);
TOneStatic<DataSpec::DNAMP1::CTweakGame> game(*strm);
g_tweakGame = game.GetAllocSpace();
strm.reset(loader.LoadNewResourceSync(IDFromFactory(factory, "Player"), nullptr));
TOneStatic<DNAMP1::CTweakPlayer> player(*strm);
TOneStatic<DataSpec::DNAMP1::CTweakPlayer> player(*strm);
g_tweakPlayer = player.GetAllocSpace();
strm.reset(loader.LoadNewResourceSync(IDFromFactory(factory, "PlayerControls"), nullptr));
TOneStatic<DNAMP1::CTweakPlayerControl> playerControl(*strm);
TOneStatic<DataSpec::DNAMP1::CTweakPlayerControl> playerControl(*strm);
g_tweakPlayerControl = playerControl.GetAllocSpace();
#endif
}