Skip to content

Commit 25aa632

Browse files
authored
Merge pull request #3 from powerof3/gamesettings
feat: `GameSettingCollection` and related RE
2 parents 212e70d + 3c53d48 commit 25aa632

File tree

15 files changed

+877
-0
lines changed

15 files changed

+877
-0
lines changed

CommonLibOB64/cmake/sourcelist.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,22 @@ set(SOURCES
55
include/OBSE/OBSE.h
66
include/OBSE/Trampoline.h
77
include/OBSE/Version.h
8+
include/RE/B/BSTCaseInsensitiveStringMap.h
9+
include/RE/G/GameSettingCollection.h
810
include/RE/IDs.h
11+
include/RE/M/MemoryManager.h
12+
include/RE/N/NiTDefaultAllocator.h
13+
include/RE/N/NiTMap.h
14+
include/RE/N/NiTMapBase.h
15+
include/RE/N/NiTStringMap.h
916
include/RE/NiRTTI_IDs.h
1017
include/RE/Oblivion.h
1118
include/RE/RTTI.h
1219
include/RE/RTTI_IDs.h
20+
include/RE/S/Setting.h
21+
include/RE/S/SettingCollection.h
22+
include/RE/S/SettingCollectionMap.h
23+
include/RE/S/SettingT.h
1324
include/RE/VTABLE_IDs.h
1425
include/REL/ASM.h
1526
include/REL/Hook.h
@@ -68,6 +79,7 @@ set(SOURCES
6879
src/OBSE/Impl/PCH.cpp
6980
src/OBSE/Interfaces.cpp
7081
src/RE/Oblivion.cpp
82+
src/RE/S/Setting.cpp
7183
src/REL/HookObject.cpp
7284
src/REL/HookStore.cpp
7385
src/REL/IAT.cpp
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "RE/N/NiTStringMap.h"
4+
5+
namespace RE
6+
{
7+
// 28
8+
template <class T>
9+
class BSTCaseInsensitiveStringMap : public NiTStringMap<T>
10+
{
11+
private:
12+
using base = NiTStringMap<T>;
13+
14+
public:
15+
using key_type = typename base::key_type;
16+
17+
virtual ~BSTCaseInsensitiveStringMap(); // 00
18+
19+
// override (NiTStringMap<T>)
20+
std::uint32_t hash_function(key_type a_key) const override; // 01
21+
bool key_eq(key_type a_lhs, key_type a_rhs) const override; // 02
22+
};
23+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#pragma once
2+
3+
#include "RE/S/Setting.h"
4+
#include "RE/S/SettingCollectionMap.h"
5+
6+
namespace RE
7+
{
8+
class GameSettingCollection : public SettingCollectionMap<Setting>
9+
{
10+
public:
11+
inline static constexpr auto RTTI = RTTI::GameSettingCollection;
12+
inline static constexpr auto VTABLE = VTABLE::GameSettingCollection;
13+
14+
~GameSettingCollection() override; // 00
15+
16+
// override (SettingCollectionMap<Setting>)
17+
bool WriteSetting(Setting* a_setting) override; // 03 - { return false; }
18+
bool ReadSetting(Setting* a_setting) override; // 04
19+
bool OpenHandle(bool a_create) override; // 05 - { return handle != 0; }
20+
bool CloseHandle() override; // 06 - { handle = 0; return true; }
21+
22+
// add
23+
virtual void Unk_0A(void); // 0A
24+
25+
static GameSettingCollection* GetSingleton()
26+
{
27+
static REL::Relocation<GameSettingCollection*> singleton{ ID::GameSettingCollection::Singleton };
28+
return singleton.get();
29+
}
30+
31+
Setting* GetSetting(const char* a_name)
32+
{
33+
auto it = settings.find(a_name);
34+
return it != settings.end() ? it->second : nullptr;
35+
}
36+
};
37+
static_assert(sizeof(GameSettingCollection) == 0x140);
38+
}

CommonLibOB64/include/RE/IDs.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,18 @@
22

33
namespace RE::ID
44
{
5+
namespace GameSettingCollection
6+
{
7+
inline constexpr REL::Offset Singleton{ 0x8FE1E10 };
8+
}
9+
10+
namespace Setting
11+
{
12+
inline constexpr REL::Offset SetString{ 0x6710B70 };
13+
}
14+
15+
inline constexpr REL::Offset malloc{ 0x472FD40 };
16+
inline constexpr REL::Offset free{ 0x0E30580 };
17+
518
inline constexpr REL::Offset RTDynamicCast{ 0x6C23656 };
619
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#pragma once
2+
3+
namespace RE
4+
{
5+
inline void* malloc(std::size_t a_size)
6+
{
7+
using func_t = decltype(&malloc);
8+
static REL::Relocation<func_t> func{ ID::malloc };
9+
return func(a_size);
10+
}
11+
12+
template <class T>
13+
inline T* malloc(std::size_t a_size)
14+
{
15+
return static_cast<T*>(malloc(a_size));
16+
}
17+
18+
template <class T>
19+
inline T* malloc()
20+
{
21+
return malloc<T>(sizeof(T));
22+
}
23+
24+
inline void* calloc(std::size_t a_num, std::size_t a_size)
25+
{
26+
const auto ret = malloc(a_num * a_size);
27+
if (ret) {
28+
std::memset(ret, 0, a_num * a_size);
29+
}
30+
return ret;
31+
}
32+
33+
template <class T>
34+
inline T* calloc(std::size_t a_num, std::size_t a_size)
35+
{
36+
return static_cast<T*>(calloc(a_num, a_size));
37+
}
38+
39+
template <class T>
40+
inline T* calloc(std::size_t a_num)
41+
{
42+
return calloc<T>(a_num, sizeof(T));
43+
}
44+
45+
inline void free(void* a_ptr)
46+
{
47+
if (a_ptr) {
48+
using func_t = decltype(&free);
49+
static REL::Relocation<func_t> func{ ID::free };
50+
func(a_ptr);
51+
}
52+
}
53+
}
54+
55+
#define TES_HEAP_REDEFINE_NEW() \
56+
[[nodiscard]] inline void* operator new(std::size_t a_count) \
57+
{ \
58+
const auto mem = RE::malloc(a_count); \
59+
if (mem) { \
60+
return mem; \
61+
} else { \
62+
stl::report_and_fail("out of memory"sv); \
63+
} \
64+
} \
65+
\
66+
[[nodiscard]] inline void* operator new[](std::size_t a_count) \
67+
{ \
68+
const auto mem = RE::malloc(a_count); \
69+
if (mem) { \
70+
return mem; \
71+
} else { \
72+
stl::report_and_fail("out of memory"sv); \
73+
} \
74+
} \
75+
\
76+
[[nodiscard]] constexpr void* operator new(std::size_t, void* a_ptr) noexcept { return a_ptr; } \
77+
[[nodiscard]] constexpr void* operator new[](std::size_t, void* a_ptr) noexcept { return a_ptr; } \
78+
[[nodiscard]] constexpr void* operator new(std::size_t, std::align_val_t, void* a_ptr) noexcept { return a_ptr; } \
79+
[[nodiscard]] constexpr void* operator new[](std::size_t, std::align_val_t, void* a_ptr) noexcept { return a_ptr; } \
80+
\
81+
inline void operator delete(void* a_ptr) { RE::free(a_ptr); } \
82+
inline void operator delete[](void* a_ptr) { RE::free(a_ptr); } \
83+
inline void operator delete(void* a_ptr, std::size_t) { RE::free(a_ptr); } \
84+
inline void operator delete[](void* a_ptr, std::size_t) { RE::free(a_ptr); }
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include "RE/M/MemoryManager.h"
4+
5+
#define NiTDefaultAllocator DFALL
6+
7+
namespace RE
8+
{
9+
template <class T>
10+
class NiTDefaultAllocator
11+
{
12+
public:
13+
void* Allocate()
14+
{
15+
return malloc(sizeof(T));
16+
}
17+
18+
void Deallocate(void* a_ptr)
19+
{
20+
return free(a_ptr);
21+
}
22+
};
23+
}
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#pragma once
2+
3+
#include "RE/N/NiTDefaultAllocator.h"
4+
#include "RE/N/NiTMapBase.h"
5+
6+
namespace RE
7+
{
8+
template <class Key, class T>
9+
class NiTMap : public NiTMapBase<NiTDefaultAllocator<NiTMapItem<Key, T>>, Key, T>
10+
{
11+
private:
12+
using Base = NiTMapBase<NiTDefaultAllocator<NiTMapItem<Key, T>>, Key, T>;
13+
14+
public:
15+
using key_type = typename Base::key_type;
16+
using mapped_type = typename Base::mapped_type;
17+
using value_type = typename Base::value_type;
18+
using size_type = typename Base::size_type;
19+
20+
NiTMap(std::uint32_t a_hashSize = 37) :
21+
Base(a_hashSize)
22+
{}
23+
24+
~NiTMap() override // 00
25+
{}
26+
27+
protected:
28+
using Base::_allocator;
29+
30+
// override (NiTMapBase)
31+
value_type* malloc_value() override // 05
32+
{
33+
return static_cast<value_type*>(_allocator.Allocate());
34+
}
35+
36+
void free_value(value_type* a_value) override // 06
37+
{
38+
if (a_value) {
39+
a_value->~value_type();
40+
_allocator.Deallocate(a_value);
41+
}
42+
}
43+
};
44+
static_assert(sizeof(NiTMap<void*, void*>) == 0x20);
45+
}

0 commit comments

Comments
 (0)