pt2game/textbox.cpp

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);
}