Bug fixes and CGuiFrame mouse events

This commit is contained in:
Jack Andersen 2019-01-19 20:43:11 -10:00
parent 851e113dc0
commit 47c6b5cba8
21 changed files with 118 additions and 46 deletions

View File

@ -268,9 +268,10 @@ CCharAnimTime CAnimData::GetTimeOfUserEvent(EUserEventType type, const CCharAnim
for (int i = 0; i < count; ++i) {
CInt32POINode& poi = g_TransientInt32POINodes[i];
if (poi.GetPoiType() == EPOIType::UserEvent && EUserEventType(poi.GetValue()) == type) {
CCharAnimTime ret = poi.GetTime();
for (; i < count; ++i)
g_TransientInt32POINodes[i] = CInt32POINode();
return poi.GetTime();
return ret;
} else {
poi = CInt32POINode();
}

View File

@ -74,9 +74,9 @@ void CBSAttack::UpdatePhysicsActor(CBodyController& bc, float dt) {
if (x34_curTime >= x2c_alignTargetPosStartTime && x34_curTime <= x30_alignTargetPosTime) {
if (TCastToPtr<CPhysicsActor> act = bc.GetOwner()) {
zeus::CVector3f delta = x20_targetPos - act->GetTranslation();
float td = x30_alignTargetPosTime - x2c_alignTargetPosStartTime;
if (dt > 0.f)
delta *= zeus::CVector3f(dt / td);
float dur = x30_alignTargetPosTime - x2c_alignTargetPosStartTime;
if (dur > 0.f)
delta *= zeus::CVector3f(dt / dur);
zeus::CVector3f localDelta = act->GetTransform().transposeRotate(delta);
act->ApplyImpulseWR(act->GetMoveToORImpulseWR(localDelta, dt), zeus::CAxisAngle::sIdentity);
}

View File

@ -30,7 +30,7 @@ bool CCharAnimTime::operator==(const CCharAnimTime& other) const {
if (x4_type == EType::NonZero) {
if (other.x4_type == EType::NonZero)
return x0_time == other.x0_time;
return !other.EqualsZero();
return false;
}
if (EqualsZero()) {

View File

@ -9,6 +9,7 @@
#include "zeus/CColor.hpp"
#include "CSimplePool.hpp"
#include "Graphics/CModel.hpp"
#include "CGuiWidgetDrawParms.hpp"
namespace urde {
@ -140,6 +141,16 @@ void CGuiFrame::Draw(const CGuiWidgetDrawParms& parms) const {
CGraphics::SetCullMode(ERglCullMode::Front);
}
CGuiWidget* CGuiFrame::BestCursorHit(const zeus::CVector2f& point, const CGuiWidgetDrawParms& parms) const {
x14_camera->Draw(parms);
zeus::CMatrix4f vp = CGraphics::GetPerspectiveProjectionMatrix(false) * CGraphics::g_CameraMatrix.toMatrix4f();
CGuiWidget* ret = nullptr;
for (const auto& widget : x2c_widgets)
if (widget->GetMouseActive() && widget->TestCursorHit(vp, point))
ret = widget.get();
return ret;
}
void CGuiFrame::Initialize() {
SortDrawOrder();
xc_headWidget->SetColor(xc_headWidget->xa4_color);
@ -168,6 +179,28 @@ void CGuiFrame::LoadWidgetsInGame(CInputStream& in, CSimplePool* sp) {
}
void CGuiFrame::ProcessUserInput(const CFinalInput& input) const {
if (const auto& kbm = input.GetKBM()) {
zeus::CVector2f point(kbm->m_mouseCoord.norm[0] * 2.f - 1.f,
kbm->m_mouseCoord.norm[1] * 2.f - 1.f);
CGuiWidget* hit = BestCursorHit(point, {});
if (!m_inMouseDown && kbm->m_mouseButtons[int(boo::EMouseButton::Primary)]) {
m_inMouseDown = true;
m_mouseDownWidget = hit;
if (m_mouseDownCb)
m_mouseDownCb(hit);
} else if (m_inMouseDown && !kbm->m_mouseButtons[int(boo::EMouseButton::Primary)]) {
m_inMouseDown = false;
if (m_mouseUpCb)
m_mouseUpCb(m_mouseDownWidget);
}
if (hit != m_lastMouseOverWidget) {
if (m_inMouseDown)
hit = nullptr;
if (m_mouseOverChangeCb)
m_mouseOverChangeCb(m_lastMouseOverWidget, hit);
m_lastMouseOverWidget = hit;
}
}
if (input.ControllerIdx() != 0)
return;
for (auto& widget : x2c_widgets) {

View File

@ -41,6 +41,13 @@ private:
float m_aspectConstraint = -1.f;
float m_maxAspect = -1.f;
mutable bool m_inMouseDown = false;
mutable CGuiWidget* m_mouseDownWidget = nullptr;
mutable CGuiWidget* m_lastMouseOverWidget = nullptr;
std::function<void(CGuiWidget*, CGuiWidget*)> m_mouseOverChangeCb;
std::function<void(CGuiWidget*)> m_mouseDownCb;
std::function<void(CGuiWidget*)> m_mouseUpCb;
public:
CGuiFrame(CAssetId id, CGuiSys& sys, int a, int b, int c, CSimplePool* sp);
~CGuiFrame();
@ -66,9 +73,19 @@ public:
const zeus::CTransform& GetAspectTransform() const { return m_aspectTransform; }
void SetAspectConstraint(float c);
void SetMaxAspect(float c);
void SetMouseOverChangeCallback(std::function<void(CGuiWidget*, CGuiWidget*)>&& cb) {
m_mouseOverChangeCb = std::move(cb);
}
void SetMouseDownCallback(std::function<void(CGuiWidget*)>&& cb) {
m_mouseDownCb = std::move(cb);
}
void SetMouseUpCallback(std::function<void(CGuiWidget*)>&& cb) {
m_mouseUpCb = std::move(cb);
}
void Update(float dt);
void Draw(const CGuiWidgetDrawParms& parms) const;
CGuiWidget* BestCursorHit(const zeus::CVector2f& point, const CGuiWidgetDrawParms& parms) const;
void Initialize();
void LoadWidgetsInGame(CInputStream& in, CSimplePool* sp);
void ProcessUserInput(const CFinalInput& input) const;

View File

@ -104,6 +104,12 @@ void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const {
CGuiWidget::Draw(parms);
}
bool CGuiModel::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const {
if (!xb8_model || !xb8_model.IsLoaded())
return false;
return xb8_model->GetAABB().projectedPointTest(vp * x34_worldXF.toMatrix4f(), point);
}
std::shared_ptr<CGuiWidget> CGuiModel::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) {
CGuiWidgetParms parms = ReadWidgetHeader(frame, in);

View File

@ -20,6 +20,7 @@ public:
bool GetIsFinishedLoadingWidgetSpecific() const;
void Touch() const;
void Draw(const CGuiWidgetDrawParms& parms) const;
bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const;
static std::shared_ptr<CGuiWidget> Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp);
};

View File

@ -20,6 +20,7 @@ public:
virtual ~CGuiObject() = default;
virtual void Update(float dt);
virtual void Draw(const CGuiWidgetDrawParms& parms) const;
virtual bool TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const { return false; }
virtual void Initialize() = 0;
void MoveInWorld(const zeus::CVector3f& vec);

View File

@ -21,6 +21,7 @@ CGuiWidget::CGuiWidget(const CGuiWidgetParms& parms)
xb6_31_depthTest = true;
xb7_24_depthWrite = false;
xb7_25_ = true;
m_mouseActive = false;
RecalcWidgetColor(ETraversalMode::Single);
}
@ -89,6 +90,8 @@ bool CGuiWidget::GetIsVisible() const { return xb6_25_isVisible; }
bool CGuiWidget::GetIsActive() const { return xb6_26_isActive; }
bool CGuiWidget::GetMouseActive() const { return m_mouseActive; }
void CGuiWidget::InitializeRGBAFactor() {
CGuiWidget* child = static_cast<CGuiWidget*>(GetChildObject());
if (child)

View File

@ -68,6 +68,7 @@ protected:
bool xb6_31_depthTest : 1;
bool xb7_24_depthWrite : 1;
bool xb7_25_ : 1;
bool m_mouseActive : 1;
public:
CGuiWidget(const CGuiWidgetParms& parms);
@ -82,6 +83,7 @@ public:
virtual void Touch() const;
virtual bool GetIsVisible() const;
virtual bool GetIsActive() const;
virtual bool GetMouseActive() const;
virtual FourCC GetWidgetTypeID() const { return FOURCC('BWIG'); }
virtual bool AddWorkerWidget(CGuiWidget* worker);
virtual bool GetIsFinishedLoadingWidgetSpecific() const;
@ -103,6 +105,7 @@ public:
void SetIsActive(bool);
bool GetIsSelectable() const { return xb6_27_isSelectable; }
void SetIsSelectable(bool v) { xb6_27_isSelectable = v; }
void SetMouseActive(bool v) { m_mouseActive = v; }
void ParseBaseInfo(CGuiFrame* frame, CInputStream& in, const CGuiWidgetParms& parms);
void AddChildWidget(CGuiWidget* widget, bool makeWorldLocal, bool atEnd);

View File

@ -25,24 +25,25 @@ CHudRadarInterface::CHudRadarInterface(CGuiFrame& baseHud, CStateManager& stateM
x40_BaseWidget_RadarStuff->SetColor(g_tweakGuiColors->GetRadarStuffColor());
}
void CHudRadarInterface::DoDrawRadarPaint(float radius, const zeus::CColor& color) const {
void CHudRadarInterface::DoDrawRadarPaint(const zeus::CVector3f& translate, float radius,
const zeus::CColor& color) const {
radius *= 4.f;
const_cast<CHudRadarInterface&>(*this).m_paintInsts.emplace_back();
CRadarPaintShader::Instance& inst = const_cast<CHudRadarInterface&>(*this).m_paintInsts.back();
inst.pos[0].assign(-radius, 0.f, radius);
m_paintInsts.emplace_back();
CRadarPaintShader::Instance& inst = m_paintInsts.back();
inst.pos[0] = translate + zeus::CVector3f(-radius, 0.f, radius);
inst.uv[0].assign(0.f, 1.f);
inst.pos[1].assign(-radius, 0.f, -radius);
inst.pos[1] = translate + zeus::CVector3f(-radius, 0.f, -radius);
inst.uv[1].assign(0.f, 0.f);
inst.pos[2].assign(radius, 0.f, radius);
inst.pos[2] = translate + zeus::CVector3f(radius, 0.f, radius);
inst.uv[2].assign(1.f, 1.f);
inst.pos[3].assign(radius, 0.f, -radius);
inst.pos[3] = translate + zeus::CVector3f(radius, 0.f, -radius);
inst.uv[3].assign(1.f, 0.f);
inst.color = color;
}
void CHudRadarInterface::DrawRadarPaint(const zeus::CVector3f& enemyPos, float radius, float alpha,
const SRadarPaintDrawParms& parms) const {
zeus::CVector2f playerToEnemy(enemyPos.x() - parms.x0_playerPos.x(), enemyPos.y() - parms.x0_playerPos.y());
zeus::CVector2f playerToEnemy = enemyPos.toVec2f() - parms.x0_playerPos.toVec2f();
float zDelta = std::fabs(enemyPos.z() - parms.x0_playerPos.z());
@ -50,13 +51,9 @@ void CHudRadarInterface::DrawRadarPaint(const zeus::CVector3f& enemyPos, float r
if (zDelta > parms.x80_ZCloseRadius)
alpha *= 1.f - (zDelta - parms.x80_ZCloseRadius) / (parms.x7c_zRadius - parms.x80_ZCloseRadius);
zeus::CVector2f scopeScaled = playerToEnemy * parms.x70_scopeScalar;
zeus::CTransform modelMatrix =
parms.x3c_postTranslate *
zeus::CTransform::Translate(parms.xc_preTranslate * zeus::CVector3f(scopeScaled.x(), 0.f, scopeScaled.y()));
CGraphics::SetModelMatrix(modelMatrix);
zeus::CColor color = g_tweakGuiColors->GetRadarEnemyPaintColor();
color.a() *= alpha;
DoDrawRadarPaint(radius, color);
DoDrawRadarPaint(parms.xc_preTranslate * zeus::CVector3f(scopeScaled.x(), 0.f, scopeScaled.y()), radius, color);
}
}
@ -110,13 +107,13 @@ void CHudRadarInterface::Draw(const CStateManager& mgr, float alpha) const {
drawParms.x3c_postTranslate = x40_BaseWidget_RadarStuff->GetWorldTransform();
float enemyRadius = g_tweakGui->GetRadarEnemyPaintRadius();
const_cast<CHudRadarInterface&>(*this).m_paintInsts.clear();
m_paintInsts.clear();
x44_camera->Draw(CGuiWidgetDrawParms{0.f, zeus::CVector3f{}});
CGraphics::SetModelMatrix(drawParms.x3c_postTranslate);
zeus::CColor playerColor = g_tweakGuiColors->GetRadarPlayerPaintColor();
playerColor.a() *= alpha;
DoDrawRadarPaint(g_tweakGui->GetRadarPlayerPaintRadius(), playerColor);
DoDrawRadarPaint(zeus::CVector3f::skZero, g_tweakGui->GetRadarPlayerPaintRadius(), playerColor);
zeus::CAABox radarBounds(
player.GetTranslation().x() - drawParms.x78_xyRadius, player.GetTranslation().y() - drawParms.x78_xyRadius,
@ -129,6 +126,7 @@ void CHudRadarInterface::Draw(const CStateManager& mgr, float alpha) const {
CMaterialList(EMaterialTypes::ExcludeFromRadar),
CMaterialFilter::EFilterType::IncludeExclude),
nullptr);
drawParms.x0_playerPos = mgr.GetPlayer().GetTranslation();
for (TUniqueId id : nearList) {
if (TCastToConstPtr<CActor> act = mgr.GetObjectById(id)) {
@ -147,7 +145,7 @@ void CHudRadarInterface::Draw(const CStateManager& mgr, float alpha) const {
}
}
const_cast<CHudRadarInterface&>(*this).m_paintShader.draw(m_paintInsts, x0_txtrRadarPaint.GetObj());
m_paintShader.draw(m_paintInsts, x0_txtrRadarPaint.GetObj());
}
} // namespace urde

View File

@ -28,9 +28,9 @@ class CHudRadarInterface {
bool x3c_25_visibleDebug : 1;
CGuiWidget* x40_BaseWidget_RadarStuff;
CGuiCamera* x44_camera;
CRadarPaintShader m_paintShader;
std::vector<CRadarPaintShader::Instance> m_paintInsts;
void DoDrawRadarPaint(float radius, const zeus::CColor& color) const;
mutable CRadarPaintShader m_paintShader;
mutable std::vector<CRadarPaintShader::Instance> m_paintInsts;
void DoDrawRadarPaint(const zeus::CVector3f& translate, float radius, const zeus::CColor& color) const;
void DrawRadarPaint(const zeus::CVector3f& enemyPos, float radius, float alpha,
const SRadarPaintDrawParms& parms) const;

View File

@ -170,7 +170,8 @@ CFinalInput::CFinalInput(int cIdx, float dt, const CKeyboardMouseControllerData&
, x2e_b28_PDPRight(DDPRight() && !prevInput.DDPRight())
, x2e_b29_PDPDown(DDPDown() && !prevInput.DDPDown())
, x2e_b30_PDPLeft(DDPLeft() && !prevInput.DDPLeft())
, x2e_b31_PStart(DStart() && !prevInput.DStart()) {
, x2e_b31_PStart(DStart() && !prevInput.DStart())
, m_kbm(data) {
if (x8_anaLeftX || xc_anaLeftY) {
float len = std::sqrt(x8_anaLeftX * x8_anaLeftX + xc_anaLeftY * xc_anaLeftY);
x8_anaLeftX /= len;
@ -230,6 +231,8 @@ CFinalInput& CFinalInput::operator|=(const CFinalInput& other) {
x2e_b29_PDPDown |= other.x2e_b29_PDPDown;
x2e_b30_PDPLeft |= other.x2e_b30_PDPLeft;
x2e_b31_PStart |= other.x2e_b31_PStart;
if (other.m_kbm)
m_kbm = other.m_kbm;
return *this;
}

View File

@ -59,6 +59,8 @@ struct CFinalInput {
bool x2e_b30_PDPLeft : 1;
bool x2e_b31_PStart : 1;
std::experimental::optional<CKeyboardMouseControllerData> m_kbm;
CFinalInput();
CFinalInput(int cIdx, float dt, const boo::DolphinControllerState& data, const CFinalInput& prevInput, float leftDiv,
float rightDiv);
@ -143,6 +145,8 @@ struct CFinalInput {
float ARightTrigger() const { return x1c_anaRightTrigger; }
CFinalInput ScaleAnalogueSticks(float leftDiv, float rightDiv) const;
const std::experimental::optional<CKeyboardMouseControllerData>& GetKBM() const { return m_kbm; }
};
} // namespace urde

View File

@ -87,6 +87,7 @@ void CPauseScreenBase::InitializeFrameGlue() {
x144_model_titles.push_back(static_cast<CGuiModel*>(x8_frame.FindWidget(hecl::Format("model_title%d", i + 1))));
x15c_model_righttitledecos.push_back(
static_cast<CGuiModel*>(x8_frame.FindWidget(hecl::Format("model_righttitledeco%d", i + 1))));
x15c_model_righttitledecos.back()->SetMouseActive(true);
xa8_textpane_categories.push_back(
static_cast<CGuiTextPane*>(x8_frame.FindWidget(hecl::Format("textpane_category%d", i))));
xc0_model_categories.push_back(static_cast<CGuiModel*>(x8_frame.FindWidget(hecl::Format("model_category%d", i))));

View File

@ -862,7 +862,7 @@ void CMorphBall::UpdateBallDynamics(CStateManager& mgr, float dt) {
x1c28_tireInterpSpeed = -1.f;
UpdateMarbleDynamics(mgr, dt, x1890_spiderTrackPoint);
} else {
if (x0_player.GetSurfaceRestraint() != CPlayer::ESurfaceRestraints::InAir) {
if (x0_player.GetSurfaceRestraint() != CPlayer::ESurfaceRestraints::Air) {
zeus::CVector3f normal, point;
if (CalculateBallContactInfo(normal, point)) {
x1924_surfaceToWorld = CalculateSurfaceToWorld(normal, point, x0_player.x500_lookDir);

View File

@ -2438,13 +2438,13 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
x2ac_surfaceRestraint = ESurfaceRestraints::Ice;
break;
case EScriptObjectMessage::OnMudSlowSurface:
x2ac_surfaceRestraint = ESurfaceRestraints::MudSlow;
x2ac_surfaceRestraint = ESurfaceRestraints::Organic;
break;
case EScriptObjectMessage::OnNormalSurface:
x2ac_surfaceRestraint = ESurfaceRestraints::Normal;
break;
case EScriptObjectMessage::InSnakeWeed:
x2ac_surfaceRestraint = ESurfaceRestraints::SnakeWeed;
x2ac_surfaceRestraint = ESurfaceRestraints::Shrubbery;
break;
case EScriptObjectMessage::AddSplashInhabitant: {
SetInFluid(true, sender);
@ -2473,7 +2473,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
x2b0_outOfWaterTicks = 0;
break;
case EFluidType::PhazonFluid:
x2ac_surfaceRestraint = ESurfaceRestraints::PhazonFluid;
x2ac_surfaceRestraint = ESurfaceRestraints::Phazon;
break;
default:
break;
@ -4681,7 +4681,7 @@ void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr) {
case ESurfaceRestraints::Lava:
upVel *= g_tweakPlayer->GetLavaBallJumpFactor();
break;
case ESurfaceRestraints::PhazonFluid:
case ESurfaceRestraints::Phazon:
upVel *= g_tweakPlayer->GetPhazonBallJumpFactor();
break;
default:
@ -4785,7 +4785,7 @@ void CPlayer::SetMoveState(EPlayerMovementState newState, CStateManager& mgr) {
}
}
x258_movementState = EPlayerMovementState::Jump;
x2ac_surfaceRestraint = ESurfaceRestraints::InAir;
x2ac_surfaceRestraint = ESurfaceRestraints::Air;
x2a8_timeSinceJump = 0.f;
break;
case EPlayerMovementState::Falling:
@ -4826,7 +4826,7 @@ void CPlayer::SetMoveState(EPlayerMovementState newState, CStateManager& mgr) {
x2a4_cancelCameraPitch = false;
}
}
x2ac_surfaceRestraint = ESurfaceRestraints::InAir;
x2ac_surfaceRestraint = ESurfaceRestraints::Air;
break;
}
}
@ -4844,7 +4844,7 @@ float CPlayer::JumpInput(const CFinalInput& input, CStateManager& mgr) {
case ESurfaceRestraints::Lava:
jumpFactor = g_tweakPlayer->GetLavaJumpFactor();
break;
case ESurfaceRestraints::PhazonFluid:
case ESurfaceRestraints::Phazon:
jumpFactor = g_tweakPlayer->GetPhazonJumpFactor();
break;
default:
@ -5214,7 +5214,7 @@ float CPlayer::GetWeight() const { return xe8_mass * -GetGravity(); }
zeus::CVector3f CPlayer::GetDampedClampedVelocityWR() const {
zeus::CVector3f localVel = x34_transform.transposeRotate(x138_velocity);
if ((x258_movementState != EPlayerMovementState::ApplyJump || GetSurfaceRestraint() != ESurfaceRestraints::InAir) &&
if ((x258_movementState != EPlayerMovementState::ApplyJump || GetSurfaceRestraint() != ESurfaceRestraints::Air) &&
x304_orbitState == EPlayerOrbitState::NoOrbit) {
float friction = g_tweakPlayer->GetPlayerTranslationFriction(int(GetSurfaceRestraint()));
if (localVel.y() > 0.f)

View File

@ -78,7 +78,7 @@ public:
enum class EPlayerCameraState { FirstPerson, Ball, Two, Transitioning, Spawned };
enum class ESurfaceRestraints { Normal, InAir, Ice, MudSlow, Water, Lava, PhazonFluid, SnakeWeed };
enum class ESurfaceRestraints { Normal, Air, Ice, Organic, Water, Lava, Phazon, Shrubbery };
enum class EFootstepSfx { None, Left, Right };

View File

@ -78,7 +78,8 @@ void CStateMachineState::Update(CStateManager& mgr, CAi& ai, float delta) {
if (andPassed && state) {
x4_state->CallFunc(mgr, ai, EStateMsg::Deactivate, 0.f);
x4_state = state;
printf("%s %d\n", state->xc_name, int(state - x0_machine->GetStateVector().data()));
printf("%04X %08X %s - %s %d\n", ai.GetUniqueId().Value(), ai.GetEditorId().id, ai.GetName().data(),
state->xc_name, int(state - x0_machine->GetStateVector().data()));
x8_time = 0.f;
x18_24_codeTrigger = false;
xc_random = mgr.GetActiveRandom()->Float();

View File

@ -1,13 +1,13 @@
#shader CRadarPaintShader
#attribute position4 0
#attribute position4 1
#attribute position4 2
#attribute position4 3
#attribute uv4 0
#attribute uv4 1
#attribute uv4 2
#attribute uv4 3
#attribute color
#instattribute position4 0
#instattribute position4 1
#instattribute position4 2
#instattribute position4 3
#instattribute uv4 0
#instattribute uv4 1
#instattribute uv4 2
#instattribute uv4 3
#instattribute color
#srcfac srcalpha
#dstfac one
#primitive tristrips

@ -1 +1 @@
Subproject commit 8da97f6c95872fb3fe7211c8bd6cf6a0f13050a6
Subproject commit 995b4268bd37b4ab93cc794a9e6bd7b38bbda1c0