4
Fork 0
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

205 lines
3.5 KiB

#pragma once
#include "skse64_common/Utilities.h"
#include "skse64/GameTypes.h"
class VMClassInfo;
// ??
class VMIdentifier
{
public:
enum
{
kLockBit = 0x80000000,
kFastSpinThreshold = 10000
};
SInt32 m_refCount; // 00
UInt32 unk04; // 04
VMClassInfo * m_type; // 08
void * unk08; // 10
void * unk0C; // 18
volatile UInt64 m_handle; // 20
volatile SInt32 m_lock; // 28
UInt64 GetHandle(void);
SInt32 Lock(void);
void Unlock(SInt32 oldLock);
// lock and refcount?
void IncrementLock(void);
SInt32 DecrementLock(void);
void Destroy(void);
MEMBER_FN_PREFIX(VMIdentifier);
DEFINE_MEMBER_FN(Destroy_Internal, void, 0x0135EA90);
};
// 10
class VMValue
{
public:
VMValue() :type(kType_None) { data.p = 0; }
~VMValue() { CALL_MEMBER_FN(this, Destroy)(); }
VMValue(const VMValue & other)
{
if (&other != this)
{
type = kType_None;
data.p = nullptr;
CALL_MEMBER_FN(this, Set)(&other);
}
}
VMValue& operator=(const VMValue& other)
{
if (&other == this)
return *this;
CALL_MEMBER_FN(this, Set)(&other);
return *this;
}
enum
{
kType_None = 0,
kType_Identifier = 1,
kType_String = 2,
kType_Int = 3,
kType_Float = 4,
kType_Bool = 5,
kType_Unk0B = 0x0B,
kType_ArraysStart = 11,
kType_StringArray = 12,
kType_IntArray = 13,
kType_FloatArray = 14,
kType_BoolArray = 15,
kType_ArraysEnd = 16,
kNumLiteralArrays = 4
};
// 18+
struct ArrayData
{
volatile SInt32 refCount; // 00
UInt32 unk04; // 04
UInt64 unk08; // 08
UInt32 len; // 10
UInt32 unk14; // 14
UInt64 unk18; // 18
//VMValue data[0]; // 20
VMValue * GetData(void) { return (VMValue *)(this + 1); }
MEMBER_FN_PREFIX(ArrayData);
DEFINE_MEMBER_FN(Destroy, void, 0x0136C5D0);
};
UInt64 type; // 00
union
{
SInt32 i;
UInt32 u;
float f;
bool b;
void * p;
ArrayData * arr;
VMIdentifier * id;
const char * str; // BSFixedString
BSFixedString * GetStr(void) { return (BSFixedString *)(&str); }
} data; // 04
MEMBER_FN_PREFIX(VMValue);
DEFINE_MEMBER_FN(Set, void, 0x013623F0, const VMValue * src);
DEFINE_MEMBER_FN(Destroy, void, 0x013622F0);
DEFINE_MEMBER_FN(SetArray, void, 0x01361320, ArrayData * data);
bool IsIdentifierArray()
{
return (type >= kType_ArraysEnd && type & kType_Identifier);
}
bool IsLiteralArray()
{
return type - kType_ArraysStart <= kNumLiteralArrays;
}
bool IsArray()
{
return IsLiteralArray() || IsIdentifierArray();
}
void SetNone(void)
{
CALL_MEMBER_FN(this, Destroy)();
type = kType_None;
data.u = 0;
}
void SetInt(SInt32 i)
{
CALL_MEMBER_FN(this, Destroy)();
type = kType_Int;
data.i = i;
}
void SetFloat(float f)
{
CALL_MEMBER_FN(this, Destroy)();
type = kType_Float;
data.f = f;
}
void SetBool(bool b)
{
CALL_MEMBER_FN(this, Destroy)();
type = kType_Bool;
data.b = b;
}
void SetIdentifier(VMClassInfo * classInfo)
{
CALL_MEMBER_FN(this, Destroy)();
type = (UInt64)classInfo;
data.id = NULL;
}
void SetIdentifier(VMIdentifier ** identifier)
{
if (GetUnmangledType() == kType_Identifier)
{
CALL_MEMBER_FN(this, Destroy)();
if (*identifier)
(*identifier)->IncrementLock();
data.id = *identifier;
}
}
void SetString(const char * str)
{
CALL_MEMBER_FN(this, Destroy)();
type = kType_String;
CALL_MEMBER_FN(data.GetStr(), Set)(str);
}
// 00-0F are untouched
// 10+ alternate between 0x01 and 0x0B
UInt32 GetUnmangledType(void);
bool IsIdentifier(void) { return GetUnmangledType() == kType_Identifier; }
};