Mercurial > molko
changeset 64:da9b7462ab92
core: implement question, closes #2464 @2h
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 23 Jan 2020 20:44:01 +0100 |
parents | ec0872aaee07 |
children | 80a913d25aa9 |
files | src/adventure/main.c src/core/message.c src/core/message.h |
diffstat | 3 files changed, 142 insertions(+), 60 deletions(-) [+] |
line wrap: on
line diff
--- a/src/adventure/main.c Thu Jan 23 13:48:49 2020 +0100 +++ b/src/adventure/main.c Thu Jan 23 20:44:01 2020 +0100 @@ -16,8 +16,6 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -#include <stdio.h> - #include "clock.h" #include "error.h" #include "event.h" @@ -57,26 +55,25 @@ struct font *font; struct texture *frame; - if (!(font = font_openf(sys_datapath("fonts/DejaVuSans.ttf"), 14))) + if (!(font = font_openf(sys_datapath("fonts/DejaVuSans.ttf"), 15))) error_fatal(); if (!(frame = image_openf(sys_datapath("images/message.png")))) error_fatal(); struct message msg = { .text = { - "Hello Molko.", - "This is your unique adventure, you must listen to me.", - "Do not give up, please be brave.", - "Feel free to come back if you need assistance.", - "But be sure to take a look at the manual pages.", - "And don't forget to update." + "Flip a coin.", + "Try your best my friend." }, - .color = 0xd9caddff, + .colors = { + 0xd9caddff, + 0x94d5ffff + }, .font = font, - .frame = frame + .frame = frame, + .flags = MESSAGE_QUESTION }; - clock_start(&clock); message_start(&msg); @@ -90,11 +87,13 @@ if (ev.type == EVENT_QUIT) return; - if (msg.state) - message_update(&msg, elapsed); //game_handle(&ev); + message_handle(&msg, &ev); } - + + if (msg.state) + message_update(&msg, elapsed); + painter_set_color(0xffffffff); painter_clear();
--- a/src/core/message.c Thu Jan 23 13:48:49 2020 +0100 +++ b/src/core/message.c Thu Jan 23 20:44:01 2020 +0100 @@ -18,6 +18,7 @@ #include <assert.h> +#include "event.h" #include "font.h" #include "message.h" #include "painter.h" @@ -25,19 +26,19 @@ #include "texture.h" #include "window.h" -#define MESSAGE_SPEED 1000 /* Time delay for animations */ +#define MESSAGE_SPEED 150 /* Time delay for animations */ #define MESSAGE_TIMEOUT 5000 /* Time for auto-closing */ static unsigned int -average_height(const struct message *msg) +average(const struct message *msg) { unsigned int n = 0; unsigned int total = 0; for (int i = 0; i < 6; ++i) { - if (msg->ttext[i]) { + if (msg->textures[i]) { n += 1; - total += texture_height(msg->ttext[i]); + total += texture_height(msg->textures[i]); } } @@ -45,15 +46,44 @@ } static void +clear(struct message *msg) +{ + for (unsigned int i = 0; i < 12; ++i) { + if (msg->textures[i]) { + texture_close(msg->textures[i]); + msg->textures[i] = NULL; + } + } +} + +static void redraw(struct message *msg) { + clear(msg); + /* Generate textures if not already done. */ - for (int i = 0; i < 6; ++i) { - if (!msg->text[i] || msg->ttext[i] || msg->stext[i]) + for (unsigned int i = 0; i < 6; ++i) { + if (!msg->text[i]) continue; - msg->stext[i] = font_render(msg->font, msg->text[i], 0x000000ff); - msg->ttext[i] = font_render(msg->font, msg->text[i], msg->color); + /* Normal lines of text. */ + unsigned long color = msg->colors[0]; + + if (msg->flags & MESSAGE_QUESTION && msg->index == i) + color = msg->colors[1]; + + if (!msg->textures[i]) + msg->textures[i] = font_render( + msg->font, + msg->text[i], + color + ); + if (!msg->textures[i + 6]) + msg->textures[i + 6] = font_render( + msg->font, + msg->text[i], + 0x000000ff + ); } } @@ -63,8 +93,40 @@ assert(msg); msg->elapsed = 0; - msg->alpha = 0; msg->state = MESSAGE_OPENING; + msg->height[0] = texture_height(msg->frame); + msg->height[1] = 0; + + redraw(msg); +} + +void +message_handle(struct message *msg, const union event *ev) +{ + assert(msg); + assert(ev); + + if (ev->type != EVENT_KEYDOWN || msg->state == MESSAGE_NONE) + return; + + switch (ev->key.key) { + case KEY_UP: + if (msg->index > 0) + msg->index--; + break; + case KEY_DOWN: + if (msg->index < 5 && msg->text[msg->index + 1]) + msg->index++; + break; + case KEY_ENTER: + msg->state = MESSAGE_HIDING; + msg->elapsed = 0; + break; + default: + break; + } + + redraw(msg); } bool @@ -76,10 +138,10 @@ switch (msg->state) { case MESSAGE_OPENING: - msg->alpha += 255 * ticks / MESSAGE_SPEED; + msg->height[1] += texture_height(msg->frame) * ticks / MESSAGE_SPEED; - if (msg->alpha > 255) - msg->alpha = 255; + if (msg->height[1] > msg->height[0]) + msg->height[1] = msg->height[0]; if (msg->elapsed >= MESSAGE_SPEED) { msg->state = MESSAGE_SHOWING; msg->elapsed = 0; @@ -95,6 +157,8 @@ break; case MESSAGE_HIDING: + msg->height[1] -= texture_height(msg->frame) * ticks / MESSAGE_SPEED; + if (msg->elapsed >= MESSAGE_SPEED) { msg->state = MESSAGE_NONE; msg->elapsed = 0; @@ -118,23 +182,31 @@ const unsigned int h = texture_height(msg->frame); const unsigned int x = (window_width() / 2) - (w / 2); const unsigned int y = 80; - const unsigned int avgh = average_height(msg); + const unsigned int avgh = average(msg); const unsigned int gapy = (h - (avgh * 6)) / 7; - /* TODO: handle state */ - redraw(msg); - texture_draw(msg->frame, x, y); + switch (msg->state) { + case MESSAGE_OPENING: + case MESSAGE_HIDING: + texture_draw_ex(msg->frame, 0, 0, w, msg->height[1], x, y, w, msg->height[1], 0); + break; + case MESSAGE_SHOWING: + texture_draw(msg->frame, x, y); - for (int i = 0; i < 6; ++i) { - /* TODO: avatar handling */ - const int real_x = x + 20; - const int real_y = y + ((i + 1) * gapy) + (i * avgh); + for (int i = 0; i < 6; ++i) { + /* TODO: avatar handling */ + const int real_x = x + 20; + const int real_y = y + ((i + 1) * gapy) + (i * avgh); - if (!msg->ttext[i]) - continue; + if (!msg->textures[i]) + continue; - texture_draw(msg->stext[i], real_x + 2, real_y + 2); - texture_draw(msg->ttext[i], real_x, real_y); + texture_draw(msg->textures[i + 6], real_x + 2, real_y + 2); + texture_draw(msg->textures[i], real_x, real_y); + } + break; + default: + break; } } @@ -152,14 +224,5 @@ { assert(msg); - for (int i = 0; i < 6; ++i) { - if (msg->ttext[i]) { - texture_close(msg->ttext[i]); - msg->ttext[i] = NULL; - } - if (msg->stext[i]) { - texture_close(msg->stext[i]); - msg->stext[i] = NULL; - } - } + clear(msg); }
--- a/src/core/message.h Thu Jan 23 13:48:49 2020 +0100 +++ b/src/core/message.h Thu Jan 23 20:44:01 2020 +0100 @@ -29,21 +29,24 @@ struct texture; struct font; +union event; + /** * \brief Message flags. */ enum message_flags { - MESSAGE_AUTOMATIC = (1 << 0) /*!< Message will automatically close */ + MESSAGE_AUTOMATIC = (1 << 0), /*!< Will automatically change state by itself. */ + MESSAGE_QUESTION = (1 << 1) /*!< The message is a question. */ }; /** * \brief Message state. */ enum message_state { - MESSAGE_NONE, /*!< Message hasn't start yet or is finished */ - MESSAGE_OPENING, /*!< Message animation is opening */ - MESSAGE_SHOWING, /*!< Message is displaying */ - MESSAGE_HIDING /*!< Message animation for hiding */ + MESSAGE_NONE, /*!< Message hasn't start yet or is finished */ + MESSAGE_OPENING, /*!< Message animation is opening */ + MESSAGE_SHOWING, /*!< Message is displaying */ + MESSAGE_HIDING /*!< Message animation for hiding */ }; /** @@ -57,15 +60,18 @@ struct texture *frame; /*!< (RW) Frame to use */ struct texture *avatar; /*!< (RW) Optional avatar */ struct font *font; /*!< (RW) Font to use */ - unsigned long color; /*!< (RW) Font color to use */ + unsigned long colors[2]; /*!< (RW) Normal/selected colors */ + unsigned int index; /*!< (RW) Line selected */ enum message_flags flags; /*!< (RW) Message flags */ enum message_state state; /*!< (RO) Current state */ - /* PRIVATE */ - struct texture *ttext[6]; /*!< (RW) Textures for every lines */ - struct texture *stext[6]; /*!< (RW) Textures for every lines */ - unsigned int elapsed; /*!< (RW) Elapsed time while displaying */ - unsigned int alpha; /*!< (RO) Alpha progression */ + /*! \cond PRIVATE */ + + struct texture *textures[12]; + unsigned int elapsed; + int height[2]; + + /*! \endcond */ }; /** @@ -79,6 +85,20 @@ message_start(struct message *msg); /** + * Handle input events. + * + * This function will alter state of the message and change its selection in + * case of question. + * + * \pre msg != NULL + * \pre ev != NULL + * \param msg the message + * \param ev the event which occured + */ +void +message_handle(struct message *msg, const union event *ev); + +/** * Update the message state and elapsed time.. * * \pre msg != NULL