Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion config/SZBE69/symbols.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39031,7 +39031,7 @@ __ct__16CharBonesSamplesFv = .text:0x804B1B20; // type:function size:0x64
__dt__16CharBonesSamplesFv = .text:0x804B1B84; // type:function size:0x7C
Set__16CharBonesSamplesFRCQ211stlpmtx_std77vector<Q29CharBones4Bone,Us,Q211stlpmtx_std31StlNodeAlloc<Q29CharBones4Bone>>iQ29CharBones15CompressionType = .text:0x804B1C00; // type:function size:0x80
Clone__16CharBonesSamplesFRC16CharBonesSamples = .text:0x804B1C80; // type:function size:0x68
fn_804B1CE8 = .text:0x804B1CE8; // type:function size:0x14
SetStartFromRawData__16CharBonesSamplesFi = .text:0x804B1CE8; // type:function size:0x14
NumSamples__16CharBonesSamplesCFv = .text:0x804B1CFC; // type:function size:0x8
AllocateSize__16CharBonesSamplesFv = .text:0x804B1D04; // type:function size:0x10
FracToSample__16CharBonesSamplesCFPf = .text:0x804B1D14; // type:function size:0x160
Expand Down
102 changes: 74 additions & 28 deletions src/system/char/CharBones.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include "char/CharBones.h"
#include "char/CharClip.h"
#include "decomp.h"
#include "math/Mtx.h"
#include "math/Rot.h"
#include "math/Vec.h"
#include "utl/MakeString.h"
#include "utl/Symbols.h"

void TestDstComplain(Symbol s) {
Expand All @@ -16,7 +21,7 @@ CharBones::CharBones() : mCompression(kCompressNone), mStart(0), mTotalSize(0) {
}

CharBones::Type CharBones::TypeOf(Symbol s) {
for (const char *p = s.Str(); p != 0; p++) {
for (const char *p = s.Str(); *p != 0; p++) {
if (*p == '.') {
switch (p[1]) {
case 'p':
Expand All @@ -26,9 +31,10 @@ CharBones::Type CharBones::TypeOf(Symbol s) {
case 'q':
return TYPE_QUAT;
case 'r': {
// check if rot is x, y, or z
unsigned char next = p[3];
if (next + 0x88U <= 2)
return (Type)(next - 0x75);
if ((unsigned char)(next - 'x') <= 2)
return (Type)((char)next - 'u');
}
default:
break;
Expand Down Expand Up @@ -100,32 +106,20 @@ void CharBones::ListBones(std::list<Bone> &bones) const {

void CharBones::Zero() { memset(mStart, 0, mTotalSize); }

// enum CompressionType {
// kCompressNone,
// kCompressRots,
// kCompressVects,
// kCompressQuats,
// kCompressAll
// };

int CharBones::TypeSize(int i) const {
if (i < 2) {
if (mCompression < kCompressVects)
return 0xC;
else
return 6;
}
if (i != 2) {
if (mCompression == kCompressNone)
return 4;
else
return 2;
if(i > 1U){
if(i != 2){
if(mCompression != kCompressNone) return 2;
else return 4;
}
else {
if(mCompression >= kCompressQuats) return 4;
else if(mCompression != kCompressNone) return 8;
else return 16;
}
}
if (mCompression > kCompressVects)
return 4;
if (mCompression == kCompressNone)
return 0x10;
return 8;
else if(mCompression >= kCompressVects) return 6;
else return 12;
}

int CharBones::FindOffset(Symbol s) const {
Expand Down Expand Up @@ -173,12 +167,64 @@ void CharBones::SetCompression(CompressionType ty) {
}
}

DECOMP_FORCEACTIVE(CharBones, "!mCompression && !bones.mCompression")

const char* CharBones::StringVal(Symbol s){
void* ptr = FindPtr(s);
CharBones::Type t = TypeOf(s);
if(t < 2){
if(mCompression >= 2){
Vector3 vshort((short*)ptr);
return MakeString("%g %g %g", vshort.x, vshort.y, vshort.z);
}
else {
Vector3* vptr = (Vector3*)vptr;
return MakeString("%g %g %g", vptr->x, vptr->y, vptr->z);
}
}
else if(t == 2){
Hmx::Quat q;
Hmx::Quat* qPtr = (Hmx::Quat*)ptr;
if(mCompression >= 3){
ByteQuat* bqPtr = (ByteQuat*)qPtr;
bqPtr->ToQuat(q);
}
else if(mCompression != kCompressNone){
ShortQuat* sqPtr = (ShortQuat*)qPtr;
sqPtr->ToQuat(q);
}
else q = *qPtr;
Vector3 v40;
MakeEuler(q, v40);
v40 *= RAD2DEG;
return MakeString("quat(%g %g %g %g) euler(%g %g %g)", q.x, q.y, q.z, q.w, v40.x, v40.y, v40.z);
}
else {
float floatVal;
if(mCompression != kCompressNone){
floatVal = *((short*)ptr) * 0.00061035156f;
}
else {
floatVal = *((float*)ptr);
}
floatVal *= RAD2DEG;
if(mCompression != kCompressNone){
return MakeString("deg %g raw %d", floatVal, *((short*)ptr));
}
else {
return MakeString("deg %g rad %g", floatVal, *((float*)ptr));
}
}
}

void CharBones::Print() {
for (std::vector<Bone>::iterator it = mBones.begin(); it != mBones.end(); ++it) {
MILO_LOG("%s %.2f: %s\n", (*it).name, (*it).weight, StringVal((*it).name));
MILO_LOG("%s %.2f: %s\n", it->name, it->weight, StringVal(it->name));
}
}

DECOMP_FORCEACTIVE(CharBones, "!mCompression", "false", "newSize == 4", "oldSize == 2", "end >= start")

void CharBones::ScaleAdd(CharClip *clip, float f1, float f2, float f3) {
clip->ScaleAdd(*this, f1, f2, f3);
}
Expand Down
1 change: 1 addition & 0 deletions src/system/char/CharBones.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ class CharBones {
char *RotYOffset() const { return mStart + mRotYOffset; }
char *RotZOffset() const { return mStart + mRotZOffset; }
char *EndOffset() const { return mStart + mEndOffset; }
char* SetStart(char* ptr){ mStart = ptr; }

static Type TypeOf(Symbol);
static const char *SuffixOf(Type);
Expand Down
169 changes: 163 additions & 6 deletions src/system/char/CharBonesSamples.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
#include "char/CharBonesSamples.h"
#include "char/CharBones.h"
#include "decomp.h"
#include "math/Mtx.h"
#include "os/Debug.h"
#include "utl/BinStream.h"
#include "utl/MemMgr.h"
#include "utl/Symbols.h"

int gVer;
Expand All @@ -12,6 +17,11 @@ DECOMP_FORCEACTIVE(
"CharBonesSamples are already compressed, can't remove bones."
)

DECOMP_FORCEACTIVE(CharBonesSamples,
"FracToSample: sample is %d, clip only has %d samples, frac was %g, is %g",
"FracToSample: frac is %g, outside of 0 and 1"
)

CharBonesSamples::CharBonesSamples() : mNumSamples(0), mPreviewSample(0), mRawData(0) {}

CharBonesSamples::~CharBonesSamples() { _MemFree(mRawData); }
Expand All @@ -34,10 +44,9 @@ void CharBonesSamples::Clone(const CharBonesSamples &samp) {
mFrames = samp.mFrames;
}

#pragma push
#pragma force_active on
inline int CharBonesSamples::AllocateSize() { return mTotalSize * mNumSamples; }
#pragma pop
FORCE_LOCAL_INLINE
int CharBonesSamples::AllocateSize() { return mTotalSize * mNumSamples; }
END_FORCE_LOCAL_INLINE

void CharBonesSamples::RotateBy(CharBones &bones, int i) {
mStart = &mRawData[mTotalSize * i];
Expand All @@ -63,7 +72,7 @@ void CharBonesSamples::ScaleAddSample(CharBones &bones, float f1, int i, float f
}

void CharBonesSamples::Print() {
MILO_LOG(
TheDebug << MakeString(
"samples: %d size: %d address: %x compression %d\n",
mNumSamples,
AllocateSize(),
Expand Down Expand Up @@ -107,11 +116,159 @@ void CharBonesSamples::Load(BinStream &bs) {
LoadData(bs);
}

void CharBonesSamples::ReadCounts(BinStream& bs, int i2){
int i = 0;
int numTypesToRead = Min(7, i2);
for(; i < numTypesToRead; i++){
bs >> mCounts[i];
}
for(int numTypesRead = i; numTypesRead < i2; numTypesRead++){
int tmp;
bs >> tmp;
MILO_ASSERT((tmp - mCounts[NUM_TYPES - 1]) == 0, 0x2B2);
}
for(; i < 7; i++){
mCounts[i] = 0;
}
}

void CharBonesSamples::LoadHeader(BinStream& bs){
_MemFree(mRawData);
int numBones; bs >> numBones;
mBones.resize(numBones);
if(gVer > 0xA){
for(int i = 0; i < numBones; i++){
bs >> mBones[i];
}
}
else {
for(int i = 0; i < numBones; i++){
bs >> mBones[i].name;
}
}

if(gVer > 9){
ReadCounts(bs, gVer > 0xF ? 7 : 10);
bs >> (int&)mCompression;
int numSamples;
bs >> numSamples;
MILO_ASSERT(numSamples < 32767, 0x2D7);
mNumSamples = numSamples;
}
else {
int i;
if (gVer > 5) {
int count;
if (gVer > 7) {
count = 9;
} else {
count = 10;
if (gVer > 6)
count = 6;
}
for(i = 0; i < count; i++){
int sp14;
bs >> sp14;
}
bs >> (int&)mCompression;
int numSamples;
bs >> numSamples;
MILO_ASSERT(numSamples < 32767, 0x2F1);
mNumSamples = numSamples;
}
else {
int numSamples;
bs >> numSamples;
MILO_ASSERT(numSamples < 32767, 0x2FC);
mNumSamples = numSamples;
if(gVer > 3){
bs >> (int&)mCompression;
}
}
for(i = 0; i < 7; i++){
mCounts[i] = 0;
}
for(i = 0; i < mBones.size(); i++){
mCounts[CharBones::TypeOf(mBones[i].name) + 1]++;
}
for(i = 1; i < 7; i++){
mCounts[i] += mCounts[i-1];
}
}

if(gVer > 0xB){
bs >> mFrames;
}
else mFrames.clear();
RecomputeSizes();
mRawData = (char*)_MemAlloc(AllocateSize(), 0);
}

void CharBonesSamples::LoadData(BinStream& bs){
if(gVer == 0xE){
bool x; bs >> x;
}
for(int i = 0; i < mNumSamples; i++){
SetStartFromRawData(Min(i, mNumSamples - 1));

if(mCompression >= kCompressVects){
short* offset = (short*)QuatOffset();
for(short* p = (short*)Start(); p < offset; p += 3){
bs >> p[0] >> p[1] >> p[2];
}
}
else {
Vector3* offset = (Vector3*)QuatOffset();
for(Vector3* p = (Vector3*)Start(); p < offset; p++){
bs >> *p;
}
}

if(mCompression >= kCompressQuats){
char* offset = RotXOffset();
for(char* p = QuatOffset(); p < offset; p += 4){
bs >> p[0] >> p[1] >> p[2] >> p[3];
}
}
else if(mCompression != kCompressNone){
short* offset = (short*)RotXOffset();
for(short* p = (short*)QuatOffset(); p < offset; p += 4){
bs >> p[0] >> p[1] >> p[2] >> p[3];
}
}
else {
Hmx::Quat* offset = (Hmx::Quat*)RotXOffset();
for(Hmx::Quat* p = (Hmx::Quat*)QuatOffset(); p < offset; p++){
bs >> *p;
}
}

if(mCompression != kCompressNone){
short* offset = (short*)EndOffset();
for(short* p = (short*)RotXOffset(); p < offset; p++){
bs >> *p;
}
}
else {
float* offset = (float*)EndOffset();
for(float* p = (float*)RotXOffset(); p < offset; p++){
bs >> *p;
}
}

if((i & 0x7F) == 0x7F){
while(bs.Eof() == TempEof){
Timer::Sleep(0);
}
}
}
}

void CharBonesSamples::SetPreview(int i) {
int tmp = Clamp(0, mNumSamples - 1, i);
MILO_ASSERT(mPreviewSample < 32767, 0x38B);
mPreviewSample = tmp;
mStart = &mRawData[mTotalSize * tmp];
mStart = &mRawData[mTotalSize * mPreviewSample];
}

BEGIN_PROPSYNCS(CharBonesSamples)
Expand Down
12 changes: 12 additions & 0 deletions src/system/char/CharBonesSamples.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,18 @@ class CharBonesSamples : public CharBones {
static void SetVer(int);
int NumSamples() const { return mNumSamples; }

void SetStartFromRawData(int idx){
SetStart(&mRawData[mTotalSize * idx]);
}
// set mStart to mRawData[mTotalSize * 2];

// void fn_804B1CE8(int param_1,int param_2)

// {
// fn_8034D25C(param_1,*(param_1 + 0x54) + *(param_1 + 0x4c) * param_2);
// return;
// }

short mNumSamples; // 0x50
short mPreviewSample; // 0x52
char *mRawData; // 0x54
Expand Down
Loading