Features to support cooking

This commit is contained in:
Jack Andersen 2015-09-30 14:40:06 -10:00
parent 63a432090c
commit 391ee13816
8 changed files with 147 additions and 56 deletions

View File

@ -342,7 +342,16 @@ BlenderConnection::~BlenderConnection()
_closePipe();
}
bool BlenderConnection::createBlend(const SystemString& path)
static std::string BlendTypeStrs[] =
{
"NONE",
"MESH",
"ACTOR",
"AREA",
""
};
bool BlenderConnection::createBlend(const SystemString& path, BlendType type)
{
if (m_lock)
{
@ -351,7 +360,7 @@ bool BlenderConnection::createBlend(const SystemString& path)
return false;
}
HECL::SystemUTF8View pathView(path);
_writeLine(("CREATE \"" + pathView.str() + "\" \"" + m_startupBlend + "\"").c_str());
_writeLine(("CREATE \"" + pathView.str() + "\" " + BlendTypeStrs[type] + " \"" + m_startupBlend + "\"").c_str());
char lineBuf[256];
_readLine(lineBuf, sizeof(lineBuf));
if (!strcmp(lineBuf, "FINISHED"))
@ -362,6 +371,18 @@ bool BlenderConnection::createBlend(const SystemString& path)
return false;
}
BlenderConnection::BlendType BlenderConnection::getBlendType()
{
_writeLine("GETTYPE");
char lineBuf[256];
_readLine(lineBuf, sizeof(lineBuf));
unsigned idx = 0;
while (BlendTypeStrs[idx].size())
if (!BlendTypeStrs[idx].compare(lineBuf))
return BlendType(idx);
return TypeNone;
}
bool BlenderConnection::openBlend(const SystemString& path)
{
if (m_lock)
@ -432,41 +453,6 @@ void BlenderConnection::PyOutStream::linkBlend(const std::string& target, const
objName.c_str(), objName.c_str(), target.c_str(), objName.c_str());
}
bool BlenderConnection::cookBlend(std::function<char*(uint32_t)> bufGetter,
const std::string& expectedType,
const std::string& platform,
bool bigEndian)
{
char lineBuf[256];
char reqLine[512];
snprintf(reqLine, 512, "COOK %s %c", platform.c_str(), bigEndian?'>':'<');
_writeLine(reqLine);
_readLine(lineBuf, sizeof(lineBuf));
if (strcmp(expectedType.c_str(), lineBuf))
{
BlenderLog.report(LogVisor::Error, "expected '%s' to contain '%s' not '%s'",
m_loadedBlend.c_str(), expectedType.c_str(), lineBuf);
return false;
}
_writeLine("ACK");
for (_readLine(lineBuf, sizeof(lineBuf));
!strcmp("BUF", lineBuf);
_readLine(lineBuf, sizeof(lineBuf)))
{
uint32_t sz;
_readBuf((char*)&sz, 4);
char* buf = bufGetter(sz);
_readBuf(buf, sz);
}
if (!strcmp("SUCCESS", lineBuf))
return true;
else if (!strcmp("EXCEPTION", lineBuf))
BlenderLog.report(LogVisor::FatalError, "blender script exception");
return false;
}
void BlenderConnection::quitBlender()
{
_writeLine("QUIT");

View File

@ -47,19 +47,19 @@ public:
BlenderConnection(int verbosityLevel=1);
~BlenderConnection();
bool createBlend(const SystemString& path);
enum BlendType
{
TypeNone,
TypeMesh,
TypeActor,
TypeArea
};
bool createBlend(const SystemString& path, BlendType type);
BlendType getBlendType();
bool openBlend(const SystemString& path);
bool saveBlend();
void deleteBlend();
enum CookPlatform
{
CP_MODERN = 0,
CP_GX = 1,
};
bool cookBlend(std::function<char*(uint32_t)> bufGetter,
const std::string& expectedType,
const std::string& platform,
bool bigEndian=false);
class PyOutStream : public std::ostream
{

View File

@ -135,17 +135,21 @@ while True:
writepipeline(b'CANCELLED')
elif cmdargs[0] == 'CREATE':
if len(cmdargs) >= 3:
bpy.ops.wm.open_mainfile(filepath=cmdargs[2])
if len(cmdargs) >= 4:
bpy.ops.wm.open_mainfile(filepath=cmdargs[3])
else:
bpy.ops.wm.read_homefile()
bpy.context.user_preferences.filepaths.save_version = 0
if 'FINISHED' in bpy.ops.wm.save_as_mainfile(filepath=cmdargs[1]):
bpy.ops.file.hecl_patching_load()
bpy.context.scene.hecl_type = cmdargs[2]
writepipeline(b'FINISHED')
else:
writepipeline(b'CANCELLED')
elif cmdargs[0] == 'GETTYPE':
writepipeline(bpy.context.scene.hecl_type.encode())
elif cmdargs[0] == 'SAVE':
bpy.context.user_preferences.filepaths.save_version = 0
if 'FINISHED' in bpy.ops.wm.save_mainfile(check_existing=False, compress=True):

2
hecl/extern/Athena vendored

@ -1 +1 @@
Subproject commit a999744ab6f22f09293db4b2680fa2c95f541e1d
Subproject commit f4716070dd33f910e4854997a91a249e40922229

View File

@ -306,15 +306,20 @@ public:
*
* Self explanatory
*/
const ProjectPath& getProjectRootPath() const {return m_workRoot;}
const ProjectRootPath& getProjectRootPath() const {return m_rootPath;}
/**
* @brief Get the path of project's working directory
* @return project working path
*/
const ProjectPath& getProjectWorkingPath() const {return m_workRoot;}
/**
* @brief Get the path of project's cooked directory for a specific DataSpec
* @param DataSpec to retrieve path for
* @return project cooked path
*
* The cooked path matches the directory layout of the working directory,
* except data is
* The cooked path matches the directory layout of the working directory
*/
const ProjectPath& getProjectCookedPath(const DataSpecEntry& spec) const
{

View File

@ -279,6 +279,15 @@ static inline void SNPrintf(SystemChar* str, size_t maxlen, const SystemChar* fo
va_end(va);
}
static inline int StrCmp(const SystemChar* str1, const SystemChar* str2)
{
#if HECL_UCS2
return wcscmp(str1, str2);
#else
return strcmp(str1, str2);
#endif
}
#define FORMAT_BUF_SZ 1024
#if __GNUC__
@ -599,7 +608,7 @@ public:
/**
* @brief Obtain c-string of final path component (stored within relative path)
* @return Final component c-string
* @return Final component c-string (may be empty)
*/
const SystemChar* getLastComponent() const
{
@ -609,6 +618,25 @@ public:
return m_relPath.c_str() + pos + 1;
}
/**
* @brief Obtain c-string of extension of final path component (stored within relative path)
* @return Final component extension c-string (may be nullptr)
*/
const SystemChar* getLastComponentExt() const
{
const SystemChar* lastCompOrig = getLastComponent();
const SystemChar* lastComp = lastCompOrig;
while (*lastComp != _S('\0'))
++lastComp;
while (lastComp != lastCompOrig)
{
if (*lastComp == _S('.'))
return lastComp + 1;
--lastComp;
}
return nullptr;
}
/**
* @brief Access fully-canonicalized absolute path in UTF-8
* @return Absolute path reference
@ -729,6 +757,27 @@ ProjectRootPath SearchForProject(const SystemString& path);
*/
ProjectRootPath SearchForProject(const SystemString& path, SystemString& subpathOut);
/**
* @brief Test if given path is a PNG (based on file header)
* @param path Path to test
* @return true if PNG
*/
bool IsPathPNG(const HECL::ProjectPath& path);
/**
* @brief Test if given path is a blend (based on file header)
* @param path Path to test
* @return true if blend
*/
bool IsPathBlend(const HECL::ProjectPath& path);
/**
* @brief Test if given path is a yaml (based on file extension)
* @param path Path to test
* @return true if yaml
*/
bool IsPathYAML(const HECL::ProjectPath& path);
#undef bswap16
#undef bswap32
#undef bswap64

View File

@ -359,10 +359,10 @@ static void VisitDirectory(std::list<std::pair<ProjectPath, std::list<ProjectPat
{
std::list<ProjectPath> children;
dir.getDirChildren(children);
for (ProjectPath& child : children)
{
allDirs.emplace_back(dir, std::list<ProjectPath>());
std::list<ProjectPath>& ch = allDirs.back().second;
for (ProjectPath& child : children)
{
switch (child.getPathType())
{
case ProjectPath::PT_FILE:

View File

@ -29,4 +29,51 @@ void SanitizePath(std::wstring& path)
});
}
bool IsPathPNG(const HECL::ProjectPath& path)
{
FILE* fp = HECL::Fopen(path.getAbsolutePath().c_str(), _S("rb"));
if (!fp)
return false;
uint32_t buf;
if (fread(&buf, 1, 4, fp) != 4)
{
fclose(fp);
return false;
}
fclose(fp);
buf = HECL::SBig(buf);
if (buf == 0x89504e47)
return true;
return false;
}
bool IsPathBlend(const HECL::ProjectPath& path)
{
FILE* fp = HECL::Fopen(path.getAbsolutePath().c_str(), _S("rb"));
if (!fp)
return false;
uint32_t buf;
if (fread(&buf, 1, 4, fp) != 4)
{
fclose(fp);
return false;
}
fclose(fp);
buf = HECL::SLittle(buf);
if (buf == 0x4e454c42 || buf == 0x88b1f)
return true;
return false;
}
bool IsPathYAML(const HECL::ProjectPath& path)
{
const SystemChar* lastCompExt = path.getLastComponentExt();
if (!lastCompExt)
return false;
if (!HECL::StrCmp(lastCompExt, _S("yaml")) ||
!HECL::StrCmp(lastCompExt, _S("yml")))
return true;
return false;
}
}