kettek2/wiki/games/newsboy/Newsboy_0x00/engine/Message.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;
}