Mercurial > molko
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 } |