changeset 447:e1fa1b867281

cmake: resurrection Using GNU make for such a big project is tedious.
author David Demelier <markand@malikania.fr>
date Sat, 18 Feb 2023 12:43:05 +0100
parents 4607eea0eabc
children 0c4cd552879d
files .hgignore CMakeLists.txt GNUmakefile README.md cmake/FindJansson.cmake cmake/FindLibzip.cmake cmake/FindNLS.cmake cmake/FindSDL2.cmake cmake/FindSndFile.cmake cmake/FindZSTD.cmake cmake/MlkBcc.cmake cmake/MlkExecutable.cmake cmake/MlkLibrary.cmake cmake/MlkMap.cmake cmake/MlkNls.cmake cmake/MlkTileset.cmake doc/CMakeLists.txt doc/mkdocs.yml examples/CMakeLists.txt examples/example-action/CMakeLists.txt examples/example-animation/CMakeLists.txt examples/example-audio/CMakeLists.txt examples/example-battle/CMakeLists.txt examples/example-cursor/CMakeLists.txt examples/example-debug/CMakeLists.txt examples/example-drawable/CMakeLists.txt examples/example-font/CMakeLists.txt examples/example-gridmenu/CMakeLists.txt examples/example-label/CMakeLists.txt examples/example-message/CMakeLists.txt examples/example-notify/CMakeLists.txt examples/example-sprite/CMakeLists.txt examples/example-trace/CMakeLists.txt examples/example-ui/CMakeLists.txt extern/libdt/CMakeLists.txt extern/libduktape/CMakeLists.txt extern/libsqlite/CMakeLists.txt libmlk-core/CMakeLists.txt libmlk-core/nls/fr.po libmlk-core/nls/libmlk-core.pot libmlk-rpg/CMakeLists.txt libmlk-rpg/mlk/rpg/character.c libmlk-rpg/mlk/rpg/property.c libmlk-rpg/mlk/rpg/quest.c libmlk-rpg/mlk/rpg/save.c libmlk-rpg/nls/fr.po libmlk-rpg/nls/libmlk-rpg.pot libmlk-ui/CMakeLists.txt libmlk-ui/mlk/ui/theme.c libmlk-ui/nls/fr.po libmlk-ui/nls/libmlk-ui.pot libmlk-util/CMakeLists.txt mlk-bcc/CMakeLists.txt mlk-map/CMakeLists.txt mlk-tileset/CMakeLists.txt tests/CMakeLists.txt
diffstat 56 files changed, 2555 insertions(+), 457 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Sat Feb 18 12:15:14 2023 +0100
+++ b/.hgignore	Sat Feb 18 12:43:05 2023 +0100
@@ -24,7 +24,6 @@
 
 # Generated files.
 \.exe$
-^config\.mk$
 
 # Examples.
 ^examples/example-action/example-action$
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,90 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2023 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+cmake_minimum_required(VERSION 3.20)
+project(molko C)
+
+set_property(GLOBAL PROPERTY USE_FOLDERS On)
+
+set(CMAKE_C_STANDARD 99)
+set(CMAKE_C_STANDARD_REQUIRED On)
+set(CMAKE_C_EXTENSIONS On)
+set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
+
+if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
+	set(CMAKE_C_FLAGS "-Wall -Wextra -Wno-deprecated-declarations -Wno-unknown-pragmas -pedantic ${CMAKE_C_FLAGS}")
+
+	if (CMAKE_C_COMPILER_ID MATCHES "GNU")
+		set(CMAKE_C_FLAGS "-Wno-format-truncation ${CMAKE_C_FLAGS}")
+	endif ()
+elseif (CMAKE_C_COMPILER_ID MATCHES "MSVC")
+	set(CMAKE_C_FLAGS "/W3 /wd4090 /wd4244 /wd4267 /wd4996 /wd5105 /wd6031 /wd6001 /wd26451 ${CMAKE_C_FLAGS}")
+	set(CMAKE_C_FLAGS "/D_CRT_SECURE_NO_WARNINGS ${CMAKE_C_FLAGS}")
+endif ()
+
+option(MLK_WITH_DOC "Enable mkdocs documentation" On)
+option(MLK_WITH_EXAMPLES "Enable examples" Off)
+option(MLK_WITH_NLS "Enable NLS support" On)
+option(MLK_WITH_TESTS "Enable unit tests" Off)
+
+include(cmake/MlkBcc.cmake)
+include(cmake/MlkExecutable.cmake)
+include(cmake/MlkLibrary.cmake)
+include(cmake/MlkMap.cmake)
+include(cmake/MlkNls.cmake)
+include(cmake/MlkTileset.cmake)
+
+include(GNUInstallDirs)
+
+find_package(SDL2 REQUIRED COMPONENTS image ttf)
+find_package(OpenAL REQUIRED)
+find_package(SndFile REQUIRED)
+find_package(Jansson REQUIRED)
+
+# POSIX math library isn't available everywhere.
+find_library(M_LIBRARY m)
+
+if (MLK_WITH_NLS)
+	find_package(NLS REQUIRED)
+	find_package(Intl REQUIRED)
+endif ()
+
+add_subdirectory(extern/libsqlite)
+add_subdirectory(extern/libdt)
+
+if (MLK_WITH_DOC)
+	add_subdirectory(doc)
+endif ()
+
+add_subdirectory(mlk-bcc)
+add_subdirectory(mlk-tileset)
+add_subdirectory(mlk-map)
+
+add_subdirectory(libmlk-util)
+add_subdirectory(libmlk-core)
+add_subdirectory(libmlk-ui)
+add_subdirectory(libmlk-rpg)
+
+if (MLK_WITH_TESTS)
+	enable_testing()
+	add_subdirectory(tests)
+endif ()
+
+if (MLK_WITH_EXAMPLES)
+	add_subdirectory(examples)
+endif ()
--- a/GNUmakefile	Sat Feb 18 12:15:14 2023 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,444 +0,0 @@
--include config.mk
-
-# Toolchain options.
-CC ?=                   clang
-CFLAGS ?=               -g -O0
-
-# Installation directory.
-PREFIX ?=               /usr/local
-LIBDIR ?=               $(PREFIX)/lib
-INCDIR ?=               $(PREFIX)/include
-MANDIR ?=               $(PREFIX)/share/man
-
-# User options.
-WITH_DEBUG ?=           no
-
-OS :=                   $(shell uname -s)
-
-SDL2_INCS ?=            $(shell pkg-config --cflags sdl2)
-SDL2_LIBS ?=            $(shell pkg-config --libs sdl2)
-
-SDL2_IMAGE_INCS ?=      $(shell pkg-config --cflags SDL2_image)
-SDL2_IMAGE_LIBS ?=      $(shell pkg-config --libs SDL2_image)
-
-SDL2_TTF_INCS ?=        $(shell pkg-config --cflags SDL2_ttf)
-SDL2_TTF_LIBS ?=        $(shell pkg-config --libs SDL2_ttf)
-
-SNDFILE_INCS ?=         $(shell pkg-config --cflags sndfile)
-SNDFILE_LIBS ?=         $(shell pkg-config --libs sndfile)
-
-JANSSON_INCS ?=         $(shell pkg-config --cflags jansson)
-JANSSON_LIBS ?=         $(shell pkg-config --libs jansson)
-
-ifeq ($(OS),Darwin)
-OPENAL_LIBS ?=          -framework OpenAL
-else
-OPENAL_INCS ?=          $(shell pkg-config --cflags openal)
-OPENAL_LIBS ?=          $(shell pkg-config --libs openal)
-endif
-
-MATH_LIBS ?=            -lm
-
-# Global INCS, OPTS and DEFS for every targets.
-INCS :=                 -Iextern/libdt \
-                        -Iextern/libsqlite \
-                        -Ilibmlk-util \
-                        -Ilibmlk-core \
-                        -Ilibmlk-ui \
-                        -Ilibmlk-rpg \
-                        -I. \
-                        $(SDL2_INCS) \
-                        $(SDL2_IMAGE_INCS) \
-                        $(SDL2_TTF_INCS) \
-                        $(OPENAL_INCS) \
-                        $(SNDFILE_INCS)
-
-OPTS +=                 -Wall -Wextra -pipe
-
-ifeq ($(OS),Darwin)
-OPTS +=                 -Wno-deprecated-declarations
-endif
-
-ifeq ($(WITH_DEBUG),yes)
-OPTS +=                 -g -O0
-else
-OPTS +=                 -DNDEBUG -O3
-endif
-
-BCC_OPTS :=             -cs
-MD ?=                   -MD
-
-# Meta variable that contains all libraries, used for executables and tests.
-LIBMLK =                $(LIBMLK_RPG) \
-                        $(LIBMLK_UI) \
-                        $(LIBMLK_CORE) \
-                        $(LIBMLK_UTIL) \
-                        $(LIBMLK_SQLITE) \
-                        $(MATH_LIBS) \
-                        $(SDL2_LIBS) \
-                        $(SDL2_IMAGE_LIBS) \
-                        $(SDL2_TTF_LIBS) \
-                        $(OPENAL_LIBS) \
-                        $(SNDFILE_LIBS)
-
-.DEFAULT_GOAL :=        all
-
-.SUFFIXES:
-.SUFFIXES: .c .h .o .ogg .png .sql .ttf .wav
-
-.c.o:
-	$(CC) $(OPTS) $(INCS) $(DEFS) $(CFLAGS) $(MD) -c $< -o $@
-
-.c:
-	$(CC) $(OPTS) $(INCS) $(DEFS) $(CFLAGS) $< -o $@ $(OBJS) $(LIBS) $(LDFLAGS)
-
-.ogg.h .png.h .ttf.h .sql.h .wav.h:
-	$(MLK_BCC) $(BCC_OPTS) $< assets_$(basename $(<F)) > $@
-
-%.a:
-	$(AR) -rc $@ $(OBJS)
-
-# {{{ libmlk-util
-
-LIBMLK_UTIL :=          libmlk-util.a
-LIBMLK_UTIL_SRCS :=     libmlk-util/mlk/util/fmemopen.c \
-                        libmlk-util/mlk/util/openbsd/basename.c \
-                        libmlk-util/mlk/util/openbsd/dirname.c \
-                        libmlk-util/mlk/util/openbsd/getopt.c \
-                        libmlk-util/mlk/util/openbsd/strlcat.c \
-                        libmlk-util/mlk/util/openbsd/strlcpy.c
-LIBMLK_UTIL_OBJS :=     $(LIBMLK_UTIL_SRCS:.c=.o)
-LIBMLK_UTIL_DEPS :=     $(LIBMLK_UTIL_SRCS:.c=.d)
-
--include $(LIBMLK_UTIL_DEPS)
-
-$(LIBMLK_UTIL): INCS :=
-$(LIBMLK_UTIL): OBJS := $(LIBMLK_UTIL_OBJS)
-$(LIBMLK_UTIL): $(LIBMLK_UTIL_OBJS)
-
-all: $(LIBMLK_UTIL)
-
-# }}}
-
-# {{{ mlk-bcc
-
-MLK_BCC :=              mlk-bcc/mlk-bcc
-
-$(MLK_BCC): INCS :=
-
-all: $(MLK_BCC)
-
-# }}}
-
-# {{{ mlk-tileset
-
-MLK_TILESET :=          mlk-tileset/mlk-tileset
-
-$(MLK_TILESET): INCS := $(JANSSON_INCS)
-$(MLK_TILESET): LIBS := $(JANSSON_LIBS)
-
-all: $(MLK_TILESET)
-
-# }}}
-
-# {{{ mlk-map
-
-MLK_MAP :=              mlk-map/mlk-map
-
-$(MLK_MAP): INCS := -Ilibmlk-util $(JANSSON_INCS)
-$(MLK_MAP): LIBS := $(LIBMLK_UTIL) $(JANSSON_LIBS)
-$(MLK_MAP): $(LIBMLK_UTIL)
-
-all: $(MLK_MAP)
-
-# }}}
-
-# {{{ libmlk-sqlite
-
-LIBMLK_SQLITE :=          libmlk-sqlite.a
-LIBMLK_SQLITE_SRCS :=     extern/libsqlite/sqlite3.c
-LIBMLK_SQLITE_OBJS :=     $(LIBMLK_SQLITE_SRCS:.c=.o)
-LIBMLK_SQLITE_DEPS :=     $(LIBMLK_SQLITE_SRCS:.c=.d)
-
--include $(LIBMLK_SQLITE_DEPS)
-
-$(LIBMLK_SQLITE_OBJS): private DEFS += -DSQLITE_THREADSAFE=0 \
-                                       -DSQLITE_DEFAULT_MEMSTATUS=0 \
-                                       -DSQLITE_OMIT_DECLTYPE \
-                                       -DSQLITE_OMIT_DEPRECATED \
-                                       -DSQLITE_OMIT_LOAD_EXTENSION \
-                                       -DSQLITE_DEFAULT_FOREIGN_KEY=0
-
-$(LIBMLK_SQLITE): private INCS :=
-$(LIBMLK_SQLITE): private OBJS := $(LIBMLK_SQLITE_OBJS)
-$(LIBMLK_SQLITE): $(LIBMLK_SQLITE_OBJS)
-
-all: $(LIBMLK_SQLITE)
-
-# }}}
-
-# {{{ libmlk-core
-
-LIBMLK_CORE :=          libmlk-core.a
-LIBMLK_CORE_SRCS :=     libmlk-core/mlk/core/action-stack.c \
-                        libmlk-core/mlk/core/action.c \
-                        libmlk-core/mlk/core/alloc.c \
-                        libmlk-core/mlk/core/animation.c \
-                        libmlk-core/mlk/core/clock.c \
-                        libmlk-core/mlk/core/core.c \
-                        libmlk-core/mlk/core/drawable-stack.c \
-                        libmlk-core/mlk/core/drawable.c \
-                        libmlk-core/mlk/core/err.c \
-                        libmlk-core/mlk/core/error.c \
-                        libmlk-core/mlk/core/event.c \
-                        libmlk-core/mlk/core/font.c \
-                        libmlk-core/mlk/core/game.c \
-                        libmlk-core/mlk/core/gamepad.c \
-                        libmlk-core/mlk/core/image.c \
-                        libmlk-core/mlk/core/maths.c \
-                        libmlk-core/mlk/core/music.c \
-                        libmlk-core/mlk/core/painter.c \
-                        libmlk-core/mlk/core/panic.c \
-                        libmlk-core/mlk/core/script.c \
-                        libmlk-core/mlk/core/sound.c \
-                        libmlk-core/mlk/core/sprite.c \
-                        libmlk-core/mlk/core/state.c \
-                        libmlk-core/mlk/core/sys.c \
-                        libmlk-core/mlk/core/texture.c \
-                        libmlk-core/mlk/core/trace.c \
-                        libmlk-core/mlk/core/util.c \
-                        libmlk-core/mlk/core/window.c
-LIBMLK_CORE_OBJS :=     $(LIBMLK_CORE_SRCS:.c=.o)
-LIBMLK_CORE_DEPS :=     $(LIBMLK_CORE_SRCS:.c=.d)
-
--include $(LIBMLK_CORE_DEPS)
-
-$(LIBMLK_CORE): private OBJS := $(LIBMLK_CORE_OBJS)
-$(LIBMLK_CORE): $(LIBMLK_CORE_OBJS)
-
-all: $(LIBMLK_CORE)
-
-# }}}
-
-# {{{ libmlk-ui
-
-LIBMLK_UI :=            libmlk-ui.a
-LIBMLK_UI_SRCS :=       libmlk-ui/mlk/ui/align.c \
-                        libmlk-ui/mlk/ui/button.c \
-                        libmlk-ui/mlk/ui/checkbox.c \
-                        libmlk-ui/mlk/ui/debug.c \
-                        libmlk-ui/mlk/ui/frame.c \
-                        libmlk-ui/mlk/ui/gridmenu.c \
-                        libmlk-ui/mlk/ui/label.c \
-                        libmlk-ui/mlk/ui/notify.c \
-                        libmlk-ui/mlk/ui/theme.c \
-                        libmlk-ui/mlk/ui/ui.c
-
-LIBMLK_UI_OBJS :=       $(LIBMLK_UI_SRCS:.c=.o)
-LIBMLK_UI_DEPS :=       $(LIBMLK_UI_SRCS:.c=.d)
-LIBMLK_UI_DATA_SRCS :=  libmlk-ui/assets/fonts/opensans-light.ttf \
-                        libmlk-ui/assets/fonts/opensans-medium.ttf \
-                        libmlk-ui/assets/fonts/opensans-regular.ttf
-LIBMLK_UI_DATA_OBJS :=  $(addsuffix .h,$(basename $(LIBMLK_UI_DATA_SRCS)))
-
-$(LIBMLK_UI_DATA_OBJS): $(MLK_BCC)
-
-$(LIBMLK_UI_OBJS): $(LIBMLK_UI_DATA_OBJS)
-
-$(LIBMLK_UI): $(LIBMLK_UI_OBJS)
-$(LIBMLK_UI): private OBJS := $(LIBMLK_UI_OBJS)
-
-all: $(LIBMLK_UI)
-
-# }}}
-
-# {{{ libmlk-rpg
-
-LIBMLK_RPG :=           libmlk-rpg.a
-LIBMLK_RPG_SRCS :=      libmlk-rpg/mlk/rpg/battle-bar-default.c \
-                        libmlk-rpg/mlk/rpg/battle-bar.c \
-                        libmlk-rpg/mlk/rpg/battle-entity-state-attacking.c \
-                        libmlk-rpg/mlk/rpg/battle-entity-state-blinking.c \
-                        libmlk-rpg/mlk/rpg/battle-entity-state-moving.c \
-                        libmlk-rpg/mlk/rpg/battle-entity-state-normal.c \
-                        libmlk-rpg/mlk/rpg/battle-entity-state.c \
-                        libmlk-rpg/mlk/rpg/battle-entity.c \
-                        libmlk-rpg/mlk/rpg/battle-indicator.c \
-                        libmlk-rpg/mlk/rpg/battle-message.c \
-                        libmlk-rpg/mlk/rpg/battle-state-ai.c \
-                        libmlk-rpg/mlk/rpg/battle-state-attacking.c \
-                        libmlk-rpg/mlk/rpg/battle-state-check.c \
-                        libmlk-rpg/mlk/rpg/battle-state-closing.c \
-                        libmlk-rpg/mlk/rpg/battle-state-item.c \
-                        libmlk-rpg/mlk/rpg/battle-state-lost.c \
-                        libmlk-rpg/mlk/rpg/battle-state-menu.c \
-                        libmlk-rpg/mlk/rpg/battle-state-opening.c \
-                        libmlk-rpg/mlk/rpg/battle-state-rendering.c \
-                        libmlk-rpg/mlk/rpg/battle-state-selection.c \
-                        libmlk-rpg/mlk/rpg/battle-state-victory.c \
-                        libmlk-rpg/mlk/rpg/battle-state.c \
-                        libmlk-rpg/mlk/rpg/battle.c \
-                        libmlk-rpg/mlk/rpg/character.c \
-                        libmlk-rpg/mlk/rpg/equipment.c \
-                        libmlk-rpg/mlk/rpg/inventory.c \
-                        libmlk-rpg/mlk/rpg/item.c \
-                        libmlk-rpg/mlk/rpg/map-file.c \
-                        libmlk-rpg/mlk/rpg/map.c \
-                        libmlk-rpg/mlk/rpg/message.c \
-                        libmlk-rpg/mlk/rpg/property.c \
-                        libmlk-rpg/mlk/rpg/quest.c \
-                        libmlk-rpg/mlk/rpg/rpg.c \
-                        libmlk-rpg/mlk/rpg/save.c \
-                        libmlk-rpg/mlk/rpg/selection.c \
-                        libmlk-rpg/mlk/rpg/spell.c \
-                        libmlk-rpg/mlk/rpg/team.c \
-                        libmlk-rpg/mlk/rpg/tileset-file.c \
-                        libmlk-rpg/mlk/rpg/tileset.c \
-                        libmlk-rpg/mlk/rpg/walksprite.c
-LIBMLK_RPG_OBJS :=      $(LIBMLK_RPG_SRCS:.c=.o)
-LIBMLK_RPG_DEPS :=      $(LIBMLK_RPG_SRCS:.c=.d)
-
-LIBMLK_RPG_DATA_SRCS := libmlk-rpg/assets/sql/character-load.sql \
-                        libmlk-rpg/assets/sql/character-save.sql \
-                        libmlk-rpg/assets/sql/init.sql \
-                        libmlk-rpg/assets/sql/property-load.sql \
-                        libmlk-rpg/assets/sql/property-remove.sql \
-                        libmlk-rpg/assets/sql/property-save.sql \
-                        libmlk-rpg/assets/sql/quest-remove.sql \
-                        libmlk-rpg/assets/sql/quest-save.sql \
-                        libmlk-rpg/assets/sql/quest-step-load.sql \
-                        libmlk-rpg/assets/sql/quest-step-save.sql
-LIBMLK_RPG_DATA_OBJS := $(addsuffix .h,$(basename $(LIBMLK_RPG_DATA_SRCS)))
-
-$(LIBMLK_RPG_DATA_OBJS): BCC_OPTS := -cs0
-$(LIBMLK_RPG_DATA_OBJS): $(MLK_BCC)
-
-$(LIBMLK_RPG_OBJS): $(LIBMLK_RPG_DATA_OBJS)
-
-$(LIBMLK_RPG): $(LIBMLK_RPG_OBJS)
-$(LIBMLK_RPG): private OBJS := $(LIBMLK_RPG_OBJS)
-
-all: $(LIBMLK_RPG)
-
-# }}}
-
-# {{{ libmlk-example
-
-LIBMLK_EXAMPLE :=               libmlk-example.a
-LIBMLK_EXAMPLE_SRCS :=          examples/example/character-john.c \
-                                examples/example/registry.c \
-                                examples/example/spell-fire.c \
-                                examples/example/trace_hud.c
-
-LIBMLK_EXAMPLE_DATA_SRCS :=     examples/assets/images/battle-background.png \
-                                examples/assets/images/black-cat.png \
-                                examples/assets/images/haunted-wood.png \
-                                examples/assets/images/sword.png \
-                                examples/assets/music/vabsounds-romance.ogg \
-                                examples/assets/sounds/fire.wav \
-                                examples/assets/sprites/chest.png \
-                                examples/assets/sprites/explosion.png \
-                                examples/assets/sprites/john-sword.png \
-                                examples/assets/sprites/john-walk.png \
-                                examples/assets/sprites/numbers.png \
-                                examples/assets/sprites/people.png \
-                                examples/assets/sprites/ui-cursor.png
-LIBMLK_EXAMPLE_DATA_OBJS :=     $(addsuffix .h,$(basename $(LIBMLK_EXAMPLE_DATA_SRCS)))
-
-LIBMLK_EXAMPLE_OBJS :=          $(LIBMLK_EXAMPLE_SRCS:.c=.o)
-LIBMLK_EXAMPLE_DEPS :=          $(LIBMLK_EXAMPLE_SRCS:.c=.d)
-
--include $(LIBMLK_EXAMPLE_DEPS)
-
-$(LIBMLK_EXAMPLE_DATA_OBJS): $(MLK_BCC)
-
-$(LIBMLK_EXAMPLE_OBJS): private INCS += -Iexamples
-$(LIBMLK_EXAMPLE_OBJS): $(LIBMLK_EXAMPLE_DATA_OBJS)
-
-$(LIBMLK_EXAMPLE): private OBJS := $(LIBMLK_EXAMPLE_OBJS)
-$(LIBMLK_EXAMPLE): $(LIBMLK_EXAMPLE_OBJS)
-
-# }}}
-
-# {{{ examples
-
-EXAMPLES :=             examples/example-action/example-action.c \
-                        examples/example-animation/example-animation.c \
-                        examples/example-audio/example-audio.c \
-                        examples/example-cursor/example-cursor.c \
-                        examples/example-debug/example-debug.c \
-                        examples/example-drawable/example-drawable.c \
-                        examples/example-font/example-font.c \
-                        examples/example-gridmenu/example-gridmenu.c \
-                        examples/example-label/example-label.c \
-                        examples/example-message/example-message.c \
-                        examples/example-notify/example-notify.c \
-                        examples/example-sprite/example-sprite.c \
-                        examples/example-ui/example-ui.c
-EXAMPLES_EXE :=         $(EXAMPLES:.c=)
-EXAMPLES_OBJS :=        $(EXAMPLES_EXE)
-
-$(EXAMPLES_EXE): private LIBS += $(LIBMLK) $(LIBMLK_EXAMPLE)
-$(EXAMPLES_EXE): private INCS += -Iexamples
-$(EXAMPLES_EXE): $(LIBMLK_RPG) $(LIBMLK_UI) $(LIBMLK_CORE) $(LIBMLK_UTIL) $(LIBMLK_SQLITE) $(LIBMLK_EXAMPLE)
-
-examples: $(EXAMPLES_EXE)
-
-# }}}
-
-# {{{ tests
-
-TESTS :=        tests/test-action-script.c \
-                tests/test-action.c \
-                tests/test-alloc.c \
-                tests/test-character.c \
-                tests/test-color.c \
-                tests/test-drawable.c \
-                tests/test-error.c \
-                tests/test-map.c \
-                tests/test-save-quest.c \
-                tests/test-save.c \
-                tests/test-state.c \
-                tests/test-tileset.c \
-                tests/test-util.c
-
-TESTS_EXE :=    $(TESTS:.c=)
-
-$(TESTS_EXE): private LIBS += $(LIBMLK)
-$(TESTS_EXE): private DEFS += -DDIRECTORY=\"$(CURDIR)/tests/assets\"
-$(TESTS_EXE): $(LIBMLK_RPG) $(LIBMLK_UI) $(LIBMLK_CORE) $(LIBMLK_UTIL) $(LIBMLK_SQLITE)
-
-tests: $(TESTS_EXE)
-	for t in $(TESTS_EXE); do ./$$t; done
-
-# }}}
-
-doc:
-	cd doc && mkdocs build
-
-doc-serve:
-	cd doc && mkdocs serve
-
-install:
-	mkdir -p $(DESTDIR)$(LIBDIR)
-	mkdir -p $(DESTDIR)$(INCDIR)/mlk/core
-	mkdir -p $(DESTDIR)$(INCDIR)/mlk/ui
-	mkdir -p $(DESTDIR)$(INCDIR)/mlk/rpg
-	cp $(LIBMLK_SQLITE) $(LIBMLK_CORE) $(LIBMLK_UI) $(LIBMLK_RPG) $(DESTDIR)$(LIBDIR)
-	cp -R libmlk-core/mlk/core/*.h $(DESTDIR)$(INCDIR)/mlk/core
-	cp -R libmlk-ui/mlk/ui/*.h $(DESTDIR)$(INCDIR)/mlk/ui
-	cp -R libmlk-rpg/mlk/rpg/*.h $(DESTDIR)$(INCDIR)/mlk/rpg
-	mkdir -p $(DESTDIR)$(MANDIR)/man3
-	cp man/*.3 $(DESTDIR)$(MANDIR)/man3
-
-clean:
-	rm -f $(MLK_BCC) $(MLK_MAP) $(MLK_TILESET)
-	rm -f $(LIBMLK_SQLITE) $(LIBMLK_SQLITE_DEPS) $(LIBMLK_SQLITE_OBJS)
-	rm -f $(LIBMLK_UTIL) $(LIBMLK_UTIL_DEPS) $(LIBMLK_UTIL_OBJS)
-	rm -f $(LIBMLK_CORE) $(LIBMLK_CORE_DEPS) $(LIBMLK_CORE_OBJS)
-	rm -f $(LIBMLK_UI) $(LIBMLK_UI_DEPS) $(LIBMLK_UI_OBJS) $(LIBMLK_UI_DATA_OBJS)
-	rm -f $(LIBMLK_RPG) $(LIBMLK_RPG_DEPS) $(LIBMLK_RPG_OBJS) $(LIBMLK_RPG_DATA_OBJS)
-	rm -f $(LIBMLK_EXAMPLE) $(LIBMLK_EXAMPLE_DEPS) $(LIBMLK_EXAMPLE_OBJS) $(LIBMLK_EXAMPLE_DATA_OBJS)
-	rm -f $(TESTS_EXE) $(EXAMPLES_EXE)
-
-.PHONY: all clean doc doc-serve examples install tests
--- a/README.md	Sat Feb 18 12:15:14 2023 +0100
+++ b/README.md	Sat Feb 18 12:43:05 2023 +0100
@@ -11,8 +11,54 @@
 - Simple, flexible,
 - Well documented,
 - Virtual file system support.
+- Usable in both C or Javascript.
 - Can embed resources using `mlk-bcc`.
 
+Javascript quick startup
+------------------------
+
+The `mlk-run` executable exposes the Javascript API and start a game from a
+directory or a .mlk file (which is a .zip file with a .mlk extension).
+
+Hello world in Javascript:
+
+	mkdir superluigi
+
+Add the following content in superluigi/main.js:
+
+```js
+var w = new Window("Super Luigi, number one", 640, 480);
+var run = true;
+
+while (run) {
+	var ev;
+
+	while ((ev = Event.poll())) {
+		switch (ev.type) {
+		case Event.Type.QUIT:
+			run = false;
+			break;
+		default:
+			break;
+		}
+
+		Painter.color = 0xFFFFFFFF;
+		Painter.clear();
+		Painter.present();
+	}
+}
+```
+
+Finally run the game using `mlk-run superluigi`.
+
+You can also create a .zip file with a .mlk extension and `mlk-run` will be able
+to use content from it.
+
+	cd superluigi
+	zip -r ../superluigi.mlk .
+	cd ..
+	mlk-run superluigi.mlk
+
 Documentation
 -------------
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/FindJansson.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,42 @@
+# FindJansson
+# -----------
+#
+# Find Jansson library, this modules defines:
+#
+# Jansson_INCLUDE_DIRS, where to find jansson.h
+# Jansson_LIBRARIES, where to find library
+# Jansson_FOUND, if it is found
+#
+# The following imported targets will be available:
+#
+# Jansson::Jansson, if found.
+#
+
+find_path(Jansson_INCLUDE_DIR NAMES jansson.h)
+find_library(Jansson_LIBRARY NAMES libjansson jansson jansson_d libjansson_d)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(
+	Jansson
+	FOUND_VAR Jansson_FOUND
+	REQUIRED_VARS Jansson_LIBRARY Jansson_INCLUDE_DIR
+)
+
+if (Jansson_FOUND)
+	set(Jansson_LIBRARIES ${Jansson_LIBRARY})
+	set(Jansson_INCLUDE_DIRS ${Jansson_INCLUDE_DIR})
+
+	if (NOT TARGET Jansson::Jansson)
+		add_library(Jansson::Jansson UNKNOWN IMPORTED)
+		set_target_properties(
+			Jansson::Jansson
+			PROPERTIES
+				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+				IMPORTED_LOCATION "${Jansson_LIBRARY}"
+				INTERFACE_INCLUDE_DIRECTORIES "${Jansson_INCLUDE_DIRS}"
+		)
+	endif ()
+endif ()
+
+mark_as_advanced(Jansson_INCLUDE_DIR Jansson_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/FindLibzip.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,42 @@
+# FindLibzip
+# -----------
+#
+# Find Libzip library, this modules defines:
+#
+# Libzip_INCLUDE_DIRS, where to find libzip.h
+# Libzip_LIBRARIES, where to find library
+# Libzip_FOUND, if it is found
+#
+# The following imported targets will be available:
+#
+# Libzip::Libzip, if found.
+#
+
+find_path(Libzip_INCLUDE_DIR NAMES zip.h)
+find_library(Libzip_LIBRARY NAMES libzip zip)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(
+	Libzip
+	FOUND_VAR Libzip_FOUND
+	REQUIRED_VARS Libzip_LIBRARY Libzip_INCLUDE_DIR
+)
+
+if (Libzip_FOUND)
+	set(Libzip_LIBRARIES ${Libzip_LIBRARY})
+	set(Libzip_INCLUDE_DIRS ${Libzip_INCLUDE_DIR})
+
+	if (NOT TARGET Libzip::Libzip)
+		add_library(Libzip::Libzip UNKNOWN IMPORTED)
+		set_target_properties(
+			Libzip::Libzip
+			PROPERTIES
+				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+				IMPORTED_LOCATION "${Libzip_LIBRARY}"
+				INTERFACE_INCLUDE_DIRECTORIES "${Libzip_INCLUDE_DIRS}"
+		)
+	endif ()
+endif ()
+
+mark_as_advanced(Libzip_INCLUDE_DIR Libzip_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/FindNLS.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,31 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+find_program(XGETTEXT xgettext DOC "Path to xgettext utility")
+find_program(MSGFMT msgfmt DOC "Path to msgfmt")
+find_program(MSGMERGE msgmerge DOC "Path to msgmerge")
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(
+	NLS
+	FOUND_VAR NLS_FOUND
+	REQUIRED_VARS XGETTEXT MSGFMT MSGMERGE
+)
+
+mark_as_advanced(XGETTEXT MSGFMT MSGMERGE)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/FindSDL2.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,101 @@
+# FindSDL2
+# --------
+#
+# Find SDL2 library and components, this modules defines:
+#
+#  SDL2_LIBRARY, the name of the library to link against.
+#  SDL2_MAIN_LIBRARY, for SDL2main (if present).
+#  SDL2_LIBRARIES, alias to SDL2_LIBRARY.
+#  SDL2_FOUND, true if found.
+#  SDL2_INCLUDE_DIR, where to find SDL.h.
+#
+# The following imported targets will be defined:
+#
+# SDL2::SDL2
+# SDL2::SDL2main (if present)
+#
+# This module also handle the following official SDL addons:
+#
+# - image
+# - mixer
+# - net
+# - ttf
+#
+# And thus, variables SDL2_<C>_LIBRARY, SDL2_<C>_INCLUDE_DIRS and SDL2::<C>
+# imported targets will be defined if they are found.
+#
+
+include(FindPackageHandleStandardArgs)
+
+# The official include convention is <SDL.h> not <SDL/SDL.h>.
+find_path(
+	SDL2_INCLUDE_DIR
+	NAMES SDL.h
+	PATH_SUFFIXES include/SDL2 include
+)
+
+find_library(SDL2_LIBRARY NAMES SDL2 libSDL2 SDL2d libSDL2d)
+find_library(SDL2_MAIN_LIBRARY NAMES SDL2main libSDL2main SDL2maind libSDL2maind)
+
+# Standard components.
+foreach (c ${SDL2_FIND_COMPONENTS})
+	find_path(
+		SDL2_${c}_INCLUDE_DIR
+		NAMES SDL.h
+		PATH_SUFFIXES include/SDL2 include
+	)
+
+	find_library(
+		SDL2_${c}_LIBRARY
+		NAMES SDL2_${c} libSDL2_${c}
+	)
+
+	if (NOT TARGET SDL2::${c} AND SDL2_${c}_LIBRARY)
+		set(SDL2_${c}_FOUND TRUE)
+		add_library(SDL2::${c} UNKNOWN IMPORTED)
+		set_target_properties(
+			SDL2::${c}
+			PROPERTIES
+				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+				IMPORTED_LOCATION "${SDL2_${c}_LIBRARY}"
+				INTERFACE_INCLUDE_DIRECTORIES "${SDL2_${c}_INCLUDE_DIRS}"
+		)
+	endif ()
+
+	mark_as_advanced(SDL2_${c}_INCLUDE_DIR SDL2_${c}_LIBRARY)
+endforeach ()
+
+find_package_handle_standard_args(
+	SDL2
+	REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR
+	HANDLE_COMPONENTS
+)
+
+if (SDL2_FOUND)
+	set(SDL2_LIBRARIES ${SDL2_LIBRARY})
+	set(SDL2_INCLUDE_DIRS ${SDL2_INCLUDE_DIR})
+
+	if (NOT TARGET SDL2::SDL2)
+		add_library(SDL2::SDL2 UNKNOWN IMPORTED)
+		set_target_properties(
+			SDL2::SDL2
+			PROPERTIES
+				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+				IMPORTED_LOCATION "${SDL2_LIBRARY}"
+				INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
+		)
+	endif ()
+
+	if (NOT TARGET SDL2::main AND SDL2_MAIN_LIBRARY)
+		add_library(SDL2::main UNKNOWN IMPORTED)
+		set_target_properties(
+			SDL2::main
+			PROPERTIES
+				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+				IMPORTED_LOCATION "${SDL2_MAIN_LIBRARY}"
+				INTERFACE_INCLUDE_DIRECTORIES "${SDL2_INCLUDE_DIRS}"
+		)
+	endif ()
+endif ()
+
+mark_as_advanced(SDL2_INCLUDE_DIR SDL2_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/FindSndFile.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,42 @@
+# FindSndFile
+# -----------
+#
+# Find SndFile library, this modules defines:
+#
+# SndFile_INCLUDE_DIRS, where to find sndfile.h
+# SndFile_LIBRARIES, where to find library
+# SndFile_FOUND, if it is found
+#
+# The following imported targets will be available:
+#
+# SndFile::SndFile, if found.
+#
+
+find_path(SndFile_INCLUDE_DIR NAMES sndfile.h)
+find_library(SndFile_LIBRARY NAMES libsndfile sndfile)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(
+	SndFile
+	FOUND_VAR SndFile_FOUND
+	REQUIRED_VARS SndFile_LIBRARY SndFile_INCLUDE_DIR
+)
+
+if (SndFile_FOUND)
+	set(SndFile_LIBRARIES ${SndFile_LIBRARY})
+	set(SndFile_INCLUDE_DIRS ${SndFile_INCLUDE_DIR})
+
+	if (NOT TARGET SndFile::SndFile)
+		add_library(SndFile::SndFile UNKNOWN IMPORTED)
+		set_target_properties(
+			SndFile::SndFile
+			PROPERTIES
+				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+				IMPORTED_LOCATION "${SndFile_LIBRARY}"
+				INTERFACE_INCLUDE_DIRECTORIES "${SndFile_INCLUDE_DIRS}"
+		)
+	endif ()
+endif ()
+
+mark_as_advanced(SndFile_INCLUDE_DIR SndFile_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/FindZSTD.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,50 @@
+# FindZSTD
+# --------
+#
+# Find ZSTD library, this modules defines:
+#
+# ZSTD_INCLUDE_DIRS, where to find zstd.h
+# ZSTD_LIBRARIES, where to find library
+# ZSTD_FOUND, if it is found
+# ZSTD_EXE, path to zstd executable if found
+#
+# The following imported targets will be available:
+#
+# ZSTD::ZSTD, if found.
+# ZSTD::exe, alias to ZSTD_EXE
+#
+
+find_path(ZSTD_INCLUDE_DIR NAMES zstd.h)
+find_library(ZSTD_LIBRARY NAMES libzstd zstd)
+find_program(ZSTD_EXE NAMES zstd)
+
+include(FindPackageHandleStandardArgs)
+
+find_package_handle_standard_args(
+	ZSTD
+	FOUND_VAR ZSTD_FOUND
+	REQUIRED_VARS ZSTD_LIBRARY ZSTD_INCLUDE_DIR
+)
+
+if (ZSTD_FOUND)
+	set(ZSTD_LIBRARIES ${ZSTD_LIBRARY})
+	set(ZSTD_INCLUDE_DIRS ${ZSTD_INCLUDE_DIR})
+
+	if (NOT TARGET ZSTD::ZSTD)
+		add_library(ZSTD::ZSTD UNKNOWN IMPORTED)
+		set_target_properties(
+			ZSTD::ZSTD
+			PROPERTIES
+				IMPORTED_LINK_INTERFACE_LANGUAGES "C"
+				IMPORTED_LOCATION "${ZSTD_LIBRARY}"
+				INTERFACE_INCLUDE_DIRECTORIES "${ZSTD_INCLUDE_DIRS}"
+		)
+	endif ()
+
+	if (ZSTD_EXE AND NOT TARGET ZSTD::exe)
+		add_executable(ZSTD::exe IMPORTED GLOBAL)
+		set_target_properties(ZSTD::exe PROPERTIES IMPORTED_LOCATION "${ZSTD_EXE}")
+	endif ()
+endif ()
+
+mark_as_advanced(ZSTD_INCLUDE_DIR ZSTD_LIBRARY)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/MlkBcc.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,63 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+macro(mlk_bcc)
+	set(options "")
+	set(oneValueArgs OUTPUTS_VAR)
+	set(multiValueArgs ASSETS)
+
+	cmake_parse_arguments(_bcc "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+	if (NOT _bcc_OUTPUTS_VAR)
+		message(FATAL_ERROR "Missing OUTPUTS_VAR")
+	elseif (NOT _bcc_ASSETS)
+		message(FATAL_ERROR "Missing ASSETS")
+	endif ()
+
+	foreach (a ${_bcc_ASSETS})
+		cmake_path(
+			RELATIVE_PATH a
+			BASE_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+			OUTPUT_VARIABLE output
+		)
+		cmake_path(GET output PARENT_PATH outputdir)
+		cmake_path(GET output EXTENSION extension)
+		cmake_path(REPLACE_EXTENSION output .h)
+		cmake_path(REMOVE_EXTENSION output OUTPUT_VARIABLE outputname)
+
+		if (extension MATCHES ".sql")
+			set(args "-0cs")
+		else ()
+			set(args "-cs")
+		endif ()
+
+		set(outputfile ${CMAKE_CURRENT_BINARY_DIR}/${output})
+
+		add_custom_command(
+			OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${output}
+			COMMAND
+				${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${outputdir}
+			COMMAND
+				$<TARGET_FILE:mlk-bcc> ${args} ${a} ${outputname} > ${outputfile}
+			COMMENT "Generating ${output}"
+			DEPENDS $<TARGET_FILE:mlk-bcc> ${a}
+		)
+
+		list(APPEND ${_bcc_OUTPUTS_VAR} ${CMAKE_CURRENT_BINARY_DIR}/${output})
+	endforeach ()
+endmacro()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/MlkExecutable.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,53 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+function(mlk_executable)
+	set(options "INSTALL")
+	set(oneValueArgs "NAME;FOLDER")
+	set(multiValueArgs "ASSETS;SOURCES;LIBRARIES;INCLUDES;FLAGS")
+
+	cmake_parse_arguments(EXE "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+	if (NOT EXE_NAME)
+		message(FATAL_ERROR "Missing NAME")
+	endif ()
+
+	if (EXE_ASSETS)
+		mlk_bcc(ASSETS ${EXE_ASSETS} OUTPUTS_VAR HEADERS)
+		source_group(build/assets FILES ${HEADERS})
+	endif ()
+
+	add_executable(${EXE_NAME} ${EXE_SOURCES} ${HEADERS})
+	target_include_directories(${EXE_NAME} PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
+
+	if (EXE_FOLDER)
+		set_target_properties(${EXE_NAME} PROPERTIES FOLDER ${EXE_FOLDER})
+	endif ()
+
+	if (EXE_LIBRARIES)
+		target_link_libraries(${EXE_NAME} ${EXE_LIBRARIES})
+	endif ()
+
+	if (EXE_INCLUDES)
+		target_include_directories(${EXE_NAME} ${EXE_INCLUDES})
+	endif ()
+
+	if (EXE_INSTALL)
+		install(TARGETS ${EXE_NAME} DESTINATION ${CMAKE_INSTALL_BINDIR})
+	endif ()
+endfunction()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/MlkLibrary.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,71 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+include(${CMAKE_CURRENT_LIST_DIR}/MlkBcc.cmake)
+include(${CMAKE_CURRENT_LIST_DIR}/MlkNls.cmake)
+
+function(mlk_library)
+	set(options "")
+	set(oneValueArgs "NAME;FOLDER;TYPE")
+	set(multiValueArgs "SOURCES;ASSETS;LANGS;LIBRARIES;INCLUDES;FLAGS;OPTIONS")
+
+	cmake_parse_arguments(LIB "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+	if (NOT LIB_NAME)
+		message(FATAL_ERROR "Missing NAME")
+	endif ()
+
+	if (LIB_ASSETS)
+		mlk_bcc(ASSETS ${LIB_ASSETS} OUTPUTS_VAR HEADERS)
+		source_group(build/assets FILES ${HEADERS})
+	endif ()
+
+	if (LIB_LANGS AND MLK_WITH_NLS)
+		mlk_nls(
+			NAME ${LIB_NAME}
+			LANGS ${LIB_LANGS}
+			SOURCES ${LIB_SOURCES}
+			OUTPUTS_VAR MO
+		)
+		source_group(build/nls FILES ${MO})
+	endif ()
+
+	add_library(${LIB_NAME} ${LIB_TYPE} ${LIB_SOURCES} ${HEADERS} ${MO})
+
+	if (LIB_FOLDER)
+		set_target_properties(${LIB_NAME} PROPERTIES FOLDER extern)
+	endif ()
+
+	if (LIB_FLAGS)
+		target_compile_definitions(${LIB_NAME} ${LIB_FLAGS})
+	endif ()
+
+	if (LIB_OPTIONS)
+		target_compile_options(${LIB_NAME} ${LIB_OPTIONS})
+	endif ()
+
+	if (LIB_LIBRARIES)
+		target_link_libraries(${LIB_NAME} ${LIB_LIBRARIES})
+	endif ()
+
+	if (LIB_INCLUDES)
+		target_include_directories(${LIB_NAME} ${LIB_INCLUDES})
+	endif ()
+
+	set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
+endfunction()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/MlkMap.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,35 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+function(mlk_map input output)
+	if (MLK_WITH_ZSTD)
+		set(cmd
+			COMMAND $<TARGET_FILE:mlk-map> < ${input} > ${output}.zst
+			COMMAND ZSTD::exe -17 -fq --rm ${output}.zst -o ${output}
+		)
+	else ()
+		set(cmd COMMAND $<TARGET_FILE:mlk-map> < ${input} > ${output})
+	endif ()
+
+	add_custom_command(
+		OUTPUT ${output}
+		COMMAND ${cmd}
+		DEPENDS $<TARGET_FILE:mlk-map>
+		COMMENT "Generating ${output}"
+	)
+endfunction()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/MlkNls.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,70 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+macro(mlk_nls)
+	set(options "")
+	set(oneValueArgs "NAME")
+	set(multiValueArgs "LANGS;SOURCES;OUTPUTS_VAR")
+
+	cmake_parse_arguments(_nls "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
+
+	if (NOT _nls_NAME)
+		message(FATAL_ERROR "Missing NAME")
+	elseif (NOT _nls_OUTPUTS_VAR)
+		message(FATAL_ERROR "Missing OUTPUTS_VAR")
+	elseif (NOT _nls_LANGS)
+		message(FATAL_ERROR "Missing LANGS")
+	elseif (NOT _nls_SOURCES)
+		message(FATAL_ERROR "Missing SOURCES")
+	endif ()
+
+	set(_nls_po_cmds)
+
+	foreach (l ${_nls_LANGS})
+		cmake_path(GET l FILENAME name)
+		cmake_path(REMOVE_EXTENSION name)
+
+		add_custom_command(
+			OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}.mo
+			COMMAND ${MSGFMT} -o ${CMAKE_CURRENT_BINARY_DIR}/${name}.mo ${l}
+			COMMENT "Generating NLS translation ${name}.mo"
+		)
+
+		list(APPEND ${_nls_OUTPUTS_VAR} ${CMAKE_CURRENT_BINARY_DIR}/${name}.mo)
+		install(
+			FILES ${CMAKE_CURRENT_BINARY_DIR}/${name}.mo
+			DESTINATION ${CMAKE_INSTALL_LOCALEDIR}/${name}/LC_MESSAGES
+			RENAME ${_nls_NAME}.mo
+		)
+
+		# Commands to update .po files.
+		list(
+			APPEND _nls_po_cmds
+			COMMAND ${MSGMERGE} --backup=off -qU ${l} ${CMAKE_CURRENT_SOURCE_DIR}/nls/${_nls_NAME}.pot
+		)
+	endforeach ()
+
+	add_custom_target(
+		po-${_nls_NAME}
+		COMMAND
+			${XGETTEXT} -cj -k_ -kN_ -LC -s -o ${CMAKE_CURRENT_SOURCE_DIR}/nls/${_nls_NAME}.pot ${_nls_SOURCES}
+			${_nls_po_cmds}
+		COMMENT "Updating in-source .pot and .po files"
+	)
+	set_target_properties(po-${_nls_NAME} PROPERTIES FOLDER "nls")
+endmacro()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cmake/MlkTileset.cmake	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,35 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+function(mlk_tileset input output)
+	if (MLK_WITH_ZSTD)
+		set(cmd
+			COMMAND $<TARGET_FILE:mlk-tileset> < ${input} > ${output}.zst
+			COMMAND ZSTD::exe -17 -fq --rm ${output}.zst -o ${output}
+		)
+	else ()
+		set(cmd COMMAND $<TARGET_FILE:mlk-tileset> < ${input} > ${output})
+	endif ()
+
+	add_custom_command(
+		OUTPUT ${output}
+		COMMAND ${cmd}
+		DEPENDS $<TARGET_FILE:mlk-tileset>
+		COMMENT "Generating ${output}"
+	)
+endfunction()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,89 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(doc)
+
+set(
+	SOURCES
+	${doc_SOURCE_DIR}/CMakeLists.txt
+	${doc_SOURCE_DIR}/mkdocs.yml
+	${doc_SOURCE_DIR}/docs
+	${doc_SOURCE_DIR}/docs/tools
+	${doc_SOURCE_DIR}/docs/tools/map.md
+	${doc_SOURCE_DIR}/docs/tools/bcc.md
+	${doc_SOURCE_DIR}/docs/tools/tileset.md
+	${doc_SOURCE_DIR}/docs/specs
+	${doc_SOURCE_DIR}/docs/specs/map.md
+	${doc_SOURCE_DIR}/docs/specs/tileset.md
+	${doc_SOURCE_DIR}/docs/install.md
+	${doc_SOURCE_DIR}/docs/index.md
+	${doc_SOURCE_DIR}/docs/dev
+	${doc_SOURCE_DIR}/docs/dev/faq.md
+	${doc_SOURCE_DIR}/docs/dev/error.md
+	${doc_SOURCE_DIR}/docs/dev/ownership.md
+	${doc_SOURCE_DIR}/docs/dev/api
+	${doc_SOURCE_DIR}/docs/dev/api/core
+	${doc_SOURCE_DIR}/docs/dev/api/core/texture.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/mouse.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/inhibit.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/sprite.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/animation.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/music.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/image.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/zfile.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/alloc.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/sys.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/state.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/maths.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/script.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/error.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/color.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/window.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/sound.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/save.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/translate.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/event.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/trace.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/core.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/action.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/font.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/panic.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/key.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/painter.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/game.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/util.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/clock.md
+	${doc_SOURCE_DIR}/docs/dev/api/core/drawable.md
+	${doc_SOURCE_DIR}/docs/dev/howto
+	${doc_SOURCE_DIR}/docs/dev/howto/01-init.md
+	${doc_SOURCE_DIR}/docs/about.md
+)
+
+add_custom_target(
+	doc
+	SOURCES ${SOURCES}
+)
+
+add_custom_target(
+	doc-serve
+	SOURCES ${SOURCES}
+	COMMAND mkdocs serve
+	WORKING_DIRECTORY ${doc_SOURCE_DIR}
+)
+
+source_group(TREE ${doc_SOURCE_DIR} FILES ${SOURCES})
--- a/doc/mkdocs.yml	Sat Feb 18 12:15:14 2023 +0100
+++ b/doc/mkdocs.yml	Sat Feb 18 12:43:05 2023 +0100
@@ -74,3 +74,6 @@
         - util: dev/api/core/util.md
         - window: dev/api/core/window.md
         - zfile: dev/api/core/zfile.md
+    - Javascript API Reference:
+      - Core:
+        - animation: dev/jsapi/core/animation.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,42 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(examples)
+
+set(
+	DIRS
+	example-action
+	example-animation
+	example-audio
+	example-battle
+	example-cursor
+	example-debug
+	example-drawable
+	example-font
+	example-gridmenu
+	example-label
+	example-message
+	example-notify
+	example-sprite
+	example-trace
+	example-ui
+)
+
+foreach (d ${DIRS})
+	add_subdirectory(${d})
+endforeach ()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-action/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,40 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-action)
+
+set(
+	SOURCES
+	${example-action_SOURCE_DIR}/main.c
+)
+
+set(
+	ASSETS
+	${example-action_SOURCE_DIR}/assets/sprites/chest.png
+	${example-action_SOURCE_DIR}/assets/sprites/people.png
+)
+
+mlk_executable(
+	NAME example-action
+	FOLDER examples
+	LIBRARIES libmlk-rpg
+	SOURCES ${ASSETS} ${SOURCES}
+	ASSETS ${ASSETS}
+)
+
+source_group(TREE ${example-action_SOURCE_DIR} FILES ${ASSETS} ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-animation/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,39 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-animation)
+
+set(
+	SOURCES
+	${example-animation_SOURCE_DIR}/main.c
+)
+
+set(
+	ASSETS
+	${example-animation_SOURCE_DIR}/assets/sprites/numbers.png
+)
+
+mlk_executable(
+	NAME example-animation
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${ASSETS} ${SOURCES}
+	ASSETS ${ASSETS}
+)
+
+source_group(TREE ${example-animation_SOURCE_DIR} FILES ${ASSETS} ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-audio/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,40 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-audio)
+
+set(
+	SOURCES
+	${example-audio_SOURCE_DIR}/main.c
+)
+
+set(
+	ASSETS
+	${example-audio_SOURCE_DIR}/assets/music/vabsounds-romance.ogg
+	${example-audio_SOURCE_DIR}/assets/sounds/fire.wav
+)
+
+mlk_executable(
+	NAME example-audio
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${ASSETS} ${SOURCES}
+	ASSETS ${ASSETS}
+)
+
+source_group(TREE ${example-audio_SOURCE_DIR} FILES ${ASSETS} ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-battle/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,52 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-battle)
+
+set(
+	SOURCES
+	${example-battle_SOURCE_DIR}/character-john.c
+	${example-battle_SOURCE_DIR}/character-john.h
+	${example-battle_SOURCE_DIR}/main.c
+	${example-battle_SOURCE_DIR}/registry.c
+	${example-battle_SOURCE_DIR}/registry.h
+	${example-battle_SOURCE_DIR}/spell-fire.c
+	${example-battle_SOURCE_DIR}/spell-fire.h
+)
+
+set(
+	ASSETS
+	${example-battle_SOURCE_DIR}/assets/images/battle-background.png
+	${example-battle_SOURCE_DIR}/assets/images/black-cat.png
+	${example-battle_SOURCE_DIR}/assets/images/haunted-wood.png
+	${example-battle_SOURCE_DIR}/assets/sounds/fire.wav
+	${example-battle_SOURCE_DIR}/assets/sprites/explosion.png
+	${example-battle_SOURCE_DIR}/assets/sprites/john-sword.png
+	${example-battle_SOURCE_DIR}/assets/sprites/john-walk.png
+	${example-battle_SOURCE_DIR}/assets/sprites/ui-cursor.png
+)
+
+mlk_executable(
+	NAME example-battle
+	FOLDER examples
+	LIBRARIES libmlk-rpg
+	SOURCES ${ASSETS} ${SOURCES}
+	ASSETS ${ASSETS}
+)
+
+source_group(TREE ${example-battle_SOURCE_DIR} FILES ${ASSETS} ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-cursor/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,33 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-cursor)
+
+set(
+	SOURCES
+	${example-cursor_SOURCE_DIR}/main.c
+)
+
+mlk_executable(
+	NAME example-cursor
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-cursor_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-debug/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,33 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-debug)
+
+set(
+	SOURCES
+	${example-debug_SOURCE_DIR}/main.c
+)
+
+mlk_executable(
+	NAME example-debug
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-debug_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-drawable/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,39 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-drawable)
+
+set(
+	SOURCES
+	${example-drawable_SOURCE_DIR}/main.c
+)
+
+set(
+	ASSETS
+	${example-drawable_SOURCE_DIR}/assets/sprites/explosion.png
+)
+
+mlk_executable(
+	NAME example-drawable
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${ASSETS} ${SOURCES}
+	ASSETS ${ASSETS}
+)
+
+source_group(TREE ${example-drawable_SOURCE_DIR} FILES ${ASSETS} ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-font/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,33 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-font)
+
+set(
+	SOURCES
+	${example-font_SOURCE_DIR}/main.c
+)
+
+mlk_executable(
+	NAME example-font
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-font_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-gridmenu/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,33 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-gridmenu)
+
+set(
+	SOURCES
+	${example-gridmenu_SOURCE_DIR}/main.c
+)
+
+mlk_executable(
+	NAME example-gridmenu
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-gridmenu_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-label/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,33 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-label)
+
+set(
+	SOURCES
+	${example-label_SOURCE_DIR}/main.c
+)
+
+mlk_executable(
+	NAME example-label
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-label_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-message/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,33 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-message)
+
+set(
+	SOURCES
+	${example-message_SOURCE_DIR}/main.c
+)
+
+mlk_executable(
+	NAME example-message
+	FOLDER examples
+	LIBRARIES libmlk-rpg
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-message_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-notify/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,39 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-notify)
+
+set(
+	SOURCES
+	${example-notify_SOURCE_DIR}/main.c
+)
+
+set(
+	ASSETS
+	${example-notify_SOURCE_DIR}/assets/images/sword.png
+)
+
+mlk_executable(
+	NAME example-notify
+	FOLDER examples
+	LIBRARIES libmlk-rpg
+	ASSETS ${ASSETS}
+	SOURCES ${ASSETS} ${SOURCES}
+)
+
+source_group(TREE ${example-notify_SOURCE_DIR} FILES ${ASSETS} ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-sprite/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,39 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-sprite)
+
+set(
+	SOURCES
+	${example-sprite_SOURCE_DIR}/main.c
+)
+
+set(
+	ASSETS
+	${example-sprite_SOURCE_DIR}/assets/sprites/people.png
+)
+
+mlk_executable(
+	NAME example-sprite
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${ASSETS} ${SOURCES}
+	ASSETS ${ASSETS}
+)
+
+source_group(TREE ${example-sprite_SOURCE_DIR} FILES ${ASSETS} ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-trace/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,34 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-trace)
+
+set(
+	SOURCES
+	${example-trace_SOURCE_DIR}/main.c
+	${example-trace_SOURCE_DIR}/trace_hud.c
+)
+
+mlk_executable(
+	NAME example-trace
+	FOLDER examples
+	LIBRARIES libmlk-rpg
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-trace_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/example-ui/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,33 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(example-ui)
+
+set(
+	SOURCES
+	${example-ui_SOURCE_DIR}/main.c
+)
+
+mlk_executable(
+	NAME example-ui
+	FOLDER examples
+	LIBRARIES libmlk-ui
+	SOURCES ${SOURCES}
+)
+
+source_group(TREE ${example-ui_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extern/libdt/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,29 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(libmlk-dt)
+
+add_library(libmlk-dt INTERFACE ${libmlk-dt_SOURCE_DIR}/dt.h)
+target_include_directories(
+	libmlk-dt
+	INTERFACE
+		 $<BUILD_INTERFACE:${libmlk-dt_SOURCE_DIR}>
+)
+set_target_properties(libmlk-dt PROPERTIES FOLDER extern)
+
+source_group("" FILES ${libmlk-dt_SOURCE_DIR}/dt.h)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extern/libduktape/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,41 @@
+#
+# CMakeLists.txt -- CMake build system for duktape
+#
+# Copyright (c) 2016-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+cmake_minimum_required(VERSION 3.0)
+project(libmlk-duktape)
+
+add_library(
+	libmlk-duktape
+	STATIC
+	${libmlk-duktape_SOURCE_DIR}/duk_config.h
+	${libmlk-duktape_SOURCE_DIR}/duk_module_duktape.c
+	${libmlk-duktape_SOURCE_DIR}/duk_module_duktape.h
+	${libmlk-duktape_SOURCE_DIR}/duktape.c
+	${libmlk-duktape_SOURCE_DIR}/duktape.h
+)
+target_include_directories(
+	libmlk-duktape
+	PUBLIC
+		$<BUILD_INTERFACE:${libmlk-duktape_SOURCE_DIR}>
+)
+
+set_target_properties(libmlk-duktape PROPERTIES PREFIX "")
+
+if (M_LIBRARY)
+	target_link_libraries(libmlk-duktape ${M_LIBRARY})
+endif ()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extern/libsqlite/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,48 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(libmlk-sqlite)
+
+set(
+	SOURCES
+	${libmlk-sqlite_SOURCE_DIR}/sqlite3.c
+	${libmlk-sqlite_SOURCE_DIR}/sqlite3.h
+)
+
+if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
+	list(APPEND OPTIONS -Wno-unused-parameter)
+endif ()
+
+mlk_library(
+	NAME libmlk-sqlite
+	SOURCES ${SOURCES}
+	FOLDER extern
+	OPTIONS PRIVATE ${OPTIONS}
+	FLAGS
+		PRIVATE
+			SQLITE_THREADSAFE=0
+			SQLITE_DEFAULT_MEMSTATUS=0
+			SQLITE_OMIT_DECLTYPE
+			SQLITE_OMIT_DEPRECATED
+			SQLITE_OMIT_LOAD_EXTENSION
+			SQLITE_DEFAULT_FOREIGN_KEYS=1
+	INCLUDES
+		PUBLIC $<BUILD_INTERFACE:${libmlk-sqlite_SOURCE_DIR}>
+)
+
+source_group(TREE ${libmlk-sqlite_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-core/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,128 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(libmlk-core)
+
+set(
+	SOURCES
+	${libmlk-core_SOURCE_DIR}/mlk/core/action.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/action.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/action-stack.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/action-stack.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/alloc.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/alloc.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/animation.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/animation.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/clock.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/clock.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/color.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/core.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/core.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/drawable.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/drawable.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/drawable-stack.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/drawable-stack.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/error.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/error.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/event.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/event.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/font.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/font.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/game.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/game.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/image.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/image.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/inhibit.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/key.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/maths.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/maths.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/mouse.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/music.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/music.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/painter.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/painter.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/panic.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/panic.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/script.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/script.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/sound.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/sound.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/sprite.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/sprite.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/state.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/state.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/sys.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/sys.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/sys_p.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/texture.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/texture.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/texture_p.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/trace.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/trace.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/util.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/util.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/window.c
+	${libmlk-core_SOURCE_DIR}/mlk/core/window.h
+	${libmlk-core_SOURCE_DIR}/mlk/core/window_p.h
+)
+
+set(
+	NLS
+	${libmlk-core_SOURCE_DIR}/nls/fr.po
+)
+
+if (MLK_WITH_NLS)
+	list(APPEND LIBRARIES ${Intl_LIBRARIES})
+endif ()
+
+if (MLK_WITH_ZSTD)
+	list(APPEND LIBRARIES ZSTD::ZSTD)
+endif ()
+
+if (MLK_WITH_ZIP)
+	list(APPEND LIBRARIES Libzip::Libzip)
+endif ()
+
+if (CMAKE_SYSTEM_NAME MATCHES "Windows")
+	list(APPEND LIBRARIES shlwapi)
+endif ()
+
+if (M_LIBRARY)
+	list(APPEND LIBRARIES ${M_LIBRARY})
+endif ()
+
+mlk_library(
+	NAME libmlk-core
+	SOURCES ${SOURCES} ${NLS}
+	LANGS ${NLS}
+	LIBRARIES
+		PUBLIC
+			${LIBRARIES}
+			${OPENAL_LIBRARY}
+			SndFile::SndFile
+			SDL2::SDL2
+			SDL2::image
+			SDL2::ttf
+			libmlk-util
+	INCLUDES
+		PUBLIC
+			${OPENAL_INCLUDE_DIR}
+			$<BUILD_INTERFACE:${libmlk-core_SOURCE_DIR}>
+)
+
+source_group(TREE ${libmlk-core_SOURCE_DIR} FILES ${SOURCES} ${NLS})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-core/nls/fr.po	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,47 @@
+#
+# fr.po -- French translations for libmlk-core
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-09-21 22:44+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: /Users/markand/Dev/molko/libmlk-core/core/panic.c:30
+#, c-format
+msgid "abort: %s\n"
+msgstr "fatal: %s\n"
+
+#: /Users/markand/Dev/molko/libmlk-core/core/panic.c:76
+#, c-format
+msgid "abort: panic handler returned\n"
+msgstr "fatal: la fonction de panique n'aurait pas du continuer\n"
+
+#~ msgid "database not initialized correctly"
+#~ msgstr "database non initialisée"
+
+#, c-format
+#~ msgid "property '%s' was not found"
+#~ msgstr "propriété '%s' non trouvée"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-core/nls/libmlk-core.pot	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,28 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-09-21 22:47+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: /Users/markand/Dev/molko/libmlk-core/core/panic.c:30
+#, c-format
+msgid "abort: %s\n"
+msgstr ""
+
+#: /Users/markand/Dev/molko/libmlk-core/core/panic.c:76
+#, c-format
+msgid "abort: panic handler returned\n"
+msgstr ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-rpg/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,137 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(libmlk-rpg)
+
+set(
+	SOURCES
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-bar-default.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-bar-default.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-bar.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-bar.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-attacking.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-attacking.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-blinking.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-blinking.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-moving.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-moving.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-normal.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state-normal.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity-state.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-entity.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-indicator.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-indicator.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-message.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-message.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-ai.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-ai.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-attacking.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-attacking.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-check.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-check.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-closing.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-closing.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-item.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-item.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-lost.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-lost.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-menu.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-menu.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-opening.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-opening.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-rendering.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-rendering.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-selection.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-selection.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-victory.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state-victory.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle-state.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/battle.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/character.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/character.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/equipment.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/equipment.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/inventory.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/inventory.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/item.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/item.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/map-file.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/map-file.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/map.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/map.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/message.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/message.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/property.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/property.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/quest.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/quest.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/rpg.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/rpg.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/save.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/save.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/selection.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/selection.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/spell.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/spell.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/team.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/team.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/tileset-file.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/tileset-file.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/tileset.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/tileset.h
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/walksprite.c
+	${libmlk-rpg_SOURCE_DIR}/mlk/rpg/walksprite.h
+)
+
+set(
+	ASSETS
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/character-load.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/character-save.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/init.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/property-load.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/property-remove.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/property-save.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/quest-remove.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/quest-save.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/quest-step-load.sql
+	${libmlk-rpg_SOURCE_DIR}/assets/sql/quest-step-save.sql
+)
+
+set(
+	NLS
+	${libmlk-rpg_SOURCE_DIR}/nls/fr.po
+)
+
+mlk_library(
+	NAME libmlk-rpg
+	SOURCES ${SOURCES} ${ASSETS} ${NLS}
+	LANGS ${NLS}
+	ASSETS ${ASSETS}
+	LIBRARIES
+		libmlk-ui
+		libmlk-sqlite
+	INCLUDES
+		PRIVATE $<BUILD_INTERFACE:${libmlk-rpg_BINARY_DIR}>
+		PUBLIC $<BUILD_INTERFACE:${libmlk-rpg_SOURCE_DIR}>
+)
+
+source_group(TREE ${libmlk-rpg_SOURCE_DIR} FILES ${SOURCES} ${ASSETS} ${NLS})
--- a/libmlk-rpg/mlk/rpg/character.c	Sat Feb 18 12:15:14 2023 +0100
+++ b/libmlk-rpg/mlk/rpg/character.c	Sat Feb 18 12:43:05 2023 +0100
@@ -76,7 +76,7 @@
 	assert(ch);
 	assert(save_ok(s));
 
-	return save_exec(s, (const char *)assets_character_save, "s iii i iiiiii",
+	return save_exec(s, (const char *)assets_sql_character_save, "s iii i iiiiii",
 	    ch->name,
 	    ch->hp,
 	    ch->mp,
@@ -100,7 +100,7 @@
 	struct save_stmt stmt;
 	enum save_stmt_errno ret;
 
-	if (save_stmt_init(&stmt, s, (const char *)assets_character_load, "s", ch->name) < 0)
+	if (save_stmt_init(&stmt, s, (const char *)assets_sql_character_load, "s", ch->name) < 0)
 		return -1;
 
 	ret = save_stmt_next(&stmt, "iii i iiiiii",
--- a/libmlk-rpg/mlk/rpg/property.c	Sat Feb 18 12:15:14 2023 +0100
+++ b/libmlk-rpg/mlk/rpg/property.c	Sat Feb 18 12:43:05 2023 +0100
@@ -31,7 +31,7 @@
 	assert(p);
 	assert(save_ok(s));
 
-	return save_exec(s, (const char *)assets_property_save, "ss", p->key, p->value);
+	return save_exec(s, (const char *)assets_sql_property_save, "ss", p->key, p->value);
 }
 
 int
@@ -43,7 +43,7 @@
 	struct save_stmt stmt;
 	enum save_stmt_errno ret;
 
-	if (save_stmt_init(&stmt, s, (const char *)assets_property_load, "s", p->key) < 0)
+	if (save_stmt_init(&stmt, s, (const char *)assets_sql_property_load, "s", p->key) < 0)
 		return -1;
 
 	ret = save_stmt_next(&stmt, "s", p->value, sizeof (p->value)) == SAVE_STMT_ROW;
@@ -58,6 +58,6 @@
 	assert(p);
 	assert(save_ok(s));
 
-	return save_exec(s, (const char *)assets_property_remove, "s", p->key);
+	return save_exec(s, (const char *)assets_sql_property_remove, "s", p->key);
 }
 
--- a/libmlk-rpg/mlk/rpg/quest.c	Sat Feb 18 12:15:14 2023 +0100
+++ b/libmlk-rpg/mlk/rpg/quest.c	Sat Feb 18 12:43:05 2023 +0100
@@ -37,7 +37,7 @@
 	if (save_tx_begin(s) < 0)
 		return -1;
 
-	if (save_exec(s, (const char *)assets_quest_save, "s", q->name) < 0) {
+	if (save_exec(s, (const char *)assets_sql_quest_save, "s", q->name) < 0) {
 		save_tx_rollback(s);
 		return -1;
 	}
@@ -45,7 +45,7 @@
 	for (size_t i = 0; i < q->stepsz; ++i) {
 		step = &q->steps[i];
 
-		if (save_exec(s, (const char *)assets_quest_step_save, "ssi", q->name, step->name, step->percent) < 0) {
+		if (save_exec(s, (const char *)assets_sql_quest_step_save, "ssi", q->name, step->name, step->percent) < 0) {
 			save_tx_rollback(s);
 			return -1;
 		}
@@ -68,7 +68,7 @@
 	for (size_t i = 0; i < q->stepsz; ++i) {
 		step = &q->steps[i];
 
-		if (save_stmt_init(&stmt, s, (const char *)assets_quest_step_load, "s", step->name))
+		if (save_stmt_init(&stmt, s, (const char *)assets_sql_quest_step_load, "s", step->name))
 			return -1;
 
 		if (save_stmt_next(&stmt, "i", &step->percent) < 0) {
--- a/libmlk-rpg/mlk/rpg/save.c	Sat Feb 18 12:15:14 2023 +0100
+++ b/libmlk-rpg/mlk/rpg/save.c	Sat Feb 18 12:43:05 2023 +0100
@@ -183,7 +183,7 @@
 	if (sqlite3_open_v2(path, (sqlite3**)&db->handle, flags, NULL) != SQLITE_OK)
 		goto sqlite3_err;
 
-	if (mode == SAVE_MODE_WRITE && execu(db, assets_init) < 0)
+	if (mode == SAVE_MODE_WRITE && execu(db, assets_sql_init) < 0)
 		goto sqlite3_err;
 
 	return verify(db);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-rpg/nls/fr.po	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,155 @@
+#
+# fr.po -- French translations for libmlk-rpg
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-06-28 21:06+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libmlk-rpg/rpg/battle-bar.c:143
+msgid "Attack"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-bar.c:150
+msgid "Magic"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-bar.c:157
+msgid "Objects"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-bar.c:164
+msgid "Special"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-state-victory.c:86
+msgid "Victory!"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-state-lost.c:85
+msgid "You have been defeated..."
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:241
+msgid "could not parse image"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:149
+msgid "could not parse tileset"
+msgstr ""
+
+#: libmlk-rpg/rpg/save.c:78
+msgid "database not initialized correctly"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:91
+#, c-format
+msgid "ignoring action %d,%d,%u,%u,%d,%s"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:60
+#, c-format
+msgid "invalid layer type: %s"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:194
+msgid "invalid origin"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:277
+msgid "message has null dimensions"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:140
+#, c-format
+msgid "message height too small: %u < %u"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:171
+msgid "message is automatic but has zero timeout"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:138
+#, c-format
+msgid "message width too small: %u < %u"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:255
+msgid "missing background layer"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:257
+msgid "missing foreground layer"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:133
+msgid "missing layer type definition"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:129
+msgid "missing map dimensions before layer"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:239
+msgid "missing tile dimensions before image"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:259
+msgid "missing tileset"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:298
+msgid "missing tileset image"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:248
+msgid "missing title"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:176
+msgid "null map columns"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:185
+msgid "null map rows"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:165
+msgid "null map title"
+msgstr ""
+
+#: libmlk-rpg/rpg/save.c:263
+#, c-format
+msgid "property '%s' was not found"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:142
+msgid "tileheight is null"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:133
+msgid "tilewidth is null"
+msgstr ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-rpg/nls/libmlk-rpg.pot	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,143 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-06-28 21:06+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libmlk-rpg/rpg/battle-bar.c:143
+msgid "Attack"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-bar.c:150
+msgid "Magic"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-bar.c:157
+msgid "Objects"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-bar.c:164
+msgid "Special"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-state-victory.c:86
+msgid "Victory!"
+msgstr ""
+
+#: libmlk-rpg/rpg/battle-state-lost.c:85
+msgid "You have been defeated..."
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:241
+msgid "could not parse image"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:149
+msgid "could not parse tileset"
+msgstr ""
+
+#: libmlk-rpg/rpg/save.c:78
+msgid "database not initialized correctly"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:91
+#, c-format
+msgid "ignoring action %d,%d,%u,%u,%d,%s"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:60
+#, c-format
+msgid "invalid layer type: %s"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:194
+msgid "invalid origin"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:277
+msgid "message has null dimensions"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:140
+#, c-format
+msgid "message height too small: %u < %u"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:171
+msgid "message is automatic but has zero timeout"
+msgstr ""
+
+#: libmlk-rpg/rpg/message.c:138
+#, c-format
+msgid "message width too small: %u < %u"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:255
+msgid "missing background layer"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:257
+msgid "missing foreground layer"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:133
+msgid "missing layer type definition"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:129
+msgid "missing map dimensions before layer"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:239
+msgid "missing tile dimensions before image"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:259
+msgid "missing tileset"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:298
+msgid "missing tileset image"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:248
+msgid "missing title"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:176
+msgid "null map columns"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:185
+msgid "null map rows"
+msgstr ""
+
+#: libmlk-rpg/rpg/map-file.c:165
+msgid "null map title"
+msgstr ""
+
+#: libmlk-rpg/rpg/save.c:263
+#, c-format
+msgid "property '%s' was not found"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:142
+msgid "tileheight is null"
+msgstr ""
+
+#: libmlk-rpg/rpg/tileset-file.c:133
+msgid "tilewidth is null"
+msgstr ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-ui/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,68 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(libmlk-ui)
+
+set(
+	SOURCES
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/align.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/align.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/button.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/button.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/checkbox.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/checkbox.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/debug.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/debug.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/frame.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/frame.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/gridmenu.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/gridmenu.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/label.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/label.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/notify.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/notify.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/theme.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/theme.h
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/ui.c
+	${libmlk-ui_SOURCE_DIR}/mlk/ui/ui.h
+)
+
+set(
+	ASSETS
+	${libmlk-ui_SOURCE_DIR}/assets/fonts/opensans-light.ttf
+	${libmlk-ui_SOURCE_DIR}/assets/fonts/opensans-medium.ttf
+	${libmlk-ui_SOURCE_DIR}/assets/fonts/opensans-regular.ttf
+)
+
+set(
+	NLS
+	${libmlk-ui_SOURCE_DIR}/nls/fr.po
+)
+
+mlk_library(
+	NAME libmlk-ui
+	SOURCES ${SOURCES} ${ASSETS} ${NLS}
+	LANGS ${NLS}
+	ASSETS ${ASSETS}
+	LIBRARIES libmlk-core
+	INCLUDES
+		PRIVATE $<BUILD_INTERFACE:${libmlk-ui_BINARY_DIR}>
+		PUBLIC $<BUILD_INTERFACE:${libmlk-ui_SOURCE_DIR}>
+)
+
+source_group(TREE ${libmlk-ui_SOURCE_DIR} FILES ${SOURCES} ${ASSETS} ${NLS})
--- a/libmlk-ui/mlk/ui/theme.c	Sat Feb 18 12:15:14 2023 +0100
+++ b/libmlk-ui/mlk/ui/theme.c	Sat Feb 18 12:43:05 2023 +0100
@@ -66,9 +66,9 @@
 	struct font **dest;
 	struct font font;
 } default_fonts[] = {
-	FONT(assets_opensans_light, 12, THEME_FONT_DEBUG),
-	FONT(assets_opensans_regular, 14, THEME_FONT_INTERFACE),
-	FONT(assets_opensans_medium, 14, THEME_FONT_IMPORTANT)
+	FONT(assets_fonts_opensans_light, 12, THEME_FONT_DEBUG),
+	FONT(assets_fonts_opensans_regular, 14, THEME_FONT_INTERFACE),
+	FONT(assets_fonts_opensans_medium, 14, THEME_FONT_IMPORTANT)
 };
 
 int
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-ui/nls/fr.po	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,50 @@
+#
+# fr.po -- French translations for libmlk-ui
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-06-28 21:04+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libmlk-ui/ui/button.c:75
+#, c-format
+msgid "button height is too small for text: %u < %u"
+msgstr ""
+
+#: libmlk-ui/ui/button.c:73
+#, c-format
+msgid "button width is too small for text: %u < %u"
+msgstr ""
+
+#: libmlk-ui/ui/gridmenu.c:86
+#, c-format
+msgid "gridmenu height is too small: %u < %u"
+msgstr ""
+
+#: libmlk-ui/ui/gridmenu.c:78
+#, c-format
+msgid "gridmenu width is too small: %u < %u"
+msgstr ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-ui/nls/libmlk-ui.pot	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,38 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2021-06-28 21:06+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: libmlk-ui/ui/button.c:75
+#, c-format
+msgid "button height is too small for text: %u < %u"
+msgstr ""
+
+#: libmlk-ui/ui/button.c:73
+#, c-format
+msgid "button width is too small for text: %u < %u"
+msgstr ""
+
+#: libmlk-ui/ui/gridmenu.c:86
+#, c-format
+msgid "gridmenu height is too small: %u < %u"
+msgstr ""
+
+#: libmlk-ui/ui/gridmenu.c:78
+#, c-format
+msgid "gridmenu width is too small: %u < %u"
+msgstr ""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libmlk-util/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,43 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(libmlk-util)
+
+set(
+	SOURCES
+	${libmlk-util_SOURCE_DIR}/mlk/util/fmemopen.c
+	${libmlk-util_SOURCE_DIR}/mlk/util/openbsd/basename.c
+	${libmlk-util_SOURCE_DIR}/mlk/util/openbsd/dirname.c
+	${libmlk-util_SOURCE_DIR}/mlk/util/openbsd/getopt.c
+	${libmlk-util_SOURCE_DIR}/mlk/util/openbsd/strlcat.c
+	${libmlk-util_SOURCE_DIR}/mlk/util/openbsd/strlcpy.c
+	${libmlk-util_SOURCE_DIR}/mlk/util/util.h
+)
+
+mlk_library(
+	NAME libmlk-util
+	SOURCES ${SOURCES}
+	TYPE STATIC
+	LIBRARIES ${LIBRARIES}
+	INCLUDES
+		PUBLIC
+			$<BUILD_INTERFACE:${libmlk-util_SOURCE_DIR}>
+			$<BUILD_INTERFACE:${libmlk-util_BINARY_DIR}>
+)
+
+source_group(TREE ${libmlk-util_SOURCE_DIR} FILES ${SOURCES})
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mlk-bcc/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,27 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(mlk-bcc)
+
+mlk_executable(
+	NAME mlk-bcc
+	SOURCES ${mlk-bcc_SOURCE_DIR}/mlk-bcc.c
+	LIBRARIES libmlk-util
+	INSTALL
+	FOLDER tools
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mlk-map/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,27 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(mlk-map)
+
+mlk_executable(
+	NAME mlk-map
+	SOURCES ${mlk-map_SOURCE_DIR}/mlk-map.c
+	LIBRARIES Jansson::Jansson libmlk-util
+	FOLDER tools
+	INSTALL
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mlk-tileset/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,27 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(mlk-tileset)
+
+mlk_executable(
+	NAME mlk-tileset
+	SOURCES ${mlk-tileset_SOURCE_DIR}/mlk-tileset.c
+	LIBRARIES Jansson::Jansson libmlk-util
+	FOLDER tools
+	INSTALL
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/CMakeLists.txt	Sat Feb 18 12:43:05 2023 +0100
@@ -0,0 +1,49 @@
+#
+# CMakeLists.txt -- CMake build system for Molko's Engine
+#
+# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr>
+#
+# Permission to use, copy, modify, and/or distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+#
+
+project(tests)
+
+set(
+	TESTS
+	action
+	action-script
+	alloc
+	character
+	color
+	drawable
+	error
+	map
+	save
+	save-quest
+	state
+	tileset
+	util
+)
+
+foreach (t ${TESTS})
+	add_executable(test-${t} ${tests_SOURCE_DIR}/test-${t}.c)
+	add_test(NAME test-${t} COMMAND test-${t})
+	target_link_libraries(test-${t} libmlk-rpg libmlk-dt)
+	target_compile_definitions(test-${t} PRIVATE DIRECTORY="${tests_SOURCE_DIR}/assets")
+	set_target_properties(test-${t} PROPERTIES FOLDER tests)
+	source_group("" FILES test-${t}.c)
+
+	if (CMAKE_C_COMPILER_ID MATCHES "GNU|Clang")
+		target_compile_options(test-${t} PRIVATE -Wno-unused-parameter)
+	endif ()
+endforeach ()