85 lines
2.0 KiB
C++
85 lines
2.0 KiB
C++
#include "engine.h"
|
|
#include "objids.h"
|
|
#include <string.h>
|
|
|
|
// TODO: should be scene variables, so multiple textboxes can be stacked
|
|
static const char *textbox_text;
|
|
static int tb_width_chars, tb_height_chars;
|
|
static int visible_chars = 0;
|
|
|
|
extern const unsigned char _binary_sprite_font_raw_start[];
|
|
|
|
|
|
|
|
#define CHARSIZE 24
|
|
#define HSPACE 2
|
|
#define LINESPACE 8
|
|
|
|
static void textbox_render_fn(struct scene *s) {
|
|
|
|
struct sprite *fontsprite = get_decompressed_sprite(_binary_sprite_font_raw_start);
|
|
|
|
int boxheight = tb_height_chars*(CHARSIZE + LINESPACE) - LINESPACE;
|
|
int boxwidth = tb_width_chars*(CHARSIZE + HSPACE) - HSPACE;
|
|
int x = (1280 - tb_width_chars*CHARSIZE)/2;
|
|
int y = (800 - tb_height_chars*CHARSIZE)/2;
|
|
int xleft = x;
|
|
|
|
fillrect(x-CHARSIZE, y-CHARSIZE, boxwidth+2*CHARSIZE, boxheight+2*CHARSIZE, 0);
|
|
|
|
for(const char *str = textbox_text; *str; str++) {
|
|
if(str == textbox_text + visible_chars)
|
|
break;
|
|
if(*str == '\n') {
|
|
x = xleft;
|
|
y += CHARSIZE + LINESPACE;
|
|
} else {
|
|
blit(x, y, CHARSIZE, CHARSIZE, (*str - 32)*(CHARSIZE*CHARSIZE) + (uint32_t*)fontsprite->pixels);
|
|
x += CHARSIZE + HSPACE;
|
|
}
|
|
}
|
|
}
|
|
|
|
static void textbox_animtimer_fn(struct scene *s) {
|
|
if(textbox_text[visible_chars]) {
|
|
visible_chars++;
|
|
need_rerender = true;
|
|
}
|
|
}
|
|
static void textbox_handle_tap(struct scene *s, int x, int y) {
|
|
if(textbox_text[visible_chars]) {
|
|
visible_chars = strlen(textbox_text);
|
|
need_rerender = true;
|
|
} else {
|
|
pop_scene();
|
|
}
|
|
}
|
|
|
|
static void textbox_setup_fn(scene *s, int scene, int fromscene) {
|
|
s->render_fn = textbox_render_fn;
|
|
s->animtimer_fn = textbox_animtimer_fn;
|
|
s->handle_tap_fn = textbox_handle_tap;
|
|
}
|
|
|
|
|
|
void push_scene_textbox(const char *text) {
|
|
textbox_text = text;
|
|
visible_chars = 0;
|
|
|
|
tb_width_chars = 0;
|
|
tb_height_chars = 1;
|
|
int cur_width = 0;
|
|
for(const char *s = text; *s; s++) {
|
|
if(*s == '\n') {
|
|
tb_height_chars++;
|
|
cur_width = 0;
|
|
} else {
|
|
cur_width++;
|
|
if(cur_width > tb_width_chars)
|
|
tb_width_chars = cur_width;
|
|
}
|
|
}
|
|
|
|
push_scene(SCENE_TEXTBOX, textbox_setup_fn);
|
|
}
|