Mercurial > molko
annotate libadventure/adventure/state/panic.c @ 162:629f55f3961e
core: rework states
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 18 Oct 2020 12:01:59 +0200 |
parents | libadventure/adventure/panic_state.c@c577c15df07f |
children | 6992085d47fd |
rev | line source |
---|---|
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
1 /* |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
2 * panic_state.c -- panic state |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
3 * |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr> |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
5 * |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
6 * Permission to use, copy, modify, and/or distribute this software for any |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
7 * purpose with or without fee is hereby granted, provided that the above |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
8 * copyright notice and this permission notice appear in all copies. |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
9 * |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
17 */ |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
18 |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
19 #include <assert.h> |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
20 #include <stdio.h> |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
21 #include <stdlib.h> |
162 | 22 #include <stdnoreturn.h> |
23 #include <string.h> | |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
24 |
121
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
25 #include <core/error.h> |
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
26 #include <core/event.h> |
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
27 #include <core/font.h> |
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
28 #include <core/game.h> |
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
29 #include <core/painter.h> |
162 | 30 #include <core/panic.h> |
31 #include <core/state.h> | |
121
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
32 #include <core/sys.h> |
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
33 #include <core/texture.h> |
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
34 #include <core/util.h> |
789b23e01f52
misc: reorganize hierarchy, closes #2490
David Demelier <markand@malikania.fr>
parents:
117
diff
changeset
|
35 #include <core/window.h> |
148
c577c15df07f
misc: split libraries, closes #2496
David Demelier <markand@malikania.fr>
parents:
135
diff
changeset
|
36 |
162 | 37 #include <ui/align.h> |
38 #include <ui/theme.h> | |
39 | |
148
c577c15df07f
misc: split libraries, closes #2496
David Demelier <markand@malikania.fr>
parents:
135
diff
changeset
|
40 #include <rpg/map_state.h> |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
41 |
162 | 42 #include "panic.h" |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
43 |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
44 #define BACKGROUND 0x4f5070ff |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
45 #define FOREGROUND 0xffffffff |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
46 |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
47 #define OUT "molko-adventure.txt" |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
48 |
162 | 49 struct view { |
50 struct { | |
51 struct texture tex; | |
52 int x; | |
53 int y; | |
54 } texts[4]; | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
55 }; |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
56 |
162 | 57 static noreturn void |
95
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
58 die(const char *fmt, ...) |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
59 { |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
60 assert(fmt); |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
61 |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
62 va_list ap; |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
63 |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
64 va_start(ap, fmt); |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
65 fprintf(stderr, "abort: "); |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
66 vfprintf(stderr, fmt, ap); |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
67 va_end(ap); |
162 | 68 abort(); |
95
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
69 exit(1); |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
70 } |
e82eca4f8606
core: simplify error/panic routines
David Demelier <markand@malikania.fr>
parents:
94
diff
changeset
|
71 |
162 | 72 static noreturn void |
73 stop(void) | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
74 { |
162 | 75 die("%s", error()); |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
76 } |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
77 |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
78 static void |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
79 dump(void) |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
80 { |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
81 FILE *fp; |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
82 |
162 | 83 if ((fp = fopen(OUT, "w"))) { |
84 /* TODO: add more info here. */ | |
85 fprintf(fp, "Molko's Adventure crash dump report\n"); | |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
86 fclose(fp); |
162 | 87 } |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
88 |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
89 abort(); |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
90 } |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
91 |
162 | 92 static struct view * |
93 init(void) | |
94 { | |
95 struct theme *theme; | |
96 struct view *view; | |
97 struct font font; | |
98 | |
99 theme = theme_default(); | |
100 view = ecalloc(1, sizeof (*view)); | |
101 | |
102 /* Generate the texts. */ | |
103 font_shallow(&font, theme->fonts[THEME_FONT_INTERFACE]); | |
104 font.style = FONT_STYLE_ANTIALIASED, | |
105 font.color = FOREGROUND; | |
106 | |
107 if (!font_render(&font, &view->texts[0].tex, "An unrecoverable error occured and the game cannot continue.") || | |
108 !font_render(&font, &view->texts[1].tex, "Please report the detailed error as provided below.") || | |
109 !font_render(&font, &view->texts[2].tex, "Press <s> to save information and generate a core dump.") || | |
110 !font_render(&font, &view->texts[3].tex, "Press <q> to quit without saving information.")) | |
111 die("%s", error()); | |
112 | |
113 /* All align x the same. */ | |
114 for (size_t i = 0; i < NELEM(view->texts); ++i) | |
115 view->texts[i].x = theme->padding; | |
116 | |
117 /* Header (0-1). */ | |
118 view->texts[0].y = theme->padding; | |
119 view->texts[1].y = view->texts[0].y + view->texts[0].tex.h + theme->padding; | |
120 | |
121 /* Footer. (2-3). */ | |
122 view->texts[3].y = window.h - view->texts[2].tex.h - theme->padding; | |
123 view->texts[2].y = view->texts[3].y - view->texts[3].tex.h - theme->padding; | |
124 | |
125 return view; | |
126 } | |
127 | |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
128 static void |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
129 handle_keydown(const struct event_key *ev) |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
130 { |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
131 assert(ev); |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
132 |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
133 switch (ev->key) { |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
134 case KEY_q: |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
135 game_quit(); |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
136 break; |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
137 case KEY_s: |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
138 dump(); |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
139 break; |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
140 default: |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
141 break; |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
142 } |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
143 } |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
144 |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
145 static void |
162 | 146 start(struct state *state) |
147 { | |
148 (void)state; | |
149 | |
150 /* We remove the panic handler to avoid infinite recursion. */ | |
151 panic_handler = stop; | |
152 } | |
153 | |
154 static void | |
155 handle(struct state *state, const union event *ev) | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
156 { |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
157 assert(ev); |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
158 |
162 | 159 (void)state; |
160 | |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
161 switch (ev->type) { |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
162 case EVENT_KEYDOWN: |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
163 handle_keydown(&ev->key); |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
164 break; |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
165 default: |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
166 break; |
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
167 } |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
168 } |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
169 |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
170 static void |
162 | 171 draw(struct state *state) |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
172 { |
162 | 173 struct theme *theme = theme_default(); |
174 struct view *view = state->data; | |
175 struct texture tex; | |
176 struct font font; | |
177 int x, y; | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
178 |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
179 painter_set_color(BACKGROUND); |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
180 painter_clear(); |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
181 |
162 | 182 for (size_t i = 0; i < NELEM(view->texts); ++i) |
183 texture_draw(&view->texts[i].tex, view->texts[i].x, view->texts[i].y); | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
184 |
162 | 185 /* The error is only available here. */ |
186 font_shallow(&font, theme->fonts[THEME_FONT_INTERFACE]); | |
187 font.color = FOREGROUND; | |
188 font.style = FONT_STYLE_ANTIALIASED; | |
91
8bfb90e85b28
adventure: add more details in panic
David Demelier <markand@malikania.fr>
parents:
89
diff
changeset
|
189 |
162 | 190 if (!font_render(&font, &tex, error())) |
191 die("%s\n", error()); | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
192 |
162 | 193 align(ALIGN_LEFT, &x, &y, tex.w, tex.h, 0, 0, window.w, window.h); |
194 | |
195 texture_draw(&tex, x + theme->padding, y); | |
196 texture_finish(&tex); | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
197 } |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
198 |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
199 static void |
162 | 200 finish(struct state *state) |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
201 { |
162 | 202 struct view *view = state->data; |
203 | |
204 if (!view) | |
205 return; | |
206 | |
207 for (size_t i = 0; i < NELEM(view->texts); ++i) | |
208 texture_finish(&view->texts[i].tex); | |
209 | |
210 free(view); | |
211 memset(state, 0, sizeof (*state)); | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
212 } |
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
213 |
162 | 214 void |
215 panic_state(struct state *state) | |
216 { | |
217 assert(state); | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
218 |
162 | 219 memset(state, 0, sizeof (*state)); |
220 state->data = init(); | |
221 state->start = start; | |
222 state->handle = handle; | |
223 state->draw = draw; | |
224 state->finish = finish; | |
89
30baadb6f6a2
core: add a panic_state in the adventure, continue #2484 @2h
David Demelier <markand@malikania.fr>
parents:
diff
changeset
|
225 } |