Index: trunk/nv/curses/curses_terminal.hh
===================================================================
--- trunk/nv/curses/curses_terminal.hh	(revision 222)
+++ trunk/nv/curses/curses_terminal.hh	(revision 222)
@@ -0,0 +1,81 @@
+// Copyright (C) 2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+/**
+ * @file curses_terminal.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief curses terminal interface
+ */
+
+#ifndef NV_CURSES_TERMINAL_HH
+#define NV_CURSES_TERMINAL_HH
+
+#include <nv/common.hh>
+#include <nv/interface/terminal.hh>
+#include <nv/io_event.hh>
+
+namespace nv
+{
+	class curses_terminal : public terminal
+	{
+	public:	
+		/**
+		 * Constructor
+		 */
+		curses_terminal( dimension size );
+
+        /**
+         * Update the screen
+         */
+        virtual void update();
+
+        /**
+         * Print a character of the given color to the screen memory
+         */
+        virtual void print( position p, uint32 color, unsigned char ch );
+
+        /**
+		 * Clear screen memory
+         */
+        virtual void clear( rectangle r );
+
+        /**
+         * Clear screen memory
+         */
+        virtual void clear();
+
+        /**
+         * Polls event
+         */
+        virtual bool poll( io_event& kevent );
+
+		/**
+		 * Set cursor position
+		 */
+		virtual void set_cursor( position p );
+
+		/**
+		 * Show cursor
+		 */
+		virtual void show_cursor();
+
+		/**
+		 * Hide cursor
+		 */
+		virtual void hide_cursor();
+
+	public: // other methods
+		/**
+		 * Virtual destructor
+		 */
+		virtual ~curses_terminal();;
+
+	protected:
+		void* m_screen;
+		bool  m_update_needed;
+	};
+}
+
+#endif // NV_TERMINAL_HH
Index: trunk/nv/interface/terminal.hh
===================================================================
--- trunk/nv/interface/terminal.hh	(revision 222)
+++ trunk/nv/interface/terminal.hh	(revision 222)
@@ -0,0 +1,95 @@
+// Copyright (C) 2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+/**
+ * @file terminal.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief terminal interface
+ */
+
+#ifndef NV_TERMINAL_HH
+#define NV_TERMINAL_HH
+
+#include <nv/common.hh>
+#include <nv/position.hh>
+#include <nv/io_event.hh>
+
+namespace nv
+{
+	class terminal
+	{
+	public:	
+		/**
+		 * Constructor
+		 */
+		terminal( dimension size ) : m_size( size ), m_cursor(1,1) {}
+
+        /**
+         * Update the screen
+         */
+        virtual void update() = 0;
+
+        /**
+         * Print a character of the given color to the screen memory
+         */
+        virtual void print( position p, uint32 color, unsigned char ch ) = 0;
+
+        /**
+		 * Clear screen memory
+         */
+        virtual void clear( rectangle r ) = 0;
+
+        /**
+         * Clear screen memory
+         */
+        virtual void clear() = 0;
+
+        /**
+         * Polls event
+         */
+        virtual bool poll( io_event& kevent ) = 0;
+
+		/**
+		 * Set cursor position
+		 */
+		virtual void set_cursor( position p )
+		{
+			m_cursor = p;
+		}
+
+		/**
+		 * Show cursor
+		 */
+		virtual void show_cursor() = 0;
+
+		/**
+		 * Hide cursor
+		 */
+		virtual void hide_cursor() = 0;
+
+	public: // other methods
+
+		/**
+		 * Get cursor position
+		 */
+		virtual position get_cursor() const { return m_cursor; }
+
+		/**
+		 * Get the size
+		 */
+		virtual dimension get_size() const { return m_size; }
+
+		/**
+		 * Virtual destructor
+		 */
+		virtual ~terminal() {};
+
+	protected:
+		position  m_cursor;
+		dimension m_size;
+	};
+}
+
+#endif // NV_TERMINAL_HH
Index: trunk/src/curses/curses_terminal.cc
===================================================================
--- trunk/src/curses/curses_terminal.cc	(revision 222)
+++ trunk/src/curses/curses_terminal.cc	(revision 222)
@@ -0,0 +1,178 @@
+// Copyright (C) 2013 ChaosForge / Kornel Kisielewicz
+// http://chaosforge.org/
+//
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/curses/curses_terminal.hh"
+
+#include "nv/time.hh"
+#include "nv/lib/curses.hh"
+
+using namespace nv;
+
+curses_terminal::curses_terminal( dimension size ) : terminal( size )
+{
+	load_curses_library();
+	m_screen = initscr();
+	raw();
+	cbreak();
+	noecho();
+
+	nodelay  ( (WINDOW*)m_screen, true );
+	intrflush( (WINDOW*)m_screen, false );
+	keypad   ( (WINDOW*)m_screen, true );
+
+	start_color();
+	resize_term( size.y, size.x );
+	PDC_save_key_modifiers( true );
+
+	init_pair( 1, 0, 0 );
+	init_pair( 2, 1, 0 );
+	init_pair( 3, 2, 0 );
+	init_pair( 4, 3, 0 );
+	init_pair( 5, 4, 0 );
+	init_pair( 6, 5, 0 );
+	init_pair( 7, 6, 0 );
+	init_pair( 8, 7, 0 );
+
+	clear();
+	refresh();    
+	curs_set(1);
+
+	m_update_needed = false;
+}
+
+void curses_terminal::update()
+{
+	if (m_update_needed)
+	{
+		refresh();
+		m_update_needed = false;
+	}
+}
+
+void curses_terminal::print( position p, uint32 color, unsigned char ch )
+{
+	m_update_needed = true;
+	if ( color > 7 )
+	{
+		attrset((static_cast<uint32>(color-7) << 24)  & 0xff000000ul | 0x00800000ul);
+	}
+	else
+	{
+		attrset((static_cast<uint32>(color+1) << 24)  & 0xff000000ul);
+	}
+	mvaddch( p.y-1, p.x-1, ch );
+	move( m_cursor.y-1, m_cursor.x-1 );
+}
+
+void curses_terminal::clear( rectangle r )
+{
+	attrset( 0x00000000ul | 0x00800000ul );
+	for ( int x = r.ul.x-1; x <= r.lr.x-1; ++x )
+		for ( int y = r.ul.y-1; y <= r.lr.y-1; ++y )
+			mvaddch( y, x, ' ' );
+}
+
+void curses_terminal::clear()
+{
+	m_update_needed = true;
+	::clear();
+	move( m_cursor.y-1, m_cursor.x-1 );
+}
+
+bool curses_terminal::poll( io_event& kevent )
+{
+	// Sleep so we don't get 100% processor usage
+	sleep(10);
+
+	// Get value from curses
+	int result = wgetch((WINDOW*)m_screen);
+
+	// If value is err, return none event
+	if ( result == -1 )
+	{
+		return false;
+	}
+
+	// Zero the fields
+	kevent.type        = EV_KEY;
+	kevent.key.pressed = true;
+	kevent.key.ascii   = 0;
+	kevent.key.code    = nv::KEY_NONE;
+	kevent.key.control = false;
+	kevent.key.shift   = false;
+
+	// if result is a typable char place it into the structure
+	if ( result >= 32 && result < 128 )
+	{
+		kevent.key.ascii = static_cast<nv::char8>(result);
+	}
+
+	// Check the control and shift states
+	// TODO: obviously there is an ERROR here :P
+	kevent.key.control = (PDC_get_key_modifiers() & 2) != 0;
+	kevent.key.shift   = (PDC_get_key_modifiers() & 2) != 0;
+
+	// if result is a typable char from the directly transformable ranges
+	if ( (result >= nv::KEY_A && result <= nv::KEY_Z) ||
+		(result >= nv::KEY_0 && result <= nv::KEY_9) ||
+		result == ' ' )
+	{
+		kevent.key.code = static_cast<nv::key_code>(result);
+	}
+
+	// if result is a typable char from the a..z range
+	if ( result >= nv::KEY_A + 32 && result <= nv::KEY_Z + 32 )
+	{
+		kevent.key.code = static_cast<nv::key_code>(result - 32);
+	}
+
+	// if result is a typable char from the 0..9 range
+	if ( result >= nv::KEY_0 && result <= nv::KEY_9 )
+	{
+		kevent.key.code = static_cast<nv::key_code>(result);
+	}
+
+	// other recognized codes
+	switch ( result )
+	{
+	case 8         : kevent.key.code = nv::KEY_BACK; break;
+	case 9         : kevent.key.code = nv::KEY_TAB; break;
+	case 13        : kevent.key.code = nv::KEY_ENTER; break;
+	case 27        : kevent.key.code = nv::KEY_ESCAPE; break;
+	case 0x103     : kevent.key.code = nv::KEY_UP; break;
+	case 0x102     : kevent.key.code = nv::KEY_DOWN; break;
+	case 0x104     : kevent.key.code = nv::KEY_LEFT; break;
+	case 0x105     : kevent.key.code = nv::KEY_RIGHT; break;
+	case 0x153     : kevent.key.code = nv::KEY_PGUP; break;
+	case 0x152     : kevent.key.code = nv::KEY_PGDOWN; break;
+	case 0x106     : kevent.key.code = nv::KEY_HOME; break;
+	case 0x166     : kevent.key.code = nv::KEY_END; break;
+	}
+
+	// If key was understood by nv, then it's valid, otherwise ignored
+	return kevent.key.ascii != 0 || kevent.key.code != 0;
+}
+
+void curses_terminal::set_cursor( position p )
+{
+	terminal::set_cursor( p );
+	move( m_cursor.y-1, m_cursor.x-1 );
+}
+
+void curses_terminal::show_cursor()
+{
+	curs_set(1);
+}
+
+void curses_terminal::hide_cursor()
+{
+	curs_set(0);
+}
+
+curses_terminal::~curses_terminal()
+{
+	endwin();
+}
