Add GameMode viewerspace stub

This commit is contained in:
Phillip Stephens 2016-12-12 18:56:43 -08:00
parent b6aa19540b
commit 97ab6961a2
15 changed files with 365 additions and 14 deletions

View File

@ -8,6 +8,7 @@ atdna(atdna_ResourceBrowser.cpp ResourceBrowser.hpp)
atdna(atdna_ModelViewer.cpp ModelViewer.hpp)
atdna(atdna_ParticleEditor.cpp ParticleEditor.hpp)
atdna(atdna_InformationCenter.cpp InformationCenter.hpp)
atdna(atdna_GameMode.cpp GameMode.hpp)
if(WIN32)
set(PLAT_SRCS platforms/win/urde.rc)
@ -32,7 +33,8 @@ add_executable(urde WIN32 MACOSX_BUNDLE
ProjectManager.hpp ProjectManager.cpp
ViewManager.hpp ViewManager.cpp
Resource.hpp Resource.cpp
Camera.hpp Camera.cpp)
Camera.hpp Camera.cpp
GameMode.hpp GameMode.cpp atdna_GameMode.cpp)
target_link_libraries(urde
UrdeLocales

16
Editor/GameMode.cpp Normal file
View File

@ -0,0 +1,16 @@
#include "GameMode.hpp"
namespace urde
{
void GameMode::think()
{
ViewerSpace::think();
}
void GameMode::View::draw(boo::IGraphicsCommandQueue *gfxQ)
{
if (m_gMode.m_main)
m_gMode.m_main->Draw();
}
}

76
Editor/GameMode.hpp Normal file
View File

@ -0,0 +1,76 @@
#ifndef URDE_GAMEMODE_HPP
#define URDE_GAMEMODE_HPP
#include "Space.hpp"
#include "ViewManager.hpp"
#include "Runtime/IMain.hpp"
namespace urde
{
class GameMode : public ViewerSpace
{
std::shared_ptr<IMain> m_main;
struct State : Space::State
{
DECL_YAML
Value<bool> showToolbar = true;
} m_state;
const Space::State& spaceState() const { return m_state; }
struct View : specter::View
{
GameMode& m_gMode;
View(GameMode& gMode, specter::ViewResources& res)
: specter::View(res, gMode.m_vm.rootView()), m_gMode(gMode) {}
void draw(boo::IGraphicsCommandQueue *gfxQ);
};
std::unique_ptr<View> m_view;
public:
GameMode(ViewManager& vm, Space* parent)
: ViewerSpace(vm, Class::GameMode, parent)
{
reloadState();
}
GameMode(ViewManager& vm, Space* parent, const GameMode& other)
: GameMode(vm, parent)
{
m_state = other.m_state;
reloadState();
}
GameMode(ViewManager& vm, Space* parent, ConfigReader& r)
: GameMode(vm, parent)
{
m_state.read(r);
reloadState();
}
void reloadState()
{
}
virtual specter::View* buildContentView(specter::ViewResources &res)
{
m_view.reset(new View(*this, res));
return m_view.get();
}
void think();
Space* copy(Space *parent) const
{
return new GameMode(m_vm, parent, *this);
}
bool usesToolbar() const { return m_state.showToolbar; }
};
}
#endif // URDE_GAMEMODE_HPP

View File

@ -4,6 +4,7 @@
#include "ParticleEditor.hpp"
#include "ModelViewer.hpp"
#include "InformationCenter.hpp"
#include "GameMode.hpp"
#include "icons/icons.hpp"
namespace urde
@ -46,7 +47,8 @@ std::vector<Space::SpaceMenuNode::SubNodeData> Space::SpaceMenuNode::s_subNodeDa
{Class::ResourceBrowser, "resource_browser", "Resource Browser", GetIcon(SpaceIcon::ResourceBrowser), {0.0f, 1.0f, 0.0f, 1.0f}},
{Class::EffectEditor, "effect_editor", "Effect Editor", GetIcon(SpaceIcon::ParticleEditor), {1.0f, 0.5f, 0.0f, 1.0f}},
{Class::ModelViewer, "model_viewer", "Model Viewer", GetIcon(SpaceIcon::ModelViewer), {0.95f, 0.95f, 0.95f, 1.0f}},
{Class::InformationCenter, "information_center", "Information Center", GetIcon(SpaceIcon::InformationCenter), {0.0f, 1.0f, 1.0f, 1.0f}}
{Class::InformationCenter, "information_center", "Information Center", GetIcon(SpaceIcon::InformationCenter), {0.0f, 1.0f, 1.0f, 1.0f}},
{Class::GameMode, "game_mode", "Game Mode", GetIcon(SpaceIcon::GameMode), {}}
};
std::string Space::SpaceMenuNode::s_text = "Space Types";
@ -207,6 +209,8 @@ static Space* BuildNewSpace(ViewManager& vm, Space::Class cls, Space* parent, Re
return new ModelViewer(vm, parent, r);
case Class::InformationCenter:
return new InformationCenter(vm, parent, r);
case Class::GameMode:
return new GameMode(vm, parent, r);
default: break;
}
return nullptr;
@ -259,6 +263,10 @@ void Space::SpaceMenuNode::SubNode::activated(const boo::SWindowCoord &coord)
if (typeid(ModelViewer) != typeid(m_space))
newSpace.reset(new ModelViewer(m_space.m_parent->m_vm, m_space.m_parent));
break;
case Class::GameMode:
if (typeid(GameMode) != typeid(m_space))
newSpace.reset(new GameMode(m_space.m_parent->m_vm, m_space.m_parent));
break;
default: break;
}
if (newSpace)

View File

@ -35,7 +35,8 @@ public:
ResourceBrowser,
ModelViewer,
EffectEditor,
InformationCenter
InformationCenter,
GameMode
};
struct State : athena::io::DNAYaml<athena::BigEndian> {Delete _d;};

View File

@ -70,7 +70,7 @@ void ViewManager::BuildTestPART(urde::IObjectStore& objStore)
m_videoVoice = m_voiceEngine->allocateNewStereoVoice(32000, &m_voiceCallback);
m_videoVoice->start();
m_rootView->accessContentViews().clear();
//m_rootView->accessContentViews().clear();
m_rootView->accessContentViews().push_back(m_particleView.get());
m_rootView->updateSize();
}

View File

@ -51,6 +51,8 @@ specter::Icon& GetIcon(SpaceIcon icon)
return g_IconAtlas.getIcon(0, 3);
case SpaceIcon::ModelViewer:
return g_IconAtlas.getIcon(0, 4);
case SpaceIcon::GameMode:
return g_IconAtlas.getIcon(0, 5);
default:
return g_IconAtlas.getIcon(6, 0);
}

View File

@ -14,7 +14,8 @@ enum class SpaceIcon
ParticleEditor,
WorldEditor,
ModelViewer,
InformationCenter
InformationCenter,
GameMode
};
specter::Icon& GetIcon(SpaceIcon icon);

View File

@ -25,17 +25,17 @@
borderopacity="1.0"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:zoom="39.419828"
inkscape:cx="8.6860061"
inkscape:cy="72.349928"
inkscape:zoom="19.709914"
inkscape:cx="11.98074"
inkscape:cy="81.550111"
inkscape:document-units="px"
inkscape:current-layer="g3516"
inkscape:current-layer="layer1-5"
showgrid="true"
units="px"
inkscape:window-width="1366"
inkscape:window-height="713"
inkscape:window-width="1920"
inkscape:window-height="1051"
inkscape:window-x="0"
inkscape:window-y="31"
inkscape:window-y="0"
inkscape:window-maximized="1">
<inkscape:grid
type="xygrid"
@ -279,6 +279,191 @@
d="m 72,941.37499 -20,10 0,25 20,10 20,-10 0,-25 -20,-10 z"
id="path2993"
inkscape:connector-curvature="0" />
<g
id="g4609"
transform="matrix(0.17060215,0,0,0.17060215,50.333785,893.89389)"
style="stroke:none;stroke-opacity:1">
<path
id="path3"
d="m 87.423,88.968 c 0.562,3.126 -1.517,6.115 -4.642,6.676 l -33.956,6.102 c -3.126,0.562 -6.115,-1.517 -6.676,-4.642 l 0,0 c -0.562,-3.126 1.517,-6.115 4.642,-6.676 l 33.956,-6.102 c 3.126,-0.562 6.114,1.516 6.676,4.642 l 0,0 z"
inkscape:connector-curvature="0"
style="fill:#333333;stroke:none;stroke-opacity:1" />
<g
transform="translate(-285.71429,-365.21932)"
id="layer1-5"
style="stroke:none;stroke-opacity:1">
<g
id="g4702"
transform="matrix(1.0457519,0,0,1.0457519,-18.299215,-25.629196)">
<path
inkscape:connector-curvature="0"
id="path2985"
d="m 534.285,489.505 c 0.024,68.641 -55.601,124.305 -124.242,124.329 -68.641,0.024 -124.305,-55.602 -124.329,-124.243 0,-0.029 0,-0.058 0,-0.086 -0.024,-68.641 55.602,-124.305 124.243,-124.329 68.641,-0.023 124.305,55.602 124.328,124.243 0,0.028 0,0.057 0,0.086 z"
style="fill:#76c2af;fill-opacity:1;stroke:#000000;stroke-width:13.74423695;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:#231f20;stroke:none;stroke-width:6;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3099"
d="m 410.951,366.726 c -2.583,27.364 -8.65,40.051 -11.059,50.922 -1.204,5.436 -1.468,10.432 0.094,16.466 1.562,6.034 4.943,13.107 11.027,22.808 l 0.846,-0.518 c -6.057,-9.659 -9.378,-16.649 -10.901,-22.534 -1.523,-5.885 -1.247,-10.662 -0.063,-16.008 2.369,-10.694 8.465,-23.569 11.058,-51.044 l -1.002,-0.092 0,0 z" />
<g
style="stroke:none;stroke-opacity:1"
id="g3915">
<g
style="stroke:none;stroke-opacity:1"
id="g9">
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path2993_1_"
d="m 399.265,504.94 c 0,22.092 -17.909,40 -40,40 -22.092,0 -40,-17.908 -40,-40 l 0,0 c 0,-22.091 17.908,-40 40,-40 22.091,0 40,17.909 40,40 z" />
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path2993-7_1_"
d="m 501.264,504.94 c 0,22.092 -17.908,40 -40,40 -22.092,0 -40,-17.908 -40,-40 l 0,0 c 0,-22.091 17.908,-40 40,-40 22.092,0 40,17.909 40,40 z" />
<rect
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
id="rect3031_1_"
x="356.04999"
y="464.94"
width="105.713"
height="60" />
</g>
<g
style="stroke:none;stroke-opacity:1"
id="g14">
<path
style="fill:#f2f2f2;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path2993-6"
d="m 399.598,496.273 c 0,22.092 -17.909,40 -40,40 -22.092,0 -40,-17.908 -40,-40 l 0,0 c 0,-22.091 17.908,-40 40,-40 22.091,0 40,17.909 40,40 z" />
<path
style="fill:#f2f2f2;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path2993-7"
d="m 501.598,496.273 c 0,22.092 -17.908,40 -40,40 -22.092,0 -40,-17.908 -40,-40 l 0,0 c 0,-22.091 17.908,-40 40,-40 22.092,0 40,17.909 40,40 z" />
<rect
style="fill:#f2f2f2;stroke:none;stroke-opacity:1"
id="rect3031"
x="356.384"
y="456.27301"
width="105.714"
height="60" />
</g>
<g
style="stroke:none;stroke-opacity:1"
id="g19">
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055_2_"
d="m 472.387,478.471 c 0,5.061 -4.104,9.163 -9.164,9.163 -5.06,0 -9.163,-4.102 -9.163,-9.163 0,-5.061 4.103,-9.163 9.163,-9.163 5.06,0 9.164,4.102 9.164,9.163 l 0,0 z" />
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-0_2_"
d="m 472.531,516.005 c 0,5.061 -4.103,9.163 -9.162,9.163 -5.062,0 -9.164,-4.103 -9.164,-9.163 0,-5.062 4.103,-9.164 9.164,-9.164 5.06,0 9.162,4.102 9.162,9.164 l 0,0 z" />
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-9_2_"
d="m 491.125,497.376 c 0,5.06 -4.104,9.163 -9.162,9.163 -5.063,0 -9.164,-4.104 -9.164,-9.163 0,-5.062 4.102,-9.164 9.164,-9.164 5.058,0 9.162,4.103 9.162,9.164 l 0,0 z" />
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-4_2_"
d="m 453.724,497.356 c 0,5.063 -4.103,9.164 -9.163,9.164 -5.062,0 -9.163,-4.102 -9.163,-9.164 0,-5.06 4.102,-9.163 9.163,-9.163 5.06,0 9.163,4.103 9.163,9.163 l 0,0 z" />
</g>
<g
style="stroke:none;stroke-opacity:1"
id="g25">
<path
style="fill:#141212;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055_1_"
d="m 472.387,477.221 c 0,5.061 -4.104,9.163 -9.164,9.163 -5.06,0 -9.163,-4.102 -9.163,-9.163 0,-5.061 4.103,-9.163 9.163,-9.163 5.06,0 9.164,4.102 9.164,9.163 l 0,0 z" />
<path
style="fill:#141212;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-0_1_"
d="m 472.531,514.755 c 0,5.061 -4.103,9.163 -9.162,9.163 -5.062,0 -9.164,-4.103 -9.164,-9.163 0,-5.062 4.103,-9.164 9.164,-9.164 5.06,0 9.162,4.102 9.162,9.164 l 0,0 z" />
<path
style="fill:#141212;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-9_1_"
d="m 491.125,496.126 c 0,5.06 -4.104,9.163 -9.162,9.163 -5.063,0 -9.164,-4.104 -9.164,-9.163 0,-5.062 4.102,-9.164 9.164,-9.164 5.058,0 9.162,4.103 9.162,9.164 l 0,0 z" />
<path
style="fill:#141212;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-4_1_"
d="m 453.724,496.106 c 0,5.063 -4.103,9.164 -9.163,9.164 -5.062,0 -9.163,-4.102 -9.163,-9.164 0,-5.06 4.102,-9.163 9.163,-9.163 5.06,0 9.163,4.103 9.163,9.163 l 0,0 z" />
</g>
<path
style="fill:#333333;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055"
d="m 472.387,474.846 c 0,5.061 -4.104,9.163 -9.164,9.163 -5.06,0 -9.163,-4.103 -9.163,-9.163 0,-5.061 4.103,-9.163 9.163,-9.163 5.06,0 9.164,4.102 9.164,9.163 l 0,0 z" />
<path
style="fill:#333333;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-0"
d="m 472.531,512.38 c 0,5.061 -4.103,9.163 -9.162,9.163 -5.062,0 -9.164,-4.103 -9.164,-9.163 0,-5.062 4.103,-9.164 9.164,-9.164 5.06,0 9.162,4.102 9.162,9.164 l 0,0 z" />
<path
style="fill:#333333;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-9"
d="m 491.125,493.751 c 0,5.06 -4.104,9.163 -9.162,9.163 -5.063,0 -9.164,-4.104 -9.164,-9.163 0,-5.062 4.102,-9.164 9.164,-9.164 5.058,0.001 9.162,4.103 9.162,9.164 l 0,0 z" />
<path
style="fill:#333333;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
id="path3055-4"
d="m 453.724,493.731 c 0,5.063 -4.103,9.164 -9.163,9.164 -5.062,0 -9.163,-4.102 -9.163,-9.164 0,-5.06 4.102,-9.163 9.163,-9.163 5.06,0 9.163,4.103 9.163,9.163 l 0,0 z" />
<g
style="stroke:none;stroke-opacity:1"
id="g35">
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 383.75,502.13 c 0,3.797 -3.078,6.875 -6.875,6.875 l -36.25,0 c -3.797,0 -6.875,-3.078 -6.875,-6.875 l 0,0 c 0,-3.797 3.078,-6.875 6.875,-6.875 l 36.25,0 c 3.797,0 6.875,3.078 6.875,6.875 l 0,0 z"
id="path37" />
<path
style="fill:#c1bc9d;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 358.625,477.13 c 3.797,0 6.875,3.078 6.875,6.875 l 0,36.25 c 0,3.797 -3.078,6.875 -6.875,6.875 l 0,0 c -3.797,0 -6.875,-3.078 -6.875,-6.875 l 0,-36.25 c 0,-3.797 3.078,-6.875 6.875,-6.875 l 0,0 z"
id="path39" />
</g>
<g
style="stroke:none;stroke-opacity:1"
id="g41">
<path
style="fill:#141212;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 383.75,499.255 c 0,3.797 -3.078,6.875 -6.875,6.875 l -36.25,0 c -3.797,0 -6.875,-3.078 -6.875,-6.875 l 0,0 c 0,-3.797 3.078,-6.875 6.875,-6.875 l 36.25,0 c 3.797,0 6.875,3.078 6.875,6.875 l 0,0 z"
id="path43" />
<path
style="fill:#141212;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 358.625,474.255 c 3.797,0 6.875,3.078 6.875,6.875 l 0,36.25 c 0,3.797 -3.078,6.875 -6.875,6.875 l 0,0 c -3.797,0 -6.875,-3.078 -6.875,-6.875 l 0,-36.25 c 0,-3.797 3.078,-6.875 6.875,-6.875 l 0,0 z"
id="path45" />
</g>
<g
style="stroke:none;stroke-opacity:1"
id="g47">
<path
style="fill:#333333;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 383.75,495.755 c 0,3.797 -3.078,6.875 -6.875,6.875 l -36.25,0 c -3.797,0 -6.875,-3.078 -6.875,-6.875 l 0,0 c 0,-3.797 3.078,-6.875 6.875,-6.875 l 36.25,0 c 3.797,0 6.875,3.078 6.875,6.875 l 0,0 z"
id="path49" />
<path
style="fill:#333333;stroke:none;stroke-opacity:1"
inkscape:connector-curvature="0"
d="m 358.625,470.755 c 3.797,0 6.875,3.078 6.875,6.875 l 0,36.25 c 0,3.797 -3.078,6.875 -6.875,6.875 l 0,0 c -3.797,0 -6.875,-3.078 -6.875,-6.875 l 0,-36.25 c 0,-3.797 3.078,-6.875 6.875,-6.875 l 0,0 z"
id="path51" />
</g>
</g>
</g>
</g>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 43 KiB

After

Width:  |  Height:  |  Size: 54 KiB

View File

@ -47,6 +47,7 @@ struct Application : boo::IApplicationCallback
break;
}
m_viewManager->stop();
m_viewManager->projectManager().saveProject();
m_cvarManager.serialize();
m_viewManager.reset();
return 0;

View File

@ -64,6 +64,7 @@ set(WORLD_SOURCES
CScriptPlayerActor.hpp CScriptPlayerActor.cpp
CScriptAiJumpPoint.hpp CScriptAiJumpPoint.cpp
CScriptColorModulate.hpp CScriptColorModulate.cpp
CScriptCameraHintTrigger.hpp CScriptCameraHintTrigger.cpp
CGrappleParameters.hpp
CActorParameters.hpp
CLightParameters.hpp

View File

@ -0,0 +1,16 @@
#include "CScriptCameraHintTrigger.hpp"
#include "CActorParameters.hpp"
namespace urde
{
CScriptCameraHintTrigger::CScriptCameraHintTrigger(TUniqueId uid, bool active, const std::string& name, const CEntityInfo& info, const zeus::CVector3f& scale, const zeus::CTransform& xf, bool b2, bool b3)
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(EMaterialTypes::ThirtyFour), CActorParameters::None(), kInvalidUniqueId)
, xe8_obb(xf, scale)
, x124_scale(scale)
, x130_24_(b2)
, x130_25_(b3)
{
}
}

View File

@ -0,0 +1,28 @@
#ifndef __URDE_CSCRIPTCAMERAHINTTRIGGER_HPP__
#define __URDE_CSCRIPTCAMERAHINTTRIGGER_HPP__
#include "CActor.hpp"
#include "zeus/COBBox.hpp"
namespace urde
{
class CScriptCameraHintTrigger : public CActor
{
zeus::COBBox xe8_obb;
zeus::CVector3f x124_scale;
union
{
struct
{
bool x130_24_ : 1;
bool x130_25_ : 1;
bool x130_26_ : 1;
bool x130_27_ : 1;
};
u8 _dummy = 0;
};
public:
CScriptCameraHintTrigger(TUniqueId, bool, const std::string& name, const CEntityInfo&, const zeus::CVector3f&, const zeus::CTransform&, bool, bool);
};
}
#endif // __URDE_CSCRIPTCAMERAHINTTRIGGER_HPP__

View File

@ -47,6 +47,7 @@
#include "CScriptSpecialFunction.hpp"
#include "CScriptAiJumpPoint.hpp"
#include "CScriptColorModulate.hpp"
#include "CScriptCameraHintTrigger.hpp"
#include "Camera/CCinematicCamera.hpp"
#include "MP1/CNewIntroBoss.hpp"
#include "MP1/CBeetle.hpp"
@ -1867,7 +1868,20 @@ CEntity* ScriptLoader::LoadAtomicAlpha(CStateManager& mgr, CInputStream& in, int
CEntity* ScriptLoader::LoadCameraHintTrigger(CStateManager& mgr, CInputStream& in, int propCount,
const CEntityInfo& info)
{
return nullptr;
if (!EnsurePropertyCount(propCount, 7, "CameraHintTrigger"))
return nullptr;
SActorHead aHead = LoadActorHead(in, mgr);
zeus::CVector3f scale = 0.5f * zeus::CVector3f::ReadBig(in);
bool active = in.readBool();
bool b2 = in.readBool();
bool b3 = in.readBool();
zeus::CTransform xfRot = aHead.x10_transform.getRotation();
if (xfRot == zeus::CTransform::Identity())
return new CScriptTrigger(mgr.AllocateUniqueId(), aHead.x0_name, info, aHead.x10_transform.origin, zeus::CAABox(-scale, scale), CDamageInfo(), zeus::CVector3f::skZero, ETriggerFlags::DetectPlayer, active, b2, b3);
return new CScriptCameraHintTrigger(mgr.AllocateUniqueId(), active, aHead.x0_name, info, scale, aHead.x10_transform, b2, b3);
}
CEntity* ScriptLoader::LoadRumbleEffect(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)

@ -1 +1 @@
Subproject commit a092a62d709ae1c99722646494d917d7e4f35219
Subproject commit 7236e59845cc0f99ec2bcf2774d739e60fd48bb5