+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <gmath/gmath.h>
+#include <drawtext.h>
+#include "opengl.h"
+#include "ui.h"
+#include "app.h"
+
+#define FONTSZ 16
+
+static bool init();
+
+struct Message {
+ long start_time, show_until;
+ char *str;
+ Message *next;
+};
+static Message *msglist;
+
+static long timeout = 2000;
+static long trans_time = 250;
+static dtx_font *font;
+
+void set_message_timeout(long tm)
+{
+ timeout = tm;
+}
+
+void show_message(const char *fmt, ...)
+{
+ va_list ap;
+ char buf[512];
+
+ init();
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof buf, fmt, ap);
+ va_end(ap);
+
+ Message *msg = new Message;
+ int len = strlen(buf);
+ msg->str = new char[len + 1];
+ memcpy(msg->str, buf, len + 1);
+ msg->start_time = time_msec;
+ msg->show_until = time_msec + timeout;
+
+ Message dummy;
+ dummy.next = msglist;
+ 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 draw_ui()
+{
+ if(!font) return;
+
+ while(msglist && msglist->show_until <= time_msec) {
+ Message *msg = msglist;
+ msglist = msg->next;
+ delete [] msg->str;
+ delete msg;
+ }
+
+ dtx_use_font(font, FONTSZ);
+
+ 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);
+
+ Message *msg = msglist;
+ while(msg) {
+ long t = time_msec - msg->start_time;
+ long dur = msg->show_until - msg->start_time;
+ float alpha = smoothstep(0, trans_time, t) *
+ (1.0 - smoothstep(dur - trans_time, dur, t));
+ glColor4f(1.0, 0.5, 0.1, alpha);
+ glTranslatef(0, -dtx_line_height(), 0);
+ dtx_string(msg->str);
+ msg = msg->next;
+ }
+
+ glPopAttrib();
+
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(GL_MODELVIEW);
+ glPopMatrix();
+}
+
+static bool init()
+{
+ static bool done_init;
+ if(done_init) return true;
+
+ done_init = true;
+
+ if(!(font = dtx_open_font("data/ui.font", 0))) {
+ fprintf(stderr, "failed to open font: data/ui.font\n");
+ return false;
+ }
+ dtx_prepare_range(font, FONTSZ, 32, 127);
+ return true;
+}