summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt160
-rw-r--r--assets/final/assets.txt2
-rw-r--r--assets/final/null.bin0
-rw-r--r--assets/final/test_asset.txt3
-rw-r--r--src/tests/test_assets.cc29
-rw-r--r--tools/asset_packer.cc64
6 files changed, 154 insertions, 104 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1d06033..d460131 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -57,6 +57,33 @@ else()
list(APPEND DEMO_LIBS pthread m dl)
endif()
+option(DEMO_BUILD_TOOLS "Build tools" OFF)
+
+# Asset Packing Tool (needed during build if any assets exist)
+if(DEMO_BUILD_TOOLS OR NOT EXISTS ${CMAKE_CURRENT_BINARY_DIR}/src/assets_data.cc)
+ add_executable(asset_packer
+ tools/asset_packer.cc
+ )
+endif()
+
+# Configure asset generation
+set(ASSETS_TXT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/assets.txt)
+set(GENERATED_ASSETS_H ${CMAKE_CURRENT_BINARY_DIR}/src/assets.h)
+set(GENERATED_ASSETS_DATA_CC ${CMAKE_CURRENT_BINARY_DIR}/src/assets_data.cc)
+
+add_custom_command(
+ OUTPUT ${GENERATED_ASSETS_H} ${GENERATED_ASSETS_DATA_CC}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src
+ COMMAND asset_packer ${ASSETS_TXT_PATH} ${GENERATED_ASSETS_H} ${GENERATED_ASSETS_DATA_CC}
+ DEPENDS asset_packer ${ASSETS_TXT_PATH}
+ COMMENT "Generating assets.h and assets_data.cc"
+)
+
+add_custom_target(generate_assets ALL
+ DEPENDS ${GENERATED_ASSETS_H} ${GENERATED_ASSETS_DATA_CC}
+)
+
+# Main Demo Target
add_executable(demo64k
src/main.cc
src/platform.cc
@@ -67,9 +94,12 @@ add_executable(demo64k
src/audio/window.cc
src/audio/synth.cc
third_party/glfw3webgpu/glfw3webgpu.c
+ ${GENERATED_ASSETS_DATA_CC}
)
+add_dependencies(demo64k generate_assets)
target_link_libraries(demo64k PRIVATE ${DEMO_LIBS})
+target_include_directories(demo64k PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src)
if (DEMO_SIZE_OPT)
if (MSVC)
@@ -84,6 +114,7 @@ if (DEMO_SIZE_OPT)
endif()
endif()
+# Tests
option(DEMO_BUILD_TESTS "Build tests" OFF)
enable_testing()
@@ -104,104 +135,55 @@ if(DEMO_BUILD_TESTS)
target_include_directories(test_synth PRIVATE src)
add_test(NAME SynthEngineTest COMMAND test_synth)
- add_executable(test_spectool
-
- src/tests/test_spectool.cc
-
- src/audio/audio.cc
-
- src/audio/window.cc
-
- src/audio/fdct.cc
-
- src/audio/synth.cc
-
- src/audio/idct.cc
-
- third_party/glfw3webgpu/glfw3webgpu.c
-
- )
-
- target_include_directories(test_spectool PRIVATE
-
- src
-
- third_party
-
- ${WGPU_INCLUDE_DIR}
-
- third_party/glfw3webgpu
-
- )
+ add_executable(test_spectool
+ src/tests/test_spectool.cc
+ src/audio/audio.cc
+ src/audio/window.cc
+ src/audio/fdct.cc
+ src/audio/synth.cc
+ src/audio/idct.cc
+ third_party/glfw3webgpu/glfw3webgpu.c
+ )
+ target_include_directories(test_spectool PRIVATE
+ src
+ third_party
+ ${WGPU_INCLUDE_DIR}
+ third_party/glfw3webgpu
+ )
target_link_libraries(test_spectool PRIVATE ${DEMO_LIBS})
add_test(NAME SpectoolEndToEndTest COMMAND test_spectool)
-endif()
-option(DEMO_BUILD_TOOLS "Build tools" OFF)
+ add_executable(test_assets
+ src/tests/test_assets.cc
+ ${GENERATED_ASSETS_DATA_CC}
+ )
+ target_include_directories(test_assets PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src src)
+ add_dependencies(test_assets generate_assets)
+ add_test(NAME AssetManagerTest COMMAND test_assets)
+endif()
+# Tools
if(DEMO_BUILD_TOOLS)
- add_executable(spectool
- tools/spectool.cc
- src/platform.cc
- src/audio/audio.cc
- src/audio/fdct.cc
- src/audio/idct.cc
- src/audio/window.cc
- src/audio/synth.cc
- third_party/glfw3webgpu/glfw3webgpu.c
- )
- target_include_directories(spectool PRIVATE
- src
- third_party
- ${WGPU_INCLUDE_DIR}
- third_party/glfw3webgpu
- )
+ add_executable(spectool
+ tools/spectool.cc
+ src/platform.cc
+ src/audio/audio.cc
+ src/audio/fdct.cc
+ src/audio/idct.cc
+ src/audio/window.cc
+ src/audio/synth.cc
+ third_party/glfw3webgpu/glfw3webgpu.c
+ )
+ target_include_directories(spectool PRIVATE
+ src
+ third_party
+ ${WGPU_INCLUDE_DIR}
+ third_party/glfw3webgpu
+ )
target_link_libraries(spectool PRIVATE ${DEMO_LIBS})
add_executable(specview
tools/specview.cc
)
target_include_directories(specview PRIVATE src)
-
- add_executable(asset_packer
- tools/asset_packer.cc
- )
endif()
-
-# Configure asset generation
-set(ASSETS_TXT_PATH ${CMAKE_CURRENT_SOURCE_DIR}/assets/final/assets.txt)
-set(GENERATED_ASSETS_H ${CMAKE_CURRENT_BINARY_DIR}/src/assets.h)
-set(GENERATED_ASSETS_DATA_CC ${CMAKE_CURRENT_BINARY_DIR}/src/assets_data.cc)
-
-add_custom_command(
- OUTPUT ${GENERATED_ASSETS_H} ${GENERATED_ASSETS_DATA_CC}
- COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/src
- COMMAND asset_packer ${ASSETS_TXT_PATH} ${GENERATED_ASSETS_H} ${GENERATED_ASSETS_DATA_CC}
- DEPENDS tools/asset_packer.cc ${ASSETS_TXT_PATH}
- COMMENT "Generating assets.h and assets_data.cc"
-)
-
-add_custom_target(generate_assets ALL
- DEPENDS ${GENERATED_ASSETS_H} ${GENERATED_ASSETS_DATA_CC}
-)
-
-add_executable(demo64k
- src/main.cc
- src/platform.cc
- src/gpu/gpu.cc
- src/audio/audio.cc
- src/audio/fdct.cc
- src/audio/idct.cc
- src/audio/window.cc
- src/audio/synth.cc
- third_party/glfw3webgpu/glfw3webgpu.c
- ${GENERATED_ASSETS_DATA_CC}
-)
-
-# Ensure demo64k depends on the generated assets
-add_dependencies(demo64k generate_assets)
-
-target_link_libraries(demo64k PRIVATE ${DEMO_LIBS})
-
-# Include generated assets header for compilation
-target_include_directories(demo64k PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/src) \ No newline at end of file
diff --git a/assets/final/assets.txt b/assets/final/assets.txt
index e69de29..c22fad8 100644
--- a/assets/final/assets.txt
+++ b/assets/final/assets.txt
@@ -0,0 +1,2 @@
+NULL_ASSET, null.bin, NONE, "Empty asset"
+TEST_ASSET, test_asset.txt, NONE, "Test asset for verification"
diff --git a/assets/final/null.bin b/assets/final/null.bin
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/assets/final/null.bin
diff --git a/assets/final/test_asset.txt b/assets/final/test_asset.txt
new file mode 100644
index 0000000..8a18097
--- /dev/null
+++ b/assets/final/test_asset.txt
@@ -0,0 +1,3 @@
+This is a test asset file.
+It contains some text data to verify the asset packing system.
+1234567890
diff --git a/src/tests/test_assets.cc b/src/tests/test_assets.cc
new file mode 100644
index 0000000..eedc92b
--- /dev/null
+++ b/src/tests/test_assets.cc
@@ -0,0 +1,29 @@
+#include "assets.h"
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+
+int main() {
+ printf("Running AssetManager test...\n");
+
+ size_t size = 0;
+ const uint8_t *data = GetAsset(AssetId::ASSET_TEST_ASSET, &size);
+
+ assert(data != nullptr);
+ assert(size > 0);
+
+ const char *expected_prefix = "This is a test asset file.";
+ if (strncmp((const char *)data, expected_prefix, strlen(expected_prefix)) ==
+ 0) {
+ printf("Asset content verification: SUCCESS\n");
+ } else {
+ printf("Asset content verification: FAILED\n");
+ printf("Got: %.*s\n", (int)size, (const char *)data);
+ return 1;
+ }
+
+ printf("Asset size: %zu bytes\n", size);
+ printf("AssetManager test PASSED\n");
+
+ return 0;
+}
diff --git a/tools/asset_packer.cc b/tools/asset_packer.cc
index 8b06829..a67ddcc 100644
--- a/tools/asset_packer.cc
+++ b/tools/asset_packer.cc
@@ -39,7 +39,8 @@ int main(int argc, char *argv[]) {
// Generate assets.h
assets_h_file << "#pragma once\n";
- assets_h_file << "#include <cstdint>\n\n";
+ assets_h_file << "#include <cstdint>\n";
+ assets_h_file << "#include <cstddef>\n\n";
assets_h_file << "enum class AssetId : uint16_t {\n";
// Generate assets_data.cc header
@@ -65,23 +66,51 @@ int main(int argc, char *argv[]) {
asset_name.erase(0, asset_name.find_first_not_of(" \t\r\n"));
asset_name.erase(asset_name.find_last_not_of(" \t\r\n") + 1);
- if (asset_name.empty()) {
- std::cerr << "Warning: Skipping line with empty asset name: " << line
- << "\n";
+ size_t second_comma = line.find(',', first_comma + 1);
+ if (second_comma == std::string::npos) {
+ std::cerr << "Warning: Skipping malformed line in assets.txt (missing "
+ "filename): "
+ << line << "\n";
continue;
}
+ std::string filename =
+ line.substr(first_comma + 1, second_comma - first_comma - 1);
+ filename.erase(0, filename.find_first_not_of(" \t\r\n"));
+ filename.erase(filename.find_last_not_of(" \t\r\n") + 1);
+
+ // Read the actual file
+ std::string base_dir =
+ assets_txt_path.substr(0, assets_txt_path.find_last_of("/\\") + 1);
+ std::ifstream asset_file(base_dir + filename, std::ios::binary);
+ if (!asset_file.is_open()) {
+ std::cerr << "Error: Could not open asset file: " << base_dir + filename
+ << "\n";
+ return 1;
+ }
+
+ std::vector<uint8_t> buffer((std::istreambuf_iterator<char>(asset_file)),
+ std::istreambuf_iterator<char>());
+ asset_file.close();
+
asset_names.push_back(asset_name);
// Add to assets.h enum
assets_h_file << " ASSET_" << asset_name << " = " << asset_id_counter
<< ",\n";
- // Placeholder for assets_data.cc (empty data for now)
+ // Write data to assets_data.cc
assets_data_cc_file << "const uint8_t ASSET_DATA_" << asset_name
- << "[] = {};\n";
- assets_data_cc_file << "const size_t ASSET_SIZE_" << asset_name
- << " = 0;\n\n";
+ << "[] = {";
+ for (size_t i = 0; i < buffer.size(); ++i) {
+ if (i % 12 == 0)
+ assets_data_cc_file << "\n ";
+ assets_data_cc_file << "0x" << std::hex << (int)buffer[i] << std::dec
+ << (i == buffer.size() - 1 ? "" : ", ");
+ }
+ assets_data_cc_file << "\n};\n";
+ assets_data_cc_file << "const size_t ASSET_SIZE_" << asset_name << " = "
+ << buffer.size() << ";\n\n";
asset_id_counter++;
}
@@ -89,19 +118,22 @@ int main(int argc, char *argv[]) {
assets_h_file << "};\n\n";
// Generate GetAsset function declaration in assets.h
+ assets_h_file << "const uint8_t *GetAsset(AssetId asset_id, size_t *out_size "
+ "= nullptr);\n";
assets_h_file
- << "const uint8_t *GetAsset(AssetId asset_id, size_t *out_size = nullptr);\n";
- assets_h_file << "void DropAsset(AssetId asset_id, const uint8_t *asset); // For lazy "
- "decompression scaffolding\n";
+ << "void DropAsset(AssetId asset_id, const uint8_t *asset); // For lazy "
+ "decompression scaffolding\n";
assets_h_file.close();
// Generate GetAsset function implementation in assets_data.cc
- assets_data_cc_file << "const uint8_t *GetAsset(AssetId asset_id, size_t *out_size) {\n";
+ assets_data_cc_file
+ << "const uint8_t *GetAsset(AssetId asset_id, size_t *out_size) {\n";
assets_data_cc_file << " if (out_size) *out_size = 0;\n"; // Default for now
assets_data_cc_file << " switch (asset_id) {\n";
for (const std::string &name : asset_names) {
assets_data_cc_file << " case AssetId::ASSET_" << name << ":\n";
- assets_data_cc_file << " if (out_size) *out_size = ASSET_SIZE_" << name << ";\n";
+ assets_data_cc_file << " if (out_size) *out_size = ASSET_SIZE_" << name
+ << ";\n";
assets_data_cc_file << " return ASSET_DATA_" << name << ";\n";
}
assets_data_cc_file << " default:\n";
@@ -110,10 +142,12 @@ int main(int argc, char *argv[]) {
assets_data_cc_file << "}\n\n";
// Dummy DropAsset implementation
- assets_data_cc_file << "void DropAsset(AssetId asset_id, const uint8_t *asset) {\n";
+ assets_data_cc_file
+ << "void DropAsset(AssetId asset_id, const uint8_t *asset) {\n";
assets_data_cc_file << " (void)asset_id;\n";
assets_data_cc_file << " (void)asset;\n";
- assets_data_cc_file << " // No-op for now, actual implementation for lazy decompression goes here\n";
+ assets_data_cc_file << " // No-op for now, actual implementation for lazy "
+ "decompression goes here\n";
assets_data_cc_file << "}\n";
assets_data_cc_file.close();