diff --git a/libc3/window/sdl2/configure b/libc3/window/sdl2/configure
index a82e519..078a37c 100755
--- a/libc3/window/sdl2/configure
+++ b/libc3/window/sdl2/configure
@@ -46,6 +46,7 @@ config_gnu
pkg_config ftgl
pkg_config gl
pkg_config glu
+config_lib IL -lIL -lILU
pkg_config sdl2
pkg_config libbsd-overlay
config_lib OPENGL -framework OpenGL
diff --git a/libc3/window/sdl2/demo/configure b/libc3/window/sdl2/demo/configure
index b8c8e00..70696cf 100755
--- a/libc3/window/sdl2/demo/configure
+++ b/libc3/window/sdl2/demo/configure
@@ -52,6 +52,7 @@ config_gnu
pkg_config ftgl
pkg_config gl
pkg_config glu
+config_lib IL -lIL -lILU
pkg_config sdl2
config_lib OPENGL -framework OpenGL
#config_lib SDL2 -framework SDL2
diff --git a/libc3/window/sdl2/sdl2_sprite.c b/libc3/window/sdl2/sdl2_sprite.c
new file mode 100644
index 0000000..8725265
--- /dev/null
+++ b/libc3/window/sdl2/sdl2_sprite.c
@@ -0,0 +1,106 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#include <assert.h>
+#include <err.h>
+#include <unistd.h>
+#include <libc3/c3.h>
+#include "sdl2_sprite.h"
+
+bool g_il_is_loaded = false;
+
+static void ilEnsureInit (void)
+{
+ if (! g_il_is_loaded) {
+ ilInit();
+ iluInit();
+ g_il_is_loaded = true;
+ }
+}
+
+void ilClean (void)
+{
+ if (g_il_is_loaded) {
+ iluInit();
+ ilInit();
+ }
+}
+
+void sdl2_sprite_clean (s_sdl2_sprite *sprite)
+{
+ assert(sprite);
+ (void) sprite;
+ // TODO
+}
+
+s_sdl2_sprite * sdl2_sprite_init (s_sdl2_sprite *sprite,
+ const s8 *path,
+ uw dim_x, uw dim_y,
+ uw frame_count)
+{
+ //ILint bpp;
+ ILubyte *data;
+ uw i;
+ ILuint il_images[2];
+ uw x;
+ uw y;
+ assert(sprite);
+ assert(path);
+ assert(dim_x);
+ assert(dim_y);
+ str_init_copy_1(&sprite->path, path);
+ if (! file_search(&sprite->path, sym_1("r"), &sprite->real_path)) {
+ warnx("sdl2_sprite_init:"
+ " file not found: %s", path);
+ str_clean(&sprite->path);
+ return NULL;
+ }
+ ilEnsureInit();
+ ilGenImages(2, il_images);
+ ilBindImage(il_images[0]);
+ if (! ilLoadImage(sprite->path.ptr.ps8)) {
+ warnx("sdl2_sprite_init: error loading image: %s",
+ iluErrorString(ilGetError()));
+ str_clean(&sprite->path);
+ str_clean(&sprite->real_path);
+ return NULL;
+ }
+ sprite->total_w = ilGetInteger(IL_IMAGE_WIDTH);
+ sprite->total_h = ilGetInteger(IL_IMAGE_HEIGHT);
+ //bpp = ilGetInteger(IL_IMAGE_BPP);
+ sprite->dim_x = dim_x;
+ sprite->dim_y = dim_y;
+ sprite->w = sprite->total_w / dim_x;
+ sprite->h = sprite->total_h / dim_y;
+ sprite->frame_count = frame_count ? frame_count : (dim_x * dim_y);
+ ilBindImage(il_images[1]);
+ ilTexImage(sprite->w, sprite->h, 1, 32, IL_RGBA, IL_UNSIGNED_BYTE,
+ NULL);
+ data = ilGetData();
+ ilBindImage(il_images[0]);
+ i = 0;
+ y = 0;
+ while (i < sprite->frame_count && y < dim_y) {
+ x = 0;
+ while (i < sprite->frame_count && x < dim_x) {
+ ilCopyPixels(x * sprite->w, y * sprite->h, 0,
+ sprite->w, sprite->h, 1, IL_RGBA, IL_UNSIGNED_BYTE,
+ data);
+
+ i++;
+ x++;
+ }
+ y++;
+ }
+ ilDeleteImages(2, il_images);
+ return sprite;
+}
diff --git a/libc3/window/sdl2/sdl2_sprite.h b/libc3/window/sdl2/sdl2_sprite.h
new file mode 100644
index 0000000..d405334
--- /dev/null
+++ b/libc3/window/sdl2/sdl2_sprite.h
@@ -0,0 +1,29 @@
+/* c3
+ * Copyright 2022,2023 kmx.io <contact@kmx.io>
+ *
+ * Permission is hereby granted to use this software granted the above
+ * copyright notice and this permission paragraph are included in all
+ * copies and substantial portions of this software.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS-IS" WITHOUT ANY GUARANTEE OF
+ * PURPOSE AND PERFORMANCE. IN NO EVENT WHATSOEVER SHALL THE
+ * AUTHOR BE CONSIDERED LIABLE FOR THE USE AND PERFORMANCE OF
+ * THIS SOFTWARE.
+ */
+#ifndef SDL2_SPRITE_H
+#define SDL2_SPRITE_H
+
+#include "types.h"
+
+/* stack allocation compatible functions */
+void sdl2_sprite_clean (s_sdl2_sprite *sprite);
+s_sdl2_sprite * sdl2_sprite_init (s_sdl2_sprite *sprite,
+ const s8 *path,
+ uw dim_x, uw dim_y,
+ uw frame_count);
+
+/* operations */
+void sdl2_sprite_render (const s_sdl2_sprite *sprite, uw frame,
+ uw x, uw y);
+
+#endif /* CAIRO_SPRITE_H */
diff --git a/libc3/window/sdl2/sources.mk b/libc3/window/sdl2/sources.mk
index f4e58e5..2108db7 100644
--- a/libc3/window/sdl2/sources.mk
+++ b/libc3/window/sdl2/sources.mk
@@ -1,10 +1,12 @@
# sources.mk generated by update_sources
HEADERS = \
sdl2_font.h \
+ sdl2_sprite.h \
types.h \
window_sdl2.h \
SOURCES = \
sdl2_font.c \
+ sdl2_sprite.c \
window_sdl2.c \
diff --git a/libc3/window/sdl2/sources.sh b/libc3/window/sdl2/sources.sh
index 06c8a70..8fb7b15 100644
--- a/libc3/window/sdl2/sources.sh
+++ b/libc3/window/sdl2/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
-HEADERS='sdl2_font.h types.h window_sdl2.h '
-SOURCES='sdl2_font.c window_sdl2.c '
+HEADERS='sdl2_font.h sdl2_sprite.h types.h window_sdl2.h '
+SOURCES='sdl2_font.c sdl2_sprite.c window_sdl2.c '
diff --git a/libc3/window/sdl2/types.h b/libc3/window/sdl2/types.h
index 4df7b04..093f8ea 100644
--- a/libc3/window/sdl2/types.h
+++ b/libc3/window/sdl2/types.h
@@ -22,18 +22,20 @@
#include <GL/gl.h>
#include <GL/glu.h>
#include <FTGL/ftgl.h>
+#include <IL/il.h>
+#include <IL/ilu.h>
#include <libc3/types.h>
#include "../types.h"
typedef struct sdl2_font s_sdl2_font;
typedef struct sdl2_sprite s_sdl2_sprite;
-typedef struct rgb s_rgb;
-typedef struct rgba s_rgba;
+typedef struct rgb s_rgb;
+typedef struct rgba s_rgba;
typedef struct window_sdl2 s_window_sdl2;
/* return false to break event loop */
typedef bool (*f_window_sdl2_button) (s_window_sdl2 *window,
- u8 button, sw x, sw y);
+ u8 button, sw x, sw y);
/* return false to break event loop */
typedef bool (*f_window_sdl2_key) (s_window_sdl2 *window,
@@ -44,7 +46,7 @@ typedef bool (*f_window_sdl2_load) (s_window_sdl2 *window);
/* return false to break event loop */
typedef bool (*f_window_sdl2_motion) (s_window_sdl2 *window, sw x,
- sw y);
+ sw y);
/* return false to break event loop */
typedef bool (*f_window_sdl2_render) (s_window_sdl2 *window,
@@ -52,7 +54,7 @@ typedef bool (*f_window_sdl2_render) (s_window_sdl2 *window,
/* return false to break event loop */
typedef bool (*f_window_sdl2_resize) (s_window_sdl2 *window,
- uw w, uw h);
+ uw w, uw h);
typedef bool (*f_window_sdl2_sequence_load) (s_sequence *seq,
s_window_sdl2 *window);
@@ -69,6 +71,19 @@ struct sdl2_font {
s_str real_path;
};
+struct sdl2_sprite {
+ s_str path;
+ s_str real_path;
+ uw total_w;
+ uw total_h;
+ uw dim_x;
+ uw dim_y;
+ uw frame_count;
+ uw w;
+ uw h;
+ GLuint *gl_textures;
+};
+
struct rgb {
double r;
double g;