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
|
version.h
|
||||||
*.user
|
*.user
|
||||||
|
.DS_Store
|
||||||
|
|
|
@ -4,12 +4,29 @@ project(PathShagged)
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# Shaddup 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)
|
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()
|
else()
|
||||||
if (CMAKE_COMPILER_IS_GNUCXX)
|
if (CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fpermissive")
|
||||||
message(WARNING "GCC needs -fpermissive for nested type redeclarations; expect lotsa warnings!!")
|
message(WARNING "GCC needs -fpermissive for nested type redeclarations; expect lotsa warnings!!")
|
||||||
endif()
|
endif()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wno-multichar -fno-exceptions")
|
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()
|
endif()
|
||||||
|
|
||||||
if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
|
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[0], add1.inputs[1])
|
||||||
new_grp.links.new(grp_in.outputs[2], add1.inputs[2])
|
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(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
|
grp_out.inputs[1].default_value = 1.0
|
||||||
|
|
||||||
# Reflection Map
|
# Reflection Map
|
||||||
|
|
|
@ -64,13 +64,13 @@ void MaterialSet::ConstructMaterial(Stream& out,
|
||||||
|
|
||||||
|
|
||||||
/* Blend factors */
|
/* Blend factors */
|
||||||
if (material.header.flags.additiveBlending())
|
if (material.header.flags.alphaBlending())
|
||||||
out << "new_material.game_settings.alpha_blend = 'ADD'\n"
|
out << "new_material.game_settings.alpha_blend = 'ALPHA'\n"
|
||||||
"new_material.use_transparency = True\n"
|
"new_material.use_transparency = True\n"
|
||||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||||
"new_material.alpha = 1.0\n";
|
"new_material.alpha = 1.0\n";
|
||||||
else if (material.header.flags.alphaBlending())
|
else if (material.header.flags.additiveBlending())
|
||||||
out << "new_material.game_settings.alpha_blend = 'ALPHA'\n"
|
out << "new_material.game_settings.alpha_blend = 'ADD'\n"
|
||||||
"new_material.use_transparency = True\n"
|
"new_material.use_transparency = True\n"
|
||||||
"new_material.transparency_method = 'RAYTRACE'\n"
|
"new_material.transparency_method = 'RAYTRACE'\n"
|
||||||
"new_material.alpha = 1.0\n";
|
"new_material.alpha = 1.0\n";
|
||||||
|
@ -78,6 +78,7 @@ void MaterialSet::ConstructMaterial(Stream& out,
|
||||||
/* Texmap list */
|
/* Texmap list */
|
||||||
out << "tex_maps = []\n"
|
out << "tex_maps = []\n"
|
||||||
"pnode = None\n"
|
"pnode = None\n"
|
||||||
|
"anode = None\n"
|
||||||
"rflv_tex_node = None\n";
|
"rflv_tex_node = None\n";
|
||||||
|
|
||||||
/* Add PASSes */
|
/* Add PASSes */
|
||||||
|
@ -97,9 +98,13 @@ void MaterialSet::ConstructMaterial(Stream& out,
|
||||||
/* Connect final PASS */
|
/* Connect final PASS */
|
||||||
out << "if pnode:\n"
|
out << "if pnode:\n"
|
||||||
" new_nodetree.links.new(pnode.outputs['Next Color'], final_node.inputs['Color'])\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"
|
"else:\n"
|
||||||
" new_nodetree.links.new(kcolor_nodes[-1][0].outputs[0], final_node.inputs['Color'])\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";
|
" 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()))
|
switch (Subtype(subtype.toUint32()))
|
||||||
{
|
{
|
||||||
case Subtype::OPAC:
|
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;
|
break;
|
||||||
case Subtype::BLOD:
|
case Subtype::BLOD:
|
||||||
out.format("new_material.retro_blod = %d\n", value);
|
out.format("new_material.retro_blod = %d\n", value);
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
add_subdirectory(locale)
|
add_subdirectory(locale)
|
||||||
|
add_subdirectory(icons)
|
||||||
|
|
||||||
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
|
||||||
option(RUDE_BINARY_CONFIGS
|
option(RUDE_BINARY_CONFIGS
|
||||||
|
@ -17,18 +18,21 @@ endif()
|
||||||
|
|
||||||
atdna(atdna_Space.cpp Space.hpp)
|
atdna(atdna_Space.cpp Space.hpp)
|
||||||
atdna(atdna_ResourceBrowser.cpp ResourceBrowser.hpp)
|
atdna(atdna_ResourceBrowser.cpp ResourceBrowser.hpp)
|
||||||
|
atdna(atdna_ModelViewer.cpp ModelViewer.hpp)
|
||||||
|
|
||||||
add_executable(urde WIN32
|
add_executable(urde WIN32
|
||||||
main.cpp
|
main.cpp
|
||||||
Space.hpp Space.cpp atdna_Space.cpp
|
Space.hpp Space.cpp atdna_Space.cpp
|
||||||
SplashScreen.hpp SplashScreen.cpp
|
SplashScreen.hpp SplashScreen.cpp
|
||||||
ResourceBrowser.hpp ResourceBrowser.cpp atdna_ResourceBrowser.cpp
|
ResourceBrowser.hpp ResourceBrowser.cpp atdna_ResourceBrowser.cpp
|
||||||
ModelViewer.hpp ModelViewer.cpp
|
ModelViewer.hpp ModelViewer.cpp atdna_ModelViewer.cpp
|
||||||
ProjectManager.hpp ProjectManager.cpp
|
ProjectManager.hpp ProjectManager.cpp
|
||||||
ViewManager.hpp ViewManager.cpp)
|
ViewManager.hpp ViewManager.cpp
|
||||||
|
Camera.hpp Camera.cpp)
|
||||||
|
|
||||||
target_link_libraries(urde
|
target_link_libraries(urde
|
||||||
UrdeLocales
|
UrdeLocales
|
||||||
|
UrdeIcons
|
||||||
RuntimeCommonCharacter
|
RuntimeCommonCharacter
|
||||||
RuntimeCommonInput
|
RuntimeCommonInput
|
||||||
RuntimeCommon
|
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
|
#ifndef URDE_MODEL_VIEWER_HPP
|
||||||
#define URDE_MODEL_VIEWER_HPP
|
#define URDE_MODEL_VIEWER_HPP
|
||||||
|
|
||||||
|
#include "Space.hpp"
|
||||||
|
#include "ViewManager.hpp"
|
||||||
|
#include "CVector3f.hpp"
|
||||||
|
#include "CProjection.hpp"
|
||||||
|
|
||||||
namespace URDE
|
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
|
#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.m_mainWindow->setTitle(m_proj->getProjectRootPath().getLastComponent());
|
||||||
m_vm.DismissSplash();
|
m_vm.DismissSplash();
|
||||||
m_vm.FadeInEditors();
|
m_vm.FadeInEditors();
|
||||||
|
|
||||||
|
m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
makeDefault:
|
makeDefault:
|
||||||
|
@ -164,6 +167,8 @@ bool ProjectManager::saveProject()
|
||||||
HECL::Rename(oldSpacesPath.getAbsolutePath().c_str(),
|
HECL::Rename(oldSpacesPath.getAbsolutePath().c_str(),
|
||||||
newSpacesPath.getAbsolutePath().c_str());
|
newSpacesPath.getAbsolutePath().c_str());
|
||||||
|
|
||||||
|
m_vm.pushRecentProject(m_proj->getProjectRootPath().getAbsolutePath());
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,10 @@ namespace URDE
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("URDE::Space");
|
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)
|
Specter::View* Space::buildSpaceView(Specter::ViewResources& res)
|
||||||
{
|
{
|
||||||
if (usesToolbar())
|
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));
|
m_spaceView.reset(new Specter::Space(res, m_vm.rootView(), *this, Specter::Toolbar::Position::Bottom));
|
||||||
Specter::View* sview = buildContentView(res);
|
Specter::View* sview = buildContentView(res);
|
||||||
m_spaceView->setContentView(sview);
|
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();
|
return m_spaceView.get();
|
||||||
}
|
}
|
||||||
else
|
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* RootSpace::buildSpaceView(Specter::ViewResources& res)
|
||||||
{
|
{
|
||||||
Specter::View* newRoot = buildContentView(res);
|
Specter::View* newRoot = buildContentView(res);
|
||||||
|
@ -131,26 +159,22 @@ Space* Space::NewSpaceFromConfigStream(ViewManager& vm, Space* parent, ConfigRea
|
||||||
{
|
{
|
||||||
#ifdef URDE_BINARY_CONFIGS
|
#ifdef URDE_BINARY_CONFIGS
|
||||||
Class cls = Class(r.readUint32Big());
|
Class cls = Class(r.readUint32Big());
|
||||||
return BuildNewSpace(vm, cls, parent, r);
|
|
||||||
#else
|
#else
|
||||||
Class cls = Class(r.readUint32("class"));
|
Class cls = Class(r.readUint32("class"));
|
||||||
return BuildNewSpace(vm, cls, parent, r);
|
|
||||||
#endif
|
#endif
|
||||||
|
return BuildNewSpace(vm, cls, parent, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
RootSpace* Space::NewRootSpaceFromConfigStream(ViewManager& vm, ConfigReader& r)
|
RootSpace* Space::NewRootSpaceFromConfigStream(ViewManager& vm, ConfigReader& r)
|
||||||
{
|
{
|
||||||
#ifdef URDE_BINARY_CONFIGS
|
#ifdef URDE_BINARY_CONFIGS
|
||||||
Class cls = Class(r.readUint32Big());
|
Class cls = Class(r.readUint32Big());
|
||||||
if (cls != Class::RootSpace)
|
|
||||||
return nullptr;
|
|
||||||
return BuildNewSpace(vm, cls, r);
|
|
||||||
#else
|
#else
|
||||||
Class cls = Class(r.readUint32("class"));
|
Class cls = Class(r.readUint32("class"));
|
||||||
|
#endif
|
||||||
if (cls != Class::RootSpace)
|
if (cls != Class::RootSpace)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
return new RootSpace(vm, r);
|
return new RootSpace(vm, r);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,12 +32,74 @@ public:
|
||||||
SplitSpace,
|
SplitSpace,
|
||||||
TestSpace,
|
TestSpace,
|
||||||
ResourceBrowser,
|
ResourceBrowser,
|
||||||
|
ModelViewer
|
||||||
};
|
};
|
||||||
|
|
||||||
struct State : Athena::io::DNAYaml<Athena::BigEndian> {Delete _d;};
|
struct State : Athena::io::DNAYaml<Athena::BigEndian> {Delete _d;};
|
||||||
static Space* NewSpaceFromConfigStream(ViewManager& vm, Space* parent, ConfigReader& r);
|
static Space* NewSpaceFromConfigStream(ViewManager& vm, Space* parent, ConfigReader& r);
|
||||||
static RootSpace* NewRootSpaceFromConfigStream(ViewManager& vm, 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:
|
protected:
|
||||||
friend class ViewManager;
|
friend class ViewManager;
|
||||||
friend class RootSpace;
|
friend class RootSpace;
|
||||||
|
@ -45,7 +107,7 @@ protected:
|
||||||
Class m_class = Class::None;
|
Class m_class = Class::None;
|
||||||
Space* m_parent;
|
Space* m_parent;
|
||||||
std::unique_ptr<Specter::Space> m_spaceView;
|
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 */
|
/* Allows common Space code to access DNA-encoded state */
|
||||||
virtual const Space::State& spaceState() const=0;
|
virtual const Space::State& spaceState() const=0;
|
||||||
|
@ -88,7 +150,7 @@ public:
|
||||||
{
|
{
|
||||||
m_state.read(r);
|
m_state.read(r);
|
||||||
#ifdef URDE_BINARY_CONFIGS
|
#ifdef URDE_BINARY_CONFIGS
|
||||||
m_child.reset(NewSpaceFromConfigStream(vm, this, r));
|
m_spaceTree.reset(NewSpaceFromConfigStream(vm, this, r));
|
||||||
#else
|
#else
|
||||||
r.enterSubRecord("spaceTree");
|
r.enterSubRecord("spaceTree");
|
||||||
m_spaceTree.reset(NewSpaceFromConfigStream(vm, this, r));
|
m_spaceTree.reset(NewSpaceFromConfigStream(vm, this, r));
|
||||||
|
|
|
@ -24,10 +24,6 @@ SplashScreen::SplashScreen(ViewManager& vm, Specter::ViewResources& res)
|
||||||
m_vm(vm),
|
m_vm(vm),
|
||||||
m_textColor(res.themeData().uiText()),
|
m_textColor(res.themeData().uiText()),
|
||||||
m_textColorClear(m_textColor),
|
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_newString(m_vm.translateOr("new_project", "New Project")),
|
||||||
m_newProjBind(*this),
|
m_newProjBind(*this),
|
||||||
m_openString(m_vm.translateOr("open_project", "Open Project")),
|
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_extractString(m_vm.translateOr("extract_game", "Extract Game")),
|
||||||
m_extractProjBind(*this)
|
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_openProjBind.m_openRecentMenuRoot.m_text = vm.translateOr("recent_projects", "Recent Projects");
|
||||||
m_textColorClear[3] = 0.0;
|
m_textColorClear[3] = 0.0;
|
||||||
commitResources(res);
|
commitResources(res);
|
||||||
|
@ -53,6 +59,9 @@ void SplashScreen::think()
|
||||||
if (m_fileBrowser.m_view)
|
if (m_fileBrowser.m_view)
|
||||||
m_fileBrowser.m_view->think();
|
m_fileBrowser.m_view->think();
|
||||||
|
|
||||||
|
if (m_openButt.m_view)
|
||||||
|
m_openButt.m_view->think();
|
||||||
|
|
||||||
if (m_newProjBind.m_deferPath.size())
|
if (m_newProjBind.m_deferPath.size())
|
||||||
{
|
{
|
||||||
Log.report(LogVisor::Info, _S("Making project '%s'"), m_newProjBind.m_deferPath.c_str());
|
Log.report(LogVisor::Info, _S("Making project '%s'"), m_newProjBind.m_deferPath.c_str());
|
||||||
|
@ -78,7 +87,7 @@ void SplashScreen::updateContentOpacity(float opacity)
|
||||||
Specter::ViewResources& res = rootView().viewRes();
|
Specter::ViewResources& res = rootView().viewRes();
|
||||||
|
|
||||||
if (!m_title && res.fontCacheReady())
|
if (!m_title && res.fontCacheReady())
|
||||||
{
|
{
|
||||||
m_title.reset(new Specter::TextView(res, *this, res.m_titleFont));
|
m_title.reset(new Specter::TextView(res, *this, res.m_titleFont));
|
||||||
Zeus::CColor clearColor = res.themeData().uiText();
|
Zeus::CColor clearColor = res.themeData().uiText();
|
||||||
clearColor[3] = 0.0;
|
clearColor[3] = 0.0;
|
||||||
|
@ -88,11 +97,11 @@ void SplashScreen::updateContentOpacity(float opacity)
|
||||||
m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor);
|
m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor);
|
||||||
|
|
||||||
m_newButt.m_view.reset(new Specter::Button(res, *this, &m_newProjBind, m_newString,
|
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,
|
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,
|
m_extractButt.m_view.reset(new Specter::Button(res, *this, &m_extractProjBind, m_extractString,
|
||||||
Specter::Button::Style::Text));
|
nullptr, Specter::Button::Style::Text));
|
||||||
|
|
||||||
updateSize();
|
updateSize();
|
||||||
}
|
}
|
||||||
|
|
|
@ -93,7 +93,11 @@ class SplashScreen : public Specter::ModalWindow
|
||||||
std::string m_text;
|
std::string m_text;
|
||||||
|
|
||||||
const std::string* text() const {return &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)
|
OpenRecentMenuItem(OpenRecentMenuRoot& parent, const HECL::SystemString& path)
|
||||||
: m_parent(parent), m_path(path)
|
: m_parent(parent), m_path(path)
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "SplashScreen.hpp"
|
#include "SplashScreen.hpp"
|
||||||
#include "locale/locale.hpp"
|
#include "locale/locale.hpp"
|
||||||
#include "ResourceBrowser.hpp"
|
#include "ResourceBrowser.hpp"
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
using YAMLNode = Athena::io::YAMLNode;
|
using YAMLNode = Athena::io::YAMLNode;
|
||||||
|
|
||||||
|
@ -36,7 +37,6 @@ void ViewManager::RootSpaceViewBuilt(Specter::View *view)
|
||||||
std::vector<Specter::View*>& cViews = m_rootView->accessContentViews();
|
std::vector<Specter::View*>& cViews = m_rootView->accessContentViews();
|
||||||
cViews.clear();
|
cViews.clear();
|
||||||
cViews.push_back(view);
|
cViews.push_back(view);
|
||||||
printf("RootView Set: %p [%p]\n\n", m_rootView.get(), view);
|
|
||||||
cViews.push_back(m_splash.get());
|
cViews.push_back(m_splash.get());
|
||||||
m_rootView->updateSize();
|
m_rootView->updateSize();
|
||||||
}
|
}
|
||||||
|
@ -76,20 +76,77 @@ void ViewManager::DismissSplash()
|
||||||
|
|
||||||
ViewManager::ViewManager(HECL::Runtime::FileStoreManager& fileMgr, HECL::CVarManager& cvarMgr)
|
ViewManager::ViewManager(HECL::Runtime::FileStoreManager& fileMgr, HECL::CVarManager& cvarMgr)
|
||||||
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
|
: 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() {}
|
ViewManager::~ViewManager() {}
|
||||||
|
|
||||||
void ViewManager::pushRecentProject(const HECL::SystemString& path)
|
void ViewManager::pushRecentProject(const HECL::SystemString& path)
|
||||||
{
|
{
|
||||||
|
for (HECL::SystemString& testPath : m_recentProjects)
|
||||||
|
{
|
||||||
|
if (path == testPath)
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_recentProjects.push_back(path);
|
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)
|
void ViewManager::pushRecentFile(const HECL::SystemString& path)
|
||||||
{
|
{
|
||||||
|
for (HECL::SystemString& testPath : m_recentFiles)
|
||||||
|
{
|
||||||
|
if (path == testPath)
|
||||||
|
return;
|
||||||
|
}
|
||||||
m_recentFiles.push_back(path);
|
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)
|
void ViewManager::init(boo::IApplication* app)
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,7 +29,9 @@ class ViewManager : public Specter::IViewManager
|
||||||
std::unique_ptr<RootSpace> m_rootSpace;
|
std::unique_ptr<RootSpace> m_rootSpace;
|
||||||
Specter::View* m_rootSpaceView = nullptr;
|
Specter::View* m_rootSpaceView = nullptr;
|
||||||
|
|
||||||
|
HECL::SystemString m_recentProjectsPath;
|
||||||
std::vector<HECL::SystemString> m_recentProjects;
|
std::vector<HECL::SystemString> m_recentProjects;
|
||||||
|
HECL::SystemString m_recentFilesPath;
|
||||||
std::vector<HECL::SystemString> m_recentFiles;
|
std::vector<HECL::SystemString> m_recentFiles;
|
||||||
|
|
||||||
bool m_updatePf = false;
|
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