12#include <SDL3_image/SDL_image.h>
13#include <SDL3_mixer/SDL_mixer.h>
14#include <SDL3_ttf/SDL_ttf.h>
18#include <unordered_map>
28std::unordered_map<std::string, asw::Texture>
textures;
29std::unordered_map<std::string, asw::Font>
fonts;
30std::unordered_map<std::string, asw::Sample>
samples;
31std::unordered_map<std::string, asw::Music>
music;
52 const char* base_path = SDL_GetBasePath();
53 if (base_path ==
nullptr) {
56 return std::string(base_path) + filename;
61 char* pref_path = SDL_GetPrefPath(org.c_str(), app.c_str());
62 if (pref_path ==
nullptr) {
66 std::string path(pref_path);
75 const auto full_path =
get_path(filename);
78 if (temp ==
nullptr) {
82 SDL_SetTextureScaleMode(temp, SDL_SCALEMODE_NEAREST);
83 SDL_SetTextureBlendMode(temp, SDL_BLENDMODE_BLEND);
88 return { temp, [](SDL_Texture* t) {
90 SDL_DestroyTexture(t);
128 = SDL_CreateTexture(r, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
130 if (txr ==
nullptr) {
134 SDL_SetTextureScaleMode(txr, SDL_SCALEMODE_NEAREST);
135 SDL_SetTextureBlendMode(txr, SDL_BLENDMODE_BLEND);
137 return { txr, [](SDL_Texture* t) {
139 SDL_DestroyTexture(t);
152 SDL_Surface* surface = SDL_CreateSurface(size, size, SDL_PIXELFORMAT_RGBA32);
153 if (surface ==
nullptr) {
157 const auto* details = SDL_GetPixelFormatDetails(surface->format);
158 const float half =
static_cast<float>(size) / 2.0F;
160 auto mix = [](uint8_t a, uint8_t b,
float t) {
161 return static_cast<uint8_t
>(
162 std::lround(
static_cast<float>(a) + (
static_cast<float>(b) - a) * t));
165 for (
int y = 0; y < size; y++) {
166 auto* row =
reinterpret_cast<uint32_t*
>(
167 static_cast<uint8_t*
>(surface->pixels) + y * surface->pitch);
169 for (
int x = 0; x < size; x++) {
170 const float distance = std::hypot(
static_cast<float>(x) + 0.5F - half,
171 static_cast<float>(y) + 0.5F - half)
176 row[x] = SDL_MapRGBA(details,
nullptr, mix(inner.
r, outer.
r, amount),
177 mix(inner.
g, outer.
g, amount), mix(inner.
b, outer.
b, amount),
178 mix(inner.
a, outer.
a, amount));
182 SDL_Texture* txr = SDL_CreateTextureFromSurface(r, surface);
183 SDL_DestroySurface(surface);
185 if (txr ==
nullptr) {
189 SDL_SetTextureScaleMode(txr, SDL_SCALEMODE_LINEAR);
190 SDL_SetTextureBlendMode(txr, SDL_BLENDMODE_BLEND);
192 return { txr, [](SDL_Texture* t) {
194 SDL_DestroyTexture(t);
203 const auto full_path =
get_path(filename);
204 TTF_Font* temp = TTF_OpenFont(full_path.c_str(), size);
206 if (temp ==
nullptr) {
213 TTF_SetFontHinting(temp, TTF_HINTING_MONO);
218 return { temp, [](TTF_Font* f) {
219 if (TTF_WasInit() > 0) {
226 const std::string& filename,
float size,
const std::string& key,
asw::FontStyle style)
228 if (
auto it =
fonts.find(key); it !=
fonts.end()) {
233 fonts.try_emplace(key, font);
239 auto it =
fonts.find(key);
240 if (it ==
fonts.end()) {
257 const auto full_path =
get_path(filename);
260 if (temp ==
nullptr) {
274 samples.try_emplace(key, sample);
296 const auto full_path =
get_path(filename);
299 if (temp ==
nullptr) {
308 if (
auto it =
music.find(key); it !=
music.end()) {
313 music.try_emplace(key, mus);
319 auto it =
music.find(key);
320 if (it ==
music.end()) {
348EM_JS_DEPS(asw_storage,
"$UTF8ToString,$lengthBytesUTF8,$stringToUTF8");
350EM_JS(
int, asw_storage_length, (
const char* key), {
352 const value = localStorage.getItem(UTF8ToString(key));
353 return value === null ? -1 : lengthBytesUTF8(value);
359EM_JS(
void, asw_storage_copy, (
const char* key,
char* out,
int size), {
361 const value = localStorage.getItem(UTF8ToString(key));
362 if (value !== null) {
363 stringToUTF8(value, out, size);
369EM_JS(
int, asw_storage_write, (
const char* key,
const char* value), {
371 localStorage.setItem(UTF8ToString(key), UTF8ToString(value));
379std::string storage_key(
const std::string& org,
const std::string& app,
const std::string& name)
381 return org +
"/" + app +
"/" + name;
386 const std::string& org,
const std::string& app,
const std::string& name)
388 const auto key = storage_key(org, app, name);
389 const int length = asw_storage_length(key.c_str());
394 std::string out(
static_cast<std::size_t
>(length),
'\0');
395 asw_storage_copy(key.c_str(), out.data(), length + 1);
400 const std::string& name,
const std::string& data)
402 return asw_storage_write(storage_key(org, app, name).c_str(), data.c_str()) != 0;
406 const std::string& org,
const std::string& app,
const std::string& name)
409 if (folder.empty()) {
412 std::ifstream file(folder + name, std::ios::binary);
416 std::stringstream buffer;
417 buffer << file.rdbuf();
422 const std::string& name,
const std::string& data)
425 if (folder.empty()) {
431 const std::string path = folder + name;
432 const std::string temp = path +
".tmp";
434 std::ofstream file(temp, std::ios::trunc | std::ios::binary);
435 if (!file || !(file << data)) {
440 std::filesystem::rename(temp, path, ec);
443 std::filesystem::remove(path, ec);
444 std::filesystem::rename(temp, path, ec);
Asset routines for the ASW library.
Display and window routines for the ASW library.
Routines for drawing sprites and primitives to the screen.
Easing functions for animations.
std::unordered_map< std::string, asw::Music > music
std::unordered_map< std::string, asw::Sample > samples
std::unordered_map< std::string, asw::Texture > textures
std::unordered_map< std::string, asw::Font > fonts
asw::Sample get_sample(const std::string &key)
Get a cached sample.
std::string read_save(const std::string &org, const std::string &app, const std::string &name)
Read save data written by write_save, e.g. progress or settings.
bool write_save(const std::string &org, const std::string &app, const std::string &name, const std::string &data)
Write save data, replacing what was saved under the name before.
asw::Texture create_texture(int w, int h)
Create a Texture given the specified dimensions.
void unload_music(const std::string &key)
Remove a cached music.
std::string get_path(const std::string &filename)
Get the full path to an asset given its filename. The filename is relative to the base path of the ap...
asw::Texture get_texture(const std::string &key)
Get a cached texture.
void unload_sample(const std::string &key)
Remove a cached sample.
asw::Texture create_radial_gradient(int size, asw::Color inner, asw::Color outer, asw::Falloff falloff=asw::Falloff::Smooth)
Create a square texture with a radial gradient. The colour goes from inner at the centre to outer at ...
std::string get_save_path(const std::string &org, const std::string &app)
Get a writable folder for save files and settings, unique to the organisation and application....
void unload_font(const std::string &key)
Remove a cached font.
asw::Music load_music(const std::string &filename)
Loads a music file from a file. Formats supported are WAV, AIFF, RIFF, OGG and VOC....
asw::Font load_font(const std::string &filename, float size, asw::FontStyle style=asw::FontStyle::Smooth)
Loads a TTF font from a file. This will abort if the file is not found.
void clear_all()
Clear all cached assets. This will remove all cached textures, fonts, samples, and music.
void unload_texture(const std::string &key)
Remove a cached texture.
asw::Music get_music(const std::string &key)
Get a cached music.
asw::Sample load_sample(const std::string &filename)
Loads a sample from a file. Formats supported are WAV, AIFF, RIFF, OGG and VOC. This will abort if th...
asw::Font get_font(const std::string &key)
Get a cached font.
asw::Texture load_texture(const std::string &filename)
Loads a texture from a file. Formats supported are PNG, ICO, CUR, BMP, GIF, JPG, LBM,...
asw::Renderer * get_renderer()
Get the SDL renderer.
void clear_text_cache()
Clear cached rendered text textures.
float falloff(float t, asw::Falloff mode)
MIX_Mixer * get_mixer()
Get the SDL mixer device.
uint32_t _get_session()
Get the number of times the sound module has been shut down.
void clear_text_size_cache()
Clear cached text metrics.
void abort_on_error(const std::string &message)
Abort program and display error message.
std::shared_ptr< TTF_Font > Font
Alias for a shared pointer to an TTF_Font.
std::shared_ptr< MIX_Audio > Sample
Alias for a shared pointer to an MIX_Audio.
std::shared_ptr< SDL_Texture > Texture
Alias for a shared pointer to an SDL_Texture.
std::shared_ptr< MIX_Audio > Music
Alias for a shared pointer to an MIX_Audio.
Falloff
How a gradient or light fades from its centre to its edge.
FontStyle
How a font's glyphs are rendered.
Sound module for the ASW library.
RGBA color struct with 8-bit channels.
Types used throughout the ASW library.
General utility functions.