comparison libmlk-rpg/rpg/message.h @ 243:71b3b7036de7

misc: lot of cleanups, - prefix libraries with libmlk, - move assets from source directories closes #2520, - prefix header guards closes #2519
author David Demelier <markand@malikania.fr>
date Sat, 28 Nov 2020 22:37:30 +0100
parents librpg/rpg/message.h@64f24b482722
children 08ab73b32832
comparison
equal deleted inserted replaced
242:4c24604efcab 243:71b3b7036de7
1 /*
2 * message.h -- message dialog
3 *
4 * Copyright (c) 2020 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #ifndef MOLKO_RPG_MESSAGE_H
20 #define MOLKO_RPG_MESSAGE_H
21
22 /**
23 * \file message.h
24 * \brief Message dialog.
25 * \ingroup actions
26 * \ingroup drawing
27 *
28 * This module's purpose is to show a dialog box into the screen to show text
29 * and optionally ask the user a question. It is similar to what you're used to
30 * see in many RPGs.
31 *
32 * To use it use the following procedure:
33 *
34 * 1. Create a struct message object and set required properties,
35 * 2. Call \ref message_start to reset the state,
36 * 3. Call \ref message_handle and \ref message_update with appropriate values,
37 * 4. Call \ref message_draw to render the dialog.
38 *
39 * Depending on message flags or user input, step 3 may return true in this
40 * case you should stop using the message as it has completed rendering.
41 *
42 * \note All properties must exist until the object is no longer used.
43 *
44 * \code
45 * struct message msg = {
46 * // You can show up to 6 lines.
47 * .text = {
48 * "Hello, what's up?"
49 * },
50 * // This indicates this message is a question.
51 * .flags = MESSAGE_FLAGS_QUESTION
52 * };
53 * \endcode
54 *
55 * For performance reasons, flexibility and simplicity, the message box does
56 * not try to be clever about positions of lines. It will simply create an
57 * animation for opening the box, drawing the lines to the position according
58 * to the theme padding and spacing and interact with user. For convenience
59 * though, the \ref message_query can be used to determine dimensions required
60 * for a better final result.
61 *
62 * ## Example, computing the dimensions:
63 *
64 * \code
65 * // We create a message that we put on the center of the screen.
66 * struct message msg = {
67 * .text = {
68 * "Hi, have you tried turning it off and on again?"
69 * }
70 * };
71 *
72 * message_query(&msg, &msg.w, &msg.h);
73 * align(ALIGN_CENTER, &msg.x, &msg.y, msg.w, msg.h, 0, 0, window.w, window.h);
74 * \endcode
75 */
76
77 #include <stdbool.h>
78
79 #include <core/texture.h>
80
81 struct action;
82 struct font;
83 struct theme;
84
85 union event;
86
87 /**
88 * \brief Default animation speed in milliseconds.
89 */
90 #define MESSAGE_DELAY_DEFAULT (150)
91
92 /**
93 * \brief Default timeout in milliseconds for automatic messages.
94 */
95 #define MESSAGE_TIMEOUT_DEFAULT (5000)
96
97 /**
98 * \brief Maximum number of lines allowed in the message.
99 */
100 #define MESSAGE_LINES_MAX (3)
101
102 /**
103 * \brief Message flags.
104 */
105 enum message_flags {
106 MESSAGE_FLAGS_AUTOMATIC = (1 << 0), /*!< Will automatically change state by itself. */
107 MESSAGE_FLAGS_QUESTION = (1 << 1), /*!< The message is a question. */
108 MESSAGE_FLAGS_FADEIN = (1 << 2), /*!< Animate opening. */
109 MESSAGE_FLAGS_FADEOUT = (1 << 3) /*!< Animate closing. */
110 };
111
112 /**
113 * \brief Message state.
114 */
115 enum message_state {
116 MESSAGE_STATE_NONE, /*!< Message hasn't start yet or is finished */
117 MESSAGE_STATE_OPENING, /*!< Message animation is opening */
118 MESSAGE_STATE_SHOWING, /*!< Message is displaying */
119 MESSAGE_STATE_HIDING /*!< Message animation for hiding */
120 };
121
122 /**
123 * \brief Message object.
124 */
125 struct message {
126 int x; /*!< (+) Position in x. */
127 int y; /*!< (+) Position in y. */
128 unsigned int w; /*!< (+) Width. */
129 unsigned int h; /*!< (+) Height. */
130 unsigned int spacing; /*!< (+) Spacing between lines. */
131 unsigned int delay; /*!< (+) Delay for animations. */
132 unsigned int timeout; /*!< (+) Timeout in milliseconds. */
133 const char *text[MESSAGE_LINES_MAX]; /*!< (+) Lines of text to show. */
134 unsigned int index; /*!< (+) Line selected */
135 enum message_flags flags; /*!< (+) Message flags */
136 enum message_state state; /*!< (-) Current state */
137 const struct theme *theme; /*!< (+&?) Theme to use. */
138 unsigned int elapsed; /*!< (-) Time elapsed. */
139 double scale; /*!< (-) Current scale [0-1]. */
140 };
141
142 /**
143 * Start opening the message. This function will reset the message state and
144 * elapsed time.
145 *
146 * \pre msg != NULL
147 * \pre msg->delay > 0 if msg->flags contains MESSAGE_FLAGS_FADEIN or
148 * MESSAGE_FLAGS_FADEOUT
149 * \param msg the message
150 */
151 void
152 message_start(struct message *msg);
153
154 /**
155 * Compute the minimal message dimensions required.
156 *
157 * \pre msg != NULL
158 * \param msg the message to query
159 * \param w the pointer to width (may be NULL)
160 * \param h the pointer to height (may be NULL)
161 */
162 void
163 message_query(const struct message *msg, unsigned int *w, unsigned int *h);
164
165 /**
166 * Handle input events.
167 *
168 * This function will alter state of the message and change its selection in
169 * case of question.
170 *
171 * \pre msg != NULL
172 * \pre ev != NULL
173 * \param msg the message
174 * \param ev the event which occured
175 */
176 void
177 message_handle(struct message *msg, const union event *ev);
178
179 /**
180 * Update the message state and elapsed time..
181 *
182 * \pre msg != NULL
183 * \param msg the message
184 * \param ticks the elapsed delay since last frame
185 * \return true if it has finished
186 */
187 bool
188 message_update(struct message *msg, unsigned int ticks);
189
190 /**
191 * Draw the message into the screen.
192 *
193 * \pre msg != NULL
194 * \param msg the message
195 */
196 void
197 message_draw(const struct message *msg);
198
199 /**
200 * Start hiding the message.
201 *
202 * \pre msg != NULL
203 * \param msg the message
204 * \note You should still continue to draw the message as the animation is not
205 * finished!
206 */
207 void
208 message_hide(struct message *msg);
209
210 /**
211 * Convert message into an action.
212 *
213 * \pre msg != NULL
214 * \pre act != NULL
215 * \param msg the message to reference
216 * \param act the action to fill
217 * \post act->data contains msg
218 * \post act->handle invokes message_handle
219 * \post act->update invokes message_update
220 * \post act->draw invokes message_draw
221 */
222 void
223 message_action(struct message *msg, struct action *act);
224
225 #endif /* !MOLKO_RPG_MESSAGE_H */