Player reflection and other imps

This commit is contained in:
Jack Andersen 2017-03-25 19:53:04 -10:00
parent db12dd2ea2
commit c069666307
35 changed files with 654 additions and 72 deletions

View File

@ -867,6 +867,18 @@ void _ConstructMaterial(Stream& out,
}
}
/* Indirect texture node */
if (material.flags.samusReflectionIndirectTexture())
{
Material::AddTexture(out, GX::TexGenSrc::TG_POS, -1, material.indTexSlot[0]);
out << "# Indirect Texture\n"
"ind_out = new_nodetree.nodes.new('ShaderNodeOutput')\n"
"gridder.place_node(ind_out, 3)\n"
"ind_out.name = 'IndirectOutput'\n"
"ind_out.label = 'Indirect'\n"
"new_nodetree.links.new(tex_node.outputs['Color'], ind_out.inputs['Color'])\n";
}
/* TEV-emulation combiner-node index context */
unsigned c_combiner_idx = 0;
unsigned a_combiner_idx = 0;

View File

@ -642,7 +642,14 @@ void CHintOptions::ActivateContinueDelayHintTimer(const char* name)
void CHintOptions::DismissDisplayedHint()
{
if (x10_nextHintIdx == -1)
return;
const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[x10_nextHintIdx];
SHintState& hintState = x0_hintStates[x10_nextHintIdx];
if (hintState.x4_time >= hint.GetTextTime())
return;
hintState.x4_time = hint.GetNormalTime();
hintState.x8_dismissed = true;
}
u32 CHintOptions::GetNextHintIdx() const

View File

@ -83,6 +83,30 @@ CEntity* CObjectList::GetObjectById(TUniqueId uid)
return ent.entity;
}
const CEntity* CObjectList::GetValidObjectById(TUniqueId uid) const
{
if (uid == kInvalidUniqueId)
return nullptr;
const SObjectListEntry& ent = x0_list[uid & 0x3ff];
if (!ent.entity)
return nullptr;
if (ent.entity->GetUniqueId() != uid)
return nullptr;
return ent.entity;
}
CEntity* CObjectList::GetValidObjectById(TUniqueId uid)
{
if (uid == kInvalidUniqueId)
return nullptr;
SObjectListEntry& ent = x0_list[uid & 0x3ff];
if (!ent.entity)
return nullptr;
if (ent.entity->GetUniqueId() != uid)
return nullptr;
return ent.entity;
}
bool CObjectList::IsQualified(const CEntity&) {return true;}
}

View File

@ -58,6 +58,8 @@ public:
const CEntity* GetObjectById(TUniqueId uid) const;
const CEntity* GetObjectByIndex(s32 index) const { return x0_list[index].entity; }
CEntity* GetObjectById(TUniqueId uid);
const CEntity* GetValidObjectById(TUniqueId uid) const;
CEntity* GetValidObjectById(TUniqueId uid);
TUniqueId GetFirstObjectIndex() const { return x2008_firstId; }
TUniqueId GetNextObjectIndex(TUniqueId prev) const { return x0_list[prev & 0x3ff].next; }
virtual bool IsQualified(const CEntity&);

View File

@ -170,6 +170,7 @@ public:
u32 GetLogScans() const { return x180_logScans; }
u32 GetTotalLogScans() const { return x184_totalLogScans; }
bool IsPlayerAlive() const { return x0_24_alive; }
void SetPlayerAlive(bool alive) { x0_24_alive = alive; }
void InitializeScanTimes();
const rstl::reserved_vector<std::pair<ResId, float>, 846>& GetScanTimes() const { return x170_scanTimes; }
CPlayerState();

View File

@ -37,6 +37,8 @@
#include "World/CScriptEffect.hpp"
#include "MP1/CSamusHud.hpp"
#include "Collision/CGameCollision.hpp"
#include "World/CScriptPlatform.hpp"
#include "World/CScriptRoomAcoustics.hpp"
#include <cmath>
@ -344,21 +346,64 @@ TAreaId CStateManager::GetVisAreaId() const
return curArea;
}
void CStateManager::GetWeaponIdCount(TUniqueId, EWeaponType) {}
s32 CStateManager::GetWeaponIdCount(TUniqueId uid, EWeaponType type)
{
return x878_weaponManager->GetNumActive(uid, type);
}
void CStateManager::RemoveWeaponId(TUniqueId, EWeaponType) {}
void CStateManager::RemoveWeaponId(TUniqueId uid, EWeaponType type)
{
x878_weaponManager->DecrCount(uid, type);
}
void CStateManager::AddWeaponId(TUniqueId, EWeaponType) {}
void CStateManager::AddWeaponId(TUniqueId uid, EWeaponType type)
{
x878_weaponManager->IncrCount(uid, type);
}
void CStateManager::UpdateEscapeSequenceTimer(float) {}
void CStateManager::UpdateEscapeSequenceTimer(float dt)
{
if (xf0c_escapeTimer <= 0.f)
return;
xf0c_escapeTimer = std::max(FLT_EPSILON, xf0c_escapeTimer - dt);
if (xf0c_escapeTimer <= FLT_EPSILON)
x8b8_playerState->SetPlayerAlive(false);
float CStateManager::GetEscapeSequenceTimer() const { return 0.f; }
if (!g_EscapeShakeCountdownInit)
{
g_EscapeShakeCountdown = 0.f;
g_EscapeShakeCountdownInit = true;
}
void CStateManager::ResetEscapeSequenceTimer(float) {}
g_EscapeShakeCountdown -= dt;
if (g_EscapeShakeCountdown < 0.f)
{
float factor = 1.f - xf0c_escapeTimer / xf10_escapeTotalTime;
float factor2 = factor * factor;
CCameraShakeData shakeData(1.f, factor2 * 0.2f * x900_activeRandom->Range(0.5f, 1.f));
x870_cameraManager->AddCameraShaker(shakeData, true);
x88c_rumbleManager->Rumble(*this, ERumbleFxId::Seven, 0.75f, ERumblePriority::One);
g_EscapeShakeCountdown = -12.f * factor2 + 15.f;
}
}
void CStateManager::SetupParticleHook(const CActor& actor) const {}
float CStateManager::GetEscapeSequenceTimer() const { return xf0c_escapeTimer; }
void CStateManager::MurderScriptInstanceNames() {}
void CStateManager::ResetEscapeSequenceTimer(float time)
{
xf0c_escapeTimer = time;
xf10_escapeTotalTime = time;
}
void CStateManager::SetupParticleHook(const CActor& actor) const
{
x884_actorModelParticles->SetupHook(actor.GetUniqueId());
}
void CStateManager::MurderScriptInstanceNames()
{
xb40_uniqueInstanceNames.clear();
}
std::string CStateManager::HashInstanceName(CInputStream& in)
{
@ -371,7 +416,27 @@ std::string CStateManager::HashInstanceName(CInputStream& in)
#endif
}
void CStateManager::SetActorAreaId(CActor& actor, TAreaId) {}
void CStateManager::SetActorAreaId(CActor& actor, TAreaId aid)
{
TAreaId actorAid = actor.GetAreaIdAlways();
if (actorAid == aid)
return;
if (actorAid != kInvalidAreaId)
{
CGameArea* area = x850_world->GetArea(actorAid);
if (area->IsPostConstructed())
area->GetAreaObjects().RemoveObject(actor.GetUniqueId());
}
if (aid == kInvalidAreaId)
return;
CGameArea* area = x850_world->GetArea(aid);
if (!area->IsPostConstructed() || area->GetAreaObjects().GetValidObjectById(actor.GetUniqueId()))
return;
area->GetAreaObjects().AddObject(actor);
}
void CStateManager::TouchSky() const
{
@ -382,12 +447,8 @@ void CStateManager::TouchPlayerActor()
{
if (xf6c_playerActor == kInvalidUniqueId)
return;
#if 0
TCastToPtr<CScriptPlayerActor> spa(ObjectById(xf6c_playerActor));
if (spa)
spa->TouchModels();
#endif
if (CEntity* ent = ObjectById(xf6c_playerActor))
static_cast<CScriptPlayerActor*>(ent)->TouchModels();
}
void CStateManager::DrawSpaceWarp(const zeus::CVector3f& v, float strength) const
@ -400,9 +461,37 @@ void CStateManager::DrawSpaceWarp(const zeus::CVector3f& v, float strength) cons
}
}
void CStateManager::DrawReflection(const zeus::CVector3f&) {}
void CStateManager::DrawReflection(const zeus::CVector3f& reflectPoint)
{
zeus::CAABox aabb = x84c_player->GetBoundingBox();
zeus::CVector3f playerPos = aabb.center();
zeus::CVector3f surfToPlayer = playerPos - reflectPoint;
surfToPlayer.z = 0.f;
zeus::CVector3f viewPos = playerPos - surfToPlayer.normalized() * 3.5f;
zeus::CTransform look = zeus::lookAt(viewPos, playerPos, {0.f, 0.f, -1.f});
void CStateManager::CacheReflection() {}
zeus::CTransform backupView = CGraphics::g_ViewMatrix;
CGraphics::SetViewPointMatrix(look);
CGraphics::CProjectionState backupProj = CGraphics::GetProjectionState();
CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this);
g_Renderer->SetPerspective(cam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height,
cam->GetNearClipDistance(), cam->GetFarClipDistance());
x84c_player->RenderReflectedPlayer(*this);
CGraphics::SetViewPointMatrix(backupView);
CGraphics::SetProjectionState(backupProj);
}
void CStateManager::ReflectionDrawer(void* ctx, const zeus::CVector3f& vec)
{
reinterpret_cast<CStateManager*>(ctx)->DrawReflection(vec);
}
void CStateManager::CacheReflection()
{
g_Renderer->CacheReflection(ReflectionDrawer, this, true);
}
bool CStateManager::CanCreateProjectile(TUniqueId, EWeaponType, int) const { return false; }
@ -472,7 +561,19 @@ zeus::CFrustum CStateManager::SetupViewForDraw(const SViewport& vp) const
void CStateManager::ResetViewAfterDraw(const SViewport& backupViewport,
const zeus::CTransform& backupViewMatrix) const
{
g_Renderer->SetViewport(backupViewport.x0_left, backupViewport.x4_top,
backupViewport.x8_width, backupViewport.xc_height);
const CGameCamera* cam = x870_cameraManager->GetCurrentCamera(*this);
zeus::CFrustum frustum;
frustum.updatePlanes(backupViewMatrix, zeus::SProjPersp(zeus::degToRad(cam->GetFov()),
cam->GetAspectRatio(),
cam->GetNearClipDistance(),
cam->GetFarClipDistance()));
g_Renderer->SetClippingPlanes(frustum);
g_Renderer->SetPerspective(cam->GetFov(), g_Viewport.x8_width, g_Viewport.xc_height,
cam->GetNearClipDistance(), cam->GetFarClipDistance());
}
void CStateManager::DrawWorld() const
@ -1241,7 +1342,7 @@ void CStateManager::Update(float dt)
CGameCollision::Move(*this, *x84c_player, dt, nullptr);
UpdateSortedLists();
if (!_9f4_gt0)
CrossTouchActors(dt);
CrossTouchActors();
}
else
{
@ -1306,7 +1407,7 @@ void CStateManager::Update(float dt)
g_GameState->CurrentWorldState().SetAreaId(x8cc_nextAreaId);
x850_world->TravelToArea(x8cc_nextAreaId, *this, false);
BringOutYourDead();
ClearGraveyard();
++x8d8_updateFrameIdx;
}
@ -1374,37 +1475,157 @@ void CStateManager::PreThinkEffects(float dt)
void CStateManager::MovePlatforms(float dt)
{
for (CEntity* ent : GetPlatformAndDoorObjectList())
{
if (!ent || !GetPlatformAndDoorObjectList().IsPlatform(*ent))
continue;
CScriptPlatform& plat = static_cast<CScriptPlatform&>(*ent);
if (!plat.GetActive() || plat.GetMass() == 0.f)
continue;
CGameCollision::Move(*this, plat, dt, nullptr);
}
}
void CStateManager::MoveDoors(float dt)
{
for (CEntity* ent : GetPhysicsActorObjectList())
{
if (!ent || !ent->GetActive())
continue;
CPhysicsActor& physActor = static_cast<CPhysicsActor&>(*ent);
if (physActor.GetMass() == 0.f)
continue;
if (TCastToPtr<CAi> ai = physActor)
{
bool doThink = !xf94_29_;
if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId)
{
const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways());
float f1;
if (area->IsPostConstructed())
f1 = area->GetPostConstructed()->x10e4_;
else
f1 = 0.f;
if (f1 > 5.f)
doThink = false;
}
if (!doThink)
SendScriptMsgAlways(ai->GetUniqueId(), kInvalidUniqueId,
EScriptObjectMessage::InternalMessage26);
else if (x84c_player.get() != ent)
if (!GetPlatformAndDoorObjectList().IsPlatform(*ent))
CGameCollision::Move(*this, physActor, dt, nullptr);
}
}
}
void CStateManager::CrossTouchActors(float dt)
void CStateManager::CrossTouchActors()
{
bool visits[1024] = {};
for (CEntity* ent : GetActorObjectList())
{
if (!ent)
continue;
CActor& actor = static_cast<CActor&>(*ent);
if (!actor.GetActive() || !actor.GetCallTouch())
continue;
rstl::optional_object<zeus::CAABox> touchAABB = actor.GetTouchBounds();
if (!touchAABB)
continue;
CMaterialFilter filter = CMaterialFilter::skPassEverything;
if (actor.GetMaterialList().HasMaterial(EMaterialTypes::Trigger))
filter = CMaterialFilter::MakeExclude(EMaterialTypes::Trigger);
rstl::reserved_vector<TUniqueId, 1024> nearList;
BuildNearList(nearList, *touchAABB, filter, &actor);
for (TUniqueId id : nearList)
{
CActor* ent2 = static_cast<CActor*>(ObjectById(id));
if (!ent2)
continue;
rstl::optional_object<zeus::CAABox> touchAABB2 = ent2->GetTouchBounds();
if (!ent2->GetActive() || touchAABB2)
continue;
if (visits[ent2->GetUniqueId() & 0x3ff])
continue;
if (touchAABB->intersects(*touchAABB2))
{
actor.Touch(*ent2, *this);
ent2->Touch(actor, *this);
}
visits[ent2->GetUniqueId() & 0x3ff] = true;
}
}
}
void CStateManager::ThinkEffectsAndActors(float dt)
{
if (x84c_player->x9f4_ > 0.f)
{
x84c_player->DoThink(dt, *this);
return;
}
if (x904_ == 1)
{
for (CEntity* ent : GetAllObjectList())
if (TCastToPtr<CScriptEffect> effect = ent)
effect->Think(dt, *this);
}
else
{
for (CEntity* ent : GetAllObjectList())
if (TCastToPtr<CAi> ai = ent)
{
bool doThink = !xf94_29_;
if (doThink && ai->GetAreaIdAlways() != kInvalidAreaId)
{
const CGameArea* area = x850_world->GetAreaAlways(ai->GetAreaIdAlways());
float f1;
if (area->IsPostConstructed())
f1 = area->GetPostConstructed()->x10e4_;
else
f1 = 0.f;
if (f1 > 5.f)
doThink = false;
}
if (doThink)
{
CEntity* ent2 = GetAllObjectList().GetObjectById(ai->GetUniqueId());
ent2->Think(dt, *this);
}
}
}
}
void CStateManager::UpdatePlayer(float dt)
{
x84c_player->Update(dt, *this);
}
void CStateManager::ShowPausedHUDMemo(ResId strg, float time)
{
xf78_hudMessageTime = time;
xf08_pauseHudMessage = strg;
DeferStateTransition(EStateManagerTransition::MessageScreen);
}
void CStateManager::BringOutYourDead()
void CStateManager::ClearGraveyard()
{
for (TUniqueId id : x854_objectGraveyard)
{
CEntity* ent = GetAllObjectList().GetValidObjectById(id);
RemoveObject(id);
if (ent)
std::default_delete<CEntity>()(ent);
}
x854_objectGraveyard.clear();
}
void CStateManager::FrameBegin(s32 frameCount)
@ -1528,11 +1749,52 @@ const CObjectList* CStateManager::GetObjectListById(EGameObjectList type) const
return x808_objLists[int(type)].get();
}
void CStateManager::RemoveObject(TUniqueId) {}
void CStateManager::RemoveObject(TUniqueId uid)
{
if (CEntity* ent = GetAllObjectList().GetValidObjectById(uid))
{
if (ent->GetEditorId() != kInvalidEditorId)
{
x890_scriptIdMap.erase(ent->GetEditorId());
}
if (ent->GetAreaIdAlways() != kInvalidAreaId)
{
CGameArea* area = x850_world->GetArea(ent->GetAreaIdAlways());
if (area->IsPostConstructed())
area->GetAreaObjects().RemoveObject(uid);
}
if (TCastToPtr<CActor> act = ent)
x874_sortedListManager->Remove(act.GetPtr());
}
for (auto& list : x808_objLists)
list->RemoveObject(uid);
}
void CStateManager::RemoveActor(TUniqueId) {}
void CStateManager::UpdateRoomAcoustics(TAreaId aid)
{
u32 updateCount = 0;
CScriptRoomAcoustics* updates[10];
for (CEntity* ent : GetAllObjectList())
{
if (TCastToPtr<CScriptRoomAcoustics> acoustics = ent)
{
if (acoustics->GetAreaIdAlways() != aid || !acoustics->GetActive())
continue;
updates[updateCount++] = acoustics.GetPtr();
}
if (updateCount >= 10)
break;
}
void CStateManager::UpdateRoomAcoustics(TAreaId) {}
if (!updateCount)
{
CScriptRoomAcoustics::DisableAuxCallbacks();
return;
}
int idx = updateCount * x900_activeRandom->Float() * 0.99f;
updates[idx]->EnableAuxCallbacks();
}
void CStateManager::SetCurrentAreaId(TAreaId aid)
{
@ -1551,8 +1813,6 @@ void CStateManager::SetCurrentAreaId(TAreaId aid)
x850_world->GetMapWorld()->RecalculateWorldSphere(*x8c0_mapWorldInfo, *x850_world);
}
void CStateManager::ClearGraveyard() {}
void CStateManager::DeleteObjectRequest(TUniqueId id)
{
CEntity* entity = ObjectById(id);
@ -1584,19 +1844,23 @@ void CStateManager::PrepareAreaUnload(TAreaId) {}
void CStateManager::AreaLoaded(TAreaId) {}
void CStateManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& listOut, const zeus::CVector3f&,
const zeus::CVector3f&, float, const CMaterialFilter&, const CActor*) const
void CStateManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& listOut, const zeus::CVector3f& v1,
const zeus::CVector3f& v2, float f1, const CMaterialFilter& filter,
const CActor* actor) const
{
x874_sortedListManager->BuildNearList(listOut, v1, v2, f1, filter, actor);
}
void CStateManager::BuildColliderList(rstl::reserved_vector<TUniqueId, 1024>& listOut, const CActor&,
const zeus::CAABox&) const
void CStateManager::BuildColliderList(rstl::reserved_vector<TUniqueId, 1024>& listOut, const CActor& actor,
const zeus::CAABox& aabb) const
{
x874_sortedListManager->BuildNearList(listOut, actor, aabb);
}
void CStateManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& listOut, const zeus::CAABox&,
const CMaterialFilter&, const CActor*) const
void CStateManager::BuildNearList(rstl::reserved_vector<TUniqueId, 1024>& listOut, const zeus::CAABox& aabb,
const CMaterialFilter& filter, const CActor* actor) const
{
x874_sortedListManager->BuildNearList(listOut, aabb, filter, actor);
}
void CStateManager::UpdateActorInSortedLists(CActor& act)
@ -1781,4 +2045,7 @@ bool CStateManager::ApplyDamage(TUniqueId, TUniqueId, TUniqueId, const CDamageIn
{
return false;
}
float CStateManager::g_EscapeShakeCountdown;
bool CStateManager::g_EscapeShakeCountdownInit = false;
}

View File

@ -158,8 +158,6 @@ class CStateManager
bool xab0_worldLoaded = false;
std::set<std::string> xab4_uniqueInstanceNames;
enum class EInitPhase
{
LoadWorld,
@ -167,6 +165,8 @@ class CStateManager
Done
} xb3c_initPhase = EInitPhase::LoadWorld;
std::set<std::string> xb40_uniqueInstanceNames;
CFinalInput xb54_finalInput;
CCameraFilterPass xb84_camFilterPasses[9];
CCameraBlurPass xd14_camBlurPasses[9];
@ -199,8 +199,8 @@ class CStateManager
SOnScreenTex xef4_pendingScreenTex;
ResId xf08_pauseHudMessage = -1;
float xf0c_ = 0.f;
float xf10_ = 0.f;
float xf0c_escapeTimer = 0.f;
float xf10_escapeTotalTime = 0.f;
float xf14_curTimeMod900 = 0.f;
TUniqueId xf18_ = kInvalidUniqueId;
float xf1c_ = 0.f;
@ -260,7 +260,7 @@ public:
void AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const;
bool SpecialSkipCinematic();
TAreaId GetVisAreaId() const;
void GetWeaponIdCount(TUniqueId, EWeaponType);
s32 GetWeaponIdCount(TUniqueId, EWeaponType);
void RemoveWeaponId(TUniqueId, EWeaponType);
void AddWeaponId(TUniqueId, EWeaponType);
void UpdateEscapeSequenceTimer(float);
@ -274,6 +274,7 @@ public:
void TouchPlayerActor();
void DrawSpaceWarp(const zeus::CVector3f&, float) const;
void DrawReflection(const zeus::CVector3f&);
static void ReflectionDrawer(void*, const zeus::CVector3f&);
void CacheReflection();
bool CanCreateProjectile(TUniqueId, EWeaponType, int) const;
const CGameLightList* GetDynamicLightList() const;
@ -333,11 +334,11 @@ public:
void PreThinkEffects(float dt);
void MovePlatforms(float dt);
void MoveDoors(float dt);
void CrossTouchActors(float dt);
void CrossTouchActors();
void ThinkEffectsAndActors(float dt);
void UpdatePlayer(float dt);
void ShowPausedHUDMemo(ResId strg, float time);
void BringOutYourDead();
void ClearGraveyard();
void FrameBegin(s32 frameCount);
void InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId);
void CreateStandardGameObjects();
@ -345,11 +346,9 @@ public:
CObjectList* ObjectListById(EGameObjectList type);
const CObjectList* GetObjectListById(EGameObjectList type) const;
void RemoveObject(TUniqueId);
void RemoveActor(TUniqueId);
void UpdateRoomAcoustics(TAreaId);
TAreaId GetNextAreaId() const { return x8cc_nextAreaId; }
void SetCurrentAreaId(TAreaId);
void ClearGraveyard();
void DeleteObjectRequest(TUniqueId);
CEntity* ObjectById(TUniqueId uid);
const CEntity* GetObjectById(TUniqueId uid) const;
@ -425,6 +424,9 @@ public:
void SetIsGeneratingObject(bool gen) { xf94_26_generatingObject = gen; }
u32 GetParticleFlags() const { return xf34_particleFlags; }
const CFinalInput& GetFinalInput() const { return xb54_finalInput; }
static float g_EscapeShakeCountdown;
static bool g_EscapeShakeCountdownInit;
};
}

View File

@ -94,7 +94,7 @@ void CCameraManager::SetInsideFluid(bool val, TUniqueId fluidId)
void CCameraManager::Update(float dt, CStateManager& stateMgr)
{
sub800097AC(dt, stateMgr);
UpdateCameraHints(dt, stateMgr);
ThinkCameras(dt, stateMgr);
UpdateListener(stateMgr);
UpdateRumble(dt, stateMgr);
@ -212,7 +212,7 @@ float CCameraManager::sub80009148() const
std::cos(zeus::degToRad(30.f))), 1.f);
}
void CCameraManager::sub800097AC(float, CStateManager& mgr)
void CCameraManager::UpdateCameraHints(float, CStateManager& mgr)
{
}

View File

@ -113,7 +113,7 @@ public:
float sub80009148() const;
void sub800097AC(float, CStateManager&);
void UpdateCameraHints(float, CStateManager&);
void ThinkCameras(float, CStateManager&);
void UpdateFog(float, CStateManager&);
void UpdateRumble(float, CStateManager&);

View File

@ -29,6 +29,13 @@ CCameraShakeData::CCameraShakeData(float f1, float f2, u32 w1, const zeus::CVect
: x0_duration(f1), x8_shaker1(shaker1), x44_shaker2(shaker2), x80_shaker3(shaker3), xc0_flags(w1), xc4_sfxPos(v1), xd0_f2(f2)
{}
CCameraShakeData::CCameraShakeData(float f1, float f2)
: CCameraShakeData(f1, 100.f, 0, zeus::CVector3f::skZero, CCameraShakerComponent{}, CCameraShakerComponent{},
CCameraShakerComponent{1,
SCameraShakePoint{0, 0.25f * f1, 0.f, 0.75f * f1, f2},
SCameraShakePoint{1, 0.f, 0.f, 0.5f * f1, 2.f}})
{}
float CCameraShakeData::GetSomething() const
{
float ret = 0.f;

View File

@ -54,6 +54,7 @@ public:
CCameraShakeData(float duration, float f2, u32 w1, const zeus::CVector3f& v1,
const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2,
const CCameraShakerComponent& shaker3);
CCameraShakeData(float f1, float f2);
//zeus::CVector3f GeneratePoint(float dt, CRandom16& r);
float GetSomething() const;
float GetSomething2() const;

View File

@ -45,7 +45,7 @@ void CGameCollision::InitCollision()
CCollisionPrimitive::InitEndColliders();
}
void CGameCollision::Move(CStateManager& mgr, CPlayer& player, float dt, const rstl::reserved_vector<TUniqueId, 1024>*)
void CGameCollision::Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const rstl::reserved_vector<TUniqueId, 1024>*)
{
}

View File

@ -16,7 +16,7 @@ class CCollisionInfo;
class CCollisionInfoList;
class CMaterialList;
class CStateManager;
class CPlayer;
class CPhysicsActor;
class CGameCollision
{
@ -28,7 +28,7 @@ public:
static bool NullBooleanCollider(const CInternalCollisionStructure&) { return false; }
static bool NullCollisionCollider(const CInternalCollisionStructure&, CCollisionInfoList&) { return false; }
static void InitCollision();
static void Move(CStateManager& mgr, CPlayer& player, float dt, const rstl::reserved_vector<TUniqueId, 1024>*);
static void Move(CStateManager& mgr, CPhysicsActor& actor, float dt, const rstl::reserved_vector<TUniqueId, 1024>*);
static bool CanBlock(const CMaterialList&, const zeus::CVector3f&);
static bool IsFloor(const CMaterialList&, const zeus::CVector3f&);

View File

@ -978,6 +978,14 @@ void CBooRenderer::BeginScene()
void CBooRenderer::EndScene()
{
CGraphics::EndScene();
if (x2dc_reflectionAge >= 2)
{
// Delete reflection tex x14c_
}
else
{
++x2dc_reflectionAge;
}
}
void CBooRenderer::SetAmbientColor(const zeus::CColor& color)
@ -994,6 +1002,24 @@ u32 CBooRenderer::GetFPS()
return 0;
}
void CBooRenderer::CacheReflection(TReflectionCallback cb, void* ctx, bool clearAfter)
{
if (!x318_24_refectionDirty)
return;
x318_24_refectionDirty = false;
x2dc_reflectionAge = 0;
BindReflectionDrawTarget();
SViewport backupVp = g_Viewport;
SetViewport(0, 0, 256, 256);
CGraphics::g_BooMainCommandQueue->clearTarget();
cb(ctx, CBooModel::g_ReflectViewPos);
boo::SWindowRect rect(0, 0, 256, 256);
CGraphics::g_BooMainCommandQueue->resolveBindTexture(x14c_reflectionTex, rect, false, 0, true, false);
BindMainDrawTarget();
SetViewport(backupVp.x0_left, backupVp.x4_top, backupVp.x8_width, backupVp.xc_height);
}
void CBooRenderer::DrawSpaceWarp(const zeus::CVector3f& pt, float strength)
{
m_spaceWarpFilter.setStrength(strength);

View File

@ -134,6 +134,7 @@ class CBooRenderer : public IRenderer
std::list<CFogVolumeFilter> m_fogVolumeFilters;
std::list<CFogVolumeFilter>::iterator m_nextFogVolumeFilter;
std::list<std::pair<zeus::CVector3f, float>> x2c4_spaceWarps;
u32 x2dc_reflectionAge = 2;
zeus::CColor x2e0_ = zeus::CColor::skWhite;
zeus::CVector3f x2e4_ = {0.f, 1.f, 0.f};
@ -231,7 +232,7 @@ public:
void SetAmbientColor(const zeus::CColor&);
void DrawString(const char*, int, int);
u32 GetFPS();
//void CacheReflection(TReflectionCallback, void*, bool);
void CacheReflection(TReflectionCallback, void*, bool);
void DrawSpaceWarp(const zeus::CVector3f&, float);
void DrawThermalModel(const CModel& model, const zeus::CColor& multCol, const zeus::CColor& addCol);
void DrawXRayOutline(const zeus::CAABox&);

View File

@ -178,8 +178,11 @@ public:
static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;}
static void SetNewPlayerPositionAndTime(const zeus::CVector3f& pos);
static void KillCachedViewDepState();
static zeus::CVector3f g_ReflectViewPos;
static void KillCachedViewDepState();
static void EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf,
zeus::CMatrix4f*& mtxsOut, float& alphaOut);
};
class CModel

View File

@ -46,6 +46,83 @@ void CBooModel::KillCachedViewDepState()
g_LastModelCached = nullptr;
}
zeus::CVector3f CBooModel::g_ReflectViewPos = {};
static const zeus::CMatrix4f ReflectBaseMtx =
{
0.f, 0.f, 0.f, 0.f,
0.f, 0.f, 0.f, 0.f,
0.f, 0.f, 0.f, 1.f,
0.f, 0.f, 0.f, 1.f
};
void CBooModel::EnsureViewDepStateCached(const CBooModel& model, const CBooSurface* surf,
zeus::CMatrix4f*& mtxsOut, float& alphaOut)
{
zeus::CVector3f modelToPlayer = g_PlayerPosition - CGraphics::g_GXModelMatrix.origin;
zeus::CVector3f modelToPlayerLocal = CGraphics::g_GXModelMatrix.transposeRotate(modelToPlayer);
zeus::CVector3f surfPos;
float surfSize = 0.f;
if (surf)
{
zeus::CVector3f surfCenter(surf->m_data.centroid);
zeus::CVector3f surfNormal(surf->m_data.reflectionNormal);
float dotDelta = surfNormal.dot(modelToPlayerLocal) - surfCenter.dot(surfNormal);
surfPos = modelToPlayerLocal - surfNormal * dotDelta;
}
else
{
surfPos = model.x20_aabb.center();
surfSize = (model.x20_aabb.max.x - model.x20_aabb.min.x) + (model.x20_aabb.max.y - model.x20_aabb.min.y) * 0.5f;
}
if (g_Renderer->x318_24_refectionDirty)
{
zeus::CVector3f playerToPos = g_ReflectViewPos - g_PlayerPosition;
zeus::CVector3f vecToPos = surfPos - g_PlayerPosition;
if (playerToPos.dot(playerToPos) < vecToPos.dot(vecToPos))
g_ReflectViewPos = surfPos;
}
else
{
g_ReflectViewPos = surfPos;
g_Renderer->x318_24_refectionDirty = true;
}
zeus::CVector3f playerToSurf = surfPos - modelToPlayerLocal;
float distance = std::max(-(0.5f * surfSize - playerToSurf.magnitude()), FLT_EPSILON);
if (distance >= 5.f)
{
alphaOut = 0.f;
}
else
{
alphaOut = (5.f - distance) / 5.f;
/* Indirect map matrix */
mtxsOut[0] = (CGraphics::g_ViewMatrix.inverse() * CGraphics::g_GXModelMatrix).toMatrix4f();
/* Reflection map matrix */
zeus::CVector3f v1 = playerToSurf * (1.f / surfSize);
zeus::CVector3f v2 = v1.cross(zeus::CVector3f::skUp);
if (v2.canBeNormalized())
v2.normalize();
else
v2 = zeus::CVector3f::skRight;
float timeScale = 0.32258067f * (0.02f * distance + 1.f);
float f1 = timeScale * g_TransformedTime;
float f2 = timeScale * g_TransformedTime2;
mtxsOut[1] = ReflectBaseMtx;
mtxsOut[1][0][0] = f1 * v2.x;
mtxsOut[1][1][0] = f1 * v2.y;
mtxsOut[1][3][0] = -surfPos.dot(v2) * f1 + 0.5f;
mtxsOut[1][2][1] = f2;
mtxsOut[1][3][1] = -modelToPlayerLocal.z * f2;
}
}
CBooModel::~CBooModel()
{
if (m_prev)
@ -162,11 +239,24 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
uniBufSize += thisSz;
}
/* Surface reflection texmatrix uniform with first identity slot */
size_t reflectOff = uniBufSize;
uniBufSize += 256;
for (const CBooSurface& surf : *x0_surfaces)
{
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye())
uniBufSize += 256;
}
/* Allocate resident buffer */
m_uniformDataSize = uniBufSize;
newInst.m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1);
boo::IGraphicsBuffer* bufs[] = {newInst.m_uniformBuffer, newInst.m_uniformBuffer, newInst.m_uniformBuffer};
boo::IGraphicsBuffer* bufs[] = {newInst.m_uniformBuffer,
newInst.m_uniformBuffer,
newInst.m_uniformBuffer,
newInst.m_uniformBuffer};
/* Binding for each surface */
newInst.m_shaderDataBindings.reserve(x0_surfaces->size());
@ -175,14 +265,16 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
boo::ITexture* mbShadowTexs[] = {g_Renderer->m_ballShadowId,
g_Renderer->x220_sphereRamp,
g_Renderer->m_ballFade};
size_t thisOffs[3];
size_t thisSizes[3];
size_t thisOffs[4];
size_t thisSizes[4];
static const boo::PipelineStage stages[3] = {boo::PipelineStage::Vertex,
static const boo::PipelineStage stages[4] = {boo::PipelineStage::Vertex,
boo::PipelineStage::Vertex,
boo::PipelineStage::Fragment};
boo::PipelineStage::Fragment,
boo::PipelineStage::Vertex};
/* Enumerate surfaces and build data bindings */
size_t curReflect = reflectOff + 256;
for (const CBooSurface& surf : *x0_surfaces)
{
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
@ -193,6 +285,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
TCachedToken<CTexture>& tex = x1c_textures[idx];
texs[texCount++] = tex.GetObj()->GetBooTexture();
}
texs[6] = g_Renderer->x14c_reflectionTex;
texs[7] = g_Renderer->x220_sphereRamp;
if (m_skinBankCount)
@ -212,6 +305,18 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
thisOffs[2] = lightOff;
thisSizes[2] = lightSz;
bool useReflection = mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye();
if (useReflection)
{
thisOffs[3] = curReflect;
curReflect += 256;
}
else
{
thisOffs[3] = reflectOff;
}
thisSizes[3] = 256;
const std::shared_ptr<hecl::Runtime::ShaderPipelines>& pipelines = m_pipelines->at(surf.m_data.matIdx);
newInst.m_shaderDataBindings.emplace_back();
@ -233,6 +338,11 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
texCount = 3;
ltexs = mbShadowTexs;
}
else if (useReflection)
{
texCount = 7;
ltexs = texs;
}
else
{
texCount = mat.textureIdxs.size();
@ -240,7 +350,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
}
extendeds.push_back(
ctx.newShaderDataBinding(pipeline, m_vtxFmt,
x8_vbo, nullptr, xc_ibo, 3, bufs, stages,
x8_vbo, nullptr, xc_ibo, 4, bufs, stages,
thisOffs, thisSizes, texCount, ltexs, nullptr, nullptr));
++idx;
}
@ -704,6 +814,26 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
lightingOut.fog = CGraphics::g_Fog;
}
dataCur += sizeof(CModelShaders::LightingUniform);
dataCur = dataOut + ROUND_UP_256(dataCur - dataOut);
/* Reflection texmtx uniform */
zeus::CMatrix4f* identMtxs = reinterpret_cast<zeus::CMatrix4f*>(dataCur);
identMtxs[0] = zeus::CMatrix4f();
identMtxs[1] = zeus::CMatrix4f();
u8* curReflect = dataCur + 256;
for (const CBooSurface& surf : *x0_surfaces)
{
const MaterialSet::Material& mat = x4_matSet->materials.at(surf.m_data.matIdx);
if (mat.flags.samusReflection() || mat.flags.samusReflectionSurfaceEye())
{
zeus::CMatrix4f* mtxs = reinterpret_cast<zeus::CMatrix4f*>(curReflect);
float& alpha = reinterpret_cast<float&>(mtxs[2]);
curReflect += 256;
EnsureViewDepStateCached(*this, mat.flags.samusReflectionSurfaceEye() ? &surf : nullptr, mtxs, alpha);
}
}
inst->m_uniformBuffer->unmap();
}
@ -807,10 +937,17 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
matSet.m_shaders.reserve(matSet.m_matSet.materials.size());
for (const MaterialSet::Material& mat : matSet.m_matSet.materials)
{
hecl::Backend::ReflectionType reflectionType;
if (mat.flags.samusReflectionIndirectTexture())
reflectionType = hecl::Backend::ReflectionType::Indirect;
else if (mat.flags.samusReflection())
reflectionType = hecl::Backend::ReflectionType::Simple;
else
reflectionType = hecl::Backend::ReflectionType::None;
hecl::Runtime::ShaderTag tag(mat.heclIr,
hmdlMeta.colorCount, hmdlMeta.uvCount, hmdlMeta.weightCount,
hmdlMeta.weightCount * 4, 8, boo::Primitive(hmdlMeta.topology),
true, true, true);
reflectionType, true, true, true);
matSet.m_shaders.push_back(CModelShaders::g_ModelShaders->buildExtendedShader
(tag, mat.heclIr, "CMDL", *CGraphics::g_BooFactory));
}

View File

@ -51,4 +51,7 @@ CMorphableSkinnedModel::CMorphableSkinnedModel(IObjectStore& store, ResId model,
{
}
CSkinnedModel::FPointGenerator CSkinnedModel::g_PointGenFunc = nullptr;
void* CSkinnedModel::g_PointGenCtx = nullptr;
}

View File

@ -44,6 +44,15 @@ public:
const std::experimental::optional<CVertexMorphEffect>& morphEffect,
const float* morphMagnitudes);
void Draw(const CModelFlags& drawFlags) const;
typedef void(*FPointGenerator)(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1);
static void SetPointGeneratorFunc(void* ctx, FPointGenerator func)
{
g_PointGenFunc = func;
g_PointGenCtx = ctx;
}
static FPointGenerator g_PointGenFunc;
static void* g_PointGenCtx;
};
class CMorphableSkinnedModel : public CSkinnedModel

View File

@ -88,7 +88,7 @@ public:
virtual void SetAmbientColor(const zeus::CColor&)=0;
virtual void DrawString(const char*, int, int)=0;
virtual u32 GetFPS()=0;
//virtual void CacheReflection(TReflectionCallback, void*, bool)=0;
virtual void CacheReflection(TReflectionCallback, void*, bool)=0;
virtual void DrawSpaceWarp(const zeus::CVector3f&, float)=0;
virtual void DrawThermalModel(const CModel&, const zeus::CColor&, const zeus::CColor&)=0;
virtual void DrawXRayOutline(const zeus::CAABox&)=0;

View File

@ -13,8 +13,8 @@ public:
CRumbleManager() = default;
void Update(float);
void StopRumble(u16) {}
void Rumble(ERumbleFxId, CStateManager&, ERumblePriority priority) {}
void Rumble(ERumbleFxId, float, CStateManager&, ERumblePriority priority) {}
void Rumble(CStateManager&, ERumbleFxId, ERumblePriority priority) {}
void Rumble(CStateManager&, ERumbleFxId, float, ERumblePriority priority) {}
};
}

View File

@ -7,7 +7,8 @@ namespace urde
{
enum class ERumbleFxId
{
Seven = 7
Seven = 7,
Eleven = 11
};
enum class ERumblePriority
{

View File

@ -2,4 +2,35 @@
namespace urde
{
void CWeaponMgr::Add(TUniqueId, EWeaponType)
{
}
void CWeaponMgr::Remove(TUniqueId)
{
}
void CWeaponMgr::IncrCount(TUniqueId, EWeaponType)
{
}
void CWeaponMgr::DecrCount(TUniqueId, EWeaponType)
{
}
s32 CWeaponMgr::GetNumActive(TUniqueId, EWeaponType) const
{
return 0;
}
s32 CWeaponMgr::GetIndex(TUniqueId) const
{
return 0;
}
}

View File

@ -9,6 +9,7 @@
#include "Particle/CGenDescription.hpp"
#include "World/CWorld.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "Graphics/CSkinnedModel.hpp"
namespace urde
{
@ -19,6 +20,11 @@ CActorModelParticles::CItem::CItem(const CEntity& ent, CActorModelParticles& par
x8_.resize(8);
}
void CActorModelParticles::CItem::GeneratePoints(const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1)
{
}
static const char* ParticleDGRPs[] =
{
"Effect_OnFire_DGRP",
@ -157,4 +163,25 @@ void CActorModelParticles::Update(float dt, CStateManager& mgr)
}
void CActorModelParticles::PointGenerator(void* item, const zeus::CVector3f* v1,
const zeus::CVector3f* v2, int w1)
{
reinterpret_cast<CItem*>(item)->GeneratePoints(v1, v2, w1);
}
void CActorModelParticles::SetupHook(TUniqueId uid)
{
auto search = FindSystem(uid);
if (search != x0_items.cend())
CSkinnedModel::SetPointGeneratorFunc((void*)&*search, PointGenerator);
}
std::list<CActorModelParticles::CItem>::const_iterator CActorModelParticles::FindSystem(TUniqueId uid) const
{
for (auto it = x0_items.cbegin() ; it != x0_items.cend() ; ++it)
if (it->x0_id == uid)
return it;
return x0_items.cend();
}
}

View File

@ -18,6 +18,7 @@ class CParticleElectric;
class CActorModelParticles
{
public:
class CItem
{
friend class CActorModelParticles;
@ -60,8 +61,10 @@ class CActorModelParticles
u8 x134_bits = 0;
public:
CItem(const CEntity& ent, CActorModelParticles& parent);
void GeneratePoints(const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1);
};
private:
std::list<CItem> x0_items;
TToken<CGenDescription> x18_onFire;
TToken<CGenDescription> x20_ash;
@ -84,8 +87,11 @@ class CActorModelParticles
public:
CActorModelParticles();
static void PointGenerator(void* item, const zeus::CVector3f* v1, const zeus::CVector3f* v2, int w1);
void AddStragglersToRenderer(const CStateManager& mgr);
void Update(float dt, CStateManager& mgr);
void SetupHook(TUniqueId uid);
std::list<CItem>::const_iterator FindSystem(TUniqueId uid) const;
};
}

View File

@ -1050,7 +1050,7 @@ void CGameArea::SetAreaAttributes(const CScriptAreaAttributes* areaAttributes)
bool CGameArea::CAreaObjectList::IsQualified(const CEntity& ent)
{
return (ent.GetAreaId() == x200c_areaIdx);
return (ent.GetAreaIdAlways() == x200c_areaIdx);
}
}

View File

@ -29,7 +29,7 @@ void CGameLight::Think(float dt, CStateManager& mgr)
x144_lifeTime -= dt;
if (x144_lifeTime <= 0.f)
mgr.RemoveActor(GetUniqueId());
mgr.FreeScriptObject(GetUniqueId());
}
void CGameLight::SetLightPriorityAndId()

View File

@ -121,6 +121,7 @@ public:
virtual float GetStepDownHeight() const;
virtual float GetWeight() const;
float GetMass() const { return xe8_mass; }
void sub_8011A4C(float f);
float sub_8011A4B8() const;
void SetPrimitiveOffset(const zeus::CVector2f& offset);

View File

@ -104,6 +104,13 @@ void CPlayer::DoPreThink(float dt, CStateManager& mgr)
ent->PreThink(dt, mgr);
}
void CPlayer::DoThink(float dt, CStateManager& mgr)
{
Think(dt, mgr);
if (CEntity* ent = mgr.ObjectById(xa00_))
ent->Think(dt, mgr);
}
void CPlayer::UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float) {}
void CPlayer::ValidateScanning(const CFinalInput& input, CStateManager& mgr) {}

View File

@ -319,6 +319,7 @@ public:
rstl::optional_object<zeus::CAABox> GetTouchBounds() const;
void Touch(CActor&, CStateManager& mgr);
void DoPreThink(float dt, CStateManager& mgr);
void DoThink(float dt, CStateManager& mgr);
void UpdateScanningState(const CFinalInput& input, CStateManager& mgr, float);
void ValidateScanning(const CFinalInput& input, CStateManager& mgr);
void SetScanningState(EPlayerScanState, CStateManager& mgr);

View File

@ -54,5 +54,10 @@ void CScriptPlayerActor::AddToRenderer(const zeus::CFrustum&, const CStateManage
void CScriptPlayerActor::Render(const CStateManager& mgr) const
{
}
void CScriptPlayerActor::TouchModels()
{
}
}

View File

@ -50,6 +50,7 @@ public:
void PreRender(CStateManager &, const zeus::CFrustum &);
void AddToRenderer(const zeus::CFrustum &, const CStateManager &) const;
void Render(const CStateManager &mgr) const;
void TouchModels();
};
}

View File

@ -25,8 +25,6 @@ class CScriptRoomAcoustics : public CEntity
bool x7c_delay;
amuse::EffectDelayInfo x80_delayInfo;
void EnableAuxCallbacks();
public:
CScriptRoomAcoustics(TUniqueId uid, const std::string& name,
const CEntityInfo& info, bool active, u32 volScale,
@ -41,6 +39,7 @@ public:
void Think(float dt, CStateManager& stateMgr);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr);
void Accept(IVisitor& visitor);
void EnableAuxCallbacks();
static void DisableAuxCallbacks();
};

View File

@ -219,7 +219,8 @@ enum class EScriptObjectMessage
InternalMessage17 = 39,
InternalMessage18 = 40,
InternalMessage19 = 41,
InternalMessage20 = 42
InternalMessage20 = 42,
InternalMessage26 = 48
};
}

2
hecl

@ -1 +1 @@
Subproject commit c3db26f4a195a6db5f28dd160ea9849a707745c3
Subproject commit e88c5a6891c2b68d8933df863022d3f5f3074bc2