Made emscripten work a bit better
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,9 +4,6 @@
|
||||
[submodule "lib/glm"]
|
||||
path = lib/glm
|
||||
url = https://github.com/g-truc/glm.git
|
||||
[submodule "lib/stb"]
|
||||
path = lib/stb
|
||||
url = https://github.com/nothings/stb
|
||||
[submodule "lib/SDL"]
|
||||
path = lib/SDL
|
||||
url = https://github.com/libsdl-org/SDL.git
|
||||
|
@ -3,11 +3,6 @@
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Check for build target, or default. This is pretty much not guaranteed.
|
||||
if(NOT DEFINED DAWN_BUILD_TARGET)
|
||||
set(DAWN_BUILD_TARGET "target-tools")
|
||||
endif()
|
||||
|
||||
# Now validate we have a build target for real
|
||||
if(NOT DEFINED DAWN_BUILD_TARGET)
|
||||
message(FATAL_ERROR "You need to define a DAWN_BUILD_TARGET")
|
||||
|
15
cmake/targets/target-helloworld-emscripten/CMakeLists.txt
Normal file
15
cmake/targets/target-helloworld-emscripten/CMakeLists.txt
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (c) 2023 Dominic Masters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
set(DAWN_BUILDING dawnhelloworld CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_BUILD_HOST_LIBS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_EMSCRIPTEN true CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_NAME "HelloWorld" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
|
||||
set(DAWN_EMSCRIPTEN_FLAGS "" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
|
||||
# Ensures a .HTML file is generated.
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".html" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
@ -6,4 +6,5 @@
|
||||
set(DAWN_BUILDING dawnhelloworld CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_LINUX64 true CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_GLFW true CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_NAME "HelloWorld" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_NAME "HelloWorld" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
set(DAWN_TARGET_ARCHIVE true CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
30
index.html
Normal file
30
index.html
Normal file
@ -0,0 +1,30 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Home</title>
|
||||
|
||||
<style type="text/css">
|
||||
body {
|
||||
background-color: #000000;
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
canvas {
|
||||
border: 1px solid red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Hello Emscripten</h1>
|
||||
|
||||
<canvas id="tutorial" width="300" height="300"></canvas>
|
||||
|
||||
<script type="text/javascript">
|
||||
window.Module = {};
|
||||
window.Module.canvas = document.getElementById('tutorial');
|
||||
|
||||
</script>
|
||||
<script src="./build/src/dawnhelloworld/HelloWorld.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -7,6 +7,7 @@
|
||||
if(DAWN_TARGET_GLFW)
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||
set(DAWN_EMSCRIPTEN_FLAGS "${DAWN_EMSCRIPTEN_FLAGS} -s USE_GLFW=3" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
add_subdirectory(glad)
|
||||
else()
|
||||
add_subdirectory(glad)
|
||||
add_subdirectory(glfw)
|
||||
@ -22,10 +23,6 @@ endif()
|
||||
# GLM
|
||||
add_subdirectory(glm)
|
||||
|
||||
# STB
|
||||
add_library(stb INTERFACE)
|
||||
target_include_directories(stb INTERFACE stb)
|
||||
|
||||
# FreeType
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten")
|
||||
set(DAWN_EMSCRIPTEN_FLAGS "${DAWN_EMSCRIPTEN_FLAGS} -s USE_FREETYPE=1" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
||||
@ -34,7 +31,9 @@ else()
|
||||
endif()
|
||||
|
||||
# LibArchive
|
||||
add_subdirectory(libarchive)
|
||||
if(DAWN_TARGET_ARCHIVE)
|
||||
add_subdirectory(libarchive)
|
||||
endif()
|
||||
|
||||
# OpenAL
|
||||
if(DAWN_TARGET_OPENAL)
|
||||
|
1
lib/stb
1
lib/stb
Submodule lib/stb deleted from 5736b15f7e
@ -57,6 +57,12 @@ if(DEFINED DAWN_TARGET_NAME)
|
||||
add_subdirectory(dawnopengl)
|
||||
endif()
|
||||
|
||||
if(DAWN_TARGET_ARCHIVE)
|
||||
add_subdirectory(dawnarchiveasset)
|
||||
else()
|
||||
add_subdirectory(dawnfileasset)
|
||||
endif()
|
||||
|
||||
if(DAWN_TARGET_VITA)
|
||||
add_subdirectory(dawnopengl)
|
||||
endif()
|
||||
|
@ -7,9 +7,7 @@
|
||||
target_link_libraries(${DAWN_TARGET_NAME}
|
||||
PUBLIC
|
||||
glm
|
||||
stb
|
||||
freetype
|
||||
archive_static
|
||||
)
|
||||
|
||||
# Includes
|
||||
|
@ -7,7 +7,7 @@
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
Asset.cpp
|
||||
AssetLoader.cpp
|
||||
IAssetLoader.cpp
|
||||
AssetManager.cpp
|
||||
)
|
||||
|
||||
|
22
src/dawn/asset/IAssetLoader.cpp
Normal file
22
src/dawn/asset/IAssetLoader.cpp
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "IAssetLoader.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
IAssetLoader::IAssetLoader(std::string fileName) {
|
||||
assertTrue(fileName.size() > 0, "IAssetLoader::IAssetLoader: fileName must be greater than 0");
|
||||
this->fileName = fileName;
|
||||
}
|
||||
|
||||
size_t IAssetLoader::setPosition(size_t position) {
|
||||
assertTrue(position >= 0, "IAssetLoader::setPosition: position must be greater than or equal to 0");
|
||||
this->rewind();
|
||||
return this->skip(position);
|
||||
}
|
||||
|
||||
IAssetLoader::~IAssetLoader() {
|
||||
}
|
@ -4,10 +4,6 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
extern "C" {
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
}
|
||||
#include "dawnlibs.hpp"
|
||||
#include "assert/assert.hpp"
|
||||
#include "util/memory.hpp"
|
||||
@ -18,87 +14,30 @@ extern "C" {
|
||||
#error Asset Archive Location has not been defined.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to read bytes from the archive
|
||||
* file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the read.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @param buffer Pointer to where the buffer pointer should be stored.
|
||||
* @return Count of bytes read.
|
||||
*/
|
||||
ssize_t assetLoaderArchiveRead(
|
||||
struct archive *archive,
|
||||
void *data,
|
||||
const void **buffer
|
||||
);
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to seek the archive file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the seek.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @param offset Offset to seek to.
|
||||
* @param whence Whence to seek from.
|
||||
* @return The new offset.
|
||||
*/
|
||||
int64_t assetLoaderArchiveSeek(
|
||||
struct archive *archive,
|
||||
void *data,
|
||||
int64_t offset,
|
||||
int32_t whence
|
||||
);
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to open the archive file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the open.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
int32_t assetLoaderArchiveOpen(struct archive *a, void *data);
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to close the archive file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the close.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
int32_t assetLoaderArchiveClose(struct archive *a, void *data);
|
||||
|
||||
namespace Dawn {
|
||||
class AssetLoader {
|
||||
private:
|
||||
class IAssetLoader {
|
||||
protected:
|
||||
std::string fileName;
|
||||
struct archive *assetArchive = nullptr;
|
||||
struct archive_entry *assetArchiveEntry = nullptr;
|
||||
size_t position;
|
||||
|
||||
public:
|
||||
uint8_t buffer[ASSET_LOADER_BUFFER_SIZE];
|
||||
FILE *assetArchiveFile = nullptr;
|
||||
|
||||
/**
|
||||
* Create a new asset loader. Asset Loaders can be used to load data from
|
||||
* a file in a myriad of ways.
|
||||
*
|
||||
* @param fileName File name of the asset that is to be loaded.
|
||||
*/
|
||||
AssetLoader(std::string fileName);
|
||||
IAssetLoader(std::string fileName);
|
||||
|
||||
/**
|
||||
* Platform-centric method to open a file buffer to an asset.
|
||||
*
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
void open();
|
||||
virtual void open() = 0;
|
||||
|
||||
/**
|
||||
* Closes the previously ppened asset.
|
||||
* @return 0 if successful, otherwise false.
|
||||
*/
|
||||
int32_t close();
|
||||
virtual int32_t close() = 0;
|
||||
|
||||
/**
|
||||
* Read bytes from buffer.
|
||||
@ -106,13 +45,13 @@ namespace Dawn {
|
||||
* @param size Length of the data buffer (How many bytes to read).
|
||||
* @return The count of bytes read.
|
||||
*/
|
||||
size_t read(uint8_t *buffer, size_t size);
|
||||
virtual size_t read(uint8_t *buffer, size_t size) = 0;
|
||||
|
||||
/**
|
||||
* Get the size of the asset.
|
||||
* @return The size of the asset in bytes.
|
||||
*/
|
||||
size_t getSize();
|
||||
virtual size_t getSize() = 0;
|
||||
|
||||
/**
|
||||
* Skips the read head forward to a given position.
|
||||
@ -120,12 +59,12 @@ namespace Dawn {
|
||||
* @param n Count of bytes to progress the read head by.
|
||||
* @return Count of bytes progressed.
|
||||
*/
|
||||
size_t skip(size_t n);
|
||||
virtual size_t skip(size_t n) = 0;
|
||||
|
||||
/**
|
||||
* Rewind the read head to the beginning of the file.
|
||||
*/
|
||||
void rewind();
|
||||
virtual void rewind() = 0;
|
||||
|
||||
/**
|
||||
* Sets the absolute position of the read head within the buffer of the
|
||||
@ -140,7 +79,7 @@ namespace Dawn {
|
||||
*
|
||||
* @return The current read head position.
|
||||
*/
|
||||
size_t getPosition();
|
||||
virtual size_t getPosition() = 0;
|
||||
|
||||
/**
|
||||
* Run a callback for each byte within the asset. The callback will
|
||||
@ -189,6 +128,6 @@ namespace Dawn {
|
||||
/**
|
||||
* Cleanup the asset loader.
|
||||
*/
|
||||
virtual ~AssetLoader();
|
||||
virtual ~IAssetLoader();
|
||||
};
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AudioSource;
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
struct AssetLanguageValue {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "display/Texture.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "display/Tileset.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
|
@ -5,7 +5,7 @@
|
||||
|
||||
#pragma once
|
||||
#include "../Asset.hpp"
|
||||
#include "../AssetLoader.hpp"
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "util/flag.hpp"
|
||||
#include "display/font/truetype/TrueTypeFaceTexture.hpp"
|
||||
#include "util/UsageLock.hpp"
|
||||
|
@ -9,8 +9,6 @@
|
||||
#include "dawnsharedlibs.hpp"
|
||||
#include "util/memory.hpp"
|
||||
|
||||
#include <stb_truetype.h>
|
||||
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
|
||||
|
@ -27,7 +27,7 @@ TrueTypeFaceTexture::TrueTypeFaceTexture(
|
||||
// First pass, determine the textures' dimensions.
|
||||
for(c = TRUE_TYPE_CHAR_BEGIN; c < TRUE_TYPE_CHAR_END; c++) {
|
||||
// Load the character
|
||||
auto ret = FT_Load_Char(face, c, FT_LOAD_BITMAP_METRICS_ONLY);
|
||||
auto ret = FT_Load_Char(face, c, ~FT_LOAD_RENDER);
|
||||
if(ret) {
|
||||
assertUnreachable("TrueTypeFaceTexture::TrueTypeFaceTexture: Failed to load character (0)");
|
||||
}
|
||||
|
@ -20,6 +20,7 @@ namespace Dawn {
|
||||
public:
|
||||
virtual void removeListener() = 0;
|
||||
virtual void teardown() = 0;
|
||||
virtual ~IStateOwnerEventLegacy() {}
|
||||
};
|
||||
|
||||
class IStateOwner {
|
||||
|
20
src/dawnarchiveasset/CMakeLists.txt
Normal file
20
src/dawnarchiveasset/CMakeLists.txt
Normal file
@ -0,0 +1,20 @@
|
||||
# Copyright (c) 2023 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Libraries
|
||||
target_link_libraries(${DAWN_TARGET_NAME}
|
||||
PUBLIC
|
||||
archive_static
|
||||
)
|
||||
|
||||
# Includes
|
||||
target_include_directories(${DAWN_TARGET_NAME}
|
||||
PUBLIC
|
||||
${DAWN_SHARED_INCLUDES}
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(asset)
|
@ -1,180 +1,171 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetLoader.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ssize_t assetLoaderArchiveRead(
|
||||
struct archive *archive,
|
||||
void *d,
|
||||
const void **buffer
|
||||
) {
|
||||
assertNotNull(archive, "assetArchiveRead: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveRead: Data is NULL!");
|
||||
assertNotNull(buffer, "assetArchiveRead: Buffer is NULL!");
|
||||
AssetLoader *loader = (AssetLoader*)d;
|
||||
|
||||
*buffer = loader->buffer;
|
||||
size_t read = fread(
|
||||
loader->buffer, 1, ASSET_LOADER_BUFFER_SIZE, loader->assetArchiveFile
|
||||
);
|
||||
if(ferror(loader->assetArchiveFile)) return ARCHIVE_FATAL;
|
||||
return read;
|
||||
}
|
||||
|
||||
int64_t assetLoaderArchiveSeek(
|
||||
struct archive *archive,
|
||||
void *d,
|
||||
int64_t offset,
|
||||
int32_t whence
|
||||
) {
|
||||
assertNotNull(archive, "assetArchiveSeek: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveSeek: Data is NULL!");
|
||||
assertTrue(offset > 0, "assetArchiveSeek: Offset must be greater than 0!");
|
||||
AssetLoader *loader = (AssetLoader*)d;
|
||||
int32_t ret = fseek(loader->assetArchiveFile, offset, whence);
|
||||
assertTrue(ret == 0, "assetArchiveSeek: Failed to seek!");
|
||||
return ftell(loader->assetArchiveFile);
|
||||
}
|
||||
|
||||
int32_t assetLoaderArchiveOpen(struct archive *a, void *d) {
|
||||
assertNotNull(a, "assetArchiveOpen: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveOpen: Data is NULL!");
|
||||
AssetLoader *loader = (AssetLoader*)d;
|
||||
|
||||
int32_t ret = fseek(loader->assetArchiveFile, 0, SEEK_SET);
|
||||
assertTrue(ret == 0, "assetArchiveOpen: Failed to seek to start of file!");
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
int32_t assetLoaderArchiveClose(struct archive *a, void *d) {
|
||||
assertNotNull(a, "assetArchiveClose: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveClose: Data is NULL!");
|
||||
return assetLoaderArchiveOpen(a, d);
|
||||
}
|
||||
|
||||
AssetLoader::AssetLoader(std::string fileName) {
|
||||
assertTrue(fileName.size() > 0, "AssetLoader::AssetLoader: fileName must be greater than 0");
|
||||
this->fileName = fileName;
|
||||
}
|
||||
|
||||
void AssetLoader::open() {
|
||||
assertNull(this->assetArchiveFile, "AssetLoader::open: File is already open");
|
||||
assertNull(this->assetArchive, "AssetLoader::open: Archive is already open");
|
||||
assertNull(this->assetArchiveEntry, "AssetLoader::open: Entry is already open");
|
||||
|
||||
this->assetArchiveFile = fopen(DAWN_ASSET_LOCATION, "rb");
|
||||
assertNotNull(this->assetArchiveFile, "AssetLoader::open: Failed to open file " + std::string(DAWN_ASSET_LOCATION));
|
||||
|
||||
// Open archive reader
|
||||
assetArchive = archive_read_new();
|
||||
assertNotNull(assetArchive, "AssetLoader::open: Failed to create archive reader");
|
||||
|
||||
// Set up the reader
|
||||
archive_read_support_format_tar(assetArchive);
|
||||
|
||||
// Open reader
|
||||
archive_read_set_open_callback(assetArchive, &assetLoaderArchiveOpen);
|
||||
archive_read_set_read_callback(assetArchive, &assetLoaderArchiveRead);
|
||||
archive_read_set_seek_callback(assetArchive, &assetLoaderArchiveSeek);
|
||||
archive_read_set_close_callback(assetArchive, &assetLoaderArchiveClose);
|
||||
archive_read_set_callback_data(assetArchive, this);
|
||||
|
||||
int32_t ret = archive_read_open1(assetArchive);
|
||||
assertTrue(ret == ARCHIVE_OK, "AssetLoader::open: Failed to open archive!");
|
||||
position = 0;
|
||||
|
||||
// Iterate over each file to find the one for this asset loader.
|
||||
while(archive_read_next_header(assetArchive, &assetArchiveEntry) == ARCHIVE_OK) {
|
||||
const char_t *headerFile = (char_t*)archive_entry_pathname(assetArchiveEntry);
|
||||
if(std::string(headerFile) == this->fileName) return;
|
||||
int32_t ret = archive_read_data_skip(assetArchive);
|
||||
assertTrue(ret == ARCHIVE_OK, "AssetLoader::open: Failed to skip data!");
|
||||
}
|
||||
|
||||
assertUnreachable("AssetLoader::open: Failed to find file!");
|
||||
}
|
||||
|
||||
int32_t AssetLoader::close() {
|
||||
assertNotNull(this->assetArchiveFile, "AssetLoader::close: File is NULL");
|
||||
assertNotNull(this->assetArchive, "AssetLoader::close: Archive is NULL!");
|
||||
assertNotNull(this->assetArchiveEntry, "AssetLoader::close: Entry is NULL!");
|
||||
|
||||
// Close the archive
|
||||
int32_t ret = archive_read_free(this->assetArchive);
|
||||
assertTrue(ret == ARCHIVE_OK, "AssetLoader::close: Failed to close archive!");
|
||||
|
||||
this->assetArchive = nullptr;
|
||||
this->assetArchiveEntry = nullptr;
|
||||
|
||||
// Close the file
|
||||
int32_t res = fclose(this->assetArchiveFile);
|
||||
this->assetArchiveFile = nullptr;
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t AssetLoader::read(uint8_t *buffer, size_t size) {
|
||||
assertNotNull(buffer, "assetArchiveRead: Buffer is NULL!");
|
||||
assertTrue(size > 0, "assetArchiveRead: Size must be greater than 0!");
|
||||
assertNotNull(this->assetArchive, "assetRead: Archive is NULL!");
|
||||
assertNotNull(this->assetArchiveEntry, "assetRead: Entry is NULL!");
|
||||
|
||||
ssize_t read = archive_read_data(this->assetArchive, buffer, size);
|
||||
this->position += read;
|
||||
|
||||
if(read == ARCHIVE_FATAL) {
|
||||
assertUnreachable(archive_error_string(this->assetArchive));
|
||||
}
|
||||
|
||||
assertTrue(read != ARCHIVE_RETRY, "assetRead: Failed to read data (RETRY)!");
|
||||
assertTrue(read != ARCHIVE_WARN, "assetRead: Failed to read data (WARN)!");
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
size_t AssetLoader::getSize() {
|
||||
assertTrue(this->assetArchiveEntry != nullptr, "AssetLoader::getSize: Entry is NULL!");
|
||||
assertTrue(archive_entry_size_is_set(assetArchiveEntry), "assetGetSize: Entry size is not set!");
|
||||
return archive_entry_size(assetArchiveEntry);
|
||||
}
|
||||
|
||||
size_t AssetLoader::skip(size_t n) {
|
||||
assertTrue(n >= 0, "AssetLoader::skip: Byte count must be greater than 0.");
|
||||
|
||||
uint8_t dumpBuffer[ASSET_LOADER_BUFFER_SIZE];
|
||||
size_t skipped = 0;
|
||||
size_t n2, n3;
|
||||
while(n != 0) {
|
||||
n2 = mathMin<size_t>(n, ASSET_LOADER_BUFFER_SIZE);
|
||||
n3 = this->read(dumpBuffer, n2);
|
||||
assertTrue(n3 == n2, "AssetLoader::skip: Failed to skip bytes!");
|
||||
n -= n3;
|
||||
}
|
||||
|
||||
return skipped;
|
||||
}
|
||||
|
||||
void AssetLoader::rewind() {
|
||||
// TODO: See if I can optimize this
|
||||
this->close();
|
||||
this->open();
|
||||
}
|
||||
|
||||
size_t AssetLoader::getPosition() {
|
||||
assertNotNull(this->assetArchiveFile, "AssetLoader::getPosition: File is not open!");
|
||||
return this->position;
|
||||
}
|
||||
|
||||
size_t AssetLoader::setPosition(size_t position) {
|
||||
assertTrue(position >= 0, "AssetLoader::setPosition: position must be greater than or equal to 0");
|
||||
this->rewind();
|
||||
return this->skip(position);
|
||||
}
|
||||
|
||||
AssetLoader::~AssetLoader() {
|
||||
if(this->assetArchiveFile != nullptr) this->close();
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "AssetLoader.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
ssize_t assetLoaderArchiveRead(
|
||||
struct archive *archive,
|
||||
void *d,
|
||||
const void **buffer
|
||||
) {
|
||||
assertNotNull(archive, "assetArchiveRead: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveRead: Data is NULL!");
|
||||
assertNotNull(buffer, "assetArchiveRead: Buffer is NULL!");
|
||||
AssetLoader *loader = (AssetLoader*)d;
|
||||
|
||||
*buffer = loader->buffer;
|
||||
size_t read = fread(
|
||||
loader->buffer, 1, ASSET_LOADER_BUFFER_SIZE, loader->assetArchiveFile
|
||||
);
|
||||
if(ferror(loader->assetArchiveFile)) return ARCHIVE_FATAL;
|
||||
return read;
|
||||
}
|
||||
|
||||
int64_t assetLoaderArchiveSeek(
|
||||
struct archive *archive,
|
||||
void *d,
|
||||
int64_t offset,
|
||||
int32_t whence
|
||||
) {
|
||||
assertNotNull(archive, "assetArchiveSeek: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveSeek: Data is NULL!");
|
||||
assertTrue(offset > 0, "assetArchiveSeek: Offset must be greater than 0!");
|
||||
AssetLoader *loader = (AssetLoader*)d;
|
||||
int32_t ret = fseek(loader->assetArchiveFile, offset, whence);
|
||||
assertTrue(ret == 0, "assetArchiveSeek: Failed to seek!");
|
||||
return ftell(loader->assetArchiveFile);
|
||||
}
|
||||
|
||||
int32_t assetLoaderArchiveOpen(struct archive *a, void *d) {
|
||||
assertNotNull(a, "assetArchiveOpen: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveOpen: Data is NULL!");
|
||||
AssetLoader *loader = (AssetLoader*)d;
|
||||
|
||||
int32_t ret = fseek(loader->assetArchiveFile, 0, SEEK_SET);
|
||||
assertTrue(ret == 0, "assetArchiveOpen: Failed to seek to start of file!");
|
||||
return ARCHIVE_OK;
|
||||
}
|
||||
|
||||
int32_t assetLoaderArchiveClose(struct archive *a, void *d) {
|
||||
assertNotNull(a, "assetArchiveClose: Archive is NULL!");
|
||||
assertNotNull(d, "assetArchiveClose: Data is NULL!");
|
||||
return assetLoaderArchiveOpen(a, d);
|
||||
}
|
||||
|
||||
AssetLoader::AssetLoader(std::string fileName) : IAssetLoader(fileName) {}
|
||||
|
||||
void AssetLoader::open() {
|
||||
assertNull(this->assetArchiveFile, "AssetLoader::open: File is already open");
|
||||
assertNull(this->assetArchive, "AssetLoader::open: Archive is already open");
|
||||
assertNull(this->assetArchiveEntry, "AssetLoader::open: Entry is already open");
|
||||
|
||||
this->assetArchiveFile = fopen(DAWN_ASSET_LOCATION, "rb");
|
||||
assertNotNull(this->assetArchiveFile, "AssetLoader::open: Failed to open file " + std::string(DAWN_ASSET_LOCATION));
|
||||
|
||||
// Open archive reader
|
||||
assetArchive = archive_read_new();
|
||||
assertNotNull(assetArchive, "AssetLoader::open: Failed to create archive reader");
|
||||
|
||||
// Set up the reader
|
||||
archive_read_support_format_tar(assetArchive);
|
||||
|
||||
// Open reader
|
||||
archive_read_set_open_callback(assetArchive, &assetLoaderArchiveOpen);
|
||||
archive_read_set_read_callback(assetArchive, &assetLoaderArchiveRead);
|
||||
archive_read_set_seek_callback(assetArchive, &assetLoaderArchiveSeek);
|
||||
archive_read_set_close_callback(assetArchive, &assetLoaderArchiveClose);
|
||||
archive_read_set_callback_data(assetArchive, this);
|
||||
|
||||
int32_t ret = archive_read_open1(assetArchive);
|
||||
assertTrue(ret == ARCHIVE_OK, "AssetLoader::open: Failed to open archive!");
|
||||
position = 0;
|
||||
|
||||
// Iterate over each file to find the one for this asset loader.
|
||||
while(archive_read_next_header(assetArchive, &assetArchiveEntry) == ARCHIVE_OK) {
|
||||
const char_t *headerFile = (char_t*)archive_entry_pathname(assetArchiveEntry);
|
||||
if(std::string(headerFile) == this->fileName) return;
|
||||
int32_t ret = archive_read_data_skip(assetArchive);
|
||||
assertTrue(ret == ARCHIVE_OK, "AssetLoader::open: Failed to skip data!");
|
||||
}
|
||||
|
||||
assertUnreachable("AssetLoader::open: Failed to find file!");
|
||||
}
|
||||
|
||||
int32_t AssetLoader::close() {
|
||||
assertNotNull(this->assetArchiveFile, "AssetLoader::close: File is NULL");
|
||||
assertNotNull(this->assetArchive, "AssetLoader::close: Archive is NULL!");
|
||||
assertNotNull(this->assetArchiveEntry, "AssetLoader::close: Entry is NULL!");
|
||||
|
||||
// Close the archive
|
||||
int32_t ret = archive_read_free(this->assetArchive);
|
||||
assertTrue(ret == ARCHIVE_OK, "AssetLoader::close: Failed to close archive!");
|
||||
|
||||
this->assetArchive = nullptr;
|
||||
this->assetArchiveEntry = nullptr;
|
||||
|
||||
// Close the file
|
||||
int32_t res = fclose(this->assetArchiveFile);
|
||||
this->assetArchiveFile = nullptr;
|
||||
return res;
|
||||
}
|
||||
|
||||
size_t AssetLoader::read(uint8_t *buffer, size_t size) {
|
||||
assertNotNull(buffer, "assetArchiveRead: Buffer is NULL!");
|
||||
assertTrue(size > 0, "assetArchiveRead: Size must be greater than 0!");
|
||||
assertNotNull(this->assetArchive, "assetRead: Archive is NULL!");
|
||||
assertNotNull(this->assetArchiveEntry, "assetRead: Entry is NULL!");
|
||||
|
||||
ssize_t read = archive_read_data(this->assetArchive, buffer, size);
|
||||
this->position += read;
|
||||
|
||||
if(read == ARCHIVE_FATAL) {
|
||||
assertUnreachable(archive_error_string(this->assetArchive));
|
||||
}
|
||||
|
||||
assertTrue(read != ARCHIVE_RETRY, "assetRead: Failed to read data (RETRY)!");
|
||||
assertTrue(read != ARCHIVE_WARN, "assetRead: Failed to read data (WARN)!");
|
||||
|
||||
return read;
|
||||
}
|
||||
|
||||
size_t AssetLoader::getSize() {
|
||||
assertTrue(this->assetArchiveEntry != nullptr, "AssetLoader::getSize: Entry is NULL!");
|
||||
assertTrue(archive_entry_size_is_set(assetArchiveEntry), "assetGetSize: Entry size is not set!");
|
||||
return archive_entry_size(assetArchiveEntry);
|
||||
}
|
||||
|
||||
size_t AssetLoader::skip(size_t n) {
|
||||
assertTrue(n >= 0, "AssetLoader::skip: Byte count must be greater than 0.");
|
||||
|
||||
uint8_t dumpBuffer[ASSET_LOADER_BUFFER_SIZE];
|
||||
size_t skipped = 0;
|
||||
size_t n2, n3;
|
||||
while(n != 0) {
|
||||
n2 = mathMin<size_t>(n, ASSET_LOADER_BUFFER_SIZE);
|
||||
n3 = this->read(dumpBuffer, n2);
|
||||
assertTrue(n3 == n2, "AssetLoader::skip: Failed to skip bytes!");
|
||||
n -= n3;
|
||||
}
|
||||
|
||||
return skipped;
|
||||
}
|
||||
|
||||
void AssetLoader::rewind() {
|
||||
// TODO: See if I can optimize this
|
||||
this->close();
|
||||
this->open();
|
||||
}
|
||||
|
||||
size_t AssetLoader::getPosition() {
|
||||
assertNotNull(this->assetArchiveFile, "AssetLoader::getPosition: File is not open!");
|
||||
return this->position;
|
||||
}
|
||||
|
||||
AssetLoader::~AssetLoader() {
|
||||
if(this->assetArchiveFile != nullptr) this->close();
|
||||
}
|
83
src/dawnarchiveasset/asset/AssetLoader.hpp
Normal file
83
src/dawnarchiveasset/asset/AssetLoader.hpp
Normal file
@ -0,0 +1,83 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
extern "C" {
|
||||
#include <archive.h>
|
||||
#include <archive_entry.h>
|
||||
}
|
||||
#include "asset/IAssetLoader.hpp"
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to read bytes from the archive
|
||||
* file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the read.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @param buffer Pointer to where the buffer pointer should be stored.
|
||||
* @return Count of bytes read.
|
||||
*/
|
||||
ssize_t assetLoaderArchiveRead(
|
||||
struct archive *archive,
|
||||
void *data,
|
||||
const void **buffer
|
||||
);
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to seek the archive file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the seek.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @param offset Offset to seek to.
|
||||
* @param whence Whence to seek from.
|
||||
* @return The new offset.
|
||||
*/
|
||||
int64_t assetLoaderArchiveSeek(
|
||||
struct archive *archive,
|
||||
void *data,
|
||||
int64_t offset,
|
||||
int32_t whence
|
||||
);
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to open the archive file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the open.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
int32_t assetLoaderArchiveOpen(struct archive *a, void *data);
|
||||
|
||||
/**
|
||||
* Method invoked by the libarchive internals to close the archive file pointer.
|
||||
*
|
||||
* @param archive Archive requesting the close.
|
||||
* @param data Data pointer passed to the archive.
|
||||
* @return 0 if success, otherwise for failure.
|
||||
*/
|
||||
int32_t assetLoaderArchiveClose(struct archive *a, void *data);
|
||||
|
||||
namespace Dawn {
|
||||
class AssetLoader : public IAssetLoader {
|
||||
protected:
|
||||
struct archive *assetArchive = nullptr;
|
||||
struct archive_entry *assetArchiveEntry = nullptr;
|
||||
size_t position;
|
||||
|
||||
public:
|
||||
uint8_t buffer[ASSET_LOADER_BUFFER_SIZE];
|
||||
FILE *assetArchiveFile = nullptr;
|
||||
|
||||
AssetLoader(std::string filename);
|
||||
void open() override;
|
||||
int32_t close() override;
|
||||
size_t read(uint8_t *buffer, size_t size) override;
|
||||
size_t getSize() override;
|
||||
size_t skip(size_t n) override;
|
||||
void rewind() override;
|
||||
size_t getPosition() override;
|
||||
~AssetLoader();
|
||||
};
|
||||
}
|
10
src/dawnarchiveasset/asset/CMakeLists.txt
Normal file
10
src/dawnarchiveasset/asset/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2023 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
AssetLoader.cpp
|
||||
)
|
@ -4,8 +4,45 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "host/DawnEmscripten.hpp"
|
||||
#include "host/DawnHost.hpp"
|
||||
#include "game/DawnGame.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
int main() {
|
||||
printf("Hello Emscripten\n");
|
||||
int32_t result;
|
||||
|
||||
memoryInit();
|
||||
auto host = new DawnHost();
|
||||
auto game = new DawnGame(host);
|
||||
|
||||
result = host->init(game);
|
||||
switch(result) {
|
||||
case DAWN_HOST_INIT_RESULT_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
|
||||
// Request the main loop to start running.
|
||||
result = host->start(game);
|
||||
switch(result) {
|
||||
case DAWN_HOST_START_RESULT_SUCCESS:
|
||||
break;
|
||||
case DAWN_HOST_START_RESULT_EXIT_SUCCESS:
|
||||
break;
|
||||
default:
|
||||
return result;
|
||||
}
|
||||
|
||||
// Main loop finished without errors, cleanup
|
||||
host->unload(game);
|
||||
|
||||
delete game;
|
||||
delete host;
|
||||
|
||||
memoryDispose();
|
||||
|
||||
// Success
|
||||
return 0;
|
||||
}
|
@ -4,6 +4,6 @@
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include <stdio.h>
|
||||
#include "dawnlibs.hpp"
|
||||
|
||||
int main();
|
14
src/dawnfileasset/CMakeLists.txt
Normal file
14
src/dawnfileasset/CMakeLists.txt
Normal file
@ -0,0 +1,14 @@
|
||||
# Copyright (c) 2023 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Includes
|
||||
target_include_directories(${DAWN_TARGET_NAME}
|
||||
PUBLIC
|
||||
${DAWN_SHARED_INCLUDES}
|
||||
${CMAKE_CURRENT_LIST_DIR}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(asset)
|
68
src/dawnfileasset/asset/AssetLoader.cpp
Normal file
68
src/dawnfileasset/asset/AssetLoader.cpp
Normal file
@ -0,0 +1,68 @@
|
||||
// Copyright (c) 2022 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#include "asset/AssetLoader.hpp"
|
||||
#include "util/mathutils.hpp"
|
||||
|
||||
using namespace Dawn;
|
||||
|
||||
AssetLoader::AssetLoader(std::string fileName) : IAssetLoader(fileName) {
|
||||
this->handle = nullptr;
|
||||
}
|
||||
|
||||
void AssetLoader::open() {
|
||||
assertNull(this->handle, "AssetLoader::open: File is already open?");
|
||||
|
||||
std::string pathFull = DAWN_ASSET_LOCATION + this->fileName;
|
||||
this->handle = fopen(pathFull.c_str(), "rb");
|
||||
fseek(this->handle, 0, SEEK_END);
|
||||
assertNotNull(this->handle, "AssetLoader::open: Failed to open file " + pathFull);
|
||||
|
||||
this->size = ftell(this->handle);
|
||||
assertTrue(this->size > 0, "AssetLoader::open: File size is 0?");
|
||||
|
||||
this->rewind();
|
||||
}
|
||||
|
||||
int32_t AssetLoader::close() {
|
||||
assertNotNull(this->handle, "AssetLoader::close: File is not open");
|
||||
int32_t ret = fclose(this->handle);
|
||||
this->handle = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
size_t AssetLoader::read(uint8_t *buffer, size_t size) {
|
||||
assertNotNull(buffer, "AssetLoader::read: buffer must not be null");
|
||||
assertTrue(size > 0, "AssetLoader::read: size must be greater than 0");
|
||||
assertNotNull(this->handle, "AssetLoader::read: File is not open");
|
||||
return fread(buffer, 1, size, this->handle);
|
||||
}
|
||||
|
||||
size_t AssetLoader::skip(size_t n) {
|
||||
assertTrue(n > 0, "AssetLoader::skip: n must be greater than 0");
|
||||
assertNotNull(this->handle, "AssetLoader::skip: File is not open");
|
||||
return fseek(this->handle, n, SEEK_CUR);
|
||||
}
|
||||
|
||||
void AssetLoader::rewind() {
|
||||
assertNotNull(this->handle, "AssetLoader::rewind: File is not open");
|
||||
fseek(this->handle, 0, SEEK_SET);
|
||||
}
|
||||
|
||||
size_t AssetLoader::getPosition() {
|
||||
assertNotNull(this->handle, "AssetLoader::getPosition: File is not open");
|
||||
return ftell(this->handle);
|
||||
}
|
||||
|
||||
size_t AssetLoader::getSize() {
|
||||
return this->size;
|
||||
}
|
||||
|
||||
AssetLoader::~AssetLoader() {
|
||||
if(this->handle != nullptr) {
|
||||
this->close();
|
||||
this->handle = nullptr;
|
||||
}
|
||||
}
|
26
src/dawnfileasset/asset/AssetLoader.hpp
Normal file
26
src/dawnfileasset/asset/AssetLoader.hpp
Normal file
@ -0,0 +1,26 @@
|
||||
// Copyright (c) 2023 Dominic Masters
|
||||
//
|
||||
// This software is released under the MIT License.
|
||||
// https://opensource.org/licenses/MIT
|
||||
|
||||
#pragma once
|
||||
#include "asset/IAssetLoader.hpp"
|
||||
|
||||
namespace Dawn {
|
||||
class AssetLoader : public IAssetLoader {
|
||||
private:
|
||||
FILE *handle;
|
||||
size_t size;
|
||||
|
||||
public:
|
||||
AssetLoader(std::string filename);
|
||||
void open() override;
|
||||
int32_t close() override;
|
||||
size_t read(uint8_t *buffer, size_t size) override;
|
||||
size_t getSize() override;
|
||||
size_t skip(size_t n) override;
|
||||
void rewind() override;
|
||||
size_t getPosition() override;
|
||||
~AssetLoader();
|
||||
};
|
||||
}
|
10
src/dawnfileasset/asset/CMakeLists.txt
Normal file
10
src/dawnfileasset/asset/CMakeLists.txt
Normal file
@ -0,0 +1,10 @@
|
||||
# Copyright (c) 2023 Dominic Msters
|
||||
#
|
||||
# This software is released under the MIT License.
|
||||
# https://opensource.org/licenses/MIT
|
||||
|
||||
# Sources
|
||||
target_sources(${DAWN_TARGET_NAME}
|
||||
PRIVATE
|
||||
AssetLoader.cpp
|
||||
)
|
@ -21,12 +21,11 @@ void RenderManager::init() {
|
||||
this->lockSimpleTextured = this->shaderManager.lockShader<SimpleTexturedShader>();
|
||||
this->simpleTexturedShader = this->shaderManager.getShader<SimpleTexturedShader>(this->lockSimpleTextured);
|
||||
|
||||
this->lockUIShaderProgram = this->shaderManager.lockShader<UIShader>();
|
||||
this->uiShader = this->shaderManager.getShader<UIShader>(this->lockUIShaderProgram);
|
||||
|
||||
this->lockFontShader = this->shaderManager.lockShader<FontShader>();
|
||||
this->fontShader = this->shaderManager.getShader<FontShader>(this->lockFontShader);
|
||||
// this->lockUIShaderProgram = this->shaderManager.lockShader<UIShader>();
|
||||
// this->uiShader = this->shaderManager.getShader<UIShader>(this->lockUIShaderProgram);
|
||||
|
||||
// this->lockFontShader = this->shaderManager.lockShader<FontShader>();
|
||||
// this->fontShader = this->shaderManager.getShader<FontShader>(this->lockFontShader);
|
||||
this->renderPipeline.init();
|
||||
assertNoGLError();
|
||||
|
||||
|
@ -64,7 +64,7 @@ namespace Dawn {
|
||||
*/
|
||||
shaderbufferlocation_t getBufferLocationByName(std::string name);
|
||||
|
||||
virtual void compile() = 0;
|
||||
virtual void compile() override = 0;
|
||||
void bind() override;
|
||||
void setParameterBuffer(shaderbufferlocation_t location, shaderbufferslot_t slot);
|
||||
void setMatrix(shaderparameter_t parameter, glm::mat4 matrix) override;
|
||||
|
@ -15,7 +15,7 @@ void SimpleTexturedShader::compile() {
|
||||
{ "aTexCoord", 1 }
|
||||
},
|
||||
// Vertex Shader
|
||||
"#version 330 core\n"
|
||||
"#version 300 es\n"
|
||||
"layout (location = 0) in vec3 aPos;\n"
|
||||
"layout (location = 1) in vec2 aTexCoord;\n" +
|
||||
|
||||
@ -91,6 +91,5 @@ void SimpleTexturedShader::compile() {
|
||||
this->paramColor = this->getParameterByName("u_Color");
|
||||
this->paramTexture = this->getParameterByName("u_Text");
|
||||
this->paramHasTexture = this->getParameterByName("u_HasTexture");
|
||||
|
||||
this->bufferRenderPipeline = this->getBufferLocationByName(RenderPipelineShaderBuffer::getShaderUniformName());
|
||||
}
|
@ -16,4 +16,7 @@ target_compile_definitions(${DAWN_TARGET_NAME}
|
||||
)
|
||||
|
||||
# Subdirs
|
||||
add_subdirectory(host)
|
||||
add_subdirectory(host)
|
||||
|
||||
# Build suffix
|
||||
set(CMAKE_EXECUTABLE_SUFFIX ".exe" CACHE INTERNAL ${DAWN_CACHE_TARGET})
|
Reference in New Issue
Block a user