X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=demo_prior;a=blobdiff_plain;f=src%2Fosd.c;fp=src%2Fosd.c;h=415cb86a63c7617ca0a20e3fc3c7c73e3c639581;hp=0000000000000000000000000000000000000000;hb=2f14a35e7d557da12f24056267b911f24774aa18;hpb=5eefe7b94c8d6c6caa2c10e3835ab0831a3c42a1 diff --git a/src/osd.c b/src/osd.c new file mode 100644 index 0000000..415cb86 --- /dev/null +++ b/src/osd.c @@ -0,0 +1,184 @@ +#include +#include +#include +#include +#include "cgmath/cgmath.h" +#include "opengl.h" +#include "osd.h" +#include "demo.h" + + +struct message { + long start_time, show_until; + char *str; + cgm_vec3 color; + struct message *next; +}; +static struct message *msglist; + +struct text { + char *str; + cgm_vec2 pos; + cgm_vec3 color; + struct text *next; +}; +static struct text *txlist; + +static long timeout = 2000; +static long trans_time = 250; + + +void set_message_timeout(long tm) +{ + timeout = tm; +} + +void osd_printf(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + show_messagev(timeout, 1, 1, 1, fmt, ap); + va_end(ap); +} + +void show_message(long timeout, float r, float g, float b, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + show_messagev(timeout, r, g, b, fmt, ap); + va_end(ap); +} + +void show_messagev(long timeout, float r, float g, float b, const char *fmt, va_list ap) +{ + char buf[512]; + struct message *msg; + struct message dummy; + int len; + + vsnprintf(buf, sizeof buf, fmt, ap); + + if(!(msg = malloc(sizeof *msg))) { + perror("failed to allocate memory"); + abort(); + } + len = strlen(buf); + if(!(msg->str = malloc(len + 1))) { + perror("failed to allocate memory"); + abort(); + } + memcpy(msg->str, buf, len + 1); + msg->start_time = time_msec; + msg->show_until = time_msec + timeout; + msg->color.x = r; + msg->color.y = g; + msg->color.z = b; + + dummy.next = msglist; + struct message *prev = &dummy; + while(prev->next && prev->next->show_until < msg->show_until) { + prev = prev->next; + } + msg->next = prev->next; + prev->next = msg; + msglist = dummy.next; +} + +void print_text(float x, float y, float r, float g, float b, const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + print_textv(x, y, r, g, b, fmt, ap); + va_end(ap); +} + +void print_textv(float x, float y, float r, float g, float b, const char *fmt, va_list ap) +{ + char buf[512]; + int len; + struct text *tx; + + vsnprintf(buf, sizeof buf, fmt, ap); + + if(!(tx = malloc(sizeof *tx))) { + perror("failed to allocate memory"); + abort(); + } + len = strlen(buf); + if(!(tx->str = malloc(len + 1))) { + perror("failed to allocate memory"); + abort(); + } + memcpy(tx->str, buf, len + 1); + tx->color.x = r; + tx->color.y = g; + tx->color.z = b; + tx->pos.x = x; + tx->pos.y = -y; + + tx->next = txlist; + txlist = tx; +} + +void draw_osd(void) +{ + if(!fnt_ui) return; + + while(msglist && msglist->show_until <= time_msec) { + struct message *msg = msglist; + msglist = msg->next; + free(msg->str); + free(msg); + } + + dtx_use_font(fnt_ui, fnt_ui_size); + + glMatrixMode(GL_PROJECTION); + glPushMatrix(); + glLoadIdentity(); + glOrtho(0, win_width, -win_height, 0, -1, 1); + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glLoadIdentity(); + + glPushAttrib(GL_ENABLE_BIT); + glDisable(GL_LIGHTING); + glDisable(GL_DEPTH_TEST); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glUseProgram(0); + + struct message *msg = msglist; + while(msg) { + long t = time_msec - msg->start_time; + long dur = msg->show_until - msg->start_time; + float alpha = cgm_smoothstep(0, trans_time, t) * + (1.0 - cgm_smoothstep(dur - trans_time, dur, t)); + glColor4f(msg->color.x, msg->color.y, msg->color.z, alpha); + glTranslatef(0, -dtx_line_height(), 0); + dtx_string(msg->str); + msg = msg->next; + } + + while(txlist) { + struct text *tx = txlist; + txlist = txlist->next; + + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(tx->pos.x, tx->pos.y, 0); + + glColor3f(tx->color.x, tx->color.y, tx->color.z); + dtx_string(tx->str); + + free(tx->str); + free(tx); + } + + glPopAttrib(); + + glMatrixMode(GL_PROJECTION); + glPopMatrix(); + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); +}