Match Tgl MeshImpl and GroupImpl functions (#1514)

This commit is contained in:
MS 2025-05-23 12:27:41 -04:00 committed by GitHub
parent eb1177b409
commit 4e49712391
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 386 additions and 144 deletions

View File

@ -1,5 +1,7 @@
#include "impl.h" #include "impl.h"
#include <assert.h>
using namespace TglImpl; using namespace TglImpl;
// FUNCTION: LEGO1 0x100a31d0 // FUNCTION: LEGO1 0x100a31d0
@ -9,164 +11,293 @@ void* GroupImpl::ImplementationDataPtr()
return reinterpret_cast<void*>(&m_data); return reinterpret_cast<void*>(&m_data);
} }
// FUNCTION: LEGO1 0x100a31e0 // FUNCTION: BETA10 0x1016c340
Result GroupImpl::SetTransformation(FloatMatrix4& matrix) inline Result GroupSetTransformation(IDirect3DRMFrame2* pGroup, FloatMatrix4& matrix)
{ {
D3DRMMATRIX4D helper; D3DRMMATRIX4D helper;
D3DRMMATRIX4D* d3dMatrix = Translate(matrix, helper); D3DRMMATRIX4D* d3dMatrix = Translate(matrix, helper);
return ResultVal(m_data->AddTransform(D3DRMCOMBINE_REPLACE, *d3dMatrix)); return ResultVal(pGroup->AddTransform(D3DRMCOMBINE_REPLACE, *d3dMatrix));
}
// FUNCTION: LEGO1 0x100a31e0
// FUNCTION: BETA10 0x1016a4d0
Result GroupImpl::SetTransformation(FloatMatrix4& matrix)
{
assert(m_data);
return GroupSetTransformation(m_data, matrix);
}
// FUNCTION: BETA10 0x1016c400
inline Result GroupSetColor(IDirect3DRMFrame2* pGroup, float r, float g, float b, float a)
{
if (a > 0) {
D3DCOLOR color = D3DRMCreateColorRGBA(r, g, b, a);
return ResultVal(pGroup->SetColor(color));
}
else {
return ResultVal(pGroup->SetColorRGB(r, g, b));
}
} }
// FUNCTION: LEGO1 0x100a3240 // FUNCTION: LEGO1 0x100a3240
// FUNCTION: BETA10 0x1016a530
Result GroupImpl::SetColor(float r, float g, float b, float a) Result GroupImpl::SetColor(float r, float g, float b, float a)
{ {
// The first instruction makes no sense here: assert(m_data);
// cmp dword ptr [esp + 0x10], 0
// This compares a, which we know is a float because it immediately return GroupSetColor(m_data, r, g, b, a);
// gets passed into D3DRMCreateColorRGBA, but does the comparison }
// as though it's an int??
if (*reinterpret_cast<int*>(&a) > 0) { // FUNCTION: BETA10 0x1016c5a0
D3DCOLOR color = D3DRMCreateColorRGBA(r, g, b, a); inline Result GroupSetTexture(IDirect3DRMFrame2* pGroup, IDirect3DRMTexture* pD3DTexture)
return ResultVal(m_data->SetColor(color)); {
} return ResultVal(pGroup->SetTexture(pD3DTexture));
else { }
return ResultVal(m_data->SetColorRGB(r, a, b));
} // FUNCTION: BETA10 0x1016bcc0
inline Result GroupImpl::SetTexture(const TextureImpl* pTexture)
{
assert(m_data);
assert(!pTexture || pTexture->ImplementationData());
IDirect3DRMTexture* pD3DTexture = pTexture ? pTexture->ImplementationData() : NULL;
return GroupSetTexture(m_data, pD3DTexture);
} }
// FUNCTION: LEGO1 0x100a32b0 // FUNCTION: LEGO1 0x100a32b0
// FUNCTION: BETA10 0x1016a5a0
Result GroupImpl::SetTexture(const Texture* pTexture) Result GroupImpl::SetTexture(const Texture* pTexture)
{ {
IDirect3DRMTexture* pD3DTexture = pTexture ? static_cast<const TextureImpl*>(pTexture)->ImplementationData() : NULL; assert(m_data);
return ResultVal(m_data->SetTexture(pD3DTexture));
return SetTexture(static_cast<const TextureImpl*>(pTexture));
}
// FUNCTION: BETA10 0x1016c640
inline Result GroupGetTexture(IDirect3DRMFrame2* pGroup, IDirect3DRMTexture** pD3DTexture)
{
return ResultVal(pGroup->GetTexture(pD3DTexture));
}
// FUNCTION: BETA10 0x1016beb0
inline Result GroupImpl::GetTexture(TextureImpl** ppTexture)
{
assert(m_data);
assert(ppTexture);
TextureImpl* pTextureImpl = new TextureImpl();
assert(pTextureImpl);
// TODO: This helps retail match, but it adds to the stack
IDirect3DRMTexture* tex;
Result result = GroupGetTexture(m_data, &tex);
#ifndef BETA10
if (Succeeded(result)) {
result =
ResultVal(tex->QueryInterface(IID_IDirect3DRMTexture2, (LPVOID*) (&pTextureImpl->ImplementationData())));
}
#endif
*ppTexture = pTextureImpl;
return result;
} }
// FUNCTION: LEGO1 0x100a32e0 // FUNCTION: LEGO1 0x100a32e0
// FUNCTION: BETA10 0x1016a600
Result GroupImpl::GetTexture(Texture*& pTexture) Result GroupImpl::GetTexture(Texture*& pTexture)
{ {
IDirect3DRMTexture* pD3DTexture; assert(m_data);
TextureImpl* holder = new TextureImpl();
Result result = ResultVal(m_data->GetTexture(&pD3DTexture));
if (result) {
// Seems to actually call the first virtual method of holder here
// but that doesn't make any sense since it passes three arguments
// to the method (self + string constant? + an offset?).
// This line makes the start of the function match and is what I return GetTexture(reinterpret_cast<TextureImpl**>(&pTexture));
// would expect to see there but it clearly isn't what's actually }
// there.
holder->SetImplementation(pD3DTexture); // FUNCTION: BETA10 0x1016c500
} inline Result GroupSetMaterialMode(IDirect3DRMFrame2* pGroup, MaterialMode mode)
pTexture = holder; {
return Success; D3DRMMATERIALMODE d3dMode = Translate(mode);
return ResultVal(pGroup->SetMaterialMode(d3dMode));
} }
// FUNCTION: LEGO1 0x100a33c0 // FUNCTION: LEGO1 0x100a33c0
// FUNCTION: BETA10 0x1016a660
Result GroupImpl::SetMaterialMode(MaterialMode mode) Result GroupImpl::SetMaterialMode(MaterialMode mode)
{ {
D3DRMMATERIALMODE d3dMode; assert(m_data);
switch (mode) {
case FromParent: return GroupSetMaterialMode(m_data, mode);
d3dMode = D3DRMMATERIAL_FROMPARENT; }
break;
case FromFrame: // FUNCTION: BETA10 0x1016c670
d3dMode = D3DRMMATERIAL_FROMFRAME; inline Result GroupAddGroup(IDirect3DRMFrame2* pGroup, const IDirect3DRMFrame* pChildGroup)
break; {
case FromMesh: return ResultVal(pGroup->AddVisual(const_cast<IDirect3DRMFrame*>(pChildGroup)));
d3dMode = D3DRMMATERIAL_FROMMESH; }
break;
} // FUNCTION: BETA10 0x1016c090
return ResultVal(m_data->SetMaterialMode(d3dMode)); inline Result GroupImpl::Add(const GroupImpl& rGroup)
{
assert(m_data);
assert(rGroup.ImplementationData());
return GroupAddGroup(m_data, rGroup.ImplementationData());
} }
// FUNCTION: LEGO1 0x100a3410 // FUNCTION: LEGO1 0x100a3410
// FUNCTION: BETA10 0x1016a6c0
Result GroupImpl::Add(const Group* pGroup) Result GroupImpl::Add(const Group* pGroup)
{ {
const GroupImpl* pGroupImpl = static_cast<const GroupImpl*>(pGroup); assert(m_data);
return ResultVal(m_data->AddVisual(pGroupImpl->m_data)); assert(pGroup);
return Add(*static_cast<const GroupImpl*>(pGroup));
}
// FUNCTION: BETA10 0x1016c700
inline Result GroupAddMeshBuilder(IDirect3DRMFrame2* pGroup, const IDirect3DRMMesh* pMesh)
{
return ResultVal(pGroup->AddVisual(const_cast<IDirect3DRMMesh*>(pMesh)));
}
// FUNCTION: BETA10 0x1016bff0
inline Result GroupImpl::Add(const MeshBuilderImpl& rMesh)
{
assert(m_data);
assert(rMesh.ImplementationData());
return GroupAddMeshBuilder(m_data, rMesh.ImplementationData());
} }
// FUNCTION: LEGO1 0x100a3430 // FUNCTION: LEGO1 0x100a3430
// FUNCTION: BETA10 0x1016a740
Result GroupImpl::Add(const MeshBuilder* pMeshBuilder) Result GroupImpl::Add(const MeshBuilder* pMeshBuilder)
{ {
const MeshBuilderImpl* pMeshBuilderImpl = static_cast<const MeshBuilderImpl*>(pMeshBuilder); assert(m_data);
return ResultVal(m_data->AddVisual(pMeshBuilderImpl->ImplementationData())); assert(pMeshBuilder);
return Add(*static_cast<const MeshBuilderImpl*>(pMeshBuilder));
}
// FUNCTION: BETA10 0x1016c7b0
inline Result GroupRemoveMeshBuilder(IDirect3DRMFrame2* pGroup, const IDirect3DRMMesh* pMesh)
{
return ResultVal(pGroup->DeleteVisual(const_cast<IDirect3DRMMesh*>(pMesh)));
}
// FUNCTION: BETA10 0x1016c130
inline Result GroupImpl::Remove(const MeshBuilderImpl& rMesh)
{
assert(m_data);
assert(rMesh.ImplementationData());
return GroupRemoveMeshBuilder(m_data, rMesh.ImplementationData());
} }
// FUNCTION: LEGO1 0x100a3450 // FUNCTION: LEGO1 0x100a3450
// FUNCTION: BETA10 0x1016a7c0
Result GroupImpl::Remove(const MeshBuilder* pMeshBuilder) Result GroupImpl::Remove(const MeshBuilder* pMeshBuilder)
{ {
const MeshBuilderImpl* pMeshBuilderImpl = static_cast<const MeshBuilderImpl*>(pMeshBuilder); assert(m_data);
return ResultVal(m_data->DeleteVisual(pMeshBuilderImpl->ImplementationData())); assert(pMeshBuilder);
return Remove(*static_cast<const MeshBuilderImpl*>(pMeshBuilder));
}
// FUNCTION: BETA10 0x1016c730
inline Result GroupRemoveGroup(IDirect3DRMFrame2* pGroup, const IDirect3DRMFrame* pChildGroup)
{
return ResultVal(pGroup->DeleteVisual(const_cast<IDirect3DRMFrame*>(pChildGroup)));
}
// FUNCTION: BETA10 0x1016c1d0
inline Result GroupImpl::Remove(const GroupImpl& rGroup)
{
assert(m_data);
assert(rGroup.ImplementationData());
return GroupRemoveGroup(m_data, rGroup.ImplementationData());
} }
// FUNCTION: LEGO1 0x100a3480 // FUNCTION: LEGO1 0x100a3480
// FUNCTION: BETA10 0x1016a840
Result GroupImpl::Remove(const Group* pGroup) Result GroupImpl::Remove(const Group* pGroup)
{ {
const GroupImpl* pGroupImpl = static_cast<const GroupImpl*>(pGroup); assert(m_data);
return ResultVal(m_data->DeleteVisual(pGroupImpl->m_data)); assert(pGroup);
return Remove(*static_cast<const GroupImpl*>(pGroup));
} }
// FUNCTION: LEGO1 0x100a34b0 // FUNCTION: BETA10 0x1016c850
Result GroupImpl::RemoveAll() inline Result GroupRemoveAll(IDirect3DRMFrame2* pFrame)
{ {
IDirect3DRMVisualArray* visuals; IDirect3DRMVisualArray* visuals;
IDirect3DRMFrame2* frame = m_data; int refCount;
Result result = (Result) SUCCEEDED(frame->GetVisuals(&visuals));
if (result == Success) { Result result = ResultVal(pFrame->GetVisuals(&visuals));
assert(Succeeded(result));
if (Succeeded(result)) {
for (int i = 0; i < (int) visuals->GetSize(); i++) { for (int i = 0; i < (int) visuals->GetSize(); i++) {
IDirect3DRMVisual* visual; IDirect3DRMVisual* visual;
result = (Result) SUCCEEDED(visuals->GetElement(i, &visual)); result = ResultVal(visuals->GetElement(i, &visual));
frame->DeleteVisual(visual); assert(Succeeded(result));
visual->Release();
result = ResultVal(pFrame->DeleteVisual(visual));
assert(Succeeded(result));
refCount = visual->Release();
} }
visuals->Release(); refCount = visuals->Release();
assert(refCount == 0);
} }
return result; return result;
} }
// FUNCTION: LEGO1 0x100a3540 // FUNCTION: LEGO1 0x100a34b0
Result GroupImpl::Bounds(D3DVECTOR* p_min, D3DVECTOR* p_max) // FUNCTION: BETA10 0x1016a8c0
Result GroupImpl::RemoveAll()
{
assert(m_data);
return GroupRemoveAll(m_data);
}
// FUNCTION: BETA10 0x1016cb70
inline Result GroupBounds(IDirect3DRMFrame2* pFrame, D3DVECTOR* p_min, D3DVECTOR* p_max)
{ {
D3DRMBOX size; D3DRMBOX size;
IDirect3DRMFrame2* frame = m_data; int refCount;
size.min.x = 88888.f; size.min.x = size.min.y = size.min.z = 88888.f;
size.min.y = 88888.f; size.max.x = size.max.y = size.max.z = -88888.f;
size.min.z = 88888.f;
size.max.x = -88888.f;
size.max.y = -88888.f;
size.max.z = -88888.f;
IDirect3DRMVisualArray* visuals; IDirect3DRMVisualArray* visuals;
Result result = (Result) SUCCEEDED(frame->GetVisuals(&visuals)); Result result = ResultVal(pFrame->GetVisuals(&visuals));
assert(Succeeded(result));
if (result == Success) { if (Succeeded(result)) {
int i; for (int i = 0; i < (int) visuals->GetSize(); i++) {
for (i = 0; i < (int) visuals->GetSize(); i++) {
IDirect3DRMVisual* visual; IDirect3DRMVisual* visual;
visuals->GetElement(i, &visual); result = ResultVal(visuals->GetElement(i, &visual));
IDirect3DRMMesh* mesh; assert(Succeeded(result));
/* /*
* BUG: should be: * BUG: should be:
* visual->QueryInterface(IID_IDirect3DRMMesh, (void**)&mesh)); * visual->QueryInterface(IID_IDirect3DRMMesh, (void**)&mesh));
*/ */
result = (Result) SUCCEEDED(visual->QueryInterface(IID_IDirect3DRMMeshBuilder, (void**) &mesh)); IDirect3DRMMesh* mesh;
result = ResultVal(visual->QueryInterface(IID_IDirect3DRMMeshBuilder, (void**) &mesh));
if (result == Success) { if (Succeeded(result)) {
D3DRMBOX box; D3DRMBOX box;
result = (Result) SUCCEEDED(mesh->GetBox(&box)); result = ResultVal(mesh->GetBox(&box));
assert(Succeeded(result));
if (size.max.y < box.max.y) {
size.max.y = box.max.y;
}
if (size.max.z < box.max.z) {
size.max.z = box.max.z;
}
if (box.min.x < size.min.x) { if (box.min.x < size.min.x) {
size.min.x = box.min.x; size.min.x = box.min.x;
} }
@ -179,17 +310,36 @@ Result GroupImpl::Bounds(D3DVECTOR* p_min, D3DVECTOR* p_max)
if (size.max.x < box.max.x) { if (size.max.x < box.max.x) {
size.max.x = box.max.x; size.max.x = box.max.x;
} }
if (size.max.y < box.max.y) {
size.max.y = box.max.y;
}
if (size.max.z < box.max.z) {
size.max.z = box.max.z;
}
mesh->Release(); mesh->Release();
} }
visual->Release(); refCount = visual->Release();
} }
visuals->Release(); refCount = visuals->Release();
} }
*p_min = size.min; p_min->x = size.min.x;
*p_max = size.max; p_min->y = size.min.y;
p_min->z = size.min.z;
p_max->x = size.max.x;
p_max->y = size.max.y;
p_max->z = size.max.z;
return result; return result;
} }
// FUNCTION: LEGO1 0x100a3540
// FUNCTION: BETA10 0x1016a920
Result GroupImpl::Bounds(D3DVECTOR* p_min, D3DVECTOR* p_max)
{
assert(m_data);
return GroupBounds(m_data, p_min, p_max);
}

View File

@ -436,6 +436,9 @@ public:
inline void Destroy(); inline void Destroy();
inline Mesh* DeepClone(const MeshBuilderImpl& rMesh); inline Mesh* DeepClone(const MeshBuilderImpl& rMesh);
inline Result GetTexture(TextureImpl** ppTexture);
inline Result SetTexture(const TextureImpl* pTexture);
inline Mesh* ShallowClone(const MeshBuilderImpl& rMesh);
friend class RendererImpl; friend class RendererImpl;
@ -498,6 +501,12 @@ public:
GroupDataType& ImplementationData() { return m_data; } GroupDataType& ImplementationData() { return m_data; }
inline void Destroy(); inline void Destroy();
inline Result SetTexture(const TextureImpl* pTexture);
inline Result GetTexture(TextureImpl** ppTexture);
inline Result Add(const GroupImpl& rGroup);
inline Result Add(const MeshBuilderImpl& rMesh);
inline Result Remove(const GroupImpl& rGroup);
inline Result Remove(const MeshBuilderImpl& rMesh);
friend class RendererImpl; friend class RendererImpl;
@ -677,6 +686,18 @@ void TextureImpl::Destroy()
} }
} }
// Used by both Mesh and MeshBuilder
// FUNCTION: BETA10 0x10170270
inline Result MeshSetTextureMappingMode(MeshImpl::MeshData* pMesh, TextureMappingMode mode)
{
if (mode == PerspectiveCorrect) {
return ResultVal(pMesh->groupMesh->SetGroupMapping(pMesh->groupIndex, D3DRMMAP_PERSPCORRECT));
}
else {
return ResultVal(pMesh->groupMesh->SetGroupMapping(pMesh->groupIndex, 0));
}
}
// Translation helpers // Translation helpers
// FUNCTION: BETA10 0x1016fc40 // FUNCTION: BETA10 0x1016fc40
inline D3DRMRENDERQUALITY Translate(ShadingModel tglShadingModel) inline D3DRMRENDERQUALITY Translate(ShadingModel tglShadingModel)
@ -728,6 +749,7 @@ inline D3DRMPROJECTIONTYPE Translate(ProjectionType tglProjectionType)
// Yes this function serves no purpose, originally they intended it to // Yes this function serves no purpose, originally they intended it to
// convert from doubles to floats but ended up using floats throughout // convert from doubles to floats but ended up using floats throughout
// the software stack. // the software stack.
// FUNCTION: BETA10 0x1016fa10
inline D3DRMMATRIX4D* Translate(FloatMatrix4& tglMatrix4x4, D3DRMMATRIX4D& rD3DRMMatrix4x4) inline D3DRMMATRIX4D* Translate(FloatMatrix4& tglMatrix4x4, D3DRMMATRIX4D& rD3DRMMatrix4x4)
{ {
for (int i = 0; i < (sizeof(rD3DRMMatrix4x4) / sizeof(rD3DRMMatrix4x4[0])); i++) { for (int i = 0; i < (sizeof(rD3DRMMatrix4x4) / sizeof(rD3DRMMatrix4x4[0])); i++) {
@ -778,6 +800,26 @@ inline D3DRMLIGHTTYPE Translate(LightType tglLightType)
return lightType; return lightType;
} }
// FUNCTION: BETA10 0x101702e0
inline D3DRMMATERIALMODE Translate(MaterialMode mode)
{
D3DRMMATERIALMODE d3dMode;
switch (mode) {
case FromParent:
d3dMode = D3DRMMATERIAL_FROMPARENT;
break;
case FromFrame:
d3dMode = D3DRMMATERIAL_FROMFRAME;
break;
case FromMesh:
d3dMode = D3DRMMATERIAL_FROMMESH;
break;
}
return d3dMode;
}
} /* namespace TglImpl */
// SYNTHETIC: LEGO1 0x100a16d0 // SYNTHETIC: LEGO1 0x100a16d0
// SYNTHETIC: BETA10 0x10169aa0 // SYNTHETIC: BETA10 0x10169aa0
// TglImpl::RendererImpl::`scalar deleting destructor' // TglImpl::RendererImpl::`scalar deleting destructor'
@ -820,6 +862,4 @@ inline D3DRMLIGHTTYPE Translate(LightType tglLightType)
// GLOBAL: LEGO1 0x100dd1e0 // GLOBAL: LEGO1 0x100dd1e0
// IID_IDirect3DRMMeshBuilder // IID_IDirect3DRMMeshBuilder
} /* namespace TglImpl */
#endif #endif

View File

@ -16,39 +16,60 @@ void* MeshImpl::ImplementationDataPtr()
return reinterpret_cast<void*>(&m_data); return reinterpret_cast<void*>(&m_data);
} }
// FUNCTION: LEGO1 0x100a3ee0 // FUNCTION: BETA10 0x10170590
Result MeshImpl::SetColor(float r, float g, float b, float a) inline Result MeshSetColor(MeshImpl::MeshData* pMesh, float r, float g, float b, float a)
{ {
// The first instruction makes no sense here: if (a > 0) {
// cmp dword ptr [esp + 0x10], 0
// This compares a, which we know is a float because it immediately
// gets passed into D3DRMCreateColorRGBA, but does the comparison
// as though it's an int??
if (*reinterpret_cast<int*>(&a) > 0) {
D3DCOLOR color = D3DRMCreateColorRGBA(r, g, b, a); D3DCOLOR color = D3DRMCreateColorRGBA(r, g, b, a);
return ResultVal(m_data->groupMesh->SetGroupColor(m_data->groupIndex, color)); return ResultVal(pMesh->groupMesh->SetGroupColor(pMesh->groupIndex, color));
} }
else { else {
return ResultVal(m_data->groupMesh->SetGroupColorRGB(m_data->groupIndex, r, g, b)); return ResultVal(pMesh->groupMesh->SetGroupColorRGB(pMesh->groupIndex, r, g, b));
} }
} }
// FUNCTION: LEGO1 0x100a3ee0
// FUNCTION: BETA10 0x10170520
Result MeshImpl::SetColor(float r, float g, float b, float a)
{
assert(m_data);
return MeshSetColor(m_data, r, g, b, a);
}
// FUNCTION: BETA10 0x10171320
inline Result MeshSetTexture(MeshImpl::MeshData* pMesh, IDirect3DRMTexture* pD3DTexture)
{
Result result = ResultVal(pMesh->groupMesh->SetGroupTexture(pMesh->groupIndex, pD3DTexture));
return result;
}
// FUNCTION: BETA10 0x10171260
inline Result MeshImpl::SetTexture(const TextureImpl* pTexture)
{
assert(m_data);
assert(!pTexture || pTexture->ImplementationData());
IDirect3DRMTexture* pD3DTexture = pTexture ? pTexture->ImplementationData() : NULL;
return MeshSetTexture(m_data, pD3DTexture);
}
// FUNCTION: LEGO1 0x100a3f50 // FUNCTION: LEGO1 0x100a3f50
// FUNCTION: BETA10 0x10170630
Result MeshImpl::SetTexture(const Texture* pTexture) Result MeshImpl::SetTexture(const Texture* pTexture)
{ {
IDirect3DRMTexture* texture = pTexture ? static_cast<const TextureImpl*>(pTexture)->ImplementationData() : NULL; assert(m_data);
return ResultVal(m_data->groupMesh->SetGroupTexture(m_data->groupIndex, texture));
return SetTexture(static_cast<const TextureImpl*>(pTexture));
} }
// FUNCTION: LEGO1 0x100a3f80 // FUNCTION: LEGO1 0x100a3f80
// FUNCTION: BETA10 0x10170690
Result MeshImpl::SetTextureMappingMode(TextureMappingMode mode) Result MeshImpl::SetTextureMappingMode(TextureMappingMode mode)
{ {
if (mode == PerspectiveCorrect) { assert(m_data);
return ResultVal(m_data->groupMesh->SetGroupMapping(m_data->groupIndex, D3DRMMAP_PERSPCORRECT));
} return MeshSetTextureMappingMode(m_data, mode);
else {
return ResultVal(m_data->groupMesh->SetGroupMapping(m_data->groupIndex, 0));
}
} }
// FUNCTION: BETA10 0x10170750 // FUNCTION: BETA10 0x10170750
@ -159,39 +180,80 @@ Mesh* MeshImpl::DeepClone(MeshBuilder* pMesh)
return DeepClone(*static_cast<MeshBuilderImpl*>(pMesh)); return DeepClone(*static_cast<MeshBuilderImpl*>(pMesh));
} }
inline Result MeshShallowClone(MeshImpl::MeshData* pSource, MeshImpl::MeshData*& rpTarget, IDirect3DRMMesh* pMesh)
{
Result result = Error;
rpTarget = new MeshImpl::MeshData();
if (rpTarget) {
rpTarget->groupMesh = pMesh;
rpTarget->groupIndex = pSource->groupIndex;
result = Success;
}
return result;
}
inline Mesh* MeshImpl::ShallowClone(const MeshBuilderImpl& rMesh)
{
assert(m_data);
assert(rMesh.ImplementationData());
MeshImpl* clone = new MeshImpl();
assert(!clone->ImplementationData());
if (!MeshShallowClone(m_data, clone->ImplementationData(), rMesh.ImplementationData())) {
delete clone;
clone = NULL;
}
return clone;
}
// FUNCTION: LEGO1 0x100a4240 // FUNCTION: LEGO1 0x100a4240
Mesh* MeshImpl::ShallowClone(MeshBuilder* pMeshBuilder) Mesh* MeshImpl::ShallowClone(MeshBuilder* pMeshBuilder)
{ {
MeshImpl* newGroup = new MeshImpl(); assert(m_data);
MeshData* newData = new MeshData(); assert(pMeshBuilder);
newGroup->m_data = newData;
if (newData) { return ShallowClone(*static_cast<MeshBuilderImpl*>(pMeshBuilder));
newData->groupIndex = m_data->groupIndex; }
newData->groupMesh = static_cast<MeshBuilderImpl*>(pMeshBuilder)->ImplementationData();
// FUNCTION: BETA10 0x10171ac0
inline Result MeshGetTexture(MeshImpl::MeshData* pMesh, IDirect3DRMTexture** pD3DTexture)
{
return ResultVal(pMesh->groupMesh->GetGroupTexture(pMesh->groupIndex, pD3DTexture));
}
// FUNCTION: BETA10 0x10171980
inline Result MeshImpl::GetTexture(TextureImpl** ppTexture)
{
assert(m_data);
assert(ppTexture);
TextureImpl* pTextureImpl = new TextureImpl();
assert(pTextureImpl);
// TODO: This helps retail match, but it adds to the stack
IDirect3DRMTexture* tex;
Result result = MeshGetTexture(m_data, &tex);
#ifndef BETA10
if (Succeeded(result)) {
result =
ResultVal(tex->QueryInterface(IID_IDirect3DRMTexture2, (LPVOID*) (&pTextureImpl->ImplementationData())));
} }
else { #endif
delete newGroup;
newGroup = NULL; *ppTexture = pTextureImpl;
} return result;
return newGroup;
} }
// FUNCTION: LEGO1 0x100a4330 // FUNCTION: LEGO1 0x100a4330
// FUNCTION: BETA10 0x10170820
Result MeshImpl::GetTexture(Texture*& rpTexture) Result MeshImpl::GetTexture(Texture*& rpTexture)
{ {
IDirect3DRMTexture* texture; assert(m_data);
TextureImpl* holder = new TextureImpl();
Result result = ResultVal(m_data->groupMesh->GetGroupTexture(m_data->groupIndex, &texture));
if (result) {
// Seems to actually call the first virtual method of holder here
// but that doesn't make any sense since it passes three arguments
// to the method (self + string constant? + an offset?).
// This line makes the start of the function match and is what I return GetTexture(reinterpret_cast<TextureImpl**>(&rpTexture));
// would expect to see there but it clearly isn't what's actually
// there.
holder->SetImplementation(texture);
}
rpTexture = holder;
return Success;
} }

View File

@ -45,16 +45,6 @@ Mesh* MeshBuilderImpl::CreateMesh(
return pMeshImpl; return pMeshImpl;
} }
inline Result MeshSetTextureMappingMode(MeshImpl::MeshData* pMesh, TextureMappingMode mode)
{
if (mode == PerspectiveCorrect) {
return ResultVal(pMesh->groupMesh->SetGroupMapping(pMesh->groupIndex, D3DRMMAP_PERSPCORRECT));
}
else {
return ResultVal(pMesh->groupMesh->SetGroupMapping(pMesh->groupIndex, 0));
}
}
inline Result CreateMesh( inline Result CreateMesh(
IDirect3DRMMesh* pD3DRM, IDirect3DRMMesh* pD3DRM,
unsigned long faceCount, unsigned long faceCount,