diff --git a/neercs/term/ansi.cpp b/neercs/term/ansi.cpp
index 799166a..996465c 100644
--- a/neercs/term/ansi.cpp
+++ b/neercs/term/ansi.cpp
@@ -272,8 +272,11 @@ size_t Term::ReadAnsi(void const *data, size_t size)
 
     if (!m_init)
     {
-        m_dfg = CACA_LIGHTGRAY;
-        m_dbg = CACA_BLACK;
+        m_fg = m_dfg = CACA_LIGHTGRAY;
+        m_bg = m_dbg = CACA_BLACK;
+
+        m_bold = m_blink = m_italics = m_negative = m_concealed
+         = m_underline = m_faint = m_strike = m_proportional = 0;
 
         caca_set_color_ansi(m_caca, m_dfg, m_dbg);
         m_clearattr = caca_get_attr(m_caca, -1, -1);
diff --git a/neercs/term/pty.cpp b/neercs/term/pty.cpp
index a1ddbf3..5e14941 100644
--- a/neercs/term/pty.cpp
+++ b/neercs/term/pty.cpp
@@ -46,7 +46,8 @@ Pty::Pty()
     m_pid(-1),
     m_eof(false),
     m_unread_data(0),
-    m_unread_len(0)
+    m_unread_len(0),
+    m_size(-1, -1)
 {
     ;
 }
@@ -110,6 +111,9 @@ bool Pty::IsEof() const
     return m_eof;
 }
 
+/* Read data from the PTY. We only perform one read() call so that the
+ * caller can decide whether to ask for more data or not. This lets us
+ * prioritise data in some way. */
 size_t Pty::ReadData(char *data, size_t maxlen)
 {
 #if defined HAVE_FORKPTY
diff --git a/neercs/term/term.cpp b/neercs/term/term.cpp
index b451cc6..7d90bca 100644
--- a/neercs/term/term.cpp
+++ b/neercs/term/term.cpp
@@ -30,6 +30,10 @@ Term::Term(ivec2 size)
     m_caca(caca_create_canvas(size.x, size.y)),
     m_size(size),
     m_title(0),
+    m_bell(0),
+    m_init(0),
+    m_report_mouse(0),
+    m_changed(0),
     m_time(0.f),
     m_debug(false)
 {
@@ -133,14 +137,22 @@ void Term::TickGame(float seconds)
         size_t current = m_pty->ReadData(buf, BUFSIZ);
         if (current <= 0)
             break;
-        total += current;
+        /* FIXME: by the time we're finished decoding the ANSI data, some
+         * new data may be available. We need to avoid reading it because
+         * it's time rendering the canvas isntead. */
         size_t processed = ReadAnsi(buf, current);
         if (processed < current)
             m_pty->UnreadData(buf + processed, current - processed);
-        if (current < BUFSIZ)
+        total += processed;
+        if (processed == 0)
+            break;
+
+        /* FIXME: when do we know when to stop? If we read too much
+         * data, some of our frames will not be rendered because they'll
+         * be overwritten by new data. If we don't read enough, we will
+         * start rendering even if a frame isn't finished. */
+        if (total > 12000)
             break;
-//        if (total > 10000)
-//            break;
     }
 
     /* Some fancy shit if we press F3 */
@@ -256,4 +268,4 @@ void Term::DrawFancyShit()
 
     caca_set_color_argb(m_caca, 0x777, bg_color);
     caca_put_str(m_caca, 0, 0, "rez@lol:~/code/neercs/");
-}
\ No newline at end of file
+}
diff --git a/neercs/video/text-render.cpp b/neercs/video/text-render.cpp
index 221e4cf..e5372e2 100644
--- a/neercs/video/text-render.cpp
+++ b/neercs/video/text-render.cpp
@@ -121,6 +121,7 @@ void TextRender::Render()
 
     /* Upload libcaca canvas contents to the vertex buffers */
     uint32_t *colors = (uint32_t *)m_vbo1->Lock(0, 0);
+    uint32_t savedattr = caca_get_attr(m_caca, -1, -1);
     for (int j = 0; j < m_canvas_size.y; j++)
     for (int i = 0; i < m_canvas_size.x; i++)
     {
@@ -131,6 +132,7 @@ void TextRender::Render()
         attr = caca_get_attr(m_caca, -1, -1);
         caca_put_attr(m_caca, i, j, attr);
     }
+    caca_set_attr(m_caca, savedattr);
     memcpy(colors, caca_get_canvas_attrs(m_caca),
            m_cells * sizeof(uint32_t));
     m_vbo1->Unlock();