Mercurial > molko
changeset 414:6947c1fefe5c
misc: extreme cleanup
- Remove of Javascript binding for many reasons.
- Put examples and tests in GNU make.
- Create a library with shared example code.
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 09 Oct 2022 13:51:03 +0200 |
parents | 222045c513ec |
children | a5b98db4fd87 |
files | .hgignore GNUmakefile README.md examples/assets/images/battle-background.png examples/assets/images/black-cat.png examples/assets/images/haunted-wood.png examples/assets/images/sword.png examples/assets/music/vabsounds-romance.ogg examples/assets/sounds/fire.wav examples/assets/sprites/chest.png examples/assets/sprites/explosion.png examples/assets/sprites/john-sword.png examples/assets/sprites/john-walk.png examples/assets/sprites/numbers.png examples/assets/sprites/people.png examples/assets/sprites/ui-cursor.png examples/example-action/assets/sprites/chest.png examples/example-action/assets/sprites/people.png examples/example-action/main.c examples/example-animation/assets/sprites/numbers.png examples/example-animation/main.c examples/example-audio/assets/music/vabsounds-romance.ogg examples/example-audio/assets/sounds/fire.wav examples/example-audio/main.c examples/example-battle/assets/images/battle-background.png examples/example-battle/assets/images/black-cat.png examples/example-battle/assets/images/haunted-wood.png examples/example-battle/assets/sounds/fire.wav examples/example-battle/assets/sprites/explosion.png examples/example-battle/assets/sprites/john-sword.png examples/example-battle/assets/sprites/john-walk.png examples/example-battle/assets/sprites/ui-cursor.png examples/example-battle/character-john.c examples/example-battle/character-john.h examples/example-battle/registry.c examples/example-battle/registry.h examples/example-battle/spell-fire.c examples/example-battle/spell-fire.h examples/example-cursor/main.c examples/example-debug/main.c examples/example-drawable/assets/sprites/explosion.png examples/example-drawable/main.c examples/example-font/main.c examples/example-gridmenu/main.c examples/example-label/main.c examples/example-message/main.c examples/example-notify/assets/images/sword.png examples/example-notify/main.c examples/example-sprite/assets/sprites/people.png examples/example-sprite/main.c examples/example-trace/main.c examples/example-trace/trace_hud.c examples/example-trace/trace_hud.h examples/example-ui/main.c examples/example/character-john.c examples/example/character-john.h examples/example/registry.c examples/example/registry.h examples/example/spell-fire.c examples/example/spell-fire.h examples/example/trace_hud.c examples/example/trace_hud.h src/libmlk-core-js/CMakeLists.txt src/libmlk-core-js/core/js-action-stack.c src/libmlk-core-js/core/js-action-stack.h src/libmlk-core-js/core/js-action.c src/libmlk-core-js/core/js-action.h src/libmlk-core-js/core/js-animation.c src/libmlk-core-js/core/js-animation.h src/libmlk-core-js/core/js-clock.c src/libmlk-core-js/core/js-clock.h src/libmlk-core-js/core/js-color.c src/libmlk-core-js/core/js-color.h src/libmlk-core-js/core/js-core.c src/libmlk-core-js/core/js-core.h src/libmlk-core-js/core/js-drawable-stack.c src/libmlk-core-js/core/js-drawable-stack.h src/libmlk-core-js/core/js-drawable.c src/libmlk-core-js/core/js-drawable.h src/libmlk-core-js/core/js-event.c src/libmlk-core-js/core/js-event.h src/libmlk-core-js/core/js-font.c src/libmlk-core-js/core/js-font.h src/libmlk-core-js/core/js-game.c src/libmlk-core-js/core/js-game.h src/libmlk-core-js/core/js-music.c src/libmlk-core-js/core/js-music.h src/libmlk-core-js/core/js-painter.c src/libmlk-core-js/core/js-painter.h src/libmlk-core-js/core/js-panic.c src/libmlk-core-js/core/js-panic.h src/libmlk-core-js/core/js-sound.c src/libmlk-core-js/core/js-sound.h src/libmlk-core-js/core/js-sprite.c src/libmlk-core-js/core/js-sprite.h src/libmlk-core-js/core/js-state.c src/libmlk-core-js/core/js-state.h src/libmlk-core-js/core/js-texture.c src/libmlk-core-js/core/js-texture.h src/libmlk-core-js/core/js-trace.c src/libmlk-core-js/core/js-trace.h src/libmlk-core-js/core/js-window.c src/libmlk-core-js/core/js-window.h src/mlk-run/CMakeLists.txt src/mlk-run/main.c src/tools/bcc/arg.h src/tools/bcc/main.c src/tools/map/main.c src/tools/map/mlk-map.c src/tools/tileset/main.c src/tools/tileset/mlk-tileset.c |
diffstat | 111 files changed, 1328 insertions(+), 8047 deletions(-) [+] |
line wrap: on
line diff
--- a/.hgignore Fri Oct 07 15:25:32 2022 +0200 +++ b/.hgignore Sun Oct 09 13:51:03 2022 +0200 @@ -25,7 +25,48 @@ # Generated files. \.exe$ ^config\.h$ -^mlk- -^example- ^src/libmlk-data/maps/.*\.map$ ^src/libmlk-data/maps/.*\.tileset$ + +# Examples. +examples/example-action/example-action +examples/example-animation/example-animation +examples/example-audio/example-audio +examples/example-battle/main +examples/example-cursor/example-cursor +examples/example-debug/example-debug +examples/example-drawable/example-drawable +examples/example-font/example-font +examples/example-gridmenu/example-gridmenu +examples/example-label/example-label +examples/example-message/example-message +examples/example-notify/example-notify +examples/example-sprite/example-sprite +examples/example-trace/example-trace +examples/example-ui/example-ui +examples/example/character-john +examples/example/registry +examples/example/spell-fire +examples/example/trace_hud + +# Tests. +tests/test-action-script +tests/test-action +tests/test-alloc +tests/test-character +tests/test-color +tests/test-drawable +tests/test-error +tests/test-map +tests/test-save-quest +tests/test-save +tests/test-state +tests/test-tileset +tests/test-util +tests/test-vfs-directory +tests/test-vfs-zip + +# Tools. +src/tools/bcc/mlk-bcc +src/tools/bcc/mlk-map +src/tools/bcc/mlk-tileset
--- a/GNUmakefile Fri Oct 07 15:25:32 2022 +0200 +++ b/GNUmakefile Sun Oct 09 13:51:03 2022 +0200 @@ -3,7 +3,7 @@ # Toolchain options. CC ?= clang CFLAGS ?= -g -O0 -BCC ?= bcc +BCC ?= src/tools/bcc/mlk-bcc BCC_OPTS ?= -cs MD ?= -MD @@ -26,6 +26,9 @@ SNDFILE_INCS ?= $(shell pkg-config --cflags sndfile) SNDFILE_LIBS ?= $(shell pkg-config --libs sndfile) +JANSSON_INCS ?= $(shell pkg-config --cflags jansson) +JANSSON_LIBS ?= $(shell pkg-config --libs jansson) + ifeq ($(WITH_ZSTD),yes) ZSTD_INCS ?= $(shell pkg-config --cflags libzstd) ZSTD_LIBS ?= $(shell pkg-config --libs libzstd) @@ -67,7 +70,7 @@ INCS += $(ZIP_INCS) endif -OPTS := -Wall -Wextra -Wno-format-truncation -pipe +OPTS := -Wall -Wextra -pipe ifeq ($(OS),Darwin) OPTS += -Wno-deprecated-declarations @@ -79,18 +82,39 @@ OPTS += -DNDEBUG -O3 endif +# Meta variable that contains all libraries, used for executables and tests. +LIBMLK = $(LIBMLK_RPG) \ + $(LIBMLK_UI) \ + $(LIBMLK_CORE) \ + $(LIBMLK_PORT) \ + $(LIBMLK_SQLITE) \ + $(MATH_LIBS) \ + $(SDL2_LIBS) \ + $(SDL2_IMAGE_LIBS) \ + $(SDL2_TTF_LIBS) \ + $(OPENAL_LIBS) \ + $(SNDFILE_LIBS) + +ifeq ($(WITH_ZSTD),yes) +LIBMLK += $(ZSTD_LIBS) +endif + +ifeq ($(WITH_ZIP),yes) +LIBMLK += $(LIBZIP_LIBS) +endif + .DEFAULT_GOAL := all .SUFFIXES: -.SUFFIXES: .c .h .o .sql .ttf +.SUFFIXES: .c .h .o .ogg .png .sql .ttf .wav .c.o: $(CC) $(OPTS) $(INCS) $(DEFS) $(CFLAGS) $(MD) -c $< -o $@ .c: - $(CC) $(OPTS) $(INCS) $(DEFS) $(CFLAGS) $< -o $@ $(LIBS) $(LDFLAGS) + $(CC) $(OPTS) $(INCS) $(DEFS) $(CFLAGS) $< -o $@ $(OBJS) $(LIBS) $(LDFLAGS) -.ttf.h .sql.h: +.ogg.h .png.h .ttf.h .sql.h .wav.h: $(BCC) $(BCC_OPTS) $< assets_$(basename $(<F)) > $@ %.a: @@ -132,6 +156,39 @@ # }}} +# {{{ mlk-bcc + +MLK_BCC := src/tools/bcc/mlk-bcc + +$(MLK_BCC): INCS := + +all: $(MLK_BCC) + +# }}} + +# {{{ mlk-tileset + +MLK_TILESET := src/tools/tileset/mlk-tileset + +$(MLK_TILESET): INCS := $(JANSSON_INCS) +$(MLK_TILESET): LIBS := $(JANSSON_LIBS) + +all: $(MLK_TILESET) + +# }}} + +# {{{ mlk-map + +MLK_MAP := src/tools/map/mlk-map + +$(MLK_MAP): INCS := -Isrc/libmlk-port $(JANSSON_INCS) +$(MLK_MAP): LIBS := $(LIBMLK_PORT) $(JANSSON_LIBS) +$(MLK_MAP): $(LIBMLK_PORT) + +all: $(MLK_MAP) + +# }}} + # {{{ libmlk-sqlite LIBMLK_SQLITE := libmlk-sqlite.a @@ -141,8 +198,8 @@ -include $(LIBMLK_SQLITE_DEPS) -$(LIBMLK_SQLITE): INCS := -$(LIBMLK_SQLITE): OBJS := $(LIBMLK_SQLITE_OBJS) +$(LIBMLK_SQLITE): private INCS := +$(LIBMLK_SQLITE): private OBJS := $(LIBMLK_SQLITE_OBJS) $(LIBMLK_SQLITE): $(LIBMLK_SQLITE_OBJS) all: $(LIBMLK_SQLITE) @@ -189,7 +246,7 @@ -include $(LIBMLK_CORE_DEPS) $(LIBMLK_CORE_OBJS): config.h -$(LIBMLK_CORE): OBJS := $(LIBMLK_CORE_OBJS) +$(LIBMLK_CORE): private OBJS := $(LIBMLK_CORE_OBJS) $(LIBMLK_CORE): $(LIBMLK_CORE_OBJS) all: $(LIBMLK_CORE) @@ -217,9 +274,12 @@ src/libmlk-ui/assets/fonts/opensans-regular.ttf LIBMLK_UI_DATA_OBJS := $(addsuffix .h,$(basename $(LIBMLK_UI_DATA_SRCS))) +$(LIBMLK_UI_DATA_OBJS): $(MLK_BCC) + $(LIBMLK_UI_OBJS): $(LIBMLK_UI_DATA_OBJS) + $(LIBMLK_UI): $(LIBMLK_UI_OBJS) -$(LIBMLK_UI): OBJS := $(LIBMLK_UI_OBJS) +$(LIBMLK_UI): private OBJS := $(LIBMLK_UI_OBJS) all: $(LIBMLK_UI) @@ -268,9 +328,9 @@ src/libmlk-rpg/rpg/tileset-file.c \ src/libmlk-rpg/rpg/tileset.c \ src/libmlk-rpg/rpg/walksprite.c - LIBMLK_RPG_OBJS := $(LIBMLK_RPG_SRCS:.c=.o) LIBMLK_RPG_DEPS := $(LIBMLK_RPG_SRCS:.c=.d) + LIBMLK_RPG_DATA_SRCS := src/libmlk-rpg/assets/sql/character-load.sql \ src/libmlk-rpg/assets/sql/character-save.sql \ src/libmlk-rpg/assets/sql/init.sql \ @@ -284,34 +344,82 @@ LIBMLK_RPG_DATA_OBJS := $(addsuffix .h,$(basename $(LIBMLK_RPG_DATA_SRCS))) $(LIBMLK_RPG_DATA_OBJS): BCC_OPTS := -cs0 +$(LIBMLK_RPG_DATA_OBJS): $(MLK_BCC) + $(LIBMLK_RPG_OBJS): $(LIBMLK_RPG_DATA_OBJS) + $(LIBMLK_RPG): $(LIBMLK_RPG_OBJS) -$(LIBMLK_RPG): OBJS := $(LIBMLK_RPG_OBJS) +$(LIBMLK_RPG): private OBJS := $(LIBMLK_RPG_OBJS) all: $(LIBMLK_RPG) # }}} -# Meta variable that contains all libraries, used for executables and tests. -LIBMLK := $(LIBMLK_RPG) \ - $(LIBMLK_UI) \ - $(LIBMLK_CORE) \ - $(LIBMLK_PORT) \ - $(LIBMLK_SQLITE) \ - $(MATH_LIBS) \ - $(SDL2_LIBS) \ - $(SDL2_IMAGE_LIBS) \ - $(SDL2_TTF_LIBS) \ - $(OPENAL_LIBS) \ - $(SNDFILE_LIBS) +# {{{ libmlk-example + +LIBMLK_EXAMPLE := libmlk-example.a +LIBMLK_EXAMPLE_SRCS := examples/example/character-john.c \ + examples/example/registry.c \ + examples/example/spell-fire.c \ + examples/example/trace_hud.c + +LIBMLK_EXAMPLE_DATA_SRCS := examples/assets/images/battle-background.png \ + examples/assets/images/black-cat.png \ + examples/assets/images/haunted-wood.png \ + examples/assets/images/sword.png \ + examples/assets/music/vabsounds-romance.ogg \ + examples/assets/sounds/fire.wav \ + examples/assets/sprites/chest.png \ + examples/assets/sprites/explosion.png \ + examples/assets/sprites/john-sword.png \ + examples/assets/sprites/john-walk.png \ + examples/assets/sprites/numbers.png \ + examples/assets/sprites/people.png \ + examples/assets/sprites/ui-cursor.png +LIBMLK_EXAMPLE_DATA_OBJS := $(addsuffix .h,$(basename $(LIBMLK_EXAMPLE_DATA_SRCS))) + +LIBMLK_EXAMPLE_OBJS := $(LIBMLK_EXAMPLE_SRCS:.c=.o) +LIBMLK_EXAMPLE_DEPS := $(LIBMLK_EXAMPLE_SRCS:.c=.d) + +-include $(LIBMLK_EXAMPLE_DEPS) + +$(LIBMLK_EXAMPLE_DATA_OBJS): $(MLK_BCC) + +$(LIBMLK_EXAMPLE_OBJS): private INCS += -Iexamples +$(LIBMLK_EXAMPLE_OBJS): $(LIBMLK_EXAMPLE_DATA_OBJS) -ifeq ($(WITH_ZSTD),yes) -LIBMLK += $(ZSTD_LIBS) -endif +$(LIBMLK_EXAMPLE): private OBJS := $(LIBMLK_EXAMPLE_OBJS) +$(LIBMLK_EXAMPLE): $(LIBMLK_EXAMPLE_OBJS) + +# }}} + +# {{{ examples -ifeq ($(WITH_ZIP),yes) -LIBMLK += $(LIBZIP_LIBS) -endif +EXAMPLES := examples/example-action/example-action.c \ + examples/example-animation/example-animation.c \ + examples/example-audio/example-audio.c \ + examples/example-cursor/example-cursor.c \ + examples/example-debug/example-debug.c \ + examples/example-drawable/example-drawable.c \ + examples/example-font/example-font.c \ + examples/example-gridmenu/example-gridmenu.c \ + examples/example-label/example-label.c \ + examples/example-message/example-message.c \ + examples/example-notify/example-notify.c \ + examples/example-sprite/example-sprite.c \ + examples/example-ui/example-ui.c +EXAMPLES_EXE := $(EXAMPLES:.c=) +EXAMPLES_OBJS := $(EXAMPLES_EXE) + +$(EXAMPLES_EXE): private LIBS += $(LIBMLK) $(LIBMLK_EXAMPLE) +$(EXAMPLES_EXE): private INCS += -Iexamples +$(EXAMPLES_EXE): $(LIBMLK_RPG) $(LIBMLK_UI) $(LIBMLK_CORE) $(LIBMLK_PORT) $(LIBMLK_SQLITE) $(LIBMLK_EXAMPLE) + +examples: $(EXAMPLES_EXE) + +# }}} + +# {{{ tests TESTS := tests/test-action-script.c \ tests/test-action.c \ @@ -341,13 +449,17 @@ tests: $(TESTS_EXE) for t in $(TESTS_EXE); do ./$$t; done +# }}} + clean: rm -f config.h + rm -f $(MLK_BCC) $(MLK_MAP) $(MLK_TILESET) rm -f $(LIBMLK_SQLITE) $(LIBMLK_SQLITE_DEPS) $(LIBMLK_SQLITE_OBJS) rm -f $(LIBMLK_PORT) $(LIBMLK_PORT_DEPS) $(LIBMLK_PORT_OBJS) rm -f $(LIBMLK_CORE) $(LIBMLK_CORE_DEPS) $(LIBMLK_CORE_OBJS) rm -f $(LIBMLK_UI) $(LIBMLK_UI_DEPS) $(LIBMLK_UI_OBJS) $(LIBMLK_UI_DATA_OBJS) rm -f $(LIBMLK_RPG) $(LIBMLK_RPG_DEPS) $(LIBMLK_RPG_OBJS) $(LIBMLK_RPG_DATA_OBJS) - rm -f $(TESTS_EXE) + rm -f $(LIBMLK_EXAMPLE) $(LIBMLK_EXAMPLE_DEPS) $(LIBMLK_EXAMPLE_OBJS) $(LIBMLK_EXAMPLE_DATA_OBJS) + rm -f $(TESTS_EXE) $(EXAMPLES_EXE) -.PHONY: all clean tests +.PHONY: all clean examples tests
--- a/README.md Fri Oct 07 15:25:32 2022 +0200 +++ b/README.md Sun Oct 09 13:51:03 2022 +0200 @@ -1,9 +1,8 @@ Molko's Engine ============== -The Molko's Engine is a C and Javascript framework to write 2D RPG games in a -portable manner. It is designed in mind to be flexible, simple and convenient to -use. +The Molko's Engine is a C and framework to write 2D RPG games in a portable +manner. It is designed in mind to be flexible, simple and convenient to use. It has the following features:
--- a/examples/example-action/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,425 +0,0 @@ -/* - * example-action.c -- example on how to use automatic actions - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/action.h> -#include <core/action-stack.h> -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/image.h> -#include <core/maths.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/script.h> -#include <core/sprite.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/texture.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/theme.h> -#include <ui/ui.h> - -#include <rpg/message.h> -#include <rpg/rpg.h> - -#include <assets/sprites/chest.h> -#include <assets/sprites/people.h> - -#define W 1280 -#define H 720 - -#define MW (W * 0.75) -#define MX ((W / 2) - (MW / 2)) -#define MY (100) - -/* This is a stack of "parallel" events. */ -static struct action *events_actions[32]; -static struct action_stack events; - -/* This is a stack of modal events. */ -static struct action *modal_actions[32]; -static struct action_stack modal; - -/* Maximum number of states. */ -static struct state *states[1]; - -/* - * Event object for the chest to click on. - */ -static struct { - const char *text[2]; - struct message msg; - struct action msg_act; - int x; - int y; - int opened; - struct texture image; - struct sprite sprite; - struct action event; -} chest = { - .text = { - "100000 pièces.", - "Te voilà riche sale file de crevette." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = chest.text, - .linesz = 2 - } -}; - -/* - * Event object for the guide who ask dialog with you. - * - * It is a script spawned upon click like this. - * - * [guide.event] - * | spawn - * (on click)------------------->[message 1] - * v - * [message 2] - * v - * [question 3] - * spawn v - * [response]<---------------------[check result] - * v - * [message 4/5] - */ -static struct { - struct { - const char *text[6]; - struct message msg; - struct action act; - } msgs[5]; - - /* This is the sprite and action to click on. */ - int x; - int y; - struct texture image; - struct sprite sprite; - struct action event; - - /* This is the event for the response. */ - struct action response; - - struct script script; - struct action script_act; -} guide = { - .msgs = { - { - .text = { - "Bienvenue dans ce monde Molko." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, - .flags = MESSAGE_FLAGS_FADEIN, - .lines = guide.msgs[0].text, - .linesz = 1 - }, - }, - { - .text = { - "Penses tu vraiment pouvoir me battre ?" - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = guide.msgs[1].text, - .linesz = 1 - } - }, - { - .text = { - "Non j'ai la trouille.", - "Bien sûr, je suis la légende." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .flags = MESSAGE_FLAGS_QUESTION, - .lines = guide.msgs[2].text, - .linesz = 2 - } - }, - - /* In case of NO. */ - { - .text = { - "Poule mouillée." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = guide.msgs[3].text, - .linesz = 1 - } - }, - - /* In case of YES. */ - { - .text = { - "Prépare toi à souffrir." - }, - .msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = guide.msgs[4].text, - .linesz = 1 - } - } - } -}; - -static int -guide_response_update(struct action *act, unsigned int ticks) -{ - /* Immediately return to get access to end. */ - (void)act; - (void)ticks; - - return 1; -} - -static void -guide_response_end(struct action *act) -{ - (void)act; - - /* We add a final response depending on the result. */ - const int index = guide.msgs[2].msg.index + 3; - - message_action(&guide.msgs[index].msg, &guide.msgs[index].act); - message_query(&guide.msgs[index].msg, NULL, &guide.msgs[index].msg.h); - action_stack_add(&modal, &guide.msgs[index].act); -} - -static void -guide_popup(void) -{ - /* Prepare the script with first 3 messages. */ - for (size_t i = 0; i < 3; ++i) { - message_action(&guide.msgs[i].msg, &guide.msgs[i].act); - message_query(&guide.msgs[i].msg, NULL, &guide.msgs[i].msg.h); - script_append(&guide.script, &guide.msgs[i].act); - } - - /* Reset the message index. */ - guide.msgs[2].msg.index = 0; - - /* This is final action that analyze user input. */ - guide.response.update = guide_response_update; - guide.response.end = guide_response_end; - script_append(&guide.script, &guide.response); - - script_action(&guide.script, &guide.script_act); - action_stack_add(&modal, &guide.script_act); -} - -static void -guide_handle(struct action *act, const union event *ev) -{ - (void)act; - - if (!action_stack_completed(&modal)) - return; - - switch (ev->type) { - case EVENT_CLICKDOWN: - if (maths_is_boxed(guide.x, guide.y, - guide.sprite.cellw, guide.sprite.cellh, - ev->click.x, ev->click.y)) - guide_popup(); - break; - default: - break; - } -} - -static void -guide_draw(struct action *act) -{ - (void)act; - - sprite_draw(&guide.sprite, 0, 0, guide.x, guide.y); -} - -static void -guide_init(void) -{ - if (image_openmem(&guide.image, assets_sprites_people, sizeof (assets_sprites_people)) < 0) - panic(); - - sprite_init(&guide.sprite, &guide.image, 48, 48); - - /* This is the global guide action. */ - guide.event.handle = guide_handle; - guide.event.draw = guide_draw; - guide.x = 200; - guide.y = 200; -} - -static void -chest_handle(struct action *act, const union event *ev) -{ - (void)act; - - if (chest.opened || !action_stack_completed(&modal)) - return; - - switch (ev->type) { - case EVENT_CLICKDOWN: - if (maths_is_boxed(chest.x, chest.y, chest.sprite.cellw, chest.sprite.cellh, - ev->click.x, ev->click.y)) { - chest.opened = 1; - message_action(&chest.msg, &chest.msg_act); - message_query(&chest.msg, NULL, &chest.msg.h); - action_stack_add(&modal, &chest.msg_act); - } - default: - break; - } -} - -static void -chest_draw(struct action *act) -{ - (void)act; - - const int row = chest.opened ? chest.sprite.nrows - 1 : 0; - const int col = chest.opened ? chest.sprite.ncols - 1 : 0; - - sprite_draw(&chest.sprite, row, col, chest.x, chest.y); -} - -static void -chest_init(void) -{ - if (image_openmem(&chest.image, assets_sprites_chest, sizeof (assets_sprites_chest)) < 0) - panic(); - - sprite_init(&chest.sprite, &chest.image, 32, 32); - - chest.x = 100; - chest.y = 100; - chest.event.handle = chest_handle; - chest.event.draw = chest_draw; -} - -static void -init(void) -{ - if (core_init("fr.malikania", "example-action") < 0 || ui_init() < 0 || rpg_init() < 0) - panic(); - if (window_open("Example - Action", W, H) < 0) - panic(); - - guide_init(); - chest_init(); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_QUIT: - game_quit(); - break; - default: - action_stack_handle(&events, ev); - action_stack_handle(&modal, ev); - break; - } -} - -static void -update(struct state *st, unsigned int ticks) -{ - (void)st; - - action_stack_update(&events, ticks); - action_stack_update(&modal, ticks); -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0xffffffff); - painter_clear(); - action_stack_draw(&events); - action_stack_draw(&modal); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .update = update, - .draw = draw - }; - - action_stack_init(&modal, modal_actions, UTIL_SIZE(modal_actions)); - - action_stack_init(&events, events_actions, UTIL_SIZE(events_actions)); - action_stack_add(&events, &chest.event); - action_stack_add(&events, &guide.event); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - rpg_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); - - return 0; -}
--- a/examples/example-animation/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * example-animation.c -- example on how to use animations - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <core/animation.h> -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/image.h> -#include <core/sys.h> -#include <core/window.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/sprite.h> -#include <core/state.h> -#include <core/texture.h> -#include <core/util.h> - -#include <ui/label.h> -#include <ui/ui.h> - -#include <assets/sprites/numbers.h> - -#define W 1280 -#define H 720 - -static struct label label = { - .text = "Keys: <Space> start or reset the animation.", - .x = 10, - .y = 10, - .flags = LABEL_FLAGS_SHADOW -}; - -static struct state *states[1]; -static struct texture numbers; -static struct animation animation; -static struct sprite sprite; -static int completed = 1; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-animation") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Animation", W, H) < 0) - panic(); - if (image_openmem(&numbers, assets_sprites_numbers, sizeof (assets_sprites_numbers)) < 0) - panic(); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_KEYDOWN: - switch (ev->key.key) { - case KEY_SPACE: - animation_start(&animation); - completed = animation_completed(&animation); - break; - default: - break; - } - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -update(struct state *st, unsigned int ticks) -{ - (void)st; - - if (!completed) - completed = animation_update(&animation, ticks); -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0x4f8fbaff); - painter_clear(); - label_draw(&label); - - if (!completed) - animation_draw(&animation, (window.w - sprite.cellw) / 2, (window.h - sprite.cellh) / 2); - - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .update = update, - .draw = draw - }; - - sprite_init(&sprite, &numbers, 48, 48); - animation_init(&animation, &sprite, 1000); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -} -
--- a/examples/example-audio/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,155 +0,0 @@ -/* - * example-audio.c -- show how to use sounds and music - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/music.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/sound.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/label.h> -#include <ui/theme.h> -#include <ui/ui.h> - -#include <assets/music/vabsounds-romance.h> -#include <assets/sounds/fire.h> - -#define W 1280 -#define H 720 - -static struct state *states[1]; -static struct music music; -static struct sound sound; - -static struct label label_music = { - .text = "Music: <Space> play, <p> pause, <r> resume, <q> stop, <l> loop.", - .x = 10, - .y = 10, - .flags = LABEL_FLAGS_SHADOW -}; - -static struct label label_sound = { - .text = "Sound: click anywhere to pop a sound.", - .x = 10, - .y = 30, - .flags = LABEL_FLAGS_SHADOW -}; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-audio") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Audio", W, H) < 0) - panic(); - if (music_openmem(&music, assets_music_vabsounds_romance, sizeof (assets_music_vabsounds_romance)) < 0 || - sound_openmem(&sound, assets_sounds_fire, sizeof (assets_sounds_fire)) < 0) - panic(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_CLICKDOWN: - if (sound_play(&sound) < 0) - panic(); - break; - case EVENT_KEYDOWN: - switch (ev->key.key) { - case KEY_p: - music_pause(&music); - break; - case KEY_r: - music_resume(&music); - break; - case KEY_q: - music_stop(&music); - break; - case KEY_l: - music_play(&music, MUSIC_LOOP); - break; - case KEY_SPACE: - music_play(&music, 0); - break; - default: - break; - } - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0x006554ff); - painter_clear(); - label_draw(&label_music); - label_draw(&label_sound); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .draw = draw - }; - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); - - music_finish(&music); - sound_finish(&sound); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -}
--- a/examples/example-battle/character-john.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,50 +0,0 @@ -/* - * character-john.c -- john character - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <rpg/character.h> - -#include "character-john.h" -#include "spell-fire.h" -#include "registry.h" - -static void -adventurer_reset(struct character *ch) -{ - /* TODO: this function should compute the attack thanks to the level. */ - ch->hpmax = 120; - ch->mpmax = 50; - ch->atk = 50; - ch->def = 50; - ch->agt = 50; - ch->luck = 50; -} - -const struct character character_john = { - .name = "John ", - .level = 1, - .hp = 120, - .mp = 50, - .reset = adventurer_reset, - .sprites = { - [CHARACTER_SPRITE_NORMAL] = ®istry_sprites[REGISTRY_TEXTURE_JOHN_WALK], - [CHARACTER_SPRITE_SWORD] = ®istry_sprites[REGISTRY_TEXTURE_JOHN_SWORD] - }, - .spells = { - &spell_fire - } -};
--- a/examples/example-battle/character-john.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * character-john.h -- john character - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef EXAMPLES_BATTLE_CHARACTER_JOHN_H -#define EXAMPLES_BATTLE_CHARACTER_JOHN_H - -const struct character character_john; - -#endif /* !EXAMPLES_BATTLE_CHARACTER_JOHN_H */
--- a/examples/example-battle/registry.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* - * registry.h -- registry of resources - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stddef.h> - -#include <core/image.h> -#include <core/panic.h> -#include <core/util.h> -#include <core/sys.h> - -#include <assets/images/battle-background.h> -#include <assets/images/black-cat.h> -#include <assets/images/haunted-wood.h> - -#include <assets/sounds/fire.h> - -#include <assets/sprites/explosion.h> -#include <assets/sprites/john-sword.h> -#include <assets/sprites/john-walk.h> -#include <assets/sprites/ui-cursor.h> - -#include "registry.h" - -struct texture registry_images[REGISTRY_IMAGE_NUM]; -struct texture registry_textures[REGISTRY_TEXTURE_NUM]; -struct sprite registry_sprites[REGISTRY_TEXTURE_NUM]; -struct sound registry_sounds[REGISTRY_SOUND_NUM]; - -#define REGISTRY_IMAGE(i, data) \ - { (i), (data), sizeof (data) } - -static const struct { - enum registry_image index; - const unsigned char *data; - size_t datasz; -} images[] = { - REGISTRY_IMAGE(REGISTRY_IMAGE_BATTLE_BACKGROUND, assets_images_battle_background) -}; - -#define REGISTRY_TEXTURE(s, data, cw, ch) \ - { (s), (data), sizeof (data), (cw), (ch) } - -static const struct { - enum registry_texture index; - const unsigned char *data; - size_t datasz; - unsigned int cellw; - unsigned int cellh; -} textures[] = { - REGISTRY_TEXTURE(REGISTRY_TEXTURE_CURSOR, assets_sprites_ui_cursor, 24, 24), - REGISTRY_TEXTURE(REGISTRY_TEXTURE_EXPLOSION, assets_sprites_explosion, 256, 256), - REGISTRY_TEXTURE(REGISTRY_TEXTURE_JOHN_SWORD, assets_sprites_john_sword, 256, 256), - REGISTRY_TEXTURE(REGISTRY_TEXTURE_JOHN_WALK, assets_sprites_john_walk, 256, 256), - REGISTRY_TEXTURE(REGISTRY_TEXTURE_HAUNTED_WOOD, assets_images_haunted_wood, 0, 0), - REGISTRY_TEXTURE(REGISTRY_TEXTURE_BLACK_CAT, assets_images_black_cat, 0, 0) -}; - -#define REGISTRY_SOUND(s, data) \ - { (s), (data), sizeof (data) } - -static const struct { - enum registry_sound index; - const unsigned char *data; - size_t datasz; -} sounds[] = { - REGISTRY_SOUND(REGISTRY_SOUND_FIRE, assets_sounds_fire) -}; - -static void -load_images(void) -{ - for (size_t i = 0; i < UTIL_SIZE(images); ++i) { - struct texture *texture = ®istry_images[images[i].index]; - - if (image_openmem(texture, images[i].data, images[i].datasz) < 0) - panic(); - } -} - -static void -load_textures_and_sprites(void) -{ - for (size_t i = 0; i < UTIL_SIZE(textures); ++i) { - struct texture *texture = ®istry_textures[textures[i].index]; - struct sprite *sprite = ®istry_sprites[textures[i].index]; - - if (image_openmem(texture, textures[i].data, textures[i].datasz) < 0) - panic(); - - if (textures[i].cellw == 0 || textures[i].cellh == 0) - sprite_init(sprite, texture, texture->w, texture->h); - else - sprite_init(sprite, texture, textures[i].cellw, textures[i].cellh); - } -} - -static void -load_sounds(void) -{ - for (size_t i = 0; i < UTIL_SIZE(sounds); ++i) { - struct sound *sound = ®istry_sounds[sounds[i].index]; - - if (sound_openmem(sound, sounds[i].data, sounds[i].datasz) < 0) - panic(); - } -} - -void -registry_init(void) -{ - load_images(); - load_textures_and_sprites(); - load_sounds(); -} - -void -registry_finish(void) -{ - for (size_t i = 0; i < UTIL_SIZE(registry_images); ++i) - texture_finish(®istry_images[i]); - for (size_t i = 0; i < UTIL_SIZE(registry_textures); ++i) - texture_finish(®istry_textures[i]); - for (size_t i = 0; i < UTIL_SIZE(registry_sounds); ++i) - sound_finish(®istry_sounds[i]); -}
--- a/examples/example-battle/registry.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,66 +0,0 @@ -/* - * registry.h -- registry of resources - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef EXAMPLES_BATTLE_REGISTRY_H -#define EXAMPLES_BATTLE_REGISTRY_H - -#include <core/sound.h> -#include <core/sprite.h> -#include <core/texture.h> - -enum registry_texture { - /* UI. */ - REGISTRY_TEXTURE_CURSOR, - - /* Animations. */ - REGISTRY_TEXTURE_EXPLOSION, - - /* Characters. */ - REGISTRY_TEXTURE_JOHN_WALK, - REGISTRY_TEXTURE_JOHN_SWORD, - - /* Enemies. */ - REGISTRY_TEXTURE_HAUNTED_WOOD, - REGISTRY_TEXTURE_BLACK_CAT, - - /* Unused.*/ - REGISTRY_TEXTURE_NUM -}; - -enum registry_image { - REGISTRY_IMAGE_BATTLE_BACKGROUND, - REGISTRY_IMAGE_NUM -}; - -enum registry_sound { - REGISTRY_SOUND_FIRE, - REGISTRY_SOUND_NUM -}; - -extern struct texture registry_images[REGISTRY_IMAGE_NUM]; -extern struct texture registry_textures[REGISTRY_TEXTURE_NUM]; -extern struct sprite registry_sprites[REGISTRY_TEXTURE_NUM]; -extern struct sound registry_sounds[REGISTRY_SOUND_NUM]; - -void -registry_init(void); - -void -registry_finish(void); - -#endif /* !EXAMPLES_BATTLE_REGISTRY_H */
--- a/examples/example-battle/spell-fire.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * spell-fire.c -- example of spell: fire - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdlib.h> - -#include <core/action.h> -#include <core/animation.h> -#include <core/drawable.h> -#include <core/alloc.h> - -#include <ui/align.h> - -#include <rpg/battle-state-check.h> -#include <rpg/battle-state-rendering.h> -#include <rpg/battle.h> -#include <rpg/character.h> -#include <rpg/spell.h> - -#include "registry.h" -#include "spell-fire.h" - -struct self { - struct battle *battle; - struct character *target; - struct animation animation; - struct drawable drawable; - unsigned int selection; -}; - -static int -update(struct drawable *dw, unsigned int ticks) -{ - struct self *self = dw->data; - - return animation_update(&self->animation, ticks); -} - -static void -draw(struct drawable *dw) -{ - const struct self *self = dw->data; - const struct battle_entity *et = self->battle->enemies[self->selection]; - const struct sprite *sprite = et->ch->sprites[CHARACTER_SPRITE_NORMAL]; - int x, y; - - align(ALIGN_CENTER, - &x, &y, self->animation.sprite->cellw, self->animation.sprite->cellh, - et->x, et->y, sprite->cellw, sprite->cellh); - - animation_draw(&self->animation, x, y); -} - -static void -end(struct drawable *dw) -{ - struct self *self = dw->data; - struct character *ch = self->battle->enemies[self->selection]->ch; - - /* TODO: compute damage. */ - const unsigned int damage = 100; - - if ((unsigned int)ch->hp < damage) - ch->hp = 0; - else - ch->hp -= damage; - - battle_indicator_hp(self->battle, self->battle->enemies[self->selection]->ch, 100); - battle_state_check(self->battle); -} - -static void -finish(struct drawable *dw) -{ - free(dw->data); -} - -static void -fire_select(const struct battle *bt, struct selection *slt) -{ - slt->index_side = 0; - - selection_first(slt, bt); -} - -static void -fire_action(struct battle *bt, struct character *owner, const struct selection *slt) -{ - struct self *self; - - (void)owner; - - self = alloc_new0(sizeof (*self)); - self->selection = slt->index_character; - self->battle = bt; - self->drawable.data = self; - self->drawable.update = update; - self->drawable.draw = draw; - self->drawable.finish = finish; - self->drawable.end = end; - - animation_init(&self->animation, ®istry_sprites[REGISTRY_TEXTURE_EXPLOSION], 12); - animation_start(&self->animation); - - sound_play(®istry_sounds[REGISTRY_SOUND_FIRE]); - battle_state_rendering(bt, &self->drawable); -} - -const struct spell spell_fire = { - .name = "Fire", - .description = "A delicate fire.", - .mp = 5, - .type = SPELL_TYPE_FIRE, - .select = fire_select, - .select_kind = SELECTION_KIND_ONE, - .select_side = SELECTION_SIDE_ENEMY, - .action = fire_action -};
--- a/examples/example-battle/spell-fire.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,24 +0,0 @@ -/* - * spell-fire.c -- example of spell: fire - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef EXAMPLES_BATTLE_SPELL_FIRE_H -#define EXAMPLES_BATTLE_SPELL_FIRE_H - -extern const struct spell spell_fire; - -#endif /* !EXAMPLES_BATTLE_SPELL_FIRE_H */
--- a/examples/example-cursor/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * example-cursor.c -- example on how to change cursor - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdio.h> - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/key.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/label.h> -#include <ui/ui.h> - -#define W 1280 -#define H 720 - -static struct state *states[1]; -static char help_text[128]; -static enum window_cursor cursor = WINDOW_CURSOR_ARROW; - -static struct label help = { - .x = 10, - .y = 10, - .text = help_text, - .flags = LABEL_FLAGS_SHADOW -}; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-cursor") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Cursor", W, H) < 0) - panic(); -} - -static void -change(enum window_cursor cursor) -{ - static const char *names[] = { - [WINDOW_CURSOR_ARROW] = "WINDOW_CURSOR_ARROW", - [WINDOW_CURSOR_EDIT] = "WINDOW_CURSOR_EDIT", - [WINDOW_CURSOR_WAIT] = "WINDOW_CURSOR_WAIT", - [WINDOW_CURSOR_CROSSHAIR] = "WINDOW_CURSOR_CROSSHAIR", - [WINDOW_CURSOR_SIZE] = "WINDOW_CURSOR_SIZE", - [WINDOW_CURSOR_NO] = "WINDOW_CURSOR_NO", - [WINDOW_CURSOR_HAND] = "WINDOW_CURSOR_HAND" - }; - - snprintf(help_text, sizeof (help_text), "Keys: <Left>/<Right> to change cursor. Current: %s", names[cursor]); - window_set_cursor(cursor); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_KEYDOWN: - switch (ev->key.key) { - case KEY_LEFT: - if (cursor > 0) - change(--cursor); - break; - case KEY_RIGHT: - if (cursor + 1 < WINDOW_CURSOR_LAST) - change(++cursor); - break; - default: - break; - } - - - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0xebede9ff); - painter_clear(); - label_draw(&help); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .draw = draw - }; - - change(cursor); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -}
--- a/examples/example-debug/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * example-debug.c -- example on how to use debug interface - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/window.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/util.h> - -#include <ui/debug.h> -#include <ui/theme.h> -#include <ui/ui.h> - -#define W 1280 -#define H 720 - -static struct state *states[1]; -static int mouse_x; -static int mouse_y; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-debug") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Debug", W, H) < 0) - panic(); - - debug_options.enable = 1; -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_MOUSE: - mouse_x = ev->mouse.x; - mouse_y = ev->mouse.y; - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -draw(struct state *st) -{ - (void)st; - - struct debug_report report = {0}; - - painter_set_color(0x4f8fbaff); - painter_clear(); - debugf(&report, "Game running."); - debugf(&report, "mouse: %d, %d", mouse_x, mouse_y); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .draw = draw - }; - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -} -
--- a/examples/example-drawable/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,208 +0,0 @@ -/* - * example-drawable.c -- example on how to use automatic drawables - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdio.h> -#include <stdlib.h> - -#include <core/alloc.h> -#include <core/animation.h> -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/drawable.h> -#include <core/drawable-stack.h> -#include <core/key.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/sys.h> -#include <core/image.h> -#include <core/sprite.h> -#include <core/state.h> -#include <core/texture.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/label.h> -#include <ui/theme.h> -#include <ui/ui.h> - -#include <assets/sprites/explosion.h> - -#define W 1280 -#define H 720 - -static struct label help = { - .x = 10, - .y = 10, - .text = "Keys: <Esc> to reset. Click anywhere to spawn a drawable.", - .flags = LABEL_FLAGS_SHADOW -}; - -static struct state *states[1]; -static struct drawable *drawables[64]; -static struct drawable_stack stack; - -/* - * List of drawables for this example. - * ----------------------------------------------------------------------------- - */ - -/* 0: Explosion animation. */ -static struct texture explosion_tex; -static struct sprite explosion_sprite; - -struct explosion { - struct animation anim; - struct drawable dw; -}; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-drawable") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Drawable", W, H) < 0) - panic(); - - /* 0: Explosion animation. */ - if (image_openmem(&explosion_tex, assets_sprites_explosion, sizeof (assets_sprites_explosion)) < 0) - panic(); - - sprite_init(&explosion_sprite, &explosion_tex, 256, 256); -} - -static int -explosion_update(struct drawable *dw, unsigned int ticks) -{ - struct explosion *ex = dw->data; - - return animation_update(&ex->anim, ticks); -} - -static void -explosion_draw(struct drawable *dw) -{ - struct explosion *ex = dw->data; - - animation_draw(&ex->anim, ex->dw.x, ex->dw.y); -} - -static void -explosion_finish(struct drawable *dw) -{ - free(dw->data); -} - -static void -spawn(int x, int y) -{ - struct explosion *ex = alloc_new0(sizeof (*ex)); - - animation_init(&ex->anim, &explosion_sprite, 15); - - ex->dw.data = ex; - ex->dw.x = x - (int)(explosion_sprite.cellw / 2); - ex->dw.y = y - (int)(explosion_sprite.cellh / 2); - ex->dw.update = explosion_update; - ex->dw.draw = explosion_draw; - ex->dw.finish = explosion_finish; - - drawable_stack_add(&stack, &ex->dw); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_KEYDOWN: - switch (ev->key.key) { - case KEY_ESCAPE: - drawable_stack_finish(&stack); - break; - default: - break; - } - break; - case EVENT_CLICKDOWN: - spawn(ev->click.x, ev->click.y); - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -update(struct state *st, unsigned int ticks) -{ - (void)st; - - drawable_stack_update(&stack, ticks); - -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0xebede9ff); - painter_clear(); - label_draw(&help); - drawable_stack_draw(&stack); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .update = update, - .draw = draw - }; - - drawable_stack_init(&stack, drawables, UTIL_SIZE(drawables)); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -}
--- a/examples/example-font/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,148 +0,0 @@ -/* - * example-font.c -- show how to use fonts - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <core/core.h> -#include <core/event.h> -#include <core/font.h> -#include <core/game.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/texture.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/theme.h> -#include <ui/ui.h> - -#define W (1280) -#define H (720) - -/* Friendly taken from: https://lospec.com/palette-list/apollo */ -static const unsigned long colors[] = { - 0x3c5e8bff, /* Blue. */ - 0x468232ff, /* Green. */ - 0xad7757ff, /* Light brown. */ - 0x884b2bff, /* Brown. */ - 0x752438ff, /* Red. */ - 0x7a367bff, /* Magenta. */ - 0x151d28ff, /* Dark */ - 0xc7cfccff, /* Christian Grey. */ -}; - -static struct state *states[1]; -static int ci = 0; -static enum font_style style = FONT_STYLE_ANTIALIASED; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-font") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Font", W, H) < 0) - panic(); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_KEYDOWN: - switch (ev->key.key) { - case KEY_LEFT: - if (ci > 0) - ci--; - break; - case KEY_RIGHT: - if ((size_t)ci < UTIL_SIZE(colors)) - ci++; - break; - case KEY_SPACE: - if (style == FONT_STYLE_ANTIALIASED) - style = FONT_STYLE_NONE; - else - style = FONT_STYLE_ANTIALIASED; - - theme_default()->fonts[THEME_FONT_INTERFACE]->style = style; - default: - break; - } - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -draw(struct state *st) -{ - (void)st; - - struct font *font = theme_default()->fonts[THEME_FONT_INTERFACE]; - struct texture tex; - - painter_set_color(0xffffffff); - painter_clear(); - - if (font_render(font, &tex, "Example of text. Use <Left>/<Right> to change color and <Space> to toggle antialiasing.", colors[ci]) < 0) - panic(); - - texture_draw(&tex, 10, 10); - painter_present(); - texture_finish(&tex); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .draw = draw - }; - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); - - return 0; -}
--- a/examples/example-gridmenu/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,132 +0,0 @@ -/* - * example-gridmenu.c -- show how to use grid menu - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/trace.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/align.h> -#include <ui/gridmenu.h> -#include <ui/label.h> -#include <ui/theme.h> -#include <ui/ui.h> - -#define W (1280) -#define H (720) - -static struct state *states[1]; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-gridmenu") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Grid menu", W, H) < 0) - panic(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -static void -handle(struct state *st, const union event *ev) -{ - struct gridmenu *menu = st->data; - - switch (ev->type) { - case EVENT_QUIT: - game_quit(); - break; - default: - if (gridmenu_handle(st->data, ev)) - tracef("selected index: %zu (%s)", menu->selected, menu->items[menu->selected]); - break; - } -} - -static void -draw(struct state *st) -{ - painter_set_color(0x4f8fbaff); - painter_clear(); - gridmenu_draw(st->data); - painter_present(); -} - -static void -run(void) -{ - const char * const items[] = { - "Feu mineur", - "Feu majeur", - "Feu septième", - "Glace mineure", - "Glace majeure", - "Glace septième", - "Foudre mineure", - "Foudre majeure", - "Foudre septième", - "Choc mineur", - "Choc majeur", - "Choc septième", - "Portée", - "Escapade", - "Destruction", - "Résurrection", - "Double tour" - }; - - struct gridmenu menu = {0}; - struct state state = { - .data = &menu, - .handle = handle, - .draw = draw, - }; - - gridmenu_init(&menu, 3, 2, items, UTIL_SIZE(items)); - gridmenu_resize(&menu, 0, 0, 300, 100); - - align(ALIGN_CENTER, &menu.x, &menu.y, menu.w, menu.h, 0, 0, W, H); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -}
--- a/examples/example-label/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - * example-label.c -- show how to use label and alignments - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stddef.h> - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/align.h> -#include <ui/label.h> -#include <ui/theme.h> -#include <ui/ui.h> - -#define W (1280) -#define H (720) - -struct { - enum align align; - struct label label; -} table[] = { - { - .align = ALIGN_TOP_LEFT, - .label = { - .text = "Top left" - } - }, - { - .align = ALIGN_TOP, - .label = { - .text = "Top", - } - }, - { - .align = ALIGN_TOP_RIGHT, - .label = { - .text = "Top right", - } - }, - { - .align = ALIGN_RIGHT, - .label = { - .text = "Right", - } - }, - { - .align = ALIGN_BOTTOM_RIGHT, - .label = { - .text = "Bottom right", - } - }, - { - .align = ALIGN_BOTTOM, - .label = { - .text = "Bottom", - } - }, - { - .align = ALIGN_BOTTOM_LEFT, - .label = { - .text = "Bottom left", - } - }, - { - .align = ALIGN_LEFT, - .label = { - .text = "Left", - } - }, - { - .align = ALIGN_CENTER, - .label = { - .text = "The world is Malikania.", - .flags = LABEL_FLAGS_SHADOW - } - } -}; - -static struct label mlabel = { - .text = "This one follows your mouse and is not aligned." -}; - -static struct state *states[1]; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-label") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Label", W, H) < 0) - panic(); - - for (size_t i = 0; i < UTIL_SIZE(table); ++i) { - struct label *l = &table[i].label; - unsigned int w, h; - - label_query(l, &w, &h); - align(table[i].align, &l->x, &l->y, w, h, 0, 0, W, H); - } -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_MOUSE: - mlabel.x = ev->mouse.x; - mlabel.y = ev->mouse.y; - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0x4f8fbaff); - painter_clear(); - - for (size_t i = 0; i < UTIL_SIZE(table); ++i) - label_draw(&table[i].label); - - label_draw(&mlabel); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .draw = draw - }; - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -}
--- a/examples/example-message/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,350 +0,0 @@ -/* - * example-message.c -- show how to use messages - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stddef.h> - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/frame.h> -#include <ui/theme.h> -#include <ui/ui.h> - -#include <rpg/message.h> -#include <rpg/rpg.h> - -#define W (1280) -#define H (720) - -#define MW (W * 0.75) -#define MH (H * 0.120) -#define MX ((W / 2) - (MW / 2)) -#define MY (100) - -static struct state *states[1]; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-message") < 0 || ui_init() < 0 || rpg_init() < 0) - panic(); - if (window_open("Example - Message", W, H) < 0) - panic(); -} - -static void -quit(void) -{ - window_finish(); - rpg_finish(); - ui_finish(); - core_finish(); -} - -static void -handle(struct state *st, const union event *ev) -{ - switch (ev->type) { - case EVENT_QUIT: - game_quit(); - break; - default: - message_handle(st->data, ev); - break; - } -} - -static void -update(struct state *st, unsigned int ticks) -{ - if (message_update(st->data, ticks)) - game_quit(); -} - -static void -draw(struct state *st) -{ - painter_set_color(0xffffffff); - painter_clear(); - message_draw(st->data); - painter_present(); -} - -static void -run(struct message *msg) -{ - struct state state = { - .data = msg, - .handle = handle, - .update = update, - .draw = draw - }; - - message_start(msg); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -my_draw_frame(const struct theme *th, const struct frame *f) -{ - (void)th; - - painter_set_color(0xff0000ff); - painter_draw_rectangle(f->x, f->y, f->w, f->h); -} - -static void -basic(void) -{ - const char * const text[] = { - "This is a basic message.", - "Vertical spacing is automatically computed.", - "You need to press <Enter> to close it.", - }; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .spacing = 12, - .lines = text, - .linesz = 3 - }; - - message_query(&msg, NULL, &msg.h); - run(&msg); -} - -static void -automatic(void) -{ - const char * const text[] = { - "This is a an automatic message.", - "It will disappear in a few seconds.", - "You can still press <Enter> to close it quicker." - }; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .timeout = MESSAGE_TIMEOUT_DEFAULT, - .lines = text, - .linesz = 3, - .flags = MESSAGE_FLAGS_AUTOMATIC - }; - - message_query(&msg, NULL, &msg.h); - run(&msg); -} - -static void -fadein(void) -{ - const char * const text[] = { - "This message will fade in." - }; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, - .lines = text, - .linesz = 1, - .flags = MESSAGE_FLAGS_FADEIN - }; - - message_query(&msg, NULL, &msg.h); - run(&msg); -} - -static void -fadeout(void) -{ - const char * const text[] = { - "This message will fade out." - }; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, - .lines = text, - .linesz = 1, - .flags = MESSAGE_FLAGS_FADEOUT - }; - - message_query(&msg, NULL, &msg.h); - run(&msg); -} - -static void -fade(void) -{ - const char * const text[] = { - "This message will fade in and out." - }; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .delay = MESSAGE_DELAY_DEFAULT, - .lines = text, - .linesz = 1, - .flags = MESSAGE_FLAGS_FADEIN | MESSAGE_FLAGS_FADEOUT - }; - - message_query(&msg, NULL, &msg.h); - run(&msg); -} - -static void -question(void) -{ - const char * const text[] = { - "Okay, I've understood.", - "Nevermind, I'll do it again." - }; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .lines = text, - .linesz = 2, - .flags = MESSAGE_FLAGS_QUESTION - }; - - message_query(&msg, NULL, &msg.h); - run(&msg); -} - -static void -smallbottom(void) -{ - const unsigned int w = window.w / 4; - const unsigned int h = MH; - const int x = (window.w / 2) - (w / 2); - const int y = (window.h - h - 10); - const char * const text[] = { - "This one is small here." - }; - - struct message msg = { - .x = x, - .y = y, - .w = w, - .h = h, - .delay = MESSAGE_DELAY_DEFAULT, - .flags = MESSAGE_FLAGS_FADEIN | MESSAGE_FLAGS_FADEOUT, - .lines = text, - .linesz = 1 - }; - - run(&msg); -} - -static void -toosmallh(void) -{ - const char * const text[] = { - "This one is too small in height and will emit a warning.", - "Because this line will be incomplete." - }; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .h = 40, - .lines = text, - .linesz = 2 - }; - - run(&msg); -} - -static void -toosmallw(void) -{ - const char * const text[] = { - "This one is too small in width." - }; - struct message msg = { - .x = MX, - .y = MY, - .w = 160, - .h = MH, - .lines = text, - .linesz = 1 - }; - - run(&msg); -} - -static void -custom(void) -{ - const char * const text[] = { - "This one will destroy your eyes.", - "Because it use a terrible custom theme." - }; - struct theme theme; - struct message msg = { - .x = MX, - .y = MY, - .w = MW, - .h = MH, - .lines = text, - .linesz = 2, - .theme = &theme - }; - - /* Borrow default theme and change its frame drawing. */ - theme_shallow(&theme, NULL); - theme.draw_frame = my_draw_frame; - theme.colors[THEME_COLOR_NORMAL] = 0x0000ffff; - - run(&msg); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - basic(); - fadein(); - fadeout(); - fade(); - automatic(); - question(); - smallbottom(); - toosmallh(); - toosmallw(); - custom(); - quit(); -}
--- a/examples/example-notify/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -/* - * example-notify -- show how notifications work - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/image.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/texture.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/notify.h> -#include <ui/label.h> -#include <ui/ui.h> - -/* Sword by Icongeek26 (https://www.flaticon.com). */ -#include <assets/images/sword.h> - -#define W 1280 -#define H 720 - -static struct label help = { - .text = "Keys: <Space> to generate a notification.", - .x = 10, - .y = 10, - .flags = LABEL_FLAGS_SHADOW -}; -static struct texture icon; -static struct state *states[1]; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-notify") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Notify", W, H) < 0) - panic(); - if (image_openmem(&icon, assets_images_sword, sizeof (assets_images_sword)) < 0) - panic(); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_QUIT: - game_quit(); - break; - case EVENT_KEYDOWN: - if (ev->key.key == KEY_SPACE) - notify(&icon, "Quest", "Quest finished."); - break; - default: - break; - } -} - -static void -update(struct state *st, unsigned int ticks) -{ - (void)st; - - notify_update(ticks); -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0xffffffff); - painter_clear(); - label_draw(&help); - notify_draw(); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .update = update, - .draw = draw - }; - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); - - return 0; -}
--- a/examples/example-sprite/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,164 +0,0 @@ -/* - * example-sprite.c -- example on how to use sprites - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdio.h> - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/image.h> -#include <core/key.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/image.h> -#include <core/sprite.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/texture.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/align.h> -#include <ui/label.h> -#include <ui/ui.h> - -#include <assets/sprites/people.h> - -#define W 1280 -#define H 720 -#define HEADER "Keys: <Left>/<Right> and <Up/Down> to select a column/row. Current: %u, %u (total %u/%u)" - -static char msg[512]; -static struct texture texture; -static struct sprite sprite; -static unsigned int row, column; -static struct state *states[1]; - -static struct label help = { - .x = 10, - .y = 10, - .text = msg, - .flags = LABEL_FLAGS_SHADOW -}; - -static void -changed(void) -{ - snprintf(msg, sizeof (msg), HEADER, column, row, sprite.ncols, sprite.nrows); -} - -static void -init(void) -{ - if (core_init("fr.malikania", "example-sprite") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Sprite", W, H) < 0) - panic(); - if (image_openmem(&texture, assets_sprites_people, sizeof (assets_sprites_people)) < 0) - panic(); - - sprite_init(&sprite, &texture, 48, 48); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_KEYDOWN: - switch (ev->key.key) { - case KEY_LEFT: - if (column > 0) - column--; - break; - case KEY_RIGHT: - if (column + 1 < sprite.ncols) - column++; - break; - case KEY_UP: - if (row > 0) - row--; - break; - case KEY_DOWN: - if (row + 1 < sprite.nrows) - row++; - break; - default: - break; - } - - changed(); - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -draw(struct state *st) -{ - (void)st; - - int x, y; - - painter_set_color(0xebede9ff); - painter_clear(); - align(ALIGN_CENTER, &x, &y, sprite.cellw, sprite.cellh, 0, 0, W, H); - sprite_draw(&sprite, row, column, x, y); - label_draw(&help); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .draw = draw - }; - - changed(); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - texture_finish(&texture); - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -}
--- a/examples/example-trace/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,129 +0,0 @@ -/* - * example-trace.c -- example on how to use custom trace handlers - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/sys.h> -#include <core/window.h> -#include <core/painter.h> -#include <core/panic.h> -#include <core/state.h> -#include <core/trace.h> -#include <core/util.h> - -#include <ui/theme.h> -#include <ui/ui.h> - -#include "trace_hud.h" - -#define W 1280 -#define H 720 - -static struct state *states[1]; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-trace") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - Trace", W, H) < 0) - panic(); - - trace_handler = trace_hud_handler; -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_KEYDOWN: - switch (ev->key.key) { - case KEY_ESCAPE: - trace_hud_clear(); - break; - default: - tracef("keydown pressed: %d", ev->key.key); - break; - } - break; - case EVENT_CLICKDOWN: - tracef("click at %d,%d", ev->click.x, ev->click.y); - break; - case EVENT_QUIT: - game_quit(); - break; - default: - break; - } -} - -static void -update(struct state *st, unsigned int ticks) -{ - (void)st; - - trace_hud_update(ticks); -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0x4f8fbaff); - painter_clear(); - trace_hud_draw(); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .update = update, - .draw = draw - }; - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); -} -
--- a/examples/example-trace/trace_hud.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,145 +0,0 @@ -/* - * trace_hud.c -- on screen hud - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <stdio.h> -#include <string.h> - -#include <core/action.h> -#include <core/font.h> -#include <core/trace.h> -#include <core/window.h> - -#include <ui/label.h> -#include <ui/theme.h> - -#include "trace_hud.h" - -#define LINES_MAX (4) -#define THEME(t) ((t) ? (t) : theme_default()) - -static struct { - char lines[LINES_MAX + 1][TRACE_LINE_MAX]; - unsigned int elapsed; -} data; - -struct trace_hud trace_hud = { - .timeout = TRACE_HUD_TIMEOUT_DEFAULT -}; - -void -trace_hud_handler(const char *str) -{ - assert(str); - - /* 1.Try to find an empty line. */ - for (size_t i = 0; i < LINES_MAX; ++i) { - if (data.lines[i][0] == '\0') { - snprintf(data.lines[i], sizeof (data.lines[i]), "%s", str); - return; - } - } - - /* 2. All lines are full, put in last one and move other. */ - memmove(&data.lines[0], &data.lines[1], sizeof (data.lines[0]) * LINES_MAX - 1); - snprintf(data.lines[LINES_MAX - 1], sizeof (data.lines[0]), "%s", str); - - /* 3. Reset elapsed time now. */ - data.elapsed = 0; -} - -void -trace_hud_update(unsigned int ticks) -{ - data.elapsed += ticks; - - /* - * We have an empty line in the data.lines at LINES_MAX, so we simply so - * to move the whole array. - * - * [0] = "abc" - * [1] = "def" - * [2] = "xyz" - * [3] = "zef" - * [n] = "ldkf" - * [LINES_MAX + 1] = "\0" - */ - if (data.elapsed >= trace_hud.timeout) { - data.elapsed = 0; - memmove(&data.lines[0], &data.lines[1], sizeof (data.lines[0]) * LINES_MAX); - } -} - -void -trace_hud_draw(void) -{ - struct theme *th; - int x, y; - - th = THEME(trace_hud.theme); - x = th->padding; - y = th->padding; - - for (int i = 0; i < LINES_MAX && data.lines[i][0]; ++i) { - label_draw(&(struct label) { - .x = x, - .y = y, - .text = data.lines[i], - .theme = th, - .flags = LABEL_FLAGS_SHADOW - }); - - y += font_height(th->fonts[THEME_FONT_INTERFACE]); - y += th->padding; - } -} - -void -trace_hud_clear(void) -{ - memset(&data, 0, sizeof (data)); -} - -static int -update(struct action *a, unsigned int ticks) -{ - (void)a; - - trace_hud_update(ticks); - - return 0; -} - -static void -draw(struct action *a) -{ - (void)a; - - trace_hud_draw(); -} - -struct action * -trace_hud_action(void) -{ - static struct action a = { - .update = update, - .draw = draw - }; - - return &a; -}
--- a/examples/example-trace/trace_hud.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -/* - * trace_hud.h -- on screen hud - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef EXAMPLES_TRACE_TRACE_HUD_H -#define EXAMPLES_TRACE_TRACE_HUD_H - -#define TRACE_HUD_TIMEOUT_DEFAULT (3000) - -struct action; -struct theme; - -struct trace_hud { - struct theme *theme; - unsigned int timeout; -}; - -extern struct trace_hud trace_hud; - -void -trace_hud_handler(const char *); - -void -trace_hud_update(unsigned int); - -void -trace_hud_draw(void); - -void -trace_hud_clear(void); - -struct action * -trace_hud_action(void); - -#endif /* !EXAMPLES_TRACE_TRACE_HUD_H */
--- a/examples/example-ui/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,288 +0,0 @@ -/* - * example-action.c -- example on how to use automatic actions - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <core/core.h> -#include <core/event.h> -#include <core/game.h> -#include <core/maths.h> -#include <core/panic.h> -#include <core/painter.h> -#include <core/state.h> -#include <core/sys.h> -#include <core/util.h> -#include <core/window.h> - -#include <ui/align.h> -#include <ui/button.h> -#include <ui/checkbox.h> -#include <ui/frame.h> -#include <ui/label.h> -#include <ui/theme.h> -#include <ui/ui.h> - -#define W (1280) -#define H (720) - -#define FRAME_ORIGIN_X (10) -#define FRAME_ORIGIN_Y (10) -#define FRAME_WIDTH (400) -#define FRAME_HEIGHT (200) - -#define HEADER_HEIGHT (32) - -#define ELEMENT_HEIGHT (20) - -/* - * We design a basic UI like this. - * - * FRAME_WIDTH - * +---------------------------------------------+-- - * | Title | | HEADER_HEIGHT - * +---------------------------------------------+-- - * | [x] Auto save | - * | | - * | | - * | [ Quit ] | - * +---------------------------------------------+ - */ -static struct { - struct { - int active; - int x; - int y; - } motion; - - struct { - struct frame frame; - } panel; - - struct { - struct label label; - } header; - - struct { - struct checkbox cb; - struct label label; - } autosave; - - struct { - struct button button; - } quit; -} ui = { - .panel = { - .frame = { - .x = FRAME_ORIGIN_X, - .y = FRAME_ORIGIN_Y, - .w = FRAME_WIDTH, - .h = FRAME_HEIGHT - } - }, - .header = { - .label = { - .text = "Preferences", - .x = FRAME_ORIGIN_X, - .y = FRAME_ORIGIN_Y, - .flags = LABEL_FLAGS_SHADOW, - } - }, - .autosave = { - .cb = { - .w = ELEMENT_HEIGHT, - .h = ELEMENT_HEIGHT - }, - .label = { - .text = "Auto save game", - .flags = LABEL_FLAGS_SHADOW, - } - }, - .quit = { - .button = { - .text = "Quit", - .h = ELEMENT_HEIGHT - } - } -}; - -static struct state *states[1]; - -static void -init(void) -{ - if (core_init("fr.malikania", "example-ui") < 0 || ui_init() < 0) - panic(); - if (window_open("Example - UI", W, H) < 0) - panic(); -} - -static void -resize_header(void) -{ - struct frame *f = &ui.panel.frame; - struct label *l = &ui.header.label; - unsigned int w, h; - - /* Header. */ - label_query(l, &w, &h); - align(ALIGN_LEFT, &l->x, &l->y, w, h, f->x, f->y, f->w, HEADER_HEIGHT); - - l->x += theme_default()->padding; -} - -static void -resize_autosave(void) -{ - unsigned int padding = theme_default()->padding; - struct frame *f = &ui.panel.frame; - struct checkbox *c = &ui.autosave.cb; - struct label *l = &ui.autosave.label; - - c->x = f->x + padding; - c->y = f->y + HEADER_HEIGHT + padding; - - l->x = c->x + c->w + padding; - l->y = c->y; -} - -static void -resize_button(void) -{ - unsigned int padding = theme_default()->padding; - struct frame *f = &ui.panel.frame; - struct button *b = &ui.quit.button; - - /* Button. */ - b->w = f->w / 4; - - align(ALIGN_BOTTOM_RIGHT, &b->x, &b->y, b->w, b->h, - f->x, f->y, f->w, f->h); - - b->x -= padding; - b->y -= padding; -} - -static void -resize(void) -{ - resize_header(); - resize_autosave(); - resize_button(); -} - -static int -headerclick(int x, int y) -{ - return maths_is_boxed( - ui.panel.frame.x, - ui.panel.frame.y, - ui.panel.frame.w, - HEADER_HEIGHT, - x, - y - ); -} - -static void -handle(struct state *st, const union event *ev) -{ - (void)st; - - switch (ev->type) { - case EVENT_QUIT: - game_quit(); - break; - case EVENT_MOUSE: - if (ui.motion.active) { - ui.panel.frame.x += ev->mouse.x - ui.motion.x; - ui.panel.frame.y += ev->mouse.y - ui.motion.y; - ui.motion.x = ev->mouse.x; - ui.motion.y = ev->mouse.y; - resize(); - } - break; - case EVENT_CLICKDOWN: - if (headerclick(ev->click.x, ev->click.y)) { - ui.motion.active = 1; - ui.motion.x = ev->click.x; - ui.motion.y = ev->click.y; - window_set_cursor(WINDOW_CURSOR_SIZE); - } - break; - case EVENT_CLICKUP: - ui.motion.active = 0; - window_set_cursor(WINDOW_CURSOR_ARROW); - break; - default: - break; - } - - checkbox_handle(&ui.autosave.cb, ev); - - if (button_handle(&ui.quit.button, ev)) - game_quit(); -} - -static void -draw(struct state *st) -{ - (void)st; - - painter_set_color(0xffffffff); - painter_clear(); - frame_draw(&ui.panel.frame); - label_draw(&ui.header.label); - checkbox_draw(&ui.autosave.cb); - label_draw(&ui.autosave.label); - button_draw(&ui.quit.button); - painter_present(); -} - -static void -run(void) -{ - struct state state = { - .handle = handle, - .draw = draw - }; - - resize(); - - game_init(states, UTIL_SIZE(states)); - game_push(&state); - game_loop(); -} - -static void -quit(void) -{ - window_finish(); - ui_finish(); - core_finish(); -} - -int -main(int argc, char **argv) -{ - (void)argc; - (void)argv; - - init(); - run(); - quit(); - - return 0; -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/character-john.c Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,50 @@ +/* + * character-john.c -- john character + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <rpg/character.h> + +#include "character-john.h" +#include "spell-fire.h" +#include "registry.h" + +static void +adventurer_reset(struct character *ch) +{ + /* TODO: this function should compute the attack thanks to the level. */ + ch->hpmax = 120; + ch->mpmax = 50; + ch->atk = 50; + ch->def = 50; + ch->agt = 50; + ch->luck = 50; +} + +const struct character character_john = { + .name = "John ", + .level = 1, + .hp = 120, + .mp = 50, + .reset = adventurer_reset, + .sprites = { + [CHARACTER_SPRITE_NORMAL] = ®istry_sprites[REGISTRY_TEXTURE_JOHN_WALK], + [CHARACTER_SPRITE_SWORD] = ®istry_sprites[REGISTRY_TEXTURE_JOHN_SWORD] + }, + .spells = { + &spell_fire + } +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/character-john.h Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,24 @@ +/* + * character-john.h -- john character + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef EXAMPLES_BATTLE_CHARACTER_JOHN_H +#define EXAMPLES_BATTLE_CHARACTER_JOHN_H + +const struct character character_john; + +#endif /* !EXAMPLES_BATTLE_CHARACTER_JOHN_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/registry.c Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,140 @@ +/* + * registry.h -- registry of resources + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stddef.h> + +#include <core/image.h> +#include <core/panic.h> +#include <core/util.h> +#include <core/sys.h> + +#include <assets/images/battle-background.h> +#include <assets/images/black-cat.h> +#include <assets/images/haunted-wood.h> + +#include <assets/sounds/fire.h> + +#include <assets/sprites/explosion.h> +#include <assets/sprites/john-sword.h> +#include <assets/sprites/john-walk.h> +#include <assets/sprites/ui-cursor.h> + +#include "registry.h" + +struct texture registry_images[REGISTRY_IMAGE_NUM]; +struct texture registry_textures[REGISTRY_TEXTURE_NUM]; +struct sprite registry_sprites[REGISTRY_TEXTURE_NUM]; +struct sound registry_sounds[REGISTRY_SOUND_NUM]; + +#define REGISTRY_IMAGE(i, data) \ + { (i), (data), sizeof (data) } + +static const struct { + enum registry_image index; + const unsigned char *data; + size_t datasz; +} images[] = { + REGISTRY_IMAGE(REGISTRY_IMAGE_BATTLE_BACKGROUND, assets_battle_background) +}; + +#define REGISTRY_TEXTURE(s, data, cw, ch) \ + { (s), (data), sizeof (data), (cw), (ch) } + +static const struct { + enum registry_texture index; + const unsigned char *data; + size_t datasz; + unsigned int cellw; + unsigned int cellh; +} textures[] = { + REGISTRY_TEXTURE(REGISTRY_TEXTURE_CURSOR, assets_ui_cursor, 24, 24), + REGISTRY_TEXTURE(REGISTRY_TEXTURE_EXPLOSION, assets_explosion, 256, 256), + REGISTRY_TEXTURE(REGISTRY_TEXTURE_JOHN_SWORD, assets_john_sword, 256, 256), + REGISTRY_TEXTURE(REGISTRY_TEXTURE_JOHN_WALK, assets_john_walk, 256, 256), + REGISTRY_TEXTURE(REGISTRY_TEXTURE_HAUNTED_WOOD, assets_haunted_wood, 0, 0), + REGISTRY_TEXTURE(REGISTRY_TEXTURE_BLACK_CAT, assets_black_cat, 0, 0) +}; + +#define REGISTRY_SOUND(s, data) \ + { (s), (data), sizeof (data) } + +static const struct { + enum registry_sound index; + const unsigned char *data; + size_t datasz; +} sounds[] = { + REGISTRY_SOUND(REGISTRY_SOUND_FIRE, assets_fire) +}; + +static void +load_images(void) +{ + for (size_t i = 0; i < UTIL_SIZE(images); ++i) { + struct texture *texture = ®istry_images[images[i].index]; + + if (image_openmem(texture, images[i].data, images[i].datasz) < 0) + panic(); + } +} + +static void +load_textures_and_sprites(void) +{ + for (size_t i = 0; i < UTIL_SIZE(textures); ++i) { + struct texture *texture = ®istry_textures[textures[i].index]; + struct sprite *sprite = ®istry_sprites[textures[i].index]; + + if (image_openmem(texture, textures[i].data, textures[i].datasz) < 0) + panic(); + + if (textures[i].cellw == 0 || textures[i].cellh == 0) + sprite_init(sprite, texture, texture->w, texture->h); + else + sprite_init(sprite, texture, textures[i].cellw, textures[i].cellh); + } +} + +static void +load_sounds(void) +{ + for (size_t i = 0; i < UTIL_SIZE(sounds); ++i) { + struct sound *sound = ®istry_sounds[sounds[i].index]; + + if (sound_openmem(sound, sounds[i].data, sounds[i].datasz) < 0) + panic(); + } +} + +void +registry_init(void) +{ + load_images(); + load_textures_and_sprites(); + load_sounds(); +} + +void +registry_finish(void) +{ + for (size_t i = 0; i < UTIL_SIZE(registry_images); ++i) + texture_finish(®istry_images[i]); + for (size_t i = 0; i < UTIL_SIZE(registry_textures); ++i) + texture_finish(®istry_textures[i]); + for (size_t i = 0; i < UTIL_SIZE(registry_sounds); ++i) + sound_finish(®istry_sounds[i]); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/registry.h Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,66 @@ +/* + * registry.h -- registry of resources + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef EXAMPLES_BATTLE_REGISTRY_H +#define EXAMPLES_BATTLE_REGISTRY_H + +#include <core/sound.h> +#include <core/sprite.h> +#include <core/texture.h> + +enum registry_texture { + /* UI. */ + REGISTRY_TEXTURE_CURSOR, + + /* Animations. */ + REGISTRY_TEXTURE_EXPLOSION, + + /* Characters. */ + REGISTRY_TEXTURE_JOHN_WALK, + REGISTRY_TEXTURE_JOHN_SWORD, + + /* Enemies. */ + REGISTRY_TEXTURE_HAUNTED_WOOD, + REGISTRY_TEXTURE_BLACK_CAT, + + /* Unused.*/ + REGISTRY_TEXTURE_NUM +}; + +enum registry_image { + REGISTRY_IMAGE_BATTLE_BACKGROUND, + REGISTRY_IMAGE_NUM +}; + +enum registry_sound { + REGISTRY_SOUND_FIRE, + REGISTRY_SOUND_NUM +}; + +extern struct texture registry_images[REGISTRY_IMAGE_NUM]; +extern struct texture registry_textures[REGISTRY_TEXTURE_NUM]; +extern struct sprite registry_sprites[REGISTRY_TEXTURE_NUM]; +extern struct sound registry_sounds[REGISTRY_SOUND_NUM]; + +void +registry_init(void); + +void +registry_finish(void); + +#endif /* !EXAMPLES_BATTLE_REGISTRY_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/spell-fire.c Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,132 @@ +/* + * spell-fire.c -- example of spell: fire + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <stdlib.h> + +#include <core/action.h> +#include <core/animation.h> +#include <core/drawable.h> +#include <core/alloc.h> + +#include <ui/align.h> + +#include <rpg/battle-state-check.h> +#include <rpg/battle-state-rendering.h> +#include <rpg/battle.h> +#include <rpg/character.h> +#include <rpg/spell.h> + +#include "registry.h" +#include "spell-fire.h" + +struct self { + struct battle *battle; + struct character *target; + struct animation animation; + struct drawable drawable; + unsigned int selection; +}; + +static int +update(struct drawable *dw, unsigned int ticks) +{ + struct self *self = dw->data; + + return animation_update(&self->animation, ticks); +} + +static void +draw(struct drawable *dw) +{ + const struct self *self = dw->data; + const struct battle_entity *et = self->battle->enemies[self->selection]; + const struct sprite *sprite = et->ch->sprites[CHARACTER_SPRITE_NORMAL]; + int x, y; + + align(ALIGN_CENTER, + &x, &y, self->animation.sprite->cellw, self->animation.sprite->cellh, + et->x, et->y, sprite->cellw, sprite->cellh); + + animation_draw(&self->animation, x, y); +} + +static void +end(struct drawable *dw) +{ + struct self *self = dw->data; + struct character *ch = self->battle->enemies[self->selection]->ch; + + /* TODO: compute damage. */ + const unsigned int damage = 100; + + if ((unsigned int)ch->hp < damage) + ch->hp = 0; + else + ch->hp -= damage; + + battle_indicator_hp(self->battle, self->battle->enemies[self->selection]->ch, 100); + battle_state_check(self->battle); +} + +static void +finish(struct drawable *dw) +{ + free(dw->data); +} + +static void +fire_select(const struct battle *bt, struct selection *slt) +{ + slt->index_side = 0; + + selection_first(slt, bt); +} + +static void +fire_action(struct battle *bt, struct character *owner, const struct selection *slt) +{ + struct self *self; + + (void)owner; + + self = alloc_new0(sizeof (*self)); + self->selection = slt->index_character; + self->battle = bt; + self->drawable.data = self; + self->drawable.update = update; + self->drawable.draw = draw; + self->drawable.finish = finish; + self->drawable.end = end; + + animation_init(&self->animation, ®istry_sprites[REGISTRY_TEXTURE_EXPLOSION], 12); + animation_start(&self->animation); + + sound_play(®istry_sounds[REGISTRY_SOUND_FIRE]); + battle_state_rendering(bt, &self->drawable); +} + +const struct spell spell_fire = { + .name = "Fire", + .description = "A delicate fire.", + .mp = 5, + .type = SPELL_TYPE_FIRE, + .select = fire_select, + .select_kind = SELECTION_KIND_ONE, + .select_side = SELECTION_SIDE_ENEMY, + .action = fire_action +};
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/spell-fire.h Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,24 @@ +/* + * spell-fire.c -- example of spell: fire + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef EXAMPLES_BATTLE_SPELL_FIRE_H +#define EXAMPLES_BATTLE_SPELL_FIRE_H + +extern const struct spell spell_fire; + +#endif /* !EXAMPLES_BATTLE_SPELL_FIRE_H */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/trace_hud.c Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,145 @@ +/* + * trace_hud.c -- on screen hud + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdio.h> +#include <string.h> + +#include <core/action.h> +#include <core/font.h> +#include <core/trace.h> +#include <core/window.h> + +#include <ui/label.h> +#include <ui/theme.h> + +#include "trace_hud.h" + +#define LINES_MAX (4) +#define THEME(t) ((t) ? (t) : theme_default()) + +static struct { + char lines[LINES_MAX + 1][TRACE_LINE_MAX]; + unsigned int elapsed; +} data; + +struct trace_hud trace_hud = { + .timeout = TRACE_HUD_TIMEOUT_DEFAULT +}; + +void +trace_hud_handler(const char *str) +{ + assert(str); + + /* 1.Try to find an empty line. */ + for (size_t i = 0; i < LINES_MAX; ++i) { + if (data.lines[i][0] == '\0') { + snprintf(data.lines[i], sizeof (data.lines[i]), "%s", str); + return; + } + } + + /* 2. All lines are full, put in last one and move other. */ + memmove(&data.lines[0], &data.lines[1], sizeof (data.lines[0]) * LINES_MAX - 1); + snprintf(data.lines[LINES_MAX - 1], sizeof (data.lines[0]), "%s", str); + + /* 3. Reset elapsed time now. */ + data.elapsed = 0; +} + +void +trace_hud_update(unsigned int ticks) +{ + data.elapsed += ticks; + + /* + * We have an empty line in the data.lines at LINES_MAX, so we simply so + * to move the whole array. + * + * [0] = "abc" + * [1] = "def" + * [2] = "xyz" + * [3] = "zef" + * [n] = "ldkf" + * [LINES_MAX + 1] = "\0" + */ + if (data.elapsed >= trace_hud.timeout) { + data.elapsed = 0; + memmove(&data.lines[0], &data.lines[1], sizeof (data.lines[0]) * LINES_MAX); + } +} + +void +trace_hud_draw(void) +{ + struct theme *th; + int x, y; + + th = THEME(trace_hud.theme); + x = th->padding; + y = th->padding; + + for (int i = 0; i < LINES_MAX && data.lines[i][0]; ++i) { + label_draw(&(struct label) { + .x = x, + .y = y, + .text = data.lines[i], + .theme = th, + .flags = LABEL_FLAGS_SHADOW + }); + + y += font_height(th->fonts[THEME_FONT_INTERFACE]); + y += th->padding; + } +} + +void +trace_hud_clear(void) +{ + memset(&data, 0, sizeof (data)); +} + +static int +update(struct action *a, unsigned int ticks) +{ + (void)a; + + trace_hud_update(ticks); + + return 0; +} + +static void +draw(struct action *a) +{ + (void)a; + + trace_hud_draw(); +} + +struct action * +trace_hud_action(void) +{ + static struct action a = { + .update = update, + .draw = draw + }; + + return &a; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/examples/example/trace_hud.h Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,49 @@ +/* + * trace_hud.h -- on screen hud + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef EXAMPLES_TRACE_TRACE_HUD_H +#define EXAMPLES_TRACE_TRACE_HUD_H + +#define TRACE_HUD_TIMEOUT_DEFAULT (3000) + +struct action; +struct theme; + +struct trace_hud { + struct theme *theme; + unsigned int timeout; +}; + +extern struct trace_hud trace_hud; + +void +trace_hud_handler(const char *); + +void +trace_hud_update(unsigned int); + +void +trace_hud_draw(void); + +void +trace_hud_clear(void); + +struct action * +trace_hud_action(void); + +#endif /* !EXAMPLES_TRACE_TRACE_HUD_H */
--- a/src/libmlk-core-js/CMakeLists.txt Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -# -# CMakeLists.txt -- CMake build system for Molko's Engine -# -# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -project(libmlk-core-js) - -set( - SOURCES - ${libmlk-core-js_SOURCE_DIR}/core/js-action-stack.c - ${libmlk-core-js_SOURCE_DIR}/core/js-action-stack.h - ${libmlk-core-js_SOURCE_DIR}/core/js-action.c - ${libmlk-core-js_SOURCE_DIR}/core/js-action.h - ${libmlk-core-js_SOURCE_DIR}/core/js-animation.c - ${libmlk-core-js_SOURCE_DIR}/core/js-animation.h - ${libmlk-core-js_SOURCE_DIR}/core/js-clock.c - ${libmlk-core-js_SOURCE_DIR}/core/js-clock.h - ${libmlk-core-js_SOURCE_DIR}/core/js-color.c - ${libmlk-core-js_SOURCE_DIR}/core/js-color.h - ${libmlk-core-js_SOURCE_DIR}/core/js-core.c - ${libmlk-core-js_SOURCE_DIR}/core/js-core.h - ${libmlk-core-js_SOURCE_DIR}/core/js-drawable-stack.c - ${libmlk-core-js_SOURCE_DIR}/core/js-drawable-stack.h - ${libmlk-core-js_SOURCE_DIR}/core/js-drawable.c - ${libmlk-core-js_SOURCE_DIR}/core/js-drawable.h - ${libmlk-core-js_SOURCE_DIR}/core/js-event.c - ${libmlk-core-js_SOURCE_DIR}/core/js-event.h - ${libmlk-core-js_SOURCE_DIR}/core/js-font.c - ${libmlk-core-js_SOURCE_DIR}/core/js-font.h - ${libmlk-core-js_SOURCE_DIR}/core/js-game.c - ${libmlk-core-js_SOURCE_DIR}/core/js-game.h - ${libmlk-core-js_SOURCE_DIR}/core/js-music.c - ${libmlk-core-js_SOURCE_DIR}/core/js-music.h - ${libmlk-core-js_SOURCE_DIR}/core/js-painter.c - ${libmlk-core-js_SOURCE_DIR}/core/js-painter.h - ${libmlk-core-js_SOURCE_DIR}/core/js-panic.c - ${libmlk-core-js_SOURCE_DIR}/core/js-panic.h - ${libmlk-core-js_SOURCE_DIR}/core/js-sound.c - ${libmlk-core-js_SOURCE_DIR}/core/js-sound.h - ${libmlk-core-js_SOURCE_DIR}/core/js-sprite.c - ${libmlk-core-js_SOURCE_DIR}/core/js-sprite.h - ${libmlk-core-js_SOURCE_DIR}/core/js-state.c - ${libmlk-core-js_SOURCE_DIR}/core/js-state.h - ${libmlk-core-js_SOURCE_DIR}/core/js-texture.c - ${libmlk-core-js_SOURCE_DIR}/core/js-texture.h - ${libmlk-core-js_SOURCE_DIR}/core/js-trace.c - ${libmlk-core-js_SOURCE_DIR}/core/js-trace.h - ${libmlk-core-js_SOURCE_DIR}/core/js-window.c - ${libmlk-core-js_SOURCE_DIR}/core/js-window.h -) - -mlk_library( - NAME libmlk-core-js - SOURCES ${SOURCES} - LIBRARIES libmlk-core libmlk-duktape - INCLUDES - PUBLIC $<BUILD_INTERFACE:${libmlk-core-js_SOURCE_DIR}> -) - -source_group(TREE ${libmlk-core-js_SOURCE_DIR} FILES ${SOURCES})
--- a/src/libmlk-core-js/core/js-action-stack.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,143 +0,0 @@ -/* - * js-drawable-stack.h -- core drawable_stack binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/action.h> -#include <core/action-stack.h> -#include <core/alloc.h> - -#include "js-event.h" -#include "js-action-stack.h" -#include "js-action.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.ActionStack") - -static inline struct action_stack * -self(duk_context *ctx) -{ - struct action_stack *sf = NULL; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - sf = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!sf) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a ActionStack object"), NULL; - - return sf; -} - -static duk_ret_t -ActionStack_constructor(duk_context *ctx) -{ - duk_push_this(ctx); - duk_push_pointer(ctx, alloc_new0(sizeof (struct action_stack))); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -ActionStack_destructor(duk_context *ctx) -{ - struct action_stack *st; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((st = duk_to_pointer(ctx, -1))) { - action_stack_finish(st); - free(st); - } - - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static duk_ret_t -ActionStack_add(duk_context *ctx) -{ - struct action_stack *st = self(ctx); - struct js_action *act = js_action_require(ctx, 0); - - if (action_stack_add(st, &act->act) < 0) - action_finish(&act->act); - else { - duk_push_this(ctx); - act->parent = duk_get_heapptr(ctx, -1); - duk_push_sprintf(ctx, "%p", act); - duk_dup(ctx, 0); - duk_put_prop(ctx, -3); - duk_pop(ctx); - } - - return 0; -} - -static duk_ret_t -ActionStack_handle(duk_context *ctx) -{ - action_stack_handle(self(ctx), js_event_require(ctx, 0)); - - return 0; -} - -static duk_ret_t -ActionStack_update(duk_context *ctx) -{ - struct action_stack *st = self(ctx); - const unsigned int ticks = duk_require_uint(ctx, 0); - - duk_push_uint(ctx, action_stack_update(st, ticks)); - - return 1; -} - -static duk_ret_t -ActionStack_draw(duk_context *ctx) -{ - action_stack_draw(self(ctx)); - - return 0; -} - -static duk_function_list_entry methods[] = { - { "add", ActionStack_add, 1 }, - { "handle", ActionStack_handle, 1 }, - { "update", ActionStack_update, 1 }, - { "draw", ActionStack_draw, 0 }, - { NULL, NULL, 0 } -}; - -void -js_action_stack_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, ActionStack_constructor, 0); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, ActionStack_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "ActionStack"); -}
--- a/src/libmlk-core-js/core/js-action-stack.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-action-stack.h -- core action_stack binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_ACTION_STACK_H -#define MLK_CORE_JS_ACTION_STACK_H - -#include <duktape.h> - -void -js_action_stack_bind(duk_context *); - -#endif /* !MLK_CORE_JS_ACTION_STACK_H */
--- a/src/libmlk-core-js/core/js-action.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,193 +0,0 @@ -/* - * js-action.c -- core action binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <stdlib.h> - -#include <core/alloc.h> -#include <core/action.h> - -#include "js-action.h" -#include "js-event.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Action") - -static inline duk_context * -callable(struct js_action *data, const char *prop) -{ - duk_context *ctx; - - if (!data->ptr) - return NULL; - - duk_push_heapptr(data->ctx, data->ptr); - duk_get_prop_string(data->ctx, -1, prop); - duk_pull(data->ctx, -2); - - if (duk_is_callable(data->ctx, -2)) - ctx = data->ctx; - else { - ctx = NULL; - duk_pop_n(data->ctx, 2); - } - - return ctx; -} - -static void -handle(struct action *data, const union event *ev) -{ - duk_context *ctx; - - if ((ctx = callable(data->data, "handle"))) { - js_event_push(ctx, ev); - duk_call_method(ctx, 1); - duk_pop(ctx); - } -} - -static int -update(struct action *data, unsigned int ticks) -{ - duk_context *ctx; - int ret = 0; - - if ((ctx = callable(data->data, "update"))) { - duk_push_uint(ctx, ticks); - duk_call_method(ctx, 1); - ret = duk_to_int(ctx, -1); - duk_pop(ctx); - } - - return ret; -} - -static void -draw(struct action *data) -{ - duk_context *ctx; - - if ((ctx = callable(data->data, "draw"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -end(struct action *data) -{ - duk_context *ctx; - - if ((ctx = callable(data->data, "end"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -finish(struct action *act) -{ - struct js_action *data = act->data; - - /* I must not be called anymore. */ - data->ptr = NULL; - - /* Remove myself from parent stack if any. */ - if (data->parent) { - duk_push_heapptr(data->ctx, data->parent); - duk_push_sprintf(data->ctx, "%p", data); - duk_del_prop(data->ctx, -2); - duk_pop(data->ctx); - data->parent = NULL; - } - - if (--data->refc == 0) - free(data); -} - -static duk_ret_t -Action_constructor(duk_context *ctx) -{ - struct js_action *data; - - data = alloc_new0(sizeof (*data)); - data->ctx = ctx; - data->refc = 1; - data->act.data = data; - data->act.handle = handle; - data->act.update = update; - data->act.finish = finish; - data->act.draw = draw; - data->act.end = end; - - duk_push_this(ctx); - data->ptr = duk_get_heapptr(ctx, -1); - duk_push_pointer(ctx, data); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Action_destructor(duk_context *ctx) -{ - struct js_action *data; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((data = duk_to_pointer(ctx, -1))) - action_finish(&data->act); - - duk_del_prop_string(ctx, 0, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -void -js_action_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Action_constructor, 0); - duk_push_object(ctx); - duk_push_c_function(ctx, Action_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Action"); -} - -struct js_action * -js_action_require(duk_context *ctx, duk_idx_t idx) -{ - struct js_action *act = NULL; - - if (duk_is_object(ctx, idx)) { - duk_get_prop_string(ctx, idx, SIGNATURE); - act = duk_to_pointer(ctx, -1); - duk_pop(ctx); - } - - if (!act) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Action object"), NULL; - - act->refc++; - - return act; -}
--- a/src/libmlk-core-js/core/js-action.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * js-action.h -- core action binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_ACTION_H -#define MLK_CORE_JS_ACTION_H - -#include <duktape.h> - -#include <core/action.h> - -struct js_action { - duk_context *ctx; - void *ptr; - void *parent; - unsigned int refc; - struct action act; -}; - -void -js_action_bind(duk_context *); - -struct js_action * -js_action_require(duk_context *, duk_idx_t); - -#endif /* !MLK_CORE_JS_ACTION_H */
--- a/src/libmlk-core-js/core/js-animation.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,140 +0,0 @@ -/* - * js-animation.c -- core animation binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/animation.h> - -#include "js-animation.h" -#include "js-sprite.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Animation") -#define SPRITEREF DUK_HIDDEN_SYMBOL("Mlk.Animation.sprite") - -static inline struct animation * -self(duk_context *ctx) -{ - struct animation *anim; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - anim = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!anim) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Animation object"), NULL; - - return anim; -} - -static duk_ret_t -Animation_getComplete(duk_context *ctx) -{ - duk_push_boolean(ctx, animation_completed(self(ctx))); - - return 1; -} - -static duk_ret_t -Animation_start(duk_context *ctx) -{ - animation_start(self(ctx)); - - return 0; -} - -static duk_ret_t -Animation_update(duk_context *ctx) -{ - struct animation *anim = self(ctx); - const unsigned int dt = duk_require_uint(ctx, 0); - - duk_push_boolean(ctx, animation_update(anim, dt)); - - return 1; -} - -static duk_ret_t -Animation_draw(duk_context *ctx) -{ - const struct animation *anim = self(ctx); - const int x = duk_require_int(ctx, 0); - const int y = duk_require_int(ctx, 1); - - if (!animation_completed(anim)) - animation_draw(anim, x, y); - - return 0; -} - -static duk_ret_t -Animation_constructor(duk_context *ctx) -{ - const struct sprite *sprite = js_sprite_require(ctx, 0); - const unsigned int delay = duk_require_uint(ctx, 1); - struct animation *anim; - - anim = alloc_new0(sizeof (*anim)); - animation_init(anim, sprite, delay); - - duk_push_this(ctx); - duk_push_pointer(ctx, anim); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_push_string(ctx, "complete"); - duk_push_c_function(ctx, Animation_getComplete, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Animation_destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, SIGNATURE); - free(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - /* Remove sprite reference. */ - duk_del_prop_string(ctx, 0, SPRITEREF); - - return 0; -} - -static const duk_function_list_entry methods[] = { - { "start", Animation_start, 0 }, - { "update", Animation_update, 1 }, - { "draw", Animation_draw, 2 }, - { NULL, NULL, 0 } -}; - -void -js_animation_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Animation_constructor, 2); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, Animation_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Animation"); -}
--- a/src/libmlk-core-js/core/js-animation.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-animation.h -- core animation binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_ANIMATION_H -#define MLK_CORE_JS_ANIMATION_H - -#include <duktape.h> - -void -js_animation_bind(duk_context *); - -#endif /* !MLK_CORE_JS_ANIMATION_H */
--- a/src/libmlk-core-js/core/js-clock.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,107 +0,0 @@ -/* - * js-clock.c -- core clock binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/clock.h> - -#include "js-clock.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Clock") - -static inline struct clock * -self(duk_context *ctx) -{ - struct clock *clk; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - clk = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!clk) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Clock object"), NULL; - - return clk; -} - -static duk_ret_t -Clock_elapsed(duk_context *ctx) -{ - duk_push_number(ctx, clock_elapsed(self(ctx))); - - return 1; -} - -static duk_ret_t -Clock_constructor(duk_context *ctx) -{ - struct clock *clk; - - clk = alloc_new(sizeof (*clk)); - clock_start(clk); - - duk_push_this(ctx); - duk_push_pointer(ctx, clk); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_push_string(ctx, "elapsed"); - duk_push_c_function(ctx, Clock_elapsed, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Clock_start(duk_context *ctx) -{ - clock_start(self(ctx)); - - return 0; -} - -static duk_ret_t -Clock_destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, SIGNATURE); - free(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static const duk_function_list_entry methods[] = { - { "start", Clock_start, 0 }, - { NULL, NULL, 0 } -}; - -void -js_clock_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Clock_constructor, 0); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, Clock_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Clock"); -}
--- a/src/libmlk-core-js/core/js-clock.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-clock.h -- core clock binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_CLOCK_H -#define MLK_CORE_JS_CLOCK_H - -#include <duktape.h> - -void -js_clock_bind(duk_context *); - -#endif /* !MLK_CORE_JS_CLOCK_H */
--- a/src/libmlk-core-js/core/js-color.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * js-color.c -- core color binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/color.h> - -#include "js-color.h" - -static inline unsigned int -component(duk_context *ctx, duk_idx_t ind, const char *prop, unsigned int def) -{ - unsigned int value = 0; - - if (duk_is_object(ctx, 0)) { - duk_get_prop_string(ctx, 0, prop); - value = duk_get_uint_default(ctx, -1, def); - duk_pop(ctx); - } else - value = duk_get_uint_default(ctx, ind, def); - - return value; -} - -static duk_ret_t -Color_fromRGB(duk_context *ctx) -{ - const unsigned int r = component(ctx, 0, "r", 0); - const unsigned int g = component(ctx, 1, "g", 0); - const unsigned int b = component(ctx, 2, "b", 0); - const unsigned int a = component(ctx, 3, "a", 255); - - duk_push_number(ctx, COLOR_HEX(r, g, b, a)); - - return 1; -} - -static duk_ret_t -Color_toRGB(duk_context *ctx) -{ - const unsigned long hex = duk_require_uint(ctx, 0); - - duk_push_object(ctx); - duk_push_uint(ctx, COLOR_R(hex)); - duk_put_prop_string(ctx, -2, "r"); - duk_push_uint(ctx, COLOR_G(hex)); - duk_put_prop_string(ctx, -2, "g"); - duk_push_uint(ctx, COLOR_B(hex)); - duk_put_prop_string(ctx, -2, "b"); - duk_push_uint(ctx, COLOR_A(hex)); - duk_put_prop_string(ctx, -2, "a"); - - return 1; -} - -static const duk_function_list_entry functions[] = { - { "fromRGB", Color_fromRGB, DUK_VARARGS }, - { "toRGB", Color_toRGB, 1 }, - { NULL, NULL, 0 } -}; - -void -js_color_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_object(ctx); - duk_put_function_list(ctx, -1, functions); - duk_put_global_string(ctx, "Color"); -}
--- a/src/libmlk-core-js/core/js-color.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-color.h -- core color binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_COLOR_H -#define MLK_CORE_JS_COLOR_H - -#include <duktape.h> - -void -js_color_bind(duk_context *); - -#endif /* !MLK_CORE_JS_COLOR_H */
--- a/src/libmlk-core-js/core/js-core.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * js-core.c -- core binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include "js-core.h" - -#define VFS DUK_HIDDEN_SYMBOL("Mlk.Vfs") - -void -js_core_bind(duk_context *ctx, struct vfs *vfs) -{ - assert(ctx); - assert(vfs); - - /* We put the VFS object. */ - duk_push_global_stash(ctx); - duk_push_pointer(ctx, vfs); - duk_put_prop_string(ctx, -2, VFS); - duk_pop(ctx); - - duk_push_object(ctx); - duk_put_global_string(ctx, "Mlk"); -} - -struct vfs * -js_core_global_vfs(duk_context *ctx) -{ - assert(ctx); - - struct vfs *vfs; - - duk_push_global_stash(ctx); - duk_get_prop_string(ctx, -1, VFS); - vfs = duk_to_pointer(ctx, -1); - duk_pop(ctx); - - return vfs; -}
--- a/src/libmlk-core-js/core/js-core.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * js-core.h -- core binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_H -#define MLK_CORE_JS_H - -#include <duktape.h> - -struct vfs; - -void -js_core_bind(duk_context *, struct vfs *); - -struct vfs * -js_core_global_vfs(duk_context *); - -#endif /* !MLK_CORE_JS_H */
--- a/src/libmlk-core-js/core/js-drawable-stack.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,133 +0,0 @@ -/* - * js-drawable-stack.h -- core drawable_stack binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/drawable.h> -#include <core/drawable-stack.h> - -#include "js-drawable-stack.h" -#include "js-drawable.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.DrawableStack") - -static inline struct drawable_stack * -self(duk_context *ctx) -{ - struct drawable_stack *sf = NULL; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - sf = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!sf) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a DrawableStack object"), NULL; - - return sf; -} - -static duk_ret_t -DrawableStack_constructor(duk_context *ctx) -{ - duk_push_this(ctx); - duk_push_pointer(ctx, alloc_new0(sizeof (struct drawable_stack))); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -DrawableStack_destructor(duk_context *ctx) -{ - struct drawable_stack *st; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((st = duk_to_pointer(ctx, -1))) { - drawable_stack_finish(st); - free(st); - } - - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static duk_ret_t -DrawableStack_add(duk_context *ctx) -{ - struct drawable_stack *st = self(ctx); - struct js_drawable *dw = js_drawable_require(ctx, 0); - - if (drawable_stack_add(st, &dw->dw) < 0) - drawable_finish(&dw->dw); - else { - duk_push_this(ctx); - dw->parent = duk_get_heapptr(ctx, -1); - duk_push_sprintf(ctx, "%p", dw); - duk_dup(ctx, 0); - duk_put_prop(ctx, -3); - duk_pop(ctx); - } - - return 0; -} - -static duk_ret_t -DrawableStack_update(duk_context *ctx) -{ - struct drawable_stack *st = self(ctx); - const unsigned int ticks = duk_require_uint(ctx, 0); - - duk_push_uint(ctx, drawable_stack_update(st, ticks)); - - return 1; -} - -static duk_ret_t -DrawableStack_draw(duk_context *ctx) -{ - drawable_stack_draw(self(ctx)); - - return 0; -} - -static duk_function_list_entry methods[] = { - { "add", DrawableStack_add, 1 }, - { "update", DrawableStack_update, 1 }, - { "draw", DrawableStack_draw, 0 }, - { NULL, NULL, 0 } -}; - -void -js_drawable_stack_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, DrawableStack_constructor, 0); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, DrawableStack_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "DrawableStack"); -}
--- a/src/libmlk-core-js/core/js-drawable-stack.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-drawable-stack.h -- core drawable_stack binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_DRAWABLE_STACK_H -#define MLK_CORE_JS_DRAWABLE_STACK_H - -#include <duktape.h> - -void -js_drawable_stack_bind(duk_context *); - -#endif /* !MLK_CORE_JS_DRAWABLE_STACK_H */
--- a/src/libmlk-core-js/core/js-drawable.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,238 +0,0 @@ -/* - * js-drawable.c -- core drawable binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/drawable.h> - -#include "js-drawable.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Drawable") - -static inline struct js_drawable * -self(duk_context *ctx) -{ - struct js_drawable *data = NULL; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - data = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!data) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Drawable object"), NULL; - - return data; -} - -static inline duk_context * -callable(struct js_drawable *data, const char *prop) -{ - duk_context *ctx; - - if (!data->ptr) - return NULL; - - duk_push_heapptr(data->ctx, data->ptr); - duk_get_prop_string(data->ctx, -1, prop); - duk_pull(data->ctx, -2); - - if (duk_is_callable(data->ctx, -2)) - ctx = data->ctx; - else { - ctx = NULL; - duk_pop_n(data->ctx, 2); - } - - return ctx; -} - -static int -update(struct drawable *dw, unsigned int ticks) -{ - duk_context *ctx; - int ret = 0; - - if ((ctx = callable(dw->data, "update"))) { - duk_push_uint(ctx, ticks); - duk_call_method(ctx, 1); - ret = duk_to_int(ctx, -1); - duk_pop(ctx); - } - - return ret; -} - -static void -draw(struct drawable *dw) -{ - duk_context *ctx; - - if ((ctx = callable(dw->data, "draw"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -end(struct drawable *dw) -{ - duk_context *ctx; - - if ((ctx = callable(dw->data, "end"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -finish(struct drawable *dw) -{ - struct js_drawable *data = dw->data; - - /* I must not be called anymore. */ - data->ptr = NULL; - - /* Remove myself from parent stack if any. */ - if (data->parent) { - duk_push_heapptr(data->ctx, data->parent); - duk_push_sprintf(data->ctx, "%p", data); - duk_del_prop(data->ctx, -2); - duk_pop(data->ctx); - data->parent = NULL; - } - - if (--data->refc == 0) - free(data); -} - -static duk_ret_t -Drawable_getX(duk_context *ctx) -{ - duk_push_uint(ctx, self(ctx)->dw.x); - - return 1; -} - -static duk_ret_t -Drawable_setX(duk_context *ctx) -{ - self(ctx)->dw.x = duk_require_uint(ctx, 0); - - return 0; -} - -static duk_ret_t -Drawable_getY(duk_context *ctx) -{ - duk_push_uint(ctx, self(ctx)->dw.y); - - return 1; -} - -static duk_ret_t -Drawable_setY(duk_context *ctx) -{ - self(ctx)->dw.y = duk_require_uint(ctx, 0); - - return 0; -} - -static duk_ret_t -Drawable_constructor(duk_context *ctx) -{ - struct js_drawable *data; - const int x = duk_require_int(ctx, 0); - const int y = duk_require_int(ctx, 1); - - data = alloc_new0(sizeof (*data)); - data->refc = 1; - data->ctx = ctx; - data->dw.x = x; - data->dw.y = y; - data->dw.data = data; - data->dw.update = update; - data->dw.finish = finish; - data->dw.draw = draw; - data->dw.end = end; - - duk_push_this(ctx); - data->ptr = duk_get_heapptr(ctx, -1); - duk_push_pointer(ctx, data); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_push_string(ctx, "x"); - duk_push_c_function(ctx, Drawable_getX, 0); - duk_push_c_function(ctx, Drawable_setX, 1); - duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); - duk_push_string(ctx, "y"); - duk_push_c_function(ctx, Drawable_getY, 0); - duk_push_c_function(ctx, Drawable_setY, 1); - duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Drawable_destructor(duk_context *ctx) -{ - struct js_drawable *data; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((data = duk_to_pointer(ctx, -1))) - drawable_finish(&data->dw); - - duk_del_prop_string(ctx, 0, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -void -js_drawable_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Drawable_constructor, 2); - duk_push_object(ctx); - duk_push_c_function(ctx, Drawable_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Drawable"); -} - -struct js_drawable * -js_drawable_require(duk_context *ctx, duk_idx_t idx) -{ - struct js_drawable *data = NULL; - - if (duk_is_object(ctx, idx)) { - duk_get_prop_string(ctx, idx, SIGNATURE); - data = duk_to_pointer(ctx, -1); - duk_pop(ctx); - } - - if (!data) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Drawable object"), NULL; - - data->refc++; - - return data; -}
--- a/src/libmlk-core-js/core/js-drawable.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * js-drawable.h -- core drawable binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_DRAWABLE_H -#define MLK_CORE_JS_DRAWABLE_H - -#include <duktape.h> - -#include <core/drawable.h> - -struct js_drawable { - duk_context *ctx; - void *ptr; - void *parent; - unsigned int refc; - struct drawable dw; -}; - -void -js_drawable_bind(duk_context *); - -struct js_drawable * -js_drawable_require(duk_context *, duk_idx_t); - -#endif /* !MLK_CORE_JS_DRAWABLE_H */
--- a/src/libmlk-core-js/core/js-event.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,335 +0,0 @@ -/* - * js-event.c -- core event binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/event.h> - -#include "js-event.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Event") - -static void -push_click(duk_context *ctx, const union event *ev) -{ - duk_push_int(ctx, ev->click.button); - duk_put_prop_string(ctx, -2, "button"); - duk_push_int(ctx, ev->click.x); - duk_put_prop_string(ctx, -2, "x"); - duk_push_int(ctx, ev->click.y); - duk_put_prop_string(ctx, -2, "y"); - duk_push_int(ctx, ev->click.clicks); - duk_put_prop_string(ctx, -2, "clicks"); -} - -static void -push_key(duk_context *ctx, const union event *ev) -{ - duk_push_int(ctx, ev->key.key); - duk_put_prop_string(ctx, -2, "key"); -} - -static void -push_mouse(duk_context *ctx, const union event *ev) -{ - duk_push_int(ctx, ev->mouse.buttons); - duk_put_prop_string(ctx, -2, "buttons"); - duk_push_int(ctx, ev->mouse.x); - duk_put_prop_string(ctx, -2, "x"); - duk_push_int(ctx, ev->mouse.y); - duk_put_prop_string(ctx, -2, "y"); -} - -static void -push_quit(duk_context *ctx, const union event *ev) -{ - (void)ctx; - (void)ev; -} - -static void (*push[])(duk_context *, const union event *) = { - [EVENT_CLICKDOWN] = push_click, - [EVENT_CLICKUP] = push_click, - [EVENT_KEYDOWN] = push_key, - [EVENT_KEYUP] = push_key, - [EVENT_MOUSE] = push_mouse, - [EVENT_QUIT] = push_quit, -}; - -static duk_ret_t -Event_poll(duk_context *ctx) -{ - (void)ctx; - - union event ev; - - if (!event_poll(&ev)) - duk_push_null(ctx); - else - js_event_push(ctx, &ev); - - return 1; -} - -static const duk_function_list_entry functions[] = { - { "poll", Event_poll, 0 }, - { NULL, NULL, 0 } -}; - -static const duk_number_list_entry types[] = { - { "CLICKDOWN", EVENT_CLICKDOWN }, - { "CLICKUP", EVENT_CLICKUP }, - { "KEYDOWN", EVENT_KEYDOWN }, - { "KEYUP", EVENT_KEYUP }, - { "MOUSE", EVENT_MOUSE }, - { "QUIT", EVENT_QUIT }, - { NULL, 0 } -}; - -static const duk_number_list_entry keys[] = { - { "UNKNOWN", KEY_UNKNOWN }, - { "ENTER", KEY_ENTER }, - { "ESCAPE", KEY_ESCAPE }, - { "BACKSPACE", KEY_BACKSPACE }, - { "TAB", KEY_TAB }, - { "SPACE", KEY_SPACE }, - { "EXCLAIM", KEY_EXCLAIM }, - { "DOUBLE_QUOTE", KEY_DOUBLE_QUOTE }, - { "HASH", KEY_HASH }, - { "PERCENT", KEY_PERCENT }, - { "DOLLAR", KEY_DOLLAR }, - { "AMPERSAND", KEY_AMPERSAND }, - { "QUOTE", KEY_QUOTE }, - { "LEFT_PAREN", KEY_LEFT_PAREN }, - { "RIGHT_PAREN", KEY_RIGHT_PAREN }, - { "ASTERISK", KEY_ASTERISK }, - { "PLUS", KEY_PLUS }, - { "COMMA", KEY_COMMA }, - { "MINUS", KEY_MINUS }, - { "PERIOD", KEY_PERIOD }, - { "SLASH", KEY_SLASH }, - { "0", KEY_0 }, - { "1", KEY_1 }, - { "2", KEY_2 }, - { "3", KEY_3 }, - { "4", KEY_4 }, - { "5", KEY_5 }, - { "6", KEY_6 }, - { "7", KEY_7 }, - { "8", KEY_8 }, - { "9", KEY_9 }, - { "COLON", KEY_COLON }, - { "SEMICOLON", KEY_SEMICOLON }, - { "LESS", KEY_LESS }, - { "EQUALS", KEY_EQUALS }, - { "GREATER", KEY_GREATER }, - { "QUESTION", KEY_QUESTION }, - { "AT", KEY_AT }, - { "LEFT_BRACKET", KEY_LEFT_BRACKET }, - { "BACKSLASH", KEY_BACKSLASH }, - { "RIGHT_BRACKET", KEY_RIGHT_BRACKET }, - { "CARET", KEY_CARET }, - { "UNDERSCORE", KEY_UNDERSCORE }, - { "BACKQUOTE", KEY_BACKQUOTE }, - { "a", KEY_a }, - { "b", KEY_b }, - { "c", KEY_c }, - { "d", KEY_d }, - { "e", KEY_e }, - { "f", KEY_f }, - { "g", KEY_g }, - { "h", KEY_h }, - { "i", KEY_i }, - { "j", KEY_j }, - { "k", KEY_k }, - { "l", KEY_l }, - { "m", KEY_m }, - { "n", KEY_n }, - { "o", KEY_o }, - { "p", KEY_p }, - { "q", KEY_q }, - { "r", KEY_r }, - { "s", KEY_s }, - { "t", KEY_t }, - { "u", KEY_u }, - { "v", KEY_v }, - { "w", KEY_w }, - { "x", KEY_x }, - { "y", KEY_y }, - { "z", KEY_z }, - { "CAPSLOCK", KEY_CAPSLOCK }, - { "F1", KEY_F1 }, - { "F2", KEY_F2 }, - { "F3", KEY_F3 }, - { "F4", KEY_F4 }, - { "F5", KEY_F5 }, - { "F6", KEY_F6 }, - { "F7", KEY_F7 }, - { "F8", KEY_F8 }, - { "F9", KEY_F9 }, - { "F10", KEY_F10 }, - { "F11", KEY_F11 }, - { "F12", KEY_F12 }, - { "F13", KEY_F13 }, - { "F14", KEY_F14 }, - { "F15", KEY_F15 }, - { "F16", KEY_F16 }, - { "F17", KEY_F17 }, - { "F18", KEY_F18 }, - { "F19", KEY_F19 }, - { "F20", KEY_F20 }, - { "F21", KEY_F21 }, - { "F22", KEY_F22 }, - { "F23", KEY_F23 }, - { "F24", KEY_F24 }, - { "PRINTSCREEN", KEY_PRINTSCREEN }, - { "SCROLL_LOCK", KEY_SCROLL_LOCK }, - { "PAUSE", KEY_PAUSE }, - { "INSERT", KEY_INSERT }, - { "HOME", KEY_HOME }, - { "PAGEUP", KEY_PAGEUP }, - { "DELETE", KEY_DELETE }, - { "END", KEY_END }, - { "PAGEDOWN", KEY_PAGEDOWN }, - { "RIGHT", KEY_RIGHT }, - { "LEFT", KEY_LEFT }, - { "DOWN", KEY_DOWN }, - { "UP", KEY_UP }, - { "NUMLOCKCLEAR", KEY_NUMLOCKCLEAR }, - { "KP_DIVIDE", KEY_KP_DIVIDE }, - { "KP_MULTIPLY", KEY_KP_MULTIPLY }, - { "KP_MINUS", KEY_KP_MINUS }, - { "KP_PLUS", KEY_KP_PLUS }, - { "KP_ENTER", KEY_KP_ENTER }, - { "KP_00", KEY_KP_00 }, - { "KP_000", KEY_KP_000 }, - { "KP_1", KEY_KP_1 }, - { "KP_2", KEY_KP_2 }, - { "KP_3", KEY_KP_3 }, - { "KP_4", KEY_KP_4 }, - { "KP_5", KEY_KP_5 }, - { "KP_6", KEY_KP_6 }, - { "KP_7", KEY_KP_7 }, - { "KP_8", KEY_KP_8 }, - { "KP_9", KEY_KP_9 }, - { "KP_0", KEY_KP_0 }, - { "KP_PERIOD", KEY_KP_PERIOD }, - { "KP_COMMA", KEY_KP_COMMA }, - { "MENU", KEY_MENU }, - { "MUTE", KEY_MUTE }, - { "VOLUME_UP", KEY_VOLUME_UP }, - { "VOLUME_DOWN", KEY_VOLUME_DOWN }, - { "LCTRL", KEY_LCTRL }, - { "LSHIFT", KEY_LSHIFT }, - { "LALT", KEY_LALT }, - { "LSUPER", KEY_LSUPER }, - { "RCTRL", KEY_RCTRL }, - { "RSHIFT", KEY_RSHIFT }, - { "RALT", KEY_RALT }, - { "RSUPER", KEY_RSUPER }, - { NULL, 0 } -}; - -static const duk_number_list_entry keymods[] = { - { "LSHIFT", KEYMOD_LSHIFT }, - { "LCTRL", KEYMOD_LCTRL }, - { "LALT", KEYMOD_LALT }, - { "LSUPER", KEYMOD_LSUPER }, - { "RSHIFT", KEYMOD_RSHIFT }, - { "RTCRL", KEYMOD_RCTRL }, - { "RALT", KEYMOD_RALT }, - { "RSUPER", KEYMOD_RSUPER }, - { NULL, 0 } -}; - -static const duk_number_list_entry buttons[] = { - { "LEFT", MOUSE_BUTTON_LEFT }, - { "MIDDLE", MOUSE_BUTTON_MIDDLE }, - { "RIGHT", MOUSE_BUTTON_RIGHT }, - { NULL, 0 } -}; - -static duk_ret_t -Event_destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, SIGNATURE); - free(duk_to_pointer(ctx, -1)); - duk_del_prop_string(ctx, 0, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -void -js_event_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_global_object(ctx); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, functions); - duk_push_object(ctx); - duk_put_number_list(ctx, -1, types); - duk_put_prop_string(ctx, -2, "Type"); - duk_push_object(ctx); - duk_put_number_list(ctx, -1, keys); - duk_put_prop_string(ctx, -2, "Key"); - duk_push_object(ctx); - duk_put_number_list(ctx, -1, keymods); - duk_put_prop_string(ctx, -2, "Keymod"); - duk_push_object(ctx); - duk_put_number_list(ctx, -1, buttons); - duk_put_prop_string(ctx, -2, "Button"); - duk_put_prop_string(ctx, -2, "Event"); - duk_pop(ctx); -} - -void -js_event_push(duk_context *ctx, const union event *ev) -{ - assert(ctx); - - duk_push_object(ctx); - duk_push_c_function(ctx, Event_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_push_pointer(ctx, alloc_dup(ev, sizeof (*ev))); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_push_int(ctx, ev->type); - duk_put_prop_string(ctx, -2, "type"); - push[ev->type](ctx, ev); -} - -union event * -js_event_require(duk_context *ctx, duk_idx_t idx) -{ - assert(ctx); - - union event *ev = NULL; - - if (duk_is_object(ctx, idx)) { - duk_get_prop_string(ctx, idx, SIGNATURE); - ev = duk_to_pointer(ctx, -1); - duk_pop(ctx); - } - - if (!ev) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not an Event object"), NULL; - - return ev; -}
--- a/src/libmlk-core-js/core/js-event.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * js-event.h -- core event binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_EVENT_H -#define MLK_CORE_JS_EVENT_H - -#include <duktape.h> - -union event; - -void -js_event_bind(duk_context *); - -void -js_event_push(duk_context *, const union event *); - -union event * -js_event_require(duk_context *, duk_idx_t); - -#endif /* !MLK_CORE_JS_EVENT_H */
--- a/src/libmlk-core-js/core/js-font.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,195 +0,0 @@ -/* - * js-font.c -- core texture binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/error.h> -#include <core/font.h> -#include <core/texture.h> -#include <core/vfs.h> - -#include "js-core.h" -#include "js-font.h" -#include "js-texture.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Font") - -static inline struct font * -self(duk_context *ctx) -{ - struct font *font; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - font = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!font) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Font object"), NULL; - - return font; -} - -static duk_ret_t -Font_getStyle(duk_context *ctx) -{ - duk_push_int(ctx, self(ctx)->style); - - return 1; -} - -static duk_ret_t -Font_setStyle(duk_context *ctx) -{ - const int style = duk_require_int(ctx, 0); - - if (style < 0 || style >= FONT_STYLE_LAST) - return duk_error(ctx, DUK_ERR_ERROR, "invalid style"); - - self(ctx)->style = style; - - return 0; -} - -static duk_ret_t -Font_getHeight(duk_context *ctx) -{ - duk_push_uint(ctx, font_height(self(ctx))); - - return 1; -} - -static duk_ret_t -Font_new(duk_context *ctx) -{ - const char *entry = duk_require_string(ctx, 0); - const unsigned int size = duk_require_uint(ctx, 1); - struct vfs_file file; - struct font *font; - - if (vfs_open(js_core_global_vfs(ctx), &file, entry, "r") < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - font = alloc_new0(sizeof (*font)); - - if (font_openvfs(font, &file, size) < 0) { - free(font); - vfs_file_finish(&file); - - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - } - - vfs_file_finish(&file); - - duk_push_this(ctx); - duk_push_pointer(ctx, font); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_push_string(ctx, "style"); - duk_push_c_function(ctx, Font_getStyle, 0); - duk_push_c_function(ctx, Font_setStyle, 1); - duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_GETTER | DUK_DEFPROP_HAVE_SETTER); - duk_push_string(ctx, "height"); - duk_push_c_function(ctx, Font_getHeight, 0); - duk_def_prop(ctx, -3, DUK_DEFPROP_HAVE_GETTER); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Font_render(duk_context *ctx) -{ - const char *text = duk_require_string(ctx, 0); - unsigned long color = duk_require_uint(ctx, 1); - struct texture *tex; - - tex = alloc_new0(sizeof (*tex)); - - if (font_render(self(ctx), tex, text, color) < 0) { - free(tex); - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - } - - js_texture_push(ctx, tex); - - return 1; -} - -static duk_ret_t -Font_query(duk_context *ctx) -{ - const char *text = duk_require_string(ctx, 0); - unsigned int w, h; - - if (font_query(self(ctx), text, &w, &h) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - duk_push_object(ctx); - duk_push_uint(ctx, w); - duk_put_prop_string(ctx, -2, "w"); - duk_push_uint(ctx, h); - duk_put_prop_string(ctx, -2, "h"); - - return 1; -} - -static duk_ret_t -Font_destructor(duk_context *ctx) -{ - struct font *font; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((font = duk_to_pointer(ctx, -1))) - font_finish(font); - - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static const struct duk_function_list_entry methods[] = { - { "render", Font_render, 2 }, - { "query", Font_query, 1 }, - { NULL, NULL, 0 } -}; - -static const struct duk_number_list_entry styles[] = { - { "ANTIALIASED", FONT_STYLE_ANTIALIASED, }, - { "NONE", FONT_STYLE_NONE }, - { NULL, 0 } -}; - -void -js_font_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Font_new, 2); - duk_push_object(ctx); - duk_put_number_list(ctx, -1, styles); - duk_put_prop_string(ctx, -2, "Style"); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, Font_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Font"); -}
--- a/src/libmlk-core-js/core/js-font.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-font.h -- core texture binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_FONT_H -#define MLK_CORE_JS_FONT_H - -#include <duktape.h> - -void -js_font_bind(duk_context *); - -#endif /* !MLK_CORE_JS_FONT_H */
--- a/src/libmlk-core-js/core/js-game.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,106 +0,0 @@ -/* - * js-game.c -- core gamej binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/game.h> -#include <core/state.h> -#include <core/util.h> - -#include "js-game.h" -#include "js-state.h" - -/* - * TODO: determine if it's worth it to add handle, update and draw functions. - */ -static struct state *states[16]; - -static duk_ret_t -Game_push(duk_context *ctx) -{ - struct js_state *state = js_state_require(ctx, 0); - - if (game.state == &game.states[game.statesz - 1]) { - state_finish(&state->st); - return duk_error(ctx, DUK_ERR_RANGE_ERROR, "too many states"); - } - - duk_push_this(ctx); - state->parent = duk_get_heapptr(ctx, -1); - duk_push_sprintf(ctx, "%p", state); - duk_dup(ctx, 0); - duk_put_prop(ctx, -3); - duk_pop(ctx); - - game_push(&state->st); - - return 0; -} - -static duk_ret_t -Game_pop(duk_context *ctx) -{ - (void)ctx; - - if (game.state == &game.states[0]) - return 0; - - game_pop(); - - return 0; -} - -static duk_ret_t -Game_loop(duk_context *ctx) -{ - (void)ctx; - - game_loop(); - - return 0; -} - -static duk_ret_t -Game_quit(duk_context *ctx) -{ - (void)ctx; - - game_quit(); - - return 0; -} - -static const duk_function_list_entry functions[] = { - { "push", Game_push, 1 }, - { "pop", Game_pop, 0 }, - { "loop", Game_loop, 0 }, - { "quit", Game_quit, 0 }, - { NULL, NULL, 0 } -}; - -void -js_game_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_object(ctx); - duk_put_function_list(ctx, -1, functions); - duk_put_global_string(ctx, "Game"); - - game_init(states, UTIL_SIZE(states)); -}
--- a/src/libmlk-core-js/core/js-game.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-game.h -- core game binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_GAME_H -#define MLK_CORE_JS_GAME_H - -#include <duktape.h> - -void -js_game_bind(duk_context *); - -#endif /* !MLK_CORE_JS_GAME_H */
--- a/src/libmlk-core-js/core/js-music.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,156 +0,0 @@ -/* - * js-music.c -- core music binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/error.h> -#include <core/music.h> -#include <core/vfs.h> - -#include "js-core.h" -#include "js-music.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Music") - -static inline struct music * -self(duk_context *ctx) -{ - struct music *mus; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - mus = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!mus) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Music object"), NULL; - - return mus; -} - -static duk_ret_t -Music_new(duk_context *ctx) -{ - const char *entry = duk_require_string(ctx, 0); - struct vfs_file file; - struct music *mus; - - if (vfs_open(js_core_global_vfs(ctx), &file, entry, "r") < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - mus = alloc_new0(sizeof (*mus)); - - if (music_openvfs(mus, &file) < 0) { - free(mus); - vfs_file_finish(&file); - - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - } - - vfs_file_finish(&file); - - duk_push_this(ctx); - duk_push_pointer(ctx, mus); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Music_play(duk_context *ctx) -{ - const int flags = duk_get_int_default(ctx, 0, MUSIC_NONE); - - if (music_play(self(ctx), flags) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - return 0; -} - -static duk_ret_t -Music_pause(duk_context *ctx) -{ - music_pause(self(ctx)); - - return 0; -} - -static duk_ret_t -Music_resume(duk_context *ctx) -{ - music_resume(self(ctx)); - - return 0; -} - -static duk_ret_t -Music_stop(duk_context *ctx) -{ - music_stop(self(ctx)); - - return 0; -} - -static duk_ret_t -Music_destructor(duk_context *ctx) -{ - struct music *mus; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((mus = duk_to_pointer(ctx, -1))) - music_finish(mus); - - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static const duk_function_list_entry methods[] = { - { "play", Music_play, DUK_VARARGS }, - { "pause", Music_pause, 0 }, - { "resume", Music_resume, 0 }, - { "stop", Music_stop, DUK_VARARGS }, - { NULL, NULL, 0 } -}; - -static const duk_number_list_entry flags[] = { - { "NONE", MUSIC_NONE }, - { "LOOP", MUSIC_LOOP }, - { NULL, 0 } -}; - -void -js_music_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Music_new, 1); - duk_push_object(ctx); - duk_put_number_list(ctx, -1, flags); - duk_put_prop_string(ctx, -2, "Flags"); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, Music_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Music"); -}
--- a/src/libmlk-core-js/core/js-music.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-music.h -- core music binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_MUSIC_H -#define MLK_CORE_JS_MUSIC_H - -#include <duktape.h> - -void -js_music_bind(duk_context *); - -#endif /* !MLK_CORE_JS_MUSIC_H */
--- a/src/libmlk-core-js/core/js-painter.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,165 +0,0 @@ -/* - * js-painter.c -- core painter binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/painter.h> - -#include "js-painter.h" -#include "js-texture.h" - -static duk_ret_t -Painter_getTarget(duk_context *ctx) -{ - struct texture *tex; - - if (!(tex = painter_get_target())) - duk_push_null(ctx); - else - js_texture_push(ctx, tex); - - return 1; -} - -static duk_ret_t -Painter_setTarget(duk_context *ctx) -{ - if (duk_is_null(ctx, 0)) - painter_set_target(NULL); - else - painter_set_target(js_texture_require(ctx, 0)); - - return 0; -} - -static duk_ret_t -Painter_getColor(duk_context *ctx) -{ - duk_push_number(ctx, painter_get_color()); - - return 1; -} - -static duk_ret_t -Painter_setColor(duk_context *ctx) -{ - const unsigned long color = duk_require_number(ctx, 0); - - painter_set_color(color); - - return 0; -} - -static duk_ret_t -Painter_drawLine(duk_context *ctx) -{ - const int x1 = duk_require_int(ctx, 0); - const int y1 = duk_require_int(ctx, 1); - const int x2 = duk_require_int(ctx, 2); - const int y2 = duk_require_int(ctx, 3); - - painter_draw_line(x1, y1, x2, y2); - - return 0; -} - -static duk_ret_t -Painter_drawPoint(duk_context *ctx) -{ - const int x = duk_require_int(ctx, 0); - const int y = duk_require_int(ctx, 1); - - painter_draw_point(x, y); - - return 0; -} - -static duk_ret_t -Painter_drawRectangle(duk_context *ctx) -{ - const int x = duk_require_int(ctx, 0); - const int y = duk_require_int(ctx, 1); - const unsigned int w = duk_require_uint(ctx, 2); - const unsigned int h = duk_require_uint(ctx, 3); - - painter_draw_rectangle(x, y, w, h); - - return 0; -} - -static duk_ret_t -Painter_drawCircle(duk_context *ctx) -{ - const int x = duk_require_int(ctx, 0); - const int y = duk_require_int(ctx, 1); - const int r = duk_require_int(ctx, 2); - - painter_draw_circle(x, y, r); - - return 0; -} - -static duk_ret_t -Painter_clear(duk_context *ctx) -{ - (void)ctx; - - painter_clear(); - - return 0; -} - -static duk_ret_t -Painter_present(duk_context *ctx) -{ - (void)ctx; - - painter_present(); - - return 0; -} - -static const duk_function_list_entry functions[] = { - { "drawLine", Painter_drawLine, 4 }, - { "drawPoint", Painter_drawPoint, 2 }, - { "drawRectangle", Painter_drawRectangle, 4 }, - { "drawCircle", Painter_drawCircle, 3 }, - { "clear", Painter_clear, 0 }, - { "present", Painter_present, 0 }, - { NULL, NULL, 0 } -}; - -void -js_painter_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_global_object(ctx); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, functions); - duk_push_string(ctx, "color"); - duk_push_c_function(ctx, Painter_getColor, 0); - duk_push_c_function(ctx, Painter_setColor, 1); - duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER); - duk_push_string(ctx, "target"); - duk_push_c_function(ctx, Painter_getTarget, 0); - duk_push_c_function(ctx, Painter_setTarget, 1); - duk_def_prop(ctx, -4, DUK_DEFPROP_HAVE_SETTER | DUK_DEFPROP_HAVE_GETTER); - duk_put_prop_string(ctx, -2, "Painter"); - duk_pop(ctx); -}
--- a/src/libmlk-core-js/core/js-painter.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-painter.h -- core painter binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_PAINTER_H -#define MLK_CORE_JS_PAINTER_H - -#include <duktape.h> - -void -js_painter_bind(duk_context *); - -#endif /* !MLK_CORE_JS_PAINTER_H */
--- a/src/libmlk-core-js/core/js-panic.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,88 +0,0 @@ -/* - * js-panic.c -- core panic binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <stdio.h> - -#include <core/panic.h> - -#include "js-panic.h" - -#define PANIC_CB DUK_HIDDEN_SYMBOL("Mlk.panicHandler") - -static void -handler(void) -{ - duk_context *ctx = panic_data; - - duk_push_global_stash(ctx); - duk_get_prop_string(ctx, -1, PANIC_CB); - duk_remove(ctx, -2); - - if (duk_is_callable(ctx, -1)) { - duk_call(ctx, 0); - duk_pop(ctx); - } else { - fprintf(stderr, "abort: javascript panic handler not callable\n"); - exit(1); - } -} - -static duk_ret_t -Mlk_panic(duk_context *ctx) -{ - if (duk_get_top(ctx) >= 1) - panicf("%s", duk_to_string(ctx, 0)); - else - panic(); - - return 0; -} - -static duk_ret_t -Mlk_setPanic(duk_context *ctx) -{ - if (!duk_is_callable(ctx, 0)) - return duk_error(ctx, DUK_ERR_TYPE_ERROR, "handler not callable"); - - duk_push_global_stash(ctx); - duk_dup(ctx, 0); - duk_put_prop_string(ctx, -2, PANIC_CB); - duk_pop(ctx); - - panic_handler = handler; - panic_data = ctx; - - return 0; -} - -static const duk_function_list_entry functions[] = { - { "panic", Mlk_panic, DUK_VARARGS }, - { "setPanic", Mlk_setPanic, 1 }, - { NULL, NULL, 0 } -}; - -void -js_panic_bind(duk_context *ctx) -{ - assert(ctx); - - duk_get_global_string(ctx, "Mlk"); - duk_put_function_list(ctx, -1, functions); - duk_pop(ctx); -}
--- a/src/libmlk-core-js/core/js-panic.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-panic.h -- core panic binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_PANIC_H -#define MLK_CORE_JS_PANIC_H - -#include <duktape.h> - -void -js_panic_bind(duk_context *); - -#endif /* !MLK_CORE_JS_PANIC_H */
--- a/src/libmlk-core-js/core/js-sound.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,147 +0,0 @@ -/* - * js-sound.c -- core sound binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/error.h> -#include <core/sound.h> -#include <core/vfs.h> - -#include "js-core.h" -#include "js-sound.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Sound") - -static struct sound * -self(duk_context *ctx) -{ - struct sound *snd; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - snd = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!snd) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Sound object"), NULL; - - return snd; -} - -static duk_ret_t -Sound_constructor(duk_context *ctx) -{ - const char *entry = duk_require_string(ctx, 0); - struct vfs_file file; - struct sound *snd; - - if (vfs_open(js_core_global_vfs(ctx), &file, entry, "r") < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - snd = alloc_new0(sizeof (*snd)); - - if (sound_openvfs(snd, &file) < 0) { - free(snd); - vfs_file_finish(&file); - - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - } - - vfs_file_finish(&file); - - duk_push_this(ctx); - duk_push_pointer(ctx, snd); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; - - -} - -static duk_ret_t -Sound_destructor(duk_context *ctx) -{ - struct sound *snd; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((snd = duk_to_pointer(ctx, -1))) - sound_finish(snd); - - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static duk_ret_t -Sound_proto_play(duk_context *ctx) -{ - if (sound_play(self(ctx)) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - return 0; -} - -static duk_ret_t -Sound_proto_pause(duk_context *ctx) -{ - sound_pause(self(ctx)); - - return 0; -} - -static duk_ret_t -Sound_proto_resume(duk_context *ctx) -{ - sound_resume(self(ctx)); - - return 0; -} - -static duk_ret_t -Sound_proto_stop(duk_context *ctx) -{ - sound_stop(self(ctx)); - - return 0; -} - -static const duk_function_list_entry methods[] = { - { "play", Sound_proto_play, DUK_VARARGS }, - { "pause", Sound_proto_pause, 0 }, - { "resume", Sound_proto_resume, 0 }, - { "stop", Sound_proto_stop, DUK_VARARGS }, - { NULL, NULL, 0 } -}; - -void -js_sound_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Sound_constructor, 1); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, Sound_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Sound"); -}
--- a/src/libmlk-core-js/core/js-sound.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-sound.h -- core sound binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_SOUND_H -#define MLK_CORE_JS_SOUND_H - -#include <duktape.h> - -void -js_sound_bind(duk_context *); - -#endif /* !MLK_CORE_JS_SOUND_H */
--- a/src/libmlk-core-js/core/js-sprite.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,160 +0,0 @@ -/* - * js-sprite.c -- core sprite binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/sprite.h> - -#include "js-sprite.h" -#include "js-texture.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Sprite") -#define PROTOTYPE DUK_HIDDEN_SYMBOL("Mlk.Sprite.Prototype") -#define TEXREF DUK_HIDDEN_SYMBOL("Mlk.Sprite.texture") - -static inline struct sprite * -self(duk_context *ctx) -{ - struct sprite *sprite; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - sprite = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!sprite) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Sprite object"), NULL; - - return sprite; -} - -static duk_ret_t -Sprite_constructor(duk_context *ctx) -{ - struct sprite *sprite; - struct texture *tex = js_texture_require(ctx, 0); - const unsigned int cellw = duk_require_uint(ctx, 1); - const unsigned int cellh = duk_require_uint(ctx, 2); - - sprite = alloc_new0(sizeof (*sprite)); - sprite_init(sprite, tex, cellw, cellh); - - duk_push_this(ctx); - duk_push_pointer(ctx, sprite); - duk_put_prop_string(ctx, -2, SIGNATURE); - - /* Store a copy of texture to avoid destruction. */ - duk_dup(ctx, 0); - duk_put_prop_string(ctx, -2, TEXREF); - - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Sprite_destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, SIGNATURE); - free(duk_to_pointer(ctx, -1)); - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - /* Remove texture reference. */ - duk_del_prop_string(ctx, 0, TEXREF); - - return 0; -} - -static duk_ret_t -Sprite_draw(duk_context *ctx) -{ - const struct sprite *sprite = self(ctx); - const unsigned int r = duk_require_uint(ctx, 0); - const unsigned int c = duk_require_uint(ctx, 1); - const int x = duk_require_int(ctx, 2); - const int y = duk_require_int(ctx, 3); - - if (r >= sprite->nrows) - return duk_error(ctx, DUK_ERR_RANGE_ERROR, "row overflow: %u >= %u", r, sprite->nrows); - if (c >= sprite->ncols) - return duk_error(ctx, DUK_ERR_RANGE_ERROR, "column overflow: %u >= %u", c, sprite->ncols); - - sprite_draw(sprite, r, c, x, y); - - return 0; -} - -static duk_ret_t -Sprite_scale(duk_context *ctx) -{ - const struct sprite *sprite = self(ctx); - const unsigned int r = duk_require_uint(ctx, 0); - const unsigned int c = duk_require_uint(ctx, 1); - const int x = duk_require_int(ctx, 2); - const int y = duk_require_int(ctx, 3); - const unsigned int w = duk_require_uint(ctx, 4); - const unsigned int h = duk_require_uint(ctx, 5); - - if (r >= sprite->nrows) - return duk_error(ctx, DUK_ERR_RANGE_ERROR, "row overflow: %u >= %u", r, sprite->nrows); - if (c >= sprite->ncols) - return duk_error(ctx, DUK_ERR_RANGE_ERROR, "column overflow: %u >= %u", c, sprite->ncols); - - sprite_scale(sprite, r, c, x, y, w, h); - - return 0; -} - -static const duk_function_list_entry methods[] = { - { "draw", Sprite_draw, 4 }, - { "scale", Sprite_scale, 6 }, - { NULL, NULL, 0 } -}; - -void -js_sprite_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Sprite_constructor, 3); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, Sprite_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_dup(ctx, -1); - duk_put_global_string(ctx, PROTOTYPE); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Sprite"); -} - -struct sprite * -js_sprite_require(duk_context *ctx, duk_idx_t idx) -{ - struct sprite *sprite; - - duk_get_prop_string(ctx, idx, SIGNATURE); - sprite = duk_to_pointer(ctx, -1); - duk_pop(ctx); - - if (!sprite) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Sprite object"), NULL; - - return sprite; -}
--- a/src/libmlk-core-js/core/js-sprite.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * js-sprite.h -- core sprite binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_SPRITE_H -#define MLK_CORE_JS_SPRITE_H - -#include <duktape.h> - -struct sprite; - -void -js_sprite_bind(duk_context *); - -struct sprite * -js_sprite_require(duk_context *, duk_idx_t); - -#endif /* !MLK_CORE_JS_SPRITE_H */
--- a/src/libmlk-core-js/core/js-state.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,224 +0,0 @@ -/* - * js-state.c -- core state binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <stdlib.h> - -#include <core/alloc.h> -#include <core/state.h> - -#include "js-event.h" -#include "js-state.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.State") - -static inline duk_context * -callable(struct js_state *data, const char *prop) -{ - duk_context *ctx; - - if (!data->ptr) - return NULL; - - duk_push_heapptr(data->ctx, data->ptr); - duk_get_prop_string(data->ctx, -1, prop); - duk_pull(data->ctx, -2); - - if (duk_is_callable(data->ctx, -2)) - ctx = data->ctx; - else { - ctx = NULL; - duk_pop_n(data->ctx, 2); - } - - return ctx; -} - -static void -start(struct state *state) -{ - duk_context *ctx; - - if ((ctx = callable(state->data, "start"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -handle(struct state *state, const union event *ev) -{ - duk_context *ctx; - - if ((ctx = callable(state->data, "handle"))) { - js_event_push(ctx, ev); - duk_call_method(ctx, 1); - duk_pop(ctx); - } -} - -static void -update(struct state *state, unsigned int ticks) -{ - duk_context *ctx; - - if ((ctx = callable(state->data, "update"))) { - duk_push_uint(ctx, ticks); - duk_call_method(ctx, 1); - duk_pop(ctx); - } -} - -static void -draw(struct state *state) -{ - duk_context *ctx; - - if ((ctx = callable(state->data, "draw"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -suspend(struct state *state) -{ - duk_context *ctx; - - if ((ctx = callable(state->data, "suspend"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -resume(struct state *state) -{ - duk_context *ctx; - - if ((ctx = callable(state->data, "resume"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -end(struct state *state) -{ - duk_context *ctx; - - if ((ctx = callable(state->data, "end"))) { - duk_call_method(ctx, 0); - duk_pop(ctx); - } -} - -static void -finish(struct state *state) -{ - struct js_state *data = state->data; - - /* I must not be called anymore. */ - data->ptr = NULL; - - /* Remove myself from parent stack if any. */ - if (data->parent) { - duk_push_heapptr(data->ctx, data->parent); - duk_push_sprintf(data->ctx, "%p", data); - duk_del_prop(data->ctx, -2); - duk_pop(data->ctx); - data->parent = NULL; - } - - if (--data->refc == 0) - free(data); -} - -static duk_ret_t -State_constructor(duk_context *ctx) -{ - struct js_state *data; - - data = alloc_new0(sizeof (*data)); - data->ctx = ctx; - data->refc = 1; - data->st.data = data; - data->st.start = start; - data->st.handle = handle; - data->st.update = update; - data->st.draw = draw; - data->st.suspend = suspend; - data->st.resume = resume; - data->st.end = end; - data->st.finish = finish; - - duk_push_this(ctx); - data->ptr = duk_get_heapptr(ctx, -1); - duk_push_pointer(ctx, data); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -State_destructor(duk_context *ctx) -{ - struct js_state *data; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((data = duk_to_pointer(ctx, -1))) - state_finish(&data->st); - - duk_pop(ctx); - - return 0; -} - -void -js_state_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, State_constructor, 1); - duk_push_object(ctx); - duk_push_c_function(ctx, State_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "State"); -} - -struct js_state * -js_state_require(duk_context *ctx, duk_idx_t idx) -{ - struct js_state *data = NULL; - - if (duk_is_object(ctx, idx)) { - duk_get_prop_string(ctx, idx, SIGNATURE); - data = duk_to_pointer(ctx, -1); - duk_pop(ctx); - } - - if (!data) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a State object"), NULL; - - data->refc++; - - return data; -}
--- a/src/libmlk-core-js/core/js-state.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * js-state.h -- core state binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_STATE_H -#define MLK_CORE_JS_STATE_H - -#include <duktape.h> - -#include <core/state.h> - -struct js_state { - duk_context *ctx; - void *ptr; - void *parent; - unsigned int refc; - struct state st; -}; - -void -js_state_bind(duk_context *); - -struct js_state * -js_state_require(duk_context *, duk_idx_t); - -#endif /* !MLK_CORE_JS_STATE_H */
--- a/src/libmlk-core-js/core/js-texture.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,249 +0,0 @@ -/* - * js-texture.c -- core texture binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/alloc.h> -#include <core/error.h> -#include <core/image.h> -#include <core/texture.h> -#include <core/vfs.h> - -#include "js-core.h" -#include "js-texture.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Texture") -#define PROTOTYPE DUK_HIDDEN_SYMBOL("Mlk.Texture.Prototype") - -static inline struct texture * -self(duk_context *ctx) -{ - struct texture *tex; - - duk_push_this(ctx); - duk_get_prop_string(ctx, -1, SIGNATURE); - tex = duk_to_pointer(ctx, -1); - duk_pop_2(ctx); - - if (!tex) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Texture object"), NULL; - - return tex; -} - -static duk_ret_t -Texture_constructor(duk_context *ctx) -{ - const unsigned int w = duk_require_uint(ctx, 0); - const unsigned int h = duk_require_uint(ctx, 1); - struct texture *tex; - - tex = alloc_new(sizeof (*tex)); - - if (texture_new(tex, w, h) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - duk_push_this(ctx); - duk_push_pointer(ctx, tex); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Texture_setBlendMode(duk_context *ctx) -{ - const int blend = duk_require_uint(ctx, 0); - struct texture *tex = self(ctx); - - if (blend < 0 || blend >= TEXTURE_BLEND_LAST) - return duk_error(ctx, DUK_ERR_ERROR, "invalid blend"); - if (texture_set_blend_mode(tex, blend) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - return 0; -} - -static duk_ret_t -Texture_setAlphaMod(duk_context *ctx) -{ - const unsigned int alpha = duk_require_uint(ctx, 0); - struct texture *tex = self(ctx); - - if (texture_set_alpha_mod(tex, alpha) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - return 0; -} - -static duk_ret_t -Texture_setColorMod(duk_context *ctx) -{ - const unsigned long color = duk_require_uint(ctx, 0); - struct texture *tex = self(ctx); - - if (texture_set_color_mod(tex, color) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - return 0; -} - -static duk_ret_t -Texture_draw(duk_context *ctx) -{ - const int x = duk_require_int(ctx, 0); - const int y = duk_require_int(ctx, 1); - struct texture *tex = self(ctx); - - if (texture_draw(tex, x, y) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - return 0; -} - -static duk_ret_t -Texture_scale(duk_context *ctx) -{ - const int srcx = duk_require_int(ctx, 0); - const int srcy = duk_require_int(ctx, 1); - const unsigned srcw = duk_require_uint(ctx, 2); - const unsigned srch = duk_require_uint(ctx, 3); - const int dstx = duk_require_int(ctx, 4); - const int dsty = duk_require_int(ctx, 5); - const unsigned dstw = duk_require_uint(ctx, 6); - const unsigned dsth = duk_require_uint(ctx, 7); - const double angle = duk_get_number_default(ctx, 8, .0); - struct texture *tex = self(ctx); - - if (texture_scale(tex, srcx, srcy, srcw, srch, dstx, dsty, dstw, dsth, angle) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - return 0; -} - -static duk_ret_t -Texture_destructor(duk_context *ctx) -{ - struct texture *tex; - - duk_get_prop_string(ctx, 0, SIGNATURE); - - if ((tex = duk_to_pointer(ctx, -1))) - texture_finish(tex); - - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static duk_ret_t -Texture_fromImage(duk_context *ctx) -{ - const char *entry = duk_require_string(ctx, 0); - struct texture *tex; - struct vfs_file file; - - if (vfs_open(js_core_global_vfs(ctx), &file, entry, "r") < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - tex = alloc_new0(sizeof (*tex)); - - if (image_openvfs(tex, &file) < 0) { - free(tex); - vfs_file_finish(&file); - - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - } - - vfs_file_finish(&file); - js_texture_push(ctx, tex); - - return 1; -} - -static const struct duk_function_list_entry methods[] = { - { "setBlendMode", Texture_setBlendMode, 1 }, - { "setAlphaMod", Texture_setAlphaMod, 1 }, - { "setColorMod", Texture_setColorMod, 1 }, - { "draw", Texture_draw, 2 }, - { "scale", Texture_scale, DUK_VARARGS }, - { NULL, NULL, 0 } -}; - -static const struct duk_function_list_entry functions[] = { - { "fromImage", Texture_fromImage, 1 }, - { NULL, NULL, 0 } -}; - -static const duk_number_list_entry blend[] = { - { "NONE", TEXTURE_BLEND_NONE }, - { "BLEND", TEXTURE_BLEND_BLEND }, - { "ADD", TEXTURE_BLEND_ADD }, - { "MODULATE", TEXTURE_BLEND_MODULATE }, - { NULL, 0 } -}; - -void -js_texture_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Texture_constructor, 2); - duk_put_function_list(ctx, -1, functions); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_push_c_function(ctx, Texture_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_push_object(ctx); - duk_put_number_list(ctx, -1, blend); - duk_put_prop_string(ctx, -2, "Blend"); - duk_dup(ctx, -1); - duk_put_global_string(ctx, PROTOTYPE); - duk_put_prop_string(ctx, -2, "prototype"); - duk_put_global_string(ctx, "Texture"); -} - -struct texture * -js_texture_require(duk_context *ctx, duk_idx_t idx) -{ - struct texture *tex; - - duk_get_prop_string(ctx, idx, SIGNATURE); - tex = duk_to_pointer(ctx, -1); - duk_pop(ctx); - - if (!tex) - return (void)duk_error(ctx, DUK_ERR_TYPE_ERROR, "not a Texture object"), NULL; - - return tex; -} - -void -js_texture_push(duk_context *ctx, struct texture *tex) -{ - assert(ctx); - assert(tex); - - duk_push_object(ctx); - duk_push_pointer(ctx, tex); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_get_global_string(ctx, PROTOTYPE); - duk_set_prototype(ctx, -2); -}
--- a/src/libmlk-core-js/core/js-texture.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,35 +0,0 @@ -/* - * js-texture.h -- core texture binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_TEXTURE_H -#define MLK_CORE_JS_TEXTURE_H - -#include <duktape.h> - -struct texture; - -void -js_texture_bind(duk_context *); - -struct texture * -js_texture_require(duk_context *, duk_idx_t); - -void -js_texture_push(duk_context *, struct texture *); - -#endif /* !MLK_CORE_JS_TEXTURE_H */
--- a/src/libmlk-core-js/core/js-trace.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,85 +0,0 @@ -/* - * js-trace.c -- core trace binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/trace.h> - -#include "js-trace.h" - -#define TRACE_CB DUK_HIDDEN_SYMBOL("Mlk.traceHandler") - -static void -handler(const char *msg) -{ - duk_context *ctx = trace_data; - - duk_push_global_stash(ctx); - duk_get_prop_string(ctx, -1, TRACE_CB); - duk_remove(ctx, -2); - - if (duk_is_callable(ctx, -1)) { - duk_push_string(ctx, msg); - duk_call(ctx, 1); - duk_pop(ctx); - } else { - fprintf(stderr, "abort: javascript panic handler not callable\n"); - exit(1); - } -} - -static duk_ret_t -Mlk_trace(duk_context *ctx) -{ - tracef("%s", duk_require_string(ctx, 0)); - - return 0; -} - -static duk_ret_t -Mlk_setTrace(duk_context *ctx) -{ - if (!duk_is_callable(ctx, 0)) - return duk_error(ctx, DUK_ERR_TYPE_ERROR, "handler not callable"); - - duk_push_global_stash(ctx); - duk_dup(ctx, 0); - duk_put_prop_string(ctx, -2, TRACE_CB); - duk_pop(ctx); - - trace_handler = handler; - trace_data = ctx; - - return 0; -} - -static const duk_function_list_entry functions[] = { - { "trace", Mlk_trace, 1 }, - { "setTrace", Mlk_setTrace, 1 }, - { NULL, NULL, 0 } -}; - -void -js_trace_bind(duk_context *ctx) -{ - assert(ctx); - - duk_get_global_string(ctx, "Mlk"); - duk_put_function_list(ctx, -1, functions); - duk_pop(ctx); -}
--- a/src/libmlk-core-js/core/js-trace.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-trace.h -- core trace binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_TRACE_H -#define MLK_CORE_JS_TRACE_H - -#include <duktape.h> - -void -js_trace_bind(duk_context *); - -#endif /* !MLK_CORE_JS_TRACE_H */
--- a/src/libmlk-core-js/core/js-window.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,90 +0,0 @@ -/* - * js-window.c -- core window binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> - -#include <core/error.h> -#include <core/window.h> - -#include "js-window.h" - -#define SIGNATURE DUK_HIDDEN_SYMBOL("Mlk.Window") - -static duk_ret_t -Window_constructor(duk_context *ctx) -{ - const char *title = duk_require_string(ctx, 0); - const unsigned int w = duk_require_uint(ctx, 1); - const unsigned int h = duk_require_uint(ctx, 2); - - if (window_open(title, w, h) < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - - duk_push_this(ctx); - duk_push_boolean(ctx, 1); - duk_put_prop_string(ctx, -2, SIGNATURE); - duk_pop(ctx); - - return 0; -} - -static duk_ret_t -Window_setCursor(duk_context *ctx) -{ - const unsigned int cursor = duk_require_uint(ctx, 0); - - if (cursor >= WINDOW_CURSOR_LAST) - return duk_error(ctx, DUK_ERR_RANGE_ERROR, "invalid cursor"); - - window_set_cursor(cursor); - - return 0; -} - -static duk_ret_t -Window_destructor(duk_context *ctx) -{ - duk_get_prop_string(ctx, 0, SIGNATURE); - - if (duk_to_boolean(ctx, -1)) - window_finish(); - - duk_pop(ctx); - duk_del_prop_string(ctx, 0, SIGNATURE); - - return 0; -} - -static const duk_function_list_entry methods[] = { - { "setCursor", Window_setCursor, 1 }, - { NULL, NULL, 0 } -}; - -void -js_window_bind(duk_context *ctx) -{ - assert(ctx); - - duk_push_c_function(ctx, Window_constructor, 3); - duk_push_object(ctx); - duk_put_function_list(ctx, -1, methods); - duk_put_prop_string(ctx, -2, "prototype"); - duk_push_c_function(ctx, Window_destructor, 1); - duk_set_finalizer(ctx, -2); - duk_put_global_string(ctx, "Window"); -}
--- a/src/libmlk-core-js/core/js-window.h Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,27 +0,0 @@ -/* - * js-window.h -- core window binding - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#ifndef MLK_CORE_JS_WINDOW_H -#define MLK_CORE_JS_WINDOW_H - -#include <duktape.h> - -void -js_window_bind(duk_context *); - -#endif /* !MLK_CORE_JS_WINDOW_H */
--- a/src/mlk-run/CMakeLists.txt Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,31 +0,0 @@ -# -# CMakeLists.txt -- CMake build system for Molko's Engine -# -# Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> -# -# Permission to use, copy, modify, and/or distribute this software for any -# purpose with or without fee is hereby granted, provided that the above -# copyright notice and this permission notice appear in all copies. -# -# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. -# - -project(mlk-run) - -set( - SOURCES - ${mlk-run_SOURCE_DIR}/main.c -) - -mlk_executable( - NAME mlk-run - INSTALL - SOURCES ${SOURCES} - LIBRARIES libmlk-core-js -)
--- a/src/mlk-run/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,215 +0,0 @@ -/* - * main.c -- main mlk-run file - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <stdio.h> -#include <stdlib.h> -#include <limits.h> - -#include <duktape.h> -#include <duk_module_duktape.h> - -#include <port/port.h> - -#include <core/error.h> -#include <core/panic.h> -#include <core/vfs-directory.h> -#include <core/vfs-zip.h> -#include <core/vfs.h> - -#include <core/js-action.h> -#include <core/js-action-stack.h> -#include <core/js-animation.h> -#include <core/js-clock.h> -#include <core/js-color.h> -#include <core/js-core.h> -#include <core/js-drawable.h> -#include <core/js-drawable-stack.h> -#include <core/js-event.h> -#include <core/js-font.h> -#include <core/js-game.h> -#include <core/js-music.h> -#include <core/js-painter.h> -#include <core/js-panic.h> -#include <core/js-sound.h> -#include <core/js-sprite.h> -#include <core/js-state.h> -#include <core/js-texture.h> -#include <core/js-trace.h> -#include <core/js-window.h> - -/* VFS loader to support zip and directories when loading game. */ -static struct vfs vfs; - -/* Javascript context. */ -static duk_context *ctx; - -static duk_ret_t -print(duk_context *ctx) -{ - puts(duk_require_string(ctx, 0)); - - return 0; -} - -static duk_ret_t -modsearch(duk_context *ctx) -{ - char path[PATH_MAX], *data; - struct vfs_file file; - size_t datasz; - - snprintf(path, sizeof (path), "%s.js", duk_require_string(ctx, 0)); - - if (vfs_open(&vfs, &file, path, "r") < 0) - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - if (!(data = vfs_file_aread(&file, &datasz))) { - vfs_file_finish(&file); - return duk_error(ctx, DUK_ERR_ERROR, "%s", error()); - } - - vfs_file_finish(&file); - duk_push_lstring(ctx, data, datasz); - free(data); - - return 1; -} - -static void -core_bind(duk_context *ctx) -{ - /* Brings Mlk global object. */ - js_core_bind(ctx, &vfs); - - js_action_bind(ctx); - js_action_stack_bind(ctx); - js_animation_bind(ctx); - js_clock_bind(ctx); - js_color_bind(ctx); - js_drawable_bind(ctx); - js_drawable_stack_bind(ctx); - js_event_bind(ctx); - js_font_bind(ctx); - js_game_bind(ctx); - js_music_bind(ctx); - js_painter_bind(ctx); - js_panic_bind(ctx); - js_sound_bind(ctx); - js_sprite_bind(ctx); - js_state_bind(ctx); - js_texture_bind(ctx); - js_trace_bind(ctx); - js_window_bind(ctx); -} - -static void -init(void) -{ - /* TODO: this is temporary. */ - if (core_init("fr.malikania", "mlk-run") < 0) - panic(); - - /* Fireup Javascript. */ - ctx = duk_create_heap_default(); - core_bind(ctx); - - /* Setup some convenient global functions. */ - duk_push_global_object(ctx); - duk_push_c_function(ctx, print, 1); - duk_put_prop_string(ctx, -2, "print"); - duk_pop(ctx); - - /* Setup module loader. */ - duk_module_duktape_init(ctx); - duk_get_global_string(ctx, "Duktape"); - duk_push_c_function(ctx, modsearch, 4); - duk_put_prop_string(ctx, -2, "modSearch"); - duk_pop(ctx); -} - -static void -startup(void) -{ - struct vfs_file main; - char *code; - - if (vfs_open(&vfs, &main, "main.js", "r") < 0) - panic(); - if (!(code = vfs_file_aread(&main, NULL))) - panic(); - - vfs_file_finish(&main); - - if (duk_peval_string(ctx, code)) - panicf("%s", duk_safe_to_string(ctx, -1)); - - free(code); -} - -static void -finish(void) -{ - vfs_finish(&vfs); - duk_destroy_heap(ctx); -} - -static void -loadzip(const char *path) -{ - if (vfs_zip(&vfs, path, "r") < 0) - panic(); -} - -static void -loaddirectory(const char *path) -{ - vfs_directory(&vfs, path); -} - -static void -load(const char *path) -{ - /* TODO: improve this. */ - if (strstr(path, ".mlk")) - loadzip(path); - else - loaddirectory(path); - - startup(); -} - -static void -run(int argc, char **argv) -{ - if (argc < 0) { - fprintf(stderr, "usage: mlk-run game\n"); - exit(1); - } - - load(argv[0]); -} - -int -main(int argc, char **argv) -{ - --argc; - ++argv; - - init(); - run(argc, argv); - finish(); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/bcc/arg.h Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,49 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] == '-'\ + && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +#define ARGEND }\ + } + +#define ARGC() argc_ + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#define ARGF() ((argv[0][1] == '\0' && argv[1] == NULL)?\ + (char *)0 :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + +#endif
--- a/src/tools/bcc/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,176 +0,0 @@ -/* - * main.c -- binary to C/C++ arrays converter - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <errno.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <port/port.h> - -static const char *charset = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"; -static char findentchar = '\t'; -static int findent = 1; -static bool fconst; -static bool fnull; -static bool fstatic; -static bool funsigned; - -static void -usage(void) -{ - fprintf(stderr, "usage: bcc [-0csu] [-I tab-indent] [-i space-indent] input variable\n"); - exit(1); -} - -static void -die(const char *fmt, ...) -{ - va_list ap; - - va_start(ap, fmt); - fputs("abort: ", stderr); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); -} - -static char * -mangle(char *variable) -{ - char *p; - size_t pos; - - /* Remove extension. */ - if ((p = strrchr(variable, '.'))) - *p = '\0'; - - /* Remove disallowed characters. */ - while ((pos = strspn(variable, charset)) != strlen(variable)) - variable[pos] = '_'; - - return variable; -} - -static void -indent(void) -{ - for (int i = 0; i < findent; ++i) - putchar(findentchar); -} - -static void -put(int ch) -{ - if (funsigned) - printf("0x%02hhx", (unsigned char)ch); - else - printf("%hhd", (signed char)ch); -} - -static void -process(const char *input, const char *variable) -{ - FILE *fp; - int ch, col = 0; - - if (strcmp(input, "-") == 0) - fp = stdin; - else if (!(fp = fopen(input, "rb"))) - die("%s: %s\n", input, strerror(errno)); - - if (fstatic) - printf("static "); - if (fconst) - printf("const "); - - printf(funsigned ? "unsigned " : "signed "); - printf("char %s[] = {\n", variable); - - for (ch = fgetc(fp); ch != EOF; ) { - if (col == 0) - indent(); - - put(ch); - - if ((ch = fgetc(fp)) != EOF || fnull) - printf(",%s", col < 3 ? " " : ""); - - if (++col == 4) { - col = 0; - putchar('\n'); - } - - /* Add final '\0' if required. */ - if (ch == EOF && fnull) { - if (col++ == 0) - indent(); - - put(0); - } - } - - if (col != 0) - printf("\n"); - - puts("};"); - fclose(fp); -} - -int -main(int argc, char **argv) -{ - int ch; - - while ((ch = port_getopt(argc, argv, "0cI:i:su")) != -1) { - switch (ch) { - case '0': - fnull = true; - break; - case 'c': - fconst = true; - break; - case 'I': - findentchar = '\t'; - findent = atoi(port_optarg); - break; - case 'i': - findentchar = ' '; - findent = atoi(port_optarg); - break; - case 's': - fstatic = true; - break; - case 'u': - funsigned = true; - break; - default: - break; - } - } - - argc -= port_optind; - argv += port_optind; - - if (argc < 2) - usage(); - - process(argv[0], mangle(argv[1])); -}
--- a/src/tools/map/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,257 +0,0 @@ -/* - * main.c -- convert tiled tiled JSON files into custom files - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <limits.h> -#include <stdarg.h> -#include <stdbool.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include <jansson.h> - -#include <port/port.h> - -static void -die(const char *fmt, ...) -{ - assert(fmt); - - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); -} - -static bool -is_layer(const char *name) -{ - return strcmp(name, "background") == 0 || - strcmp(name, "foreground") == 0 || - strcmp(name, "above") == 0 || - strcmp(name, "actions") == 0; -} - -static const json_t * -find_property(const json_t *props, const char *which) -{ - const json_t *obj; - size_t index; - - json_array_foreach(props, index, obj) { - if (!json_is_object(obj)) - continue; - - const json_t *key = json_object_get(obj, "name"); - const json_t *value = json_object_get(obj, "value"); - - if (json_is_string(key) && value && strcmp(json_string_value(key), which) == 0) - return value; - } - - return NULL; -} - -static void -write_title(const json_t *props) -{ - const json_t *prop_title = find_property(props, "title"); - - if (prop_title && json_is_string(prop_title)) - printf("title|%s\n", json_string_value(prop_title)); -} - -static void -write_origin(const json_t *props) -{ - const json_t *prop_origin_x = find_property(props, "origin-x"); - const json_t *prop_origin_y = find_property(props, "origin-y"); - - if (!prop_origin_x || !json_is_integer(prop_origin_x) || - !prop_origin_y || !json_is_integer(prop_origin_y)) - return; - - printf("origin|%d|%d\n", - (int)json_integer_value(prop_origin_x), - (int)json_integer_value(prop_origin_y)); -} - -static void -write_properties(const json_t *props) -{ - write_title(props); - write_origin(props); -} - -static void -write_dimensions(const json_t *document) -{ - json_t *width = json_object_get(document, "width"); - json_t *height = json_object_get(document, "height"); - - if (!width || !json_is_integer(width)) - die("missing 'width' property\n"); - if (!height || !json_is_integer(height)) - die("missing 'height' property\n"); - - printf("columns|%d\n", (int)json_integer_value(width)); - printf("rows|%d\n", (int)json_integer_value(height)); -} - -static void -write_object(const json_t *object) -{ - assert(json_is_object(object)); - - json_t *x = json_object_get(object, "x"); - json_t *y = json_object_get(object, "y"); - json_t *width = json_object_get(object, "width"); - json_t *height = json_object_get(object, "height"); - json_t *props = json_object_get(object, "properties"); - const json_t *exec, *block; - - if (!x || !json_is_number(x)) - die("invalid 'x' property in object\n"); - if (!y || !json_is_number(y)) - die("invalid 'y' property in object\n"); - if (!width || !json_is_number(width)) - die("invalid 'width' property in object\n"); - if (!height || !json_is_number(height)) - die("invalid 'height' property in object\n"); - - /* This is optional and set to 0 if not present. */ - block = find_property(props, "block"); - - /* In tiled, those properties are float but we only use ints in MA */ - printf("%d|%d|%d|%d|%d", - (int)json_integer_value(x), - (int)json_integer_value(y), - (int)json_integer_value(width), - (int)json_integer_value(height), - (int)json_is_true(block) - ); - - if ((exec = find_property(props, "exec")) && json_is_string(exec)) - printf("|%s", json_string_value(exec)); - - printf("\n"); -} - -static void -write_layer(const json_t *layer) -{ - json_t *objects = json_object_get(layer, "objects"); - json_t *data = json_object_get(layer, "data"); - json_t *name = json_object_get(layer, "name"); - json_t *tile, *object; - size_t index; - - if (!name || !json_is_string(name)) - die("invalid 'name' property in layer"); - if (!is_layer(json_string_value(name))) - die("invalid 'name' layer: %s\n", json_string_value(name)); - - printf("layer|%s\n", json_string_value(name)); - - /* Only foreground/background have 'data' property */ - if (json_is_array(data)) { - json_array_foreach(data, index, tile) { - if (!json_is_integer(tile)) - die("invalid 'data' property in layer\n"); - - printf("%d\n", (int)json_integer_value(tile)); - } - } - - /* Only objects has 'objects' property */ - if (json_is_array(objects)) { - json_array_foreach(objects, index, object) { - if (!json_is_object(object)) - die("invalid 'objects' property in layer\n"); - - write_object(object); - } - } -} - -static void -write_layers(const json_t *layers) -{ - size_t index; - json_t *layer; - - if (!layers) - return; - - json_array_foreach(layers, index, layer) { - if (!json_is_object(layer)) - die("layer is not an object\n"); - - write_layer(layer); - } -} - -static void -write_tileset(const json_t *tilesets) -{ - char path[PATH_MAX]; - char filename[FILENAME_MAX] = {0}, *ext; - const json_t *tileset, *source; - - if (json_array_size(tilesets) != 1) - die("map must contain exactly one tileset"); - - tileset = json_array_get(tilesets, 0); - source = json_object_get(tileset, "source"); - - if (!json_is_string(source)) - die("invalid 'source' property in tileset\n"); - - /* We need to replace the .json extension to .tileset. */ - snprintf(path, sizeof (path), "%s", json_string_value(source)); - snprintf(filename, sizeof (filename), "%s", port_basename(path)); - - if (!(ext = strstr(filename, ".json"))) - die("could not determine tileset extension"); - - *ext = '\0'; - - printf("tileset|%s.tileset\n", filename); -} - -int -main(void) -{ - json_t *document; - json_error_t error; - - document = json_loadf(stdin, 0, &error); - - if (!document) - die("%d:%d: %s\n", error.line, error.column, error.text); - - write_properties(json_object_get(document, "properties")); - write_dimensions(document); - write_layers(json_object_get(document, "layers")); - write_tileset(json_object_get(document, "tilesets")); - - json_decref(document); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/map/mlk-map.c Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,257 @@ +/* + * main.c -- convert tiled tiled JSON files into custom files + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <limits.h> +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <jansson.h> + +#include <port/port.h> + +static void +die(const char *fmt, ...) +{ + assert(fmt); + + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +static bool +is_layer(const char *name) +{ + return strcmp(name, "background") == 0 || + strcmp(name, "foreground") == 0 || + strcmp(name, "above") == 0 || + strcmp(name, "actions") == 0; +} + +static const json_t * +find_property(const json_t *props, const char *which) +{ + const json_t *obj; + size_t index; + + json_array_foreach(props, index, obj) { + if (!json_is_object(obj)) + continue; + + const json_t *key = json_object_get(obj, "name"); + const json_t *value = json_object_get(obj, "value"); + + if (json_is_string(key) && value && strcmp(json_string_value(key), which) == 0) + return value; + } + + return NULL; +} + +static void +write_title(const json_t *props) +{ + const json_t *prop_title = find_property(props, "title"); + + if (prop_title && json_is_string(prop_title)) + printf("title|%s\n", json_string_value(prop_title)); +} + +static void +write_origin(const json_t *props) +{ + const json_t *prop_origin_x = find_property(props, "origin-x"); + const json_t *prop_origin_y = find_property(props, "origin-y"); + + if (!prop_origin_x || !json_is_integer(prop_origin_x) || + !prop_origin_y || !json_is_integer(prop_origin_y)) + return; + + printf("origin|%d|%d\n", + (int)json_integer_value(prop_origin_x), + (int)json_integer_value(prop_origin_y)); +} + +static void +write_properties(const json_t *props) +{ + write_title(props); + write_origin(props); +} + +static void +write_dimensions(const json_t *document) +{ + json_t *width = json_object_get(document, "width"); + json_t *height = json_object_get(document, "height"); + + if (!width || !json_is_integer(width)) + die("missing 'width' property\n"); + if (!height || !json_is_integer(height)) + die("missing 'height' property\n"); + + printf("columns|%d\n", (int)json_integer_value(width)); + printf("rows|%d\n", (int)json_integer_value(height)); +} + +static void +write_object(const json_t *object) +{ + assert(json_is_object(object)); + + json_t *x = json_object_get(object, "x"); + json_t *y = json_object_get(object, "y"); + json_t *width = json_object_get(object, "width"); + json_t *height = json_object_get(object, "height"); + json_t *props = json_object_get(object, "properties"); + const json_t *exec, *block; + + if (!x || !json_is_number(x)) + die("invalid 'x' property in object\n"); + if (!y || !json_is_number(y)) + die("invalid 'y' property in object\n"); + if (!width || !json_is_number(width)) + die("invalid 'width' property in object\n"); + if (!height || !json_is_number(height)) + die("invalid 'height' property in object\n"); + + /* This is optional and set to 0 if not present. */ + block = find_property(props, "block"); + + /* In tiled, those properties are float but we only use ints in MA */ + printf("%d|%d|%d|%d|%d", + (int)json_integer_value(x), + (int)json_integer_value(y), + (int)json_integer_value(width), + (int)json_integer_value(height), + (int)json_is_true(block) + ); + + if ((exec = find_property(props, "exec")) && json_is_string(exec)) + printf("|%s", json_string_value(exec)); + + printf("\n"); +} + +static void +write_layer(const json_t *layer) +{ + json_t *objects = json_object_get(layer, "objects"); + json_t *data = json_object_get(layer, "data"); + json_t *name = json_object_get(layer, "name"); + json_t *tile, *object; + size_t index; + + if (!name || !json_is_string(name)) + die("invalid 'name' property in layer"); + if (!is_layer(json_string_value(name))) + die("invalid 'name' layer: %s\n", json_string_value(name)); + + printf("layer|%s\n", json_string_value(name)); + + /* Only foreground/background have 'data' property */ + if (json_is_array(data)) { + json_array_foreach(data, index, tile) { + if (!json_is_integer(tile)) + die("invalid 'data' property in layer\n"); + + printf("%d\n", (int)json_integer_value(tile)); + } + } + + /* Only objects has 'objects' property */ + if (json_is_array(objects)) { + json_array_foreach(objects, index, object) { + if (!json_is_object(object)) + die("invalid 'objects' property in layer\n"); + + write_object(object); + } + } +} + +static void +write_layers(const json_t *layers) +{ + size_t index; + json_t *layer; + + if (!layers) + return; + + json_array_foreach(layers, index, layer) { + if (!json_is_object(layer)) + die("layer is not an object\n"); + + write_layer(layer); + } +} + +static void +write_tileset(const json_t *tilesets) +{ + char path[PATH_MAX]; + char filename[FILENAME_MAX] = {0}, *ext; + const json_t *tileset, *source; + + if (json_array_size(tilesets) != 1) + die("map must contain exactly one tileset"); + + tileset = json_array_get(tilesets, 0); + source = json_object_get(tileset, "source"); + + if (!json_is_string(source)) + die("invalid 'source' property in tileset\n"); + + /* We need to replace the .json extension to .tileset. */ + snprintf(path, sizeof (path), "%s", json_string_value(source)); + snprintf(filename, sizeof (filename), "%s", port_basename(path)); + + if (!(ext = strstr(filename, ".json"))) + die("could not determine tileset extension"); + + *ext = '\0'; + + printf("tileset|%s.tileset\n", filename); +} + +int +main(void) +{ + json_t *document; + json_error_t error; + + document = json_loadf(stdin, 0, &error); + + if (!document) + die("%d:%d: %s\n", error.line, error.column, error.text); + + write_properties(json_object_get(document, "properties")); + write_dimensions(document); + write_layers(json_object_get(document, "layers")); + write_tileset(json_object_get(document, "tilesets")); + + json_decref(document); +}
--- a/src/tools/tileset/main.c Fri Oct 07 15:25:32 2022 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,204 +0,0 @@ -/* - * main.c -- convert tiled tilesets JSON files into custom files - * - * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include <assert.h> -#include <stdarg.h> -#include <stdio.h> -#include <string.h> - -#include <jansson.h> - -static void -die(const char *fmt, ...) -{ - assert(fmt); - - va_list ap; - - va_start(ap, fmt); - vfprintf(stderr, fmt, ap); - va_end(ap); - exit(1); -} - -static void -write_dimensions(const json_t *document) -{ - const json_t *tilewidth = json_object_get(document, "tilewidth"); - const json_t *tileheight = json_object_get(document, "tileheight"); - - if (!json_is_integer(tilewidth)) - die("invalid 'tilewidth' property\n"); - if (!json_is_integer(tileheight)) - die("invalid 'tileheight' property\n"); - - printf("tilewidth|%u\n", (unsigned int)json_integer_value(tilewidth)); - printf("tileheight|%u\n", (unsigned int)json_integer_value(tileheight)); -} - -static void -write_image(const json_t *document) -{ - const json_t *image = json_object_get(document, "image"); - - if (!json_is_string(image)) - die("invalid 'image' property\n"); - - printf("image|%s\n", json_string_value(image)); -} - -static const json_t * -find_property_value(const json_t *array, const char *prop) -{ - const json_t *obj; - size_t i; - - json_array_foreach(array, i, obj) { - const json_t *name = json_object_get(obj, "name"); - - if (!name || !json_is_string(name)) - die("invalid property object\n"); - - if (strcmp(json_string_value(name), prop) == 0) - return json_object_get(obj, "value"); - } - - return NULL; -} - -static void -write_animation(const json_t *tile) -{ - const json_t *id = json_object_get(tile, "id"); - const json_t *properties = json_object_get(tile, "properties"); - const json_t *file = find_property_value(properties, "animation-file"); - const json_t *delay = find_property_value(properties, "animation-delay"); - - /* Animations are completely optional. */ - if (!json_is_array(properties)) - return; - - if (!json_is_integer(id)) - die("invalid 'id' property in tile\n"); - - if (json_is_string(file)) { - printf("%d|%s|", (int)json_integer_value(id), json_string_value(file)); - - if (json_is_integer(delay)) - printf("%d\n", (int)json_integer_value(delay)); - else - printf("10\n"); - } -} - -static void -write_tiledef(const json_t *tile) -{ - const json_t *id = json_object_get(tile, "id"); - const json_t *objectgroup = json_object_get(tile, "objectgroup"); - const json_t *objects = json_object_get(objectgroup, "objects"); - const json_t *first = json_array_get(objects, 0); - const json_t *x, *y, *w, *h; - - /* Collisions are optional. */ - if (!json_is_object(objectgroup)) - return; - - if (!json_is_integer(id)) - die("invalid 'id' property in tile\n"); - if (!json_is_array(objects)) - die("invalid 'objects' property in tile\n"); - - x = json_object_get(first, "x"); - y = json_object_get(first, "y"); - w = json_object_get(first, "width"); - h = json_object_get(first, "height"); - - if (!json_is_integer(x) || !json_is_integer(y) || - !json_is_integer(w) || !json_is_integer(h)) - die("invalid collide object in tile description\n"); - - printf("%d|%d|%d|%d|%d\n", - (int)json_integer_value(id), - (int)json_integer_value(x), - (int)json_integer_value(y), - (int)json_integer_value(w), - (int)json_integer_value(h)); -} - -static void -write_tiledefs(const json_t *tiles) -{ - size_t index; - json_t *object; - - if (!json_is_array(tiles)) - return; - - puts("tiledefs"); - - json_array_foreach(tiles, index, object) { - if (!json_is_object(object)) - die("tile is not an object\n"); - - write_tiledef(object); - } -} - -static void -write_animations(const json_t *tiles) -{ - size_t index; - json_t *object; - - if (!json_is_array(tiles)) - return; - - puts("animations"); - - json_array_foreach(tiles, index, object) { - if (!json_is_object(object)) - die("tile is not an object\n"); - - write_animation(object); - } -} - -int -main(int argc, char *argv[]) -{ - (void)argc; - (void)argv; - - json_t *document; - json_error_t error; - - document = json_loadf(stdin, 0, &error); - - if (!document) - die("%d:%d: %s\n", error.line, error.column, error.text); - if (!json_is_object(document)) - die("root value isn't an object\n"); - - write_dimensions(document); - write_image(document); - write_tiledefs(json_object_get(document, "tiles")); - write_animations(json_object_get(document, "tiles")); - - json_decref(document); -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/tools/tileset/mlk-tileset.c Sun Oct 09 13:51:03 2022 +0200 @@ -0,0 +1,204 @@ +/* + * main.c -- convert tiled tilesets JSON files into custom files + * + * Copyright (c) 2020-2022 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include <jansson.h> + +static void +die(const char *fmt, ...) +{ + assert(fmt); + + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + exit(1); +} + +static void +write_dimensions(const json_t *document) +{ + const json_t *tilewidth = json_object_get(document, "tilewidth"); + const json_t *tileheight = json_object_get(document, "tileheight"); + + if (!json_is_integer(tilewidth)) + die("invalid 'tilewidth' property\n"); + if (!json_is_integer(tileheight)) + die("invalid 'tileheight' property\n"); + + printf("tilewidth|%u\n", (unsigned int)json_integer_value(tilewidth)); + printf("tileheight|%u\n", (unsigned int)json_integer_value(tileheight)); +} + +static void +write_image(const json_t *document) +{ + const json_t *image = json_object_get(document, "image"); + + if (!json_is_string(image)) + die("invalid 'image' property\n"); + + printf("image|%s\n", json_string_value(image)); +} + +static const json_t * +find_property_value(const json_t *array, const char *prop) +{ + const json_t *obj; + size_t i; + + json_array_foreach(array, i, obj) { + const json_t *name = json_object_get(obj, "name"); + + if (!name || !json_is_string(name)) + die("invalid property object\n"); + + if (strcmp(json_string_value(name), prop) == 0) + return json_object_get(obj, "value"); + } + + return NULL; +} + +static void +write_animation(const json_t *tile) +{ + const json_t *id = json_object_get(tile, "id"); + const json_t *properties = json_object_get(tile, "properties"); + const json_t *file = find_property_value(properties, "animation-file"); + const json_t *delay = find_property_value(properties, "animation-delay"); + + /* Animations are completely optional. */ + if (!json_is_array(properties)) + return; + + if (!json_is_integer(id)) + die("invalid 'id' property in tile\n"); + + if (json_is_string(file)) { + printf("%d|%s|", (int)json_integer_value(id), json_string_value(file)); + + if (json_is_integer(delay)) + printf("%d\n", (int)json_integer_value(delay)); + else + printf("10\n"); + } +} + +static void +write_tiledef(const json_t *tile) +{ + const json_t *id = json_object_get(tile, "id"); + const json_t *objectgroup = json_object_get(tile, "objectgroup"); + const json_t *objects = json_object_get(objectgroup, "objects"); + const json_t *first = json_array_get(objects, 0); + const json_t *x, *y, *w, *h; + + /* Collisions are optional. */ + if (!json_is_object(objectgroup)) + return; + + if (!json_is_integer(id)) + die("invalid 'id' property in tile\n"); + if (!json_is_array(objects)) + die("invalid 'objects' property in tile\n"); + + x = json_object_get(first, "x"); + y = json_object_get(first, "y"); + w = json_object_get(first, "width"); + h = json_object_get(first, "height"); + + if (!json_is_integer(x) || !json_is_integer(y) || + !json_is_integer(w) || !json_is_integer(h)) + die("invalid collide object in tile description\n"); + + printf("%d|%d|%d|%d|%d\n", + (int)json_integer_value(id), + (int)json_integer_value(x), + (int)json_integer_value(y), + (int)json_integer_value(w), + (int)json_integer_value(h)); +} + +static void +write_tiledefs(const json_t *tiles) +{ + size_t index; + json_t *object; + + if (!json_is_array(tiles)) + return; + + puts("tiledefs"); + + json_array_foreach(tiles, index, object) { + if (!json_is_object(object)) + die("tile is not an object\n"); + + write_tiledef(object); + } +} + +static void +write_animations(const json_t *tiles) +{ + size_t index; + json_t *object; + + if (!json_is_array(tiles)) + return; + + puts("animations"); + + json_array_foreach(tiles, index, object) { + if (!json_is_object(object)) + die("tile is not an object\n"); + + write_animation(object); + } +} + +int +main(int argc, char *argv[]) +{ + (void)argc; + (void)argv; + + json_t *document; + json_error_t error; + + document = json_loadf(stdin, 0, &error); + + if (!document) + die("%d:%d: %s\n", error.line, error.column, error.text); + if (!json_is_object(document)) + die("root value isn't an object\n"); + + write_dimensions(document); + write_image(document); + write_tiledefs(json_object_get(document, "tiles")); + write_animations(json_object_get(document, "tiles")); + + json_decref(document); +}