mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'master' of https://github.com/AxioDL/PathShagged
This commit is contained in:
commit
323367466e
|
@ -1,2 +1,3 @@
|
|||
version.h
|
||||
*.user
|
||||
.DS_Store
|
||||
|
|
|
@ -4,12 +4,29 @@ project(PathShagged)
|
|||
if(MSVC)
|
||||
# Shaddup MSVC
|
||||
add_definitions(-DUNICODE=1 -D_UNICODE=1 -D__SSE__=1 -D_CRT_SECURE_NO_WARNINGS=1 -DD_SCL_SECURE_NO_WARNINGS=1 /wd4267 /wd4244 /wd4305)
|
||||
|
||||
# Link-time Code Generation for Release builds
|
||||
set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy /MD")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "/DNDEBUG /Zi /O2 /Oy- /GL /Gy /MD")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO")
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "/DEBUG /RELEASE /LTCG /OPT:REF /OPT:ICF /INCREMENTAL:NO /DEBUGTYPE:cv,fixup")
|
||||
|
||||
else()
|
||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive")
|
||||
message(WARNING "GCC needs -fpermissive for nested type redeclarations; expect lotsa warnings!!")
|
||||
endif()
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wno-multichar -fno-exceptions")
|
||||
|
||||
if(APPLE)
|
||||
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -flto")
|
||||
set(CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO} -flto")
|
||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -flto")
|
||||
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -flto")
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
||||
|
|
|
@ -673,6 +673,7 @@ def make_pass_inca():
|
|||
new_grp.links.new(grp_in.outputs[0], add1.inputs[1])
|
||||
new_grp.links.new(grp_in.outputs[2], add1.inputs[2])
|
||||
new_grp.links.new(add1.outputs[0], grp_out.inputs[0])
|
||||
new_grp.links.new(grp_in.outputs[1], grp_out.inputs[1])
|
||||
grp_out.inputs[1].default_value = 1.0
|
||||
|
||||
# Reflection Map
|
||||
|
|
|
@ -64,13 +64,13 @@ void MaterialSet::ConstructMaterial(Stream& out,
|
|||
|
||||
|
||||
/* Blend factors */
|
||||
if (material.header.flags.additiveBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ADD'\n"
|
||||
if (material.header.flags.alphaBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ALPHA'\n"
|
||||
"new_material.use_transparency = True\n"
|
||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||
"new_material.alpha = 1.0\n";
|
||||
else if (material.header.flags.alphaBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ALPHA'\n"
|
||||
else if (material.header.flags.additiveBlending())
|
||||
out << "new_material.game_settings.alpha_blend = 'ADD'\n"
|
||||
"new_material.use_transparency = True\n"
|
||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||
"new_material.alpha = 1.0\n";
|
||||
|
@ -78,6 +78,7 @@ void MaterialSet::ConstructMaterial(Stream& out,
|
|||
/* Texmap list */
|
||||
out << "tex_maps = []\n"
|
||||
"pnode = None\n"
|
||||
"anode = None\n"
|
||||
"rflv_tex_node = None\n";
|
||||
|
||||
/* Add PASSes */
|
||||
|
@ -97,9 +98,13 @@ void MaterialSet::ConstructMaterial(Stream& out,
|
|||
/* Connect final PASS */
|
||||
out << "if pnode:\n"
|
||||
" new_nodetree.links.new(pnode.outputs['Next Color'], final_node.inputs['Color'])\n"
|
||||
" new_nodetree.links.new(pnode.outputs['Next Alpha'], final_node.inputs['Alpha'])\n"
|
||||
"else:\n"
|
||||
" new_nodetree.links.new(kcolor_nodes[-1][0].outputs[0], final_node.inputs['Color'])\n"
|
||||
"if anode:\n"
|
||||
" new_nodetree.links.new(anode.outputs['Value'], final_node.inputs['Alpha'])\n"
|
||||
"elif pnode:\n"
|
||||
" new_nodetree.links.new(pnode.outputs['Next Alpha'], final_node.inputs['Alpha'])\n"
|
||||
"else:\n"
|
||||
" new_nodetree.links.new(kcolor_nodes[-1][1].outputs[0], final_node.inputs['Alpha'])\n";
|
||||
}
|
||||
|
||||
|
@ -278,7 +283,13 @@ void Material::SectionINT::constructNode(HECL::BlenderConnection::PyOutStream& o
|
|||
switch (Subtype(subtype.toUint32()))
|
||||
{
|
||||
case Subtype::OPAC:
|
||||
out.format("new_material.retro_opac = %d\n", value);
|
||||
{
|
||||
GX::Color clr(value);
|
||||
out.format("anode = new_nodetree.nodes.new('ShaderNodeValue')\n"
|
||||
"anode.outputs['Value'].default_value = %f\n",
|
||||
float(clr[3]) / float(0xff));
|
||||
out << "gridder.place_node(anode, 1)\n";
|
||||
}
|
||||
break;
|
||||
case Subtype::BLOD:
|
||||
out.format("new_material.retro_blod = %d\n", value);
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_subdirectory(locale)
|
||||
add_subdirectory(icons)
|
||||
|
||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||
option(RUDE_BINARY_CONFIGS
|
||||
|
@ -17,18 +18,21 @@ endif()
|
|||
|
||||
atdna(atdna_Space.cpp Space.hpp)
|
||||
atdna(atdna_ResourceBrowser.cpp ResourceBrowser.hpp)
|
||||
atdna(atdna_ModelViewer.cpp ModelViewer.hpp)
|
||||
|
||||
add_executable(urde WIN32
|
||||
main.cpp
|
||||
Space.hpp Space.cpp atdna_Space.cpp
|
||||
SplashScreen.hpp SplashScreen.cpp
|
||||
ResourceBrowser.hpp ResourceBrowser.cpp atdna_ResourceBrowser.cpp
|
||||
ModelViewer.hpp ModelViewer.cpp
|
||||
ModelViewer.hpp ModelViewer.cpp atdna_ModelViewer.cpp
|
||||
ProjectManager.hpp ProjectManager.cpp
|
||||
ViewManager.hpp ViewManager.cpp)
|
||||
ViewManager.hpp ViewManager.cpp
|
||||
Camera.hpp Camera.cpp)
|
||||
|
||||
target_link_libraries(urde
|
||||
UrdeLocales
|
||||
UrdeIcons
|
||||
RuntimeCommonCharacter
|
||||
RuntimeCommonInput
|
||||
RuntimeCommon
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
#ifndef URDE_CAMERA_HPP
|
||||
#define URDE_CAMERA_HPP
|
||||
#include <CProjection.hpp>
|
||||
#include <CFrustum.hpp>
|
||||
#include <CQuaternion.hpp>
|
||||
#include <CVector3f.hpp>
|
||||
#include <Math.hpp>
|
||||
|
||||
namespace URDE
|
||||
{
|
||||
class Camera
|
||||
{
|
||||
Zeus::CFrustum m_frustum;
|
||||
Zeus::CProjection m_projection;
|
||||
Zeus::CVector3f m_position;
|
||||
Zeus::CQuaternion m_orientation;
|
||||
public:
|
||||
|
||||
Camera(const Zeus::CVector3f& position, Zeus::EProjType projType=Zeus::EProjType::Perspective,
|
||||
const Zeus::CVector3f& up=Zeus::Math::kUpVec)
|
||||
: m_position(position)
|
||||
{
|
||||
}
|
||||
|
||||
const Zeus::CMatrix4f& projectionMatrix() const { return m_projection.getCachedMatrix(); }
|
||||
const Zeus::CProjection& projection() const { return m_projection; }
|
||||
|
||||
virtual void think()
|
||||
{
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
#endif // URDE_CAMERA_HPP
|
|
@ -1,8 +1,78 @@
|
|||
#ifndef URDE_MODEL_VIEWER_HPP
|
||||
#define URDE_MODEL_VIEWER_HPP
|
||||
|
||||
#include "Space.hpp"
|
||||
#include "ViewManager.hpp"
|
||||
#include "CVector3f.hpp"
|
||||
#include "CProjection.hpp"
|
||||
|
||||
namespace URDE
|
||||
{
|
||||
class ModelViewer : public Space
|
||||
{
|
||||
struct State : Space::State
|
||||
{
|
||||
DECL_YAML
|
||||
enum class Mode
|
||||
{
|
||||
Solid,
|
||||
Material,
|
||||
Wireframe
|
||||
};
|
||||
|
||||
Value<Mode> renderMode = Mode::Material;
|
||||
Value<Zeus::CVector3f> cameraPosition;
|
||||
Value<Zeus::CQuaternion> cameraOrientation;
|
||||
|
||||
} m_state;
|
||||
|
||||
const Space::State& spaceState() const { return m_state; }
|
||||
|
||||
struct View : Specter::View
|
||||
{
|
||||
};
|
||||
|
||||
virtual Specter::View* buildContentView(Specter::ViewResources& res)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
virtual Specter::View* buildSpaceView(Specter::ViewResources& res)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
public:
|
||||
ModelViewer(ViewManager& vm, Space* parent)
|
||||
: Space(vm, Class::ModelViewer, parent)
|
||||
{
|
||||
reloadState();
|
||||
}
|
||||
|
||||
ModelViewer(ViewManager& vm, Space* parent, const ModelViewer& other)
|
||||
: ModelViewer(vm, parent)
|
||||
{
|
||||
m_state = other.m_state;
|
||||
reloadState();
|
||||
}
|
||||
|
||||
ModelViewer(ViewManager& vm, Space* parent, ConfigReader& r)
|
||||
: ModelViewer(vm, parent)
|
||||
{
|
||||
m_state.read(r);
|
||||
reloadState();
|
||||
}
|
||||
|
||||
void reloadState()
|
||||
{}
|
||||
|
||||
Space* copy(Space *parent) const
|
||||
{
|
||||
return new ModelViewer(m_vm, parent, *this);
|
||||
}
|
||||
|
||||
bool usesToolbar() const { return true; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // URDE_MODEL_VIEWER_HPP
|
||||
|
|
|
@ -99,6 +99,9 @@ bool ProjectManager::openProject(const HECL::SystemString& path)
|
|||
m_vm.m_mainWindow->setTitle(m_proj->getProjectRootPath().getLastComponent());
|
||||
m_vm.DismissSplash();
|
||||
m_vm.FadeInEditors();
|
||||
|
||||
m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());
|
||||
|
||||
return true;
|
||||
|
||||
makeDefault:
|
||||
|
@ -164,6 +167,8 @@ bool ProjectManager::saveProject()
|
|||
HECL::Rename(oldSpacesPath.getAbsolutePath().c_str(),
|
||||
newSpacesPath.getAbsolutePath().c_str());
|
||||
|
||||
m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,10 @@ namespace URDE
|
|||
{
|
||||
static LogVisor::LogModule Log("URDE::Space");
|
||||
|
||||
Space::Space(ViewManager& vm, Class cls, Space* parent)
|
||||
: m_spaceMenuNode(*this), m_spaceSelectBind(*this),
|
||||
m_vm(vm), m_class(cls), m_parent(parent) {}
|
||||
|
||||
Specter::View* Space::buildSpaceView(Specter::ViewResources& res)
|
||||
{
|
||||
if (usesToolbar())
|
||||
|
@ -13,7 +17,12 @@ Specter::View* Space::buildSpaceView(Specter::ViewResources& res)
|
|||
m_spaceView.reset(new Specter::Space(res, m_vm.rootView(), *this, Specter::Toolbar::Position::Bottom));
|
||||
Specter::View* sview = buildContentView(res);
|
||||
m_spaceView->setContentView(sview);
|
||||
buildToolbarView(res, *m_spaceView->toolbar());
|
||||
Specter::Toolbar& tb = *m_spaceView->toolbar();
|
||||
const std::string* classStr = SpaceMenuNode::lookupClassString(m_class);
|
||||
m_spaceSelectButton.reset(new Specter::Button(res, tb, &m_spaceSelectBind,
|
||||
classStr?*classStr:"Unknown Class"));
|
||||
tb.push_back(m_spaceSelectButton.get());
|
||||
buildToolbarView(res, tb);
|
||||
return m_spaceView.get();
|
||||
}
|
||||
else
|
||||
|
@ -25,6 +34,25 @@ Specter::View* Space::buildSpaceView(Specter::ViewResources& res)
|
|||
}
|
||||
}
|
||||
|
||||
std::vector<Space::SpaceMenuNode::SubNodeData> Space::SpaceMenuNode::s_subNodeDats =
|
||||
{
|
||||
{Class::ResourceBrowser, "resource_browser", "Resource Browser"}
|
||||
};
|
||||
std::string Space::SpaceMenuNode::s_text = "Space Types";
|
||||
|
||||
void Space::SpaceMenuNode::initializeStrings(ViewManager& vm)
|
||||
{
|
||||
s_text = vm.translateOr("space_types", s_text.c_str());
|
||||
for (SubNodeData& sn : s_subNodeDats)
|
||||
sn.m_text = vm.translateOr(sn.m_key, sn.m_text.c_str());
|
||||
}
|
||||
|
||||
std::unique_ptr<Specter::View> Space::SpaceSelectBind::buildMenu(const Specter::Button* button)
|
||||
{
|
||||
return std::unique_ptr<Specter::View>(new Specter::Menu(m_space.m_vm.rootView().viewRes(),
|
||||
*m_space.m_spaceView, &m_space.m_spaceMenuNode));
|
||||
}
|
||||
|
||||
Specter::View* RootSpace::buildSpaceView(Specter::ViewResources& res)
|
||||
{
|
||||
Specter::View* newRoot = buildContentView(res);
|
||||
|
@ -131,26 +159,22 @@ Space* Space::NewSpaceFromConfigStream(ViewManager& vm, Space* parent, ConfigRea
|
|||
{
|
||||
#ifdef URDE_BINARY_CONFIGS
|
||||
Class cls = Class(r.readUint32Big());
|
||||
return BuildNewSpace(vm, cls, parent, r);
|
||||
#else
|
||||
Class cls = Class(r.readUint32("class"));
|
||||
return BuildNewSpace(vm, cls, parent, r);
|
||||
#endif
|
||||
return BuildNewSpace(vm, cls, parent, r);
|
||||
}
|
||||
|
||||
RootSpace* Space::NewRootSpaceFromConfigStream(ViewManager& vm, ConfigReader& r)
|
||||
{
|
||||
#ifdef URDE_BINARY_CONFIGS
|
||||
Class cls = Class(r.readUint32Big());
|
||||
if (cls != Class::RootSpace)
|
||||
return nullptr;
|
||||
return BuildNewSpace(vm, cls, r);
|
||||
#else
|
||||
Class cls = Class(r.readUint32("class"));
|
||||
#endif
|
||||
if (cls != Class::RootSpace)
|
||||
return nullptr;
|
||||
return new RootSpace(vm, r);
|
||||
#endif
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,12 +32,74 @@ public:
|
|||
SplitSpace,
|
||||
TestSpace,
|
||||
ResourceBrowser,
|
||||
ModelViewer
|
||||
};
|
||||
|
||||
struct State : Athena::io::DNAYaml<Athena::BigEndian> {Delete _d;};
|
||||
static Space* NewSpaceFromConfigStream(ViewManager& vm, Space* parent, ConfigReader& r);
|
||||
static RootSpace* NewRootSpaceFromConfigStream(ViewManager& vm, ConfigReader& r);
|
||||
|
||||
struct SpaceMenuNode : Specter::IMenuNode
|
||||
{
|
||||
struct SubNodeData : Specter::IMenuNode
|
||||
{
|
||||
Class m_cls;
|
||||
std::string m_key;
|
||||
std::string m_text;
|
||||
const std::string* text() const {return &m_text;}
|
||||
void activated(const boo::SWindowCoord& coord) {}
|
||||
|
||||
SubNodeData(Class cls, const char* key, const char* text)
|
||||
: m_cls(cls), m_key(key), m_text(text) {}
|
||||
};
|
||||
static std::vector<SubNodeData> s_subNodeDats;
|
||||
|
||||
struct SubNode : Specter::IMenuNode
|
||||
{
|
||||
Space& m_space;
|
||||
const SubNodeData& m_data;
|
||||
const std::string* text() const {return &m_data.m_text;}
|
||||
void activated(const boo::SWindowCoord& coord) {}
|
||||
|
||||
SubNode(Space& space, const SubNodeData& data) : m_space(space), m_data(data) {}
|
||||
};
|
||||
std::vector<SubNode> m_subNodes;
|
||||
|
||||
SpaceMenuNode(Space& space)
|
||||
{
|
||||
m_subNodes.reserve(s_subNodeDats.size());
|
||||
for (const SubNodeData& sn : s_subNodeDats)
|
||||
m_subNodes.emplace_back(space, sn);
|
||||
}
|
||||
|
||||
static std::string s_text;
|
||||
const std::string* text() const {return &s_text;}
|
||||
|
||||
size_t subNodeCount() const {return m_subNodes.size();}
|
||||
IMenuNode* subNode(size_t idx) {return &m_subNodes[idx];}
|
||||
|
||||
static void initializeStrings(ViewManager& vm);
|
||||
static const std::string* lookupClassString(Class cls)
|
||||
{
|
||||
for (const SubNodeData& sn : s_subNodeDats)
|
||||
if (sn.m_cls == cls)
|
||||
return &sn.m_text;
|
||||
return nullptr;
|
||||
}
|
||||
} m_spaceMenuNode;
|
||||
|
||||
struct SpaceSelectBind : Specter::IButtonBinding
|
||||
{
|
||||
Space& m_space;
|
||||
const char* name(const Specter::Control* control) const {return SpaceMenuNode::s_text.c_str();}
|
||||
|
||||
MenuStyle menuStyle(const Specter::Button* button) const {return MenuStyle::Primary;}
|
||||
std::unique_ptr<Specter::View> buildMenu(const Specter::Button* button);
|
||||
|
||||
SpaceSelectBind(Space& space) : m_space(space) {}
|
||||
} m_spaceSelectBind;
|
||||
std::unique_ptr<Specter::Button> m_spaceSelectButton;
|
||||
|
||||
protected:
|
||||
friend class ViewManager;
|
||||
friend class RootSpace;
|
||||
|
@ -45,7 +107,7 @@ protected:
|
|||
Class m_class = Class::None;
|
||||
Space* m_parent;
|
||||
std::unique_ptr<Specter::Space> m_spaceView;
|
||||
Space(ViewManager& vm, Class cls, Space* parent) : m_vm(vm), m_class(cls), m_parent(parent) {}
|
||||
Space(ViewManager& vm, Class cls, Space* parent);
|
||||
|
||||
/* Allows common Space code to access DNA-encoded state */
|
||||
virtual const Space::State& spaceState() const=0;
|
||||
|
@ -88,7 +150,7 @@ public:
|
|||
{
|
||||
m_state.read(r);
|
||||
#ifdef URDE_BINARY_CONFIGS
|
||||
m_child.reset(NewSpaceFromConfigStream(vm, this, r));
|
||||
m_spaceTree.reset(NewSpaceFromConfigStream(vm, this, r));
|
||||
#else
|
||||
r.enterSubRecord("spaceTree");
|
||||
m_spaceTree.reset(NewSpaceFromConfigStream(vm, this, r));
|
||||
|
|
|
@ -24,10 +24,6 @@ SplashScreen::SplashScreen(ViewManager& vm, Specter::ViewResources& res)
|
|||
m_vm(vm),
|
||||
m_textColor(res.themeData().uiText()),
|
||||
m_textColorClear(m_textColor),
|
||||
m_buildInfoStr(HECL::Format("%s: %s\n%s: %s\n%s: %s",
|
||||
vm.translateOr("branch", "Branch").c_str(), GIT_BRANCH,
|
||||
vm.translateOr("commit", "Commit").c_str(), GIT_COMMIT_HASH,
|
||||
vm.translateOr("date", "Date").c_str(), GIT_COMMIT_DATE)),
|
||||
m_newString(m_vm.translateOr("new_project", "New Project")),
|
||||
m_newProjBind(*this),
|
||||
m_openString(m_vm.translateOr("open_project", "Open Project")),
|
||||
|
@ -35,6 +31,16 @@ SplashScreen::SplashScreen(ViewManager& vm, Specter::ViewResources& res)
|
|||
m_extractString(m_vm.translateOr("extract_game", "Extract Game")),
|
||||
m_extractProjBind(*this)
|
||||
{
|
||||
if (GIT_COMMIT_DATE[0] != '\0' &&
|
||||
GIT_COMMIT_HASH[0] != '\0' &&
|
||||
GIT_BRANCH[0] != '\0')
|
||||
{
|
||||
m_buildInfoStr = HECL::Format("%s: %s\n%s: %s\n%s: %s",
|
||||
vm.translateOr("branch", "Branch").c_str(), GIT_BRANCH,
|
||||
vm.translateOr("commit", "Commit").c_str(), GIT_COMMIT_HASH,
|
||||
vm.translateOr("date", "Date").c_str(), GIT_COMMIT_DATE);
|
||||
}
|
||||
|
||||
m_openProjBind.m_openRecentMenuRoot.m_text = vm.translateOr("recent_projects", "Recent Projects");
|
||||
m_textColorClear[3] = 0.0;
|
||||
commitResources(res);
|
||||
|
@ -53,6 +59,9 @@ void SplashScreen::think()
|
|||
if (m_fileBrowser.m_view)
|
||||
m_fileBrowser.m_view->think();
|
||||
|
||||
if (m_openButt.m_view)
|
||||
m_openButt.m_view->think();
|
||||
|
||||
if (m_newProjBind.m_deferPath.size())
|
||||
{
|
||||
Log.report(LogVisor::Info, _S("Making project '%s'"), m_newProjBind.m_deferPath.c_str());
|
||||
|
@ -88,11 +97,11 @@ void SplashScreen::updateContentOpacity(float opacity)
|
|||
m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor);
|
||||
|
||||
m_newButt.m_view.reset(new Specter::Button(res, *this, &m_newProjBind, m_newString,
|
||||
Specter::Button::Style::Text));
|
||||
nullptr, Specter::Button::Style::Text));
|
||||
m_openButt.m_view.reset(new Specter::Button(res, *this, &m_openProjBind, m_openString,
|
||||
Specter::Button::Style::Text));
|
||||
nullptr, Specter::Button::Style::Text));
|
||||
m_extractButt.m_view.reset(new Specter::Button(res, *this, &m_extractProjBind, m_extractString,
|
||||
Specter::Button::Style::Text));
|
||||
nullptr, Specter::Button::Style::Text));
|
||||
|
||||
updateSize();
|
||||
}
|
||||
|
|
|
@ -93,7 +93,11 @@ class SplashScreen : public Specter::ModalWindow
|
|||
std::string m_text;
|
||||
|
||||
const std::string* text() const {return &m_text;}
|
||||
void activated() {m_parent.m_openProjBind.m_deferPath = m_path;}
|
||||
void activated(const boo::SWindowCoord& coord)
|
||||
{
|
||||
m_parent.m_openProjBind.m_deferPath = m_path;
|
||||
m_parent.m_openProjBind.m_splash.m_openButt.m_view->closeMenu(coord);
|
||||
}
|
||||
|
||||
OpenRecentMenuItem(OpenRecentMenuRoot& parent, const HECL::SystemString& path)
|
||||
: m_parent(parent), m_path(path)
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "SplashScreen.hpp"
|
||||
#include "locale/locale.hpp"
|
||||
#include "ResourceBrowser.hpp"
|
||||
#include <cstdio>
|
||||
|
||||
using YAMLNode = Athena::io::YAMLNode;
|
||||
|
||||
|
@ -36,7 +37,6 @@ void ViewManager::RootSpaceViewBuilt(Specter::View *view)
|
|||
std::vector<Specter::View*>& cViews = m_rootView->accessContentViews();
|
||||
cViews.clear();
|
||||
cViews.push_back(view);
|
||||
printf("RootView Set: %p [%p]\n\n", m_rootView.get(), view);
|
||||
cViews.push_back(m_splash.get());
|
||||
m_rootView->updateSize();
|
||||
}
|
||||
|
@ -76,20 +76,77 @@ void ViewManager::DismissSplash()
|
|||
|
||||
ViewManager::ViewManager(HECL::Runtime::FileStoreManager& fileMgr, HECL::CVarManager& cvarMgr)
|
||||
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
|
||||
m_fontCache(fileMgr), m_translator(URDE::SystemLocaleOrEnglish())
|
||||
{}
|
||||
m_fontCache(fileMgr), m_translator(URDE::SystemLocaleOrEnglish()),
|
||||
m_recentProjectsPath(HECL::SysFormat(_S("%s/recent_projects.txt"), fileMgr.getStoreRoot().c_str())),
|
||||
m_recentFilesPath(HECL::SysFormat(_S("%s/recent_files.txt"), fileMgr.getStoreRoot().c_str()))
|
||||
{
|
||||
Space::SpaceMenuNode::initializeStrings(*this);
|
||||
char path[2048];
|
||||
HECL::Sstat theStat;
|
||||
|
||||
FILE* fp = HECL::Fopen(m_recentProjectsPath.c_str(), _S("r"), HECL::FileLockType::Read);
|
||||
if (fp)
|
||||
{
|
||||
while (fgets(path, 2048, fp))
|
||||
{
|
||||
std::string pathStr(path);
|
||||
pathStr.pop_back();
|
||||
HECL::SystemStringView pathStrView(pathStr);
|
||||
if (!HECL::Stat(pathStrView.c_str(), &theStat) && S_ISDIR(theStat.st_mode))
|
||||
m_recentProjects.push_back(pathStrView);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
fp = HECL::Fopen(m_recentFilesPath.c_str(), _S("r"), HECL::FileLockType::Read);
|
||||
if (fp)
|
||||
{
|
||||
while (fgets(path, 2048, fp))
|
||||
{
|
||||
std::string pathStr(path);
|
||||
pathStr.pop_back();
|
||||
HECL::SystemStringView pathStrView(pathStr);
|
||||
if (!HECL::Stat(pathStrView.c_str(), &theStat) && S_ISDIR(theStat.st_mode))
|
||||
m_recentFiles.push_back(pathStrView);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
ViewManager::~ViewManager() {}
|
||||
|
||||
void ViewManager::pushRecentProject(const HECL::SystemString& path)
|
||||
{
|
||||
for (HECL::SystemString& testPath : m_recentProjects)
|
||||
{
|
||||
if (path == testPath)
|
||||
return;
|
||||
}
|
||||
m_recentProjects.push_back(path);
|
||||
FILE* fp = HECL::Fopen(m_recentProjectsPath.c_str(), _S("w"), HECL::FileLockType::Write);
|
||||
if (fp)
|
||||
{
|
||||
for (HECL::SystemString& pPath : m_recentProjects)
|
||||
fprintf(fp, "%s\n", HECL::SystemUTF8View(pPath).c_str());
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
||||
void ViewManager::pushRecentFile(const HECL::SystemString& path)
|
||||
{
|
||||
m_recentFiles.push_back(path);
|
||||
for (HECL::SystemString& testPath : m_recentFiles)
|
||||
{
|
||||
if (path == testPath)
|
||||
return;
|
||||
}
|
||||
m_recentFiles.push_back(path);
|
||||
FILE* fp = HECL::Fopen(m_recentFilesPath.c_str(), _S("w"), HECL::FileLockType::Write);
|
||||
if (fp)
|
||||
{
|
||||
for (HECL::SystemString& pPath : m_recentFiles)
|
||||
fprintf(fp, "%s\n", HECL::SystemUTF8View(pPath).c_str());
|
||||
fclose(fp);
|
||||
}}
|
||||
|
||||
void ViewManager::init(boo::IApplication* app)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,9 @@ class ViewManager : public Specter::IViewManager
|
|||
std::unique_ptr<RootSpace> m_rootSpace;
|
||||
Specter::View* m_rootSpaceView = nullptr;
|
||||
|
||||
HECL::SystemString m_recentProjectsPath;
|
||||
std::vector<HECL::SystemString> m_recentProjects;
|
||||
HECL::SystemString m_recentFilesPath;
|
||||
std::vector<HECL::SystemString> m_recentFiles;
|
||||
|
||||
bool m_updatePf = false;
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
cmake_policy(SET CMP0053 OLD)
|
||||
|
||||
include_directories(${LIBPNG_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
|
||||
add_executable(packicons packicons.c)
|
||||
target_link_libraries(packicons ${PNG_LIB} ${ZLIB_LIBRARIES})
|
||||
|
||||
unset(INKSCAPE_BIN CACHE)
|
||||
set(CMAKE_FIND_APPBUNDLE "NEVER")
|
||||
if(WIN32)
|
||||
find_program(INKSCAPE_BIN inkscape.exe PATHS
|
||||
"$ENV{PROGRAMFILES}/Inkscape"
|
||||
"$ENV{ProgramW6432}/Inkscape"
|
||||
"$ENV{PROGRAMFILES(X86)}/Inkscape")
|
||||
else()
|
||||
find_program(INKSCAPE_BIN inkscape)
|
||||
endif()
|
||||
if(INKSCAPE_BIN STREQUAL "INKSCAPE_BIN-NOTFOUND")
|
||||
message(STATUS "Inkscape not found; downloading icons")
|
||||
file(DOWNLOAD "https://www.dropbox.com/s/wnj17dwgcsky0o9/icons.bin"
|
||||
${CMAKE_CURRENT_BINARY_DIR}/icons.bin SHOW_PROGRESS)
|
||||
else()
|
||||
message(STATUS "Inkscape found; will render icons locally")
|
||||
add_custom_command(OUTPUT icons.bin COMMAND $<TARGET_FILE:packicons>
|
||||
ARGS ${INKSCAPE_BIN} ${CMAKE_CURRENT_SOURCE_DIR}/icons.svg
|
||||
${CMAKE_CURRENT_BINARY_DIR}/icons.bin
|
||||
MAIN_DEPENDENCY icons.svg COMMENT "Generating icons.bin")
|
||||
endif()
|
||||
|
||||
bintoc(icons.c ${CMAKE_CURRENT_BINARY_DIR}/icons.bin URDE_ICONS)
|
||||
add_library(UrdeIcons icons.cpp icons.hpp icons.bin icons.c)
|
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 37 KiB |
|
@ -0,0 +1,329 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <zlib.h>
|
||||
#include <png.h>
|
||||
|
||||
#if _WIN32
|
||||
#define htonl(v) _byteswap_ulong(v)
|
||||
#define htons(v) _byteswap_ushort(v)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
static int CountBits(uint32_t n)
|
||||
{
|
||||
int ret = 0;
|
||||
for (int i=0 ; i<32 ; ++i)
|
||||
if (((n >> i) & 1) != 0)
|
||||
++ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
if (argc < 4)
|
||||
{
|
||||
fprintf(stderr, "Usage: packicons <inkscape-bin> <in.svg> <out.bin>\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Validate inkscape */
|
||||
char command[2048];
|
||||
FILE* fp;
|
||||
|
||||
#if _WIN32
|
||||
STARTUPINFOA sinfo = {sizeof(STARTUPINFOA)};
|
||||
|
||||
HANDLE hChildStd_OUT_Rd = NULL;
|
||||
HANDLE hChildStd_OUT_Wr = NULL;
|
||||
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
// Create a pipe for the child process's STDOUT.
|
||||
if (!CreatePipe(&hChildStd_OUT_Rd, &hChildStd_OUT_Wr, &saAttr, 0))
|
||||
{
|
||||
fprintf(stderr, "unable to CreatePipe\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Ensure the read handle to the pipe for STDOUT is not inherited
|
||||
if (!SetHandleInformation(hChildStd_OUT_Rd, HANDLE_FLAG_INHERIT, 0))
|
||||
{
|
||||
fprintf(stderr, "unable to SetHandleInformation\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sinfo.hStdError = hChildStd_OUT_Wr;
|
||||
sinfo.hStdOutput = hChildStd_OUT_Wr;
|
||||
sinfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||
|
||||
PROCESS_INFORMATION pinfo;
|
||||
if (!CreateProcessA(argv[1], " --version", NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo))
|
||||
{
|
||||
LPSTR messageBuffer = NULL;
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||
fprintf(stderr, "unable to launch inkscape from %s: %s\n", argv[1], messageBuffer);
|
||||
return 1;
|
||||
}
|
||||
CloseHandle(hChildStd_OUT_Wr);
|
||||
CloseHandle(pinfo.hThread);
|
||||
|
||||
char readback[8];
|
||||
DWORD bytesRead = 0;
|
||||
if (!ReadFile(hChildStd_OUT_Rd, readback, 8, &bytesRead, NULL) || bytesRead != 8 ||
|
||||
strncmp(readback, "Inkscape", 8))
|
||||
{
|
||||
fprintf(stderr, "'%s' did not return expected \"Inkscape\"\n", command);
|
||||
CloseHandle(hChildStd_OUT_Rd);
|
||||
CloseHandle(pinfo.hProcess);
|
||||
return 1;
|
||||
}
|
||||
CloseHandle(hChildStd_OUT_Rd);
|
||||
WaitForSingleObject(pinfo.hProcess, INFINITE);
|
||||
CloseHandle(pinfo.hProcess);
|
||||
|
||||
#else
|
||||
snprintf(command, 2048, "%s --version", argv[1]);
|
||||
fp = popen(command, "r");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not executable on this system\n", command);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char readback[8];
|
||||
if (fread(readback, 1, 8, fp) != 8 || strncmp(readback, "Inkscape", 8))
|
||||
{
|
||||
fprintf(stderr, "'%s' did not return expected \"Inkscape\"\n", command);
|
||||
pclose(fp);
|
||||
return 1;
|
||||
}
|
||||
pclose(fp);
|
||||
|
||||
#endif
|
||||
|
||||
/* Validate input */
|
||||
fp = fopen(argv[2], "rb");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not able to be opened for reading as a regular file\n", argv[2]);
|
||||
return 1;
|
||||
}
|
||||
fclose(fp);
|
||||
|
||||
#ifdef _WIN32
|
||||
char* TMPDIR = getenv("TEMP");
|
||||
if (!TMPDIR)
|
||||
TMPDIR = (char*)"\\Temp";
|
||||
#else
|
||||
char* TMPDIR = getenv("TMPDIR");
|
||||
if (!TMPDIR)
|
||||
TMPDIR = (char*)"/tmp";
|
||||
#endif
|
||||
|
||||
FILE* ofp = fopen(argv[3], "wb");
|
||||
if (!ofp)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not able to be opened for writing as a regular file\n", argv[3]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int numMips = 0;
|
||||
for (int i=512 ; i>=1 ; i/=2)
|
||||
++numMips;
|
||||
|
||||
z_stream z = {0};
|
||||
size_t rowSz = 0;
|
||||
uLong rowSzC = 0;
|
||||
png_bytep row;
|
||||
png_bytep rowC;
|
||||
|
||||
for (int i=512 ; i>=1 ; i/=2)
|
||||
{
|
||||
printf("Rendering icons @%dx%d\n", i, i);
|
||||
fflush(stdout);
|
||||
|
||||
#if _WIN32
|
||||
snprintf(command, 2048, " --export-png=\"%s/icon_pack.png\" --export-width=%d --export-height=%d \"%s\"",
|
||||
TMPDIR, i, i, argv[2]);
|
||||
|
||||
STARTUPINFOA sinfo = {sizeof(STARTUPINFOA)};
|
||||
PROCESS_INFORMATION pinfo;
|
||||
if (!CreateProcessA(argv[1], command, NULL, NULL, TRUE, NORMAL_PRIORITY_CLASS, NULL, NULL, &sinfo, &pinfo))
|
||||
{
|
||||
LPSTR messageBuffer = NULL;
|
||||
FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
|
||||
fprintf(stderr, "unable to launch inkscape from %s: %s\n", argv[1], messageBuffer);
|
||||
return 1;
|
||||
}
|
||||
CloseHandle(pinfo.hThread);
|
||||
WaitForSingleObject(pinfo.hProcess, INFINITE);
|
||||
CloseHandle(pinfo.hProcess);
|
||||
|
||||
#else
|
||||
snprintf(command, 2048, "%s --export-png=\"%s/icon_pack.png\" --export-width=%d --export-height=%d \"%s\"",
|
||||
argv[1], TMPDIR, i, i, argv[2]);
|
||||
fp = popen(command, "r");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not executable on this system\n", command);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
int status = pclose(fp);
|
||||
if (WEXITSTATUS(status))
|
||||
{
|
||||
fprintf(stderr, "'%s' failed\n", command);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Get PNG data */
|
||||
snprintf(command, 2048, "%s/icon_pack.png", TMPDIR);
|
||||
fp = fopen(command, "rb");
|
||||
if (!fp)
|
||||
{
|
||||
fprintf(stderr, "unable to open '%s' for reading\n", command);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char header[8];
|
||||
fread(header, 1, 8, fp);
|
||||
if (png_sig_cmp((png_const_bytep)header, 0, 8))
|
||||
{
|
||||
fprintf(stderr, "invalid PNG signature in '%s'\n", command);
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
png_structp pngRead = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
|
||||
if (!pngRead)
|
||||
{
|
||||
fprintf(stderr, "unable to initialize libpng\n");
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
png_infop info = png_create_info_struct(pngRead);
|
||||
if (!info)
|
||||
{
|
||||
fprintf(stderr, "unable to initialize libpng info\n");
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(pngRead)))
|
||||
{
|
||||
fprintf(stderr, "unable to initialize libpng I/O for '%s'\n", command);
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
png_init_io(pngRead, fp);
|
||||
png_set_sig_bytes(pngRead, 8);
|
||||
|
||||
png_read_info(pngRead, info);
|
||||
|
||||
png_uint_32 width = png_get_image_width(pngRead, info);
|
||||
png_uint_32 height = png_get_image_height(pngRead, info);
|
||||
png_byte colorType = png_get_color_type(pngRead, info);
|
||||
png_byte bitDepth = png_get_bit_depth(pngRead, info);
|
||||
|
||||
if (CountBits(width) != 1 || CountBits(height) != 1)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not power-of-2 in one or both dimensions\n", command);
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not in RGBA color mode\n", command);
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (bitDepth != 8)
|
||||
{
|
||||
fprintf(stderr, "'%s' is not 8 bits-per-channel\n", command);
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (setjmp(png_jmpbuf(pngRead)))
|
||||
{
|
||||
fprintf(stderr, "unable to read image in '%s'\n", command);
|
||||
fclose(fp);
|
||||
fclose(ofp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (i == 512)
|
||||
{
|
||||
uint32_t fmt = htonl(16);
|
||||
uint16_t w = htons(width);
|
||||
uint16_t h = htons(height);
|
||||
uint32_t mips = htonl(numMips);
|
||||
fwrite(&fmt, 1, 4, ofp);
|
||||
fwrite(&w, 1, 2, ofp);
|
||||
fwrite(&h, 1, 2, ofp);
|
||||
fwrite(&mips, 1, 4, ofp);
|
||||
|
||||
rowSz = width*4;
|
||||
rowSzC = compressBound(rowSz);
|
||||
deflateInit(&z, Z_DEFAULT_COMPRESSION);
|
||||
row = malloc(rowSz);
|
||||
rowC = malloc(rowSzC);
|
||||
}
|
||||
|
||||
for (png_uint_32 r=0 ; r<height ; ++r)
|
||||
{
|
||||
png_read_row(pngRead, row, NULL);
|
||||
z.next_in = row;
|
||||
z.avail_in = rowSz;
|
||||
z.next_out = rowC;
|
||||
z.avail_out = rowSzC;
|
||||
z.total_out = 0;
|
||||
deflate(&z, Z_NO_FLUSH);
|
||||
fwrite(rowC, 1, z.total_out, ofp);
|
||||
}
|
||||
rowSz /= 2;
|
||||
|
||||
png_destroy_read_struct(&pngRead, &info, NULL);
|
||||
fclose(fp);
|
||||
}
|
||||
|
||||
if (rowSzC)
|
||||
{
|
||||
int finishCycle = Z_OK;
|
||||
while (finishCycle != Z_STREAM_END)
|
||||
{
|
||||
z.next_out = rowC;
|
||||
z.avail_out = rowSzC;
|
||||
z.total_out = 0;
|
||||
finishCycle = deflate(&z, Z_FINISH);
|
||||
fwrite(rowC, 1, z.total_out, ofp);
|
||||
}
|
||||
deflateEnd(&z);
|
||||
free(row);
|
||||
free(rowC);
|
||||
}
|
||||
|
||||
fclose(ofp);
|
||||
return 0;
|
||||
}
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit 5d0c80b9e603ecb2762b281d8736d21a324c3e76
|
||||
Subproject commit 7978e31e6fbbbd45915c2684ee0fb1a376020255
|
|
@ -1 +1 @@
|
|||
Subproject commit 2490aa3bb82860fa2969d2cc797324d846e3b51c
|
||||
Subproject commit cd54225b2af5cd2978b0ad3fab10561693fc54b2
|
Loading…
Reference in New Issue