changeset 253:c4da052c0def

core: goodbye doxygen
author David Demelier <markand@malikania.fr>
date Thu, 03 Dec 2020 09:06:52 +0100
parents 95c2c4a72410
children 6367b976112d
files doc/CMakeLists.txt doc/cmake-extract.sh doc/docs/cmake/MolkoBuildAssets.md doc/docs/cmake/MolkoBuildMaps.md doc/docs/cmake/MolkoBuildTilesets.md doc/docs/cmake/MolkoBuildTranslations.md doc/docs/cmake/MolkoDefineExecutable.md doc/docs/cmake/MolkoDefineLibrary.md doc/docs/cmake/MolkoDefineTest.md doc/docs/cmake/MolkoSetBuildDirectories.md doc/docs/cmake/MolkoSetCompilerFlags.md doc/docs/dev/api/core/action.md doc/docs/dev/api/core/alloc.md doc/docs/dev/api/core/animation.md doc/docs/dev/api/core/clock.md doc/docs/dev/api/core/color.md doc/docs/dev/api/core/core.md doc/docs/dev/api/core/drawable.md doc/docs/dev/api/core/error.md doc/docs/dev/api/core/event.md doc/docs/dev/api/core/font.md doc/docs/dev/api/core/game.md doc/docs/dev/api/core/image.md doc/docs/dev/api/core/inhibit.md doc/docs/dev/api/core/key.md doc/docs/dev/api/core/maths.md doc/docs/dev/api/core/mouse.md doc/docs/dev/api/core/music.md doc/docs/dev/api/core/painter.md doc/docs/dev/api/core/panic.md doc/docs/dev/api/core/save.md doc/docs/dev/api/core/script.md doc/docs/dev/api/core/sound.md doc/docs/dev/api/core/sprite.md doc/docs/dev/api/core/state.md doc/docs/dev/api/core/sys.md doc/docs/dev/api/core/texture.md doc/docs/dev/api/core/trace.md doc/docs/dev/api/core/translate.md doc/docs/dev/api/core/util.md doc/docs/dev/api/core/window.md doc/doxybook.json doc/doxygen/groups.c doc/mkdocs.yml doc/scripts/cmake-extract.sh doc/templates/breadcrumbs.tmpl doc/templates/class_members_details.tmpl doc/templates/class_members_inherited_tables.tmpl doc/templates/class_members_tables.tmpl doc/templates/details.tmpl doc/templates/footer.tmpl doc/templates/header.tmpl doc/templates/index.tmpl doc/templates/index_classes.tmpl doc/templates/index_examples.tmpl doc/templates/index_files.tmpl doc/templates/index_groups.tmpl doc/templates/index_namespaces.tmpl doc/templates/index_pages.tmpl doc/templates/kind_class.tmpl doc/templates/kind_example.tmpl doc/templates/kind_file.tmpl doc/templates/kind_group.tmpl doc/templates/kind_nonclass.tmpl doc/templates/kind_page.tmpl doc/templates/member_details.tmpl doc/templates/meta.tmpl doc/templates/nonclass_members_details.tmpl doc/templates/nonclass_members_tables.tmpl libmlk-core/CMakeLists.txt libmlk-core/core/action.h libmlk-core/core/alloc.h libmlk-core/core/animation.c libmlk-core/core/animation.h libmlk-core/core/clock.h libmlk-core/core/color.h libmlk-core/core/core.h libmlk-core/core/drawable.h libmlk-core/core/error.c libmlk-core/core/error.h libmlk-core/core/event.c libmlk-core/core/event.h libmlk-core/core/font.h libmlk-core/core/game.h libmlk-core/core/image.h libmlk-core/core/inhibit.h libmlk-core/core/key.h libmlk-core/core/maths.h libmlk-core/core/mouse.h libmlk-core/core/music.h libmlk-core/core/painter.h libmlk-core/core/panic.c libmlk-core/core/panic.h libmlk-core/core/save.h libmlk-core/core/script.h libmlk-core/core/sound.h libmlk-core/core/sprite.h libmlk-core/core/state.h libmlk-core/core/sys.h libmlk-core/core/texture.h libmlk-core/core/trace.c libmlk-core/core/trace.h libmlk-core/core/translate.h libmlk-core/core/util.h libmlk-core/core/wait.c libmlk-core/core/wait.h libmlk-core/core/window.h
diffstat 105 files changed, 3663 insertions(+), 2844 deletions(-) [+]
line wrap: on
line diff
--- a/doc/CMakeLists.txt	Tue Dec 01 21:53:23 2020 +0100
+++ b/doc/CMakeLists.txt	Thu Dec 03 09:06:52 2020 +0100
@@ -18,102 +18,92 @@
 
 project(doc)
 
-find_package(Doxygen QUIET)
 find_program(MKDOCS_EXE mkdocs DOC "Path to mkdocs")
-find_program(DOXYBOOK2_EXE doxybook2 DOC "Path to doxybook2")
 find_program(SH_EXE sh DOC "Path to a POSIX shell")
 
-if (DOXYGEN_FOUND AND MKDOCS_EXE AND DOXYBOOK2_EXE AND SH_EXE)
-	set(
-		DOXYGEN_SOURCES
-		libmlk-core
-		libmlk-ui
-		libmlk-rpg
-		${doc_SOURCE_DIR}/doxygen/groups.c
-	)
-
-	set(
-		DOXYGEN_STRIP_FROM_PATH
-		${CMAKE_SOURCE_DIR}/libmlk-core
-		${CMAKE_SOURCE_DIR}/libmlk-ui
-		${CMAKE_SOURCE_DIR}/libmlk-rpg
-	)
+if (MKDOCS_EXE)
 	set(
 		DOC_SOURCES
+		${doc_SOURCE_DIR}/docs/about.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoBuildAssets.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoBuildMaps.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoBuildTilesets.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoBuildTranslations.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoDefineExecutable.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoDefineLibrary.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoDefineTest.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoSetBuildDirectories.md
+		${doc_SOURCE_DIR}/docs/cmake/MolkoSetCompilerFlags.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/action.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/alloc.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/animation.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/clock.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/color.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/core.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/drawable.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/event.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/error.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/font.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/game.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/image.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/inhibit.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/key.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/maths.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/mouse.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/music.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/painter.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/panic.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/save.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/script.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/sound.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/sprite.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/state.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/sys.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/texture.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/trace.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/translate.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/util.md
+		${doc_SOURCE_DIR}/docs/dev/api/core/window.md
+		${doc_SOURCE_DIR}/docs/dev/error.md
+		${doc_SOURCE_DIR}/docs/dev/faq.md
+		${doc_SOURCE_DIR}/docs/dev/howto/01-init.md
+		${doc_SOURCE_DIR}/docs/dev/ownership.md
+		${doc_SOURCE_DIR}/docs/index.md
+		${doc_SOURCE_DIR}/docs/install.md
 		${doc_SOURCE_DIR}/docs/specs/map.md
 		${doc_SOURCE_DIR}/docs/specs/tileset.md
 		${doc_SOURCE_DIR}/docs/tools/bcc.md
 		${doc_SOURCE_DIR}/docs/tools/map.md
 		${doc_SOURCE_DIR}/docs/tools/tileset.md
-		${doc_SOURCE_DIR}/docs/about.md
-		${doc_SOURCE_DIR}/docs/index.md
-		${doc_SOURCE_DIR}/docs/install.md
 		${doc_SOURCE_DIR}/mkdocs.yml
 	)
 
-	# 1. Generate XML structure with Doxygen.
-	set(DOXYGEN_ALLOW_UNICODE_NAMES YES)
-	set(DOXYGEN_AUTOLINK_SUPPORT NO)
-	set(DOXYGEN_ENABLE_PREPROCESSING YES)
-	set(DOXYGEN_EXAMPLE_PATH examples)
-	set(DOXYGEN_EXCLUDE_PATTERNS *_p.h)
-	set(DOXYGEN_FILE_PATTERNS *.h)
-	set(DOXYGEN_GENERATE_HTML YES)
-	set(DOXYGEN_GENERATE_LATEX NO)
-	set(DOXYGEN_GENERATE_MAN NO)
-	set(DOXYGEN_GENERATE_XML YES)
-	set(DOXYGEN_HIDE_SCOPE_NAMES YES)
-	set(DOXYGEN_INPUT_ENCODING UTF-8)
-	set(DOXYGEN_MAX_INITIALIZER_LINES 0)
-	set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)
-	set(DOXYGEN_OUTPUT_DIRECTORY doxygen)
-	set(DOXYGEN_PREDEFINED DOXYGEN)
-	set(DOXYGEN_QUIET YES)
-	set(DOXYGEN_RECURSIVE YES)
-	set(DOXYGEN_SHOW_GROUPED_MEMB_INC NO)
-	set(DOXYGEN_SHOW_INCLUDE_FILES NO)
-	set(DOXYGEN_SHOW_USED_FILES NO)
-	set(DOXYGEN_TAB_SIZE 8)
-	set(DOXYGEN_WARNINGS YES)
-
-	set(DOXYGEN_HTML_OUTPUT ${doc_BINARY_DIR}/doxygen/html)
-	set(DOXYGEN_XML_OUTPUT ${doc_BINARY_DIR}/doxygen/xml)
-
-	# 0. Create commands to prepare the output build directory.
-	list(
-		APPEND commands
+	add_custom_target(
+		doc
+		VERBATIM
+		SOURCES ${DOC_SOURCES}
+		WORKING_DIRECTORY ${doc_SOURCE_DIR}
 		COMMAND
-			${CMAKE_COMMAND} -E make_directory ${doc_BINARY_DIR}/docs/cmake
-		COMMAND
-			${CMAKE_COMMAND} -E copy_directory
-				${doc_SOURCE_DIR}/docs
-				${doc_BINARY_DIR}/docs
-		COMMAND
-			${CMAKE_COMMAND} -E copy
-				${doc_SOURCE_DIR}/mkdocs.yml
-				${doc_BINARY_DIR}
+			${MKDOCS_EXE} build -d ${doc_BINARY_DIR}/html
 	)
 
-	# 1. Generate HTML/XML from doxygen.
-	doxygen_add_docs(
-		doc-doxygen
-		${DOXYGEN_SOURCES}
-		WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+	add_custom_target(
+		doc-serve
+		VERBATIM
+		SOURCES ${DOC_SOURCES}
+		WORKING_DIRECTORY ${doc_SOURCE_DIR}
+		COMMAND
+			${MKDOCS_EXE} serve
 	)
 
-	# 2. Use doxybook2 to convert doxygen XML to markdown files.
-	list(
-		APPEND commands
-		COMMAND ${DOXYBOOK2_EXE} -q
-			-t ${doc_SOURCE_DIR}/templates
-			-i ${doc_BINARY_DIR}/doxygen/xml
-			-o ${doc_BINARY_DIR}/docs
-			-c ${doc_SOURCE_DIR}/doxybook.json
-	)
+	set_target_properties(doc doc-serve PROPERTIES FOLDER doc)
+	source_group(TREE ${doc_SOURCE_DIR} FILES ${DOC_SOURCES})
+endif ()
 
-	# 3. Convert our CMake macros into documentation.
+if (SH_EXE)
+	# Our CMake macros are extracted from the source code itself.
 	set(
-		MACROS
+		DOC_MACROS
 		${cmake_SOURCE_DIR}/MolkoBuildAssets.cmake
 		${cmake_SOURCE_DIR}/MolkoBuildMaps.cmake
 		${cmake_SOURCE_DIR}/MolkoBuildTilesets.cmake
@@ -125,38 +115,26 @@
 		${cmake_SOURCE_DIR}/MolkoSetCompilerFlags.cmake
 	)
 
-	foreach (m ${MACROS})
+	foreach (m ${DOC_MACROS})
 		get_filename_component(file ${m} NAME_WE)
-		set(output ${doc_BINARY_DIR}/docs/cmake/${file}.md)
+		set(output ${doc_SOURCE_DIR}/docs/cmake/${file}.md)
+
 		list(
 			APPEND commands
-			COMMAND ${SH_EXE} ${doc_SOURCE_DIR}/cmake-extract.sh ${m} > ${output}
+			COMMAND
+				${SH_EXE} ${doc_SOURCE_DIR}/scripts/cmake-extract.sh ${m} > ${output}
 		)
 	endforeach ()
 
-	# Create our final targets.
+	# Create a non-ALL target to update CMake documentation in the source
+	# tree.
 	add_custom_target(
-		doc
+		doc-cmake
 		VERBATIM
-		DEPENDS doc-doxygen
-		SOURCES ${DOC_SOURCES} ${cmake_outputs}
-		WORKING_DIRECTORY ${doc_BINARY_DIR}
-		${commands}
-		COMMAND
-			${MKDOCS_EXE} build -d ${doc_BINARY_DIR}/html
+		DEPENDS ${doc_SOURCE_DIR}/scripts/cmake-extract.sh
+		COMMENT "Updating in-source ${doc_SOURCE_DIR}/docs/cmake"
+		COMMAND ${commands}
 	)
 
-	add_custom_target(
-		doc-serve
-		VERBATIM
-		DEPENDS doc-doxygen
-		SOURCES ${DOC_SOURCES}
-		WORKING_DIRECTORY ${doc_BINARY_DIR}
-		${commands}
-		COMMAND
-			${MKDOCS_EXE} serve
-	)
-
-	set_target_properties(doc doc-doxygen doc-serve PROPERTIES FOLDER doc)
-	source_group(TREE ${doc_SOURCE_DIR}  FILES ${DOC_SOURCES})
+	set_target_properties(doc-cmake PROPERTIES FOLDER doc)
 endif ()
--- a/doc/cmake-extract.sh	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,39 +0,0 @@
-#!/bin/sh
-#
-# cmake-extract.sh -- extract documentation from CMake headers
-#
-# CMakeLists.txt -- CMake build system for molko
-#
-# Copyright (c) 2020 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.
-#
-
-prog=$(basename $0)
-
-usage()
-{
-	printf "usage: $prog cmake-file\n" 1>&2
-	exit 1
-}
-
-if [ $# -ne 1 ]; then
-	usage
-fi
-
-#
-# Remove ISC license header then every grep every lines that start with a #
-# and finally remove them.
-#
-
-sed -e "1,19d" "$1" | grep '^#' | sed -e "s/^# *//"
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoBuildAssets.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,27 @@
+# molko_build_assets
+
+Generate custom commands to convert assets into C header files using mlk-bcc.
+The argument output will be set to contain every generated output so that the
+caller can set them as source input and be generated before the target itself.
+
+## Synopsis:
+
+```cmake
+molko_build_assets(assets outputs)
+```
+
+## Example
+
+```cmake
+molko_build_assets(image.png outputs)
+add_executable(main main.c ${outputs})
+```
+
+Do not forget to add the CMake current binary directory
+`${CMAKE_CURRENT_BINARY_DIR}` through the include flags of the given target.
+
+Each file is generated using the exact same file hierarchy as the input so
+an input of foo/bar/baz.png will be generated as foo/bar/baz.h in the binary
+directory. The exported symbol use the pattern <last-directory>_<basename> so
+in the above example, the file variable would be "bar_baz"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoBuildMaps.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,17 @@
+# molko_build_maps
+
+Generate .map files from tiled .json files using the mlk-map tool. The file
+hierarchy is kept and only extension is changed from .json to .map.
+
+## Synopsis
+
+```cmake
+molko_build_maps(input outputs)
+```
+
+Argument outputs will be set with the generated output files in the binary
+directory to be added as target sources.
+
+Make sure to add `${CMAKE_CURRENT_BINARY_DIR}` into the target include
+directories.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoBuildTilesets.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,18 @@
+# molko_build_tilesets
+
+Generate .tileset files from tiled .json files using the mlk-tileset tool.
+The file hierarchy is kept and only extension is changed from .json to
+.tileset.
+
+## Synopsis
+
+```cmake
+molko_build_tilesets(input outputs)
+```
+
+Argument outputs will be set with the generated output files in the binary
+directory to be added as target sources.
+
+Make sure to add `${CMAKE_CURRENT_BINARY_DIR}` into the target include
+directories.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoBuildTranslations.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,37 @@
+# molko_build_translations
+
+Build translations and update them.
+
+## Synopsis
+
+```cmake
+molko_build_translations(
+TARGET              target name
+SOURCES             target sources
+OUTPUTS             output variable
+TRANSLATIONS        list of localizations
+)
+```
+
+Generate target and output commands for NLS (via GNU gettext) support for the
+given *TARGET* name.
+
+The argument *SOURCES* must contain sources to extract gettext keywords, it
+will search for _, N_. The list of *SOURCES* can contain any files, only .c
+and .h will be filtered.
+
+The argument *OUTPUTS* will be set with the generated .mo files in the binary
+directory and installed to *CMAKE_INSTALL_LOCALEDIR*.
+
+The argument *TRANSLATIONS* should contain a list of languages supported in the
+gettext form (ll_LL@variant, see ISO 639 and ISO 3166 for more details).
+
+This macro create a `<TARGET>-po` target that will recreate the .pot file and
+every .po files in the nls/ directory for each language specified in
+*TRANSLATIONS*. Note, if you add a new language into translations but do not
+copy the .pot file, a warning will be issued and you should copy the .pot
+file as the new .po language file.
+
+Since the target is modifying files directly in the source tree they are not
+included in any build process and must be invoked manually.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoDefineExecutable.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,30 @@
+# molko_define_executable
+
+Create an executable.
+
+## Synopsis
+
+```cmake
+molko_define_test(
+TARGET              target name
+SOURCES             src1, src2, srcn
+FOLDER              (Optional) IDE folder if supported
+TRANSLATIONS        (Optional) list of translations
+ASSETS              (Optional) list of assets to build
+FLAGS               (Optional) C flags (without -D)
+LIBRARIES           (Optional) libraries to link
+INCLUDES            (Optional) includes
+)
+```
+
+Create an executable with the name *TARGET* with the given *SOURCES*.
+
+Optional include paths, libraries and flags can be specified via *INCLUDES*,
+*LIBRARIES* and *FLAGS* arguments respectively.
+
+If argument *ASSETS* is set, they are generated in the target binary
+directory.
+
+The optional argument *TRANSLATIONS* should contain a list of supported
+translations. See molko_build_translations for more info.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoDefineLibrary.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,45 @@
+# molko_define_library
+
+Create any kind of library.
+
+## Synopsis
+
+```cmake
+molko_define_library(
+TARGET              target name
+SOURCES             src1, src2, srcn
+EXTERNAL            (Optional) set to true for external libraries
+FOLDER              (Optional) optional subfolder to organize
+TYPE                (Optional) type of library
+ASSETS              (Optional) list of assets
+LIBRARIES           (Optional) libraries to link
+PRIVATE_FLAGS       (Optional) C flags (without -D)
+PRIVATE_INCLUDES    (Optional) local includes for the target only
+PUBLIC_FLAGS        (Optional) C flags (without -D)
+PUBLIC_INCLUDES     (Optional) includes to share with target dependencies
+)
+```
+
+Create a library and optionally install it.
+
+The function create a new library named with the parameter *TARGET*, you
+should prefix it with "lib" as its the convention within molko (e.g. libfoo),
+the prefix is automatically removed.
+
+The argument *SOURCES* should contains the C source files and *HEADERS*
+should points to a directory to be installed verbatim in the include
+directory.
+
+Optional argument *EXTERNAL* should be set for targets that are not
+maintained here (e.g. third party libraries embedded).
+
+Optional argument *PRIVATE_FLAGS*, *PUBLIC_FLAGS*, *PRIVATE_INCLUDES*,
+*PUBLIC_INCLUDES*, *LIBRARIES* may be passed to set compile flags, includes
+and libraries respectively.
+
+The arguments *ASSETS* contains a list of assets to be converted during the
+build. The file hierarchy is conserved in the `${CMAKE_CURRENT_BINARY_DIR}`.
+
+If *FOLDER* option is set, it is organized into its name under the IDE if
+supported.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoDefineTest.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,26 @@
+# molko_define_test
+
+Create unit test.
+
+## Synopsis
+
+```cmake
+molko_define_test(
+TARGET      target name
+SOURCES     src1, src2, srcn
+ASSETS      (Optional) list of assets to build
+FLAGS       (Optional) C flags (without -D)
+LIBRARIES   (Optional) libraries to link
+INCLUDES    (Optional) includes
+)
+```
+
+Create an executable with the name *TARGET* and a test case of the same name
+with the given *SOURCES*.
+
+Optional include paths, libraries and flags can be specified via *INCLUDES*,
+*LIBRARIES* and *FLAGS* arguments respectively.
+
+If argument *ASSETS* is set, they are generated in the target binary
+directory.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoSetBuildDirectories.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,13 @@
+# molko_set_build_directories
+
+Change build directories for the given target.
+
+## Synopsis
+
+```cmake
+molko_set_build_directories(target)
+```
+
+This function will set output directories for the given target. It is
+necessary so that binaries can know where to find extra data.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/cmake/MolkoSetCompilerFlags.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,13 @@
+# molko_set_compiler_flags
+
+Set default compiler flags for the given target.
+
+## Synopsis
+
+```cmake
+molko_set_compiler_flags(target)
+```
+
+This function will adds some compiler flags for the development such as
+warnings, sanitizers if the compiler is compatible.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/action.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,240 @@
+# Module: action
+
+Synopsis
+
+```c
+#include <core/action.h>
+```
+
+Generic updatable and drawable actions.
+
+This module help creating user interaction within the gameplay by adding
+actions. They have the following properties:
+
+- Can handle user input and events,
+- Can be updated through the game loop,
+- Can be drawn.
+
+Most more high level objects can handle actions to add flexibility (like in
+battles, maps, etc).
+
+## Macros
+
+### ACTION\_STACK\_MAX
+
+Maximum number of action in a unique [action_stack](#action_stack).
+
+```c
+#define ACTION_STACK_MAX 128
+```
+
+## Structs
+
+### action
+
+Use this structure to create an action that may handle input, be updated and
+drawn.
+
+All members can be NULL.
+
+| Field             | Access | Type                                             |
+|-------------------|--------|--------------------------------------------------|
+| [data](#data)     | (+&?)  | `void *`                                         |
+| [handle](#handle) | (+?)   | `void (*)(struct action *, const union event *)` |
+| [update](#update) | (+?)   | `bool (*)(struct action *, unsigned int)`        |
+| [draw](#draw)     | (+?)   | `void (*)(struct action *)`                      |
+| [end](#end)       | (+?)   | `void (*)(struct action *)`                      |
+| [finish](#finish) | (+?)   | `void (*)(struct action *)`                      |
+
+#### data
+
+Arbitrary user data.
+
+```c
+void *data
+```
+
+#### handle
+
+Handle an event.
+
+```c
+void (*handle)(struct action *self, const union event *ev)
+```
+
+#### update
+
+Update the action `self` with the `ticks` since last frame. The callback should
+return true if it is considered complete.
+
+```c
+bool (*update)(struct action *self, unsigned int ticks)
+```
+
+#### draw
+
+Draw the action `self`.
+
+```c
+void (*draw)(struct action *self)
+```
+
+#### end
+
+Called with the action `self` when it was completed.
+
+This callback is mostly provided to allow the user doing something else once an
+action is complete. Predefined actions should not use this callback by
+themselves.
+
+```c
+void (*end)(struct action *self)
+```
+
+#### finish
+
+Destroy internal resources for the action `self`.
+
+Close the action before removal. This function should be used to deallocate
+memory if necessary.
+
+```c
+void (*finish)(struct action *act)
+```
+
+### action\_stack
+
+Stack of actions.
+
+The purpose of this structure is to help managing several actions at once.
+Actions are automatically removed from the stack if the corresponding update
+member function returns true after completion.
+
+This structure contains pointers to actions that must be kept until the stack is
+destroyed. User is responsible of deallocating them if they were allocated from
+the heap.
+
+| Field               | Type                                |
+|---------------------|-------------------------------------|
+| [actions](#actions) | `struct action *[ACTION_STACK_MAX]` |
+
+#### actions
+
+Non-owning array of actions to manage.
+
+## Functions
+
+### action\_handle
+
+Invoke the `act` [handle callback](#handle) with the given event `ev` if it is
+not NULL.
+
+```c
+void
+action_handle(struct action *act, const union event *ev)
+```
+
+### action\_update
+
+Invoke and return the `act` [update callback](#update) with `ticks` since last
+frame if it is not NULL.
+
+```c
+bool
+action_update(struct action *act, unsigned int ticks)
+```
+
+### action\_draw
+
+Invoke the `act` [draw callback](#draw) if it is not NULL.
+
+```c
+void
+action_draw(struct action *act)
+```
+
+### action\_end
+
+Invoke the `act` [end callback](#end) if it is not NULL.
+
+```c
+void
+action_end(struct action *act)
+```
+
+### action\_finish
+
+Invoke the `act` [finish callback](#finish) if it is not NULL.
+
+```c
+void
+action_finish(struct action *act)
+```
+
+### action\_stack\_init
+
+Initalize the action stack `st`.
+
+!!! note
+    It is unnecessary if the object was zero'ed.
+
+```
+void
+action_stack_init(struct action_stack *st)
+```
+
+### action\_stack\_add
+
+Add the action `act` to the stack pointed by `st`. Returns true if there was
+enough room to insert.
+
+```c
+bool
+action_stack_add(struct action_stack *st, struct action *act)
+```
+
+### action\_stack\_handle
+
+Handle the event `ev` for all actions in the stack `st`.
+
+```c
+void
+action_stack_handle(struct action_stack *st, const union event *ev)
+```
+
+### action\_stack\_update
+
+Update all actions with `ticks` since last frame in the stack `st`.
+
+```c
+bool
+action_stack_update(struct action_stack *st, unsigned int ticks)
+```
+
+### action\_stack\_draw
+
+Draw all actions in the stack `st`.
+
+```c
+void
+action_stack_draw(const struct action_stack *st)
+```
+
+### action\_stack\_completed
+
+Tells if there is any pending action in the stack `st`. Returns true if there
+are no actions or if they have all completed.
+
+```c
+bool
+action_stack_completed(const struct action_stack *st)
+```
+
+### action\_stack\_finish
+
+Terminate all actions and clear the stack `st`.
+
+```c
+void
+action_stack_finish(struct action_stack *st)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/alloc.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,287 @@
+# Module: alloc
+
+Synopsis
+
+```c
+#include <core/alloc.h>
+```
+
+This module controls how the API should allocate memory. Although dynamic
+allocation isn't much used in the core API, it is used in few places where
+static arrays would not fit (e.g. loading maps).
+
+## Macros
+
+### ALLOC\_POOL\_INIT\_DEFAULT
+
+Default size to allocate in struct alloc_pool.
+
+!!! warning
+    Must be a power of 2.
+
+```c
+#define ALLOC_POOL_INIT_DEFAULT 32
+```
+
+## Structs
+
+### alloc\_funcs
+
+Allocator functions.
+
+!!! warning
+    When changing allocator using [alloc_set](#alloc_set) all functions must
+    be set.
+
+| Field               | Access | Type                                        |
+|---------------------|--------|---------------------------------------------|
+| [alloc](#alloc)     | (+?)   | `void *(*)(size_t)`               |
+| [realloc](#realloc) | (+?)   | `void *(*)(void *, size_t)`  |
+| [free](#free)       | (+?)   | `void (*)(void *)`                   |
+
+#### alloc
+
+Allocate the given `size` of bytes. Returns the allocated memory (or NULL on
+failure).
+
+The default implementation uses malloc and calls [panic](panic.md) in case of
+failure.
+
+!!! note
+    You should set an [error](error.md) in case of failure.
+
+```c
+void *(*alloc)(size_t size)
+```
+
+#### realloc
+
+Realloc the region `ptr` with the new given `size`. Returns the new memory (may
+be NULL).
+
+The default implementation uses malloc and calls [panic](panic.md) in case of
+failure.
+
+!!! note
+    You should set an [error](error.md) in case of failure.
+
+```c
+void *(*realloc)(void *ptr, size_t size)
+```
+
+#### free
+
+Free memory pointed by `ptr`.
+
+The default implementation calls standard C free function.
+
+```c
+void (*free)(void *ptr)
+```
+
+### alloc\_pool
+
+Pool allocator.
+
+This small structure is a helper to reallocate data each time a new slot is
+requested. It allocates twice as the current storage when size exceeds
+capacity.
+
+It uses realloc mechanism to upgrade the new storage space so pointers
+returned must not be referenced directly.
+
+It is designed in mind to help allocating resources locally that may be
+referenced in another module without having to manage an array from the user
+code. Because it is designed for this responsability only it only supports
+insertion.
+
+The initial capacity is controlled by the
+[ALLOC\_POOL\_INIT\_DEFAULT](#macro-alloc_pool_init_default) macro and **must**
+be a power of two.
+
+A custom finalizer function can be set to finalize each individual object if
+necessary.
+
+| Field                 | Access | Type     |
+|-----------------------|--------|----------|
+| [data](#data)         | (+?)   | `void *` |
+| [elemsize](#elemsize) | (-)    | `size_t` |
+| [size](#size)         | (-)    | `size_t` |
+| [capacity](#capacity) | (-)    | `size_t` |
+
+#### data
+
+Pointer to the region.
+
+```c
+void *data
+```
+
+#### elemsize
+
+Size of individual element.
+
+```c
+size_t elemsize
+```
+
+#### size
+
+Number of items in array.
+
+```c
+size_t size
+```
+
+#### capacity
+
+Current capacity.
+
+```c
+size_t capacity
+```
+
+#### finalizer
+
+Optional finalizer that should finalize the object pointed by `data`.
+
+This function will be invoked for every element when
+[alloc\_pool\_finish](#alloc_pool_finish) is called.
+
+```c
+void (*finalizer)(void *data)
+```
+
+## Functions
+
+### alloc\_set
+
+Use [`funcs`](#alloc_funcs) as the new allocator routines. It must be kept valid
+until the program is no longer used.
+
+```c
+void
+alloc_set(const struct alloc_funcs *funcs)
+```
+
+### alloc\_new
+
+Allocate new uninitialized data of the given `size`. Returns the result of the
+current allocator [alloc](#alloc) function set.
+
+```c
+void *
+alloc_new(size_t size)
+```
+
+### alloc\_new0
+
+Invoke [alloc_new](#alloc_new) but zero initialize the memory.
+
+```c
+void *
+alloc_new0(size_t size)
+```
+
+### alloc\_array
+
+Allocate an uninitialized array of `n` elements of `size` individually. Returns
+the result of the current [alloc](#alloc) function set.
+
+```c
+void *
+alloc_array(size_t n, size_t size)
+```
+
+### alloc\_array0
+
+Invoke [alloc_array](#alloc_array) but zero initialize the memory.
+
+```c
+void *
+alloc_array0(size_t n, size_t size)
+```
+
+### alloc\_renew
+
+Reallocate the pointer `ptr` (which may be NULL) to the new `amount` size. The
+size can be 0. Returns the result of the current [alloc](#alloc) function set.
+
+```c
+void *
+alloc_renew(void *ptr, size_t amount)
+```
+
+### alloc\_rearray
+
+Reallocate the `ptr` (which may be NULL) as an array of `n` elements of `size`
+individually. Returns the result of the current [alloc](#alloc) function set.
+
+```c
+void *
+alloc_rearray(void *ptr, size_t n, size_t size)
+```
+
+### alloc\_dup
+
+Duplicate the `ptr` region with the given `size`.
+
+```c
+void *
+alloc_dup(const void *ptr, size_t size)
+```
+
+### alloc\_pool\_init
+
+Initialize the `pool` as an array where elements have `elemsize` size. Optional
+[`finalizer`](#finalizer) argument can be passed to finalize every element when
+clearing the pool.
+
+This will effectively create a initial storage according to
+[ALLOC_POOL_INIT_DEFAULT](#alloc_pool_init_default).
+
+Returns false on errors depending on the result of the of the current
+[alloc](#alloc) function set.
+
+```c
+bool
+alloc_pool_init(struct alloc_pool *pool, size_t elemsize, void (*finalizer)(void *))
+```
+
+### alloc\_pool\_new
+
+Request a new slot from the `pool`.
+
+If the current size has reached the capacity, it will be doubled in that case it
+is possible that all previous pointer may be invalidated.
+
+Returns NULL on errors depending on the result of the of the current
+[realloc](#realloc) function set.
+
+```c
+void *
+alloc_pool_new(struct alloc_pool *pool)
+```
+
+### alloc\_pool\_get
+
+Get the value at the given `index` from the `pool`.
+
+!!! warning
+    Undefined behavior if `index` is out of bounds.
+
+```c
+void *
+alloc_pool_get(const struct alloc_pool *pool, size_t index)
+```
+
+### alloc\_pool\_finish
+
+inalize the `pool` and all individual element if a finalizer is set.
+
+You must call [alloc\_pool\_init](#alloc_pool_init) again before reusing it.
+
+```c
+void
+alloc_pool_finish(struct alloc_pool *pool)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/animation.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,154 @@
+# Module: animation
+
+Synopsis
+
+```c
+#include <core/animation.h>
+```
+
+Drawable animations.
+
+Animations are small objects using a [sprite](sprite.md) to update itself and
+draw next frames depending on delay set.
+
+## Structs
+
+### animation
+
+| Field               | Access | Type              |
+|---------------------|--------|-------------------|
+| [sprite](#sprite)   | (+&)   | `struct sprite *` |
+| [row](#row)         | (+)    | `unsigned int`    |
+| [column](#column)   | (+)    | `unsigned int`    |
+| [delay](#delay)     | (+)    | `unsigned int`    |
+| [elapsed](#elapsed) | (-)    | `unsigned int`    |
+
+#### sprite
+
+The [sprite](sprite.md) file to use.
+
+#### row
+
+Current row to be shown.
+
+#### column
+
+Current column to be shown.
+
+#### delay
+
+Delay between each frame in milliseconds.
+
+#### elapsed
+
+Elapsed time since last frame.
+
+## Functions
+
+### animation\_init
+
+Initialize the animation `an` with the sprite `sprite` using a `delay` between
+each frame.
+
+!!! note
+    This function can be omitted if the object is set using designated
+    initializers (setting other fields to 0).
+
+```c
+void
+animation_init(struct animation *an, struct sprite *sprite, unsigned int delay)
+```
+
+### animation\_start
+
+Start or reset the animation `an` to the beginning.
+
+```c
+void
+animation_start(struct animation *an)
+```
+
+### animation\_completed
+
+Returns true if the animation `an` was completely shown.
+
+```c
+bool
+animation_completed(const struct animation *an)
+```
+
+### animation\_update
+
+Update the animation `an` with `ticks` since last frame. Returns true if it has
+completed.
+
+```c
+bool
+animation_update(struct animation *an, unsigned int ticks)
+```
+
+### animation\_draw
+
+Draw the animation `an` to the given `x`, `y` coordinates.
+
+!!! warning
+    You must not call this function is the animation is complete.
+
+```c
+bool
+animation_draw(const struct animation *an, int x, int y)
+```
+
+### animation\_drawable
+
+Fill the `dw` drawable with functions to draw the animation `an` at the
+coordinates `x`, `y`.
+
+!!! important
+    The animation is only borrowed and must be kept valid during the whole `dw`
+    lifetime.
+
+```c
+void
+animation_drawable(struct animation *an, struct drawable *dw, int x, int y)
+```
+
+## Examples
+
+### Initialization
+
+Initialize using designated initializers
+
+```c
+struct animation an = {
+	.sprite = &my_sprite,
+	.delay = 50
+};
+```
+
+Using `animation_init`
+
+```c
+struct animation an;
+
+animation_init(&an, &my_sprite, 50);
+```
+
+### Updating and drawing
+
+A simple animation loop should like this:
+
+```c
+struct animation an = {
+	.sprite = &my_sprite,
+	.delay = 50
+};
+
+for (;;) {
+	/* Compute ticks in your game loop frame time. */
+	unsigned int ticks = UserTicks();
+
+	if (!animation_update(&an, ticks))
+		animation_draw(&an, 100, 150);
+}
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/clock.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,42 @@
+# Module: clock
+
+Synopsis
+
+```c
+#include <core/clock.h>
+```
+
+Module to keep track of elapsed time.
+
+## Structs
+
+### clock
+
+| Field           | Access | Type           |
+|-----------------|--------|----------------|
+| [ticks](#ticks) | (+)    | `unsigned int` |
+
+#### ticks
+
+Time point on clock initialization in milliseconds.
+
+## Functions
+
+### clock\_start
+
+Start capturing time in the clock `clock`.
+
+```c
+void
+clock_start(struct clock *clock)
+```
+
+### clock\_elapsed
+
+Returns the elapsed time since the last call to [clock_start](#clock_start) in
+the clock `clock`.
+
+```c
+unsigned int
+clock_elapsed(const struct clock *clock)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/color.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,78 @@
+# Module: color
+
+Synopsis
+
+```c
+#include <core/color.h>
+```
+
+Color conversions.
+
+Within the whole API, colors are managed through a 32 bits unsigned integer and
+can be converted back-and-forth using macros from this module.
+
+## Macros
+
+### COLOR\_R
+
+Returns red component of hexadecimal color `c`.
+
+```c
+#define COLOR_R(c)
+```
+
+### COLOR\_G
+
+Returns green component of hexadecimal color `c`.
+
+```c
+#define COLOR_G(c)
+```
+
+### COLOR\_B
+
+Returns blue component of hexadecimal color `c`.
+
+```c
+#define COLOR_B(c)
+```
+
+### COLOR\_A
+
+Returns alpha component of hexadecimal color `c`.
+
+```c
+#define COLOR_A(c)
+```
+
+### COLOR\_HEX
+
+Convert `r`, `g`, `b`, `a`  components into a hexadecimal color.
+
+```c
+#define COLOR_HEX(r, g, b, a)
+```
+
+## Examples
+
+### Convert from hexadecimal to RGBA
+
+```c
+unsigned long color = 0x12feacff;
+unsigned char r, g, b, a;
+
+r = COLOR_R(color);
+g = COLOR_G(color);
+b = COLOR_B(color);
+a = COLOR_A(color);
+```
+
+### Convert from RGBA to hexadecimal
+
+```c
+unsigned int r = 40;
+unsigned int g = 60;
+unsigned int b = 100;
+unsigned int a = 255;
+unsigned long color = COLOR_HEX(r, g, b, a);
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/core.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,42 @@
+# Module: core
+
+Synopsis
+
+```c
+#include <core/core.h>
+```
+
+Main entry point for the libmlk-core library.
+
+The library must be initialized before attempting to call any other functions in
+the API.
+
+## Functions
+
+### core\_init
+
+Initialize the library.
+
+You must specify an `organization` and program `name`. The `organization`
+argument can be anything but [reversed domain name notation][rdnn] is often
+used. It will also determine the path to the preferred directories on certain
+platforms so make sure to not use characters that may be illegal on some
+filesystems.
+
+Returns false in case of errors.
+
+```c
+bool
+core_init(const char *organization, const char *name)
+```
+
+### core\_finish
+
+Close the library.
+
+```c
+void
+core_finish(void)
+```
+
+[rdnn]: https://en.wikipedia.org/wiki/Reverse_domain_name_notation
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/drawable.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,200 @@
+# Module: drawable
+
+Synopsis
+
+```c
+#include <core/drawable.h>
+```
+
+Automatic drawable objects.
+
+This module allows creating automatic objects that draw theirselves into the
+screen and vanish once complete. They could be considered as lightweight
+alternatives to [actions](action.md), however in contrast to them, drawables do
+have a position.
+
+## Macros
+
+### DRAWABLE\_STACK\_MAX
+
+Maximum number of drawable in a unique [drawable_stack](#drawable_stack).
+
+```c
+#define DRAWABLE_STACK_MAX      128
+```
+
+## Structs
+
+### drawable
+
+Abstract drawable object.
+
+| Field             | Access | Type                                        |
+|-------------------|--------|---------------------------------------------|
+| [data](#data)     | (+&?)  | `void *`                                    |
+| [x](#x)           | (+)    | `int`                                       |
+| [y](#y)           | (+)    | `int`                                       |
+| [update](#update) | (+?)   | `bool (*)(struct drawable *, unsigned int)` |
+| [draw](#draw)     | (+?)   | `void (*)(struct drawable *)`               |
+| [end](#end)       | (+?)   | `void (*)(struct drawable *)`               |
+| [finish](#finish) | (+?)   | `void (*)(struct drawable *)`               |
+
+#### data
+
+Optional drawable data.
+
+#### x, y
+
+Position on screen.
+
+#### update
+
+Update the drawable `self` with the `ticks` since last frame. The callback
+should return true if it is considered complete.
+
+```c
+bool (*update)(struct drawable *self, unsigned int ticks)
+```
+
+#### draw
+
+Draw the drawable `self`.
+
+```c
+void (*draw)(struct drawable *self)
+```
+
+#### end
+
+Called with the drawable `self` when it was completed.
+
+This callback is mostly provided to allow the user doing something else once an
+drawable is complete. Predefined drawable should not use this callback by
+themselves.
+
+```c
+void (*end)(struct drawable *self)
+```
+
+#### finish
+
+Destroy internal resources for the drawable `self`.
+
+```c
+void (*finish)(struct drawable *self)
+```
+
+### drawable\_stack
+
+Stack of drawable objects.
+
+This stack of drawable object can be used to store drawable objects within a
+specific transition (state, battle, menu, etc).
+
+You can add, clear, update and draw them.
+
+| Field               | Access | Type                                    |
+|---------------------|--------|-----------------------------------------|
+| [objects](#objects) | (+&?)  | `struct drawable *[DRAWABLE_STACK_MAX]` |
+
+#### objects
+
+Non-owning array of drawables to manage.
+
+## Functions
+
+### drawable\_update
+
+Invoke and return the `dw` [update callback](#update) with the given event `ev`
+and `ticks` since last frame if it is not NULL.
+
+```c
+bool
+drawable_update(struct drawable *dw, unsigned int ticks)
+```
+
+### drawable\_draw
+
+Invoke the `dw` [draw callback](#draw) if it is not NULL.
+
+```c
+void
+drawable_draw(struct drawable *dw)
+```
+
+### drawable\_end
+
+Invoke the `dw` [end callback](#end) if it is not NULL.
+
+```c
+void
+drawable_end(struct drawable *dw)
+```
+
+### drawable\_finish
+
+Invoke the `dw` [finish callback](#finish) if it is not NULL.
+
+```c
+void
+drawable_finish(struct drawable *dw)
+```
+
+### drawable\_stack\_init
+
+Initalize the drawable stack `st`.
+
+!!! note
+    It is unnecessary if the object was zero'ed.
+
+```
+void
+drawable_stack_init(struct drawable_stack *st)
+```
+
+### drawable\_stack\_add
+
+Add the drawable `dw` to the stack pointed by `st`. Returns true if there was
+enough room to insert.
+
+```c
+bool
+drawable_stack_add(struct drawable_stack *st, struct drawable *dw)
+```
+
+### drawable\_stack\_update
+
+Update all drawables with `ticks` since last frame in the stack `st`.
+
+```c
+bool
+drawable_stack_update(struct drawable_stack *st, unsigned int ticks)
+```
+
+### drawable\_stack\_draw
+
+Draw all drawables in the stack `st`.
+
+```c
+void
+drawable_stack_draw(const struct drawable_stack *st)
+```
+
+### drawable\_stack\_completed
+
+Tells if there is any pending drawable in the stack `st`. Returns true if there
+are no drawables or if they have all completed.
+
+```c
+bool
+drawable_stack_completed(const struct drawable_stack *st)
+```
+
+### drawable\_stack\_finish
+
+Terminate all drawables and clear the stack `st`.
+
+```c
+void
+drawable_stack_finish(struct drawable_stack *st)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/error.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,44 @@
+# Module: error
+
+Synopsis:
+
+```c
+#include <core/error.h>
+```
+
+Retrieve or set last global error.
+
+!!! note
+    The error variable is global and not thread safe nor reentrant.
+
+## Functions
+
+### error
+
+Return the last error string.
+
+```c
+const char *
+error(void)
+```
+
+### errorf
+
+Set the global error using [printf][] format string. Also return false for
+convenience.
+
+```c
+bool
+errorf(const char *fmt, ...)
+```
+
+### errorva
+
+Similar to [errorf](#errorf) but using a `va_list` argument instead.
+
+```c
+bool
+errorva(const char *fmt, va_list ap)
+```
+
+[printf]: https://en.cppreference.com/w/c/io/fprintf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/event.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,129 @@
+# Module: event
+
+Synopsis
+
+```c
+#include <core/event.h>
+```
+
+Poll user input and system events.
+
+## Enums
+
+### event\_type
+
+Which kind of event has been reported.
+
+| Enumerator        | Description                                           |
+|-------------------|-------------------------------------------------------|
+| `EVENT_CLICKDOWN` | Mouse click down, see [event_click](#event_click)     |
+| `EVENT_CLICKUP`   | Mouse click released, see [event_click](#event_click) |
+| `EVENT_KEYDOWN`   | Single key down, see [event_key](#event_key)          |
+| `EVENT_KEYUP`     | Single key released, see [event_key](#event_key)      |
+| `EVENT_MOUSE`     | Mouse moved, see [event_mouse](#event_mouse)          |
+| `EVENT_QUIT`      | Quit request                                          |
+
+## Unions
+
+### event
+
+Union that store every kind of event.
+
+The union along with every sub structures that are defined all have the `enum
+event_type` as first field which means that you can access the union's type
+field directly.
+
+Depending on the [type](#type) field, access only the appropriate sub structure
+that describe the event. See below structures that describe events.
+
+| Field           | Access | Type                 |
+|-----------------|--------|----------------------|
+| [type](#type)   | (-)    | `enum event_type`    |
+| [key](#key)     | (+)    | `struct event_key`   |
+| [mouse](#mouse) | (+)    | `struct event_mouse` |
+| [click](#click) | (+)    | `struct event_click` |
+
+#### type
+
+Which kind of event happened.
+
+#### key, mouse, click
+
+Access to the element details depending on the type.
+
+## Structs
+
+### event\_key
+
+Describe a keyboard key that was pressed or released.
+
+| Field           | Access | Type              |
+|-----------------|--------|-------------------|
+| [type](#type_1) | (-)    | `enum event_type` |
+| [key](#key)     | (+)    | `enum key`        |
+
+#### type
+
+Set to `EVENT_KEYDOWN` or `EVENT_KEYUP`.
+
+#### key
+
+Which key, see [key](key.md) for more information.
+
+### event\_mouse
+
+Describe a mouse motion.
+
+| Field               | Access | Type                |
+|---------------------|--------|---------------------|
+| [type](#type_2)     | (-)    | `enum event_type`   |
+| [buttons](#buttons) | (+)    | `enum mouse_button` |
+| [x](#x-y)           | (+)    | `int`               |
+| [y](#y-y)           | (+)    | `int`               |
+
+#### type
+
+Set to `EVENT_MOUSE`.
+
+#### buttons
+
+OR'ed values of buttons currently pressed, see [mouse](mouse.md) for more
+information.
+
+#### x, y
+
+New absolute coordinates.
+
+### event\_click
+
+Describe a mouse click or release.
+
+| Field             | Access | Type                |
+|-------------------|--------|---------------------|
+| [type](#type_2)   | (-)    | `enum event_type`   |
+| [button](#button) | (+)    | `enum mouse_button` |
+| [x](#x-y_1)       | (+)    | `int`               |
+| [y](#y-y_1)       | (+)    | `int`               |
+
+#### type
+
+Set to `EVENT_CLICKDOWN` or `EVENT_CLICKUP`.
+
+#### button
+
+Unique button pressed or released.
+
+#### x, y
+
+Absolute coordinates.
+
+## Functions
+
+### event\_poll
+
+Fetch the next event into `ev` or return false if there are not.
+
+```c
+bool
+event_poll(union event *ev)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/font.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,112 @@
+# Module: font
+
+Synopsis
+
+```c
+#include <core/font.h>
+```
+
+Open and use fonts for rendering UTF-8 text.
+
+## Enums
+
+### font\_style
+
+Specify the font style to use.
+
+| Enumerator               | Description                  |
+|--------------------------|------------------------------|
+| `FONT_STYLE_ANTIALIASED` | Pretty antialiasing looking. |
+| `FONT_STYLE_NONE`        | No antialiasing.             |
+
+## Structs
+
+### font
+
+A font handle to render text.
+
+| Field           | Access | Type              |
+|-----------------|--------|-------------------|
+| [style](#style) | (+)    | `enum font_style` |
+
+#### style
+
+Font [style](#font_style) to use for the next rendering operations.
+
+## Functions
+
+### font\_open
+
+Open and load `font` of the given pixel `size` from file `path`. Returns false
+on errors.
+
+```c
+bool
+font_open(struct font *font, const char *path, unsigned int size)
+```
+
+### font\_openmem
+
+Open font and load `font` from the const memory buffer pointed by `buffer` and
+of size `buflen` using a pixel size of `size`. Returns false on errors.
+
+!!! note
+    The argument `buffer` must stay valid until the font is no longer used.
+
+```c
+bool
+font_openmem(struct font *font, const void *buffer, size_t buflen, unsigned int size)
+```
+
+### font\_ok
+
+Returns true if the `font` is properly loaded.
+
+```c
+bool
+font_ok(const struct font *font)
+```
+
+### font\_render
+
+Render the UTF-8 `text` into the texture `tex` using the font pointed by `font`.
+The foreground `color` will be used to draw the text.
+
+Returns false in case of rendering error, in this case `tex` remains
+uninitialized and must not be used.
+
+```c
+bool
+font_render(struct font *font, struct texture *tex, const char *text, unsigned int color)
+```
+
+### font\_height
+
+Returns the maximum glyph height in pixels present in `font`.
+
+```c
+unsigned int
+font_height(const struct font *font)
+```
+
+### font\_query
+
+Query the dimensions that the UTF-8 `text` would require with this `font`. Store
+the dimensions into the `w`, `h` pointers which can be both NULL.
+
+Return false in case of error, in this case both `w` and `h` remain
+uninitialized and must not be used.
+
+```c
+bool
+font_query(const struct font *font, const char *text, unsigned int *w, unsigned int *h)
+```
+
+### font\_finish
+
+Close this `font`.
+
+```c
+void
+font_finish(struct font *font)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/game.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,127 @@
+# Module: game
+
+Synopsis
+
+```c
+#include <core/game.h>
+```
+
+Main game loop and states.
+
+This module offers a global game structure that contain a [state](state.md). It
+is designed to help switching game states and inhibit some of the functions when
+necessary.
+
+In contrast to popular engines, states are not stacked and only one is used at a
+time. Switching states mean that the current state will run until next frame and
+will be closed afterwards.
+
+The main loop use a constant frame rate mechanism based on the screen refresh
+rate if supported, otherwise it use a default frame rate of 60hz. In any case,
+the frame rate is capped in the main loop and the elapsed time is measured
+accordingly to update the game at constant speed no matter the refresh rate is
+present.
+
+Since only one game must be present at a time, a global `game` variable is
+available for convenience to not carrying it everywhere.
+
+## Globals
+
+| Variable | Type          |
+|----------|---------------|
+| `game`   | `struct game` |
+
+## Structs
+
+### game
+
+Game structure.
+
+| Field                     | Access | Type             |
+|---------------------------|--------|------------------|
+| [inhibit](#inhibit)       | (+)    | `enum inhibit`   |
+| [state](#state)           | (+&?)  | `struct state *` |
+| [state_next](#state_next) | (+&?)  | `struct state *` |
+
+#### inhibit
+
+Current inhibit flags set, see [inhibit](inhibit.md) for more information.
+
+#### state
+
+Current state running.
+
+#### state\_next
+
+Optional next state to be changed in next frame loop.
+
+## Functions
+
+### game\_switch
+
+Set `state` for the next frame.
+
+The state will only be effective after the next call to
+[game_update](#game_update).
+
+If argument `quick` is set to true, the state is changed immediately and the
+current state code should immediately return.
+
+```c
+void
+game_switch(struct state *state, bool quick)
+```
+
+#### game\_handle
+
+Handle the event `ev` into the current state.
+
+```c
+void
+game_handle(const union event *ev)
+```
+
+#### game\_update
+
+Update the current state with `ticks` since last frame.
+
+```c
+void
+game_update(unsigned int ticks)
+```
+
+#### game\_draw
+
+Draw the current state.
+
+```c
+void
+game_draw(void)
+```
+
+#### game\_loop
+
+Start a blocking loop that call in order [game_handle](#game_handle),
+[game_update](#game_update) and [game_draw](#game_draw) while keeping a constant
+framerate.
+
+```c
+void
+game_loop(void)
+```
+
+#### game\_stop
+
+Destroy both next and current state if any.
+
+Even if you don't use [game_loop](#game_loop) you should call this function
+because it will close state resources.
+
+!!! caution
+    If you call this function from a state itself, you must return immediately
+    because the state will be finalized immediately.
+
+```c
+void
+game_quit(void)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/image.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,36 @@
+# Module: image
+
+Synopsis
+
+```c
+#include <core/image.h>
+```
+
+Load images from disk or memory and convert them as [textures](texture.md).
+
+## Functions
+
+### image\_open
+
+Load the image from `path` on disk and convert it as a texture into `tex`.
+Returns false on errors, in this case `tex` remains uninitialized and must not
+be used.
+
+```c
+bool
+image_open(struct texture *tex, const char *path)
+```
+
+### image\_openmem
+
+Load the image from memory pointed by `buffer` of size `size` and convert it as
+a texture into `tex`. Returns false on errors, in this case `tex` remains
+uninitialized and must not be used.
+
+!!! note
+    The argument `buffer` must stay valid until the font is no longer used.
+
+```c
+bool
+image_openmem(struct texture *tex, const void *buffer, size_t size)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/inhibit.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,34 @@
+# Module: inhibit
+
+Synopsis
+
+```c
+#include <core/inhibit.h>
+```
+
+Inhibit some mechanism of the game loop.
+
+This module is mostly use only for the [game](game.md) module.
+
+!!! hint
+    This module should be used as last resort because it may introduce bugs if
+    you forget to reset inhibit. In most of the cases you would want to use
+    [actions](action.md) and block a state until it's complete.
+
+## Enums
+
+### inhibit
+
+This enumeration contains values than can be OR'ed and stored in
+[game.inhibit](game.md#inhibit) variable.
+
+| Enumerator             | Description           |
+|------------------------|-----------------------|
+| `INHIBIT_NONE`         | Disable nothing.      |
+| `INHIBIT_STATE_INPUT`  | Disable every events. |
+| `INHIBIT_STATE_UPDATE` | Disable update.       |
+| `INHIBIT_STATE_DRAW`   | Disable draw.         |
+
+!!! caution
+    Use `INHIBIT_STATE_DRAW` with care because not re-rendering the screen can
+    cause artifacts.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/key.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,175 @@
+# Module: key
+
+Synopsis
+
+```c
+#include <core/key.h>
+```
+
+Keyboard definitions.
+
+## Enums
+
+### key
+
+This enumeration contains keys supported by the API.
+
+!!! caution
+    Many keys are not portable or may be not available on every keyboards. For
+    example, it's pretty common to not see some keys on laptops which has much
+    smaller keyboards. Avoid use of non “simple” keys in your game play.
+
+| Enumerator            | Description                   |
+|-----------------------|-------------------------------|
+| `KEY_UNKNOWN`         | Unknown key                   |
+| `KEY_ENTER`           | Return                        |
+| `KEY_ESCAPE`          | Escape                        |
+| `KEY_BACKSPACE`       | Backspace                     |
+| `KEY_TAB`             | Tab                           |
+| `KEY_SPACE`           | Space                         |
+| `KEY_EXCLAIM`         | !                             |
+| `KEY_DOUBLE_QUOTE`    | "                             |
+| `KEY_HASH`            | #                             |
+| `KEY_PERCENT`         | %                             |
+| `KEY_DOLLAR`          | $                             |
+| `KEY_AMPERSAND`       | %                             |
+| `KEY_QUOTE`           | '                             |
+| `KEY_LEFT_PAREN`      | (                             |
+| `KEY_RIGHT_PAREN`     | )                             |
+| `KEY_ASTERISK`        | \*                            |
+| `KEY_PLUS`            | + (top row)                   |
+| `KEY_COMMA`           | ,                             |
+| `KEY_MINUS`           | - (top row)                   |
+| `KEY_PERIOD`          | .                             |
+| `KEY_SLASH`           | /                             |
+| `KEY_0`               | (top row)                     |
+| `KEY_1`               | (top row)                     |
+| `KEY_2`               | (top row)                     |
+| `KEY_3`               | (top row)                     |
+| `KEY_4`               | (top row)                     |
+| `KEY_5`               | (top row)                     |
+| `KEY_6`               | (top row)                     |
+| `KEY_7`               | (top row)                     |
+| `KEY_8`               | (top row)                     |
+| `KEY_9`               | (top row)                     |
+| `KEY_COLON`           | :                             |
+| `KEY_SEMICOLON`       | ;                             |
+| `KEY_LESS`            | <                             |
+| `KEY_EQUALS`          | =                             |
+| `KEY_GREATER`         | >                             |
+| `KEY_QUESTION`        | ?                             |
+| `KEY_AT`              | @                             |
+| `KEY_LEFT_BRACKET`    | [                             |
+| `KEY_BACKSLASH`       | \                             |
+| `KEY_RIGHT_BRACKET`   | ]                             |
+| `KEY_CARET`           | ^                             |
+| `KEY_UNDERSCORE`      | \_                            |
+| `KEY_BACKQUOTE`       | \`                            |
+| `KEY_a`               |                               |
+| `KEY_b`               |                               |
+| `KEY_c`               |                               |
+| `KEY_d`               |                               |
+| `KEY_e`               |                               |
+| `KEY_f`               |                               |
+| `KEY_g`               |                               |
+| `KEY_h`               |                               |
+| `KEY_i`               |                               |
+| `KEY_j`               |                               |
+| `KEY_k`               |                               |
+| `KEY_l`               |                               |
+| `KEY_m`               |                               |
+| `KEY_n`               |                               |
+| `KEY_o`               |                               |
+| `KEY_p`               |                               |
+| `KEY_q`               |                               |
+| `KEY_r`               |                               |
+| `KEY_s`               |                               |
+| `KEY_t`               |                               |
+| `KEY_u`               |                               |
+| `KEY_v`               |                               |
+| `KEY_w`               |                               |
+| `KEY_x`               |                               |
+| `KEY_y`               |                               |
+| `KEY_z`               |                               |
+| `KEY_CAPSLOCK`        | Caps lock                     |
+| `KEY_F1`              |                               |
+| `KEY_F2`              |                               |
+| `KEY_F3`              |                               |
+| `KEY_F4`              |                               |
+| `KEY_F5`              |                               |
+| `KEY_F6`              |                               |
+| `KEY_F7`              |                               |
+| `KEY_F8`              |                               |
+| `KEY_F9`              |                               |
+| `KEY_F10`             |                               |
+| `KEY_F11`             |                               |
+| `KEY_F12`             |                               |
+| `KEY_F13`             | (not portable)                |
+| `KEY_F14`             | (not portable)                |
+| `KEY_F15`             | (not portable)                |
+| `KEY_F16`             | (not portable)                |
+| `KEY_F17`             | (not portable)                |
+| `KEY_F18`             | (not portable)                |
+| `KEY_F19`             | (not portable)                |
+| `KEY_F20`             | (not portable)                |
+| `KEY_F21`             | (not portable)                |
+| `KEY_F22`             | (not portable)                |
+| `KEY_F23`             | (not portable)                |
+| `KEY_F24`             | (not portable)                |
+| `KEY_PRINTSCREEN`     | Print screen                  |
+| `KEY_PAUSE`           | Media pause                   |
+| `KEY_INSERT`          | Insert (not portable)         |
+| `KEY_HOME`            | Home (not portable)           |
+| `KEY_PAGEUP`          | Page up                       |
+| `KEY_DELETE`          | Back delete                   |
+| `KEY_END`             | End                           |
+| `KEY_PAGEDOWN`        | Page down                     |
+| `KEY_RIGHT`           | Right arrow                   |
+| `KEY_LEFT`            | Left arrow                    |
+| `KEY_DOWN`            | Down arrow                    |
+| `KEY_UP`              | Up arrow                      |
+| `KEY_KP_DIVIDE`       | / (keypad)                    |
+| `KEY_KP_MULTIPLY`     | * (keypad)                    |
+| `KEY_KP_MINUS`        | - (keypad)                    |
+| `KEY_KP_PLUS`         | + (keypad)                    |
+| `KEY_KP_ENTER`        | Return (keypad)               |
+| `KEY_KP_1`            | (keypad)                      |
+| `KEY_KP_2`            | (keypad)                      |
+| `KEY_KP_3`            | (keypad)                      |
+| `KEY_KP_4`            | (keypad)                      |
+| `KEY_KP_5`            | (keypad)                      |
+| `KEY_KP_6`            | (keypad)                      |
+| `KEY_KP_7`            | (keypad)                      |
+| `KEY_KP_8`            | (keypad)                      |
+| `KEY_KP_9`            | (keypad)                      |
+| `KEY_KP_0`            | (keypad)                      |
+| `KEY_KP_PERIOD`       | . (keypad)                    |
+| `KEY_KP_COMMA`        | , (keypad)                    |
+| `KEY_MENU`            | Menu key (not portable)       |
+| `KEY_MUTE`            | Volumne mute (not portable)   |
+| `KEY_VOLUME_UP`       | Volume up (not portable)      |
+| `KEY_VOLUME_DOWN`     | Volume down (not portable)    |
+| `KEY_LCTRL`           | Left control                  |
+| `KEY_LSHIFT`          | Left shift                    |
+| `KEY_LALT`            | Left alt                      |
+| `KEY_LSUPER`          | Left super (or logo)          |
+| `KEY_RCTRL`           | Right control                 |
+| `KEY_RSHIFT`          | Right shift                   |
+| `KEY_RALT`            | Right alt                     |
+| `KEY_RSUPER`          | Right super (or logo)         |
+
+### keymod
+
+This enumeration contains keyboards modifiers that can be OR'ed because you may
+press them more than one at once.
+
+| Enumerator      | Description        |
+|-----------------|--------------------|
+| `KEYMOD_LSHIFT` | Left shift         |
+| `KEYMOD_LCTRL`  | Left control       |
+| `KEYMOD_LALT`   | Left alt           |
+| `KEYMOD_LSUPER` | Left super (logo)  |
+| `KEYMOD_RSHIFT` | Right shift        |
+| `KEYMOD_RCTRL`  | Right control      |
+| `KEYMOD_RALT`   | Right alt          |
+| `KEYMOD_RSUPER` | Right super (logo) |
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/maths.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,21 @@
+# Module: maths
+
+Synopsis
+
+```c
+#include <core/maths.h>
+```
+
+Basic maths.
+
+## Functions
+
+### maths\_is\_boxed
+
+Check if the coordinates `px`, `py` are withing the bounding rectangle specified
+by `x`, `y`, `w` and `h`.
+
+```c
+bool
+maths_is_boxed(int x, int y, unsigned int w, unsigned int h, int px, int py)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/mouse.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,20 @@
+# Module: mouse
+
+Synopsis
+
+```c
+#include <core/mouse.h>
+```
+
+## Enums
+
+### mouse\_button
+
+Every available button as a bitmask.
+
+| Enumerator            | Description            |
+|-----------------------|------------------------|
+| `MOUSE_BUTTON_NONE`   | No buttons pressed.    |
+| `MOUSE_BUTTON_LEFT`   | Left button pressed.   |
+| `MOUSE_BUTTON_MIDDLE` | Middle button pressed. |
+| `MOUSE_BUTTON_RIGHT`  | Right button pressed.  |
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/music.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,125 @@
+# Module: music
+
+Synopsis
+
+```c
+#include <core/music.h>
+```
+
+This module provide support for playing music. In contrast to [sounds](sound.md)
+only one music can be played at a time.
+
+## Enums
+
+### music\_flags
+
+Optional music flags that can be OR'ed in functions which use them.
+
+| Enumerator   | Description     |
+|--------------|-----------------|
+| `MUSIC_NONE` | No flags.       |
+| `MUSIC_LOOP` | Loop the music. |
+
+## Structs
+
+### music
+
+This structure has no public editable fields but is still publicly exposed to
+allow stack allocation.
+
+## Functions
+
+### music\_open
+
+Open a music file from `path` and store the result into `mus`. Returns false on
+errors, in this case `mus` remains uninitialized and must not be used.
+
+```c
+bool
+music_open(struct music *mus, const char *path)
+```
+
+### music\_openmem
+
+Open a music from the memory `buffer` of size `buffersz` and store the result
+into `mus`. Returns false on errors, in this case `mus` remains uninitialized
+and must not be used.
+
+!!! note
+    The argument `buffer` must stay valid until the music is no longer used.
+
+```c
+bool
+music_openmem(struct music *mus, const void *buffer, size_t buffersz)
+```
+
+### music\_ok
+
+Returns true if the music `mus` is properly initialized.
+
+```c
+bool
+music_ok(const struct music *mus)
+```
+
+### music\_play
+
+Start playing the given music `mus`.
+
+The argument `flags` can control the playback options and if `fadein` is greater
+than 0 it will fade in during the number of specified milliseconds.
+
+This function will resume the playback since the beginning and will stop the
+current music. If the music playing is currently fading out the playback will
+not start until it has finished.
+
+```
+bool
+music_play(struct music *mus, enum music_flags flags, unsigned int fadein)
+```
+
+### music\_playing
+
+Returns true if a music is playing.
+
+```c
+bool
+music_playing(void)
+```
+
+### music\_pause
+
+Pause the music playback immediately.
+
+```c
+void
+music_pause(void)
+```
+
+### music\_resume
+
+Resume the music playback immediately.
+
+```c
+void
+music_resume(void)
+```
+
+### music\_stop
+
+Stop the music playback, applying an optional `fadeout` delay expressed in
+milliseconds.
+
+```c
+void
+music_stop(unsigned int fadeout)
+```
+
+### music\_finish
+
+Close the music `mus`, if it is playing it is immediately stopped.
+
+```c
+void
+music_finish(struct music *mus)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/painter.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,155 @@
+# Module: painter
+
+Synopsis
+
+```c
+#include <core/painter.h>
+```
+
+Low level basic graphics primitives.
+
+This module is used to draw on the window or on a specific
+[texture](texture.md).
+
+!!! important
+    You must open a [window](window.md#window_open) prior to any rendering
+    operation.
+
+## Macros
+
+### PAINTER\_BEGIN
+
+Start a block to change the rendering context on the texture `tex`.
+
+!!! note
+    Since this macro starts a new scoped block, you may redefine new variables.
+
+```c
+#define PAINTER_BEGIN(tex)
+```
+
+### PAINTER\_END
+
+Terminate the rendering on the current texture.
+
+```c
+#define PAINTER_END()
+```
+
+## Functions
+
+### painter\_get\_target
+
+Get the current `texture` used for the rendering context, if NULL is returned
+the rendering operates directly on the window.
+
+```c
+struct texture *
+painter_get_target(void)
+```
+
+### painter\_set\_target
+
+Use `tex` as the rendering context for next drawing operations.
+
+If `tex` is NULL, rendering will operate on the global window instead.
+
+!!! important
+    You should keep a local texture of the previous target and restore it once
+    you're done because the previous stack frame may have set a rendering target
+    too.
+
+```c
+void
+painter_set_target(struct texture *tex)
+```
+
+### painter\_get\_color
+
+Return the current drawing color.
+
+```c
+unsigned long
+painter_get_color(void)
+```
+
+### painter\_set\_color
+
+Set the drawing `color` for the next operations.
+
+```c
+void
+painter_set_color(unsigned long color)
+```
+
+### painter\_draw\_line
+
+Draw a line that starts at `x1`, `y1` and ends at `x2`, `y2`.
+
+```c
+void
+painter_draw_line(int x1, int y1, int x2, int y2)
+```
+
+### painter\_draw\_point
+
+Draw a point at `x`, `y`.
+
+```
+void
+painter_draw_point(int x, int y)
+```
+
+### painter\_draw\_rectangle
+
+Draw and fill a rectangle at `x`, `y` of dimensions `w`, `h`.
+
+```c
+void
+painter_draw_rectangle(int x, int y, unsigned int w, unsigned int h)
+```
+
+### painter\_draw\_circle
+
+Draw and fill a circle at the coordinates `x`, `y` of radius `r`.
+
+```c
+void
+painter_draw_circle(int x, int y, int r)
+```
+
+### painter\_clear
+
+Clear the current target.
+
+```c
+void
+painter_clear(void)
+```
+
+### painter\_present
+
+Present the rendering.
+
+!!! note
+    Make sure to call this function only once in your game loop.
+
+```c
+void
+painter_present(void)
+```
+
+## Examples
+
+### Block contexts
+
+When rendering on textures, it's always safer to use
+[PAINTER_BEGIN](#painter_begin) and [PAINTER_END](#painter_end) to avoid messing
+with the global context.
+
+```c
+PAINTER_BEGIN(&my_world_texture);
+painter_set_color(0xffffffff);
+painter_draw_rectangle(0, 0, my_world_texture.w, my_world_texture.h);
+PAINTER_END()
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/panic.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,73 @@
+# Module: panic
+
+Synopsis
+
+```c
+#include <core/panic.h>
+```
+
+Unrecoverable error handling.
+
+This set of functions should be used to detect runtime errors that are
+unexpected. They should be used only when the game cannot continue because it is
+in a unrecoverable state.
+
+Examples of appropriate use cases:
+
+- Game saved data is corrupt,
+- Assets are missing,
+- No more memory.
+
+In other contexts, use asserts to indicates programming error and appropriate
+solutions to recover the game otherwise.
+
+## Globals
+
+| Variable                        | Type             |
+|---------------------------------|------------------|
+| [panic_handler](#panic_handler) | `void (*)(void)` |
+
+### panic\_handler
+
+Global panic handler.
+
+The default implementation shows the last error and exit with code 1. The
+function must not return so you have to implement a setjmp/longjmp or a
+exception to be thrown.
+
+If the user defined function returns, panic routines will finally exit with code
+1.
+
+## Functions
+
+### panicf
+
+Terminate the program using the [panic_handler](#panic_handler) routine.
+
+This function will first set the global error with the provided format
+string using the [printf][] format and then call the handler.
+
+```c
+noreturn void
+panicf(const char *fmt, ...)
+```
+
+### panicva
+
+Like [panicf](#panicf) but using a `va_list`.
+
+```c
+noreturn void
+panicva(const char *fmt, va_list ap)
+```
+
+### panic
+
+Call the [panic_handler](#panic_handler) using the last registered error.
+
+```c
+noreturn void
+panic(void)
+```
+
+[printf]: https://en.cppreference.com/w/c/io/fprintf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/save.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,140 @@
+# Module: save
+
+Synopsis
+
+```c
+#include <core/save.h>
+```
+
+Save functions.
+
+This module provides several functions to save the game data into a database.
+
+Database can be opened in read only mode `SAVE_MODE_READ` which will return an
+error if not present or write mode `SAVE_MODE_WRITE` which will create and
+initialize a database if not present on disk.
+
+## Macros
+
+### SAVE\_PROPERTY\_KEY\_MAX
+
+Maximum property key length.
+
+```c
+#define SAVE_PROPERTY_KEY_MAX (64)
+```
+
+### SAVE\_PROPERTY\_VALUE\_MAX
+
+Maximum property value length.
+
+```c
+#define SAVE_PROPERTY_VALUE_MAX (1024)
+```
+
+## Enums
+
+### save\_mode
+
+Open mode for loading database.
+
+| Enumerator        | Description                        |
+|-------------------|------------------------------------|
+| `SAVE_MODE_READ`  | Try to read (no creation).         |
+| `SAVE_MODE_WRITE` | Open for both reading and writing. |
+
+## Structs
+
+### save
+
+Database handle.
+
+| Field                       | Access | Type     |
+|-----------------------------|--------|----------|
+| [created](#created-updated) | (-)    | `time_t` |
+| [updated](#created-updated) | (-)    | `time_t` |
+
+#### created, updated
+
+Timestamp when the save was created and last modified respectively.
+
+### save\_property
+
+Structure that describe a generic key-value property.
+
+| Field                 | Access | Type                                      |
+|-----------------------|--------|-------------------------------------------|
+| [key](#key-value)     | (+)    | `char key[SAVE_PROPERTY_KEY_MAX + 1]`     |
+| [value](#key-value)   | (+)    | `char value[SAVE_PROPERTY_VALUE_MAX + 1]` |
+
+#### key, value
+
+Property key and value.
+
+## Functions
+
+### save\_open
+
+Open and load the database `db` numbered `idx`. The argument `mode` controls the
+opening mode.
+
+This function use the preferred path to store local files under the user home
+directory. The parameter idx specifies the save slot to use.
+
+Returns false on errors, in this case `db` remains uninitialized and must not be
+used.
+
+```c
+bool
+save_open(struct save *db, unsigned int idx, enum save_mode mode)
+```
+
+### save\_open\_path
+
+Similar to [save_open](#save_open) but use a `path` instead.
+
+```c
+bool
+save_open_path(struct save *db, const char *path, enum save_mode mode)
+```
+
+### save\_set\_property
+
+Sets the property `prop` in the database `db`.
+
+If the property already exists, replace it.
+
+Returns false on errors.
+
+```c
+bool
+save_set_property(struct save *db, const struct save_property *prop)
+```
+
+### save\_get\_property
+
+Get the property value from the database `db` and store result in `prop`.
+Returns false on errors.
+
+```c
+bool
+save_get_property(struct save *db, struct save_property *prop)
+```
+
+### save\_remove\_property
+
+Remove the property `prop` from the database `db`. Returns false on errors.
+
+```c
+bool
+save_remove_property(struct save *db, const struct save_property *prop)
+```
+
+### save\_finish
+
+Close the database `db`.
+
+```c
+void
+save_finish(struct save *db)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/script.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,138 @@
+# Module: script
+
+Synopsis
+
+```c
+#include <core/script.h>
+```
+
+Module to create sequence of actions.
+
+Those routines wrap individual actions into a sequence of actions into an action
+itself.
+
+This is convenient for scenarios where you need to specify several sequential
+actions that neet to waid the previous before continuing.
+
+In a nutshell, to write a scenario you should:
+
+1. Create a script with see [script_init](#script_init),
+2. Create one or more actions and append with [script_append](#script_append).
+
+## Macros
+
+### SCRIPT\_ACTION\_MAX
+
+Maximum number of actions in a script.
+
+```c
+#define SCRIPT_ACTION_MAX (128)
+```
+
+## Structs
+
+### script
+
+Structure with actions that must be ran in order.
+
+| Field                 | Access | Type                                 |
+|-----------------------|--------|--------------------------------------|
+| [actions](#action)    | (+&?)  | `struct action *[SCRIPT_ACTION_MAX]` |
+| [actionsz](#actionsz) | (+)    | `size_t`                             |
+| [cur](#cur)           | (-)    | `size_t`                             |
+
+#### actions
+
+Array of non-owning actions to run in order.
+
+#### actionsz
+
+Number of actions in array [actions](#actions)
+
+#### cur
+
+Current action index.
+
+## Functions
+
+### script\_init
+
+Initialize the script `s`.
+
+This is not necessary if you zero'ed the structure.
+
+```c
+void
+script_init(struct script *s)
+```
+
+### script\_append
+
+Add the action `a` into the script `s`. Returns true if there was enough room
+to insert.
+
+!!! note
+    The argument `a` must stay valid until the script is no longer used.
+
+```c
+bool
+script_append(struct script *s, struct action *a)
+```
+
+### script\_handle
+
+Handle the event `ev` into the current action in script `s`.
+
+```c
+void
+script_handle(struct script *s, const union event *ev)
+```
+
+### script\_update
+
+Update the current action in the script `s` with `ticks` since last frame.
+Returns true if the script completed.
+
+```c
+bool
+script_update(struct script *s, unsigned int ticks)
+```
+
+### script\_draw
+
+Draw the current action in script `s`.
+
+```c
+void
+script_draw(struct script *s)
+```
+
+### script\_completed
+
+Returns true if the script `s` is complete.
+
+```c
+bool
+script_completed(const struct script *s)
+```
+
+### script\_finish
+
+Clear the script `s` and all of its actions.
+
+```c
+void
+script_finish(struct script *s)
+```
+
+### script\_action
+
+Convert the script `s` into the action `dst`.
+
+!!! note
+    The argument `s` must stay valid until the script is no longer used.
+
+```c
+void
+script_action(struct script *s, struct action *dst)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/sound.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,114 @@
+# Module: sound
+
+Synopsis
+
+```c
+#include <core/sound.h>
+```
+
+This module provides sound support. Sounds differ from [musics](music.md)
+because several sounds can be played at a time using channels.
+
+## Macros
+
+### SOUND\_CHANNEL\_MAX
+
+Number of channels allocated.
+
+```c
+#define SOUND_CHANNELS_MAX (256)
+```
+
+## Structs
+
+### sound
+
+This structure has no public editable fields but is still publicly exposed to
+allow stack allocation.
+
+## Functions
+
+### sound\_open
+
+Open a sound file from `path` and store the result into `snd`. Returns false on
+errors, in this case `snd` remains uninitialized and must not be used.
+
+```c
+bool
+sound_open(struct sound *snd, const char *path)
+```
+
+### sound\_openmem
+
+Open a sound from the memory `buffer` of size `buffersz` and store the result
+into `snd`. Returns false on errors, in this case `snd` remains uninitialized
+and must not be used.
+
+!!! note
+    The argument `buffer` must stay valid until the sound is no longer used.
+
+```c
+bool
+sound_openmem(struct sound *snd, const void *buffer, size_t buffersz)
+```
+
+### sound\_ok
+
+Returns true if the sound `snd` is properly initialized.
+
+```c
+bool
+sound_ok(const struct sound *snd)
+```
+
+### sound\_play
+
+Start playing the sound `snd` on the given `channel` (or -1 to pick one). If the
+channel is currently playing, its playback is stopped.
+
+The optional argument `fadein` can create a fade in effect expressed in
+milliseconds.
+
+```c
+bool
+sound_play(struct sound *snd, int channel, unsigned int fadein)
+```
+
+### sound\_pause
+
+Pause the sound `snd` playback or all if set to NULL.
+
+```c
+void
+sound_pause(struct sound *snd)
+```
+
+### sound\_resume
+
+Resume the sound `snd` playback or all if set to NULL.
+
+```c
+void
+sound_resume(struct sound *snd)
+```
+
+### sound\_stop
+
+Stop the sound `snd` playback or all if set to NULL.
+
+The optional argument `fadeout` can create a fade out effect expressed in
+milliseconds.
+
+```c
+void
+sound_stop(struct sound *snd, unsigned int fadeout)
+```
+
+### sound\_finish
+
+Close the sound `snd`, if it is currently playing it will immediately stops.
+
+```
+void
+sound_finish(struct sound *snd)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/sprite.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,85 @@
+# Module: sprite
+
+Synopsis
+
+```c
+#include <core/sprite.h>
+```
+
+The sprite is a module to help rendering a large image that is split into
+individual parts. This improves memory usage as several images are loaded in a
+unique one instead of individual parts.
+
+!!! important
+    The image may not contain space, margins or padding within each cell.
+
+## Structs
+
+### sprite
+
+| Field               | Access | Type                     |
+|---------------------|--------|--------------------------|
+| [texture](#texture) | (+&)   | `struct texture *`       |
+| [cellw](#cellw)     | (-)    | `unsigned int `          |
+| [cellh](#cellh)     | (-)    | `unsigned int `          |
+| [nrows](#nrows)     | (-)    | `unsigned int `          |
+| [ncols](#ncols)     | (-)    | `unsigned int `          |
+
+#### texture
+
+The texture to access.
+
+#### cellw
+
+Width of individual cells.
+
+#### cellh
+
+Height of individual cells.
+
+#### nrows
+
+Number of rows computed.
+
+#### ncols
+
+Number of columns computed.
+
+## Functions
+
+### sprite\_init
+
+Initialize a sprite pointed by `sprite` with the texture `tex`.
+
+Arguments `cellw` and `cellh` must specify the dimensions of individual cells in
+the image.
+
+The fields `nrows` and `ncols` will be determined automatically from the
+texture size.
+
+```c
+void
+sprite_init(struct sprite *sprite, struct texture *tex, unsigned int cellw, unsigned int cellh)
+```
+
+### sprite\_ok
+
+Returns true if the `sprite` is properly initialized.
+
+```c
+bool
+sprite_ok(const struct sprite *sprite)
+```
+
+### sprite\_draw
+
+Draw an individual cell from row `r` and column `c` at the coordinates `x`, `y`
+from the sprite `sprite`.
+
+!!! caution
+    Argument `r` and `c` must be out of bounds.
+
+```c
+bool
+sprite_draw(const struct sprite *sprite, unsigned int r, unsigned int c, int x, int y)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/state.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,142 @@
+# Module: state
+
+Synopsis
+
+```c
+#include <core/state.h>
+```
+
+The state module is a facility that allows changing game context with ease using
+a single [game_switch](game.md#game_switch) function.
+
+## Structs
+
+### state
+
+Abstract structure that consists of user callbacks to control the main game
+loop.
+
+| Field             | Access | Type                                            |
+|-------------------|--------|-------------------------------------------------|
+| [data](#data)     | (+&?)  | `void *`                                        |
+| [start](#start)   | (+?)   | `void (*)(struct state *)`                      |
+| [handle](#handle) | (+?)   | `void (*)(struct state *, const union event *)` |
+| [update](#update) | (+?)   | `void (*)(struct state *, unsigned int)`        |
+| [draw](#draw)     | (+?)   | `void (*)(struct state *)`                      |
+| [end](#end)       | (+?)   | `void (*)(struct state *)`                      |
+| [finish](#finish) | (+?)   | `void (*)(struct state *)`                      |
+
+#### data
+
+Optional user data.
+
+```c
+void *data
+```
+
+#### start
+
+This function is called when the state `self` is about to begin.
+
+```c
+void (*start)(struct state *self)
+```
+
+#### handle
+
+Call this function for the state `self` for each event `ev` that happened.
+
+```c
+void (*handle)(struct state *self, const union event *ev)
+```
+
+#### update
+
+Update the state `self` with `ticks` since last frame.
+
+```c
+void (*update)(struct state *self, unsigned int ticks)
+```
+
+#### draw
+
+Draw the state `self`.
+
+```c
+void (*draw)(struct state *self)
+```
+
+#### end
+
+This function is called with state `self` when the state is about to be switched
+off.
+
+```c
+void (*end)(struct state *self)
+```
+
+#### finish
+
+Close resources in state `self`.
+
+```c
+void (*finish)(struct state *self)
+```
+
+## Functions
+
+### state\_start
+
+Invoke the `state` [start callback](#start) if not NULL.
+
+```c
+void
+state_start(struct state *state)
+```
+
+### state\_handle
+
+Invoke the `state` [handle callback](#handle) with the given event `ev` if it is
+not NULL.
+
+```c
+void
+state_handle(struct state *state, const union event *ev)
+```
+
+### state\_update
+
+Invoke and return the `state` [update callback](#update) with `ticks` since last
+frame if it is not NULL.
+
+```c
+void
+state_update(struct state *state, unsigned int ticks)
+```
+
+### state\_draw
+
+Invoke the `state` [draw callback](#draw) if not NULL.
+
+```c
+void
+state_draw(struct state *state)
+```
+
+### state\_end
+
+Invoke the `state` [end callback](#end) if not NULL.
+
+```c
+void
+state_end(struct state *state)
+```
+
+### state\_finish
+
+Invoke the `state` [finish callback](#finish) if not NULL.
+
+```c
+void
+state_finish(struct state *state)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/sys.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,62 @@
+# Module: sys
+
+Synopsis
+
+```c
+#include <core/sys.h>
+```
+
+System utilities.
+
+In the API all paths are normalized using forward slashes `/` no matter which
+platforms it's running on.
+
+## Enums
+
+### sys\_dir
+
+Kind of special directories.
+
+| Enumerator       | Description                        |
+|------------------|------------------------------------|
+| `SYS_DIR_BIN`    | Path to binaries.                  |
+| `SYS_DIR_DATA`   | Directory containing data.         |
+| `SYS_DIR_LOCALE` | Path to NLS catalogs.              |
+| `SYS_DIR_SAVE`   | User directory for save databases. |
+
+## Functions
+
+### sys\_init
+
+Initialize the system.
+
+This function is automatically called from [core_init](core.md#core_init) with
+the same arguments and not necessary from the user.
+
+```c
+bool
+sys_init(const char *organization, const char *name)
+```
+
+### sys\_dir
+
+Return a system or user directory preferred for this platform for the given
+`kind`.
+
+!!! note
+    Returned path is never NULL but points to a static storage area.
+
+```c
+const char *
+sys_dir(enum sys_dir kind)
+```
+
+### sys\_finish
+
+This function is automatically called from [core_finish](core.md#core_finish)
+with the same arguments and not necessary from the user.
+
+```c
+void
+sys_finish(void)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/texture.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,134 @@
+# Module: texture
+
+Synopsis
+
+```c
+#include <core/texture.h>
+```
+
+Low level texture management.
+
+## Enums
+
+### texture\_blend
+
+Determine the color and alpha transparency to modulate while rendering the
+texture.
+
+| Enumerator               | Descriptor           |
+|--------------------------|----------------------|
+| `TEXTURE_BLEND_NONE`     | No pixel modulation. |
+| `TEXTURE_BLEND_BLEND`    | Blend transparency.  |
+| `TEXTURE_BLEND_ADD`      | Additive blending.   |
+| `TEXTURE_BLEND_MODULATE` | Color modulation.    |
+
+## Structs
+
+### texture
+
+Platform dependant rendering texture.
+
+| Field   | Access | Description    |
+|---------|--------|----------------|
+| [w](#w) | (-)    | `unsigned int` |
+| [h](#h) | (-)    | `unsigned int` |
+
+#### w, h
+
+Texture dimensions.
+
+## Functions
+
+### texture\_new
+
+Create a new texture in `tex` with `w` and `h` as dimensions. Returns false on
+errors, in this case `tex` remains uninitialized and must not be used.
+
+```c
+bool
+texture_new(struct texture *tex, unsigned int w, unsigned int h)
+```
+
+### texture\_ok
+
+Returns true if the texture `tex` is properly initialized.
+
+```c
+bool
+texture_ok(const struct texture *tex)
+```
+
+### texture\_set\_blend\_mode
+
+Set the blend mode to `blend` for future blend operations for the texture `tex`.
+
+```c
+bool
+texture_set_blend_mode(struct texture *tex, enum texture_blend blend)
+```
+
+### texture\_set\_alpha\_mod
+
+Apply the transparency `alpha` modulation to the texture `tex`. Returns false on
+errors.
+
+!!! note
+    You may need to use [texture_set_blend_mode](#texture_set_blend_mode) before
+    this function to work.
+
+```c
+bool
+texture_set_alpha_mod(struct texture *tex, unsigned int alpha)
+```
+
+### texture\_set\_color\_mod
+
+Apply the color `color` modulation to the texture `tex`. Returns false on
+errors.
+
+```c
+bool
+texture_set_color_mod(struct texture *tex, unsigned long color)
+```
+
+### texture\_draw
+
+Draw whole texture `tex` at the position `x`, `y`.
+
+```c
+bool
+texture_draw(const struct texture *tex, int x, int y)
+```
+
+### texture\_scale
+
+More advanced texture drawing.
+
+Copy the texture `tex` source rectangle specified by `src_x`, `src_y`, `src_w`,
+`src_h` at the region `dst_x`, `dst_y`, `dst_w`, `dst_h` with an optional
+`angle`.
+
+Returns false on rendering error.
+
+```c
+bool
+texture_scale(const struct texture *tex,
+              int src_x,
+              int src_y,
+              unsigned src_w,
+              unsigned src_h,
+              int dst_x,
+              int dst_y,
+              unsigned dst_w,
+              unsigned dst_h,
+              double angle)
+```
+
+### texture\_finish
+
+Close the texture `tex`.
+
+```c
+void
+texture_finish(struct texture *tex)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/trace.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,58 @@
+# Module: trace
+
+Synopsis
+
+```c
+#include <core/trace.h>
+```
+
+The purpose of this module is to provide a feedback from the code when there are
+non-fatal programming error or unexpected results. In contrast to the
+[debug](debug.md) module this one is always activated no manner if the build is
+in Debug or Release.
+
+For example, having an animation with a delay of 0 is not a technical issue
+but is probably not what the use wants. Thus, a trace warning may be
+generated in that way.
+
+## Globals
+
+| Variable                        | Type                     |
+|---------------------------------|--------------------------|
+| [trace_handler](#trace_handler) | `void (*)(const char *)` |
+
+### trace\_handler
+
+The default one use a simple printf on the standard output.
+
+## Macros
+
+### TRACE\_LINE\_MAX
+
+Maximum length for a trace log.
+
+```c
+#define TRACE_LINE_MAX (1024)
+```
+
+## Functions
+
+### tracef
+
+Log some information using [printf][] format string.
+
+```c
+void
+tracef(const char *fmt, ...)
+```
+
+### traceva
+
+Like [tracef](#tracef) but using a `va_list`.
+
+```c
+void
+traceva(const char *fmt, va_list ap)
+```
+
+[printf]: https://en.cppreference.com/w/c/io/fprintf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/translate.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,34 @@
+# Module: translate
+
+Synopsis
+
+```c
+#include <core/translate.h>
+```
+
+Translation support.
+
+!!! tip
+    This module is usually not required in user code because translations are loaded
+    from library themselves.
+
+## Functions
+
+### translate\_init
+
+Initialize native language support for the given domain `name`. Returns false on
+errors.
+
+```c
+bool
+translate_init(const char *name)
+```
+
+### translate\_finish
+
+Close translations.
+
+```c
+void
+translate_finish(void)
+```
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/util.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,55 @@
+# Module: util
+
+Synopsis
+
+```c
+#include <core/util.h>
+```
+
+Miscellaneous utilities.
+
+## Macros
+
+### NELEM
+
+Get the number of elements in the static C array `x`.
+
+```c
+#define NELEM(x) sizeof ((x)) / sizeof ((x)[0])
+```
+
+## functions
+
+### delay
+
+Put the thread to sleep for a given amount `ms` milliseconds.
+
+```c
+void
+delay(unsigned int ms)
+```
+
+### pprintf
+
+Construct a temporary path to a file that can fit in a `PATH_MAX` array.
+
+This function is useful when specifying paths into a function invocation such
+as `fopen(pprintf("%s.png", i), "r"))`.
+
+Format string is similar to [printf][]
+
+```c
+const char *
+pprintf(const char *fmt, ...)
+```
+
+### nrand
+
+Returns a random number between `lower` and `upper` (included).
+
+```c
+unsigned int
+nrand(unsigned int lower, unsigned int upper)
+```
+
+[printf]: https://en.cppreference.com/w/c/io/fprintf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/docs/dev/api/core/window.md	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,87 @@
+# Module: window
+
+Synopsis
+
+```c
+#include <core/window.h>
+```
+
+Window management.
+
+## Globals
+
+| Variable | Type            |
+|----------|-----------------|
+| `window` | `struct window` |
+
+## Enums
+
+### window\_cursor
+
+Window mouse cursor.
+
+| Enumerator                | Description               |
+|---------------------------|---------------------------|
+| `WINDOW_CURSOR_ARROW`     | Standard arrow.           |
+| `WINDOW_CURSOR_EDIT`      | Text edit cursor "I".     |
+| `WINDOW_CURSOR_WAIT`      | Busy cursor.              |
+| `WINDOW_CURSOR_CROSSHAIR` | Cross-hair for selection. |
+| `WINDOW_CURSOR_SIZE`      | Size/moving.              |
+| `WINDOW_CURSOR_NO`        | Action forbidden.         |
+| `WINDOW_CURSOR_HAND`      | Hand.                     |
+
+## Structs
+
+### window
+
+Window structure.
+
+| Field                   | Access | Type           |
+|-------------------------|--------|----------------|
+| [w](#w-h)               | (-)    | `unsigned int` |
+| [h](#w-h)               | (-)    | `unsigned int` |
+| [framerate](#framerate) | (-)    | `unsigned int` |
+
+#### w, h
+
+Window dimensions.
+
+#### framerate
+
+Display framerate if supported, otherwise set to 0.
+
+## Functions
+
+## window\_open
+
+Open a window with dimensions `width`, `height`. The argument `title` will set
+the window title if the platform supports it.
+
+Returns false on errors, otherwise the global `window` object will be set.
+
+```c
+bool
+window_open(const char *title, unsigned int width, unsigned int height)
+```
+
+## window\_set\_cursor
+
+Change the window cursor to `cursor`.
+
+```c
+void
+window_set_cursor(enum window_cursor cursor)
+```
+
+## window\_finish
+
+Close the window.
+
+!!! caution
+    Many modules expect a window to be running, do not attemps to use the API
+    after calling this function.
+
+```c
+void
+window_finish(void)
+```
--- a/doc/doxybook.json	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-{
-  "baseUrl": "/",
-  "indexInFolders": true,
-  "linkSuffix": "/",
-  "indexClassesName": "index",
-  "indexFilesName": "index",
-  "indexGroupsName": "index",
-  "indexNamespacesName": "index",
-  "indexRelatedPagesName": "index",
-  "indexExamplesName": "index",
-  "mainPageInRoot": true,
-  "mainPageName": "index",
-  "folderClassesName": "classes",
-  "folderExamplesName": "examples",
-  "folderFilesName": "files",
-  "folderGroupsName": "modules",
-  "folderNamespacesName": "namespaces",
-  "folderRelatedPagesName": "pages"
-}
--- a/doc/doxygen/groups.c	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,47 +0,0 @@
-/*
- * groups.c -- describe "Modules" in Doxygen
- *
- * Copyright (c) 2020 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.
- */
-
-/**
- * \defgroup actions Actions
- * \brief Predefined actions.
- */
-
-/**
- * \defgroup states States
- * \brief Predefined states.
- */
-
-/**
- * \defgroup basics Basics
- * \brief Basics utilities.
- */
-
-/**
- * \defgroup drawing Drawing
- * \brief Modules for rendering on the screen.
- */
-
-/**
- * \defgroup input Input and events
- * \brief Input and event handling.
- */
-
-/**
- * \defgroup ui UI
- * \brief User interface elements.
- */
--- a/doc/mkdocs.yml	Tue Dec 01 21:53:23 2020 +0100
+++ b/doc/mkdocs.yml	Thu Dec 03 09:06:52 2020 +0100
@@ -22,6 +22,8 @@
   - admonition
   - tables
   - def_list
+  - pymdownx.highlight
+  - pymdownx.superfences
 nav:
   - Home: index.md
   - About: about.md
@@ -41,15 +43,45 @@
     - Howto:
       - dev/howto/01-init.md
     - CMake macros:
-      - cmake/MolkoBuildAssets.md
-      - cmake/MolkoBuildMaps.md
+      # Don't edit manually, generated from top cmake/*.cmake files.
       - cmake/MolkoBuildTilesets.md
       - cmake/MolkoBuildTranslations.md
+      - cmake/MolkoBuildAssets.md
+      - cmake/MolkoBuildMaps.md
+      - cmake/MolkoDefineTest.md
+      - cmake/MolkoSetCompilerFlags.md
       - cmake/MolkoDefineExecutable.md
-      - cmake/MolkoDefineLibrary.md
-      - cmake/MolkoDefineTest.md
       - cmake/MolkoSetBuildDirectories.md
-      - cmake/MolkoSetCompilerFlags.md
+      - cmake/MolkoDefineLibrary.md
     - API Reference:
-      - Modules: modules/index.md
-      - Files: files/index.md
+      - libmlk-core:
+        - action: dev/api/core/action.md
+        - alloc: dev/api/core/alloc.md
+        - animation: dev/api/core/animation.md
+        - clock: dev/api/core/clock.md
+        - color: dev/api/core/color.md
+        - core: dev/api/core/core.md
+        - drawable: dev/api/core/drawable.md
+        - error: dev/api/core/error.md
+        - event: dev/api/core/event.md
+        - font: dev/api/core/font.md
+        - game: dev/api/core/game.md
+        - image: dev/api/core/image.md
+        - inhibit: dev/api/core/inhibit.md
+        - key: dev/api/core/key.md
+        - maths: dev/api/core/maths.md
+        - mouse: dev/api/core/mouse.md
+        - music: dev/api/core/music.md
+        - painter: dev/api/core/painter.md
+        - panic: dev/api/core/panic.md
+        - save: dev/api/core/save.md
+        - script: dev/api/core/script.md
+        - sound: dev/api/core/sound.md
+        - sprite: dev/api/core/sprite.md
+        - state: dev/api/core/state.md
+        - sys: dev/api/core/sys.md
+        - texture: dev/api/core/texture.md
+        - trace: dev/api/core/trace.md
+        - translate: dev/api/core/translate.md
+        - util: dev/api/core/util.md
+        - window: dev/api/core/window.md
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/scripts/cmake-extract.sh	Thu Dec 03 09:06:52 2020 +0100
@@ -0,0 +1,39 @@
+#!/bin/sh
+#
+# cmake-extract.sh -- extract documentation from CMake headers
+#
+# CMakeLists.txt -- CMake build system for molko
+#
+# Copyright (c) 2020 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.
+#
+
+prog=$(basename $0)
+
+usage()
+{
+	printf "usage: $prog cmake-file\n" 1>&2
+	exit 1
+}
+
+if [ $# -ne 1 ]; then
+	usage
+fi
+
+#
+# Remove ISC license header then every grep every lines that start with a #
+# and finally remove them.
+#
+
+sed -e "1,19d" "$1" | grep '^#' | sed -e "s/^# *//"
--- a/doc/templates/breadcrumbs.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-{% if exists("moduleBreadcrumbs") %}**Module:** {% for module in moduleBreadcrumbs %}**[{{module.title}}]({{module.url}})**{% if not loop.is_last %} **/** {% endif %}{% endfor %}{% endif %}
\ No newline at end of file
--- a/doc/templates/class_members_details.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-{% if exists("publicTypes") %}## Public Types Documentation
-
-{% for child in publicTypes %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("protectedTypes") %}## Protected Types Documentation
-
-{% for child in protectedTypes %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("publicSlots") %}## Public Slots Documentation
-
-{% for child in publicSlots %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("protectedSlots") %}## Protected Slots Documentation
-
-{% for child in protectedSlots %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("publicSignals") %}## Public Signals Documentation
-
-{% for child in publicSignals %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("protectedSignals") %}## Protected Signals Documentation
-
-{% for child in protectedSignals %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("publicFunctions") %}## Public Functions Documentation
-
-{% for child in publicFunctions %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("protectedFunctions") %}## Protected Functions Documentation
-
-{% for child in protectedFunctions %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("publicAttributes") %}## Public Attributes Documentation
-
-{% for child in publicAttributes %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("protectedAttributes") %}## Protected Attributes Documentation
-
-{% for child in protectedAttributes %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("friends") %}## Friends
-
-{% for child in friends %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
\ No newline at end of file
--- a/doc/templates/class_members_inherited_tables.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-{% for base in baseClasses %}
-{% if existsIn(base, "publicClasses") %}**Public Classes inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.publicClasses %}| {{child.kind}} | **[{{last(stripNamespace(child.name))}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "protectedClasses") %}**Protected Classes inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.protectedClasses %}| {{child.kind}} | **[{{last(stripNamespace(child.name))}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "publicTypes") %}**Public Types inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.publicTypes %}| {{child.kind}}{% if existsIn(child, "type") %} {{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})** {% if child.kind == "enum" %}{ {% for enumvalue in child.enumvalues %}{{enumvalue.name}}{% if existsIn(enumvalue, "initializer") %} {{enumvalue.initializer}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %} }{% endif %}{% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "protectedTypes") %}**Protected Types inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.protectedTypes %}| {{child.kind}}{% if existsIn(child, "type") %} {{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})** {% if child.kind == "enum" %}{ {% for enumvalue in child.enumvalues %}{{enumvalue.name}}{% if existsIn(enumvalue, "initializer") %} {{enumvalue.initializer}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %} }{% endif %}{% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "publicSlots") %}**Public Slots inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.publicSlots %}| {% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "protectedSlots") %}**Protected Slots inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.protectedSlots %}| {% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "publicSignals") %}**Public Signals inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.publicSignals %}| {% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "protectedSignals") %}**Protected Signals inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.protectedSignals %}| {% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "publicFunctions") %}**Public Functions inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.publicFunctions %}| {% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "protectedFunctions") %}**Protected Functions inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.protectedFunctions %}| {% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "publicAttributes") %}**Public Attributes inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.publicAttributes %}| {% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "protectedAttributes") %}**Protected Attributes inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.protectedAttributes %}| {% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if existsIn(base, "friends") %}**Friends inherited from [{{base.name}}]({{base.url}})**
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in base.friends %}| {% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**{% if child.type != "class" %}({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}{% endfor %}
\ No newline at end of file
--- a/doc/templates/details.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-{% if exists("brief") %}{{brief}}
-{% endif %}
-{% if exists("paramList") %}**Parameters**: 
-
-{% for param in paramList %}  * **{{param.name}}** {{param.text}}
-{% endfor %}
-{% endif %}
-{% if exists("returnsList") %}**Returns**: 
-
-{% for param in returnsList %}  * **{{param.name}}** {{param.text}}
-{% endfor %}
-{% endif %}
-{% if exists("exceptionsList") %}**Exceptions**: 
-
-{% for param in exceptionsList %}  * **{{param.name}}** {{param.text}}
-{% endfor %}
-{% endif %}
-{% if exists("templateParamsList") %}**Template Parameters**: 
-
-{% for param in templateParamsList %}  * **{{param.name}}** {{param.text}}
-{% endfor %}
-{% endif %}
-{% if exists("deprecated") %}**Deprecated**: 
-
-{{deprecated}}
-{% endif %}
-{% if exists("see") %}**See**: {% if length(see) == 1 %}{{first(see)}}{% else %}
-
-{% for item in see %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("returns") %}**Return**: {% if length(returns) == 1 %}{{first(returns)}}{% else %}
-
-{% for item in returns %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("authors") %}**Author**: {% if length(authors) == 1 %}{{first(authors)}}{% else %}
-
-{% for item in authors %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("version") %}**Version**: {% if length(version) == 1 %}{{first(version)}}{% else %}
-
-{% for item in version %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("since") %}**Since**: {% if length(since) == 1 %}{{first(since)}}{% else %}
-
-{% for item in since %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("date") %}**Date**: {% if length(date) == 1 %}{{first(date)}}{% else %}
-
-{% for item in date %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("note") %}**Note**: {% if length(note) == 1 %}{{first(note)}}{% else %}
-
-{% for item in note %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("bugs") %}**Bug**: {% if length(bugs) == 1 %}{{first(bugs)}}{% else %}
-
-{% for item in bugs %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("tests") %}**Test**: {% if length(tests) == 1 %}{{first(tests)}}{% else %}
-
-{% for item in tests %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("todos") %}**Todo**: {% if length(todos) == 1 %}{{first(todos)}}{% else %}
-
-{% for item in todos %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("warning") %}**Warning**: {% if length(warning) == 1 %}{{first(warning)}}{% else %}
-
-{% for item in warning %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("pre") %}**Precondition**: {% if length(pre) == 1 %}{{first(pre)}}{% else %}
-
-{% for item in pre %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("post") %}**Postcondition**: {% if length(post) == 1 %}{{first(post)}}{% else %}
-
-{% for item in post %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("copyright") %}**Copyright**: {% if length(copyright) == 1 %}{{first(copyright)}}{% else %}
-
-{% for item in copyright %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("invariant") %}**Invariant**: {% if length(invariant) == 1 %}{{first(invariant)}}{% else %}
-
-{% for item in invariant %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("remark") %}**Remark**: {% if length(remark) == 1 %}{{first(remark)}}{% else %}
-
-{% for item in remark %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("attention") %}**Attention**: {% if length(attention) == 1 %}{{first(attention)}}{% else %}
-
-{% for item in attention %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("par") %}**Par**: {% if length(par) == 1 %}{{first(par)}}{% else %}
-
-{% for item in par %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("rcs") %}**Rcs**: {% if length(rcs) == 1 %}{{first(rcs)}}{% else %}
-
-{% for item in rcs %}  * {{item}}
-{% endfor %}{% endif %}
-{% endif %}
-{% if exists("reimplements") %}**Reimplements**: [{{reimplements.fullname}}]({{reimplements.url}})
-
-{% endif %}{% if exists("reimplementedBy") %}**Reimplemented by**: {% for impl in reimplementedBy %}[{{impl.fullname}}]({{impl.url}}){% if not loop.is_last %}, {% endif %}{% endfor %}
-
-{% endif %}
-{% if exists("details") %}{{details}}
-{% endif %}
-{% if exists("inbody") %}{{inbody}}
-{% endif %}
\ No newline at end of file
--- a/doc/templates/footer.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,3 +0,0 @@
--------------------------------
-
-Updated on {{date("%e %B %Y at %H:%M:%S %Z")}}
\ No newline at end of file
--- a/doc/templates/header.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,7 +0,0 @@
----
-{% if exists("title") %}title: {{title}}{% else if exists("name") %}title: {{name}}{% endif %}
-{% if exists("summary") %}summary: {{summary}} {% endif%}
-{% include "meta" %}
----
-
-{% if exists("title") %}# {{title}}{% else if exists("kind") and kind != "page" %}# {{name}} {{title(kind)}} Reference{% endif %}
--- a/doc/templates/index.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,10 +0,0 @@
-
-{% for child0 in children %}* **{{child0.kind}} [{{child0.title}}]({{child0.url}})** {% if existsIn(child0, "brief") %}<br>{{child0.brief}}{% endif %}{% if existsIn(child0, "children") %}{% for child1 in child0.children %}
-    * **{{child1.kind}} [{{last(stripNamespace(child1.title))}}]({{child1.url}})** {% if existsIn(child1, "brief") %}<br>{{child1.brief}}{% endif %}{% if existsIn(child1, "children") %}{% for child2 in child1.children %}
-        * **{{child2.kind}} [{{last(stripNamespace(child2.title))}}]({{child2.url}})** {% if existsIn(child2, "brief") %}<br>{{child2.brief}}{% endif %}{% if existsIn(child2, "children") %}{% for child3 in child2.children %}
-            * **{{child3.kind}} [{{last(stripNamespace(child3.title))}}]({{child3.url}})** {% if existsIn(child3, "brief") %}<br>{{child3.brief}}{% endif %}{% if existsIn(child3, "children") %}{% for child4 in child3.children %}
-                * **{{child4.kind}} [{{last(stripNamespace(child4.title))}}]({{child4.url}})** {% if existsIn(child4, "brief") %}<br>{{child4.brief}}{% endif %}{% if existsIn(child4, "children") %}{% for child5 in child4.children %}
-                    * **{{child5.kind}} [{{last(stripNamespace(child5.title))}}]({{child5.url}})** {% if existsIn(child5, "brief") %}<br>{{child5.brief}}{% endif %}{% if existsIn(child5, "children") %}{% for child6 in child5.children %}
-                        * **{{child6.kind}} [{{last(stripNamespace(child6.title))}}]({{child6.url}})** {% if existsIn(child6, "brief") %}<br>{{child6.brief}}{% endif %}{% if existsIn(child6, "children") %}{% for child7 in child6.children %}
-                            * **{{child7.kind}} [{{last(stripNamespace(child7.title))}}]({{child7.url}})** {% if existsIn(child7, "brief") %}<br>{{child7.brief}}{% endif %}{% endfor %}{% endif %}{% endfor %}{% endif %}{% endfor %}{% endif %}{% endfor %}{% endif %}{% endfor %}{% endif %}{% endfor %}{% endif %}{% endfor %}{% endif %}
-{% endfor %}
--- a/doc/templates/index_classes.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% include "index" %}
-
-{% include "footer" %}
--- a/doc/templates/index_examples.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% include "index" %}
-
-{% include "footer" %}
--- a/doc/templates/index_files.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% include "index" %}
-
-{% include "footer" %}
--- a/doc/templates/index_groups.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% include "index" %}
-
-{% include "footer" %}
--- a/doc/templates/index_namespaces.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% include "index" %}
-
-{% include "footer" %}
--- a/doc/templates/index_pages.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% include "index" %}
-
-{% include "footer" %}
--- a/doc/templates/kind_class.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,32 +0,0 @@
-{% include "header" %}
-
-{% include "breadcrumbs" %}
-
-{% if exists("brief") %}{{brief}}{% endif %}{% if hasDetails %} [More...](#detailed-description)
-{% endif %}
-
-{% if exists("baseClasses") %}Inherits from {% for child in baseClasses %}{% if existsIn(child, "url") %}[{{child.name}}]({{child.url}}){% else %}{{child.name}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}
-{% endif %}
-{% if exists("derivedClasses") %}Inherited by {% for child in derivedClasses %}{% if existsIn(child, "url") %}[{{child.name}}]({{child.url}}){% else %}{{child.name}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}
-{% endif %}
-
-{% include "class_members_tables" %}
-
-{% if hasAdditionalMembers %}## Additional inherited members
-
-{% include "class_members_inherited_tables" %}
-{% endif %}
-
-{% if hasDetails %}## Detailed Description
-
-```cpp{% if exists("templateParams") %}
-template <{% for param in templateParams %}{{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},
-{% endif %}{% endfor %}>{% endif %}
-{% if kind == "interface" %}class{% else %}{{kind}}{% endif %} {{name}};
-```
-
-{% include "details" %}{% endif %}
-
-{% include "class_members_details" %}
-
-{% include "footer" %}
--- a/doc/templates/kind_example.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% if exists("details") %}{{details}}{% endif %}
-
-{% include "footer" %}
--- a/doc/templates/kind_file.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-{% include "header" %}
-
-{% if exists("brief") %}{{brief}}{% endif %}{% if hasDetails %} [More...](#detailed-description)
-{% endif %}
-
-{% include "nonclass_members_tables" %}
-
-{% if hasDetails %}## Detailed Description
-
-{% include "details" %}{% endif %}
-
-{% include "nonclass_members_details" %}
-
-{% if exists("programlisting")%}## Source code
-
-```cpp
-{{programlisting}}
-```
-{% endif %}
-
-{% include "footer" %}
--- a/doc/templates/kind_group.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-{% include "header" %}
-
-{% include "breadcrumbs" %}
-
-{% if exists("brief") %}{{brief}}{% endif %}{% if hasDetails %} [More...](#detailed-description)
-{% endif %}
-
-{% include "nonclass_members_tables" %}
-
-{% if hasDetails %}## Detailed Description
-
-{% include "details" %}{% endif %}
-
-{% include "nonclass_members_details" %}
-
-{% include "footer" %}
--- a/doc/templates/kind_nonclass.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-{% include "header" %}
-
-{% include "breadcrumbs" %}
-
-{% if exists("brief") %}{{brief}}{% endif %}{% if hasDetails %} [More...](#detailed-description)
-{% endif %}
-
-{% include "nonclass_members_tables" %}
-
-{% if hasDetails %}## Detailed Description
-
-{% include "details" %}{% endif %}
-
-{% include "nonclass_members_details" %}
-
-{% include "footer" %}
\ No newline at end of file
--- a/doc/templates/kind_page.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-{% include "header" %}
-
-{% if exists("details") %}{{details}}{% endif %}
-
-{% include "footer" %}
--- a/doc/templates/member_details.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-{% if kind in ["function", "slot", "signal"] %}```cpp
-{% if exists("templateParams") %}template <{% for param in templateParams %}{{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},
-{% endif %}{% endfor %}>
-{% endif %}{% if static %}static {% endif %}{% if inline %}inline {% endif %}{% if explicit %}explicit {% endif %}{% if virtual %}virtual {% endif %}{% if exists("typePlain") %}{{typePlain}} {% endif %}{{name}}{% if length(params) > 0 %}(
-{% for param in params %}    {{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},{% endif %}
-{% endfor %}){% else %}(){% endif %}{% if const %} const{% endif %}{% if override %} override{% endif %}{% if default %} =default{% endif %}{% if deleted %} =deleted{% endif %}{% if pureVirtual %} =0{% endif %}
-```{% endif %}{% if kind == "enum" %}
-| Enumerator | Value | Description |
-| ---------- | ----- | ----------- |
-{% for enumvalue in enumvalues %}| {{enumvalue.name}} | {% if existsIn(enumvalue, "initializer") %}{{replace(enumvalue.initializer, "= ", "")}}{% endif %} | {% if existsIn(enumvalue, "brief") %}{{enumvalue.brief}}{% endif %} {% if existsIn(enumvalue, "details") %}{{enumvalue.details}}{% endif %} |
-{% endfor %}
-{% endif %}{% if kind == "variable" %}```cpp
-{% if static %}static {% endif %}{% if exists("definition") %}{{definition}} {% endif %}{% if exists("initializer") %} {{initializer}}{% endif %};
-```{% endif %}{% if kind == "typedef" %}```cpp
-{{definition}};
-```{% endif %}{% if kind == "using" %}```cpp
-{% if exists("templateParams") %}template <{% for param in templateParams %}{{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},
-{% endif %}{% endfor %}>
-{% endif %}{{definition}};
-```{% endif %}{% if kind == "friend" %}```cpp
-friend {% if exists("typePlain") %}{{typePlain}} {% endif %}{{name}}{% if exists("params") %}{% endif %}{% if length(params) > 0 %}(
-{% for param in params %}    {{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},{% endif %}
-{% endfor %}){% else if typePlain != "class" %}(){% endif %};
-```{% endif %}{% if kind == "define" %}```cpp
-#define {{name}}{% if exists("params") %}(
-{% for param in params %}    {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},{% endif %}
-{% endfor %}){% endif %}{% if exists("initializer") %} {{initializer}}{% endif %}
-```{% endif %}
-
-{% include "details" %}
--- a/doc/templates/nonclass_members_details.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,24 +0,0 @@
-{% if exists("publicTypes") %}## Types Documentation
-
-{% for child in publicTypes %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("publicFunctions") %}## Functions Documentation
-
-{% for child in publicFunctions %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("publicAttributes") %}## Attributes Documentation
-
-{% for child in publicAttributes %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
-{% if exists("defines") %}## Macro Documentation
-
-{% for child in defines %}### {{child.kind}} {{child.name}}
-
-{{ render("member_details", child) }}
-{% endfor %}{% endif %}
\ No newline at end of file
--- a/doc/templates/nonclass_members_tables.tmpl	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-{% if exists("groups") %}## Modules
-
-| Name           |
-| -------------- |
-{% for child in groups %}| **[{{child.title}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("dirs") %}## Directories
-
-| Name           |
-| -------------- |
-{% for child in dirs %}| **[{{child.title}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("files") %}## Files
-
-| Name           |
-| -------------- |
-{% for child in files %}| **[{{child.title}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("namespaces") %}## Namespaces
-
-| Name           |
-| -------------- |
-{% for child in namespaces %}| **[{{child.name}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("publicClasses") %}## Classes
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in publicClasses %}| {{child.kind}} | **[{{child.name}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("publicTypes") %}## Types
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in publicTypes %}| {% if existsIn(child, "templateParams") %}template \<{% for param in child.templateParams %}{{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},{% endif %}{% endfor %}\></br>{% endif %}{{child.kind}}{% if existsIn(child, "type") %} {{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})** {% if child.kind == "enum" %}{ {% for enumvalue in child.enumvalues %}{{enumvalue.name}}{% if existsIn(enumvalue, "initializer") %} {{enumvalue.initializer}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %} }{% endif %}{% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("publicSlots") %}## Slots
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in publicSlots %}| {% if existsIn(child, "templateParams") %}template \<{% for param in child.templateParams %}{{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},{% endif %}{% endfor %}\></br>{% endif %}{% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("publicSignals") %}## Signals
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in publicSignals %}| {% if existsIn(child, "templateParams") %}template \<{% for param in child.templateParams %}{{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},{% endif %}{% endfor %}\></br>{% endif %}{% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("publicFunctions") %}## Functions
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in publicFunctions %}| {% if existsIn(child, "templateParams") %}template \<{% for param in child.templateParams %}{{param.typePlain}} {{param.name}}{% if existsIn(param, "defvalPlain") %} ={{param.defvalPlain}}{% endif %}{% if not loop.is_last %},{% endif %}{% endfor %}\></br>{% endif %}{% if child.virtual %}virtual {% endif %}{% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**({% for param in child.params %}{{param.type}} {{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% if child.const %} const{% endif %}{% if child.override %} override{% endif %}{% if child.default %} =default{% endif %}{% if child.deleted %} =deleted{% endif %}{% if child.pureVirtual %} =0{% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("publicAttributes") %}## Attributes
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in publicAttributes %}| {% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})** {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
-{% if exists("defines") %}## Defines
-
-|                | Name           |
-| -------------- | -------------- |
-{% for child in defines %}| {% if existsIn(child, "type") %}{{child.type}}{% endif %} | **[{{child.name}}]({{child.url}})**{% if existsIn(child, "params") %}({% for param in child.params %}{{param.name}}{% if existsIn(param, "defval") %} ={{param.defval}}{% endif %}{% if not loop.is_last %}, {% endif %}{% endfor %}){% endif %} {% if existsIn(child, "brief") %}<br>{{child.brief}}{% endif %} |
-{% endfor %}{% endif %}
\ No newline at end of file
--- a/libmlk-core/CMakeLists.txt	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/CMakeLists.txt	Thu Dec 03 09:06:52 2020 +0100
@@ -92,8 +92,6 @@
 	${libmlk-core_SOURCE_DIR}/core/translate.h
 	${libmlk-core_SOURCE_DIR}/core/util.c
 	${libmlk-core_SOURCE_DIR}/core/util.h
-	${libmlk-core_SOURCE_DIR}/core/wait.c
-	${libmlk-core_SOURCE_DIR}/core/wait.h
 	${libmlk-core_SOURCE_DIR}/core/window.c
 	${libmlk-core_SOURCE_DIR}/core/window.h
 	${libmlk-core_SOURCE_DIR}/core/window_p.h
--- a/libmlk-core/core/action.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/action.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,220 +19,58 @@
 #ifndef MOLKO_CORE_ACTION_H
 #define MOLKO_CORE_ACTION_H
 
-/**
- * \file action.h
- * \brief Action states.
- * \ingroup actions
- */
-
 #include <stdbool.h>
 
-/**
- * \brief Maximum number of actions in stack.
- */
-#define ACTION_STACK_MAX        128
+#define ACTION_STACK_MAX (128)
 
 union event;
 
-/**
- * \brief Action structure.
- *
- * Use this structure to create an action that reacts to user events.
- *
- * The purpose of actions is to simplify user interaction within a specific
- * state or a dedicated user routine. With the help of the companion
- * \ref action_stack it is easy to manage actions in a specific game logic
- * state.
- *
- * All members can be NULL.
- */
 struct action {
-	/**
-	 * (+&?) Arbitrary user data.
-	 */
 	void *data;
-
-	/**
-	 * (+&?) Handle event.
-	 *
-	 * \param act this action
-	 * \param ev the event
-	 */
 	void (*handle)(struct action *act, const union event *ev);
-
-	/**
-	 * (+?) Update the action.
-	 *
-	 * \param act this action
-	 * \param ticks the number of milliseconds since last frame
-	 * \return true if action has terminated
-	 */
 	bool (*update)(struct action *act, unsigned int ticks);
-
-	/**
-	 * (+?) Draw the action.
-	 *
-	 * \param act this action
-	 */
 	void (*draw)(struct action *act);
-
-	/**
-	 * (+?) Called when the action was completed.
-	 *
-	 * This callback is mostly provided to allow the user doing something
-	 * else once an action is complete. Predefined actions should not use
-	 * this callback by themselves.
-	 *
-	 * \param act this action
-	 */
 	void (*end)(struct action *act);
-
-	/**
-	 * (+?) Destroy internal resources.
-	 *
-	 * Close the action before removal. This function should be used to
-	 * deallocate memory if necessary.
-	 *
-	 * \param act this action
-	 */
 	void (*finish)(struct action *act);
 };
 
-/**
- * Shortcut for act->handle (if not NULL).
- *
- * \pre act != NULL
- * \pre ev != NULL
- * \param act the action
- * \param ev the event
- */
+struct action_stack {
+	struct action *actions[ACTION_STACK_MAX];
+};
+
 void
 action_handle(struct action *act, const union event *ev);
 
-/**
- * Shortcut for act->update (if not NULL).
- *
- * \pre act != NULL
- * \param act the action
- * \param ticks the number of milliseconds since last frame
- * \return Status of act->update or false if act->update is NULL.
- */
 bool
 action_update(struct action *act, unsigned int ticks);
 
-/**
- * Shortcut for act->draw (if not NULL).
- *
- * \pre act != NULL
- * \param act the action
- */
 void
 action_draw(struct action *act);
 
-/**
- * Shortcut for act->end (if not NULL).
- *
- * \pre act != NULL
- * \param act the action
- */
 void
 action_end(struct action *act);
 
-/**
- * Shortcut for act->finish (if not NULL).
- *
- * \pre act != NULL
- * \param act the action
- */
 void
 action_finish(struct action *act);
 
-/**
- * \brief Stack of actions.
- *
- * The purpose of this structure is to help managing several actions at once.
- * Actions are automatically removed from the stack if the corresponding update
- * member function returns true after completion.
- *
- * This structure contains pointers to actions that must be kept until the stack
- * is destroyed. User is responsible of deallocating them if they were allocated
- * from the heap.
- */
-struct action_stack {
-	struct action *actions[ACTION_STACK_MAX];        /*!< (+) Actions */
-};
-
-/**
- * Initalize the action stack.
- *
- * It is unnecessary if the object was zero'ed.
- *
- * \pre st != NULL
- * \param st the stack
- */
 void
 action_stack_init(struct action_stack *st);
 
-/**
- * Add an action to the stack.
- *
- * \pre st != NULL
- * \pre act != NULL
- * \param st the stack
- * \param act the action
- * \note The pointer must be kept alive.
- * \return True if the action was added correctly (enough space).
- */
 bool
 action_stack_add(struct action_stack *st, struct action *act);
 
-/**
- * Handle an event for all actions.
- *
- * \pre st != NULL
- * \pre ev != NULL
- * \param st the stack
- * \param ev the event
- */
 void
 action_stack_handle(struct action_stack *st, const union event *ev);
 
-/**
- * Update all actions.
- *
- * \pre st != NULL
- * \param st the stack
- * \param ticks the number of milliseconds since last frame
- * \return True if all actions completed.
- */
 bool
 action_stack_update(struct action_stack *st, unsigned int ticks);
 
-/**
- * Draw all actions.
- *
- * \pre st != NULL
- * \param st the stack
- */
 void
 action_stack_draw(const struct action_stack *st);
 
-/**
- * Tells if there is any pending action in the stack.
- *
- * \pre st != NULL
- * \param st the stack
- * \return False if there is at least one action in the stack.
- */
 bool
 action_stack_completed(const struct action_stack *st);
 
-/**
- * Terminate all actions and clear the stack.
- *
- * \pre st != NULL
- * \param st the stack
- */
 void
 action_stack_finish(struct action_stack *st);
 
--- a/libmlk-core/core/alloc.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/alloc.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,250 +19,65 @@
 #ifndef MOLKO_CORE_ALLOC_H
 #define MOLKO_CORE_ALLOC_H
 
-/**
- * \file alloc.h
- * \brief Custom allocators.
- *
- * This module controls how the API should allocate memory. Although dynamic
- * allocation isn't much used in the core API, it is used in few places where
- * static arrays would not fit (e.g. loading maps).
- *
- * To change the allocator, simply modify the global allocator object.
- */
-
 #include <stdbool.h>
 #include <stddef.h>
 
 #include "util.h"
 
-/**
- * \brief Default size to allocate in struct alloc_pool.
- * \warning Must be a power of 2.
- */
-#define ALLOC_POOL_INIT_DEFAULT 32
+/* Must be power of 2. */
+#define ALLOC_POOL_INIT_DEFAULT (32)
 
-/**
- * \brief Allocator functions.
- */
+/* Custom allocator. */
 struct alloc_funcs {
-	/**
-	 * (+) Allocate some data.
-	 *
-	 * The default implementation uses malloc and calls \ref panic in case
-	 * of failure.
-	 *
-	 * \pre size != 0
-	 * \param size the size to alloc
-	 * \return A pointer to the allocated region (NULL is allowed).
-	 */
 	void *(*alloc)(size_t size);
-
-	/**
-	 * (+) Realloc a region.
-	 *
-	 * The default implementation uses malloc and calls \ref panic in case
-	 * of failure.
-	 *
-	 * \pre size != 0
-	 * \param ptr the old region
-	 * \param size the new size
-	 * \return A pointer to the allocated region (NULL is allowed).
-	 */
 	void *(*realloc)(void *ptr, size_t size);
-
-	/**
-	 * (+) Free resources.
-	 *
-	 * The default implementation calls standard C free function.
-	 *
-	 * \param ptr the region (may be NULL)
-	 */
 	void (*free)(void *ptr);
 };
 
-/**
- * \brief Pool allocator.
- *
- * This small structure is a helper to reallocate data each time a new slot is
- * requested. It allocates twice as the current storage when size exceeds
- * capacity.
- *
- * It uses realloc mechanism to upgrade the new storage space so pointers
- * returned must not be referenced directly.
- *
- * It is designed in mind to help allocating resources locally that may be
- * referenced in another module without having to manage an array from the user
- * code. Because it is designed for this responsability only it only supports
- * insertion.
- *
- * The initial capacity is controlled by the ALLOC_POOL_INIT_DEFAULT macro and
- * **must** be a power of two.
- *
- * A custom finalizer function can be set to finalize each individual object if
- * necessary.
- */
+/* Minimalist growable array for loading data. */
 struct alloc_pool {
-	void *data;             /*!< (+?) Pointer to the region. */
-	size_t elemsize;        /*!< (-) Size of individual element. */
-	size_t size;            /*!< (-) Number of items in array. */
-	size_t capacity;        /*!< (-) Current capacity. */
-
-	/**
-	 * (+?) Optional finalizer.
-	 *
-	 * This function will be invoked for every element when \ref
-	 * alloc_pool_finish is called.
-	 *
-	 * \param data the element to finalize
-	 */
+	void *data;
+	size_t elemsize;
+	size_t size;
+	size_t capacity;
 	void (*finalizer)(void *data);
 };
 
-/**
- * Set custom allocator functions.
- *
- * The alloc_funcs struct must stay valid until the program is closed.
- *
- * \pre funcs != NULL
- * \pre funcs->alloc != NULL
- * \pre funcs->realloc != NULL
- * \pre funcs->free != NULL
- * \param funcs the functions
- */
+/* allocator functions. */
 void
 alloc_set(const struct alloc_funcs *funcs);
 
-/**
- * Shortcut for allocator->alloc.
- *
- * \pre size != 0
- * \param size the amount of bytes to allocate
- * \return The result of allocator->alloc.
- */
 void *
 alloc_new(size_t size);
 
-/**
- * Similar to alloc_new but zero-initialize the memory.
- *
- * \pre size != 0
- * \param size the amount of bytes to allocate
- * \return The result of allocator->alloc.
- */
 void *
 alloc_new0(size_t size);
 
-/**
- * Shortcut for allocator->alloc but specialized for arrays.
- *
- * \pre n != 0 && size != 0
- * \param n the number of objects to allocate
- * \param size the size of each object
- * \return The result of allocator->alloc.
- */
 void *
 alloc_array(size_t n, size_t size);
 
-/**
- * Similar to alloc_array but zero-initialize the memory.
- *
- * \pre n != 0 && size != 0
- * \param n the number of objects to allocate
- * \param size the size of each object
- * \return The result of allocator->alloc.
- */
 void *
 alloc_array0(size_t n, size_t size);
 
-/**
- * Shortcut for allocator->realloc.
- *
- * \param ptr the old pointer (maybe NULL)
- * \param amount the new amount (maybe 0)
- * \return The result of allocator->realloc
- */
 void *
 alloc_renew(void *ptr, size_t amount);
 
-/**
- * Shortcut for allocator->realloc but specialized for arrays.
- *
- * \param ptr the old pointer (maybe NULL)
- * \param n the number of element
- * \param size the size of each object
- * \return The result of allocator->realloc
- */
 void *
 alloc_rearray(void *ptr, size_t n, size_t size);
 
-/**
- * Duplicate region pointer by ptr.
- *
- * This function calls \ref alloc_new to allocate memory.
- *
- * \pre ptr != NULL
- * \param ptr the pointer
- * \param size the size of the memory to copy
- * \return The result of allocator->alloc filled with a copy of ptr.
- */
 void *
 alloc_dup(const void *ptr, size_t size);
 
-/**
- * Initialize the pool.
- *
- * This will effectively create a initial storage according to
- * ALLOC_POOL_INIT_DEFAULT.
- *
- * This function effectively use the global allocator object to initialize the
- * array.
- *
- * \pre pool != NULL
- * \pre elemsize != 0
- * \param pool the pool to initialize
- * \param elemsize size of each individual element
- * \param finalizer a finalizer to use when clearing the pool.
- * \return True if allocation suceedeed.
- */
+/* alloc_pool functions. */
 bool
 alloc_pool_init(struct alloc_pool *pool, size_t elemsize, void (*finalizer)(void *));
 
-/**
- * Request a new slot from the pool.
- *
- * If the current size has reached the capacity, it will be doubled in that case
- * it is possible that all previous pointer may be invalidated.
- *
- * This function effectively use the global allocator object to realloc the
- * array.
- *
- * \pre pool != NULL
- * \param pool the pool
- * \return The pointer to the region.
- */
 void *
 alloc_pool_new(struct alloc_pool *pool);
 
-/**
- * Get the value at the given index.
- *
- * \pre pool != NULL
- * \pre index < pool->size
- * \param pool the pool
- * \param index the object index
- * \return The pointer to the region.
- */
 void *
 alloc_pool_get(const struct alloc_pool *pool, size_t index);
 
-/**
- * Finalize the pool and all individual element if a finalizer is set.
- *
- * You must call \ref alloc_pool_init again before reusing it.
- *
- * \pre pool != NULL
- * \param pool the pool to clear
- */
 void
 alloc_pool_finish(struct alloc_pool *pool);
 
--- a/libmlk-core/core/animation.c	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/animation.c	Thu Dec 03 09:06:52 2020 +0100
@@ -36,7 +36,7 @@
 }
 
 void
-animation_init(struct animation *an, struct sprite *sprite, unsigned int delay)
+animation_init(struct animation *an, const struct sprite *sprite, unsigned int delay)
 {
 	assert(an);
 	assert(sprite);
--- a/libmlk-core/core/animation.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/animation.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,109 +19,34 @@
 #ifndef MOLKO_CORE_ANIMATION_H
 #define MOLKO_CORE_ANIMATION_H
 
-/**
- * \file animation.h
- * \brief Basic animations.
- * \ingroup drawing
- */
-
 #include <stdbool.h>
 
 struct drawable;
 struct sprite;
 
-/**
- * \brief Animation object
- */
 struct animation {
-	struct sprite *sprite;  /*!< (+&) Sprite to use. */
-	unsigned int row;       /*!< (-) Current row. */
-	unsigned int column;    /*!< (-) Current column. */
-	unsigned int delay;     /*!< (-) Delay between frames. */
-	unsigned int elapsed;   /*!< (-) Elapsed time since last frame. */
+	const struct sprite *sprite;
+	unsigned int row;
+	unsigned int column;
+	unsigned int delay;
+	unsigned int elapsed;
 };
 
-/**
- * Initialize the animation.
- *
- * The animation does not take sprite ownership, it must be valid until
- * animation is no longer used.
- *
- * \pre an != NULL
- * \pre sprite != NULL
- * \param an the animation
- * \param sprite the sprite to use
- * \param delay the delay between frames in milliseconds
- */
 void
-animation_init(struct animation *an, struct sprite *sprite, unsigned int delay);
+animation_init(struct animation *an, const struct sprite *sprite, unsigned int delay);
 
-/**
- * Start an animation.
- *
- * \pre an != NULL
- * \param an the animation
- */
 void
 animation_start(struct animation *an);
 
-/**
- * Tells if the animation has completed.
- *
- * \pre an != NULL
- * \param an the animation
- * \return True if the animation shown all images.
- */
 bool
 animation_completed(const struct animation *an);
 
-/**
- * Update the animation.
- *
- * You must call this function at each loop iteration to update the animation
- * frame depending on its delay.
- *
- * \pre an != NULL
- * \param an the animation
- * \param ticks the elapsed ticks since the last call
- * \return True if the animation is complete.
- */
 bool
 animation_update(struct animation *an, unsigned int ticks);
 
-/**
- * Draw the animation.
- *
- * \pre an != NULL && !animation_completed(an)
- * \param an the animation
- * \param x the X coordinate
- * \param y the Y coordinate
- * \return False in case of rendering error.
- */
 bool
 animation_draw(const struct animation *an, int x, int y);
 
-/**
- * Create a drawable from an animation.
- *
- * The animation must be kept alive until the drawable is used.
- *
- * The dw->data member will be set to the animation pointer and can be
- * safely used by the user for custom drawable operation if needed.
- *
- * The dw->finish member isn't used and can be re-used by the user.
- *
- * \pre an != NULL
- * \pre dw != NULL
- * \param an the animation
- * \param dw the drawable
- * \param x x position on screen
- * \param y y position on screen
- * \post dw->data contains an
- * \post dw->update contains an update function
- * \post dw->draw contains a drawing function
- * \post dw->finish is NULL
- */
 void
 animation_drawable(struct animation *an, struct drawable *dw, int x, int y);
 
--- a/libmlk-core/core/clock.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/clock.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,35 +19,13 @@
 #ifndef MOLKO_CORE_CLOCK_H
 #define MOLKO_CORE_CLOCK_H
 
-/**
- * \file clock.h
- * \brief Track elapsed time.
- * \ingroup basics
- */
-
-/**
- * \brief Clock structure.
- */
 struct clock {
-	unsigned int ticks;     /*!< (-) Time point on initialization. */
+	unsigned int ticks;
 };
 
-/**
- * Start the clock and track elapsed time.
- *
- * \pre clock != NULL
- * \param clock the clock
- */
 void
 clock_start(struct clock *clock);
 
-/**
- * Tell the measured time.
- *
- * \pre clock != NULL
- * \param clock the clock
- * \return the elapsed time in milliseconds
- */
 unsigned int
 clock_elapsed(const struct clock *clock);
 
--- a/libmlk-core/core/color.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/color.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,52 +19,10 @@
 #ifndef MOLKO_CORE_COLOR_H
 #define MOLKO_CORE_COLOR_H
 
-/**
- * \file color.h
- * \brief Basic color routines.
- */
-
-/**
- * Get red component of hexadecimal color.
- *
- * \param c the hexadecimal color
- * \return the red component
- */
 #define COLOR_R(c)              (c >> 24 & 0xff)
-
-/**
- * Get green component of hexadecimal color.
- *
- * \param c the hexadecimal color
- * \return the green component
- */
 #define COLOR_G(c)              (c >> 16 & 0xff)
-
-/**
- * Get blue component of hexadecimal color.
- *
- * \param c the hexadecimal color
- * \return the blue component
- */
 #define COLOR_B(c)              (c >> 8  & 0xff)
-
-/**
- * Get alpha component of hexadecimal color.
- *
- * \param c the hexadecimal color
- * \return the alpha component
- */
 #define COLOR_A(c)              (c       & 0xff)
-
-/**
- * Convert individual RGBA components into a hexadecimal color.
- *
- * \param r the red component
- * \param g the green component
- * \param b the blue component
- * \param a the alpha component
- * \return the hexadecimal color
- */
 #define COLOR_HEX(r, g, b, a)   \
         ((r << 24 & 0xff000000) | \
          (g << 16 & 0x00ff0000) | \
--- a/libmlk-core/core/core.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/core.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,28 +19,11 @@
 #ifndef MOLKO_CORE_CORE_H
 #define MOLKO_CORE_CORE_H
 
-/**
- * \file core.h
- *\brief libcore convenient header.
- */
-
 #include <stdbool.h>
 
-/**
- * Initialize the core library.
- *
- * \pre organization != NULL
- * \pre name != NULL
- * \param organization the name of the organization
- * \param name the game name
- * \return False on errors.
- */
 bool
 core_init(const char *organization, const char *name);
 
-/**
- * Close the core library.
- */
 void
 core_finish(void);
 
--- a/libmlk-core/core/drawable.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/drawable.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,168 +19,51 @@
 #ifndef MOLKO_CORE_DRAWABLE_H
 #define MOLKO_CORE_DRAWABLE_H
 
-/**
- * \file drawable.h
- * \brief Automatic drawable objects.
- */
-
 #include <stdbool.h>
 
-/**
- * \brief Maximum number of drawable object into a stack.
- */
-#define DRAWABLE_STACK_MAX      128
-
-/**
- * \brief Abstract drawable object.
- *
- * This structure is used to
- */
-struct drawable {
-	void *data;     /*!< (+&?) Drawable data. */
-	int x;          /*!< (+) X coordinate if necessary. */
-	int y;          /*!< (+) Y coordinate if necessary. */
+#define DRAWABLE_STACK_MAX (128)
 
-	/**
-	 * (+?) Update this drawable.
-	 *
-	 * \param dw the drawable object
-	 * \param ticks the number of ticks since last frame
-	 * \return true if object has ended
-	 */
+struct drawable {
+	void *data;
+	int x;
+	int y;
 	bool (*update)(struct drawable *dw, unsigned int ticks);
-
-	/**
-	 * (+?) Draw this drawable.
-	 *
-	 * \param dw the drawable object
-	 */
 	void (*draw)(struct drawable *dw);
-
-	/**
-	 * (+?) Called when drawable finished.
-	 *
-	 * \param act this action
-	 */
 	void (*end)(struct drawable *act);
-	
-	/**
-	 * (+?) Destroy the drawable if necessary.
-	 *
-	 * \note This function is optional and can be NULL.
-	 * \param dw the drawable object
-	 */
 	void (*finish)(struct drawable *dw);
 };
 
-/**
- * Shortcut for dw->update (if not NULL).
- *
- * \pre dw != NULL
- * \param dw the drawable object
- * \param ticks elapsed milliseconds since last frame
- * \return true if the drawable ended
- */
+struct drawable_stack {
+	struct drawable *objects[DRAWABLE_STACK_MAX];
+};
+
 bool
 drawable_update(struct drawable *dw, unsigned int ticks);
 
-/**
- * Shortcut for dw->draw (if not NULL).
- *
- * \pre dw != NULL
- * \param dw the drawable object
- */
 void
 drawable_draw(struct drawable *dw);
 
-/**
- * Shortcut for dw->end (if not NULL).
- *
- * \pre dw != NULL
- * \param dw the drawable object
- */
 void
 drawable_end(struct drawable *dw);
 
-/**
- * Shortcut for dw->finish (if not NULL).
- *
- * \pre dw != NULL
- * \param dw the drawable object
- */
 void
 drawable_finish(struct drawable *dw);
 
-/**
- * \brief Stack of drawable objects.
- *
- * This stack of drawable object can be used to store drawable objects within
- * a specific transition (state, battle, menu, etc).
- *
- * You can add, clear, update and draw them.
- */
-struct drawable_stack {
-	struct drawable *objects[DRAWABLE_STACK_MAX];   /*!< (+&?) Drawables. */
-};
-
-/**
- * Initialize the stack.
- *
- * \pre st != NULL
- * \param st the drawable stack
- */
 void
 drawable_stack_init(struct drawable_stack *st);
 
-/**
- * Add a drawable object into the stack.
- *
- * The drawable object must be kept alive until the stack uses it.
- *
- * \pre st != NULL
- * \pre dw != NULL
- * \param st the stack
- * \param dw the drawable to reference
- * \return True if the drawable was added correctly (enough space).
- */
 bool
 drawable_stack_add(struct drawable_stack *st, struct drawable *dw);
 
-/**
- * Update all drawable objects.
- *
- * Also remove drawable objects if they were finished.
- *
- * \pre st != NULL
- * \param st the drawable stack
- * \param ticks the number of ticks since last frame
- * \return True if all drawable were rendered.
- */
 bool
 drawable_stack_update(struct drawable_stack *st, unsigned int ticks);
 
-/**
- * Draw all drawable objects.
- *
- * \pre st != NULL
- * \param st the drawable stack
- */
 void
 drawable_stack_draw(struct drawable_stack *st);
 
-/**
- * Tells if there is any pending drawable in the stack.
- *
- * \pre st != NULL
- * \param st the stack
- * \return False if there is at least one drawable in the stack.
- */
 bool
 drawable_stack_completed(const struct drawable_stack *st);
 
-/**
- * Clear all drawable objects into the stack.
- */
 void
 drawable_stack_finish(struct drawable_stack *st);
 
--- a/libmlk-core/core/error.c	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/error.c	Thu Dec 03 09:06:52 2020 +0100
@@ -39,14 +39,14 @@
 	va_list ap;
 
 	va_start(ap, fmt);
-	verrorf(fmt, ap);
+	errorva(fmt, ap);
 	va_end(ap);
 
 	return false;
 }
 
 bool
-verrorf(const char *fmt, va_list ap)
+errorva(const char *fmt, va_list ap)
 {
 	assert(fmt);
 
--- a/libmlk-core/core/error.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/error.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,42 +19,16 @@
 #ifndef MOLKO_CORE_ERROR_H
 #define MOLKO_CORE_ERROR_H
 
-/**
- * \file error.h
- * \brief Error routines.
- * \ingroup basics
- */
-
 #include <stdarg.h>
 #include <stdbool.h>
 
-/**
- * Get the last error returned.
- *
- * \return The error string.
- */
 const char *
 error(void);
 
-/**
- * Set the game error with a printf-like format.
- *
- * \pre fmt != NULL
- * \param fmt the format string
- * \return Always false.
- */
 bool
 errorf(const char *fmt, ...);
 
-/**
- * Similar to \ref errorf.
- *
- * \pre fmt != NULL
- * \param fmt the format stinrg
- * \param ap the variadic arguments pointer
- * \return Always false.
- */
 bool
-verrorf(const char *fmt, va_list ap);
+errorva(const char *fmt, va_list ap);
 
 #endif /* !MOLKO_CORE_ERROR_H */
--- a/libmlk-core/core/event.c	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/event.c	Thu Dec 03 09:06:52 2020 +0100
@@ -120,7 +120,7 @@
 	{ SDLK_F23,             KEY_F23                 },
 	{ SDLK_F24,             KEY_F24                 },
 	{ SDLK_PRINTSCREEN,     KEY_PRINTSCREEN         },
-	{ SDLK_SCROLLLOCK,      KEY_SCROLLLOCK          },
+	{ SDLK_SCROLLLOCK,      KEY_SCROLL_LOCK         },
 	{ SDLK_PAUSE,           KEY_PAUSE               },
 	{ SDLK_INSERT,          KEY_INSERT              },
 	{ SDLK_HOME,            KEY_HOME                },
@@ -172,7 +172,7 @@
 	{ SDL_BUTTON_LEFT,      MOUSE_BUTTON_LEFT       },
 	{ SDL_BUTTON_MIDDLE,    MOUSE_BUTTON_MIDDLE     },
 	{ SDL_BUTTON_RIGHT,     MOUSE_BUTTON_RIGHT      },
-	{ -1,                   MOUSE_BUTTON_UNKNOWN    }
+	{ -1,                   MOUSE_BUTTON_NONE       }
 };
 
 static void
@@ -209,11 +209,11 @@
 convert_click(const SDL_Event *event, union event *ev)
 {
 	ev->type = event->type == SDL_MOUSEBUTTONDOWN ? EVENT_CLICKDOWN : EVENT_CLICKUP;
-	ev->click.button = MOUSE_BUTTON_UNKNOWN;
+	ev->click.button = MOUSE_BUTTON_NONE;
 	ev->click.x = event->button.x;
 	ev->click.y = event->button.y;
 
-	for (size_t i = 0; buttons[i].value != MOUSE_BUTTON_UNKNOWN; ++i) {
+	for (size_t i = 0; buttons[i].value != MOUSE_BUTTON_NONE; ++i) {
 		if (buttons[i].key == event->button.button) {
 			ev->click.button = buttons[i].value;
 			break;
--- a/libmlk-core/core/event.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/event.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,73 +19,46 @@
 #ifndef MOLKO_CORE_EVENT_H
 #define MOLKO_CORE_EVENT_H
 
-/**
- * \file event.h
- * \brief Event management.
- * \ingroup input
- */
-
 #include <stdbool.h>
 
 #include "key.h"
 #include "mouse.h"
 
-/**
- * \brief Kind of event.
- */
 enum event_type {
-	EVENT_CLICKDOWN,        /*!< Mouse click down (\ref event_click) */
-	EVENT_CLICKUP,          /*!< Mouse click released (\ref event_click) */
-	EVENT_KEYDOWN,          /*!< Single key down (\ref event_key) */
-	EVENT_KEYUP,            /*!< Single key released (\ref event_key) */
-	EVENT_MOUSE,            /*!< Mouse moved (\ref event_mouse) */
-	EVENT_QUIT,             /*!< Quit request */
+	EVENT_CLICKDOWN,
+	EVENT_CLICKUP,
+	EVENT_KEYDOWN,
+	EVENT_KEYUP,
+	EVENT_MOUSE,
+	EVENT_QUIT,
 };
 
-/**
- * \brief Key event.
- */
 struct event_key {
-	enum event_type type;           /*!< (+) EVENT_KEYDOWN or EVENT_KEYUP */
-	enum key key;                   /*!< (+) Which key */
+	enum event_type type;
+	enum key key;
 };
 
-/**
- * \brief Mouse motion event.
- */
 struct event_mouse {
-	enum event_type type;           /*!< (+) EVENT_MOUSE */
-	enum mouse_button buttons;      /*!< (+) OR'ed buttons that are pressed */
-	int x;                          /*!< (+) Mouse position in x */
-	int y;                          /*!< (+) Mouse position in y */
+	enum event_type type;
+	enum mouse_button buttons;
+	int x;
+	int y;
 };
 
-/**
- * \brief Mouse click event.
- */
 struct event_click {
-	enum event_type type;           /*!< (+) EVENT_CLICKDOWN or EVENT_CLICKUP */
-	enum mouse_button button;       /*!< (+) Unique button that was pressed */
-	int x;                          /*!< (+) Mouse position in x */
-	int y;                          /*!< (+) Mouse position in y */
+	enum event_type type;
+	enum mouse_button button;
+	int x;
+	int y;
 };
 
-/**
- * \brief Store events.
- */
 union event {
-	enum event_type type;           /*!< (+) Which kind of event */
-	struct event_key key;           /*!< (+) Key event */
-	struct event_mouse mouse;       /*!< (+) Mouse motion event */
-	struct event_click click;       /*!< (+) Mouse click event */
+	enum event_type type;
+	struct event_key key;
+	struct event_mouse mouse;
+	struct event_click click;
 };
 
-/**
- * Fetch the next event or return false if there are not.
- *
- * \param ev the event
- * \return True if the event was filled or false otherwise.
- */
 bool
 event_poll(union event *ev);
 
--- a/libmlk-core/core/font.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/font.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,134 +19,39 @@
 #ifndef MOLKO_CORE_FONT_H
 #define MOLKO_CORE_FONT_H
 
-/**
- * \file font.h
- * \brief Basic font management.
- * \ingroup drawing
- */
-
 #include <stdbool.h>
 #include <stddef.h>
 
 struct texture;
 
-/**
- * \brief Font style for rendering.
- */
 enum font_style {
-	FONT_STYLE_ANTIALIASED,         /*!< Pretty antialiasing looking. */
-	FONT_STYLE_NONE                 /*!< No antialiasing. */
+	FONT_STYLE_ANTIALIASED,
+	FONT_STYLE_NONE
 };
 
-/**
- * \brief Font object.
- */
 struct font {
-	enum font_style style;          /*!< (+) Style for rendering. */
-	void *handle;                   /*!< (*) Native handle. */
+	enum font_style style;
+	void *handle;
 };
 
-/**
- * Open font from path file.
- *
- * \pre font != NULL
- * \pre path != NULL
- * \param font the font to initialize
- * \param path the path to the font
- * \param size the desired size
- * \return False on errors.
- */
 bool
 font_open(struct font *font, const char *path, unsigned int size);
 
-/**
- * Open font from memory buffer.
- *
- * \pre font != NULL
- * \pre buffer != NULL
- * \param font the font to initialize
- * \param buffer the memory buffer
- * \param buflen the memory buffer length
- * \param size the desired size
- * \warning The buffer must remain valid until font is closed
- * \return False on errors.
- */
 bool
 font_openmem(struct font *font, const void *buffer, size_t buflen, unsigned int size);
 
-/**
- * Convenient shortcut to shallow copy src into dst.
- *
- * Use this function when you want your own local font to update its attributes
- * without changing the calling site.
- *
- * This is a shortcut to `memcpy(dst, src, sizeof (*src))`.
- *
- * \pre dst != NULL
- * \param dst the destination font
- * \param src the source font (may be NULL)
- * \note Internal handle points to the same pointer, do not use \ref font_finish
- *       on the destination.
- */
-void
-font_shallow(struct font *dst, const struct font *src);
-
-/**
- * Tells if the font was properly opened.
- *
- * \param font the font to check (may be NULL)
- * \return True if the native handle was opened.
- */
 bool
 font_ok(const struct font *font);
 
-/**
- * Render some text into the texture.
- *
- * This function use the current color/style and other properties in the font
- * to render the texture.
- *
- * \pre font_ok(font)
- * \pre tex != NULL
- * \param font the font to use
- * \param tex the texture to generate
- * \param text the UTF-8 text
- * \param color the foreground color
- * \return False on errors.
- */
 bool
 font_render(struct font *font, struct texture *tex, const char *text, unsigned int color);
 
-/**
- * Get the maximum height for all glyphs.
- *
- * \pre font_ok(font)
- * \param font the font handle
- * \return the height in pixels
- */
 unsigned int
 font_height(const struct font *font);
 
-/**
- * Compute the text size required with this font.
- *
- * \pre font_ok(font)
- * \pre text != NULL
- * \param font the font object
- * \param text the UTF-8 text
- * \param w pointer to width (may be NULL)
- * \param h pointer to height (may be NULL)
- * \return False in case of error and pointers to w and h are left unmodified.
- */
 bool
 font_query(const struct font *font, const char *text, unsigned int *w, unsigned int *h);
 
-/**
- * Close the font.
- *
- * \pre font != NULL
- * \param font the font handle
- */
 void
 font_finish(struct font *font);
 
--- a/libmlk-core/core/game.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/game.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,11 +19,6 @@
 #ifndef MOLKO_CORE_GAME_H
 #define MOLKO_CORE_GAME_H
 
-/**
- * \file game.h
- * \brief Main game object.
- */
-
 #include <stdbool.h>
 
 #include "inhibit.h"
@@ -32,73 +27,32 @@
 
 union event;
 
-/**
- * \brief Main game object.
- */
 struct game {
 	/* Inhibition */
-	enum inhibit inhibit;           /*!< (+) What to disable. */
+	enum inhibit inhibit;
 
 	/* Game states. */
-	struct state *state;            /*!< (-) Current state  */
-	struct state *state_next;       /*!< (-) Next state */
+	struct state *state;
+	struct state *state_next;
 };
 
-/**
- * Global game object.
- */
 extern struct game game;
 
-/**
- * Request to change state.
- *
- * This function will only update state after the next \ref  game_update call
- * unless quick is set to true.
- *
- * \warning Passing true to quick will immediately call end/finish state
- *          functions which can destroy your state while still running it.
- * \pre state != NULL
- * \param state the new state
- * \param quick quickly change the state
- */
 void
 game_switch(struct state *state, bool quick);
 
-/**
- * Handle input event.
- *
- * \param event the event
- */
 void
 game_handle(const union event *event);
 
-/**
- * Update the game state.
- *
- * \param ticks the number of milliseconds between last frame
- */
 void
 game_update(unsigned int ticks);
 
-/**
- * Draw the game using the current state.
- */
 void
 game_draw(void);
 
-/**
- * Start a game loop that calls game_handle, game_update and game_draw until
- * game_quit has been called.
- */
 void
 game_loop(void);
 
-/**
- * Stop the game.
- *
- * This will effectively stop the current state but the main loop may continue
- * until it has completed.
- */
 void
 game_quit(void);
 
--- a/libmlk-core/core/image.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/image.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,41 +19,14 @@
 #ifndef MOLKO_CORE_IMAGE_H
 #define MOLKO_CORE_IMAGE_H
 
-/**
- * \file image.h
- * \brief Basic image management.
- * \ingroup drawing
- */
-
 #include <stdbool.h>
 #include <stddef.h>
 
 struct texture;
 
-/**
- * Open a file from a path.
- *
- * \pre tex != NULL
- * \pre path != NULL
- * \param tex the texture to initialize
- * \param path the path to the file
- * \return False on errors.
- */
 bool
 image_open(struct texture *tex, const char *path);
 
-/**
- * Open a file from a memory buffer.
- *
- * The buffer must be valid until the image is no longer used.
- *
- * \pre tex != NULL
- * \pre buffer != NULL
- * \param tex the texture to initialize
- * \param buffer the memory buffer
- * \param size the memory size
- * \return False on errors.
- */
 bool
 image_openmem(struct texture *tex, const void *buffer, size_t size);
 
--- a/libmlk-core/core/inhibit.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/inhibit.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,37 +19,10 @@
 #ifndef MOLKO_CORE_INHIBIT_H
 #define MOLKO_CORE_INHIBIT_H
 
-/**
- * \file inhibit.h
- * \brief Disable specific game behavior.
- */
-
-struct action;
-
-/**
- * \brief Game inhibition.
- *
- * This enum is used to alter the game behavior.
- */
 enum inhibit {
-	/**
-	 * Nothing.
-	 */
 	INHIBIT_NONE,
-
-	/**
-	 * Disable input handling in current state.
-	 */
 	INHIBIT_STATE_INPUT        = (1 << 0),
-
-	/**
-	 * Disable current state updates.
-	 */
 	INHIBIT_STATE_UPDATE       = (1 << 1),
-
-	/**
-	 * Disable current state rendering.
-	 */
 	INHIBIT_STATE_DRAW         = (1 << 2)
 };
 
--- a/libmlk-core/core/key.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/key.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,15 +19,6 @@
 #ifndef MOLKO_CORE_KEY_H
 #define MOLKO_CORE_KEY_H
 
-/**
- * \file key.h
- * \brief Keyboard definitions.
- * \ingroup input
- */
-
-/**
- * \brief Key codes.
- */
 enum key {
 	KEY_UNKNOWN,
 	KEY_ENTER,
@@ -125,7 +116,7 @@
 	KEY_F23,
 	KEY_F24,
 	KEY_PRINTSCREEN,
-	KEY_SCROLLLOCK,
+	KEY_SCROLL_LOCK,
 	KEY_PAUSE,
 	KEY_INSERT,
 	KEY_HOME,
@@ -171,21 +162,15 @@
 	KEY_RSUPER,
 };
 
-/**
- * \brief Keybord modifiers.
- *
- * This enumeration is usually stored as OR'ed flags as several modifiers can
- * be pressed at a time.
- */
 enum keymod {
-	KEYMOD_LSHIFT   = 1 << 0,       /*!< Left shift */
-	KEYMOD_LCTRL    = 1 << 1,       /*!< Left control */
-	KEYMOD_LALT     = 1 << 2,       /*!< Left alt */
-	KEYMOD_LSUPER   = 1 << 3,       /*!< Left super (logo) */
-	KEYMOD_RSHIFT   = 1 << 4,       /*!< Right shift */
-	KEYMOD_RCTRL    = 1 << 5,       /*!< Right control */
-	KEYMOD_RALT     = 1 << 6,       /*!< Right alt */
-	KEYMOD_RSUPER   = 1 << 7        /*!< Right super (logo) */
+	KEYMOD_LSHIFT   = 1 << 0,
+	KEYMOD_LCTRL    = 1 << 1,
+	KEYMOD_LALT     = 1 << 2,
+	KEYMOD_LSUPER   = 1 << 3,
+	KEYMOD_RSHIFT   = 1 << 4,
+	KEYMOD_RCTRL    = 1 << 5,
+	KEYMOD_RALT     = 1 << 6,
+	KEYMOD_RSUPER   = 1 << 7 
 };
 
 #endif /* !MOLKO_CORE_KEY_H */
--- a/libmlk-core/core/maths.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/maths.h	Thu Dec 03 09:06:52 2020 +0100
@@ -21,22 +21,6 @@
 
 #include <stdbool.h>
 
-/**
- * \file maths.h
- * \brief Basic maths.
- */
-
-/**
- * Tells if a coordinate is within a rectangle region.
- *
- * \param x the region start
- * \param y the region start
- * \param w the region width
- * \param h the region height
- * \param px the point to test
- * \param py the point to test
- * \return True if within the region
- */
 bool
 maths_is_boxed(int x, int y, unsigned int w, unsigned int h, int px, int py);
 
--- a/libmlk-core/core/mouse.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/mouse.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,25 +19,11 @@
 #ifndef MOLKO_CORE_MOUSE_H
 #define MOLKO_CORE_MOUSE_H
 
-/**
- * \file mouse.h
- * \brief Mouse definitions.
- * \ingroup input
- */
-
-/**
- * \brief Buttons from mouse.
- *
- * This enumeration is used as both flags or constants. For example when the
- * user press one button on the mouse it generates one constant event. On the
- * other hand, while moving the mouse the user may have one or more buttons
- * pressed, thus the OR'ed combination.
- */
 enum mouse_button {
-	MOUSE_BUTTON_UNKNOWN    = 0,            /*!< No buttons pressed */
-	MOUSE_BUTTON_LEFT       = (1 << 0),     /*!< Left button pressed */
-	MOUSE_BUTTON_MIDDLE     = (1 << 1),     /*!< Middle button pressed */
-	MOUSE_BUTTON_RIGHT      = (1 << 2)      /*!< Right button pressed */
+	MOUSE_BUTTON_NONE       = 0,
+	MOUSE_BUTTON_LEFT       = (1 << 0),
+	MOUSE_BUTTON_MIDDLE     = (1 << 1),
+	MOUSE_BUTTON_RIGHT      = (1 << 2)
 };
 
 #endif /* !MOLKO_CORE_MOUSE_H */
--- a/libmlk-core/core/music.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/music.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,117 +19,42 @@
 #ifndef MOLKO_CORE_MUSIC_H
 #define MOLKO_CORE_MUSIC_H
 
-/**
- * \file music.h
- * \brief Music support.
- *
- * This module provide support for playing music. In contrast to sounds only one
- * music can be played at a time.
- */
-
 #include <stdbool.h>
 #include <stddef.h>
 
-/**
- * \brief Music flags.
- */
 enum music_flags {
-	MUSIC_NONE,                     /*!< No flags. */
-	MUSIC_LOOP      = (1 << 0)      /*!< Loop the music. */
+	MUSIC_NONE      = 0,
+	MUSIC_LOOP      = (1 << 0)
 };
 
-/**
- * \brief Music object handle.
- */
 struct music {
-	void *handle;                   /*!< (*) Implementation handle. */
+	void *handle;
 };
 
-/**
- * Open a music file.
- *
- * \pre mus != NULL
- * \pre path != NULL
- * \param mus the music object to initialize
- * \param path the path to the music file
- * \return False on errors.
- */
 bool
 music_open(struct music *mus, const char *path);
 
-/**
- * Open a music from a buffer.
- *
- * \pre mus != NULL
- * \pre buffer != NULL
- * \param mus the music object to initialize
- * \param buffer the buffer
- * \param buffersz the buffer size
- * \return False on errors.
- * \warning The buffer must exists until the sound object is closed.
- */
 bool
 music_openmem(struct music *mus, const void *buffer, size_t buffersz);
 
-/**
- * Check if this music handle is properly loaded.
- *
- * \param mus the music to check (may be NULL)
- */
 bool
 music_ok(const struct music *mus);
 
-/**
- * Start playing the given music
- *
- * This function will resume the playback since the beginning and will stop the
- * current music. If the music playing is currently fading out this function
- * will block until it has finished.
- *
- * \pre mus != NULL
- * \param mus the music to start
- * \param flags optional flags
- * \param fadein a fade in delay in milliseconds (0 to disable)
- * \return False on errors.
- */
 bool
 music_play(struct music *mus, enum music_flags flags, unsigned int fadein);
 
-/**
- * Tells if music is playing.
- *
- * You can call this function with any music even one that is not currently
- * playing.
- */
 bool
 music_playing(void);
 
-/**
- * Pause the music playback.
- */
 void
 music_pause(void);
 
-/**
- * Resume the music playback.
- */
 void
 music_resume(void);
 
-/**
- * Stop the sound music.
- *
- * \param fadeout a fade out delay in milliseconds (0 to disable)
- */
 void
 music_stop(unsigned int fadeout);
 
-/**
- * Close the associated resources.
- *
- * \pre mus != NULL
- * \param mus the music object
- */
 void
 music_finish(struct music *mus);
 
--- a/libmlk-core/core/painter.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/painter.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,130 +19,47 @@
 #ifndef MOLKO_CORE_PAINTER_H
 #define MOLKO_CORE_PAINTER_H
 
-/**
- * \file painter.h
- * \brief Basic drawing routines.
- * \ingroup drawing
- */
-
 #include <stdbool.h>
 
 struct texture;
 
-/**
- * Give the current texture being used for rendering, maybe NULL if the
- * rendering is on root.
- *
- * \return Texture or NULL.
- */
 struct texture *
 painter_get_target(void);
 
-/**
- * Set the rendering context to the given texture.
- *
- * Since this function change an internal global variable it is strongly
- * encouraged to store a local backup of the current texture using \a
- * painter_get_target and call this function with it afterwards.
- *
- * If texture is NULL, use default context aka the window.
- *
- * \param tex the texture
- * \see \ref PAINTER_BEGIN
- * \see \ref PAINTER_END
- */
 void
 painter_set_target(struct texture *tex);
 
-/**
- * Get the current drawing color.
- *
- * \return the color in RRGGBBAA format
- */
 unsigned long
 painter_get_color(void);
 
-/**
- * Set the rendering drawing color.
- *
- * \param color in RRGGBBAA format
- */
 void
 painter_set_color(unsigned long color);
 
-/**
- * Draw a line.
- *
- * \param x1 first X coordinate
- * \param y1 first Y coordinate
- * \param x2 second X coordinate
- * \param y2 second Y coordinate
- */
 void
 painter_draw_line(int x1, int y1, int x2, int y2);
 
-/**
- * Draw a pixel point.
- *
- * \param x the X coordinate
- * \param y the Y coordinate
- */
 void
 painter_draw_point(int x, int y);
 
-/**
- * Draw a rectangle
- *
- * \param x the X coordinate
- * \param y the Y coordinate
- * \param w the rectangle width
- * \param h the rectangle height
- */
 void
 painter_draw_rectangle(int x, int y, unsigned int w, unsigned int h);
 
-/**
- * Draw a circle.
- *
- * \param x the X coordinate
- * \param y the Y coordinate
- * \param radius the radius size
- */
 void
 painter_draw_circle(int x, int y, int radius);
 
-/**
- * Clear the window.
- */
 void
 painter_clear(void);
 
-/**
- * Present the window, only call this function one time in the main loop.
- */
 void
 painter_present(void);
 
-/**
- * Use this macro to start painting on the texture to store the current
- * rendering context and put it back afterwards.
- *
- * \pre tex != NULL
- * \param tex the texture to use
- * \see \ref PAINTER_END
- */
-#define PAINTER_BEGIN(tex    )                                          \
+#define PAINTER_BEGIN(tex)                                              \
 do {                                                                    \
         struct texture *__current_texture__;                            \
                                                                         \
         __current_texture__ = painter_get_target();                     \
         painter_set_target((tex))
 
-/**
- * Use this macro at the end of rendering into a given texture.
- *
- * \see \ref PAINTER_BEGIN
- */
 #define PAINTER_END()                                                   \
         painter_set_target(__current_texture__);                        \
 } while (0)
--- a/libmlk-core/core/panic.c	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/panic.c	Thu Dec 03 09:06:52 2020 +0100
@@ -46,19 +46,19 @@
 	 * called.
 	 */
 	va_start(ap, fmt);
-	verrorf(fmt, ap);
+	errorva(fmt, ap);
 	va_end(ap);
 
 	panic();
 }
 
 void
-vpanicf(const char *fmt, va_list ap)
+panicva(const char *fmt, va_list ap)
 {
 	assert(fmt);
 	assert(panic_handler);
 
-	verrorf(fmt, ap);
+	errorva(fmt, ap);
 	panic();
 }
 
--- a/libmlk-core/core/panic.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/panic.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,66 +19,18 @@
 #ifndef MOLKO_CORE_PANIC_H
 #define MOLKO_CORE_PANIC_H
 
-/**
- * \file panic.h
- * \brief Unrecoverable error handling.
- * \ingroup basics
- *
- * This set of functions should be used to detect runtime errors that are
- * unexpected. They should be used only when the game cannot continue because
- * it is in a unrecoverable state.
- *
- * Examples of appropriate use cases:
- *
- * - Game saved data is corrupt,
- * - Assets are missing,
- * - No more memory.
- *
- * In other contexts, use asserts to indicates programming error and
- * appropriate solutions to recover the game otherwise.
- */
+#include <stdarg.h>
+#include <stdnoreturn.h>
 
-#include <stdarg.h>
-
-/**
- * \brief Global panic handler.
- *
- * The default implementation shows the last error and exit with code 1. The
- * function must not return so you have to implement a setjmp/longjmp or a
- * exception to be thrown.
- *
- * If the user defined function returns, panic routines will finally exit with
- * code 1.
- */
 extern void (*panic_handler)(void);
 
-/**
- * Terminate the program using the \ref panic_handler routine.
- *
- * This function will first set the global error with the provided format
- * string and then call the handler.
- *
- * \pre fmt != NULL
- * \param fmt the printf(3) format string
- */
-void
+noreturn void
 panicf(const char *fmt, ...);
 
-/**
- * Similar to \ref panicf but with a arguments pointer.
- *
- * \pre fmt != NULL
- * \param fmt the printf(3) format string
- * \param ap the arguments pointer
- */
-void
-vpanicf(const char *fmt, va_list ap);
+noreturn void
+panicva(const char *fmt, va_list ap);
 
-/**
- * Similar to \ref panicf but use last error stored using \ref error.h
- * routines.
- */
-void
+noreturn void
 panic(void);
 
 #endif /* !MOLKO_CORE_PANIC_H */
--- a/libmlk-core/core/save.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/save.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,135 +19,43 @@
 #ifndef MOLKO_CORE_SAVE_H
 #define MOLKO_CORE_SAVE_H
 
-/**
- * \file save.h
- * \brief Save functions.
- *
- * This module provides several functions to save the game data into a database.
- *
- * Database can be opened in read only mode (\ref SAVE_MODE_READ) which will
- * return an error if not present or write mode (\ref SAVE_MODE_WRITE) which
- * will create and initialize a database if not present on disk.
- */
-
 #include <stdbool.h>
 #include <time.h>
 
-/**
- * \brief Max property key.
- */
 #define SAVE_PROPERTY_KEY_MAX   (64)
-
-/**
- * \brief Max property value.
- */
 #define SAVE_PROPERTY_VALUE_MAX (1024)
 
-/**
- * \brief Save database handle.
- */
 struct save {
-	time_t created; /*!< (-) Date when the save was created. */
-	time_t updated; /*!< (-) Date when it was last updated. */
-	void *handle;   /*!< (*) Private handle. */
+	time_t created;
+	time_t updated;
+	void *handle;
 };
 
-/**
- * \brief Open mode.
- */
 enum save_mode {
-	SAVE_MODE_READ, /*!< Only try to read (no creation). */
-	SAVE_MODE_WRITE /*!< Open for both reading and writing */
+	SAVE_MODE_READ,
+	SAVE_MODE_WRITE
 };
 
-/**
- * \brief Mapping for the property table.
- */
 struct save_property {
-	/**
-	 * (+) Property key to set.
-	 */
 	char key[SAVE_PROPERTY_KEY_MAX + 1];
-
-	/**
-	 * (+) Property value to set.
-	 */
 	char value[SAVE_PROPERTY_VALUE_MAX + 1];
 };
 
-/**
- * Open a database by index.
- *
- * This function use the preferred path to store local files under the user
- * home directory. The parameter idx specifies the save slot to use.
- *
- * \pre db != NULL
- * \param db the database to initialize
- * \param idx the save slot
- * \param mode the mode
- * \return False on error.
- */
 bool
 save_open(struct save *db, unsigned int idx, enum save_mode mode);
 
-/**
- * Open the save slot specified by path.
- *
- * \pre db != NULL
- * \pre path != NULL
- * \param db the database to initialize
- * \param path the path to the save slot
- * \param mode the mode
- * \return False on error.
- */
 bool
 save_open_path(struct save *db, const char *path, enum save_mode mode);
 
-/**
- * Sets an arbitrary property.
- *
- * If the property already exists, replace it.
- *
- * \pre db != NULL
- * \pre prop != NULL
- * \param db the database
- * \param prop the property to set
- * \return False on error.
- */
 bool
 save_set_property(struct save *db, const struct save_property *prop);
 
-/**
- * Get a property.
- *
- * Call this function by setting prop->key to the desired key to get.
- *
- * \pre db != NULL
- * \param db the database
- * \param prop the property to retrieve
- * \return False on error and prop->value is left untouched
- */
 bool
 save_get_property(struct save *db, struct save_property *prop);
 
-/**
- * Remove a property.
- *
- * \pre db != NULL
- * \pre prop != NULL
- * \param db the database
- * \param prop the property to remove
- * \return false on error
- */
 bool
 save_remove_property(struct save *db, const struct save_property *prop);
 
-/**
- * Close the save slot.
- *
- * \pre db != NULL
- * \param db the database to close
- */
 void
 save_finish(struct save *db);
 
--- a/libmlk-core/core/script.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/script.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,135 +19,42 @@
 #ifndef MOLKO_CORE_SCRIPT_H
 #define MOLKO_CORE_SCRIPT_H
 
-/**
- * \file script.h
- * \brief Convenient sequence of actions.
- * \ingroup actions
- *
- * Those routines wrap individual actions into a sequence of actions into an
- * action itself.
- *
- * This is convenient for scenarios where you need to specify several
- * sequential actions that neet to wait before continuing.
- *
- * In a nutshell, to write a scenario you should:
- *
- * 1. Create a script with see \ref script_init,
- * 2. Create one or more actions and append with \ref script_append,
- *
- * \warning You must always call \ref script_init before using this object.
- */
-
 #include <stdbool.h>
 #include <stddef.h>
 
+#define SCRIPT_ACTION_MAX (128)
+
 struct action;
 
 union event;
 
-/**
- * \brief Maximum number of actions in a script.
- */
-#define SCRIPT_ACTION_MAX       (128)
-
-/**
- * \brief Sequence of actions and state holder.
- *
- * Setup the array actions within the structure for each action you want to run
- * in order. You can use the convenient \ref script_append instead. If you do
- * manually don't forget to adjust actionsz field accordingly.
- */
 struct script {
-	struct action *actions[SCRIPT_ACTION_MAX];	/*!< (+&?) Array of actions. */
-	size_t actionsz;                                /*!< (-) Number of actions in array. */
-	size_t cur;                                     /*!< (-) Current action index.*/
+	struct action *actions[SCRIPT_ACTION_MAX];
+	size_t actionsz;
+	size_t cur;
 };
 
-/**
- * Initialize a script.
- *
- * This is not necessary if you zero'ed the structure.
- *
- * \pre s != NULL
- * \param s the script
- */
 void
 script_init(struct script *s);
 
-/**
- * Append a new action to the script.
- *
- * The action must be kept alive until the script is no longer used.
- *
- * \pre s != NULL
- * \pre a != NULL
- * \param s the script
- * \param a the action to reference
- * \return false if unable to append
- */
 bool
 script_append(struct script *s, struct action *a);
 
-/**
- * Handle the event into the current action.
- *
- * \pre s != NULL
- * \pre ev != NULL
- * \param s the script
- * \param ev the event
- */
 void
 script_handle(struct script *s, const union event *ev);
 
-/**
- * Update the current action.
- *
- * \pre s != NULL
- * \param s the script
- * \param ticks the number of milliseconds since last frame
- * \return true if the script completed
- */
 bool
 script_update(struct script *s, unsigned int ticks);
 
-/**
- * Draw the current action.
- *
- * \pre s != NULL
- * \param s the script
- */
 void
 script_draw(struct script *s);
 
-/**
- * Tells if the script is terminated.
- *
- * \pre s != NULL
- * \param s the script
- * \return true if all action were completed
- */
 bool
 script_completed(const struct script *s);
 
-/**
- * Destroy all the actions into the script.
- *
- * \pre s != NULL
- * \param s the script
- */
 void
 script_finish(struct script *s);
 
-/**
- * Create an action from the script itself for use into the game.
- *
- * The script must be kept alive until the action is no longer needed.
- *
- * \pre s != NULL
- * \pre dst != NULL
- * \param s the script
- * \param dst the action to build with the script
- */
 void
 script_action(struct script *s, struct action *dst);
 
--- a/libmlk-core/core/sound.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/sound.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,108 +19,38 @@
 #ifndef MOLKO_CORE_SOUND_H
 #define MOLKO_CORE_SOUND_H
 
-/**
- * \file sound.h
- * \brief Sound support.
- */
-
 #include <stdbool.h>
 #include <stddef.h>
 
-/**
- * \brief Number of channels allocated.
- */
-#define SOUND_CHANNELS_MAX      (256)
+
+#define SOUND_CHANNELS_MAX (256)
 
-/**
- * \brief Sound chunk.
- */
 struct sound {
-	void *handle;                   /*!< (*) Native handle. */
-	int channel;                    /*!< (*) Current channel. */
+	void *handle;
+	int channel;
 };
 
-/**
- * Open a sound audio file.
- *
- * \pre snd != NULL
- * \pre path != NULL
- * \param snd the sound object to initialize
- * \param path the path to the audio file
- * \return False on errors.
- */
 bool
 sound_open(struct sound *snd, const char *path);
 
-/**
- * Open a sound audio from a buffer.
- *
- * \pre snd != NULL
- * \pre buffer != NULL
- * \param snd the sound object to initialize
- * \param buffer the buffer
- * \param buffersz the buffer size
- * \return False on errors.
- * \warning The buffer must exists until the sound object is closed.
- */
 bool
 sound_openmem(struct sound *snd, const void *buffer, size_t buffersz);
 
-/**
- * Check if this sound handle is properly loaded.
- *
- * \param snd the sound to check (may be NULL)
- */
 bool
 sound_ok(const struct sound *snd);
 
-/**
- * Start playing the sound.
- *
- * This function will resume the playback since the beginning.
- *
- * \pre sound_ok(snd)
- * \param snd the sound object
- * \param channel the channel to use (-1 for a default)
- * \param fadein a fade in delay in milliseconds (0 to disable)
- * \return False on errors.
- */
 bool
 sound_play(struct sound *snd, int channel, unsigned int fadein);
 
-/**
- * Pause the given sound or all sounds currently playing.
- *
- * \param snd the sound object (or NULL to pause all)
- */
 void
 sound_pause(struct sound *snd);
 
-/**
- * Resume the current sound or all sounds currently paused.
- *
- * \param snd the sound object (or NULL to resume all)
- */
 void
 sound_resume(struct sound *snd);
 
-/**
- * Stop the sound music or all sounds currently playing.
- *
- * \pre sound_ok(snd)
- * \param snd the sound object
- * \param fadeout a fade out delay in milliseconds (0 to disable)
- */
 void
 sound_stop(struct sound *snd, unsigned int fadeout);
 
-/**
- * Close the associated resources. This will also stop the playback of the
- * given sound.
- *
- * \pre snd != NULL
- * \param snd the sound object
- */
 void
 sound_finish(struct sound *snd);
 
--- a/libmlk-core/core/sprite.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/sprite.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,92 +19,27 @@
 #ifndef MOLKO_CORE_SPRITE_H
 #define MOLKO_CORE_SPRITE_H
 
-/**
- * \file sprite.h
- * \brief Image sprites.
- * \ingroup drawing
- *
- * The sprite is a module to help rendering a large image that is split into
- * individual parts. This improves memory usage as several images are loaded
- * in a unique one instead of individual parts.
- *
- * Example of sprite.
- *
- * ```
- * +---+---+---+
- * | 0 | 1 | 2 |
- * +---+---+---+
- * | 3 | 4 | 5 |
- * +---+---+---+
- * ```
- *
- * If an image is designed like this grid, it contains three columns and 2 rows.
- *
- * \note The image may not contain space, margins or padding within each cell.
- */
-
 #include <stdbool.h>
 
 struct texture;
 
-/**
- * \brief Sprite structure.
- */
 struct sprite {
-	struct texture *texture;        /*!< (+&) Texture to access. */
-	unsigned int cellw;             /*!< (-) Width per cell. */
-	unsigned int cellh;             /*!< (-) Height per cell. */
-	unsigned int nrows;             /*!< (-) Number of rows. */
-	unsigned int ncols;             /*!< (-) Number of columns. */
+	struct texture *texture;
+	unsigned int cellw;
+	unsigned int cellh;
+	unsigned int nrows;
+	unsigned int ncols;
 };
 
-/**
- * Initialize a sprite.
- *
- * The sprite does not take ownership of texture and must be valid until the
- * sprite is no longer used.
- *
- * This function is only provided as convenience, user may initialize the
- * sprite by itself if wanted.
- *
- * The fields `nrows' and `ncols' will be determined automatically from the
- * texture size.
- *
- * \pre sprite != NULL
- * \pre tex != NULL && texture_ok(tex)
- * \param sprite the sprite to initialize
- * \param tex the texture
- * \param cellw the width per cell in pixels
- * \param cellh the height per cell in pixels
- */
 void
 sprite_init(struct sprite *sprite,
             struct texture *tex,
             unsigned int cellw,
             unsigned int cellh);
 
-/**
- * Tells if the sprite has a texture and isn't null sized.
- *
- * \param sprite the sprite to check (may be NULL)
- * \return True if it is initialized correctly.
- */
 bool
 sprite_ok(const struct sprite *sprite);
 
-/**
- * Draw the sprite component from row `r' and column `c'.
- *
- * \pre r < sprite->nrows
- * \pre c < sprite->ncols
- * \pre sprite != NULL
- * \param sprite the sprite to draw
- * \param r the row number
- * \param c the column number
- * \param x the X destination
- * \param y the Y destination
- * \return False in case of rendering error.
- */
 bool
 sprite_draw(const struct sprite *sprite, unsigned int r, unsigned int c, int x, int y);
 
--- a/libmlk-core/core/state.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/state.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,136 +19,33 @@
 #ifndef MOLKO_CORE_STATE_H
 #define MOLKO_CORE_STATE_H
 
-/**
- * \file state.h
- * \brief Abstract state.
- * \ingroup states
- *
- * The state module is a facility that allows changing game context with ease
- * using a single \ref game_switch routine.
- *
- * The user creates any state required, set appropriate functions if needed and
- * place them in the game using \ref game_switch. Then function \ref game_handle
- * \ref game_update and finally \ref game_draw.
- */
-
 union event;
 
-/**
- * \brief Abstract state.
- */
 struct state {
-	/**
-	 * (+&?) Optional user data.
-	 */
 	void *data;
-
-	/**
-	 * (+?) This function is called when the state is about to begin.
-	 *
-	 * \param state this state
-	 */
 	void (*start)(struct state *state);
-
-	/**
-	 * (+) This function is called for each event that happened.
-	 *
-	 * \param state this state
-	 * \param ev the event
-	 */
 	void (*handle)(struct state *state, const union event *ev);
-
-	/**
-	 * (+) Update the state.
-	 *
-	 * This function is called to update the game, with the number of
-	 * milliseconds since the last frame.
-	 *
-	 * \param state this state
-	 * \param ev the event
-	 */
 	void (*update)(struct state *state, unsigned int ticks);
-
-	/**
-	 * (+) This function is supposed to draw the game.
-	 *
-	 * \param state this state
-	 */
 	void (*draw)(struct state *state);
-
-	/**
-	 * (+?) This function is called when the state is about to be switched
-	 * away from.
-	 *
-	 * This function is not called in case `quick` is set to true when
-	 * calling \ref game_switch function.
-	 *
-	 * \param state this state
-	 */
 	void (*end)(struct state *state);
-
-	/**
-	 * (+?) This function is called to close resources if necessary.
-	 *
-	 * \param state the state
-	 */
 	void (*finish)(struct state *state);
 };
 
-/**
- * Shortcut for state->start (if not NULL)
- *
- * \pre state != NULL
- * \param state the state
- */
 void
 state_start(struct state *state);
 
-/**
- * Shortcut for state->handle (if not NULL)
- *
- * \pre state != NULL
- * \pre ev != NULL
- * \param state the state
- * \param ev the event
- */
 void
 state_handle(struct state *state, const union event *ev);
 
-/**
- * Shortcut for state->update (if not NULL)
- *
- * \pre state != NULL
- * \param state the state
- * \param ticks elapsed milliseconds since last frame
- */
 void
 state_update(struct state *state, unsigned int ticks);
 
-/**
- * Shortcut for state->draw (if not NULL)
- *
- * \pre state != NULL
- * \param state the state
- */
 void
 state_draw(struct state *state);
 
-/**
- * Shortcut for state->end (if not NULL)
- *
- * \pre state != NULL
- * \param state the state
- */
 void
 state_end(struct state *state);
 
-/**
- * Shortcut for state->finish (if not NULL)
- *
- * \pre state != NULL
- * \param state the state
- */
 void
 state_finish(struct state *state);
 
--- a/libmlk-core/core/sys.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/sys.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,56 +19,22 @@
 #ifndef MOLKO_CORE_SYS_H
 #define MOLKO_CORE_SYS_H
 
-/**
- * \file sys.h
- * \brief System routines.
- * \ingroup basics
- */
-
 #include <stdarg.h>
 #include <stdbool.h>
 
-/**
- * \brief Kind of special directories.
- */
 enum sys_dir {
-	SYS_DIR_BIN,            /*!< Path to binaries. */
-	SYS_DIR_DATA,           /*!< Directory containing data. */
-	SYS_DIR_LOCALE,         /*!< Path to NLS catalogs. */
-	SYS_DIR_SAVE,           /*!< User directory for save databases. */
+	SYS_DIR_BIN,
+	SYS_DIR_DATA,
+	SYS_DIR_LOCALE,
+	SYS_DIR_SAVE,
 };
 
-/**
- * Initialize the system.
- *
- * This function is automatically called from \ref core_init and thus not
- * necessary from user.
- *
- * \pre organization != NULL
- * \pre name != NULL
- * \param organization the name of the organization
- * \param name the game name
- * \return False on error.
- */
 bool
 sys_init(const char *organization, const char *name);
 
-/**
- * Get a system or user directory preferred for this platform.
- *
- * \pre kind must be valid
- * \param kind kind of special directory
- * \return A non-NULL pointer to a static storage path.
- */
 const char *
 sys_dir(enum sys_dir kind);
 
-/**
- * Close the system.
- *
- * This function is automatically called from \ref core_finish and thus not
- * necessary from user.
- */
 void
 sys_finish(void);
 
--- a/libmlk-core/core/texture.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/texture.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,123 +19,40 @@
 #ifndef MOLKO_CORE_TEXTURE_H
 #define MOLKO_CORE_TEXTURE_H
 
-/**
- * \file texture.h
- * \brief Basic texture management.
- * \ingroup drawing
- *
- * See also \a image.h for usage of textures.
- */
-
 #include <stdbool.h>
 
-/**
- * \brief Texture object.
- */
 struct texture {
-	unsigned int w;         /*!< (-) Texture width. */
-	unsigned int h;         /*!< (-) Texture height. */
-	void *handle;           /*!< (*) Native handle. */
+	unsigned int w;
+	unsigned int h;
+	void *handle;
 };
 
-/**
- * \brief Blend type when rendering.
- */
 enum texture_blend {
-	TEXTURE_BLEND_NONE,     /*!< No pixel modulation. */
-	TEXTURE_BLEND_BLEND,    /*!< Blend transparency. */
-	TEXTURE_BLEND_ADD,      /*!< Additive blending. */
-	TEXTURE_BLEND_MODULATE, /*!< Color modulation. */
-	TEXTURE_BLEND_LAST      /*!< Unused. */
+	TEXTURE_BLEND_NONE,
+	TEXTURE_BLEND_BLEND,
+	TEXTURE_BLEND_ADD,
+	TEXTURE_BLEND_MODULATE,
+	TEXTURE_BLEND_LAST
 };
 
-/**
- * Create a new texture.
- *
- * \pre tex != NULL
- * \param tex the texture to initialize
- * \param w the width
- * \param h the height
- * \return False on error.
- */
 bool
 texture_new(struct texture *tex, unsigned int w, unsigned int h);
 
-/**
- * Check if the texture is valid.
- *
- * This function simply checks if the texture is initialized and has non-null
- * dimensions.
- *
- * \param tex the texture to check (may be NULL)
- * \return True if the texture is properly initialized.
- */
 bool
 texture_ok(const struct texture *tex);
 
-/**
- * Set blend mode.
- *
- * \pre texture_ok(tex)
- * \param tex the texture
- * \param blend the blend mode
- * \return False on errors.
- */
 bool
 texture_set_blend_mode(struct texture *tex, enum texture_blend blend);
 
-/**
- * Apply an alpha modulation (aka transparency).
- *
- * You may need to use texture_set_blend_mode before this function to work.
- *
- * \pre texture_ok(tex)
- * \param tex the texture
- * \param alpha the alpha (0-255)
- * \return False on errors.
- */
 bool
 texture_set_alpha_mod(struct texture *tex, unsigned int alpha);
 
-/**
- * Apply a color modulation (for every pixel).
- *
- * \pre texture_ok(tex)
- * \param tex the texture to modify
- * \param color the color
- * \return False on errors.
- */
 bool
 texture_set_color_mod(struct texture *tex, unsigned long color);
 
-/**
- * Simple texture drawing.
- *
- * \pre tex != NULL
- * \param tex the texture
- * \param x the X coordinate
- * \param y the Y coordinate
- * \return False in case of rendering error.
- */
 bool
 texture_draw(const struct texture *tex, int x, int y);
 
-/**
- * Advanced texture drawing.
- *
- * \pre tex != NULL
- * \param tex the texture
- * \param src_x the source rectangle X coordinate
- * \param src_y the source rectangle Y coordinate
- * \param src_w the source rectangle width
- * \param src_h the source rectangle height
- * \param dst_x the destination rectangle X coordinate
- * \param dst_y the destination rectangle Y coordinate
- * \param dst_w the destination rectangle width
- * \param dst_h the destination rectangle height
- * \param angle the angle
- * \return False in case of rendering error.
- */
 bool
 texture_scale(const struct texture *tex,
               int src_x,
@@ -148,12 +65,6 @@
               unsigned dst_h,
               double angle);
 
-/**
- * Close the texture, do not use afterwards.
- *
- * \pre tex != NULL
- * \param tex the texture
- */
 void
 texture_finish(struct texture *tex);
 
--- a/libmlk-core/core/trace.c	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/trace.c	Thu Dec 03 09:06:52 2020 +0100
@@ -42,12 +42,12 @@
 		return;
 
 	va_start(ap, fmt);
-	vtracef(fmt, ap);
+	traceva(fmt, ap);
 	va_end(ap);
 }
 
 void
-vtracef(const char *fmt, va_list ap)
+traceva(const char *fmt, va_list ap)
 {
 	assert(fmt);
 
--- a/libmlk-core/core/trace.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/trace.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,51 +19,16 @@
 #ifndef MOLKO_CORE_TRACE_H
 #define MOLKO_CORE_TRACE_H
 
-/**
- * \file trace.h
- * \brief Non-fatal message logs.
- *
- * The purpose of this module is to provide a feedback from the code when there
- * are non-fatal programming error or unexpected results. In contrast to the
- * \ref debug.h module this one is always activated no manner if the build
- * is in Debug or Release.
- *
- * For example, having an animation with a delay of 0 is not a technical issue
- * but is probably not what the use wants. Thus, a trace warning may be
- * generated in that way.
- */
-
 #include <stdarg.h>
 
-/**
- * \brief Maximum length for a trace log.
- */
 #define TRACE_LINE_MAX (1024)
 
-/**
- * \brief Global trace handler.
- *
- * The default one use a simple printf on the standard output.
- */
 extern void (*trace_handler)(const char *);
 
-/**
- * Log some information.
- *
- * \pre fmt != NULL
- * \param fmt the printf(3) format string
- */
 void
 tracef(const char *fmt, ...);
 
-/**
- * Similar to \ref tracef with a va_list arguments pointer.
- *
- * \pre fmt != NULL
- * \param fmt the printf(3) format string
- * \param ap the argument list
- */
 void
-vtracef(const char *fmt, va_list ap);
+traceva(const char *fmt, va_list ap);
 
 #endif /* !MOLKO_CORE_TRACE_H */
--- a/libmlk-core/core/translate.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/translate.h	Thu Dec 03 09:06:52 2020 +0100
@@ -21,19 +21,9 @@
 
 #include <stdbool.h>
 
-/**
- * Initialize native language support.
- *
- * \pre name != NULL
- * \param name the domain name to initialize (e.g mlk-libcore)
- * \return True if correctly initialized.
- */
 bool
 translate_init(const char *name);
 
-/**
- * Close the native language support.
- */
 void
 translate_finish(void);
 
--- a/libmlk-core/core/util.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/util.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,59 +19,17 @@
 #ifndef MOLKO_CORE_UTIL_H
 #define MOLKO_CORE_UTIL_H
 
-/**
- * \file util.h
- * \brief Utilities.
- * \ingroup basics
- *
- * This file contains several utilities.
- *
- * \note In contrast to other files, identifiers are not prefixed with `util_`
- *       for convenience.
- */
-
 #include <stdarg.h>
 #include <stddef.h>
 
-/**
- * Get the number of elements in a static array.
- *
- * \param x the array
- * \return the number of elements
- */
 #define NELEM(x) sizeof ((x)) / sizeof ((x)[0])
 
-/**
- * Put the thread to sleep for a given amount of milliseconds.
- *
- * \param ms the number of milliseconds to wait
- */
 void
 delay(unsigned int ms);
 
-/**
- * Construct a temporary path to a file that can fit in a PATH_MAX array.
- *
- * This function is useful when specifying paths into a function invocation such
- * as `fopen(pprintf("%s.png", i), "r"))`.
- *
- * \pre fmt != NULL
- * \param fmt the format string
- * \warning This function is not reentrant, it returns a static storage path.
- * \return A non null path to a file.
- * \post Returned string is never NULL.
- */
 const char *
 pprintf(const char *fmt, ...);
 
-/**
- * Generate a random number between lower and upper (included).
- *
- * \pre upper must be <= RAND_MAX
- * \param lower the lower bound
- * \param upper the upper bound
- * \return The generated number.
- */
 unsigned int
 nrand(unsigned int lower, unsigned int upper);
 
--- a/libmlk-core/core/wait.c	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-/*
- * wait.c -- wait action
- *
- * Copyright (c) 2020 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 <assert.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "action.h"
-#include "wait.h"
-#include "util.h"
-
-static bool
-update(struct action *a, unsigned int ticks)
-{
-	assert(a);
-
-	return wait_update(a->data, ticks);
-}
-
-void
-wait_start(struct wait *w)
-{
-	assert(w);
-
-	w->elapsed = 0u;
-}
-
-bool
-wait_update(struct wait *w, unsigned int ticks)
-{
-	assert(w);
-
-	w->elapsed += ticks;
-
-	if (w->elapsed >= w->delay)
-		w->elapsed = w->delay;
-
-	return w->elapsed >= w->delay;
-}
-
-void
-wait_action(struct wait *w, struct action *a)
-{
-	assert(w);
-	assert(a);
-
-	memset(a, 0, sizeof (struct action));
-
-	a->data = w;
-	a->update = update;
-}
--- a/libmlk-core/core/wait.h	Tue Dec 01 21:53:23 2020 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,98 +0,0 @@
-/*
- * wait.h -- wait action
- *
- * Copyright (c) 2020 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.
- */
-
-#ifndef MOLKO_CORE_WAIT_H
-#define MOLKO_CORE_WAIT_H
-
-/**
- * \file wait.h
- * \brief Wait action.
- * \ingroup actions
- *
- * This module is meant to create a delayed action.
- *
- * Combined with \ref script.h, you can create a sequence of actions with
- * delays between each.
- *
- * \code
- * struct script script;
- * struct action action;
- *
- * // Prepare the script.
- * script_init(&script);
- *
- * // Add some actions to script using script_append.
- * // ...
- *
- * // Wait one second delay before next action.
- * wait_action(&(struct wait) { .delay = 1000 }, &action);
- * script_append(&script, &action);
- *
- * // Add more actions after this delay.
- * // ...
- * \endcode
- */
-
-#include <stdbool.h>
-
-struct action;
-
-/**
- * \brief Wait action.
- */
-struct wait {
-	unsigned int delay;             /*!< (+) Time to wait in milliseconds */
-	unsigned int elapsed;           /*!< (-) Elapsed time */
-};
-
-/**
- * Start the wait action.
- *
- * This function is equivalent to `w->elapsed = 0`;
- *
- * \pre w != NULL
- * \param w the wait object
- */
-void
-wait_start(struct wait *w);
-
-/**
- * Update the wait object.
- *
- * \pre w != NULL
- * \param w the wait object
- * \param ticks the number of milliseconds since last frame
- * \return true if complete
- */
-bool
-wait_update(struct wait *w, unsigned int ticks);
-
-/**
- * Create an action from the wait object.
- *
- * The wait action must be kept alive until the action completes.
- *
- * \pre w != NULL
- * \pre act != NULL
- * \param w the wait object to copy from
- * \param act the action to fill
- */
-void
-wait_action(struct wait *w, struct action *act);
-
-#endif /* !MOLKO_CORE_WAIT_H */
--- a/libmlk-core/core/window.h	Tue Dec 01 21:53:23 2020 +0100
+++ b/libmlk-core/core/window.h	Thu Dec 03 09:06:52 2020 +0100
@@ -19,69 +19,34 @@
 #ifndef MOLKO_CORE_WINDOW_H
 #define MOLKO_CORE_WINDOW_H
 
-/**
- * \file window.h
- * \brief Basic window management.
- * \ingroup drawing
- */
-
 #include <stdbool.h>
 
-/**
- * \brief Global exposed window structure.
- */
 struct window {
-	unsigned int w;         /*!< (-) Window width. */
-	unsigned int h;         /*!< (-) Window height. */
-	unsigned int framerate; /*!< (-) Device screen refresh rate. */
-	void *handle;           /*!< (*) Native handle. */
+	unsigned int w;
+	unsigned int h;
+	unsigned int framerate;
+	void *handle;
 };
 
-/**
- * \brief Window mouse cursor.
- */
 enum window_cursor {
-	WINDOW_CURSOR_ARROW,            /*!< Standard arrow.*/
-	WINDOW_CURSOR_EDIT,             /*!< Text edit cursor "I". */
-	WINDOW_CURSOR_WAIT,             /*!< Busy cursor. */
-	WINDOW_CURSOR_CROSSHAIR,        /*!< Cross-hair for selection. */
-	WINDOW_CURSOR_SIZE,             /*!< Size/moving. */
-	WINDOW_CURSOR_NO,               /*!< Action forbidden. */
-	WINDOW_CURSOR_HAND,             /*!< Hand. */
-	WINDOW_CURSOR_LAST              /*!< Number of cursors. */
+	WINDOW_CURSOR_ARROW,
+	WINDOW_CURSOR_EDIT,
+	WINDOW_CURSOR_WAIT,
+	WINDOW_CURSOR_CROSSHAIR,
+	WINDOW_CURSOR_SIZE,
+	WINDOW_CURSOR_NO,
+	WINDOW_CURSOR_HAND,
+	WINDOW_CURSOR_LAST
 };
 
-/**
- * \brief Access to global window structure.
- */
 extern struct window window;
 
-/**
- * Initialize window.
- *
- * \pre title != NULL
- * \param title the window title
- * \param width the desired width
- * \param height the desired height
- * \return true on success
- */
 bool
 window_open(const char *title, unsigned int width, unsigned int height);
 
-/**
- * Change the window cursor.
- *
- * You must open a window before calling this function.
- *
- * \pre cursor < WINDOW_CURSOR_LAST
- * \param cursor the cursor
- */
 void
 window_set_cursor(enum window_cursor cursor);
 
-/**
- * Close the window and destroy associated resources.
- */
 void
 window_finish(void);