-
Notifications
You must be signed in to change notification settings - Fork 112
/
Copy pathsprite.h
276 lines (252 loc) · 9.77 KB
/
sprite.h
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
/**
* @file sprite.h
* @brief 2D Graphics
* @ingroup graphics
*/
#ifndef __LIBDRAGON_SPRITE_H
#define __LIBDRAGON_SPRITE_H
#include <stdint.h>
#include <stdbool.h>
#include <surface.h>
#ifdef __cplusplus
extern "C" {
#endif
///@cond
typedef struct rdpq_texparms_s rdpq_texparms_t;
///@endcond
/**
* @brief Sprite structure.
*
* A "sprite" (as saved in a `.sprite` file) is a 2D image with
* metadata attached to them to facilitate drawing it onto N64.
*
* Despite the name, a libdragon sprite is basically the basic format
* to handle assets for images. It is commonly used for handling
* textures, full screen images like splash screens, tile maps,
* font pictures, and even "real" 2D sprites.
*
* If the sprite uses a color-indexed format like #FMT_CI4 or #FMT_CI8,
* the sprite contains also the corresponding palette.
*
* To convert an image file to libdragon's sprite format, use
* the mksprite tool. To load a sprite into memory, use #sprite_load.
*/
typedef struct sprite_s
{
/** @brief Width in pixels */
uint16_t width;
/** @brief Height in pixels */
uint16_t height;
/** @brief DEPRECATED: do not use this field. Use TEX_FORMAT_BITDEPTH(sprite->format) instead. */
uint8_t bitdepth __attribute__((deprecated("use TEX_FORMAT_BITDEPTH(sprite->format) instead")));
union {
/** @brief DEPRECATED: do not use this field. Use sprite_get_format(sprite) instead. */
uint8_t format __attribute__((deprecated("use sprite_get_format() instead")));
/** @brief Various flags, including texture format */
uint8_t flags;
};
/** @brief Number of horizontal sub-tiles */
uint8_t hslices;
/** @brief Number of vertical sub-tiles */
uint8_t vslices;
/** @brief Start of graphics data */
uint32_t data[0];
} sprite_t;
/**
* @brief Sprite detail texture information structure.
*
* A "detail texture" is a 2D image with metadata attached to it
* to increase the perceived resolution of the main sprite when rendering
* with little to no additional TMEM usage.
*
* If the sprite uses a detail texture, its information can be retreived
* using the #sprite_get_detail_pixels function.
*
* To include a detail texture to libdragon's sprite format, use
* the mksprite tool with --detail argument.
*
* #rdpq_sprite_upload automatically uploads detail textures associated with
* the sprite.
*/
typedef struct sprite_detail_s
{
/** @brief Is the detail texture the same as the main surface of the sprite, used for fractal detailing */
bool use_main_tex;
/** @brief Blend factor of the detail texture in range of 0 to 1 */
float blend_factor;
} sprite_detail_t;
#define SPRITE_FLAGS_TEXFORMAT 0x1F ///< Pixel format of the sprite
#define SPRITE_FLAGS_OWNEDBUFFER 0x20 ///< Flag specifying that the sprite buffer must be freed by sprite_free
#define SPRITE_FLAGS_EXT 0x80 ///< Sprite contains extended information (new format)
/**
* @brief Load a sprite from a filesystem (eg: ROM)
*
* This function loads a full sprite from a filesystem. Notice that there is no
* streaming support, so the file is fully loaded into RDRAM, in its final
* uncompressed format.
*
* sprite_load internally uses the asset API (#asset_load), so the sprite file
* is transparently uncompressed if needed.
*
* @param fn Filename of the sprite, including filesystem specifier.
* For instance: "rom:/hero.sprite" to load from DFS.
* @return sprite_t* The loaded sprite
*/
sprite_t *sprite_load(const char *fn);
/**
* @brief Load a sprite from a buffer
*
* This function loads a sprite from a buffer corresponding to sprite
* file data in memory. The function also performs any necessary processing
* to load the sprite file data.
*
* sprite_load_buf functions in-place which means it does not allocate another
* buffer for the loaded sprite. So, sprite_free will not remove the sprite data
* from memory. This means that the input buffer must be freed manually after
* sprite_free is called.
*
* @param buf Pointer to the sprite file data
* @param sz Size of the sprite file buffer
* @return sprite_t* The loaded sprite
*/
sprite_t *sprite_load_buf(void *buf, int sz);
/** @brief Deallocate a sprite */
void sprite_free(sprite_t *sprite);
/**
* @brief Get the sprite texture format
*
* @param sprite The sprite
* @return The texture format
*/
inline tex_format_t sprite_get_format(sprite_t *sprite) {
return (tex_format_t)(sprite->flags & SPRITE_FLAGS_TEXFORMAT);
}
/**
* @brief Create a surface_t pointing to the full sprite contents.
*
* This function can be used to pass a full sprite to functions accepting
* a #surface_t.
*
* Notice that no memory allocations or copies are performed:
* the returned surface will point to the sprite contents.
*
* @param sprite The sprite
* @return The surface pointing to the sprite
*/
surface_t sprite_get_pixels(sprite_t *sprite);
/**
* @brief Create a surface_t pointing to the contents of a LOD level.
*
* This function can be used to access LOD images within a sprite file.
* It is useful for sprites created by mksprite containing multiple
* mipmap levels.
*
* LOD levels are indexed from 1 upward. 0 refers to the main sprite,
* so calling `sprite_get_lod_pixels(s, 0)` is equivalent to
* `sprite_get_pixels(s)`.
*
* Notice that no memory allocations or copies are performed:
* the returned surface will point to the sprite contents.
*
* @param sprite The sprite to access
* @param num_level The number of LOD level. 0 is the main sprite.
* @return surface_t The surface containing the data.
*/
surface_t sprite_get_lod_pixels(sprite_t *sprite, int num_level);
/**
* @brief Create a surface_t pointing to the contents of a detail texture.
*
* This function can be used to access detail texture within a sprite file.
* It is useful for sprites created by mksprite containing one.
*
* If there isn't a detail texture, the returned surface is 0.
*
* Additional detail information such as factor or texparms are accessible
* through the filled sprite_detail_t and rdpq_texparms_t structure.
* If you don't wish to use this information, pass NULL to the info argument(s).
*
* Notice that no memory allocations or copies are performed:
* the returned surface will point to the sprite contents.
*
* @param sprite The sprite to access
* @param info The detail information struct to fill if needed
* @param infoparms The detail texture sampling struct to fill if needed
* @return surface_t The surface containing the data.
*/
surface_t sprite_get_detail_pixels(sprite_t *sprite, sprite_detail_t *info, rdpq_texparms_t *infoparms);
/**
* @brief Return a surface_t pointing to a specific tile of the spritemap.
*
* A sprite can be used as a spritemap, that is a collection of multiple
* smaller images of equal size, called "tiles". In this case, the number
* of tiles is stored in the members `hslices` and `vslices` of the
* sprite structure.
*
* This function allows to get a surface that points to the specific sub-tile,
* so that it can accessed directly.
*
* @param sprite The sprite used as spritemap
* @param h Horizontal index of the tile to access
* @param v Vertical index of the tile to access
* @return A surface pointing to the tile
*/
surface_t sprite_get_tile(sprite_t *sprite, int h, int v);
/**
* @brief Access the sprite palette (if any)
*
* A sprite can also contain a palette, in case the sprite data is color-indexed
* (that is, the format is either #FMT_CI4 or #FMT_CI8).
*
* This function returns a pointer to the raw palette data contained in the sprite.
*
* @param sprite The sprite to access
* @return A pointer to the palette data, or NULL if the sprite does not have a palette
*/
uint16_t* sprite_get_palette(sprite_t *sprite);
/**
* @brief Get a copy of the RDP texparms, optionally stored within the sprite.
*
* This function allows to obtain the RDP texparms structure stored within the
* sprite, if any. This structure is used by the RDP to set texture properties
* such as wrapping, mirroring, etc. It can be added to the sprite via
* the mksprite tool, using the `--texparms` option.
*
* @param sprite The sprite to access
* @param parms The texparms structure to fill
* @return true if the sprite contain RDP texparms, false otherwise
*/
bool sprite_get_texparms(sprite_t *sprite, rdpq_texparms_t *parms);
/**
* @brief Return the number of LOD levels stored within the sprite (including the main image).
*
* @param sprite The sprite to access
* @return The number of LOD levels
*/
int sprite_get_lod_count(sprite_t *sprite);
/**
* @brief Return true if the sprite fits in TMEM without splitting
*
* This function returns true if the sprite can be fully uploaded in TMEM
* (including all its LODs, detail texture and palettes).
*
* When working on 3D graphics, each texture must fit into RDP TMEM (4 KiB),
* otherwise it cannot be used. All sprites that are meant to be used as
* textures should fit in TMEM.
*
* In case of 2D graphics, it is more common to have images of arbitrary size.
* They can be drawn with #rdpq_sprite_blit (accelerated) or #graphics_draw_sprite
* (CPU) without specific limits (the RDP accelerated
* version does internally need to split the sprite in multiple parts, but
* that is indeed possible).
*
* This function is mostly for debugging purposes, as it can help validating
* whether a sprite can be used as a texture or not.
*
* @param sprite The sprite to access
* @return True if the sprite fits TMEM, false otherwise
*/
bool sprite_fits_tmem(sprite_t *sprite);
#ifdef __cplusplus
}
#endif
#endif