Skip to content

Commit

Permalink
Fixed up small_vector and small_string; this is a breaking change and…
Browse files Browse the repository at this point in the history
… requires users to set their own _Malloc and _Free functions using the provided function signatures!
  • Loading branch information
SK83RJOSH committed Nov 21, 2020
1 parent 08d00de commit f990b96
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 40 deletions.
2 changes: 1 addition & 1 deletion entities/entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ namespace Teardown { namespace Entities {
inline static function_signature<void(__fastcall*)(Entity* ptr, small_string& result, small_string* tag)> GetTagValue = { "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x41\x56\x41\x57\x48\x83\xEC\x30\x33\xDB" };
inline static function_signature<void(__fastcall*)(Entity* ptr, Entity* parent)> SetParent = { "\x4C\x8B\xC1\x48\x8B\x49\x10\x48\x8B\x41\x20" };
inline static function_signature<Entity*(__fastcall*)(Entity* ptr, Type type)> FindParentOfType = { "\x48\x8B\x41\x10\x48\x85\xC0\x74\x2A\x0F\x1F\x80\x00\x00\x00\x00" };
inline static function_signature<void(__fastcall*)(Entity* ptr, small_vector<Entity>* list, uint32_t type, bool recursive)> FindChildrenOfType = { "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\x59\x20" };
inline static function_signature<void(__fastcall*)(Entity* ptr, small_vector<Entity*>* list, uint32_t type, bool recursive)> FindChildrenOfType = { "\x48\x89\x5C\x24\x08\x48\x89\x6C\x24\x10\x48\x89\x74\x24\x18\x57\x48\x83\xEC\x20\x48\x8B\x59\x20" };
};

static_assert(sizeof(Entity::vftable) == 0x20u, "Entity::vftable size is incorrect!");
Expand Down
2 changes: 1 addition & 1 deletion internal/vox_loader.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "types.h"
#include "../types.h"

namespace Teardown { namespace Internal { namespace VoxLoader {
#pragma pack(push, 1)
Expand Down
32 changes: 16 additions & 16 deletions scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ namespace Teardown {
int32_t m_Ignored;
bool m_RejectTransparent;
uint8_t m_Pad[3];
small_vector<Entities::Body> m_IgnoredBodies;
small_vector<Entities::Body*> m_IgnoredBodies;
Entities::Body* m_IgnoredBodiesMemory[4]; // small_vector should support pre-reserved buffers... not going to add that right now.
small_vector<Entities::Shape> m_IgnoredShapes;
small_vector<Entities::Shape*> m_IgnoredShapes;
};

int64_t vftptr_0;
Expand Down Expand Up @@ -63,20 +63,20 @@ namespace Teardown {
uint32_t dword_14C;
uint64_t dword_150;
uint64_t qword_158;
small_vector<Entities::Entity> m_EntityLists[12];
small_vector<Entities::Entity> m_RootEntities;
small_vector<Entities::Body>* m_Bodies;
small_vector<Entities::Shape>* m_Shapes;
small_vector<Entities::Light>* m_Lights;
small_vector<Entities::Entity>* m_Locations;
small_vector<Entities::Entity>* m_Waters;
small_vector<Entities::Entity>* m_Enemies;
small_vector<Entities::Entity>* m_Joints;
small_vector<Entities::Entity*> m_EntityLists[12];
small_vector<Entities::Entity*> m_RootEntities;
small_vector<Entities::Body*>* m_Bodies;
small_vector<Entities::Shape*>* m_Shapes;
small_vector<Entities::Light*>* m_Lights;
small_vector<Entities::Entity*>* m_Locations;
small_vector<Entities::Entity*>* m_Waters;
small_vector<Entities::Entity*>* m_Enemies;
small_vector<Entities::Entity*>* m_Joints;
small_vector<Entities::Vehicle*>* m_Vehicles;
small_vector<Entities::Wheel>* m_Wheels;
small_vector<Entities::Entity>* m_Screens;
small_vector<Entities::Entity>* m_Triggers;
small_vector<Entities::Entity>* m_Scripts;
small_vector<Entities::Wheel*>* m_Wheels;
small_vector<Entities::Entity*>* m_Screens;
small_vector<Entities::Entity*>* m_Triggers;
small_vector<Entities::Entity*>* m_Scripts;
uint64_t qword_290;
uint64_t qword_298;
uint64_t qword_2A0;
Expand All @@ -101,7 +101,7 @@ namespace Teardown {
uint8_t gap_790[128];

inline static function_signature<bool(__fastcall*)(Scene* ptr, Vector3_f32* pos, Vector3_f32* dir, float dist, RaycastFilter* f, float* out_dist, Vector3_f32* out_pos, Entities::Shape** out_shape, VoxelsPaletteInfo* out_palette)> Raycast = { "\x48\x8B\xC4\x4C\x89\x40\x18\x48\x89\x50\x10\x55\x56\x57\x41\x54\x41\x55\x41\x56\x41\x57\x48\x8D\xA8\x38\xFC\xFF\xFF" };
inline static function_signature<bool(__fastcall*)(Scene* ptr, small_vector<Entities::Shape>* out_hit, Vector3_f32* pos, Vector3_f32* dir, RaycastFilter* f)> RaycastIntersect = { "\x4C\x8B\xDC\x57\x41\x56\x41\x57\x48\x81\xEC\x50\x0C\x00\x00\x48\xC7\x44\x24\x20\xFE\xFF\xFF\xFF\x49\x89\x5B\x08\x49\x89\x6B\x10\x49\x89\x73\x18\x49\x8B\xF1" };
inline static function_signature<bool(__fastcall*)(Scene* ptr, small_vector<Entities::Shape*>* out_hit, Vector3_f32* pos, Vector3_f32* dir, RaycastFilter* f)> RaycastIntersect = { "\x4C\x8B\xDC\x57\x41\x56\x41\x57\x48\x81\xEC\x50\x0C\x00\x00\x48\xC7\x44\x24\x20\xFE\xFF\xFF\xFF\x49\x89\x5B\x08\x49\x89\x6B\x10\x49\x89\x73\x18\x49\x8B\xF1" };
inline static function_signature<bool(__fastcall*)(Scene* ptr, Vector3_f32* pos, float radius)> CreateExplosion = { "\x48\x8B\xC4\xF3\x0F\x11\x50\x18\x55" };
inline static function_signature<bool(__fastcall*)(Scene* ptr, Vector3_f32* pos, Vector3_f32* dir, __int32 type)> CreateProjectile = { "\x48\x89\x5C\x24\x08\x57\x48\x81\xEC\x80\x00\x00\x00" };
};
Expand Down
89 changes: 67 additions & 22 deletions types.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once

#include <cstddef>
#include <cassert>
#include <cstdint>
#include <cstdlib>
Expand Down Expand Up @@ -47,6 +48,25 @@ namespace Teardown {
Vector4_f32 m_Rotation;
};

// Misuse of these will cause crashes if used improperly!
// I'm forcing you to initialize them somewhere inside of your code to ensure correct usage.
// You can find Teardown's instances of malloc and free using signature scanning. If you are exceptionally lazy you can initialize these using pointers to <cstdlib.h> with &malloc and &free.
// Be aware, if you pass data to Teardown using the incorrect malloc then you will crash, trigger asserts, and leak memory. So don't be lazy; use the signatures in <teardown/game.h>!
extern void* (__cdecl* _Malloc)(size_t size);
extern void(__fastcall* _Free)(void* mem);


/*
* Helper class for interacting with Teardown strings.
*
* This string is only meant to be used to forward and receive data from the game.
*
* It does not support:
* Copying and assignment
* Modifications
*
* You are welcome to submit pull requests for these if you wish.
*/
class small_string
{
public:
Expand All @@ -57,7 +77,7 @@ namespace Teardown {

if (len > 15)
{
dst = (char*)malloc(len + 1);
dst = (char*)_Malloc(len + 1);

if (dst == nullptr)
{
Expand All @@ -66,7 +86,7 @@ namespace Teardown {

if (m_StackBuffer[15])
{
free(m_HeapBuffer);
_Free(m_HeapBuffer);
}
else
{
Expand All @@ -79,10 +99,12 @@ namespace Teardown {
memcpy(dst, str, len);
dst[len] = 0;
}
small_string(const small_string&) = delete;
void operator=(const small_string&) = delete;
~small_string() {
if (m_StackBuffer[15])
{
free(m_HeapBuffer);
_Free(m_HeapBuffer);
}
}

Expand All @@ -95,59 +117,80 @@ namespace Teardown {
};
};

/*
* Helper class for interacting with Teardown vectors.
*
* This vector is only meant to be used to forward and receive data from the game.
*
* It does not support:
* Copying and assignment
* Non-trivially constructible types
* Insertion, deletion, modification
*
* You are welcome to submit pull requests for these if you wish.
*/
template<typename T>
class small_vector {
public:
small_vector() {};
small_vector(uint32_t capacity) { reserve(capacity); };
small_vector(const small_vector&) = delete;
void operator=(const small_vector&) = delete;
~small_vector() { clear(); }

T** begin() const { return m_Data; }
T** end() const { return m_Data + m_Size; }
T** data() const { return m_Data; }
T* begin() const { return m_Data; }
T* end() const { return m_Data + m_Size; }
T* data() const { return m_Data; }
uint32_t size() const { return m_Size; }
uint32_t capacity() const { return m_Capacity; }

void reserve(uint32_t capacity) {
T** data = m_Data;
uint32_t size = m_Size;

if (auto memory = malloc(sizeof(T) * capacity))
if (auto memory = (T*)_Malloc(sizeof(T) * capacity))
{
m_Size = 0;
m_Capacity = capacity;
m_Data = (T**)memory;
memset(m_Data, 0, sizeof(T) * capacity);
T* data = m_Data;
uint32_t size = m_Size;

if (data)
if (data != nullptr)
{
if (size > m_Capacity)
if (size >= capacity)
{
size = capacity;
}
else
{
size = m_Capacity;
memset(memory, sizeof(T) * size, sizeof(T) * capacity - size);
}

m_Size = capacity;
memcpy(m_Data, data, sizeof(T) * size);
free(data);
_Free(data);
m_Size = size;
}
else
{
m_Size = 0;
memset(memory, 0, sizeof(T) * capacity);
}

m_Data = memory;
m_Capacity = capacity;
}
}

void clear()
{
if (m_Data)
if (m_Data != nullptr)
{
m_Size = 0;
m_Capacity = 0;
free(m_Data);
_Free(m_Data);
m_Data = nullptr;
}
}

private:
uint32_t m_Size = 0;
uint32_t m_Capacity = 0;
T** m_Data = nullptr;
T* m_Data = nullptr;
};

/*
Expand All @@ -157,6 +200,8 @@ namespace Teardown {
* decltype(Teardown::Game::Update)::Type Game_Update = FindSignature(Teardown::Game.Signature);
*
* FindSignature is a user defined function accepting a const* char which scans the main Teardown.exe module.
*
* These signatures do not have a "mask" on purpose. I use (*) \x2A to represent wildcards. This maps to an unused instruction in x86/x64.
*/
template<typename T>
struct function_signature
Expand Down

0 comments on commit f990b96

Please sign in to comment.