diff --git a/config.subr b/config.subr
index c4f6dc8..c31a12b 100644
--- a/config.subr
+++ b/config.subr
@@ -120,12 +120,23 @@ config_lib() {
OUT=".config_$NAME"
echo "/* generated by configure */" > "$OUT_C"
echo "int main (void) { return 0; }" >> "$OUT_C"
- if ${CC} ${CPPFLAGS} ${CFLAGS} "$OUT_C" ${LIBS} $@ -o "$OUT"; then
+ if ${CC} ${CPPFLAGS} ${CFLAGS} "$OUT_C" ${LDFLAGS} ${LIBS} $@ -o "$OUT"; then
LIBS="$LIBS $@"
fi
rm -f "$OUT" "$OUT_C"
}
+config_no_undefined() {
+ OUT_C=".config_no_undefined.c"
+ OUT=".config_no_undefined"
+ echo "/* generated by configure */" > "$OUT_C"
+ echo "int main (void) { return 0; }" >> "$OUT_C"
+ if ${CC} ${CPPFLAGS} ${CFLAGS} "$OUT_C" ${LDFLAGS} -no-undefined ${LIBS} $@ -o "$OUT" >/dev/null 2>&1; then
+ LDFLAGS="$LDFLAGS -no-undefined"
+ fi
+ rm -f "$OUT" "$OUT_C"
+}
+
env_reset() {
CPPFLAGS="$ENV_CPPFLAGS"
CFLAGS="$ENV_CFLAGS"
@@ -351,3 +362,5 @@ if [ "x$LIBDIR" = "x" ]; then
LIBDIR="${PREFIX}/lib"
fi
echo "LIBDIR = $LIBDIR" >> ${CONFIG_MK}
+
+config_no_undefined
diff --git a/libc3/configure b/libc3/configure
index ddd324c..59c6d08 100755
--- a/libc3/configure
+++ b/libc3/configure
@@ -38,7 +38,7 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$LO_SOURCES")"
# Common config for all targets
CPPFLAGS="-I../libffi/include $CPPFLAGS"
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic -fPIC"
-LDFLAGS="--shared -no-undefined ${LDFLAGS}"
+LDFLAGS="--shared ${LDFLAGS}"
LIBS="${LIBS} -lm -pthread -rpath ${PREFIX}/lib"
config_asan
config_gnu
diff --git a/libc3/window/cairo/cairo_sprite.c b/libc3/window/cairo/cairo_sprite.c
index ebc907a..8b2063e 100644
--- a/libc3/window/cairo/cairo_sprite.c
+++ b/libc3/window/cairo/cairo_sprite.c
@@ -12,56 +12,123 @@
*/
#include <assert.h>
#include <err.h>
+#include <libc3/c3.h>
#include "cairo_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) {
+ iluDestroy();
+ ilDestroy();
+ g_il_is_loaded = false;
+ }
+ */
+}
+
void cairo_sprite_blit (const s_cairo_sprite *sprite, uw frame,
cairo_t *cr, uw x, uw y)
{
- uw frame_x;
- uw frame_y;
- cairo_matrix_t matrix;
- cairo_pattern_t *pattern;
assert(sprite);
assert(frame < sprite->frame_count);
assert(cr);
frame %= sprite->frame_count;
- frame_x = frame % sprite->dim_x;
- frame_y = frame / sprite->dim_x;
- frame_x *= sprite->w;
- frame_y *= sprite->h;
- pattern = cairo_pattern_create_for_surface(sprite->surface);
- cairo_matrix_init_translate(&matrix, frame_x, frame_y);
- cairo_pattern_set_matrix(pattern, &matrix);
- cairo_set_source(cr, pattern);
+ cairo_set_source_surface(cr, sprite->surface[frame], 0, 0);
cairo_rectangle(cr, x, y, sprite->w, sprite->h);
cairo_fill(cr);
- cairo_pattern_destroy(pattern);
}
void cairo_sprite_clean (s_cairo_sprite *sprite)
{
+ uw i;
assert(sprite);
- cairo_surface_destroy(sprite->surface);
+ i = 0;
+ while (i < sprite->frame_count) {
+ cairo_surface_destroy(sprite->surface[i]);
+ i++;
+ }
+ free(sprite->surface);
}
s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
- cairo_surface_t *surface,
+ const s8 *path,
uw dim_x, uw dim_y,
uw frame_count)
{
assert(sprite);
assert(dim_x);
assert(dim_y);
- if (! (sprite->surface = surface)) {
- warnx("cairo_sprite_init: NULL surface");
+ ILubyte *data;
+ uw i;
+ ILuint il_image[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("cairo_sprite_init: file not found: %s", path);
+ str_clean(&sprite->path);
return NULL;
}
- sprite->total_w = cairo_image_surface_get_width(surface);
- sprite->total_h = cairo_image_surface_get_height(surface);
+ ilEnsureInit();
+ ilGenImages(2, il_image);
+ ilBindImage(il_image[0]);
+ if (! ilLoadImage(sprite->path.ptr.ps8)) {
+ warnx("cairo_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);
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);
+ sprite->surface = calloc(frame_count, sizeof(cairo_surface_t *));
+ if (! sprite->surface) {
+ warn("cairo_sprite_init: sprite->surface");
+ ilDeleteImages(2, il_image);
+ str_clean(&sprite->path);
+ str_clean(&sprite->real_path);
+ return NULL;
+ }
+ i = 0;
+ y = 0;
+ while (i < sprite->frame_count && y < dim_y) {
+ x = 0;
+ while (i < sprite->frame_count && x < dim_x) {
+ ilBindImage(il_image[1]);
+ ilTexImage(sprite->w, sprite->h, 1, 32, IL_RGBA, IL_UNSIGNED_BYTE,
+ NULL);
+ data = ilGetData();
+ ilBindImage(il_image[0]);
+ ilCopyPixels(x * sprite->w, y * sprite->h, 0,
+ sprite->w, sprite->h, 1, IL_RGBA, IL_UNSIGNED_BYTE,
+ data);
+ sprite->surface[i] = cairo_image_surface_create_for_data
+ (data, CAIRO_FORMAT_ARGB32, sprite->w, sprite->h, sprite->w * 4);
+ i++;
+ x++;
+ }
+ y++;
+ }
+ ilDeleteImages(2, il_image);
return sprite;
}
diff --git a/libc3/window/cairo/cairo_sprite.h b/libc3/window/cairo/cairo_sprite.h
index 62a45b4..53822f7 100644
--- a/libc3/window/cairo/cairo_sprite.h
+++ b/libc3/window/cairo/cairo_sprite.h
@@ -19,7 +19,7 @@
/* stack allocation compatible functions */
void cairo_sprite_clean (s_cairo_sprite *sprite);
s_cairo_sprite * cairo_sprite_init (s_cairo_sprite *sprite,
- cairo_surface_t *surface,
+ const s8 *path,
uw dim_x, uw dim_y,
uw frame_count);
diff --git a/libc3/window/cairo/configure b/libc3/window/cairo/configure
index 32af4a8..d79f71b 100755
--- a/libc3/window/cairo/configure
+++ b/libc3/window/cairo/configure
@@ -38,12 +38,13 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
# Common config for all targets
CPPFLAGS="-I../../../libffi/include -I../../.. $CPPFLAGS"
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
-LDFLAGS="--shared -no-undefined ${LDFLAGS}"
+LDFLAGS="--shared ${LDFLAGS}"
LIBS="$LIBS -rpath ${PREFIX}/lib"
config_asan
config_gnu
pkg_config cairo
pkg_config freetype2
+config_lib IL -lIL -lILU
pkg_config libbsd-overlay
pkg_config xkbcommon
config_lib_have COCOA -framework Cocoa
diff --git a/libc3/window/cairo/demo/configure b/libc3/window/cairo/demo/configure
index bfbbc6a..94e186a 100755
--- a/libc3/window/cairo/demo/configure
+++ b/libc3/window/cairo/demo/configure
@@ -38,7 +38,7 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
# Common config for all targets
CPPFLAGS="-I../../../../libffi/include -I../../../.. $CPPFLAGS"
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
-LDFLAGS="--shared -no-undefined ${LDFLAGS}"
+LDFLAGS="--shared ${LDFLAGS}"
LIBS="$LIBS -rpath ${PREFIX}/lib"
config_asan
config_gnu
diff --git a/libc3/window/cairo/demo/window_cairo_demo.c b/libc3/window/cairo/demo/window_cairo_demo.c
index 62ed72a..c687106 100644
--- a/libc3/window/cairo/demo/window_cairo_demo.c
+++ b/libc3/window/cairo/demo/window_cairo_demo.c
@@ -19,7 +19,6 @@
#include "../../window.h"
#include "../window_cairo.h"
#include "../cairo_sprite.h"
-#include "../cairo_surface.h"
#include "window_cairo_demo.h"
#include "bg_rect.h"
#include "lightspeed.h"
@@ -80,23 +79,19 @@ bool window_cairo_demo_load (s_window_cairo *window)
window_cairo_sequence_init(window->sequence + 1, 20.0,
"02. Lightspeed",
lightspeed_load, lightspeed_render);
- if (! cairo_sprite_init(&g_toaster_sprite,
- cairo_png_1("img/flaps.png"),
+ if (! cairo_sprite_init(&g_toaster_sprite, "img/flaps.png",
4, 1, 4))
return false;
- if (! cairo_sprite_init(&g_toast_sprite,
- cairo_png_1("img/toast.png"),
+ if (! cairo_sprite_init(&g_toast_sprite, "img/toast.png",
1, 1, 1))
return false;
window_cairo_sequence_init(window->sequence + 2, 60.0,
"03. Toasters",
toasters_load, toasters_render);
- if (! cairo_sprite_init(&g_fly_sprite,
- cairo_png_1("img/fly-noto.png"),
+ if (! cairo_sprite_init(&g_fly_sprite, "img/fly-noto.png",
1, 1, 1))
return false;
- if (! cairo_sprite_init(&g_dead_fly_sprite,
- cairo_png_1("img/fly-dead.png"),
+ if (! cairo_sprite_init(&g_dead_fly_sprite, "img/fly-dead.png",
1, 1, 1))
return false;
window_cairo_sequence_init(window->sequence + 3, 60.0,
diff --git a/libc3/window/cairo/quartz/configure b/libc3/window/cairo/quartz/configure
index ad012e5..8fd6d69 100755
--- a/libc3/window/cairo/quartz/configure
+++ b/libc3/window/cairo/quartz/configure
@@ -47,16 +47,11 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
OBJECTS_DEBUG="$OBJECTS_DEBUG $(objc2ext .debug.lo "$OBJC_SOURCES")"
echo "OBJECTS_DEBUG = $OBJECTS_DEBUG" >> ${CONFIG_MK}
-# Default config
-CPPFLAGS="${CPPFLAGS:-}"
-ENV_CFLAGS="${CFLAGS:-}"
-DEFAULT_CFLAGS="-O2 -pipe -fPIC"
-LDFLAGS="${LDFLAGS:-}"
-LIBS="${LIBS:-}"
-
# Common config for all targets
-CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
CPPFLAGS="$CPPFLAGS -I../../../../libffi/include -I../../../.."
+CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
+LDFLAGS="--shared $LDFLAGS"
+LIBS="$LIBS"
config_asan
config_gnu
pkg_config cairo
@@ -83,6 +78,7 @@ LOCAL_LIBS_DEBUG="../libc3_window_cairo_debug.la"
LIBS_DEBUG="$LOCAL_LIBS_DEBUG $LIBS"
# Main config
+DEFAULT_CFLAGS="-O2 -pipe"
if [ "x$ENV_CFLAGS" = "x" ]; then
CFLAGS="$CFLAGS $DEFAULT_CFLAGS"
fi
diff --git a/libc3/window/cairo/quartz/demo/configure b/libc3/window/cairo/quartz/demo/configure
index c6dd7de..744a9fb 100755
--- a/libc3/window/cairo/quartz/demo/configure
+++ b/libc3/window/cairo/quartz/demo/configure
@@ -100,7 +100,7 @@ LOCAL_LIBS_DEBUG="../../demo/libc3_window_cairo_demo_debug.la ../libc3_window_ca
LIBS_DEBUG="$LOCAL_LIBS_DEBUG $LIBS"
# Main config
-DEFAULT_CFLAGS="-O2 -pipe -fPIC"
+DEFAULT_CFLAGS="-O2 -pipe"
if [ "x$ENV_CFLAGS" = "x" ]; then
CFLAGS="$CFLAGS $DEFAULT_CFLAGS"
fi
diff --git a/libc3/window/cairo/sources.mk b/libc3/window/cairo/sources.mk
index b87ea50..50abea0 100644
--- a/libc3/window/cairo/sources.mk
+++ b/libc3/window/cairo/sources.mk
@@ -2,13 +2,11 @@
HEADERS = \
cairo_font.h \
cairo_sprite.h \
- cairo_surface.h \
types.h \
window_cairo.h \
SOURCES = \
cairo_font.c \
cairo_sprite.c \
- cairo_surface.c \
window_cairo.c \
diff --git a/libc3/window/cairo/sources.sh b/libc3/window/cairo/sources.sh
index d2c7fc8..35b3d02 100644
--- a/libc3/window/cairo/sources.sh
+++ b/libc3/window/cairo/sources.sh
@@ -1,3 +1,3 @@
# sources.sh generated by update_sources
-HEADERS='cairo_font.h cairo_sprite.h cairo_surface.h types.h window_cairo.h '
-SOURCES='cairo_font.c cairo_sprite.c cairo_surface.c window_cairo.c '
+HEADERS='cairo_font.h cairo_sprite.h types.h window_cairo.h '
+SOURCES='cairo_font.c cairo_sprite.c window_cairo.c '
diff --git a/libc3/window/cairo/types.h b/libc3/window/cairo/types.h
index 7c27bf4..e8674b2 100644
--- a/libc3/window/cairo/types.h
+++ b/libc3/window/cairo/types.h
@@ -22,6 +22,8 @@
#include <cairo-ft.h>
#include <ft2build.h>
#include FT_FREETYPE_H
+#include <IL/il.h>
+#include <IL/ilu.h>
#include <libc3/types.h>
#include "../types.h"
@@ -68,6 +70,8 @@ struct cairo_font {
};
struct cairo_sprite {
+ s_str path;
+ s_str real_path;
uw total_w;
uw total_h;
uw dim_x;
@@ -75,7 +79,7 @@ struct cairo_sprite {
uw frame_count;
uw w;
uw h;
- cairo_surface_t *surface;
+ cairo_surface_t **surface;
};
struct rgb {
diff --git a/libc3/window/cairo/win32/configure b/libc3/window/cairo/win32/configure
index 83c221a..f612b27 100644
--- a/libc3/window/cairo/win32/configure
+++ b/libc3/window/cairo/win32/configure
@@ -43,7 +43,7 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
# Common config for all targets
CPPFLAGS="-I../../../../libffi/include -I../../../.. $CPPFLAGS"
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
-LDFLAGS="--shared -no-undefined ${LDFLAGS}"
+LDFLAGS="--shared $LDFLAGS"
LIBS="$LIBS -rpath ${PREFIX}/lib"
config_asan
config_gnu
diff --git a/libc3/window/cairo/xcb/configure b/libc3/window/cairo/xcb/configure
index 11dbc78..3614681 100755
--- a/libc3/window/cairo/xcb/configure
+++ b/libc3/window/cairo/xcb/configure
@@ -38,7 +38,7 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
# Common config for all targets
CPPFLAGS="$CPPFLAGS -I../../../../libffi/include -I../../../.."
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic -fPIC"
-LDFLAGS="--shared -no-undefined ${LDFLAGS}"
+LDFLAGS="--shared ${LDFLAGS}"
LIBS="$LIBS -rpath ${PREFIX}/lib"
config_asan
config_gnu
diff --git a/libc3/window/configure b/libc3/window/configure
index 89fd38b..7f67cfa 100755
--- a/libc3/window/configure
+++ b/libc3/window/configure
@@ -38,7 +38,7 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
# Common config for all targets
CPPFLAGS="-I../../libffi/include -I../.. $CPPFLAGS"
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
-LDFLAGS="--shared -no-undefined ${LDFLAGS}"
+LDFLAGS="--shared ${LDFLAGS}"
LIBS="$LIBS -rpath ${PREFIX}/lib"
config_asan
config_gnu
diff --git a/libc3/window/sdl2/configure b/libc3/window/sdl2/configure
index 078a37c..b33d970 100755
--- a/libc3/window/sdl2/configure
+++ b/libc3/window/sdl2/configure
@@ -39,7 +39,7 @@ OBJECTS_DEBUG="$(c2ext .debug.lo "$SOURCES")"
CPPFLAGS="-I../../../libffi/include -I../../.. $CPPFLAGS"
CPPFLAGS="$CPPFLAGS -DGL_SILENCE_DEPRECATION=1"
CFLAGS="$CFLAGS -W -Wall -Werror -std=c99 -pedantic"
-LDFLAGS="--shared -no-undefined ${LDFLAGS}"
+LDFLAGS="--shared ${LDFLAGS}"
LIBS="$LIBS -rpath ${PREFIX}/lib"
config_asan
config_gnu
diff --git a/libc3/window/sdl2/sdl2_sprite.c b/libc3/window/sdl2/sdl2_sprite.c
index f0c5862..5912c12 100644
--- a/libc3/window/sdl2/sdl2_sprite.c
+++ b/libc3/window/sdl2/sdl2_sprite.c
@@ -41,8 +41,10 @@ void ilClean (void)
void sdl2_sprite_clean (s_sdl2_sprite *sprite)
{
assert(sprite);
- (void) sprite;
- // TODO
+ str_clean(&sprite->path);
+ str_clean(&sprite->real_path);
+ glDeleteTextures(sprite->frame_count, sprite->texture);
+ free(sprite->texture);
}
s_sdl2_sprite * sdl2_sprite_init (s_sdl2_sprite *sprite,
@@ -51,9 +53,9 @@ s_sdl2_sprite * sdl2_sprite_init (s_sdl2_sprite *sprite,
uw frame_count)
{
//ILint bpp;
- ILubyte *data;
+ ILubyte *data[3];
uw i;
- ILuint il_images[2];
+ ILuint il_image[3];
uw x;
uw y;
assert(sprite);
@@ -68,8 +70,8 @@ s_sdl2_sprite * sdl2_sprite_init (s_sdl2_sprite *sprite,
return NULL;
}
ilEnsureInit();
- ilGenImages(2, il_images);
- ilBindImage(il_images[0]);
+ ilGenImages(3, il_image);
+ ilBindImage(il_image[0]);
if (! ilLoadImage(sprite->path.ptr.ps8)) {
warnx("sdl2_sprite_init: error loading image: %s",
iluErrorString(ilGetError()));
@@ -85,20 +87,30 @@ s_sdl2_sprite * sdl2_sprite_init (s_sdl2_sprite *sprite,
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);
- sprite->gl_textures = malloc(frame_count * sizeof(GLuint));
- if (! sprite->gl_textures) {
- warn("sdl2_sprite: sprite->gl_textures");
- ilDeleteImages(2, il_images);
+ sprite->texture = malloc(frame_count * sizeof(GLuint));
+ if (! sprite->texture) {
+ warn("sdl2_sprite_init: sprite->texture");
+ ilDeleteImages(2, il_image);
str_clean(&sprite->path);
str_clean(&sprite->real_path);
return NULL;
}
- glGenTextures(frame_count, sprite->gl_textures);
- ilBindImage(il_images[1]);
- ilTexImage(sprite->w, sprite->h, 1, 32, IL_RGBA, IL_UNSIGNED_BYTE,
+ glGenTextures(frame_count, sprite->texture);
+ ilBindImage(il_image[1]);
+ ilTexImage(sprite->w, sprite->h, 1, 4, IL_RGBA, IL_UNSIGNED_BYTE,
NULL);
- data = ilGetData();
- ilBindImage(il_images[0]);
+ data[1] = ilGetData();
+ ilBindImage(il_image[2]);
+ sprite->tex_w = 1;
+ while (sprite->tex_w < sprite->w)
+ sprite->tex_w *= 2;
+ sprite->tex_h = 1;
+ while (sprite->tex_h < sprite->h)
+ sprite->tex_h *= 2;
+ ilTexImage(sprite->tex_w, sprite->tex_h, 1, 4, IL_RGBA,
+ IL_UNSIGNED_BYTE, NULL);
+ data[2] = ilGetData();
+ ilBindImage(il_image[0]);
i = 0;
y = 0;
while (i < sprite->frame_count && y < dim_y) {
@@ -106,13 +118,19 @@ s_sdl2_sprite * sdl2_sprite_init (s_sdl2_sprite *sprite,
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);
- glTexImage2D(
+ data[1]);
+ iluImageParameter(ILU_FILTER, ILU_SCALE_MITCHELL);
+ ilBlit(il_image[1], 0, 0, 0, 0, 0, 0,
+ sprite->tex_w, sprite->tex_h, 1);
+ glBindTexture(GL_TEXTURE_2D, sprite->texture[i]);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
+ sprite->tex_w, sprite->tex_h, 0, GL_RGBA,
+ GL_UNSIGNED_BYTE, data[2]);
i++;
x++;
}
y++;
}
- ilDeleteImages(2, il_images);
+ ilDeleteImages(3, il_image);
return sprite;
}
diff --git a/libc3/window/sdl2/types.h b/libc3/window/sdl2/types.h
index 093f8ea..9e973a5 100644
--- a/libc3/window/sdl2/types.h
+++ b/libc3/window/sdl2/types.h
@@ -81,7 +81,9 @@ struct sdl2_sprite {
uw frame_count;
uw w;
uw h;
- GLuint *gl_textures;
+ uw tex_w;
+ uw tex_h;
+ GLuint *texture;
};
struct rgb {
diff --git a/libtommath b/libtommath
index 1dc2188..1012230 160000
--- a/libtommath
+++ b/libtommath
@@ -1 +1 @@
-Subproject commit 1dc21885774654ceec6b555513eebce7e2142244
+Subproject commit 10122309f4d721ad39716c29bc7c5ec9fe22be6e