diff --git a/message.c b/message.c
new file mode 100644
index 0000000000..ad58d4f94d
--- /dev/null
+++ b/message.c
@@ -0,0 +1,147 @@
+/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
+ * Copyright (C) 2010 - Hans-Kristian Arntzen
+ *
+ * Some code herein may be based on code found in BSNES.
+ *
+ * SSNES is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with SSNES.
+ * If not, see .
+ */
+
+#include "message.h"
+#include
+#include
+#include
+
+struct queue_elem
+{
+ unsigned duration;
+ unsigned prio;
+ char *msg;
+};
+
+struct msg_queue
+{
+ struct queue_elem **elems;
+ size_t ptr;
+ size_t size;
+ char *tmp_msg;
+};
+
+msg_queue_t *msg_queue_new(size_t size)
+{
+ msg_queue_t *queue = calloc(1, sizeof(*queue));
+ if (!queue)
+ return NULL;
+
+ queue->size = size + 1;
+ queue->elems = calloc(queue->size, sizeof(struct queue_elem*));
+ // Allocate one extra for scratch space when finding lowest prio elem.
+
+ if (!queue->elems)
+ {
+ free(queue);
+ return NULL;
+ }
+ queue->ptr = 1;
+ return queue;
+}
+
+void msg_queue_free(msg_queue_t *queue)
+{
+ for (size_t i = 1; i < queue->ptr; i++)
+ {
+ if (queue->elems[i])
+ {
+ free(queue->elems[i]->msg);
+ free(queue->elems[i]);
+ }
+ }
+ free(queue->elems);
+ free(queue->tmp_msg);
+ free(queue);
+}
+
+void msg_queue_push(msg_queue_t *queue, const char *msg, unsigned prio, unsigned duration)
+{
+ struct queue_elem *new_elem = calloc(1, sizeof(struct queue_elem));
+ new_elem->prio = prio;
+ new_elem->duration = duration;
+ new_elem->msg = msg ? strdup(msg) : NULL;
+
+ queue->elems[queue->ptr] = new_elem;
+ size_t tmp_ptr = queue->ptr++;
+
+ while (tmp_ptr > 1)
+ {
+ struct queue_elem *parent = queue->elems[tmp_ptr >> 1];
+ struct queue_elem *child = queue->elems[tmp_ptr];
+
+ if (child->prio <= parent->prio)
+ break;
+ else
+ {
+ queue->elems[tmp_ptr >> 1] = child;
+ queue->elems[tmp_ptr] = parent;
+ }
+ tmp_ptr >>= 1;
+ }
+}
+
+const char *msg_queue_pull(msg_queue_t *queue)
+{
+ if (queue->ptr == 1) // Nothing in queue. :(
+ return NULL;
+
+ struct queue_elem *front = queue->elems[1];
+ front->duration--;
+ if (front->duration > 0)
+ return front->msg;
+ else
+ {
+ queue->tmp_msg = front->msg;
+ front->msg = NULL;
+
+ struct queue_elem *front = queue->elems[1];
+ struct queue_elem *last = queue->elems[--queue->ptr];
+ queue->elems[1] = last;
+ free(front);
+
+ size_t tmp_ptr = 1;
+ for (;;)
+ {
+ bool left = (tmp_ptr * 2 <= queue->ptr) && (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2]);
+ bool right = (tmp_ptr * 2 + 1 <= queue->ptr) && (queue->elems[tmp_ptr] < queue->elems[tmp_ptr * 2 + 1]);
+
+ if (!left && !right)
+ break;
+
+ size_t switch_index = tmp_ptr;
+ if (left && !right)
+ switch_index <<= 1;
+ else if (right && !left)
+ switch_index += switch_index + 1;
+ else
+ {
+ if (queue->elems[tmp_ptr * 2] >= queue->elems[tmp_ptr * 2 + 1])
+ switch_index <<= 1;
+ else
+ switch_index += switch_index + 1;
+ }
+ struct queue_elem *parent = queue->elems[tmp_ptr];
+ struct queue_elem *child = queue->elems[switch_index];
+ queue->elems[tmp_ptr] = child;
+ queue->elems[switch_index] = parent;
+ tmp_ptr = switch_index;
+ }
+
+ return queue->tmp_msg;
+ }
+}
diff --git a/message.h b/message.h
new file mode 100644
index 0000000000..a5bfca5bcb
--- /dev/null
+++ b/message.h
@@ -0,0 +1,38 @@
+/* SSNES - A Super Nintendo Entertainment System (SNES) Emulator frontend for libsnes.
+ * Copyright (C) 2010 - Hans-Kristian Arntzen
+ *
+ * Some code herein may be based on code found in BSNES.
+ *
+ * SSNES is free software: you can redistribute it and/or modify it under the terms
+ * of the GNU General Public License as published by the Free Software Found-
+ * ation, either version 3 of the License, or (at your option) any later version.
+ *
+ * SSNES is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along with SSNES.
+ * If not, see .
+ */
+
+
+#ifndef __SSNES_MSG_QUEUE_H
+#define __SSNES_MSG_QUEUE_H
+
+#include
+
+typedef struct msg_queue msg_queue_t;
+
+// Creates a message queue with maximum size different messages. Returns NULL if allocation error.
+msg_queue_t *msg_queue_new(size_t size);
+
+// Higher prio is... higher prio :) Duration is how many times a message can be pulled from queue before it vanishes. (E.g. show a message for 3 seconds @ 60fps = 180 duration).
+
+void msg_queue_push(msg_queue_t *queue, const char *msg, unsigned prio, unsigned duration);
+
+// Pulls highest prio message in queue. Returns NULL if no message in queue.
+const char *msg_queue_pull(msg_queue_t *queue);
+
+void msg_queue_free(msg_queue_t *queue);
+
+#endif