changeset 89:30baadb6f6a2

core: add a panic_state in the adventure, continue #2484 @2h
author David Demelier <markand@malikania.fr>
date Thu, 12 Mar 2020 20:22:02 +0100
parents 44de3c528b63
children a6d6497adb60
files INSTALL.md Makefile assets/fonts/Lato-Regular.ttf src/adventure/main.c src/adventure/panic_state.c src/adventure/panic_state.h
diffstat 6 files changed, 224 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/INSTALL.md	Thu Mar 12 12:44:00 2020 +0100
+++ b/INSTALL.md	Thu Mar 12 20:22:02 2020 +0100
@@ -7,7 +7,8 @@
 ------------
 
 - C11 compliant compiler,
-- POSIX system (make, ar, shell, some POSIX functions),
+- POSIX system (make, ar, shell),
+- [pkg-config][], Helper for libraries.
 - [Jansson][], JSON parsing library,
 - [SDL2][], Multimedia library,
 - [SDL2_image][], Image loading addon for SDL2,
@@ -37,14 +38,17 @@
 appropriate MinGW shell prior to the chapter above.
 
 - *make*
+- *mingw-w64-x86_64-pkg-config*
 - *mingw-w64-x86_64-gcc*
-- *mingw-w64-x86_64-expat* (only for molko-map tool)
 - *mingw-w64-x86_64-SDL2*
 - *mingw-w64-x86_64-SDL2_image*
 - *mingw-w64-x86_64-SDL2_mixer*
 - *mingw-w64-x86_64-SDL2_ttf*
+- *mingw-w64-x86_64-jansson* (only for molko-map tool)
 
-Note: replace `x86_64` with `i686` if you have a deprecated system.
+Note: replace `x86_64` with `i686` if you have a deprecated system or if you
+      have issues while debugging (MinGW-w64 and/or gdb have known issues in
+      this area).
 
 [Jansson][]: http://www.digip.org/jansson
 [SDL2]: http://libsdl.org
@@ -52,3 +56,4 @@
 [SDL2_ttf]: https://www.libsdl.org/projects/SDL_ttf
 [SDL2_mixer]: https://www.libsdl.org/projects/SDL_mixer
 [MSYS2]: http://www.msys2.org
+[pkg-config]: http://pkgconf.org
--- a/Makefile	Thu Mar 12 12:44:00 2020 +0100
+++ b/Makefile	Thu Mar 12 20:22:02 2020 +0100
@@ -19,9 +19,9 @@
 .POSIX:
 
 CC=             cc
-CFLAGS=         -MMD -O0 -std=c11 -Wall -Wextra -g -Wall -Wextra
+CFLAGS=         -O0 -std=c11 -Wall -Wextra -g -ggdb
 # Use this instead to build a release.
-# CFLAGS=         -MMD -O3 -DNDEBUG -std=c11 -Wall -Wextra
+# CFLAGS=         -O3 -DNDEBUG -std=c11 -Wall -Wextra
 PROG=           molko
 LIB=            libmolko.a
 
@@ -61,6 +61,7 @@
 CORE_DEPS=      ${CORE_SRCS:.c=.d}
 
 ADV_SRCS=       src/adventure/main.c \
+                src/adventure/panic_state.c \
                 src/adventure/splashscreen_state.c \
                 src/adventure/mainmenu_state.c
 ADV_OBJS=       ${ADV_SRCS:.c=.o}
Binary file assets/fonts/Lato-Regular.ttf has changed
--- a/src/adventure/main.c	Thu Mar 12 12:44:00 2020 +0100
+++ b/src/adventure/main.c	Thu Mar 12 20:22:02 2020 +0100
@@ -16,14 +16,16 @@
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
+#include <setjmp.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <stdnoreturn.h>
 #include <string.h>
 
 #include "clock.h"
+#include "debug.h"
 #include "error.h"
 #include "event.h"
-#include "debug.h"
 #include "font.h"
 #include "game.h"
 #include "image.h"
@@ -32,17 +34,27 @@
 #include "map_state.h"
 #include "message.h"
 #include "painter.h"
+#include "panic.h"
+#include "panic_state.h"
+#include "script.h"
 #include "splashscreen_state.h"
 #include "sprite.h"
 #include "sys.h"
 #include "util.h"
 #include "wait.h"
 #include "window.h"
-#include "script.h"
 
 #define WINDOW_WIDTH 1280
 #define WINDOW_HEIGHT 720
 
+static jmp_buf panic_buf;
+
+static noreturn void
+unrecoverable(void)
+{
+	longjmp(panic_buf, 1);
+}
+
 static void
 init(void)
 {
@@ -51,6 +63,10 @@
 	if (!window_init("Molko's Adventure", WINDOW_WIDTH, WINDOW_HEIGHT))
 		error_fatal();
 
+	/* Init unrecoverable panic state. */
+	panic_state_init();
+	panic_handler = unrecoverable;
+
 	/* Default state is splash screen */
 	game_switch(&splashscreen_state, true);
 }
@@ -83,6 +99,8 @@
 			/* TODO: this must be handled by states. */
 			if (ev.type == EVENT_QUIT)
 				return;
+			if (ev.type == EVENT_KEYDOWN)
+				panic("test");
 
 			game_handle(&ev);
 		}
@@ -112,7 +130,19 @@
 	(void)argv;
 
 	init();
-	run();
+
+	if (setjmp(panic_buf) == 0)
+		/* Initial game run. */
+		run();
+	else {
+		/* Clear event queue to avoid accidental key presses. */
+		for (union event ev; event_poll(&ev); )
+			continue;
+
+		game_switch(&panic_state, true);
+		run();
+	}
+
 	close();
 
 	return 0;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/adventure/panic_state.c	Thu Mar 12 20:22:02 2020 +0100
@@ -0,0 +1,135 @@
+/*
+ * panic_state.c -- panic state
+ *
+ * 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 <error.h>
+#include <font.h>
+#include <painter.h>
+#include <sys.h>
+#include <texture.h>
+#include <util.h>
+#include <window.h>
+
+#include "panic_state.h"
+
+#define BACKGROUND 0x4f5070ff
+#define FOREGROUND 0xffffffff
+
+#define FONT "fonts/Lato-Regular.ttf"
+#define FONT_SZ 16
+
+struct label {
+	const char *text;
+	struct texture *texture;
+};
+
+static struct {
+	struct font *font;
+} data;
+
+static struct label headers[] = {
+	{ "An unrecoverable error occured and the game cannot continue.", NULL },
+	{ "Please report the detailed error as provided below.", NULL },
+};
+
+static struct label bottom[] = {
+	{ "Press <s> to save information and generate a core dump.", NULL },
+	{ "Press <q> to quit without saving information.", NULL }
+};
+
+static void
+enter(void)
+{
+}
+
+static void
+handle(const union event *ev)
+{
+	(void)ev;
+}
+
+static void
+generate(struct label labels[], size_t labelsz)
+{
+	for (size_t i = 0; i < labelsz; ++i) {
+		if (!labels[i].texture) {
+			labels[i].texture = font_render(data.font, labels[i].text, FOREGROUND);
+
+			if (!labels[i].texture)
+				error_fatal();
+		}
+	}
+}
+
+static void
+update(unsigned int ticks)
+{
+	(void)ticks;
+
+	generate(headers, NELEM(headers));
+	generate(bottom, NELEM(bottom));
+}
+
+static void
+draw(void)
+{
+	int y = 10;
+
+	painter_set_target(NULL);
+	painter_set_color(BACKGROUND);
+	painter_clear();
+
+	/* Header. */
+	for (size_t i = 0; i < NELEM(headers); ++i) {
+		texture_draw(headers[i].texture, 10, y);
+		y += texture_height(headers[i].texture) + 2;
+	}
+
+	/* Bottom. */
+	y = window_height() - 10;
+	y -= texture_height(bottom[0].texture);
+
+	for (size_t i = 0; i < NELEM(bottom); ++i) {
+		texture_draw(bottom[i].texture, 10, y);
+		y -= texture_height(bottom[i].texture) + 2;
+	}
+}
+
+static void
+leave(void)
+{
+}
+
+struct state panic_state = {
+	.enter = enter,
+	.handle = handle,
+	.update = update,
+	.draw = draw,
+	.leave = leave
+};
+
+void
+panic_state_init(void)
+{
+	/*
+	 * If the panic state can not be loaded we're unable to show any
+	 * useful information to the screen so as last resort print them
+	 * on the console.
+	 */
+	if (!(data.font = font_openf(sys_datapath(FONT), FONT_SZ)))
+		error_fatal();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/adventure/panic_state.h	Thu Mar 12 20:22:02 2020 +0100
@@ -0,0 +1,45 @@
+/*
+ * panic_state.h -- panic state
+ *
+ * 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_PANIC_STATE_H
+#define MOLKO_PANIC_STATE_H
+
+/**
+ * \file panic_state.h
+ * \brief Panic state.
+ */
+
+#include "state.h"
+
+/**
+ * \brief Global panic state structure.
+ */
+extern struct state panic_state;
+
+/**
+ * Call this function as early as possible to be able to use this state even on
+ * memory allocation errors.
+ *
+ * \note You must still initialize the system before.
+ * \see \ref sys_init
+ * \see \ref window_init
+ */
+void
+panic_state_init(void);
+
+#endif /* !MOLKO_PANIC_STATE_H */