1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# compact asset system for the 64k demo
This file describe the features of a compact asset system used in the demo.
The idea is the following:
# run-time asset retrieval:
All assets are const byte arrays. We need a 'const uint8_t* GetAsset(uint16 asset_id)'
The asset ID is defined in a 'assets.h' header, generated during the final
compile by our own assembling tool. assets.h needs to be re-generated
infrequently.
# assembling the assets:
## description file 'assets.txt'
All assets are just files in the assets/final/ directory
This directory needs a assets.txt text file to describe the asset files.
Each line of the assets.txt file contain, comma-separated:
* the name of the asset (that will be used by the #define in assets.h),
* the name of the file associated
* the compression to use for this asset (default NONE. More options later)
* and optionally the type of assets.
## example For instance, a line in assets.txt will read:
SAMPLE_142, sample_142.spec, NONE, "this is a drum kick sample"
This instructs the final assembled file assets.h to have a code line:
#define ASSET_SAMPLE_142 6323
(6323 is just an associated id)
(or an enum instead of #define's)
so that we can call
```
#include "asset.h"
const uint8_t* mysample = GetAsset(ASSET_SAMPLE_142);
...etc
```
(if we use enums, GetAssert() signature needs to be changed)
### Lazy decompression
to save memory some assets can be decompressed 'at retrieval time' but kept
compressed in memory until then.
This means that we need a 'void DropAsset(uint16 asset_id, const uint8* asset)'
method to handle memory disallocation depending on the asset type.
### assembling tool
we need a simple tool that:
* takes the assets.txt file and parse it
* generates the assets.h file with asset enums
* generates the assets_data.cc file with all the data
* put these in the source tree
* this process needs a script for automation
## Technical Details
To support diverse usage (binary data, strings, typed structs), the asset packer enforces the following:
1. **Alignment**: All static asset arrays are declared with `alignas(16)`. This ensures that `reinterpret_cast` to types like `float*` or SIMD vectors is safe (provided the data layout matches).
2. **String Safety**: Every static asset is appended with a null-terminator (`0x00`). This allows the raw pointer to be safely used as a `const char*` C-string.
3. **Size Reporting**: The `size` field in `AssetRecord` reflects the *original* file size. However, the underlying buffer is guaranteed to be at least `size + 1` bytes long (due to the null terminator).
# Shader Snippets
Shader code (WGSL) can also be managed as assets.
1. Create `.wgsl` files in `assets/final/shaders/` (or similar).
2. Add them to `assets/final/demo_assets.txt` with compression `NONE`.
Example: `SHADER_COMMON, shaders/common.wgsl, NONE`
3. In C++, retrieve them using `GetAsset()`. Since they are binary blobs,
construct a `std::string` or `std::string_view` using the returned pointer
and size.
4. Register them with the `ShaderComposer`.
|