file operation updates for uwp platform #110
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
#include "Utility/stb_image.h"
|
||||
|
||||
#define TINYGLTF_IMPLEMENTATION
|
||||
#define TINYGLTF_NO_FS
|
||||
#define TINYGLTF_NO_STB_IMAGE
|
||||
#define TINYGLTF_NO_STB_IMAGE_WRITE
|
||||
#include "tiny_gltf.h"
|
||||
@@ -26,6 +27,69 @@ static const bool transform_to_LH = true;
|
||||
|
||||
namespace tinygltf
|
||||
{
|
||||
|
||||
bool FileExists(const std::string& abs_filename, void*) {
|
||||
return wiHelper::FileExists(abs_filename);
|
||||
}
|
||||
|
||||
std::string ExpandFilePath(const std::string& filepath, void*) {
|
||||
#ifdef _WIN32
|
||||
DWORD len = ExpandEnvironmentStringsA(filepath.c_str(), NULL, 0);
|
||||
char* str = new char[len];
|
||||
ExpandEnvironmentStringsA(filepath.c_str(), str, len);
|
||||
|
||||
std::string s(str);
|
||||
|
||||
delete[] str;
|
||||
|
||||
return s;
|
||||
#else
|
||||
|
||||
#if defined(TARGET_OS_IPHONE) || defined(TARGET_IPHONE_SIMULATOR) || \
|
||||
defined(__ANDROID__) || defined(__EMSCRIPTEN__)
|
||||
// no expansion
|
||||
std::string s = filepath;
|
||||
#else
|
||||
std::string s;
|
||||
wordexp_t p;
|
||||
|
||||
if (filepath.empty()) {
|
||||
return "";
|
||||
}
|
||||
|
||||
// char** w;
|
||||
int ret = wordexp(filepath.c_str(), &p, 0);
|
||||
if (ret) {
|
||||
// err
|
||||
s = filepath;
|
||||
return s;
|
||||
}
|
||||
|
||||
// Use first element only.
|
||||
if (p.we_wordv) {
|
||||
s = std::string(p.we_wordv[0]);
|
||||
wordfree(&p);
|
||||
}
|
||||
else {
|
||||
s = filepath;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ReadWholeFile(std::vector<unsigned char>* out, std::string* err,
|
||||
const std::string& filepath, void*) {
|
||||
return wiHelper::FileRead(filepath, *out);
|
||||
}
|
||||
|
||||
bool WriteWholeFile(std::string* err, const std::string& filepath,
|
||||
const std::vector<unsigned char>& contents, void*) {
|
||||
return wiHelper::FileWrite(filepath, contents.data(), contents.size());
|
||||
}
|
||||
|
||||
bool LoadImageData(Image *image, const int image_idx, std::string *err,
|
||||
std::string *warn, int req_width, int req_height,
|
||||
const unsigned char *bytes, int size, void *)
|
||||
@@ -297,6 +361,14 @@ void ImportModel_GLTF(const std::string& fileName, Scene& scene)
|
||||
tinygltf::TinyGLTF loader;
|
||||
std::string err;
|
||||
std::string warn;
|
||||
bool ret;
|
||||
|
||||
tinygltf::FsCallbacks callbacks;
|
||||
callbacks.ReadWholeFile = tinygltf::ReadWholeFile;
|
||||
callbacks.WriteWholeFile = tinygltf::WriteWholeFile;
|
||||
callbacks.FileExists = tinygltf::FileExists;
|
||||
callbacks.ExpandFilePath = tinygltf::ExpandFilePath;
|
||||
loader.SetFsCallbacks(callbacks);
|
||||
|
||||
loader.SetImageLoader(tinygltf::LoadImageData, nullptr);
|
||||
loader.SetImageWriter(tinygltf::WriteImageData, nullptr);
|
||||
@@ -304,15 +376,31 @@ void ImportModel_GLTF(const std::string& fileName, Scene& scene)
|
||||
LoaderState state;
|
||||
state.scene = &scene;
|
||||
|
||||
bool ret;
|
||||
if (!extension.compare("GLTF"))
|
||||
std::vector<uint8_t> filedata;
|
||||
ret = wiHelper::FileRead(fileName, filedata);
|
||||
|
||||
if (ret)
|
||||
{
|
||||
ret = loader.LoadASCIIFromFile(&state.gltfModel, &err, &warn, fileName);
|
||||
std::string basedir = tinygltf::GetBaseDir(fileName);
|
||||
|
||||
if (!extension.compare("GLTF"))
|
||||
{
|
||||
ret = loader.LoadASCIIFromString(&state.gltfModel, &err, &warn,
|
||||
reinterpret_cast<const char*>(&filedata.at(0)),
|
||||
static_cast<unsigned int>(filedata.size()), basedir);
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = loader.LoadBinaryFromMemory(&state.gltfModel, &err, &warn,
|
||||
filedata.data(),
|
||||
static_cast<unsigned int>(filedata.size()), basedir);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = loader.LoadBinaryFromFile(&state.gltfModel, &err, &warn, fileName); // for binary glTF(.glb)
|
||||
err = "Failed to read file: " + fileName;
|
||||
}
|
||||
|
||||
if (!ret) {
|
||||
wiHelper::messageBox(err, "GLTF error!");
|
||||
}
|
||||
|
||||
@@ -5,13 +5,70 @@
|
||||
#define TINYOBJLOADER_IMPLEMENTATION
|
||||
#include "tiny_obj_loader.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <istream>
|
||||
#include <streambuf>
|
||||
|
||||
using namespace std;
|
||||
using namespace wiGraphics;
|
||||
using namespace wiScene;
|
||||
using namespace wiECS;
|
||||
|
||||
struct membuf : std::streambuf
|
||||
{
|
||||
membuf(char* begin, char* end) {
|
||||
this->setg(begin, begin, end);
|
||||
}
|
||||
};
|
||||
|
||||
// Custom material file reader:
|
||||
class MaterialFileReader : public tinyobj::MaterialReader {
|
||||
public:
|
||||
explicit MaterialFileReader(const std::string& mtl_basedir)
|
||||
: m_mtlBaseDir(mtl_basedir) {}
|
||||
virtual ~MaterialFileReader() {}
|
||||
virtual bool operator()(const std::string& matId,
|
||||
std::vector<tinyobj::material_t>* materials,
|
||||
std::map<std::string, int>* matMap, std::string* err)
|
||||
{
|
||||
std::string filepath;
|
||||
|
||||
if (!m_mtlBaseDir.empty()) {
|
||||
filepath = std::string(m_mtlBaseDir) + matId;
|
||||
}
|
||||
else {
|
||||
filepath = matId;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> filedata;
|
||||
if (!wiHelper::FileRead(filepath, filedata))
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "WARN: Material file [ " << filepath << " ] not found." << std::endl;
|
||||
if (err) {
|
||||
(*err) += ss.str();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
membuf sbuf((char*)filedata.data(), (char*)filedata.data() + filedata.size());
|
||||
std::istream matIStream(&sbuf);
|
||||
|
||||
std::string warning;
|
||||
LoadMtl(matMap, materials, &matIStream, &warning);
|
||||
|
||||
if (!warning.empty()) {
|
||||
if (err) {
|
||||
(*err) += warning;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_mtlBaseDir;
|
||||
};
|
||||
|
||||
// Transform the data from OBJ space to engine-space:
|
||||
static const bool transform_to_LH = true;
|
||||
|
||||
@@ -26,7 +83,20 @@ void ImportModel_OBJ(const std::string& fileName, Scene& scene)
|
||||
vector<tinyobj::material_t> obj_materials;
|
||||
string obj_errors;
|
||||
|
||||
bool success = tinyobj::LoadObj(&obj_attrib, &obj_shapes, &obj_materials, &obj_errors, fileName.c_str(), directory.c_str(), true);
|
||||
std::vector<uint8_t> filedata;
|
||||
bool success = wiHelper::FileRead(fileName, filedata);
|
||||
|
||||
if (success)
|
||||
{
|
||||
membuf sbuf((char*)filedata.data(), (char*)filedata.data() + filedata.size());
|
||||
std::istream in(&sbuf);
|
||||
MaterialFileReader matFileReader(directory);
|
||||
success = tinyobj::LoadObj(&obj_attrib, &obj_shapes, &obj_materials, &obj_errors, &in, &matFileReader, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
obj_errors = "Failed to read file: " + fileName;
|
||||
}
|
||||
|
||||
if (!obj_errors.empty())
|
||||
{
|
||||
|
||||
@@ -121,6 +121,8 @@ void MainComponent::Run()
|
||||
wiLua::GetGlobal()->RunFile("startup.lua");
|
||||
}
|
||||
|
||||
wiPlatform::PopMessages();
|
||||
|
||||
wiProfiler::BeginFrame();
|
||||
|
||||
deltaTime = float(std::max(0.0, timer.elapsed() / 1000.0));
|
||||
|
||||
@@ -23,14 +23,8 @@ wiArchive::wiArchive(const std::string& fileName, bool readMode) : fileName(file
|
||||
{
|
||||
if (readMode)
|
||||
{
|
||||
ifstream file(fileName, ios::binary | ios::ate);
|
||||
if (file.is_open())
|
||||
if (wiHelper::FileRead(fileName, DATA))
|
||||
{
|
||||
size_t dataSize = (size_t)file.tellg();
|
||||
file.seekg(0, file.beg);
|
||||
DATA.resize((size_t)dataSize);
|
||||
file.read((char*)DATA.data(), dataSize);
|
||||
file.close();
|
||||
(*this) >> version;
|
||||
if (version < __archiveVersionBarrier)
|
||||
{
|
||||
@@ -98,20 +92,7 @@ void wiArchive::Close()
|
||||
|
||||
bool wiArchive::SaveFile(const std::string& fileName)
|
||||
{
|
||||
if (pos <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ofstream file(fileName, ios::binary | ios::trunc);
|
||||
if (file.is_open())
|
||||
{
|
||||
file.write((const char*)DATA.data(), (streamsize)pos);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
return wiHelper::FileWrite(fileName, DATA.data(), pos);
|
||||
}
|
||||
|
||||
string wiArchive::GetSourceDirectory() const
|
||||
|
||||
+34
-66
@@ -196,11 +196,9 @@ namespace wiAudio
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT FindChunk(HANDLE hFile, DWORD fourcc, DWORD& dwChunkSize, DWORD& dwChunkDataPosition)
|
||||
bool FindChunk(const uint8_t* data, DWORD fourcc, DWORD& dwChunkSize, DWORD& dwChunkDataPosition)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, LARGE_INTEGER(), NULL, FILE_BEGIN))
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
size_t pos = 0;
|
||||
|
||||
DWORD dwChunkType;
|
||||
DWORD dwChunkDataSize;
|
||||
@@ -209,29 +207,26 @@ namespace wiAudio
|
||||
DWORD bytesRead = 0;
|
||||
DWORD dwOffset = 0;
|
||||
|
||||
while (hr == S_OK)
|
||||
while(true)
|
||||
{
|
||||
DWORD dwRead;
|
||||
if (0 == ReadFile(hFile, &dwChunkType, sizeof(DWORD), &dwRead, NULL))
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
|
||||
if (0 == ReadFile(hFile, &dwChunkDataSize, sizeof(DWORD), &dwRead, NULL))
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
memcpy(&dwChunkType, data + pos, sizeof(DWORD));
|
||||
pos += sizeof(DWORD);
|
||||
memcpy(&dwChunkDataSize, data + pos, sizeof(DWORD));
|
||||
pos += sizeof(DWORD);
|
||||
|
||||
switch (dwChunkType)
|
||||
{
|
||||
case fourccRIFF:
|
||||
dwRIFFDataSize = dwChunkDataSize;
|
||||
dwChunkDataSize = 4;
|
||||
if (0 == ReadFile(hFile, &dwFileType, sizeof(DWORD), &dwRead, NULL))
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
memcpy(&dwFileType, data + pos, sizeof(DWORD));
|
||||
pos += sizeof(DWORD);
|
||||
break;
|
||||
|
||||
default:
|
||||
LARGE_INTEGER li = LARGE_INTEGER();
|
||||
li.QuadPart = dwChunkDataSize;
|
||||
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, li, NULL, FILE_CURRENT))
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
pos += dwChunkDataSize;
|
||||
}
|
||||
|
||||
dwOffset += sizeof(DWORD) * 2;
|
||||
@@ -240,84 +235,57 @@ namespace wiAudio
|
||||
{
|
||||
dwChunkSize = dwChunkDataSize;
|
||||
dwChunkDataPosition = dwOffset;
|
||||
return S_OK;
|
||||
return true;
|
||||
}
|
||||
|
||||
dwOffset += dwChunkDataSize;
|
||||
|
||||
if (bytesRead >= dwRIFFDataSize) return S_FALSE;
|
||||
if (bytesRead >= dwRIFFDataSize) return false;
|
||||
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
return true;
|
||||
|
||||
}
|
||||
HRESULT ReadChunkData(HANDLE hFile, void* buffer, DWORD buffersize, DWORD bufferoffset)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
LARGE_INTEGER li = LARGE_INTEGER();
|
||||
li.QuadPart = bufferoffset;
|
||||
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, li, NULL, FILE_BEGIN))
|
||||
return HRESULT_FROM_WIN32(GetLastError());
|
||||
DWORD dwRead;
|
||||
if (0 == ReadFile(hFile, buffer, buffersize, &dwRead, NULL))
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return hr;
|
||||
}
|
||||
|
||||
bool CreateSound(const std::string& filename, Sound* sound)
|
||||
{
|
||||
std::vector<uint8_t> filedata;
|
||||
bool success = wiHelper::FileRead(filename, filedata);
|
||||
if (!success)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return CreateSound(filedata, sound);
|
||||
}
|
||||
bool CreateSound(const std::vector<uint8_t>& data, Sound* sound)
|
||||
{
|
||||
std::shared_ptr<SoundInternal> soundinternal = std::make_shared<SoundInternal>();
|
||||
sound->internal_state = soundinternal;
|
||||
|
||||
std::wstring wfilename;
|
||||
wiHelper::StringConvert(filename, wfilename);
|
||||
|
||||
HANDLE hFile = CreateFile2(
|
||||
wfilename.c_str(),
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ,
|
||||
OPEN_EXISTING,
|
||||
nullptr
|
||||
);
|
||||
|
||||
HRESULT hr;
|
||||
if (INVALID_HANDLE_VALUE == hFile)
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (INVALID_SET_FILE_POINTER == SetFilePointerEx(hFile, LARGE_INTEGER(), NULL, FILE_BEGIN))
|
||||
{
|
||||
hr = HRESULT_FROM_WIN32(GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
DWORD dwChunkSize;
|
||||
DWORD dwChunkPosition;
|
||||
|
||||
FindChunk(hFile, fourccRIFF, dwChunkSize, dwChunkPosition);
|
||||
bool success;
|
||||
|
||||
success = FindChunk(data.data(), fourccRIFF, dwChunkSize, dwChunkPosition);
|
||||
assert(success);
|
||||
DWORD filetype;
|
||||
hr = ReadChunkData(hFile, &filetype, sizeof(DWORD), dwChunkPosition);
|
||||
assert(SUCCEEDED(hr));
|
||||
memcpy(&filetype, data.data() + dwChunkPosition, sizeof(DWORD));
|
||||
assert(filetype == fourccWAVE);
|
||||
|
||||
soundinternal->audio = audio;
|
||||
|
||||
hr = FindChunk(hFile, fourccFMT, dwChunkSize, dwChunkPosition);
|
||||
assert(SUCCEEDED(hr));
|
||||
hr = ReadChunkData(hFile, &soundinternal->wfx, dwChunkSize, dwChunkPosition);
|
||||
assert(SUCCEEDED(hr));
|
||||
success = FindChunk(data.data(), fourccFMT, dwChunkSize, dwChunkPosition);
|
||||
assert(success);
|
||||
memcpy(&soundinternal->wfx, data.data() + dwChunkPosition, dwChunkSize);
|
||||
soundinternal->wfx.wFormatTag = WAVE_FORMAT_PCM;
|
||||
|
||||
hr = FindChunk(hFile, fourccDATA, dwChunkSize, dwChunkPosition);
|
||||
assert(SUCCEEDED(hr));
|
||||
success = FindChunk(data.data(), fourccDATA, dwChunkSize, dwChunkPosition);
|
||||
assert(success);
|
||||
|
||||
soundinternal->audioData.resize(dwChunkSize);
|
||||
hr = ReadChunkData(hFile, soundinternal->audioData.data(), dwChunkSize, dwChunkPosition);
|
||||
assert(SUCCEEDED(hr));
|
||||
memcpy(soundinternal->audioData.data(), data.data() + dwChunkPosition, dwChunkSize);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace wiAudio
|
||||
{
|
||||
@@ -35,6 +36,7 @@ namespace wiAudio
|
||||
};
|
||||
|
||||
bool CreateSound(const std::string& filename, Sound* sound);
|
||||
bool CreateSound(const std::vector<uint8_t>& data, Sound* sound);
|
||||
bool CreateSoundInstance(const Sound* sound, SoundInstance* instance);
|
||||
|
||||
void Play(SoundInstance* instance);
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace wiBackLog
|
||||
Toggle();
|
||||
}
|
||||
|
||||
if (isActive)
|
||||
if (isActive())
|
||||
{
|
||||
if (wiInput::Press(wiInput::KEYBOARD_BUTTON_UP))
|
||||
{
|
||||
|
||||
@@ -82,7 +82,7 @@ namespace wiFont_Internal
|
||||
void Create(const string& newName)
|
||||
{
|
||||
name = newName;
|
||||
wiHelper::readByteData(newName, fontBuffer);
|
||||
wiHelper::FileRead(newName, fontBuffer);
|
||||
|
||||
int offset = stbtt_GetFontOffsetForIndex(fontBuffer.data(), 0);
|
||||
|
||||
|
||||
+290
-39
@@ -14,13 +14,26 @@
|
||||
#include <sstream>
|
||||
#include <codecvt> // string conversion
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef PLATFORM_UWP
|
||||
#include <collection.h>
|
||||
#include <ppltasks.h>
|
||||
|
||||
// This can be used to access any file on the system, but also needs the following manifests defined:
|
||||
// xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
|
||||
// IgnorableNamespaces = "uap mp rescap" >
|
||||
//
|
||||
// And also the capability:
|
||||
// <Capabilities>
|
||||
// <rescap:Capability Name = "broadFileSystemAccess" / >
|
||||
// < / Capabilities>
|
||||
#define UWP_BROAD_FILESYSTEM_ACCESS
|
||||
|
||||
#else
|
||||
#include <Commdlg.h> // openfile
|
||||
#include <WinBase.h>
|
||||
#endif // PLATFORM_UWP
|
||||
#endif // _WIN32
|
||||
|
||||
using namespace std;
|
||||
|
||||
@@ -37,34 +50,14 @@ namespace wiHelper
|
||||
return result;
|
||||
}
|
||||
|
||||
bool readByteData(const std::string& fileName, std::vector<uint8_t>& data)
|
||||
{
|
||||
ifstream file(fileName, ios::binary | ios::ate);
|
||||
if (file.is_open())
|
||||
{
|
||||
size_t dataSize = (size_t)file.tellg();
|
||||
file.seekg(0, file.beg);
|
||||
data.resize(dataSize);
|
||||
file.read((char*)data.data(), dataSize);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
stringstream ss("");
|
||||
ss << "File not found: " << fileName;
|
||||
messageBox(ss.str());
|
||||
return false;
|
||||
}
|
||||
|
||||
void messageBox(const std::string& msg, const std::string& caption)
|
||||
{
|
||||
#ifndef PLATFORM_UWP
|
||||
MessageBoxA(wiPlatform::GetWindow(), msg.c_str(), caption.c_str(), 0);
|
||||
#else
|
||||
wstring wmsg;
|
||||
StringConvert(msg, wmsg);
|
||||
wstring wcaption(caption.begin(), caption.end());
|
||||
Windows::UI::Popups::MessageDialog(ref new Platform::String(wmsg.c_str()), ref new Platform::String(wcaption.c_str())).ShowAsync();
|
||||
#endif
|
||||
auto& state = wiPlatform::GetWindowState();
|
||||
state.messagemutex.lock();
|
||||
state.messages.emplace_back();
|
||||
StringConvert(msg, state.messages.back().message);
|
||||
StringConvert(caption, state.messages.back().caption);
|
||||
state.messagemutex.unlock();
|
||||
}
|
||||
|
||||
void screenshot(const std::string& name)
|
||||
@@ -158,29 +151,43 @@ namespace wiHelper
|
||||
|
||||
int write_result = 0;
|
||||
|
||||
std::vector<uint8_t> filedata;
|
||||
stbi_write_func* func = [](void* context, void* data, int size) {
|
||||
std::vector<uint8_t>& filedata = *(std::vector<uint8_t>*)context;
|
||||
for (int i = 0; i < size; ++i)
|
||||
{
|
||||
filedata.push_back(*((uint8_t*)data + i));
|
||||
}
|
||||
};
|
||||
|
||||
string extension = wiHelper::toUpper(wiHelper::GetExtensionFromFileName(fileName));
|
||||
if (!extension.compare("JPG"))
|
||||
{
|
||||
write_result = stbi_write_jpg(fileName.c_str(), (int)desc.Width, (int)desc.Height, 4, textureData.data(), 100);
|
||||
write_result = stbi_write_jpg_to_func(func, &filedata, (int)desc.Width, (int)desc.Height, 4, textureData.data(), 100);
|
||||
}
|
||||
else if (!extension.compare("PNG"))
|
||||
{
|
||||
write_result = stbi_write_png(fileName.c_str(), (int)desc.Width, (int)desc.Height, 4, textureData.data(), 0);
|
||||
write_result = stbi_write_png_to_func(func, &filedata, (int)desc.Width, (int)desc.Height, 4, textureData.data(), 0);
|
||||
}
|
||||
else if (!extension.compare("TGA"))
|
||||
{
|
||||
write_result = stbi_write_tga(fileName.c_str(), (int)desc.Width, (int)desc.Height, 4, textureData.data());
|
||||
write_result = stbi_write_tga_to_func(func, &filedata, (int)desc.Width, (int)desc.Height, 4, textureData.data());
|
||||
}
|
||||
else if (!extension.compare("BMP"))
|
||||
{
|
||||
write_result = stbi_write_bmp(fileName.c_str(), (int)desc.Width, (int)desc.Height, 4, textureData.data());
|
||||
write_result = stbi_write_bmp_to_func(func, &filedata, (int)desc.Width, (int)desc.Height, 4, textureData.data());
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0 && "Unsupported extension");
|
||||
}
|
||||
|
||||
return write_result != 0;
|
||||
if (write_result != 0)
|
||||
{
|
||||
return FileWrite(fileName, filedata.data(), filedata.size());
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
string getCurrentDateTimeAsString()
|
||||
@@ -341,12 +348,205 @@ namespace wiHelper
|
||||
}
|
||||
}
|
||||
|
||||
bool FileRead(const std::string& fileName, std::vector<uint8_t>& data)
|
||||
{
|
||||
#ifndef PLATFORM_UWP
|
||||
ifstream file(fileName, ios::binary | ios::ate);
|
||||
if (file.is_open())
|
||||
{
|
||||
size_t dataSize = (size_t)file.tellg();
|
||||
file.seekg(0, file.beg);
|
||||
data.resize(dataSize);
|
||||
file.read((char*)data.data(), dataSize);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
if (!FileExists(fileName))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
using namespace concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::Storage::Streams;
|
||||
wstring wstr;
|
||||
string filepath = fileName;
|
||||
if (filepath.find(":\\") == string::npos)
|
||||
{
|
||||
filepath = GetWorkingDirectory() + filepath;
|
||||
}
|
||||
StringConvert(filepath, wstr);
|
||||
std::replace(wstr.begin(), wstr.end(), '/', '\\');
|
||||
bool success = false;
|
||||
std::thread([&] {
|
||||
bool end0 = false;
|
||||
create_task(StorageFile::GetFileFromPathAsync(ref new String(wstr.c_str()))).then([&](task<StorageFile^> task) {
|
||||
|
||||
StorageFile^ file;
|
||||
try
|
||||
{
|
||||
file = task.get();
|
||||
}
|
||||
catch (Platform::AccessDeniedException^ e)
|
||||
{
|
||||
messageBox("Opening file failed: " + fileName + " , please allow file system access permission!", "Error!");
|
||||
end0 = true;
|
||||
return;
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
end0 = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (file)
|
||||
{
|
||||
bool end1 = false;
|
||||
create_task(FileIO::ReadBufferAsync(file)).then([&](IBuffer^ buffer) {
|
||||
auto reader = DataReader::FromBuffer(buffer);
|
||||
auto size = buffer->Length;
|
||||
data.resize((size_t)size);
|
||||
for (auto& x : data)
|
||||
{
|
||||
x = reader->ReadByte();
|
||||
}
|
||||
success = true;
|
||||
end1 = true;
|
||||
});
|
||||
while (!end1) { Sleep(1); }
|
||||
}
|
||||
end0 = true;
|
||||
});
|
||||
while (!end0) { Sleep(1); }
|
||||
|
||||
}).join();
|
||||
|
||||
if (success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif // PLATFORM_UWP
|
||||
|
||||
messageBox("File not found: " + fileName);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileWrite(const std::string& fileName, const uint8_t* data, size_t size)
|
||||
{
|
||||
if (size <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifndef PLATFORM_UWP
|
||||
ofstream file(fileName, ios::binary | ios::trunc);
|
||||
if (file.is_open())
|
||||
{
|
||||
file.write((const char*)data, (streamsize)size);
|
||||
file.close();
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
using namespace concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::Storage::Streams;
|
||||
using namespace Windows::Security::Cryptography;
|
||||
wstring wstr;
|
||||
string filepath = fileName;
|
||||
if (filepath.find(":\\") == string::npos)
|
||||
{
|
||||
filepath = GetWorkingDirectory() + filepath;
|
||||
}
|
||||
StringConvert(filepath, wstr);
|
||||
std::replace(wstr.begin(), wstr.end(), '/', '\\');
|
||||
bool success = false;
|
||||
std::thread([&] {
|
||||
bool end0 = false;
|
||||
create_task(StorageFile::GetFileFromPathAsync(ref new String(wstr.c_str()))).then([&](StorageFile^ file) {
|
||||
if (file)
|
||||
{
|
||||
bool end1 = false;
|
||||
create_task(FileIO::WriteBytesAsync(file, ref new Platform::Array<unsigned char>((unsigned char*)data, (unsigned int)size))).then([&]() {
|
||||
success = true;
|
||||
end1 = true;
|
||||
});
|
||||
while (!end1) { Sleep(1); }
|
||||
}
|
||||
end0 = true;
|
||||
});
|
||||
while (!end0) { Sleep(1); }
|
||||
}).join();
|
||||
|
||||
if (success)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
#endif // PLATFORM_UWP
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FileExists(const std::string& fileName)
|
||||
{
|
||||
ifstream f(fileName);
|
||||
bool exists = f.is_open();
|
||||
f.close();
|
||||
#ifndef PLATFORM_UWP
|
||||
ifstream file(fileName);
|
||||
bool exists = file.is_open();
|
||||
file.close();
|
||||
return exists;
|
||||
#else
|
||||
using namespace concurrency;
|
||||
using namespace Platform;
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::Storage::Streams;
|
||||
string filepath = fileName;
|
||||
if (filepath.find(":\\") == string::npos)
|
||||
{
|
||||
filepath = GetWorkingDirectory() + filepath;
|
||||
}
|
||||
string directory, name;
|
||||
SplitPath(filepath, directory, name);
|
||||
wstring wdir, wname;
|
||||
StringConvert(directory, wdir);
|
||||
StringConvert(name, wname);
|
||||
std::replace(wdir.begin(), wdir.end(), '/', '\\');
|
||||
bool success = false;
|
||||
std::thread([&] {
|
||||
bool end0 = false;
|
||||
create_task(StorageFolder::GetFolderFromPathAsync(ref new String(wdir.c_str()))).then([&](task<StorageFolder^> task) {
|
||||
|
||||
StorageFolder^ folder;
|
||||
try
|
||||
{
|
||||
folder = task.get();
|
||||
}
|
||||
catch (Platform::AccessDeniedException^ e)
|
||||
{
|
||||
messageBox("Opening file failed: " + fileName + " , please allow file system access permission!", "Error!");
|
||||
end0 = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (folder)
|
||||
{
|
||||
bool end1 = false;
|
||||
create_task(folder->TryGetItemAsync(ref new String(wname.c_str()))).then([&](IStorageItem^ item) {
|
||||
if (item)
|
||||
{
|
||||
success = true;
|
||||
}
|
||||
end1 = true;
|
||||
});
|
||||
while (!end1) { Sleep(1); }
|
||||
}
|
||||
end0 = true;
|
||||
});
|
||||
while (!end0) { Sleep(1); }
|
||||
}).join();
|
||||
|
||||
return success;
|
||||
#endif
|
||||
}
|
||||
|
||||
void FileDialog(const FileDialogParams& params, std::function<void(std::string fileName)> onSuccess)
|
||||
@@ -428,14 +628,57 @@ namespace wiHelper
|
||||
using namespace Platform;
|
||||
using namespace Windows::Storage;
|
||||
using namespace Windows::Storage::Pickers;
|
||||
using namespace Windows::UI::Xaml;
|
||||
using namespace Windows::UI::Xaml::Controls;
|
||||
using namespace Windows::UI::Xaml::Navigation;
|
||||
using namespace Windows::Storage::AccessCache;
|
||||
|
||||
switch (params.type)
|
||||
{
|
||||
case FileDialogParams::OPEN:
|
||||
{
|
||||
#ifndef UWP_BROAD_FILESYSTEM_ACCESS
|
||||
FolderPicker^ picker = ref new FolderPicker();
|
||||
picker->ViewMode = PickerViewMode::List;
|
||||
picker->SuggestedStartLocation = PickerLocationId::ComputerFolder;
|
||||
|
||||
for (auto& x : params.extensions)
|
||||
{
|
||||
wstring wstr;
|
||||
StringConvert(x, wstr);
|
||||
wstr = L"." + wstr;
|
||||
picker->FileTypeFilter->Append(ref new String(wstr.c_str()));
|
||||
}
|
||||
|
||||
create_task(picker->PickSingleFolderAsync()).then([=](StorageFolder^ folder) {
|
||||
if (folder)
|
||||
{
|
||||
auto futureaccess = StorageApplicationPermissions::FutureAccessList;
|
||||
futureaccess->Clear();
|
||||
futureaccess->Add(folder);
|
||||
|
||||
FileOpenPicker^ filepicker = ref new FileOpenPicker();
|
||||
filepicker->ViewMode = PickerViewMode::List;
|
||||
filepicker->SuggestedStartLocation = PickerLocationId::ComputerFolder;
|
||||
|
||||
for (auto& x : params.extensions)
|
||||
{
|
||||
wstring wstr;
|
||||
StringConvert(x, wstr);
|
||||
wstr = L"." + wstr;
|
||||
filepicker->FileTypeFilter->Append(ref new String(wstr.c_str()));
|
||||
}
|
||||
create_task(filepicker->PickSingleFileAsync()).then([=](StorageFile^ file) {
|
||||
if (file)
|
||||
{
|
||||
wstring wstr = file->Path->Data();
|
||||
string str;
|
||||
StringConvert(wstr, str);
|
||||
onSuccess(str);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
#else
|
||||
FileOpenPicker^ picker = ref new FileOpenPicker();
|
||||
picker->ViewMode = PickerViewMode::List;
|
||||
picker->SuggestedStartLocation = PickerLocationId::ComputerFolder;
|
||||
@@ -452,12 +695,17 @@ namespace wiHelper
|
||||
|
||||
if (file)
|
||||
{
|
||||
auto futureaccess = StorageApplicationPermissions::FutureAccessList;
|
||||
futureaccess->Clear();
|
||||
futureaccess->Add(file);
|
||||
wstring wstr = file->Path->Data();
|
||||
string str;
|
||||
StringConvert(wstr, str);
|
||||
onSuccess(str);
|
||||
}
|
||||
});
|
||||
#endif
|
||||
|
||||
}
|
||||
break;
|
||||
case FileDialogParams::SAVE:
|
||||
@@ -480,6 +728,9 @@ namespace wiHelper
|
||||
|
||||
if (file)
|
||||
{
|
||||
auto futureaccess = StorageApplicationPermissions::FutureAccessList;
|
||||
futureaccess->Clear();
|
||||
futureaccess->Add(file);
|
||||
wstring wstr = file->Path->Data();
|
||||
string str;
|
||||
StringConvert(wstr, str);
|
||||
@@ -494,7 +745,7 @@ namespace wiHelper
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
void StringConvert(const std::string from, std::wstring& to)
|
||||
void StringConvert(const std::string& from, std::wstring& to)
|
||||
{
|
||||
int num = MultiByteToWideChar(CP_UTF8, 0, from.c_str(), -1, NULL, 0);
|
||||
if (num > 0)
|
||||
@@ -504,7 +755,7 @@ namespace wiHelper
|
||||
}
|
||||
}
|
||||
|
||||
void StringConvert(const std::wstring from, std::string& to)
|
||||
void StringConvert(const std::wstring& from, std::string& to)
|
||||
{
|
||||
int num = WideCharToMultiByte(CP_UTF8, 0, from.c_str(), -1, NULL, 0, NULL, NULL);
|
||||
if (num > 0)
|
||||
|
||||
@@ -33,8 +33,6 @@ namespace wiHelper
|
||||
|
||||
std::string toUpper(const std::string& s);
|
||||
|
||||
bool readByteData(const std::string& fileName, std::vector<uint8_t>& data);
|
||||
|
||||
void messageBox(const std::string& msg, const std::string& caption = "Warning!");
|
||||
|
||||
void screenshot(const std::string& name = "");
|
||||
@@ -55,8 +53,6 @@ namespace wiHelper
|
||||
|
||||
bool SetWorkingDirectory(const std::string& path);
|
||||
|
||||
void GetFilesInDirectory(std::vector<std::string> &out, const std::string &directory);
|
||||
|
||||
void SplitPath(const std::string& fullPath, std::string& dir, std::string& fileName);
|
||||
|
||||
std::string GetFileNameFromPath(const std::string& fullPath);
|
||||
@@ -67,6 +63,10 @@ namespace wiHelper
|
||||
|
||||
void RemoveExtensionFromFileName(std::string& filename);
|
||||
|
||||
bool FileRead(const std::string& fileName, std::vector<uint8_t>& data);
|
||||
|
||||
bool FileWrite(const std::string& fileName, const uint8_t* data, size_t size);
|
||||
|
||||
bool FileExists(const std::string& fileName);
|
||||
|
||||
struct FileDialogParams
|
||||
@@ -81,9 +81,9 @@ namespace wiHelper
|
||||
};
|
||||
void FileDialog(const FileDialogParams& params, std::function<void(std::string fileName)> onSuccess);
|
||||
|
||||
void StringConvert(const std::string from, std::wstring& to);
|
||||
void StringConvert(const std::string& from, std::wstring& to);
|
||||
|
||||
void StringConvert(const std::wstring from, std::string& to);
|
||||
void StringConvert(const std::wstring& from, std::string& to);
|
||||
|
||||
// Parameter - to - must be pre-allocated!
|
||||
// returns result string length
|
||||
|
||||
+35
-8
@@ -1,6 +1,7 @@
|
||||
#include "wiLua.h"
|
||||
#include "wiLua_Globals.h"
|
||||
#include "wiBackLog.h"
|
||||
#include "wiHelper.h"
|
||||
#include "MainComponent_BindLua.h"
|
||||
#include "RenderPath_BindLua.h"
|
||||
#include "RenderPath2D_BindLua.h"
|
||||
@@ -27,17 +28,36 @@
|
||||
|
||||
#include <sstream>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define WILUA_ERROR_PREFIX "[Lua Error] "
|
||||
|
||||
int Internal_DoFile(lua_State* L)
|
||||
{
|
||||
int argc = wiLua::SGetArgCount(L);
|
||||
|
||||
if (argc > 0)
|
||||
{
|
||||
std::string filename = wiLua::SGetString(L, 1);
|
||||
wiLua::GetGlobal()->RunFile(filename);
|
||||
}
|
||||
else
|
||||
{
|
||||
wiLua::SError(L, "dofile(string filename) not enough arguments!");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
wiLua::wiLua()
|
||||
{
|
||||
m_luaState = NULL;
|
||||
m_luaState = luaL_newstate();
|
||||
luaL_openlibs(m_luaState);
|
||||
RegisterFunc("debugout", DebugOut);
|
||||
RegisterFunc("dofile", Internal_DoFile);
|
||||
RunText(wiLua_Globals);
|
||||
}
|
||||
|
||||
@@ -134,16 +154,23 @@ void wiLua::PostErrorMsg(bool todebug, bool tobacklog)
|
||||
}
|
||||
bool wiLua::RunFile(const std::string& filename)
|
||||
{
|
||||
lock.lock();
|
||||
m_status = luaL_loadfile(m_luaState, filename.c_str());
|
||||
lock.unlock();
|
||||
|
||||
if (Success()) {
|
||||
return RunScript();
|
||||
std::vector<uint8_t> filedata;
|
||||
if (wiHelper::FileRead(filename, filedata))
|
||||
{
|
||||
return RunText(string(filedata.begin(), filedata.end()));
|
||||
}
|
||||
|
||||
PostErrorMsg();
|
||||
return false;
|
||||
|
||||
//lock.lock();
|
||||
//m_status = luaL_loadfile(m_luaState, filename.c_str());
|
||||
//lock.unlock();
|
||||
//
|
||||
//if (Success()) {
|
||||
// return RunScript();
|
||||
//}
|
||||
|
||||
//PostErrorMsg();
|
||||
//return false;
|
||||
}
|
||||
bool wiLua::RunText(const std::string& script)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#pragma once
|
||||
// This file includes platform, os specific libraries and supplies common platform specific resources
|
||||
|
||||
#include <vector>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@@ -26,10 +30,18 @@ namespace wiPlatform
|
||||
#endif // PLATFORM_UWP
|
||||
#endif // _WIN32
|
||||
|
||||
struct DeferredMessageBox
|
||||
{
|
||||
std::wstring caption;
|
||||
std::wstring message;
|
||||
};
|
||||
|
||||
struct WindowState
|
||||
{
|
||||
window_type window;
|
||||
int dpi = 96;
|
||||
std::vector<DeferredMessageBox> messages;
|
||||
std::mutex messagemutex;
|
||||
};
|
||||
inline WindowState& GetWindowState()
|
||||
{
|
||||
@@ -81,4 +93,21 @@ namespace wiPlatform
|
||||
#endif // PLATFORM_UWP
|
||||
#endif // _WIN32
|
||||
}
|
||||
inline void PopMessages()
|
||||
{
|
||||
auto& state = GetWindowState();
|
||||
state.messagemutex.lock();
|
||||
for (auto& x : state.messages)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
#ifndef PLATFORM_UWP
|
||||
MessageBox(wiPlatform::GetWindow(), x.message.c_str(), x.caption.c_str(), 0);
|
||||
#else
|
||||
Windows::UI::Popups::MessageDialog(ref new Platform::String(x.message.c_str()), ref new Platform::String(x.caption.c_str())).ShowAsync();
|
||||
#endif // PLATFORM_UWP
|
||||
#endif // _WIN32
|
||||
}
|
||||
state.messages.clear();
|
||||
state.messagemutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1028,7 +1028,7 @@ Shader tiledLightingCS[TILEDLIGHTING_TYPE_COUNT][TILEDLIGHTING_CULLING_COUNT][TI
|
||||
bool LoadShader(SHADERSTAGE stage, wiGraphics::Shader& shader, const std::string& filename)
|
||||
{
|
||||
vector<uint8_t> buffer;
|
||||
if (wiHelper::readByteData(SHADERPATH + filename, buffer))
|
||||
if (wiHelper::FileRead(SHADERPATH + filename, buffer))
|
||||
{
|
||||
return GetDevice()->CreateShader(stage, buffer.data(), buffer.size(), &shader);
|
||||
}
|
||||
|
||||
@@ -57,6 +57,12 @@ namespace wiResourceManager
|
||||
return resource;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> filedata;
|
||||
if (!wiHelper::FileRead(name, filedata))
|
||||
{
|
||||
resource.reset();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::string ext = wiHelper::toUpper(name.substr(name.length() - 3, name.length()));
|
||||
wiResource::DATA_TYPE type;
|
||||
@@ -85,7 +91,7 @@ namespace wiResourceManager
|
||||
// Load dds
|
||||
|
||||
tinyddsloader::DDSFile dds;
|
||||
auto result = dds.Load(name.c_str());
|
||||
auto result = dds.Load(std::move(filedata));
|
||||
|
||||
if (result == tinyddsloader::Result::Success)
|
||||
{
|
||||
@@ -226,7 +232,7 @@ namespace wiResourceManager
|
||||
|
||||
const int channelCount = 4;
|
||||
int width, height, bpp;
|
||||
unsigned char* rgb = stbi_load(name.c_str(), &width, &height, &bpp, channelCount);
|
||||
unsigned char* rgb = stbi_load_from_memory(filedata.data(), (int)filedata.size(), &width, &height, &bpp, channelCount);
|
||||
|
||||
if (rgb != nullptr)
|
||||
{
|
||||
@@ -275,7 +281,7 @@ namespace wiResourceManager
|
||||
case wiResource::SOUND:
|
||||
{
|
||||
wiAudio::Sound* sound = new wiAudio::Sound;
|
||||
if (wiAudio::CreateSound(name, sound))
|
||||
if (wiAudio::CreateSound(filedata, sound))
|
||||
{
|
||||
success = sound;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace wiVersion
|
||||
// minor features, major updates
|
||||
const int minor = 41;
|
||||
// minor bug fixes, alterations, refactors, updates
|
||||
const int revision = 10;
|
||||
const int revision = 11;
|
||||
|
||||
const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user