ASW Lib
A.D.S. Games SDL Wrapper Library. A library targeted at Allegro4 users who want to switch to SDL3 and use modern c++.
Loading...
Searching...
No Matches
assets.cpp
Go to the documentation of this file.
2
3#include <SDL3/SDL.h>
4#include <SDL3_image/SDL_image.h>
5#include <SDL3_mixer/SDL_mixer.h>
6#include <SDL3_ttf/SDL_ttf.h>
7#include <string>
8#include <unordered_map>
9
11#include "./asw/modules/sound.h"
12#include "./asw/modules/types.h"
13#include "./asw/modules/util.h"
14
15namespace {
16std::unordered_map<std::string, asw::Texture> textures;
17std::unordered_map<std::string, asw::Font> fonts;
18std::unordered_map<std::string, asw::Sample> samples;
19std::unordered_map<std::string, asw::Music> music;
20} // namespace
21
22// --- Paths ---
23
24std::string asw::assets::get_path(const std::string& filename)
25{
26 // base_path is usually ".../YourGame.app/Contents/Resources/" on mac
27 // simply the directory of the executable on other platforms
28 const char* base_path = SDL_GetBasePath();
29 if (base_path == nullptr) {
30 return filename;
31 }
32 return std::string(base_path) + filename;
33}
34
35// --- Texture ---
36
37asw::Texture asw::assets::load_texture(const std::string& filename)
38{
39 const auto full_path = get_path(filename);
40 SDL_Texture* temp = IMG_LoadTexture(asw::display::get_renderer(), full_path.c_str());
41
42 if (temp == nullptr) {
43 asw::util::abort_on_error("Failed to load texture: " + full_path);
44 }
45
46 SDL_SetTextureScaleMode(temp, SDL_SCALEMODE_NEAREST);
47 SDL_SetTextureBlendMode(temp, SDL_BLENDMODE_BLEND);
48
49 // Guard: if the renderer is already gone when the deleter fires (e.g. a
50 // shared_ptr outliving core::shutdown()), skip the SDL call - SDL has
51 // already freed the texture via SDL_DestroyRenderer.
52 return { temp, [](SDL_Texture* t) {
53 if (asw::display::get_renderer() != nullptr) {
54 SDL_DestroyTexture(t);
55 }
56 } };
57}
58
59asw::Texture asw::assets::load_texture(const std::string& filename, const std::string& key)
60{
61 if (auto it = textures.find(key); it != textures.end()) {
62 return it->second;
63 }
64
65 Texture tex = load_texture(filename);
66 textures.try_emplace(key, tex);
67 return tex;
68}
69
71{
72 auto it = textures.find(key);
73 if (it == textures.end()) {
74 asw::util::abort_on_error("Texture not found: " + key);
75 }
76 return it->second;
77}
78
79void asw::assets::unload_texture(const std::string& key)
80{
81 textures.erase(key);
82}
83
85{
87 if (r == nullptr) {
88 asw::util::abort_on_error("Renderer not initialized");
89 }
90
91 SDL_Texture* txr
92 = SDL_CreateTexture(r, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, w, h);
93
94 SDL_SetTextureScaleMode(txr, SDL_SCALEMODE_NEAREST);
95 SDL_SetTextureBlendMode(txr, SDL_BLENDMODE_BLEND);
96
97 return { txr, [](SDL_Texture* t) {
98 if (asw::display::get_renderer() != nullptr) {
99 SDL_DestroyTexture(t);
100 }
101 } };
102}
103
104// --- Font ---
105
106asw::Font asw::assets::load_font(const std::string& filename, float size)
107{
108 const auto full_path = get_path(filename);
109 TTF_Font* temp = TTF_OpenFont(full_path.c_str(), size);
110
111 if (temp == nullptr) {
112 asw::util::abort_on_error("Failed to load font: " + full_path);
113 }
114
115 // Use renderer as proxy for "SDL still alive" - renderer is nulled in
116 // display::_shutdown() before TTF_Quit() is called.
117 return { temp, [](TTF_Font* f) {
118 if (asw::display::get_renderer() != nullptr) {
119 TTF_CloseFont(f);
120 }
121 } };
122}
123
124asw::Font asw::assets::load_font(const std::string& filename, float size, const std::string& key)
125{
126 if (auto it = fonts.find(key); it != fonts.end()) {
127 return it->second;
128 }
129
130 Font font = load_font(filename, size);
131 fonts.try_emplace(key, font);
132 return font;
133}
134
135asw::Font asw::assets::get_font(const std::string& key)
136{
137 auto it = fonts.find(key);
138 if (it == fonts.end()) {
139 asw::util::abort_on_error("Font not found: " + key);
140 }
141 return it->second;
142}
143
144void asw::assets::unload_font(const std::string& key)
145{
146 fonts.erase(key);
147}
148
149// --- Sample ---
150
151asw::Sample asw::assets::load_sample(const std::string& filename)
152{
153 const auto full_path = get_path(filename);
154 MIX_Audio* temp = MIX_LoadAudio(asw::sound::get_mixer(), full_path.c_str(), true);
155
156 if (temp == nullptr) {
157 asw::util::abort_on_error("Failed to load sample: " + full_path);
158 }
159
160 return { temp, [](MIX_Audio* a) {
161 if (asw::sound::get_mixer() != nullptr) {
162 MIX_DestroyAudio(a);
163 }
164 } };
165}
166
167asw::Sample asw::assets::load_sample(const std::string& filename, const std::string& key)
168{
169 if (auto it = samples.find(key); it != samples.end()) {
170 return it->second;
171 }
172
173 Sample sample = load_sample(filename);
174 samples.try_emplace(key, sample);
175 return sample;
176}
177
179{
180 auto it = samples.find(key);
181 if (it == samples.end()) {
182 asw::util::abort_on_error("Sample not found: " + key);
183 }
184 return it->second;
185}
186
187void asw::assets::unload_sample(const std::string& key)
188{
189 samples.erase(key);
190}
191
192// --- Music ---
193
194asw::Music asw::assets::load_music(const std::string& filename)
195{
196 const auto full_path = get_path(filename);
197 MIX_Audio* temp = MIX_LoadAudio(asw::sound::get_mixer(), full_path.c_str(), false);
198
199 if (temp == nullptr) {
200 asw::util::abort_on_error("Failed to load music: " + full_path);
201 }
202
203 return { temp, [](MIX_Audio* a) {
204 if (asw::sound::get_mixer() != nullptr) {
205 MIX_DestroyAudio(a);
206 }
207 } };
208}
209
210asw::Music asw::assets::load_music(const std::string& filename, const std::string& key)
211{
212 if (auto it = music.find(key); it != music.end()) {
213 return it->second;
214 }
215
216 Music mus = load_music(filename);
217 music.try_emplace(key, mus);
218 return mus;
219}
220
221asw::Music asw::assets::get_music(const std::string& key)
222{
223 auto it = music.find(key);
224 if (it == music.end()) {
225 asw::util::abort_on_error("Music not found: " + key);
226 }
227 return it->second;
228}
229
230void asw::assets::unload_music(const std::string& key)
231{
232 music.erase(key);
233}
234
235// --- Global ---
236
238{
239 textures.clear();
240 fonts.clear();
241 samples.clear();
242 music.clear();
243}
Asset routines for the ASW library.
Display and window routines for the ASW library.
std::unordered_map< std::string, asw::Music > music
Definition assets.cpp:19
std::unordered_map< std::string, asw::Sample > samples
Definition assets.cpp:18
std::unordered_map< std::string, asw::Texture > textures
Definition assets.cpp:16
std::unordered_map< std::string, asw::Font > fonts
Definition assets.cpp:17
asw::Sample get_sample(const std::string &key)
Get a cached sample.
Definition assets.cpp:178
asw::Texture create_texture(int w, int h)
Create a Texture given the specified dimensions.
Definition assets.cpp:84
void unload_music(const std::string &key)
Remove a cached music.
Definition assets.cpp:230
std::string get_path(const std::string &filename)
Get the full path to an asset given its filename. This assumes that all assets are located in an "ass...
Definition assets.cpp:24
asw::Texture get_texture(const std::string &key)
Get a cached texture.
Definition assets.cpp:70
void unload_sample(const std::string &key)
Remove a cached sample.
Definition assets.cpp:187
void unload_font(const std::string &key)
Remove a cached font.
Definition assets.cpp:144
asw::Music load_music(const std::string &filename)
Loads a music file from a file. Formats supported are WAV, AIFF, RIFF, OGG and VOC....
Definition assets.cpp:194
void clear_all()
Clear all cached assets. This will remove all cached textures, fonts, samples, and music.
Definition assets.cpp:237
void unload_texture(const std::string &key)
Remove a cached texture.
Definition assets.cpp:79
asw::Music get_music(const std::string &key)
Get a cached music.
Definition assets.cpp:221
asw::Font load_font(const std::string &filename, float size)
Loads a TTF font from a file. This will abort if the file is not found.
Definition assets.cpp:106
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...
Definition assets.cpp:151
asw::Font get_font(const std::string &key)
Get a cached font.
Definition assets.cpp:135
asw::Texture load_texture(const std::string &filename)
Loads a texture from a file. Formats supported are PNG, ICO, CUR, BMP, GIF, JPG, LBM,...
Definition assets.cpp:37
asw::Renderer * get_renderer()
Get the SDL renderer.
Definition display.cpp:62
MIX_Mixer * get_mixer()
Get the SDL mixer device.
Definition sound.cpp:43
void abort_on_error(const std::string &message)
Abort program and display error message.
Definition util.cpp:8
std::shared_ptr< TTF_Font > Font
Alias for a shared pointer to an TTF_Font.
Definition types.h:41
std::shared_ptr< MIX_Audio > Sample
Alias for a shared pointer to an MIX_Audio.
Definition types.h:44
std::shared_ptr< SDL_Texture > Texture
Alias for a shared pointer to an SDL_Texture.
Definition types.h:38
std::shared_ptr< MIX_Audio > Music
Alias for a shared pointer to an MIX_Audio.
Definition types.h:47
Sound module for the ASW library.
Types used throughout the ASW library.
General utility functions.