comparison src/core/message.c @ 64:da9b7462ab92

core: implement question, closes #2464 @2h
author David Demelier <markand@malikania.fr>
date Thu, 23 Jan 2020 20:44:01 +0100
parents d07acc6ee4d9
children 80a913d25aa9
comparison
equal deleted inserted replaced
63:ec0872aaee07 64:da9b7462ab92
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */ 17 */
18 18
19 #include <assert.h> 19 #include <assert.h>
20 20
21 #include "event.h"
21 #include "font.h" 22 #include "font.h"
22 #include "message.h" 23 #include "message.h"
23 #include "painter.h" 24 #include "painter.h"
24 #include "sprite.h" 25 #include "sprite.h"
25 #include "texture.h" 26 #include "texture.h"
26 #include "window.h" 27 #include "window.h"
27 28
28 #define MESSAGE_SPEED 1000 /* Time delay for animations */ 29 #define MESSAGE_SPEED 150 /* Time delay for animations */
29 #define MESSAGE_TIMEOUT 5000 /* Time for auto-closing */ 30 #define MESSAGE_TIMEOUT 5000 /* Time for auto-closing */
30 31
31 static unsigned int 32 static unsigned int
32 average_height(const struct message *msg) 33 average(const struct message *msg)
33 { 34 {
34 unsigned int n = 0; 35 unsigned int n = 0;
35 unsigned int total = 0; 36 unsigned int total = 0;
36 37
37 for (int i = 0; i < 6; ++i) { 38 for (int i = 0; i < 6; ++i) {
38 if (msg->ttext[i]) { 39 if (msg->textures[i]) {
39 n += 1; 40 n += 1;
40 total += texture_height(msg->ttext[i]); 41 total += texture_height(msg->textures[i]);
41 } 42 }
42 } 43 }
43 44
44 return n > 0 ? total / n : 0; 45 return n > 0 ? total / n : 0;
46 }
47
48 static void
49 clear(struct message *msg)
50 {
51 for (unsigned int i = 0; i < 12; ++i) {
52 if (msg->textures[i]) {
53 texture_close(msg->textures[i]);
54 msg->textures[i] = NULL;
55 }
56 }
45 } 57 }
46 58
47 static void 59 static void
48 redraw(struct message *msg) 60 redraw(struct message *msg)
49 { 61 {
62 clear(msg);
63
50 /* Generate textures if not already done. */ 64 /* Generate textures if not already done. */
51 for (int i = 0; i < 6; ++i) { 65 for (unsigned int i = 0; i < 6; ++i) {
52 if (!msg->text[i] || msg->ttext[i] || msg->stext[i]) 66 if (!msg->text[i])
53 continue; 67 continue;
54 68
55 msg->stext[i] = font_render(msg->font, msg->text[i], 0x000000ff); 69 /* Normal lines of text. */
56 msg->ttext[i] = font_render(msg->font, msg->text[i], msg->color); 70 unsigned long color = msg->colors[0];
71
72 if (msg->flags & MESSAGE_QUESTION && msg->index == i)
73 color = msg->colors[1];
74
75 if (!msg->textures[i])
76 msg->textures[i] = font_render(
77 msg->font,
78 msg->text[i],
79 color
80 );
81 if (!msg->textures[i + 6])
82 msg->textures[i + 6] = font_render(
83 msg->font,
84 msg->text[i],
85 0x000000ff
86 );
57 } 87 }
58 } 88 }
59 89
60 void 90 void
61 message_start(struct message *msg) 91 message_start(struct message *msg)
62 { 92 {
63 assert(msg); 93 assert(msg);
64 94
65 msg->elapsed = 0; 95 msg->elapsed = 0;
66 msg->alpha = 0;
67 msg->state = MESSAGE_OPENING; 96 msg->state = MESSAGE_OPENING;
97 msg->height[0] = texture_height(msg->frame);
98 msg->height[1] = 0;
99
100 redraw(msg);
101 }
102
103 void
104 message_handle(struct message *msg, const union event *ev)
105 {
106 assert(msg);
107 assert(ev);
108
109 if (ev->type != EVENT_KEYDOWN || msg->state == MESSAGE_NONE)
110 return;
111
112 switch (ev->key.key) {
113 case KEY_UP:
114 if (msg->index > 0)
115 msg->index--;
116 break;
117 case KEY_DOWN:
118 if (msg->index < 5 && msg->text[msg->index + 1])
119 msg->index++;
120 break;
121 case KEY_ENTER:
122 msg->state = MESSAGE_HIDING;
123 msg->elapsed = 0;
124 break;
125 default:
126 break;
127 }
128
129 redraw(msg);
68 } 130 }
69 131
70 bool 132 bool
71 message_update(struct message *msg, unsigned int ticks) 133 message_update(struct message *msg, unsigned int ticks)
72 { 134 {
74 136
75 msg->elapsed += ticks; 137 msg->elapsed += ticks;
76 138
77 switch (msg->state) { 139 switch (msg->state) {
78 case MESSAGE_OPENING: 140 case MESSAGE_OPENING:
79 msg->alpha += 255 * ticks / MESSAGE_SPEED; 141 msg->height[1] += texture_height(msg->frame) * ticks / MESSAGE_SPEED;
80 142
81 if (msg->alpha > 255) 143 if (msg->height[1] > msg->height[0])
82 msg->alpha = 255; 144 msg->height[1] = msg->height[0];
83 if (msg->elapsed >= MESSAGE_SPEED) { 145 if (msg->elapsed >= MESSAGE_SPEED) {
84 msg->state = MESSAGE_SHOWING; 146 msg->state = MESSAGE_SHOWING;
85 msg->elapsed = 0; 147 msg->elapsed = 0;
86 } 148 }
87 149
93 msg->elapsed = 0; 155 msg->elapsed = 0;
94 } 156 }
95 157
96 break; 158 break;
97 case MESSAGE_HIDING: 159 case MESSAGE_HIDING:
160 msg->height[1] -= texture_height(msg->frame) * ticks / MESSAGE_SPEED;
161
98 if (msg->elapsed >= MESSAGE_SPEED) { 162 if (msg->elapsed >= MESSAGE_SPEED) {
99 msg->state = MESSAGE_NONE; 163 msg->state = MESSAGE_NONE;
100 msg->elapsed = 0; 164 msg->elapsed = 0;
101 } 165 }
102 166
116 180
117 const unsigned int w = texture_width(msg->frame); 181 const unsigned int w = texture_width(msg->frame);
118 const unsigned int h = texture_height(msg->frame); 182 const unsigned int h = texture_height(msg->frame);
119 const unsigned int x = (window_width() / 2) - (w / 2); 183 const unsigned int x = (window_width() / 2) - (w / 2);
120 const unsigned int y = 80; 184 const unsigned int y = 80;
121 const unsigned int avgh = average_height(msg); 185 const unsigned int avgh = average(msg);
122 const unsigned int gapy = (h - (avgh * 6)) / 7; 186 const unsigned int gapy = (h - (avgh * 6)) / 7;
123 187
124 /* TODO: handle state */ 188 switch (msg->state) {
125 redraw(msg); 189 case MESSAGE_OPENING:
126 texture_draw(msg->frame, x, y); 190 case MESSAGE_HIDING:
127 191 texture_draw_ex(msg->frame, 0, 0, w, msg->height[1], x, y, w, msg->height[1], 0);
128 for (int i = 0; i < 6; ++i) { 192 break;
129 /* TODO: avatar handling */ 193 case MESSAGE_SHOWING:
130 const int real_x = x + 20; 194 texture_draw(msg->frame, x, y);
131 const int real_y = y + ((i + 1) * gapy) + (i * avgh); 195
132 196 for (int i = 0; i < 6; ++i) {
133 if (!msg->ttext[i]) 197 /* TODO: avatar handling */
134 continue; 198 const int real_x = x + 20;
135 199 const int real_y = y + ((i + 1) * gapy) + (i * avgh);
136 texture_draw(msg->stext[i], real_x + 2, real_y + 2); 200
137 texture_draw(msg->ttext[i], real_x, real_y); 201 if (!msg->textures[i])
202 continue;
203
204 texture_draw(msg->textures[i + 6], real_x + 2, real_y + 2);
205 texture_draw(msg->textures[i], real_x, real_y);
206 }
207 break;
208 default:
209 break;
138 } 210 }
139 } 211 }
140 212
141 void 213 void
142 message_hide(struct message *msg) 214 message_hide(struct message *msg)
150 void 222 void
151 message_close(struct message *msg) 223 message_close(struct message *msg)
152 { 224 {
153 assert(msg); 225 assert(msg);
154 226
155 for (int i = 0; i < 6; ++i) { 227 clear(msg);
156 if (msg->ttext[i]) { 228 }
157 texture_close(msg->ttext[i]);
158 msg->ttext[i] = NULL;
159 }
160 if (msg->stext[i]) {
161 texture_close(msg->stext[i]);
162 msg->stext[i] = NULL;
163 }
164 }
165 }