157 lines
5.6 KiB
C
157 lines
5.6 KiB
C
#include <stdlib.h>
|
|
#include "Message.h"
|
|
|
|
struct Message *newMessage(struct Box box, struct Glyphs *glyphs, struct Ui_Colors *colors, int time, const char *string) {
|
|
struct Message *message = malloc(sizeof(struct Message));
|
|
message->box = box;
|
|
message->glyphs = glyphs;
|
|
message->colors = colors;
|
|
message->render_ch = 0;
|
|
message->render_line = 0;
|
|
message->time = time;
|
|
message->elapsed = 0;
|
|
message->line_count = 0;
|
|
message->line = NULL;
|
|
message->render_text = NULL;
|
|
cleanAnim(&message->animation);
|
|
// first let's break that string into lines
|
|
char ch;
|
|
int offset = 0; // position of last line end
|
|
int offset_y = message->glyphs->ch_h[0];
|
|
int i = 0; // current position
|
|
int width = 288;
|
|
while((ch = string[i++]) != '\0') {
|
|
if (ch < 32 || ch > 127) continue;
|
|
width += message->glyphs->ch_w[ch-32];
|
|
if ((width+(message->glyphs->ch_w[ch-32]*2)) >= box.w || ch == '\n') {
|
|
// resize lines
|
|
message->line = realloc(message->line, (message->line_count+1)*sizeof(char*));
|
|
message->render_text = realloc(message->render_text, (message->line_count+1)*sizeof(struct Textt*));
|
|
int old_i = i;
|
|
while (ch != ' ') {
|
|
if (i <= 0 || ch == '\0') {
|
|
i = old_i;
|
|
ch = string[i];
|
|
break;
|
|
}
|
|
ch = string[--i];
|
|
}
|
|
// create line
|
|
int size = (i - offset);
|
|
message->line[message->line_count] = malloc(size+2);
|
|
memcpy(message->line[message->line_count], string+offset, size);
|
|
message->line[message->line_count][size+1] = '\0';
|
|
// create Textt for render later
|
|
message->render_text[message->line_count] = newTextt(glyphs, colors, "");
|
|
message->render_text[message->line_count]->box = box;
|
|
message->render_text[message->line_count]->box.y += offset_y;
|
|
offset_y += message->glyphs->ch_h[ch-32]+4;
|
|
message->render_text[message->line_count]->box.x += 288;
|
|
//
|
|
message->line_count++;
|
|
width = 288;
|
|
offset = i;
|
|
}
|
|
}
|
|
// deal with remainder
|
|
if (offset != i) {
|
|
// resize lines
|
|
message->line = realloc(message->line, (message->line_count+1)*sizeof(char*));
|
|
message->render_text = realloc(message->render_text, (message->line_count+1)*sizeof(struct Textt*));
|
|
//
|
|
int size = (i - offset);
|
|
message->line[message->line_count] = malloc(size+2);
|
|
memcpy(message->line[message->line_count], string+offset, size);
|
|
message->line[message->line_count][size+1] = '\0';
|
|
// create Textt for render later
|
|
message->render_text[message->line_count] = newTextt(glyphs, colors, "");
|
|
message->render_text[message->line_count]->box = box;
|
|
message->render_text[message->line_count]->box.y += offset_y;
|
|
offset_y += message->glyphs->ch_h[ch-32]+4;
|
|
message->render_text[message->line_count]->box.x += 288;
|
|
//
|
|
message->line_count++;
|
|
}
|
|
// at this point we should have our original string divided into lines
|
|
return message;
|
|
}
|
|
int freeMessage(struct Message *message) {
|
|
if (message == NULL) return 1;
|
|
struct FrameSheet *sheet = message->animation.sheet;
|
|
if (sheet != NULL) {
|
|
if (sheet->state != 0) closeFrameSheet(sheet);
|
|
}
|
|
if (message->line_count > 0) {
|
|
int i;
|
|
for (i = 0; i < message->line_count; i++) {
|
|
free(message->line[i]);
|
|
freeTextt(message->render_text[i]);
|
|
}
|
|
free(message->line);
|
|
free(message->render_text);
|
|
}
|
|
free(message);
|
|
return 0;
|
|
}
|
|
int processMessage(struct Message *message, int time) {
|
|
message->elapsed += time;
|
|
incAnimFrame(&message->animation);
|
|
// add all chars from each char * line to each Textt over time
|
|
if (message->render_line < message->line_count) {
|
|
// add one char per tick from current char* line to current Textt
|
|
if (message->line[message->render_line][message->render_ch] != '\0') {
|
|
//addTexttChar(message->render_text[message->render_line], message->line[message->render_line][message->render_ch]);
|
|
// FIXME, this is 'spensive
|
|
setTextt(message->render_text[message->render_line], "%s%c", message->render_text[message->render_line]->text, message->line[message->render_line][message->render_ch]);
|
|
message->render_ch++;
|
|
} else {
|
|
// done with that line, move to the next
|
|
message->render_ch = 0;
|
|
message->render_line++;
|
|
}
|
|
} else {
|
|
// we're done!
|
|
if (message->elapsed >= message->time) {
|
|
// free here?
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int renderMessage(struct Message *message) {
|
|
int i;
|
|
SDL_Color color = message->colors->bg;
|
|
color.a = 64;
|
|
renderSQuad(message->box.x, message->box.y, message->box.w, message->box.h, color);
|
|
if (message->animation.sheet != NULL) {
|
|
struct FrameSheet *sheet = message->animation.sheet;
|
|
if (sheet->state == 0) openFrameSheet(sheet);
|
|
float w = sheet->surfaces[message->animation.f]->w;
|
|
float h = sheet->surfaces[message->animation.f]->h;
|
|
glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
|
|
glBindTexture(GL_TEXTURE_2D, sheet->textures[message->animation.f]);
|
|
// make sure we're rendering textures
|
|
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
|
// reset view
|
|
glLoadIdentity();
|
|
// translate to a quad
|
|
glTranslated(message->box.x, message->box.y+message->box.h-h, 1.0f);
|
|
// draw !
|
|
glBegin(GL_QUADS);
|
|
// top left
|
|
glTexCoord2d(0.0f, 0.0f); glVertex2f(0.0f, 0.0f);
|
|
// top right
|
|
glTexCoord2d(1.0, 0.0f); glVertex2f(w, 0.0f);
|
|
// bottom right
|
|
glTexCoord2d(1.0f, 1.0f); glVertex2f(w, h);
|
|
// bottom left
|
|
glTexCoord2d(0.0f, 1.0f); glVertex2f(0.0f, h);
|
|
glEnd();
|
|
}
|
|
for (i = 0; i < message->line_count; i++) {
|
|
renderTextt(message->render_text[i]);
|
|
}
|
|
// render box?
|
|
return 0;
|
|
}
|