e923de78aa
corrected location of some protos removed un-needed includes from source files
182 lines
4.5 KiB
C
182 lines
4.5 KiB
C
|
|
#include <libdragon.h>
|
|
#include "types.h"
|
|
#include "image.h"
|
|
|
|
//#define STBI_HEADER_FILE_ONLY
|
|
#define STB_IMAGE_IMPLEMENTATION
|
|
#include "stb_image.h"
|
|
|
|
|
|
/*
|
|
* Load an image from the rom filesystem, returning a pointer to the
|
|
* sprite that hold the image.
|
|
*/
|
|
sprite_t *loadImageDFS(char *fname) {
|
|
int size, x, y, n, fd;
|
|
u8 *tbuf;
|
|
u8 *ibuf;
|
|
sprite_t *sbuf;
|
|
|
|
fd = dfs_open(fname);
|
|
if (fd < 0)
|
|
return 0; // couldn't open image
|
|
|
|
size = dfs_size(fd);
|
|
tbuf = malloc(size);
|
|
if (!tbuf) {
|
|
dfs_close(fd);
|
|
return 0; // out of memory
|
|
}
|
|
|
|
dfs_read(tbuf, 1, size, fd);
|
|
dfs_close(fd);
|
|
|
|
ibuf = stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
|
|
free(tbuf);
|
|
if (!ibuf)
|
|
return 0; // couldn't decode image
|
|
|
|
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 2);
|
|
if (!sbuf) {
|
|
stbi_image_free(ibuf);
|
|
return 0; // out of memory
|
|
}
|
|
sbuf->width = x;
|
|
sbuf->height = y;
|
|
sbuf->bitdepth = 2;
|
|
sbuf->format = 0;
|
|
sbuf->hslices = x / 32;
|
|
sbuf->vslices = y / 16;
|
|
|
|
color_t *src = (color_t*)ibuf;
|
|
u16 *dst = (u16*)((u32)sbuf + sizeof(sprite_t));
|
|
|
|
for (int j=0; j<y; j++)
|
|
for (int i=0; i<x; i++)
|
|
dst[i + j*x] = graphics_convert_color(src[i + j*x]) & 0x0000FFFF;
|
|
|
|
/* Invalidate data associated with sprite in cache */
|
|
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
|
|
|
|
stbi_image_free(ibuf);
|
|
return sbuf;
|
|
}
|
|
|
|
|
|
sprite_t *loadImage32(u8 *png, int size) {
|
|
int x, y, n, fd;
|
|
u8 *tbuf;
|
|
u32 *ibuf;
|
|
sprite_t *sbuf;
|
|
|
|
tbuf = malloc(size);
|
|
memcpy(tbuf,png,size);
|
|
|
|
ibuf = (u32*)stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
|
|
free(tbuf);
|
|
if (!ibuf)
|
|
return 0; // couldn't decode image
|
|
|
|
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 4);
|
|
if (!sbuf) {
|
|
stbi_image_free(ibuf);
|
|
return 0; // out of memory
|
|
}
|
|
|
|
sbuf->width = x;
|
|
sbuf->height = y;
|
|
sbuf->bitdepth = 4;
|
|
sbuf->format = 0;
|
|
sbuf->hslices = x / 32;
|
|
sbuf->vslices = y / 32;
|
|
|
|
// color_t *src = (color_t*)ibuf;
|
|
u32 *dst = (u32*)((u32)sbuf + sizeof(sprite_t));
|
|
|
|
for (int j=0; j<y; j++)
|
|
for (int i=0; i<x; i++)
|
|
dst[i + j*x] = ibuf[i + j*x];
|
|
|
|
/* Invalidate data associated with sprite in cache */
|
|
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
|
|
|
|
stbi_image_free(ibuf);
|
|
return sbuf;
|
|
}
|
|
|
|
sprite_t *loadImage32DFS(char *fname) {
|
|
int size, x, y, n, fd;
|
|
u8 *tbuf;
|
|
u32 *ibuf;
|
|
sprite_t *sbuf;
|
|
|
|
fd = dfs_open(fname);
|
|
if (fd < 0)
|
|
return 0; // couldn't open image
|
|
|
|
size = dfs_size(fd);
|
|
tbuf = malloc(size);
|
|
if (!tbuf) {
|
|
dfs_close(fd);
|
|
return 0; // out of memory
|
|
}
|
|
|
|
dfs_read(tbuf, 1, size, fd);
|
|
dfs_close(fd);
|
|
|
|
ibuf = (u32*)stbi_load_from_memory(tbuf, size, &x, &y, &n, 4);
|
|
free(tbuf);
|
|
if (!ibuf)
|
|
return 0; // couldn't decode image
|
|
|
|
sbuf = (sprite_t*)malloc(sizeof(sprite_t) + x * y * 4);
|
|
if (!sbuf) {
|
|
stbi_image_free(ibuf);
|
|
return 0; // out of memory
|
|
}
|
|
|
|
sbuf->width = x;
|
|
sbuf->height = y;
|
|
sbuf->bitdepth = 4;
|
|
sbuf->format = 0;
|
|
sbuf->hslices = x / 32;
|
|
sbuf->vslices = y / 32;
|
|
|
|
// color_t *src = (color_t*)ibuf;
|
|
u32 *dst = (u32*)((u32)sbuf + sizeof(sprite_t));
|
|
|
|
for (int j=0; j<y; j++)
|
|
for (int i=0; i<x; i++)
|
|
dst[i + j*x] = ibuf[i + j*x];
|
|
|
|
/* Invalidate data associated with sprite in cache */
|
|
data_cache_hit_writeback_invalidate( sbuf->data, sbuf->width * sbuf->height * sbuf->bitdepth );
|
|
|
|
stbi_image_free(ibuf);
|
|
return sbuf;
|
|
}
|
|
|
|
/*
|
|
* Draw an image to the screen using the sprite passed.
|
|
*/
|
|
void drawImage(display_context_t dcon, sprite_t *sprite) {
|
|
int x, y = 0;
|
|
|
|
rdp_sync(SYNC_PIPE);
|
|
rdp_set_default_clipping();
|
|
rdp_enable_texture_copy();
|
|
rdp_attach_display(dcon);
|
|
// Draw image
|
|
for (int j=0; j<sprite->vslices; j++) {
|
|
x = 0;
|
|
for (int i=0; i<sprite->hslices; i++) {
|
|
rdp_sync(SYNC_PIPE);
|
|
rdp_load_texture_stride(0, 0, MIRROR_DISABLED, sprite, j*sprite->hslices + i);
|
|
rdp_draw_sprite(0, x, y);
|
|
x += 32;
|
|
}
|
|
y += 16;
|
|
}
|
|
rdp_detach_display();
|
|
} |