Skip to content

Commit

Permalink
feat: add VirtualMachine, GameVM, a shitton of other stuff [Resubmitt…
Browse files Browse the repository at this point in the history
…ing with attempted build fixes] (#251)

Resubmit and fix of
#220
from @nikitalita, hoping the triggered builds either work or tell us
what's wrong.

---------

Co-authored-by: nikitalita <[email protected]>
  • Loading branch information
BrodyHiggerson and nikitalita authored Jul 24, 2024
1 parent 3a56616 commit 2449439
Show file tree
Hide file tree
Showing 52 changed files with 2,725 additions and 40 deletions.
6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ endif()
option(SFSE_SUPPORT_XBYAK "Enables trampoline support for Xbyak." OFF)
option(SFSE_BUILD_TESTS "Builds the tests." OFF)

set(Boost_USE_STATIC_RUNTIME OFF CACHE BOOL "")

# info
project(
CommonLibSF
Expand All @@ -22,6 +24,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_DEBUG OFF)
set(CMAKE_OPTIMIZE_DEPENDENCIES ON)
set(Boost_USE_STATIC_LIBS ON)

set_property(GLOBAL PROPERTY USE_FOLDERS ON)

Expand All @@ -34,6 +37,7 @@ endif()

# dependencies
find_package(spdlog CONFIG REQUIRED)
find_package(boost MODULE REQUIRED)

file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/include/*"
Expand All @@ -49,6 +53,7 @@ function(configure_target TARGET_NAME)
target_compile_definitions(
${TARGET_NAME}
PUBLIC
BOOST_STL_INTERFACES_DISABLE_CONCEPTS
WINVER=0x0A00 # windows 10, minimum supported version by starfield
_WIN32_WINNT=0x0A00
"$<$<BOOL:${SFSE_SUPPORT_XBYAK}>:SFSE_SUPPORT_XBYAK=1>"
Expand Down Expand Up @@ -110,6 +115,7 @@ function(configure_target TARGET_NAME)
target_link_libraries(
${TARGET_NAME}
PUBLIC
Boost::headers
spdlog::spdlog
Version.lib
Dbghelp.lib
Expand Down
53 changes: 53 additions & 0 deletions CommonLibSF/src/RE/R/RemoteDebugger.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#include "RE/R/RemoteDebugger.h"
namespace RE::GameScript
{
void RemoteDebugger::HandleContinueRequest(const DebuggerMessages::ContinueRequest& a_request)
{
using func_t = decltype(&RemoteDebugger::HandleContinueRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandleContinueRequest };
return func(this, a_request);
}
void RemoteDebugger::HandleDisconnectRequest(const DebuggerMessages::DisconnectRequest& a_request)
{
using func_t = decltype(&RemoteDebugger::HandleDisconnectRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandleDisconnectRequest };
return func(this, a_request);
}
void RemoteDebugger::HandlePauseRequest(const DebuggerMessages::PauseRequest& a_request)
{
using func_t = decltype(&RemoteDebugger::HandlePauseRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandlePauseRequest };
return func(this, a_request);
}
void RemoteDebugger::HandleSetBreakpointsRequest(const DebuggerMessages::SetBreakpointsRequest& a_request)
{
using func_t = decltype(&RemoteDebugger::HandleSetBreakpointsRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandleSetBreakpointsRequest };
return func(this, a_request);
}
void RemoteDebugger::HandleStackTraceRequest(const DebuggerMessages::StackTraceRequest& a_request)
{
using func_t = decltype(&RemoteDebugger::HandleStackTraceRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandleStackTraceRequest };
return func(this, a_request);
}
void RemoteDebugger::HandleStepRequest(const DebuggerMessages::Request& a_request, uint32_t a_threadid, StepKind a_stepKind)
{
using func_t = decltype(&RemoteDebugger::HandleStepRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandleStepRequest };
return func(this, a_request, a_threadid, a_stepKind);
}
void RemoteDebugger::HandleVariablesRequest(const DebuggerMessages::VariablesRequest& a_request)
{
using func_t = decltype(&RemoteDebugger::HandleVariablesRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandleVariablesRequest };
return func(this, a_request);
}
void RemoteDebugger::HandleValueRequest(const DebuggerMessages::ValueRequest& a_request)
{
using func_t = decltype(&RemoteDebugger::HandleValueRequest);
REL::Relocation<func_t> func{ ID::GameScript::RemoteDebugger::HandleValueRequest };
return func(this, a_request);
}

}
56 changes: 56 additions & 0 deletions include/RE/B/BSResourceEnums.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

namespace RE::BSResource
{
enum class ErrorCode : std::uint32_t
{
kNone = 0,
kNotExist = 1,
kInvalidPath = 2,
kFileError = 3,
kInvalidType = 4,
kMemoryError = 5,
kBusy = 6,
kInvalidParam = 7,
kUnsupported = 8
};

enum class SeekMode
{
kSet = 0,
kCurrent = 1,
kEnd = 2
};

struct FileID
{
public:
[[nodiscard]] bool operator==(const FileID&) const noexcept = default;

// members
std::uint32_t file = 0; // 0
std::uint32_t ext = 0; // 4
};
static_assert(sizeof(FileID) == 0x8);

struct ID :
public FileID // 0
{
public:
[[nodiscard]] bool operator==(const ID&) const noexcept = default;

// members
std::uint32_t dir = 0; // 8
};
static_assert(sizeof(BSResource::ID) == 0xC);

struct Info
{
public:
// members
WinAPI::FILETIME modifyTime; // 00
WinAPI::FILETIME createTime; // 08
std::uint64_t fileSize; // 10
};
static_assert(sizeof(Info) == 0x18);
}
104 changes: 104 additions & 0 deletions include/RE/B/BSStorage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#pragma once

#include "RE/B/BSIntrusiveRefCounted.h"
#include "RE/B/BSTSmartPointer.h"

namespace RE
{
namespace BSStorageDefs
{
enum class ErrorCode
{
kOK = 0,
kError = 1,
kNotImplemented = 2,
};
enum class SeekMode;
struct StreamBuffer
{
void Reset()
{
ptrCur = buffer.GetPtr();
}

StreamBuffer() = delete;
StreamBuffer(std::size_t a_size) :
size(a_size),
buffer(a_size, 8),
ptrCur(buffer.GetPtr())
{
}

std::size_t size;
MemoryManager::AutoScrapBuffer buffer;
void* ptrCur;
};
}

class __declspec(novtable) BSStorage :
public BSIntrusiveRefCounted
{
public:
inline static constexpr auto RTTI = { RTTI::BSStorage };
inline static constexpr auto VTABLE = { VTABLE::BSStorage };

virtual ~BSStorage() = default; // 00

virtual std::size_t GetSize() const = 0; // 01
virtual std::size_t GetPosition() const = 0; // 02
virtual BSStorageDefs::ErrorCode Seek(std::size_t a_offset, BSStorageDefs::SeekMode a_seekMode) const = 0; // 03
virtual BSStorageDefs::ErrorCode Read(std::size_t a_numBytes, std::byte* a_bytes) const = 0; // 04
virtual BSStorageDefs::ErrorCode Write(std::size_t a_numBytes, const std::byte* a_bytes) = 0; // 05

template <typename T>
BSStorageDefs::ErrorCode Write(T a_value)
requires(std::is_arithmetic_v<T>)
{
if (usingStreambuffer && buf && PrepareStreamBuffer(sizeof(T)) == BSStorageDefs::ErrorCode::kOK) {
*reinterpret_cast<T*>(buf->ptrCur) = a_value;
buf->ptrCur = reinterpret_cast<std::byte*>(buf->ptrCur) + sizeof(T);
return BSStorageDefs::ErrorCode::kOK;
}
return Write(sizeof(T), reinterpret_cast<const std::byte*>(&a_value));
}

template <typename T>
BSStorageDefs::ErrorCode Write(const T& a_value)
requires(!std::is_arithmetic_v<T>)
{
return Write(sizeof(T), reinterpret_cast<const std::byte*>(&a_value));
}

template <typename T>
BSStorageDefs::ErrorCode Read(T& a_value)
{
return Read(sizeof(T), reinterpret_cast<std::byte*>(&a_value));
}

BSStorageDefs::ErrorCode WriteString(const char* a_string, bool use32bitLength)
{
using func_t = decltype(&BSStorage::WriteString);
REL::Relocation<func_t> func{ ID::BSStorage::WriteString };
return func(this, a_string, use32bitLength);
}

BSStorageDefs::ErrorCode PrepareStreamBuffer(std::size_t a_size)
{
using func_t = decltype(&BSStorage::PrepareStreamBuffer);
REL::Relocation<func_t> func{ ID::BSStorage::PrepareStreamBuffer };
return func(this, a_size);
}

BSStorageDefs::ErrorCode FlushStreamBuffer()
{
using func_t = decltype(&BSStorage::FlushStreamBuffer);
REL::Relocation<func_t> func{ ID::BSStorage::FlushStreamBuffer };
return func(this);
}

// members
msvc::unique_ptr<BSStorageDefs::StreamBuffer> buf{ nullptr }; // 10
bool usingStreambuffer{ 0 }; // 18
};
static_assert(sizeof(BSStorage) == 0x20);
}
13 changes: 13 additions & 0 deletions include/RE/B/BSTArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ namespace RE

class BSScrapArrayAllocator
{
public:
void* allocate(std::size_t a_size)
{
const auto mem = _allocator->Allocate(a_size, 0);
if (!mem) {
stl::report_and_fail("out of memory"sv);
}
std::memset(mem, 0, a_size);
return mem;
}
void deallocate(void* a_ptr) { _allocator->Deallocate(a_ptr, 0); }

protected:
// members
ScrapHeap* _allocator{ nullptr }; // 00
Expand Down Expand Up @@ -301,4 +313,5 @@ namespace RE

template <class T>
using BSScrapArray = BSTArray<T, BSScrapArrayAllocator>;
static_assert(sizeof(BSScrapArray<void*>) == 0x18);
}
34 changes: 34 additions & 0 deletions include/RE/B/BSTFreeList.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#pragma once

namespace RE
{
template <class T>
struct BSTFreeListElem
{
public:
// members
std::byte rawElem[sizeof(T)]; // 00
BSTFreeListElem<T>* next; // ??
};

template <class T>
class __declspec(novtable) BSTFreeList
{
public:
virtual ~BSTFreeList(); // 00

// members
std::uint32_t lock; // 08
BSTFreeListElem<T>* free; // 10
};
//static_assert(sizeof(BSTFreeList<void*>) == 0x18);

template <class T, std::uint32_t N>
class __declspec(novtable) BSTStaticFreeList :
public BSTFreeList<T> // 00
{
public:
// members
BSTFreeListElem<T> elems[N]; // ??
};
}
Loading

0 comments on commit 2449439

Please sign in to comment.