Mercurial > molko
changeset 79:8f95462ac5f8
core: create a debugging API, closes #2469 @2h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 02 Feb 2020 15:48:36 +0100 |
parents | 1bd1233b4cbc |
children | 05ffbcdee585 |
files | Makefile src/adventure/main.c src/adventure/splashscreen_state.c src/core/debug.c src/core/debug.h src/core/font.c src/core/font.h src/core/map_state.c |
diffstat | 8 files changed, 274 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Fri Jan 31 13:57:57 2020 +0100 +++ b/Makefile Sun Feb 02 15:48:36 2020 +0100 @@ -19,7 +19,7 @@ .POSIX: CC= gcc -CFLAGS= -MMD -O0 -std=c18 -Wall -Wextra -g +CFLAGS= -MMD -O0 -std=c18 -Wall -Wextra -g -Wall -Wextra # Use this instead to build a release. # CFLAGS= -MMD -O3 -DNDEBUG -std=c18 -Wall -Wextra PROG= molko @@ -27,6 +27,7 @@ CORE_SRCS= src/core/animation.c \ src/core/clock.c \ + src/core/debug.c \ src/core/error.c \ src/core/event.c \ src/core/font.c \
--- a/src/adventure/main.c Fri Jan 31 13:57:57 2020 +0100 +++ b/src/adventure/main.c Sun Feb 02 15:48:36 2020 +0100 @@ -23,6 +23,7 @@ #include "clock.h" #include "error.h" #include "event.h" +#include "debug.h" #include "font.h" #include "game.h" #include "image.h" @@ -74,6 +75,8 @@ if (!(font = font_openf(sys_datapath("fonts/DejaVuSans.ttf"), 15))) error_fatal(); + if (!(debug_options.default_font = font_openf(sys_datapath("fonts/DejaVuSans.ttf"), 10))) + error_fatal(); if (!(frame = image_openf(sys_datapath("images/message.png")))) error_fatal(); @@ -91,6 +94,8 @@ .flags = MESSAGE_QUESTION }; + debug_options.enable = true; + clock_start(&clock); script_init(&sc);
--- a/src/adventure/splashscreen_state.c Fri Jan 31 13:57:57 2020 +0100 +++ b/src/adventure/splashscreen_state.c Sun Feb 02 15:48:36 2020 +0100 @@ -91,7 +91,6 @@ painter_set_color(0xffffffff); painter_clear(); texture_draw(text, x, y); - painter_present(); } struct state splashscreen_state = {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/debug.c Sun Feb 02 15:48:36 2020 +0100 @@ -0,0 +1,71 @@ +/* + * debug.c -- debugging interfaces + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#include <assert.h> +#include <stdio.h> + +#include "debug.h" +#include "font.h" +#include "texture.h" + +#define PADDING_X 5 +#define PADDING_Y 5 + +struct debug_options debug_options = { + .default_color = 0x0000ffff, + .default_style = FONT_STYLE_ANTIALIASED +}; + +void +debug_printf(struct debug_report *report, const char *fmt, ...) +{ + assert(report); + assert(fmt); + + va_list ap; + + va_start(ap, fmt); + debug_vprintf(report, fmt, ap); + va_end(ap); +} + +void +debug_vprintf(struct debug_report *report, const char *fmt, va_list ap) +{ + assert(report); + assert(fmt); + + char line[DEBUG_LINE_MAX]; + struct texture *tex; + struct font *font; + unsigned int gapy; + + vsnprintf(line, sizeof (line), fmt, ap); + font = report->font ? report->font : debug_options.default_font; + tex = font_render_ex(font, line, report->color, report->style); + + if (!tex) + return; + + gapy = (PADDING_Y * (report->count)) + + (font_height(font) * (report->count)); + report->count++; + + texture_draw(tex, PADDING_X, gapy); + texture_close(tex); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/core/debug.h Sun Feb 02 15:48:36 2020 +0100 @@ -0,0 +1,133 @@ +/* + * debug.h -- debugging interfaces + * + * Copyright (c) 2020 David Demelier <markand@malikania.fr> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef MOLKO_DEBUG_H +#define MOLKO_DEBUG_H + +/** + * \file debug.h + * \brief Debugging interfaces. + * + * This module provides functions to draw debugging information within the game + * window. It is mostly used for information only when state of the game is + * better inspected via direct window information rather than writing in the + * console. + * + * Predefined core states may print debugging information if + * debug_options.enabled variable is set to true. However, you need to specify + * the font to use in order to work. + * + * Each call to \ref debug_printf or \ref debug_vprintf automatically adjust + * next coordinate for rendering the text. As such, user may simply print + * several lines of text without having to deal with that manually. + * + * Example, activate global debugging. + * + * \code + * struct font *f = font_openf("foo.ttf", 10); + * + * if (!f) + * error_fatal(); + * + * debug_options.default_font = f; + * debug_options.enabled = true; + * \endcode + * + * Example, print debugging information manually. + * + * \code + * struct debug_report report = { + * .color = 0x00ff00ff, + * .font = myfont // Optional if debug_options.default_font is set. + * }; + * + * debug_printf("current position: %d, %d\n", x, y); + * \endcode + */ + +#include <stdbool.h> +#include <stdarg.h> + +#include "font.h" + +/** + * Maximum content length per report. + */ +#define DEBUG_LINE_MAX 1024 + +/** + * \brief Debugging options. + * + * Fill this structure with appropriate values to change debugging behavior + * in core API. + */ +struct debug_options { + struct font *default_font; /*!< (RW) Default font for reports. */ + enum font_style default_style; /*!< (RW) Default font style. */ + unsigned long default_color; /*!< (RW) Default font color. */ + bool enable; /*!< (RW) Enable core API debugging. */ +}; + +/** + * \brief Debug context. + * + * Use this structure each time you need to print one or more messages. + */ +struct debug_report { + struct font *font; /*!< (RW) Font to use. */ + enum font_style style; /*!< (RW) Font style to use. */ + unsigned long color; /*!< (RW) Font foreground color to use. */ + unsigned int count; /*!< (PV) Number of messages already printed. */ +}; + +/** + * Global debugging options. + */ +extern struct debug_options debug_options; + +/** + * Convenient macro to initialize \ref debug_report with default values. + */ +#define DEBUG_INIT_DEFAULTS { \ + .font = debug_options.default_font, \ + .color = debug_options.default_color, \ + .style = debug_options.default_style \ +} + +/** + * Print debugging information into the screen. + * + * \pre report != NULL + * \pre fmt != NULL + * \param report the reporting context + * \param fmt the printf(3) format string + * \note The message length must not exceed DEBUG_LINE_MAX, otherwise its + * result is truncated. + */ +void +debug_printf(struct debug_report *report, const char *fmt, ...); + +/** + * Similar to \ref debug_printf but with a va_list object. + * + * \see \ref debug_printf + */ +void +debug_vprintf(struct debug_report *report, const char *fmt, va_list ap); + +#endif /* !MOLKO_DEBUG_H */
--- a/src/core/font.c Fri Jan 31 13:57:57 2020 +0100 +++ b/src/core/font.c Sun Feb 02 15:48:36 2020 +0100 @@ -74,6 +74,15 @@ struct texture * font_render(struct font *font, const char *text, unsigned long color) { + return font_render_ex(font, text, color, FONT_STYLE_ANTIALIASED); +} + +struct texture * +font_render_ex(struct font *font, + const char *text, + unsigned long color, + enum font_style style) +{ assert(font); assert(text); @@ -83,10 +92,19 @@ .b = COLOR_B(color), .a = COLOR_A(color) }; + SDL_Surface *surface; + SDL_Surface *(*func)(TTF_Font *, const char *, SDL_Color); - SDL_Surface *surface; + switch (style) { + case FONT_STYLE_ANTIALIASED: + func = TTF_RenderUTF8_Blended; + break; + default: + func = TTF_RenderUTF8_Solid; + break; + } - if (!(surface = TTF_RenderUTF8_Blended(font->handle, text, fg))) { + if (!(surface = func(font->handle, text, fg))) { error_sdl(); return NULL; } @@ -94,6 +112,12 @@ return texture_from_surface(surface); } +unsigned int +font_height(const struct font *font) +{ + return TTF_FontHeight(font->handle); +} + void font_close(struct font *font) {
--- a/src/core/font.h Fri Jan 31 13:57:57 2020 +0100 +++ b/src/core/font.h Sun Feb 02 15:48:36 2020 +0100 @@ -37,6 +37,14 @@ struct texture; /** + * \brief Font style for rendering. + */ +enum font_style { + FONT_STYLE_NONE, /*!< No antialiasing. */ + FONT_STYLE_ANTIALIASED /*!< Pretty antialiasing looking. */ +}; + +/** * Open font from path file. * * \pre path != NULL @@ -61,6 +69,12 @@ font_openb(const void *buffer, size_t buflen, unsigned int size); /** + * Similar to \ref font_render_ex with predefined convenient values. + */ +struct texture * +font_render(struct font *font, const char *text, unsigned long color); + +/** * Render a text. * * \pre font != NULL @@ -68,9 +82,23 @@ * \param font the font handle * \param text the text in UTF-8 * \param color the color + * \param style the font style */ struct texture * -font_render(struct font *font, const char *text, unsigned long color); +font_render_ex(struct font *font, + const char *text, + unsigned long color, + enum font_style style); + +/** + * Get the maximum height for all glyphs. + * + * \pre font != NULL + * \param font the font handle + * \return the height in pixels + */ +unsigned int +font_height(const struct font *font); /** * Close the font.
--- a/src/core/map_state.c Fri Jan 31 13:57:57 2020 +0100 +++ b/src/core/map_state.c Sun Feb 02 15:48:36 2020 +0100 @@ -18,6 +18,7 @@ #include <stdio.h> +#include "debug.h" #include "event.h" #include "game.h" #include "map.h" @@ -319,12 +320,19 @@ static void draw(void) { + struct debug_report report = DEBUG_INIT_DEFAULTS; + map_draw(&map_state_data.map.map, map_state_data.view.x, map_state_data.view.y); walksprite_draw( &cache.player.ws, map_state_data.player.angle, map_state_data.player.x - map_state_data.view.x, map_state_data.player.y - map_state_data.view.y); + + debug_printf(&report, "position: %d, %d", map_state_data.player.x, + map_state_data.player.y); + debug_printf(&report, "view: %d, %d", map_state_data.view.x, + map_state_data.view.y); } struct map_state_data map_state_data;