Skip to content

Commit

Permalink
Rewrite of the class extension system, implements save game support.
Browse files Browse the repository at this point in the history
  • Loading branch information
CCHyper committed Dec 22, 2022
1 parent d4c2bbf commit b789478
Show file tree
Hide file tree
Showing 181 changed files with 8,749 additions and 8,281 deletions.
29 changes: 0 additions & 29 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -303,29 +303,6 @@ if(NOT tspp_POPULATED)
endif()


################################################################################
# Fetch the latest "robin-hood-hashing" source code
################################################################################
FetchContent_Declare(
robin_hood_hashing
GIT_REMOTE_UPDATE_STRATEGY REBASE
GIT_REPOSITORY https://github.com/martinus/robin-hood-hashing.git
GIT_TAG origin/master
GIT_SUBMODULES ""
)

FetchContent_GetProperties(robin_hood_hashing)
if(NOT robin_hood_hashing_POPULATED)
message(STATUS "Fetching robin-hood-hashing...")
FetchContent_Populate(robin_hood_hashing)
message(STATUS " Source: ${robin_hood_hashing_SOURCE_DIR}")
message(STATUS " Build: ${robin_hood_hashing_BINARY_DIR}")
add_subdirectory(${robin_hood_hashing_SOURCE_DIR} ${robin_hood_hashing_BINARY_DIR})
else()
message(STATUS "Found robin-hood-hashing.")
endif()


################################################################################
# Embed some git version information in the binary.
################################################################################
Expand Down Expand Up @@ -548,8 +525,6 @@ else()
message(STATUS "Build: Unofficial")
endif()

# Use the robin-hood-hashing library containers instead of the std C++ containers.
target_compile_definitions(${PROJECT_NAME} PUBLIC USE_ROBIN_HOOD=1)

#
# Add/Remove flags required for trying matching pre-compiled game code.
Expand Down Expand Up @@ -643,10 +618,6 @@ target_link_libraries(${PROJECT_NAME} ${REQUIRED_LIBRARIES})
# Make build check state of git to check for uncommitted changes.
add_dependencies(${PROJECT_NAME} ${PROJECT_NAME}_check_git)

# Link to the robin-hood-hashing library.
target_link_libraries(${PROJECT_NAME} robin_hood)
add_dependencies(${PROJECT_NAME} robin_hood)


################################################################################
# Setup project IDE filters.
Expand Down
257 changes: 257 additions & 0 deletions src/extensions/abstract/abstractext.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,257 @@
/*******************************************************************************
/* O P E N S O U R C E -- V I N I F E R A **
/*******************************************************************************
*
* @project Vinifera
*
* @file ABSTRACTEXT.CPP
*
* @author CCHyper
*
* @brief Base extension class for all game world objects.
*
* @license Vinifera is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version
* 3 of the License, or (at your option) any later version.
*
* Vinifera is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program.
* If not, see <http://www.gnu.org/licenses/>.
*
******************************************************************************/
#pragma once

#include "abstractext.h"
#include "tibsun_globals.h"
#include "tibsun_functions.h"
#include "swizzle.h"
#include "vinifera_saveload.h"
#include "extension.h"
#include "debughandler.h"
#include "asserthandler.h"


/**
* Class constructor
*
* @author: CCHyper
*/
AbstractClassExtension::AbstractClassExtension(const AbstractClass *this_ptr) :
ThisPtr(this_ptr)
{
//if (this_ptr) EXT_DEBUG_TRACE("AbstractClassExtension::AbstractClassExtension - 0x%08X\n", (uintptr_t)(ThisPtr));
//ASSERT(ThisPtr != nullptr); // NULL ThisPtr is valid when performing a Load state operation.
}


/**
* Class no-init constructor.
*
* @author: CCHyper
*/
AbstractClassExtension::AbstractClassExtension(const NoInitClass &noinit)
{
//EXT_DEBUG_TRACE("AbstractClassExtension::AbstractClassExtension(NoInitClass) - 0x%08X\n", (uintptr_t)(ThisPtr));
}


/**
* Class destructor
*
* @author: CCHyper
*/
AbstractClassExtension::~AbstractClassExtension()
{
//EXT_DEBUG_TRACE("AbstractClassExtension::~AbstractClassExtension - 0x%08X\n", (uintptr_t)(ThisPtr));

ThisPtr = nullptr;
}


/**
* Retrieves pointers to the supported interfaces on an object.
*
* @author: CCHyper, tomsons26
*/
LONG AbstractClassExtension::QueryInterface(REFIID riid, LPVOID *ppv)
{
/**
* Always set out parameter to NULL, validating it first.
*/
if (ppv == nullptr) {
return E_POINTER;
}
*ppv = nullptr;

if (riid == __uuidof(IUnknown)) {
*ppv = reinterpret_cast<IUnknown *>(this);
}

if (riid == __uuidof(IStream)) {
*ppv = reinterpret_cast<IStream *>(this);
}

if (riid == __uuidof(IPersistStream)) {
*ppv = static_cast<IPersistStream *>(this);
}

if (*ppv == nullptr) {
return E_NOINTERFACE;
}

/**
* Increment the reference count and return the pointer.
*/
reinterpret_cast<IUnknown *>(*ppv)->AddRef();

return S_OK;
}


/**
* Increments the reference count for an interface pointer to a COM object.
*
* @author: CCHyper
*/
ULONG AbstractClassExtension::AddRef()
{
//EXT_DEBUG_TRACE("AbstractClassExtension::AddRef - 0x%08X\n", (uintptr_t)(ThisPtr));

return 1;
}


/**
* Decrements the reference count for an interface on a COM object.
*
* @author: CCHyper
*/
ULONG AbstractClassExtension::Release()
{
//EXT_DEBUG_TRACE("AbstractClassExtension::Release - 0x%08X\n", (uintptr_t)(ThisPtr));

return 1;
}


/**
* Determines whether an object has changed since it was last saved to its stream.
*
* @author: CCHyper
*/
HRESULT AbstractClassExtension::IsDirty()
{
//EXT_DEBUG_TRACE("AbstractClassExtension::IsDirty - 0x%08X\n", (uintptr_t)(ThisPtr));

return S_OK;
}


/**
* Loads the object from the stream and requests a new pointer to
* the class we extended post-load.
*
* @author: CCHyper, tomsons26
*/
HRESULT AbstractClassExtension::Internal_Load(IStream *pStm)
{
//EXT_DEBUG_TRACE("AbstractClassExtension::Internal_Load - 0x%08X\n", (uintptr_t)(ThisPtr));

if (!pStm) {
return E_POINTER;
}

/**
* Load the unique id for this class.
*/
LONG id = 0;
HRESULT hr = pStm->Read(&id, sizeof(LONG), nullptr);
if (FAILED(hr)) {
return hr;
}

Wstring this_name = Wstring(Extension::Utility::Get_TypeID_Name(this).c_str()) + ":" + Wstring("ThisPtr");

/**
* Register this instance to be available for remapping references to.
*/
VINIFERA_SWIZZLE_REGISTER_POINTER(id, this, this_name.Peek_Buffer());

/**
* Read this classes binary blob data directly into this instance.
*/
hr = pStm->Read(this, Size_Of(), nullptr);
if (FAILED(hr)) {
return hr;
}

VINIFERA_SWIZZLE_REQUEST_POINTER_REMAP(ThisPtr, this_name.Peek_Buffer());

return hr;
}


/**
* Saves the object to the stream.
*
* @author: CCHyper, tomsons26
*/
HRESULT AbstractClassExtension::Internal_Save(IStream *pStm, BOOL fClearDirty)
{
//EXT_DEBUG_TRACE("AbstractClassExtension::Internal_Save - 0x%08X\n", (uintptr_t)(ThisPtr));

if (!pStm) {
return E_POINTER;
}

Wstring this_name = Wstring(Extension::Utility::Get_TypeID_Name(this).c_str()) + ":" + Wstring("ThisPtr");

/**
* Fetch the save id for this instance.
*/
LONG id;
VINIFERA_SWIZZLE_FETCH_SWIZZLE_ID(this, id, this_name.Peek_Buffer());

//DEV_DEBUG_INFO("Writing id = 0x%08X.\n", id);

HRESULT hr = pStm->Write(&id, sizeof(id), nullptr);
if (FAILED(hr)) {
return hr;
}

/**
* Write this class instance as a binary blob.
*/
hr = pStm->Write(this, Size_Of(), nullptr);
if (FAILED(hr)) {
return hr;
}

return hr;
}


/**
* Retrieves the size of the stream needed to save the object.
*
* @author: CCHyper, tomsons26
*/
LONG AbstractClassExtension::GetSizeMax(ULARGE_INTEGER *pcbSize)
{
//EXT_DEBUG_TRACE("AbstractClassExtension::GetSizeMax - 0x%08X\n", (uintptr_t)(ThisPtr));

if (!pcbSize) {
return E_POINTER;
}

pcbSize->LowPart = Size_Of() + sizeof(uint32_t); // Add size of swizzle "id".
pcbSize->HighPart = 0;

return S_OK;
}
Loading

0 comments on commit b789478

Please sign in to comment.