Skip to content

Commit 80363d5

Browse files
committed
feat: add MenuConsole and related classes
1 parent 44a0f96 commit 80363d5

7 files changed

Lines changed: 166 additions & 94 deletions

File tree

include/RE/B/BSStringT.h

Lines changed: 30 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -4,90 +4,15 @@
44

55
namespace RE
66
{
7-
template <class T, std::uint32_t N>
8-
class DynamicMemoryManagementPol
9-
{
10-
public:
11-
using value_type = T;
12-
13-
constexpr DynamicMemoryManagementPol() noexcept = default;
14-
DynamicMemoryManagementPol(const DynamicMemoryManagementPol&) = default;
15-
DynamicMemoryManagementPol(DynamicMemoryManagementPol&&) = default;
16-
~DynamicMemoryManagementPol() = default;
17-
18-
DynamicMemoryManagementPol& operator=(const DynamicMemoryManagementPol&) = default;
19-
DynamicMemoryManagementPol& operator=(DynamicMemoryManagementPol&&) = default;
20-
21-
[[nodiscard]] value_type* allocate(std::uint32_t a_num)
22-
{
23-
if (a_num > N) {
24-
return 0;
25-
}
26-
27-
auto size = a_num * sizeof(value_type);
28-
auto mem = malloc<value_type>(size);
29-
std::memset(mem, 0, size);
30-
return mem;
31-
}
32-
33-
void deallocate(value_type* a_ptr) { free(a_ptr); }
34-
};
35-
36-
template <class T, std::uint32_t N>
37-
class FixedLengthMemoryManagementPol
38-
{
39-
public:
40-
using value_type = T;
41-
42-
constexpr FixedLengthMemoryManagementPol() noexcept = default;
43-
44-
FixedLengthMemoryManagementPol(const FixedLengthMemoryManagementPol& a_rhs) { copy_from(a_rhs); }
45-
FixedLengthMemoryManagementPol(FixedLengthMemoryManagementPol&& a_rhs) { copy_from(a_rhs); }
46-
47-
~FixedLengthMemoryManagementPol() = default;
48-
49-
FixedLengthMemoryManagementPol& operator=(const FixedLengthMemoryManagementPol& a_rhs)
50-
{
51-
if (this != std::addressof(a_rhs)) {
52-
copy_from(a_rhs);
53-
}
54-
return *this;
55-
}
56-
57-
FixedLengthMemoryManagementPol& operator=(FixedLengthMemoryManagementPol&& a_rhs)
58-
{
59-
if (this != std::addressof(a_rhs)) {
60-
copy_from(a_rhs);
61-
}
62-
return *this;
63-
}
64-
65-
[[nodiscard]] value_type* allocate(std::uint32_t a_num)
66-
{
67-
return a_num > N ? 0 : _buffer;
68-
}
69-
70-
void deallocate(value_type*) { return; }
71-
72-
private:
73-
void copy_from(const FixedLengthMemoryManagementPol& a_rhs)
74-
{
75-
std::memcpy(_buffer, a_rhs._buffer, sizeof(value_type) * N);
76-
}
77-
78-
value_type _buffer[N]{ 0 }; // 00
79-
};
80-
81-
template <class CharT, std::uint32_t N, template <class, std::uint32_t> class Allocator>
82-
class BSStringT : public Allocator<CharT, N>
7+
template <class CharT>
8+
class BSStringT
839
{
8410
private:
85-
static constexpr auto MAX = static_cast<std::uint16_t>(N);
11+
static constexpr auto MAX{ static_cast<std::uint16_t>(-1) };
8612

8713
public:
8814
using value_type = CharT;
8915
using traits_type = std::char_traits<value_type>;
90-
using allocator_type = Allocator<value_type, N>;
9116
using size_type = std::uint16_t;
9217
using reference = value_type&;
9318
using const_reference = const value_type&;
@@ -99,14 +24,12 @@ namespace RE
9924
clear();
10025
}
10126

102-
BSStringT(const BSStringT& a_rhs) :
103-
allocator_type(a_rhs)
27+
BSStringT(const BSStringT& a_rhs)
10428
{
10529
set_cstr(a_rhs.c_str());
10630
}
10731

10832
BSStringT(BSStringT&& a_rhs) :
109-
allocator_type(std::move(a_rhs)),
11033
_data(a_rhs._data),
11134
_size(a_rhs._size),
11235
_capacity(a_rhs._capacity)
@@ -135,7 +58,6 @@ namespace RE
13558
BSStringT& operator=(const BSStringT& a_rhs)
13659
{
13760
if (this != std::addressof(a_rhs)) {
138-
static_cast<allocator_type&>(*this) = a_rhs;
13961
set_cstr(a_rhs.c_str());
14062
}
14163
return *this;
@@ -144,8 +66,6 @@ namespace RE
14466
BSStringT& operator=(BSStringT&& a_rhs)
14567
{
14668
if (this != std::addressof(a_rhs)) {
147-
static_cast<allocator_type&>(*this) = std::move(a_rhs);
148-
14969
_data = a_rhs._data;
15070
a_rhs._data = nullptr;
15171

@@ -225,19 +145,29 @@ namespace RE
225145

226146
[[nodiscard]] static int strnicmp(const wchar_t* a_lhs, const wchar_t* a_rhs, std::size_t len) { return _wcsnicmp(a_lhs, a_rhs, len); }
227147

228-
[[nodiscard]] pointer allocate(std::uint32_t a_num) { return allocator_type::allocate(a_num); }
148+
[[nodiscard]] pointer allocate(size_type a_num)
149+
{
150+
if (a_num > MAX) {
151+
return 0;
152+
}
153+
154+
auto size = a_num * sizeof(value_type);
155+
auto mem = malloc<value_type>(size);
156+
std::memset(mem, 0, size);
157+
return mem;
158+
}
229159

230-
void deallocate(pointer a_ptr) { allocator_type::deallocate(a_ptr); }
160+
void deallocate(pointer a_ptr) { free(a_ptr); }
231161

232-
bool set_cstr(const_pointer a_str, std::uint32_t a_len = 0)
162+
bool set_cstr(const_pointer a_str, size_type a_len = 0)
233163
{
234-
auto len = static_cast<std::uint16_t>(a_len);
164+
auto len = static_cast<size_type>(a_len);
235165
if (_data == a_str) {
236166
return true;
237167
}
238168

239169
if (len == 0) {
240-
len = static_cast<std::uint16_t>(traits_type::length(a_str));
170+
len = static_cast<size_type>(traits_type::length(a_str));
241171
}
242172

243173
const size_type newSize = len > MAX ? MAX : len;
@@ -269,12 +199,18 @@ namespace RE
269199
static constexpr value_type EMPTY[]{ 0 };
270200

271201
// members
272-
pointer _data{ nullptr }; // ?? (00)
273-
size_type _size{ 0 }; // ?? (08)
274-
size_type _capacity{ 0 }; // ?? (0A)
275-
std::uint32_t _pad0C{ 0 }; // ?? (0C)
202+
pointer _data{ nullptr }; // 00
203+
size_type _size{ 0 }; // 08
204+
size_type _capacity{ 0 }; // 0A
205+
std::uint32_t _pad0C{ 0 }; // 0C
276206
};
277207

278-
using BSString = BSStringT<char, static_cast<std::uint32_t>(-1), DynamicMemoryManagementPol>;
208+
using BSString = BSStringT<char>;
279209
static_assert(sizeof(BSString) == 0x10);
210+
211+
using BSStringC = BSStringT<char>;
212+
static_assert(sizeof(BSStringC) == 0x10);
213+
214+
using BSStringW = BSStringT<wchar_t>;
215+
static_assert(sizeof(BSStringW) == 0x10);
280216
}

include/RE/IDs.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ namespace RE::ID
1212
inline constexpr REL::Offset Singleton{ 0x8FE1E10 };
1313
}
1414

15+
namespace MenuConsole
16+
{
17+
inline constexpr REL::Offset Instance{ 0x665C360 };
18+
inline constexpr REL::Offset PrintLine{ 0x665C580 };
19+
}
20+
1521
namespace Setting
1622
{
1723
inline constexpr REL::Offset SetString{ 0x6710B70 };

include/RE/M/MenuConsole.h

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
3+
#include "RE/B/BSStringT.h"
4+
#include "RE/N/NiTList.h"
5+
6+
namespace RE
7+
{
8+
class ScriptCompiler;
9+
10+
class MenuConsole
11+
{
12+
public:
13+
static MenuConsole* Instance(bool a_create)
14+
{
15+
using func_t = decltype(&MenuConsole::Instance);
16+
static REL::Relocation<func_t> func{ ID::MenuConsole::Instance };
17+
return func(a_create);
18+
}
19+
20+
void PrintLine(const char* a_string, va_list a_args)
21+
{
22+
using func_t = void(MenuConsole::*)(const char*, va_list);
23+
static REL::Relocation<func_t> func{ ID::MenuConsole::PrintLine };
24+
return func(this, a_string, a_args);
25+
}
26+
27+
void PrintLine(const char* a_string, ...)
28+
{
29+
va_list args;
30+
va_start(args, a_string);
31+
PrintLine(a_string, args);
32+
va_end(args);
33+
}
34+
35+
// members
36+
ScriptCompiler* consoleCompiler;
37+
NiTList<BSString> strings;
38+
NiTList<BSString> inputs;
39+
std::int32_t inputsPos;
40+
std::int32_t numStrings;
41+
std::int32_t lastString;
42+
bool lastMenuMode;
43+
std::uint8_t visible;
44+
bool isActive;
45+
};
46+
static_assert(sizeof(MenuConsole) == 0x58);
47+
}

include/RE/N/NiTList.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#pragma once
2+
3+
#include "RE/N/NiTDefaultAllocator.h"
4+
#include "RE/N/NiTPointerListBase.h"
5+
6+
namespace RE
7+
{
8+
template <class T>
9+
class NiTList :
10+
public NiTPointerListBase<NiTDefaultAllocator<T>, T>
11+
{
12+
public:
13+
// override
14+
virtual ~NiTList(); // 00
15+
};
16+
static_assert(sizeof(NiTList<void*>) == 0x20);
17+
}

include/RE/N/NiTListBase.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#pragma once
2+
3+
#include "RE/N/NiTDefaultAllocator.h"
4+
#include "RE/N/NiTListItem.h"
5+
6+
namespace RE
7+
{
8+
template <class Allocator, class T>
9+
class NiTListBase
10+
{
11+
public:
12+
struct AntiBloatAllocator
13+
{
14+
public:
15+
// members
16+
std::uint32_t count; // 00
17+
};
18+
static_assert(sizeof(AntiBloatAllocator) == 0x04);
19+
20+
// add
21+
virtual ~NiTListBase(); // 00
22+
virtual NiTListItem<T>* NewItem() = 0; // 01
23+
virtual void DeleteItem(NiTListItem<T>*) = 0; // 02
24+
25+
// members
26+
NiTListItem<T>* head; // 08
27+
NiTListItem<T>* tail; // 10
28+
NiTListBase::AntiBloatAllocator allocator; // 18
29+
};
30+
static_assert(sizeof(NiTListBase<NiTDefaultAllocator<void*>, void*>) == 0x20);
31+
}

include/RE/N/NiTListItem.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#pragma once
2+
3+
namespace RE
4+
{
5+
template <class T>
6+
class NiTListItem
7+
{
8+
public:
9+
// members
10+
NiTListItem<T>* next; // 00
11+
NiTListItem<T>* prev; // 08
12+
T element; // 10
13+
};
14+
static_assert(sizeof(NiTListItem<void*>) == 0x18);
15+
}

include/RE/N/NiTPointerListBase.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#pragma once
2+
3+
#include "RE/N/NiTDefaultAllocator.h"
4+
#include "RE/N/NiTListBase.h"
5+
#include "RE/N/NiTListItem.h"
6+
7+
namespace RE
8+
{
9+
template <class Allocator, class T>
10+
class NiTPointerListBase :
11+
public NiTListBase<Allocator, T>
12+
{
13+
public:
14+
// override
15+
virtual ~NiTPointerListBase(); // 00
16+
virtual NiTListItem<T>* NewItem() override; // 01
17+
virtual void DeleteItem(NiTListItem<T>*) override; // 02
18+
};
19+
static_assert(sizeof(NiTPointerListBase<NiTDefaultAllocator<void*>, void*>) == 0x20);
20+
}

0 commit comments

Comments
 (0)