Lego3DManager

This commit is contained in:
Christian Semmler 2024-01-06 16:39:35 -05:00
parent f5bb767fe2
commit 2acea1e5b7
13 changed files with 186472 additions and 130 deletions

View File

@ -7,6 +7,7 @@ option(ISLE_USE_SMARTHEAP "Build with SmartHeap" ${MSVC})
option(ISLE_USE_DX5 "Build with internal DirectX 5 SDK" ON)
add_library(lego1 SHARED
LEGO1/3dmanager/lego3dmanager.cpp
LEGO1/3dmanager/lego3dview.cpp
LEGO1/3dmanager/legoview1.cpp
LEGO1/3dmanager/tglsurface.cpp
@ -50,7 +51,6 @@ add_library(lego1 SHARED
LEGO1/jukebox.cpp
LEGO1/jukeboxentity.cpp
LEGO1/jukeboxstate.cpp
LEGO1/lego3dmanager.cpp
LEGO1/legoact2state.cpp
LEGO1/legoactioncontrolpresenter.cpp
LEGO1/legoactor.cpp

View File

@ -21,6 +21,7 @@
#include "mxtimer.h"
#include "mxtransitionmanager.h"
#include "res/resource.h"
#include "viewmanager/viewmanager.h"
#include <dsound.h>

View File

@ -0,0 +1,96 @@
// Lego3DManager.cpp : implementation file
//
#include "lego3dmanager.h"
#include "../viewmanager/viewlodlist.h"
#include "decomp.h"
DECOMP_SIZE_ASSERT(Lego3DManager, 0x10);
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: LEGO1 0x100ab2d0
BOOL InitializeCreateStruct(
TglSurface::CreateStruct& rTglSurfaceCreateStruct,
const Lego3DManager::CreateStruct& rCreateStruct
)
{
// initializes a TglSurface::CreateStruct from a Lego3DManager::CreateStruct
rTglSurfaceCreateStruct.m_pDriverGUID = rCreateStruct.m_pDriverGUID;
rTglSurfaceCreateStruct.m_hWnd = rCreateStruct.m_hWnd;
rTglSurfaceCreateStruct.m_pDirectDraw = rCreateStruct.m_pDirectDraw;
rTglSurfaceCreateStruct.m_pFrontBuffer = rCreateStruct.m_pFrontBuffer;
rTglSurfaceCreateStruct.m_pBackBuffer = rCreateStruct.m_pBackBuffer;
rTglSurfaceCreateStruct.m_pPalette = rCreateStruct.m_pPalette;
rTglSurfaceCreateStruct.m_isFullScreen = rCreateStruct.m_isFullScreen;
rTglSurfaceCreateStruct.m_isWideViewAngle = rCreateStruct.m_isWideViewAngle;
rTglSurfaceCreateStruct.m_direct3d = rCreateStruct.m_direct3d;
rTglSurfaceCreateStruct.m_d3dDevice = rCreateStruct.m_d3dDevice;
return TRUE;
}
//////////////////////////////////////////////////////////////////////////////
// FUNCTION: LEGO1 0x100ab320
Lego3DManager::Lego3DManager()
{
// Tgl things
m_pRenderer = 0;
m_pLego3DView = 0;
m_pViewLODListManager = 0;
}
// FUNCTION: LEGO1 0x100ab360
Lego3DManager::~Lego3DManager()
{
Destroy();
}
// FUNCTION: LEGO1 0x100ab370
BOOL Lego3DManager::Create(CreateStruct& rCreateStruct)
{
TglSurface::CreateStruct tglSurfaceCreateStruct;
BOOL result;
assert(!m_pViewLODListManager);
assert(!m_pRenderer);
assert(!m_pLego3DView);
m_pViewLODListManager = new ViewLODListManager;
assert(m_pViewLODListManager);
m_pRenderer = Tgl::CreateRenderer();
assert(m_pRenderer);
m_pLego3DView = new Lego3DView;
result = InitializeCreateStruct(tglSurfaceCreateStruct, rCreateStruct);
assert(result);
result = m_pLego3DView->Create(tglSurfaceCreateStruct, m_pRenderer);
assert(result);
return result;
}
// FUNCTION: LEGO1 0x100ab460
void Lego3DManager::Destroy()
{
delete m_pLego3DView;
m_pLego3DView = 0;
delete m_pRenderer;
m_pRenderer = 0;
delete m_pViewLODListManager;
m_pViewLODListManager = 0;
}
// FUNCTION: LEGO1 0x100ab4b0
double Lego3DManager::Render(double p_und)
{
assert(m_pLego3DView);
return m_pLego3DView->Render(p_und);
}

View File

@ -0,0 +1,117 @@
#ifndef _Lego3DManager_h
#define _Lego3DManager_h
#include "assert.h"
#include "lego3dview.h"
class Tgl::Renderer;
class Tgl::Group;
class ViewROI;
// ??? for now
class ViewLODListManager;
/////////////////////////////////////////////////////////////////////////////
//
// Lego3DManager
// VTABLE: LEGO1 0x100dbfa4
// SIZE 0x10
class Lego3DManager {
public:
// SIZE 0x28
struct CreateStruct {
const GUID* m_pDriverGUID; // 0x00
HWND m_hWnd; // 0x04
IDirectDraw* m_pDirectDraw; // 0x08
IDirectDrawSurface* m_pFrontBuffer; // 0x0c
IDirectDrawSurface* m_pBackBuffer; // 0x10
IDirectDrawPalette* m_pPalette; // 0x14
BOOL m_isFullScreen; // 0x18
BOOL m_isWideViewAngle; // 0x1c
IDirect3D2* m_direct3d; // 0x20
IDirect3DDevice2* m_d3dDevice; // 0x24
};
public:
Lego3DManager();
virtual ~Lego3DManager();
BOOL Create(CreateStruct&);
void Destroy();
BOOL Add(ViewROI&);
BOOL Remove(ViewROI&);
BOOL Moved(ViewROI&);
BOOL SetPointOfView(ViewROI&);
double Render(double p_und);
Tgl::Renderer* GetRenderer();
Tgl::Group* GetScene();
Lego3DView* GetLego3DView();
// ??? for now
ViewLODListManager* GetViewLODListManager();
private:
Tgl::Renderer* m_pRenderer; // 0x04
Lego3DView* m_pLego3DView; // 0x08
ViewLODListManager* m_pViewLODListManager; // 0x0c
};
/////////////////////////////////////////////////////////////////////////////
//
// Lego3DManager implementaion
inline BOOL Lego3DManager::Add(ViewROI& rROI)
{
assert(m_pLego3DView);
return m_pLego3DView->Add(rROI);
}
inline BOOL Lego3DManager::Remove(ViewROI& rROI)
{
assert(m_pLego3DView);
return m_pLego3DView->Remove(rROI);
}
inline BOOL Lego3DManager::SetPointOfView(ViewROI& rROI)
{
assert(m_pLego3DView);
return m_pLego3DView->SetPointOfView(rROI);
}
inline BOOL Lego3DManager::Moved(ViewROI& rROI)
{
assert(m_pLego3DView);
return m_pLego3DView->Moved(rROI);
}
inline Tgl::Renderer* Lego3DManager::GetRenderer()
{
return m_pRenderer;
}
inline Tgl::Group* Lego3DManager::GetScene()
{
assert(m_pLego3DView);
return m_pLego3DView->GetScene();
}
inline Lego3DView* Lego3DManager::GetLego3DView()
{
return m_pLego3DView;
}
inline ViewLODListManager* Lego3DManager::GetViewLODListManager()
{
return m_pViewLODListManager;
}
#endif /* _Lego3DManager_h */

View File

@ -134,7 +134,7 @@ BOOL Lego3DView::Moved(ViewROI& rROI)
}
// STUB: LEGO1 0x100ab270
double Lego3DView::Render()
double Lego3DView::Render(double p_und)
{
// assert(m_pViewManager);

View File

@ -25,7 +25,7 @@ class Lego3DView : public LegoView1 {
BOOL Moved(ViewROI&);
BOOL SetPointOfView(ViewROI&);
double Render();
double Render(double p_und);
ViewROI* Pick(unsigned long x, unsigned long y);

View File

@ -1,71 +0,0 @@
#include "lego3dmanager.h"
#include "3dmanager/tglsurface.h"
#include "decomp.h"
#include "viewmanager/viewlodlist.h"
DECOMP_SIZE_ASSERT(Lego3DManager, 0x10);
// FUNCTION: LEGO1 0x100ab2d0
BOOL InitializeCreateStruct(TglSurface::CreateStruct& p_tglSurface, const Lego3DManager::CreateStruct& p_createStruct)
{
p_tglSurface.m_pDriverGUID = p_createStruct.m_driverGUID;
p_tglSurface.m_hWnd = p_createStruct.m_hwnd;
p_tglSurface.m_pDirectDraw = p_createStruct.m_directDraw;
p_tglSurface.m_pFrontBuffer = p_createStruct.m_ddSurface1;
p_tglSurface.m_pBackBuffer = p_createStruct.m_ddSurface2;
p_tglSurface.m_pPalette = p_createStruct.m_ddPalette;
p_tglSurface.m_isFullScreen = p_createStruct.m_isFullScreen;
p_tglSurface.m_isWideViewAngle = p_createStruct.m_isWideViewAngle;
p_tglSurface.m_direct3d = p_createStruct.m_direct3d;
p_tglSurface.m_d3dDevice = p_createStruct.m_d3dDevice;
return TRUE;
}
// FUNCTION: LEGO1 0x100ab320
Lego3DManager::Lego3DManager()
{
m_renderer = NULL;
m_3dView = NULL;
m_viewLODListManager = NULL;
}
// FUNCTION: LEGO1 0x100ab360
Lego3DManager::~Lego3DManager()
{
Destroy();
}
// FUNCTION: LEGO1 0x100ab370
BOOL Lego3DManager::Create(Lego3DManager::CreateStruct& p_createStruct)
{
TglSurface::CreateStruct surfaceCreateStruct;
m_viewLODListManager = new ViewLODListManager;
m_renderer = Tgl::CreateRenderer();
m_3dView = new Lego3DView;
InitializeCreateStruct(surfaceCreateStruct, p_createStruct);
return m_3dView->Create(surfaceCreateStruct, m_renderer);
}
// FUNCTION: LEGO1 0x100ab460
void Lego3DManager::Destroy()
{
delete m_3dView;
m_3dView = NULL;
delete m_renderer;
m_renderer = NULL;
delete m_viewLODListManager;
m_viewLODListManager = NULL;
}
// STUB: LEGO1 0xx100ab4b0
double Lego3DManager::FUN_100ab4b0(double p_und)
{
// TODO
return 0.0;
}

View File

@ -1,46 +0,0 @@
#ifndef LEGO3DMANAGER_H
#define LEGO3DMANAGER_H
#include "lego3dview.h"
class ViewLODListManager;
// VTABLE: LEGO1 0x100dbfa4
// SIZE 0x10
class Lego3DManager {
public:
// SIZE 0x28
struct CreateStruct {
GUID* m_driverGUID; // 0x00
HWND m_hwnd; // 0x04
IDirectDraw* m_directDraw; // 0x08
IDirectDrawSurface* m_ddSurface1; // 0x0c
IDirectDrawSurface* m_ddSurface2; // 0x10
IDirectDrawPalette* m_ddPalette; // 0x14
BOOL m_isFullScreen; // 0x18
BOOL m_isWideViewAngle; // 0x1c
IDirect3D2* m_direct3d; // 0x20
IDirect3DDevice2* m_d3dDevice; // 0x24
};
Lego3DManager();
virtual ~Lego3DManager();
BOOL Create(CreateStruct& p_createStruct);
double FUN_100ab4b0(double p_und);
inline Lego3DView* GetLego3DView() { return this->m_3dView; }
inline ViewLODListManager* GetViewLODListManager() { return this->m_viewLODListManager; }
private:
Tgl::Renderer* m_renderer; // 0x04
Lego3DView* m_3dView; // 0x08
ViewLODListManager* m_viewLODListManager; // 0x0c
void Destroy();
};
// SYNTHETIC: LEGO1 0x100ab340
// Lego3DManager::`scalar deleting destructor'
#endif // LEGO3DMANAGER_H

View File

@ -255,7 +255,7 @@ void FUN_1001a700()
// FUNCTION: LEGO1 0x1003dd70
LegoROI* PickROI(MxLong p_a, MxLong p_b)
{
return VideoManager()->Get3DManager()->GetLego3DView()->PickROI(p_a, p_b);
return (LegoROI*) VideoManager()->Get3DManager()->GetLego3DView()->Pick(p_a, p_b);
}
// STUB: LEGO1 0x1003ddc0

View File

@ -150,11 +150,11 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
Lego3DManager::CreateStruct createStruct;
memset(&createStruct, 0, sizeof(createStruct));
createStruct.m_hwnd = LegoOmni::GetInstance()->GetWindowHandle();
createStruct.m_directDraw = m_pDirectDraw;
createStruct.m_ddSurface1 = m_displaySurface->GetDirectDrawSurface1();
createStruct.m_ddSurface2 = m_displaySurface->GetDirectDrawSurface2();
createStruct.m_ddPalette = m_videoParam.GetPalette()->CreateNativePalette();
createStruct.m_hWnd = LegoOmni::GetInstance()->GetWindowHandle();
createStruct.m_pDirectDraw = m_pDirectDraw;
createStruct.m_pFrontBuffer = m_displaySurface->GetDirectDrawSurface1();
createStruct.m_pBackBuffer = m_displaySurface->GetDirectDrawSurface2();
createStruct.m_pPalette = m_videoParam.GetPalette()->CreateNativePalette();
createStruct.m_isFullScreen = FALSE;
createStruct.m_isWideViewAngle = m_videoParam.Flags().GetWideViewAngle();
createStruct.m_direct3d = m_direct3d->GetDirect3D();
@ -175,8 +175,8 @@ MxResult LegoVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyM
CalcLocalTransform(posVec, dirVec, upVec, outMatrix);
m_viewROI->WrappedSetLocalTransform(outMatrix);
m_3dManager->GetLego3DView()->FUN_100ab100(m_viewROI);
m_3dManager->GetLego3DView()->FUN_100ab1b0(m_viewROI);
m_3dManager->GetLego3DView()->Add(*m_viewROI);
m_3dManager->GetLego3DView()->SetPointOfView(*m_viewROI);
m_unk0x100d9d00 = new MxUnknown100d9d00;
m_unk0xe4 = FALSE;
@ -260,7 +260,7 @@ MxResult LegoVideoManager::Tickle()
presenter->PutData();
if (!m_unk0xe5) {
m_3dManager->FUN_100ab4b0(0.0);
m_3dManager->Render(0.0);
m_3dManager->GetLego3DView()->GetDevice()->Update();
}

View File

@ -1,8 +1,8 @@
#ifndef LEGOVIDEOMANAGER_H
#define LEGOVIDEOMANAGER_H
#include "3dmanager/lego3dmanager.h"
#include "decomp.h"
#include "lego3dmanager.h"
#include "mxdirect3d.h"
#include "mxdirectx/mxstopwatch.h"
#include "mxunknown100d9d00.h"
@ -10,6 +10,8 @@
#include <ddraw.h>
class LegoROI;
// VTABLE: LEGO1 0x100d9c88
// SIZE 0x590
class LegoVideoManager : public MxVideoManager {

274
out.html Normal file
View File

@ -0,0 +1,274 @@
<!DOCTYPE html>
<html>
<head>
<title>Decompilation Status</title>
<style>
body {
background: #202020;
color: #f0f0f0;
font-family: sans-serif;
}
h1 {
text-align: center;
}
.main {
width: 800px;
max-width: 100%;
margin: auto;
}
#search {
width: 100%;
box-sizing: border-box;
background: #303030;
color: #f0f0f0;
border: 1px #f0f0f0 solid;
padding: 0.5em;
border-radius: 0.5em;
}
#search::placeholder {
color: #b0b0b0;
}
#listing {
width: 100%;
border-collapse: collapse;
font-family: monospace;
}
.funcrow:hover {
background: #404040 !important;
}
.funcrow:nth-child(odd), #listing th {
background: #282828;
}
.funcrow:nth-child(even) {
background: #383838;
}
#listing td, #listing th {
border: 1px #f0f0f0 solid;
padding: 0.5em;
}
.diffneg {
color: #FF8080;
}
.diffpos {
color: #80FF80;
}
.identical {
font-style: italic;
text-align: center;
}
#sortind {
margin: 0 0.5em;
}
.filters {
font-size: 10pt;
text-align: center;
margin: 0.5em 0 1em 0;
}
</style>
<script>
var data = [{"address": "0x1007b770", "name": "LegoVideoManager::Tickle", "matching": 0.9636363636363636, "diff": ""}];
function diffCssClass(firstChar) {
return firstChar === '-' ? 'diffneg' : (firstChar === '+' ? 'diffpos' : '');
}
function asmLineToDiv(line) {
const diff_line = document.createElement('div');
diff_line.className = diffCssClass(line[0]);
diff_line.innerText = line;
return diff_line;
}
function formatAsm(asm) {
var lines = asm.split('\n');
return lines.filter(line => line.length > 0)
.map(asmLineToDiv);
}
function rowClick() {
if (this.dataset.expanded === 'true') {
this.nextSibling.remove();
this.dataset.expanded = false;
} else {
var row = this.parentNode.insertBefore(document.createElement('tr'), this.nextSibling);
row.classList.add('diff');
var decCel = row.appendChild(document.createElement('td'));
decCel.colSpan = 3;
var diff = data[this.dataset.index].diff;
if (diff == '') {
diff = document.createElement('div');
diff.className = 'identical';
diff.innerText = 'Identical function - no diff';
decCel.appendChild(diff);
} else {
diff = formatAsm(diff);
for (const el of diff) {
decCel.appendChild(el);
}
}
this.dataset.expanded = true;
}
}
function closeAllDiffs() {
const collection = document.getElementsByClassName("diff");
for (var ele of collection) {
ele.remove();
}
}
const filterOptions = { text: '', hidePerfect: false };
function filter() {
closeAllDiffs();
var ltext = filterOptions.text.toLowerCase();
const collection = document.getElementsByClassName("funcrow");
var searchCount = 0;
for (var ele of collection) {
var eledata = data[ele.dataset.index];
const textOk = (ltext == ''
|| eledata.address.toLowerCase().includes(ltext)
|| eledata.name.toLowerCase().includes(ltext));
const perfOk = (!filterOptions.hidePerfect || (eledata.matching < 1));
if (textOk && perfOk) {
ele.style.display = '';
searchCount++;
} else {
ele.style.display = 'none';
}
}
}
var lastSortedCol = -1;
var ascending = true;
function sortByColumn(column) {
closeAllDiffs();
if (column == lastSortedCol) {
ascending = !ascending;
}
lastSortedCol = column;
const collection = document.getElementsByClassName("funcrow");
var newOrder = [];
for (var ele of collection) {
var inserted = false;
for (var i = 0; i < newOrder.length; i++) {
var cmpEle = newOrder[i];
var ourCol = ele.childNodes[column];
var cmpCol = cmpEle.childNodes[column];
if ((cmpCol.dataset.value > ourCol.dataset.value) == ascending) {
newOrder.splice(i, 0, ele);
inserted = true;
break;
}
}
if (!inserted) {
newOrder.push(ele);
}
}
for (var i = 1; i < newOrder.length; i++) {
newOrder[i - 1].after(newOrder[i]);
}
var sortIndicator = document.getElementById('sortind');
if (!sortIndicator) {
sortIndicator = document.createElement('span');
sortIndicator.id = 'sortind';
}
sortIndicator.innerHTML = ascending ? '&#9650;' : '&#9660;';
var th = document.getElementById('listingheader').childNodes[column];
th.appendChild(sortIndicator);
}
document.addEventListener("DOMContentLoaded", () => {
var listing = document.getElementById('listing');
const headers = listing.getElementsByTagName('th');
var headerCount = 0;
for (const header of headers) {
header.addEventListener('click', function(){
sortByColumn(this.dataset.column, true);
});
header.dataset.column = headerCount;
headerCount++;
}
data.forEach((element, index) => {
var row = listing.appendChild(document.createElement('tr'));
var addrCel = row.appendChild(document.createElement('td'));
var nameCel = row.appendChild(document.createElement('td'));
var matchCel = row.appendChild(document.createElement('td'));
addrCel.innerText = addrCel.dataset.value = element.address;
nameCel.innerText = nameCel.dataset.value = element.name;
var effectiveNote = (element.matching == 1 && element.diff != '') ? '*' : '';
matchCel.innerHTML = (element.matching * 100).toFixed(2) + '%' + effectiveNote;
matchCel.dataset.value = element.matching;
row.classList.add('funcrow');
row.addEventListener('click', rowClick);
row.dataset.index = index;
row.dataset.expanded = false;
});
var search = document.getElementById('search');
search.addEventListener('input', function (evt) {
filterOptions.text = search.value;
filter();
});
const cbHidePerfect = document.getElementById('cbHidePerfect');
cbHidePerfect.addEventListener('change', evt => {
filterOptions.hidePerfect = evt.target.checked;
filter();
})
sortByColumn(0);
});
</script>
</head>
<body>
<div class="main">
<h1>Decompilation Status</h1>
<input id="search" type="search" placeholder="Search for offset or function name...">
<div class="filters">
<label for="cbHidePerfect">Hide 100% match</label>
<input type="checkbox" id="cbHidePerfect" />
</div>
<table id="listing">
<tr id='listingheader'><th style='width: 20%'>Address</th><th style="width:60%">Name</th><th style='width: 20%'>Matching</th></tr>
</table>
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff