Skip to content

Commit b789478

Browse files
committed
Rewrite of the class extension system, implements save game support.
1 parent d4c2bbf commit b789478

File tree

181 files changed

+8749
-8281
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

181 files changed

+8749
-8281
lines changed

CMakeLists.txt

-29
Original file line numberDiff line numberDiff line change
@@ -303,29 +303,6 @@ if(NOT tspp_POPULATED)
303303
endif()
304304

305305

306-
################################################################################
307-
# Fetch the latest "robin-hood-hashing" source code
308-
################################################################################
309-
FetchContent_Declare(
310-
robin_hood_hashing
311-
GIT_REMOTE_UPDATE_STRATEGY REBASE
312-
GIT_REPOSITORY https://github.com/martinus/robin-hood-hashing.git
313-
GIT_TAG origin/master
314-
GIT_SUBMODULES ""
315-
)
316-
317-
FetchContent_GetProperties(robin_hood_hashing)
318-
if(NOT robin_hood_hashing_POPULATED)
319-
message(STATUS "Fetching robin-hood-hashing...")
320-
FetchContent_Populate(robin_hood_hashing)
321-
message(STATUS " Source: ${robin_hood_hashing_SOURCE_DIR}")
322-
message(STATUS " Build: ${robin_hood_hashing_BINARY_DIR}")
323-
add_subdirectory(${robin_hood_hashing_SOURCE_DIR} ${robin_hood_hashing_BINARY_DIR})
324-
else()
325-
message(STATUS "Found robin-hood-hashing.")
326-
endif()
327-
328-
329306
################################################################################
330307
# Embed some git version information in the binary.
331308
################################################################################
@@ -548,8 +525,6 @@ else()
548525
message(STATUS "Build: Unofficial")
549526
endif()
550527

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

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

646-
# Link to the robin-hood-hashing library.
647-
target_link_libraries(${PROJECT_NAME} robin_hood)
648-
add_dependencies(${PROJECT_NAME} robin_hood)
649-
650621

651622
################################################################################
652623
# Setup project IDE filters.
+257
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
/*******************************************************************************
2+
/* O P E N S O U R C E -- V I N I F E R A **
3+
/*******************************************************************************
4+
*
5+
* @project Vinifera
6+
*
7+
* @file ABSTRACTEXT.CPP
8+
*
9+
* @author CCHyper
10+
*
11+
* @brief Base extension class for all game world objects.
12+
*
13+
* @license Vinifera is free software: you can redistribute it and/or
14+
* modify it under the terms of the GNU General Public License
15+
* as published by the Free Software Foundation, either version
16+
* 3 of the License, or (at your option) any later version.
17+
*
18+
* Vinifera is distributed in the hope that it will be
19+
* useful, but WITHOUT ANY WARRANTY; without even the implied
20+
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
21+
* PURPOSE. See the GNU General Public License for more details.
22+
*
23+
* You should have received a copy of the GNU General Public
24+
* License along with this program.
25+
* If not, see <http://www.gnu.org/licenses/>.
26+
*
27+
******************************************************************************/
28+
#pragma once
29+
30+
#include "abstractext.h"
31+
#include "tibsun_globals.h"
32+
#include "tibsun_functions.h"
33+
#include "swizzle.h"
34+
#include "vinifera_saveload.h"
35+
#include "extension.h"
36+
#include "debughandler.h"
37+
#include "asserthandler.h"
38+
39+
40+
/**
41+
* Class constructor
42+
*
43+
* @author: CCHyper
44+
*/
45+
AbstractClassExtension::AbstractClassExtension(const AbstractClass *this_ptr) :
46+
ThisPtr(this_ptr)
47+
{
48+
//if (this_ptr) EXT_DEBUG_TRACE("AbstractClassExtension::AbstractClassExtension - 0x%08X\n", (uintptr_t)(ThisPtr));
49+
//ASSERT(ThisPtr != nullptr); // NULL ThisPtr is valid when performing a Load state operation.
50+
}
51+
52+
53+
/**
54+
* Class no-init constructor.
55+
*
56+
* @author: CCHyper
57+
*/
58+
AbstractClassExtension::AbstractClassExtension(const NoInitClass &noinit)
59+
{
60+
//EXT_DEBUG_TRACE("AbstractClassExtension::AbstractClassExtension(NoInitClass) - 0x%08X\n", (uintptr_t)(ThisPtr));
61+
}
62+
63+
64+
/**
65+
* Class destructor
66+
*
67+
* @author: CCHyper
68+
*/
69+
AbstractClassExtension::~AbstractClassExtension()
70+
{
71+
//EXT_DEBUG_TRACE("AbstractClassExtension::~AbstractClassExtension - 0x%08X\n", (uintptr_t)(ThisPtr));
72+
73+
ThisPtr = nullptr;
74+
}
75+
76+
77+
/**
78+
* Retrieves pointers to the supported interfaces on an object.
79+
*
80+
* @author: CCHyper, tomsons26
81+
*/
82+
LONG AbstractClassExtension::QueryInterface(REFIID riid, LPVOID *ppv)
83+
{
84+
/**
85+
* Always set out parameter to NULL, validating it first.
86+
*/
87+
if (ppv == nullptr) {
88+
return E_POINTER;
89+
}
90+
*ppv = nullptr;
91+
92+
if (riid == __uuidof(IUnknown)) {
93+
*ppv = reinterpret_cast<IUnknown *>(this);
94+
}
95+
96+
if (riid == __uuidof(IStream)) {
97+
*ppv = reinterpret_cast<IStream *>(this);
98+
}
99+
100+
if (riid == __uuidof(IPersistStream)) {
101+
*ppv = static_cast<IPersistStream *>(this);
102+
}
103+
104+
if (*ppv == nullptr) {
105+
return E_NOINTERFACE;
106+
}
107+
108+
/**
109+
* Increment the reference count and return the pointer.
110+
*/
111+
reinterpret_cast<IUnknown *>(*ppv)->AddRef();
112+
113+
return S_OK;
114+
}
115+
116+
117+
/**
118+
* Increments the reference count for an interface pointer to a COM object.
119+
*
120+
* @author: CCHyper
121+
*/
122+
ULONG AbstractClassExtension::AddRef()
123+
{
124+
//EXT_DEBUG_TRACE("AbstractClassExtension::AddRef - 0x%08X\n", (uintptr_t)(ThisPtr));
125+
126+
return 1;
127+
}
128+
129+
130+
/**
131+
* Decrements the reference count for an interface on a COM object.
132+
*
133+
* @author: CCHyper
134+
*/
135+
ULONG AbstractClassExtension::Release()
136+
{
137+
//EXT_DEBUG_TRACE("AbstractClassExtension::Release - 0x%08X\n", (uintptr_t)(ThisPtr));
138+
139+
return 1;
140+
}
141+
142+
143+
/**
144+
* Determines whether an object has changed since it was last saved to its stream.
145+
*
146+
* @author: CCHyper
147+
*/
148+
HRESULT AbstractClassExtension::IsDirty()
149+
{
150+
//EXT_DEBUG_TRACE("AbstractClassExtension::IsDirty - 0x%08X\n", (uintptr_t)(ThisPtr));
151+
152+
return S_OK;
153+
}
154+
155+
156+
/**
157+
* Loads the object from the stream and requests a new pointer to
158+
* the class we extended post-load.
159+
*
160+
* @author: CCHyper, tomsons26
161+
*/
162+
HRESULT AbstractClassExtension::Internal_Load(IStream *pStm)
163+
{
164+
//EXT_DEBUG_TRACE("AbstractClassExtension::Internal_Load - 0x%08X\n", (uintptr_t)(ThisPtr));
165+
166+
if (!pStm) {
167+
return E_POINTER;
168+
}
169+
170+
/**
171+
* Load the unique id for this class.
172+
*/
173+
LONG id = 0;
174+
HRESULT hr = pStm->Read(&id, sizeof(LONG), nullptr);
175+
if (FAILED(hr)) {
176+
return hr;
177+
}
178+
179+
Wstring this_name = Wstring(Extension::Utility::Get_TypeID_Name(this).c_str()) + ":" + Wstring("ThisPtr");
180+
181+
/**
182+
* Register this instance to be available for remapping references to.
183+
*/
184+
VINIFERA_SWIZZLE_REGISTER_POINTER(id, this, this_name.Peek_Buffer());
185+
186+
/**
187+
* Read this classes binary blob data directly into this instance.
188+
*/
189+
hr = pStm->Read(this, Size_Of(), nullptr);
190+
if (FAILED(hr)) {
191+
return hr;
192+
}
193+
194+
VINIFERA_SWIZZLE_REQUEST_POINTER_REMAP(ThisPtr, this_name.Peek_Buffer());
195+
196+
return hr;
197+
}
198+
199+
200+
/**
201+
* Saves the object to the stream.
202+
*
203+
* @author: CCHyper, tomsons26
204+
*/
205+
HRESULT AbstractClassExtension::Internal_Save(IStream *pStm, BOOL fClearDirty)
206+
{
207+
//EXT_DEBUG_TRACE("AbstractClassExtension::Internal_Save - 0x%08X\n", (uintptr_t)(ThisPtr));
208+
209+
if (!pStm) {
210+
return E_POINTER;
211+
}
212+
213+
Wstring this_name = Wstring(Extension::Utility::Get_TypeID_Name(this).c_str()) + ":" + Wstring("ThisPtr");
214+
215+
/**
216+
* Fetch the save id for this instance.
217+
*/
218+
LONG id;
219+
VINIFERA_SWIZZLE_FETCH_SWIZZLE_ID(this, id, this_name.Peek_Buffer());
220+
221+
//DEV_DEBUG_INFO("Writing id = 0x%08X.\n", id);
222+
223+
HRESULT hr = pStm->Write(&id, sizeof(id), nullptr);
224+
if (FAILED(hr)) {
225+
return hr;
226+
}
227+
228+
/**
229+
* Write this class instance as a binary blob.
230+
*/
231+
hr = pStm->Write(this, Size_Of(), nullptr);
232+
if (FAILED(hr)) {
233+
return hr;
234+
}
235+
236+
return hr;
237+
}
238+
239+
240+
/**
241+
* Retrieves the size of the stream needed to save the object.
242+
*
243+
* @author: CCHyper, tomsons26
244+
*/
245+
LONG AbstractClassExtension::GetSizeMax(ULARGE_INTEGER *pcbSize)
246+
{
247+
//EXT_DEBUG_TRACE("AbstractClassExtension::GetSizeMax - 0x%08X\n", (uintptr_t)(ThisPtr));
248+
249+
if (!pcbSize) {
250+
return E_POINTER;
251+
}
252+
253+
pcbSize->LowPart = Size_Of() + sizeof(uint32_t); // Add size of swizzle "id".
254+
pcbSize->HighPart = 0;
255+
256+
return S_OK;
257+
}

0 commit comments

Comments
 (0)