texassemble/texconv: added wildcard support
This commit is contained in:
parent
2d27b1447e
commit
e35e84f6e1
@ -34,7 +34,8 @@ using namespace DirectX;
|
||||
|
||||
enum OPTIONS
|
||||
{
|
||||
OPT_CUBE = 1,
|
||||
OPT_RECURSIVE = 1,
|
||||
OPT_CUBE,
|
||||
OPT_VOLUME,
|
||||
OPT_ARRAY,
|
||||
OPT_CUBEARRAY,
|
||||
@ -68,6 +69,7 @@ struct SValue
|
||||
|
||||
SValue g_pOptions[] =
|
||||
{
|
||||
{ L"r", OPT_RECURSIVE },
|
||||
{ L"cube", OPT_CUBE },
|
||||
{ L"volume", OPT_VOLUME },
|
||||
{ L"array", OPT_ARRAY },
|
||||
@ -181,6 +183,12 @@ SValue g_pFilters[] =
|
||||
|
||||
namespace
|
||||
{
|
||||
inline HANDLE safe_handle(HANDLE h) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; }
|
||||
|
||||
struct find_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) FindClose(h); } };
|
||||
|
||||
typedef public std::unique_ptr<void, find_closer> ScopedFindHandle;
|
||||
|
||||
#pragma prefast(disable : 26018, "Only used with static internal arrays")
|
||||
|
||||
DWORD LookupByName(const wchar_t *pName, const SValue *pArray)
|
||||
@ -196,6 +204,7 @@ namespace
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const wchar_t* LookupByValue(DWORD pValue, const SValue *pArray)
|
||||
{
|
||||
while (pArray->pName)
|
||||
@ -209,6 +218,82 @@ namespace
|
||||
return L"";
|
||||
}
|
||||
|
||||
|
||||
void SearchForFiles(const wchar_t* path, std::list<SConversion>& files, bool recursive)
|
||||
{
|
||||
// Process files
|
||||
WIN32_FIND_DATA findData = {};
|
||||
ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path,
|
||||
FindExInfoBasic, &findData,
|
||||
FindExSearchNameMatch, nullptr,
|
||||
FIND_FIRST_EX_LARGE_FETCH)));
|
||||
if (hFile)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)))
|
||||
{
|
||||
wchar_t drive[_MAX_DRIVE] = {};
|
||||
wchar_t dir[_MAX_DIR] = {};
|
||||
_wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0);
|
||||
|
||||
SConversion conv;
|
||||
_wmakepath_s(conv.szSrc, drive, dir, findData.cFileName, nullptr);
|
||||
files.push_back(conv);
|
||||
}
|
||||
|
||||
if (!FindNextFile(hFile.get(), &findData))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Process directories
|
||||
if (recursive)
|
||||
{
|
||||
wchar_t searchDir[MAX_PATH] = {};
|
||||
{
|
||||
wchar_t drive[_MAX_DRIVE] = {};
|
||||
wchar_t dir[_MAX_DIR] = {};
|
||||
_wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0);
|
||||
_wmakepath_s(searchDir, drive, dir, L"*", nullptr);
|
||||
}
|
||||
|
||||
hFile.reset(safe_handle(FindFirstFileExW(searchDir,
|
||||
FindExInfoBasic, &findData,
|
||||
FindExSearchLimitToDirectories, nullptr,
|
||||
FIND_FIRST_EX_LARGE_FETCH)));
|
||||
if (!hFile)
|
||||
return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (findData.cFileName[0] != L'.')
|
||||
{
|
||||
wchar_t subdir[MAX_PATH] = {};
|
||||
|
||||
{
|
||||
wchar_t drive[_MAX_DRIVE] = {};
|
||||
wchar_t dir[_MAX_DIR] = {};
|
||||
wchar_t fname[_MAX_FNAME] = {};
|
||||
wchar_t ext[_MAX_FNAME] = {};
|
||||
_wsplitpath_s(path, drive, dir, fname, ext);
|
||||
wcscat_s(dir, findData.cFileName);
|
||||
_wmakepath_s(subdir, drive, dir, fname, ext);
|
||||
}
|
||||
|
||||
SearchForFiles(subdir, files, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
if (!FindNextFile(hFile.get(), &findData))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PrintFormat(DXGI_FORMAT Format)
|
||||
{
|
||||
for (SValue *pFormat = g_pFormats; pFormat->pName; pFormat++)
|
||||
@ -221,6 +306,7 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PrintInfo(const TexMetadata& info)
|
||||
{
|
||||
wprintf(L" (%Iux%Iu", info.width, info.height);
|
||||
@ -298,6 +384,7 @@ namespace
|
||||
|
||||
wprintf(L"Usage: texassemble [-cube | - volume | -array | -cubearray] <options> <files>\n");
|
||||
wprintf(L"\n");
|
||||
wprintf(L" -r wildcard filename search is recursive\n");
|
||||
wprintf(L" -cube create cubemap\n");
|
||||
wprintf(L" -volume create volume map\n");
|
||||
wprintf(L" -array create texture array\n");
|
||||
@ -441,6 +528,16 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (wcspbrk(pArg, L"?*") != nullptr)
|
||||
{
|
||||
size_t count = conversion.size();
|
||||
SearchForFiles(pArg, conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0);
|
||||
if (conversion.size() <= count)
|
||||
{
|
||||
wprintf(L"No matching files found for %ls\n", pArg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SConversion conv;
|
||||
|
@ -40,7 +40,8 @@ using Microsoft::WRL::ComPtr;
|
||||
|
||||
enum OPTIONS
|
||||
{
|
||||
OPT_WIDTH = 1,
|
||||
OPT_RECURSIVE = 1,
|
||||
OPT_WIDTH,
|
||||
OPT_HEIGHT,
|
||||
OPT_MIPLEVELS,
|
||||
OPT_FORMAT,
|
||||
@ -96,12 +97,14 @@ struct SValue
|
||||
DWORD dwValue;
|
||||
};
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
SValue g_pOptions[] =
|
||||
{
|
||||
{ L"r", OPT_RECURSIVE },
|
||||
{ L"w", OPT_WIDTH },
|
||||
{ L"h", OPT_HEIGHT },
|
||||
{ L"m", OPT_MIPLEVELS },
|
||||
@ -345,6 +348,12 @@ SValue g_pFeatureLevels[] = // valid feature levels for -fl for maximimum si
|
||||
|
||||
namespace
|
||||
{
|
||||
inline HANDLE safe_handle(HANDLE h) { return (h == INVALID_HANDLE_VALUE) ? 0 : h; }
|
||||
|
||||
struct find_closer { void operator()(HANDLE h) { assert(h != INVALID_HANDLE_VALUE); if (h) FindClose(h); } };
|
||||
|
||||
typedef public std::unique_ptr<void, find_closer> ScopedFindHandle;
|
||||
|
||||
inline static bool ispow2(size_t x)
|
||||
{
|
||||
return ((x != 0) && !(x & (x - 1)));
|
||||
@ -380,6 +389,81 @@ namespace
|
||||
}
|
||||
|
||||
|
||||
void SearchForFiles(const wchar_t* path, std::list<SConversion>& files, bool recursive)
|
||||
{
|
||||
// Process files
|
||||
WIN32_FIND_DATA findData = {};
|
||||
ScopedFindHandle hFile(safe_handle(FindFirstFileExW(path,
|
||||
FindExInfoBasic, &findData,
|
||||
FindExSearchNameMatch, nullptr,
|
||||
FIND_FIRST_EX_LARGE_FETCH)));
|
||||
if (hFile)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (!(findData.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_DIRECTORY)))
|
||||
{
|
||||
wchar_t drive[_MAX_DRIVE] = {};
|
||||
wchar_t dir[_MAX_DIR] = {};
|
||||
_wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0);
|
||||
|
||||
SConversion conv;
|
||||
_wmakepath_s(conv.szSrc, drive, dir, findData.cFileName, nullptr);
|
||||
files.push_back(conv);
|
||||
}
|
||||
|
||||
if (!FindNextFile(hFile.get(), &findData))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Process directories
|
||||
if (recursive)
|
||||
{
|
||||
wchar_t searchDir[MAX_PATH] = {};
|
||||
{
|
||||
wchar_t drive[_MAX_DRIVE] = {};
|
||||
wchar_t dir[_MAX_DIR] = {};
|
||||
_wsplitpath_s(path, drive, _MAX_DRIVE, dir, _MAX_DIR, nullptr, 0, nullptr, 0);
|
||||
_wmakepath_s(searchDir, drive, dir, L"*", nullptr);
|
||||
}
|
||||
|
||||
hFile.reset(safe_handle(FindFirstFileExW(searchDir,
|
||||
FindExInfoBasic, &findData,
|
||||
FindExSearchLimitToDirectories, nullptr,
|
||||
FIND_FIRST_EX_LARGE_FETCH)));
|
||||
if (!hFile)
|
||||
return;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
if (findData.cFileName[0] != L'.')
|
||||
{
|
||||
wchar_t subdir[MAX_PATH] = {};
|
||||
|
||||
{
|
||||
wchar_t drive[_MAX_DRIVE] = {};
|
||||
wchar_t dir[_MAX_DIR] = {};
|
||||
wchar_t fname[_MAX_FNAME] = {};
|
||||
wchar_t ext[_MAX_FNAME] = {};
|
||||
_wsplitpath_s(path, drive, dir, fname, ext);
|
||||
wcscat_s(dir, findData.cFileName);
|
||||
_wmakepath_s(subdir, drive, dir, fname, ext);
|
||||
}
|
||||
|
||||
SearchForFiles(subdir, files, recursive);
|
||||
}
|
||||
}
|
||||
|
||||
if (!FindNextFile(hFile.get(), &findData))
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PrintFormat(DXGI_FORMAT Format)
|
||||
{
|
||||
for (SValue *pFormat = g_pFormats; pFormat->pName; pFormat++)
|
||||
@ -511,6 +595,7 @@ namespace
|
||||
|
||||
wprintf(L"Usage: texconv <options> <files>\n");
|
||||
wprintf(L"\n");
|
||||
wprintf(L" -r wildcard filename search is recursive\n");
|
||||
wprintf(L" -w <n> width\n");
|
||||
wprintf(L" -h <n> height\n");
|
||||
wprintf(L" -m <n> miplevels\n");
|
||||
@ -1096,6 +1181,16 @@ int __cdecl wmain(_In_ int argc, _In_z_count_(argc) wchar_t* argv[])
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (wcspbrk(pArg, L"?*") != nullptr)
|
||||
{
|
||||
size_t count = conversion.size();
|
||||
SearchForFiles(pArg, conversion, (dwOptions & (1 << OPT_RECURSIVE)) != 0);
|
||||
if (conversion.size() <= count)
|
||||
{
|
||||
wprintf(L"No matching files found for %ls\n", pArg);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SConversion conv;
|
||||
|
Loading…
Reference in New Issue
Block a user