mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-02-03 12:31:15 +00:00
Merge branch 'master' into emscripten
This commit is contained in:
commit
1b119c856c
@ -16,6 +16,11 @@ class MxDSAction;
|
||||
// SIZE 0x10
|
||||
class PoliceState : public LegoState {
|
||||
public:
|
||||
enum {
|
||||
e_noAnimation = 0,
|
||||
e_playingAnimation = 1,
|
||||
};
|
||||
|
||||
PoliceState();
|
||||
~PoliceState() override {}
|
||||
|
||||
@ -38,15 +43,15 @@ class PoliceState : public LegoState {
|
||||
// SYNTHETIC: LEGO1 0x1005e920
|
||||
// PoliceState::`scalar deleting destructor'
|
||||
|
||||
undefined4 GetUnknown0x0c() { return m_unk0x0c; }
|
||||
void SetUnknown0x0c(undefined4 p_unk0x0c) { m_unk0x0c = p_unk0x0c; }
|
||||
MxS32 GetState() { return m_state; }
|
||||
void SetState(MxS32 p_state) { m_state = p_state; }
|
||||
|
||||
void FUN_1005ea40();
|
||||
void StartAnimation();
|
||||
|
||||
// TODO: Most likely getters/setters are not used according to BETA.
|
||||
|
||||
PoliceScript::Script m_policeScript; // 0x08
|
||||
undefined4 m_unk0x0c; // 0x0c
|
||||
MxS32 m_state; // 0x0c
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d8a80
|
||||
|
||||
@ -105,7 +105,7 @@ MxLong Police::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
switch (p_param.m_clickedObjectId) {
|
||||
case PoliceScript::c_LeftArrow_Ctl:
|
||||
case PoliceScript::c_RightArrow_Ctl:
|
||||
if (m_policeState->GetUnknown0x0c() == 1) {
|
||||
if (m_policeState->GetState() == PoliceState::e_playingAnimation) {
|
||||
DeleteObjects(&m_atomId, PoliceScript::c_nps001ni_RunAnim, PoliceScript::c_nps002la_RunAnim);
|
||||
}
|
||||
|
||||
@ -114,7 +114,7 @@ MxLong Police::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case PoliceScript::c_Info_Ctl:
|
||||
if (m_policeState->GetUnknown0x0c() == 1) {
|
||||
if (m_policeState->GetState() == PoliceState::e_playingAnimation) {
|
||||
DeleteObjects(&m_atomId, PoliceScript::c_nps001ni_RunAnim, PoliceScript::c_nps002la_RunAnim);
|
||||
}
|
||||
|
||||
@ -123,7 +123,7 @@ MxLong Police::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case PoliceScript::c_Door_Ctl:
|
||||
if (m_policeState->GetUnknown0x0c() == 1) {
|
||||
if (m_policeState->GetState() == PoliceState::e_playingAnimation) {
|
||||
DeleteObjects(&m_atomId, PoliceScript::c_nps001ni_RunAnim, PoliceScript::c_nps002la_RunAnim);
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ MxLong Police::HandleControl(LegoControlManagerNotificationParam& p_param)
|
||||
TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE);
|
||||
break;
|
||||
case PoliceScript::c_Donut_Ctl:
|
||||
m_policeState->FUN_1005ea40();
|
||||
m_policeState->StartAnimation();
|
||||
}
|
||||
}
|
||||
|
||||
@ -145,8 +145,8 @@ MxLong Police::HandleEndAction(MxEndActionNotificationParam& p_param)
|
||||
MxDSAction* action = p_param.GetAction();
|
||||
|
||||
if (m_radio.Notify(p_param) == 0 && m_atomId == action->GetAtomId()) {
|
||||
if (m_policeState->GetUnknown0x0c() == 1) {
|
||||
m_policeState->SetUnknown0x0c(0);
|
||||
if (m_policeState->GetState() == PoliceState::e_playingAnimation) {
|
||||
m_policeState->SetState(PoliceState::e_noAnimation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -161,9 +161,9 @@ MxLong Police::HandleKeyPress(LegoEventNotificationParam& p_param)
|
||||
{
|
||||
MxLong result = 0;
|
||||
|
||||
if (p_param.GetKey() == SDLK_SPACE && m_policeState->GetUnknown0x0c() == 1) {
|
||||
if (p_param.GetKey() == SDLK_SPACE && m_policeState->GetState() == PoliceState::e_playingAnimation) {
|
||||
DeleteObjects(&m_atomId, PoliceScript::c_nps001ni_RunAnim, PoliceScript::c_nps002la_RunAnim);
|
||||
m_policeState->SetUnknown0x0c(0);
|
||||
m_policeState->SetState(PoliceState::e_noAnimation);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -197,7 +197,7 @@ MxBool Police::Escape()
|
||||
// FUNCTION: LEGO1 0x1005e7c0
|
||||
PoliceState::PoliceState()
|
||||
{
|
||||
m_unk0x0c = 0;
|
||||
m_state = PoliceState::e_noAnimation;
|
||||
m_policeScript = (SDL_rand(2) == 0) ? PoliceScript::c_nps002la_RunAnim : PoliceScript::c_nps001ni_RunAnim;
|
||||
}
|
||||
|
||||
@ -218,11 +218,11 @@ MxResult PoliceState::Serialize(LegoStorage* p_storage)
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1005ea40
|
||||
void PoliceState::FUN_1005ea40()
|
||||
void PoliceState::StartAnimation()
|
||||
{
|
||||
PoliceScript::Script policeScript;
|
||||
|
||||
if (m_unk0x0c == 1) {
|
||||
if (m_state == PoliceState::e_playingAnimation) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -248,5 +248,5 @@ void PoliceState::FUN_1005ea40()
|
||||
Start(&action);
|
||||
}
|
||||
|
||||
m_unk0x0c = 1;
|
||||
m_state = PoliceState::e_playingAnimation;
|
||||
}
|
||||
|
||||
@ -439,6 +439,11 @@ HRESULT OpenGL1Renderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix)
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
void OpenGL1Renderer::EnableTransparency()
|
||||
{
|
||||
glDepthMask(GL_FALSE);
|
||||
}
|
||||
|
||||
void OpenGL1Renderer::SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
@ -524,6 +529,7 @@ void OpenGL1Renderer::SubmitDraw(
|
||||
|
||||
HRESULT OpenGL1Renderer::FinalizeFrame()
|
||||
{
|
||||
glDepthMask(GL_TRUE);
|
||||
glReadPixels(0, 0, m_width, m_height, GL_RGBA, GL_UNSIGNED_BYTE, m_renderedImage->pixels);
|
||||
glBindFramebuffer(GL_FRAMEBUFFER, 0);
|
||||
|
||||
|
||||
@ -735,6 +735,11 @@ HRESULT Direct3DRMSDL3GPURenderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix)
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
void Direct3DRMSDL3GPURenderer::EnableTransparency()
|
||||
{
|
||||
SDL_BindGPUGraphicsPipeline(m_renderPass, m_transparentPipeline);
|
||||
}
|
||||
|
||||
void Direct3DRMSDL3GPURenderer::SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
@ -742,9 +747,6 @@ void Direct3DRMSDL3GPURenderer::SubmitDraw(
|
||||
const Appearance& appearance
|
||||
)
|
||||
{
|
||||
// TODO only switch piplinen after all opaque's have been rendered
|
||||
SDL_BindGPUGraphicsPipeline(m_renderPass, appearance.color.a == 255 ? m_opaquePipeline : m_transparentPipeline);
|
||||
|
||||
D3DRMMATRIX4D worldViewMatrix;
|
||||
MultiplyMatrix(worldViewMatrix, worldMatrix, m_viewMatrix);
|
||||
memcpy(&m_uniforms.worldViewMatrix, worldViewMatrix, sizeof(D3DRMMATRIX4D));
|
||||
|
||||
@ -554,6 +554,10 @@ HRESULT Direct3DRMSoftwareRenderer::BeginFrame(const D3DRMMATRIX4D& viewMatrix)
|
||||
return DD_OK;
|
||||
}
|
||||
|
||||
void Direct3DRMSoftwareRenderer::EnableTransparency()
|
||||
{
|
||||
}
|
||||
|
||||
void Direct3DRMSoftwareRenderer::SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
|
||||
@ -216,6 +216,23 @@ bool IsMeshInFrustum(Direct3DRMMeshImpl* mesh, const D3DRMMATRIX4D& worldMatrix)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline D3DRMVECTOR4D TransformPoint4(const D3DRMVECTOR4D& p, const D3DRMMATRIX4D& m)
|
||||
{
|
||||
return {
|
||||
p.x * m[0][0] + p.y * m[1][0] + p.z * m[2][0] + p.w * m[3][0],
|
||||
p.x * m[0][1] + p.y * m[1][1] + p.z * m[2][1] + p.w * m[3][1],
|
||||
p.x * m[0][2] + p.y * m[1][2] + p.z * m[2][2] + p.w * m[3][2],
|
||||
p.x * m[0][3] + p.y * m[1][3] + p.z * m[2][3] + p.w * m[3][3]
|
||||
};
|
||||
}
|
||||
|
||||
float CalculateDepth(const D3DRMMATRIX4D& viewProj, const D3DRMMATRIX4D& worldMatrix)
|
||||
{
|
||||
D3DRMVECTOR4D position = {worldMatrix[3][0], worldMatrix[3][1], worldMatrix[3][2], 1.0f};
|
||||
D3DRMVECTOR4D clipPos = TransformPoint4(position, viewProj);
|
||||
return (clipPos.z / clipPos.w + 1.0f) * 0.5f;
|
||||
}
|
||||
|
||||
void Direct3DRMViewportImpl::CollectMeshesFromFrame(IDirect3DRMFrame* frame, D3DRMMATRIX4D parentMatrix)
|
||||
{
|
||||
Direct3DRMFrameImpl* frameImpl = static_cast<Direct3DRMFrameImpl*>(frame);
|
||||
@ -251,15 +268,33 @@ void Direct3DRMViewportImpl::CollectMeshesFromFrame(IDirect3DRMFrame* frame, D3D
|
||||
DWORD groupCount = mesh->GetGroupCount();
|
||||
for (DWORD gi = 0; gi < groupCount; ++gi) {
|
||||
const MeshGroup& meshGroup = mesh->GetGroup(gi);
|
||||
m_renderer->SubmitDraw(
|
||||
m_renderer->GetMeshId(mesh, &meshGroup),
|
||||
worldMatrix,
|
||||
worldMatrixInvert,
|
||||
{meshGroup.color,
|
||||
meshGroup.material ? meshGroup.material->GetPower() : 0.0f,
|
||||
meshGroup.texture ? m_renderer->GetTextureId(meshGroup.texture) : NO_TEXTURE_ID,
|
||||
meshGroup.quality == D3DRMRENDER_FLAT || meshGroup.quality == D3DRMRENDER_UNLITFLAT}
|
||||
);
|
||||
|
||||
Appearance appearance = {
|
||||
meshGroup.color,
|
||||
meshGroup.material ? meshGroup.material->GetPower() : 0.0f,
|
||||
meshGroup.texture ? m_renderer->GetTextureId(meshGroup.texture) : NO_TEXTURE_ID,
|
||||
meshGroup.quality == D3DRMRENDER_FLAT || meshGroup.quality == D3DRMRENDER_UNLITFLAT
|
||||
};
|
||||
|
||||
if (appearance.color.a != 255) {
|
||||
m_deferredDraws.push_back(
|
||||
{m_renderer->GetMeshId(mesh, &meshGroup),
|
||||
{},
|
||||
{},
|
||||
appearance,
|
||||
CalculateDepth(m_viewProjectionwMatrix, worldMatrix)}
|
||||
);
|
||||
memcpy(m_deferredDraws.back().worldMatrix, worldMatrix, sizeof(D3DRMMATRIX4D));
|
||||
memcpy(m_deferredDraws.back().normalMatrix, worldMatrixInvert, sizeof(Matrix3x3));
|
||||
}
|
||||
else {
|
||||
m_renderer->SubmitDraw(
|
||||
m_renderer->GetMeshId(mesh, &meshGroup),
|
||||
worldMatrix,
|
||||
worldMatrixInvert,
|
||||
appearance
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
mesh->Release();
|
||||
@ -274,10 +309,10 @@ HRESULT Direct3DRMViewportImpl::RenderScene()
|
||||
m_backgroundColor = static_cast<Direct3DRMFrameImpl*>(m_rootFrame)->m_backgroundColor;
|
||||
|
||||
// Compute view-projection matrix
|
||||
D3DRMMATRIX4D cameraWorld, viewProj;
|
||||
D3DRMMATRIX4D cameraWorld;
|
||||
ComputeFrameWorldMatrix(m_camera, cameraWorld);
|
||||
D3DRMMatrixInvertOrthogonal(m_viewMatrix, cameraWorld);
|
||||
D3DRMMatrixMultiply(viewProj, m_viewMatrix, m_projectionMatrix);
|
||||
D3DRMMatrixMultiply(m_viewProjectionwMatrix, m_viewMatrix, m_projectionMatrix);
|
||||
|
||||
D3DRMMATRIX4D identity = {{1.f, 0.f, 0.f, 0.f}, {0.f, 1.f, 0.f, 0.f}, {0.f, 0.f, 1.f, 0.f}, {0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
@ -289,8 +324,20 @@ HRESULT Direct3DRMViewportImpl::RenderScene()
|
||||
return status;
|
||||
}
|
||||
|
||||
ExtractFrustumPlanes(viewProj);
|
||||
ExtractFrustumPlanes(m_viewProjectionwMatrix);
|
||||
CollectMeshesFromFrame(m_rootFrame, identity);
|
||||
|
||||
std::sort(
|
||||
m_deferredDraws.begin(),
|
||||
m_deferredDraws.end(),
|
||||
[](const DeferredDrawCommand& a, const DeferredDrawCommand& b) { return a.depth > b.depth; }
|
||||
);
|
||||
m_renderer->EnableTransparency();
|
||||
for (const DeferredDrawCommand& cmd : m_deferredDraws) {
|
||||
m_renderer->SubmitDraw(cmd.meshId, cmd.worldMatrix, cmd.normalMatrix, cmd.appearance);
|
||||
}
|
||||
m_deferredDraws.clear();
|
||||
|
||||
return m_renderer->FinalizeFrame();
|
||||
}
|
||||
|
||||
|
||||
@ -42,6 +42,7 @@ class Direct3DRMRenderer : public IDirect3DDevice2 {
|
||||
virtual void GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC* helDesc) = 0;
|
||||
virtual const char* GetName() = 0;
|
||||
virtual HRESULT BeginFrame(const D3DRMMATRIX4D& viewMatrix) = 0;
|
||||
virtual void EnableTransparency() = 0;
|
||||
virtual void SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
|
||||
@ -48,6 +48,7 @@ class OpenGL1Renderer : public Direct3DRMRenderer {
|
||||
void GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC* helDesc) override;
|
||||
const char* GetName() override;
|
||||
HRESULT BeginFrame(const D3DRMMATRIX4D& viewMatrix) override;
|
||||
void EnableTransparency() override;
|
||||
void SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
|
||||
@ -55,6 +55,7 @@ class Direct3DRMSDL3GPURenderer : public Direct3DRMRenderer {
|
||||
void GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC* helDesc) override;
|
||||
const char* GetName() override;
|
||||
HRESULT BeginFrame(const D3DRMMATRIX4D& viewMatrix) override;
|
||||
void EnableTransparency() override;
|
||||
void SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
|
||||
@ -36,6 +36,7 @@ class Direct3DRMSoftwareRenderer : public Direct3DRMRenderer {
|
||||
void GetDesc(D3DDEVICEDESC* halDesc, D3DDEVICEDESC* helDesc) override;
|
||||
const char* GetName() override;
|
||||
HRESULT BeginFrame(const D3DRMMATRIX4D& viewMatrix) override;
|
||||
void EnableTransparency() override;
|
||||
void SubmitDraw(
|
||||
DWORD meshId,
|
||||
const D3DRMMATRIX4D& worldMatrix,
|
||||
|
||||
@ -5,6 +5,15 @@
|
||||
#include "miniwin/d3drm.h"
|
||||
|
||||
#include <SDL3/SDL.h>
|
||||
#include <vector>
|
||||
|
||||
struct DeferredDrawCommand {
|
||||
DWORD meshId;
|
||||
D3DRMMATRIX4D worldMatrix;
|
||||
Matrix3x3 normalMatrix;
|
||||
Appearance appearance;
|
||||
float depth;
|
||||
};
|
||||
|
||||
class Direct3DRMDeviceImpl;
|
||||
class Direct3DRMFrameImpl;
|
||||
@ -40,9 +49,11 @@ struct Direct3DRMViewportImpl : public Direct3DRMObjectBaseImpl<IDirect3DRMViewp
|
||||
void CollectMeshesFromFrame(IDirect3DRMFrame* frame, D3DRMMATRIX4D parentMatrix);
|
||||
void UpdateProjectionMatrix();
|
||||
Direct3DRMRenderer* m_renderer;
|
||||
std::vector<DeferredDrawCommand> m_deferredDraws;
|
||||
D3DCOLOR m_backgroundColor = 0xFF000000;
|
||||
DWORD m_width;
|
||||
DWORD m_height;
|
||||
D3DRMMATRIX4D m_viewProjectionwMatrix;
|
||||
D3DRMMATRIX4D m_viewMatrix;
|
||||
D3DRMMATRIX4D m_projectionMatrix;
|
||||
D3DRMMATRIX4D m_inverseProjectionMatrix;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user