Index: trunk/nv/time.hh
===================================================================
--- trunk/nv/time.hh	(revision 34)
+++ trunk/nv/time.hh	(revision 34)
@@ -0,0 +1,121 @@
+// Copyright (C) 2012-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 time.hh
+ * @author Kornel Kisielewicz epyon@chaosforge.org
+ * @brief Time related functions
+ */
+
+#ifndef NV_TIME_HH
+#define NV_TIME_HH
+
+#include <nv/common.hh>
+
+namespace nv
+{
+	/**
+	 * Returns the amount of ticks of the processors high resolution 
+	 * timer. Currently only supported on GCC and MSVC. Probably only on
+	 * some architectures.
+	 *
+	 * @returns amount of ticks
+	 */
+	volatile uint64 get_ticks();
+
+	/**
+	 * Performs an operating system sleep call.
+	 *
+	 * @param time time in milliseconds to sleep
+	 */
+	void sleep( uint32 ms );
+
+	/**
+	 * Get millisecond count based on std::clock
+	 */
+	uint32 get_cpu_ms();
+
+	/**
+	 * Get microsecond count based on std::clock
+	 */
+	uint32 get_cpu_us();
+
+	/**
+	 * Get millisecond count based on system counter
+	 */
+	uint32 get_system_ms();
+
+	/**
+	 * Get microsecond count based on system counter
+	 */
+	uint32 get_system_us();
+
+	struct cpu_ms_timer { uint32 operator()() { return get_cpu_ms(); } };
+	struct cpu_us_timer { uint32 operator()() { return get_cpu_us(); } };
+	struct system_ms_timer { uint32 operator()() { return get_system_ms(); } };
+	struct system_us_timer { uint32 operator()() { return get_system_us(); } };
+	
+	/**
+	 * Timer template class
+	 */
+	template < class Timer >
+	class timer_class
+	{
+	public:
+		timer_class()	: last( Timer()() ) {}
+		void mark()	
+		{
+			uint32 now = Timer()();
+			stored = now - last;
+			last = now;
+		}
+		uint32 elapsed() const
+		{
+			return stored;
+		}
+	private:
+		uint32 last;
+		uint32 stored;
+	};
+
+	/**
+	 * FPS template class
+	 */
+	template < class Timer >
+	class fps_counter_class
+	{
+	public:
+		fps_counter_class() : frames(1), last(0) {}
+		bool tick()
+		{
+			uint32 now = Timer()();
+			if ( now - last >= 1000 )
+			{
+				value = (static_cast<float>(frames) /
+					static_cast<float>(now - last))*1000;
+				frames = 1;
+				last = now;
+				return true;
+			}
+			frames++;
+			return false;
+		}
+		f32 fps() const
+		{
+			return value;
+		}
+	private:
+		uint32 last;
+		uint32 frames;
+		f32 value;
+	};
+
+	typedef timer_class< system_ms_timer > ms_timer;
+	typedef timer_class< system_us_timer > us_timer;
+	typedef fps_counter_class< system_ms_timer > fps_counter;
+
+} // namespace nv
+
+#endif // NV_TIME_HH
Index: trunk/src/time.cc
===================================================================
--- trunk/src/time.cc	(revision 34)
+++ trunk/src/time.cc	(revision 34)
@@ -0,0 +1,103 @@
+// Copyright (C) 2011 Kornel Kisielewicz
+// This file is part of NV Libraries.
+// For conditions of distribution and use, see copyright notice in nv.hh
+
+#include "nv/time.hh"
+
+#include "nv/logging.hh"
+
+#if NV_COMPILER == NV_MSVC
+#define WIN32_LEAN_AND_MEAN 
+#include <windows.h>
+#include <intrin.h>
+#pragma intrinsic(__rdtsc)
+#else
+#include <unistd.h>
+#include <sys/time.h>
+#endif
+
+#include <ctime>
+
+struct timer_impl
+{
+	timer_impl()
+	{
+		clock_zero = clock();
+#if NV_COMPILER == NV_MSVC
+		QueryPerformanceFrequency(&frequency);
+		QueryPerformanceCounter(&query_zero);
+#else
+		gettimeofday(&timeval_zero, NULL);
+#endif
+	}
+	clock_t clock_zero;
+#if NV_COMPILER == NV_MSVC
+	LARGE_INTEGER query_zero;
+	LARGE_INTEGER frequency;
+#else
+	struct timeval timeval_zero;
+#endif
+};
+
+static timer_impl zero_timer;
+
+volatile nv::uint64 nv::get_ticks()
+{
+#if NV_COMPILER == NV_MSVC
+	return __rdtsc();
+#elif NV_COMPILER == NV_GNUC
+	register long long ticks asm("eax");
+	asm volatile (".byte 15, 49" : : : "eax", "edx");
+	return ticks;
+#else
+	return 0; // unsupported
+#endif
+}
+
+void nv::sleep( uint32 ms )
+{
+#if NV_COMPILER == NV_MSVC
+	Sleep( ms );
+#elif NV_COMPILER == NV_GNUC
+	usleep( ms * 1000 );
+#else
+#endif
+}
+
+nv::uint32 nv::get_cpu_ms()
+{
+	return (uint32)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000.0 ) ) ;
+}
+
+nv::uint32 nv::get_cpu_us()
+{
+	return (uint32)( (f32)( clock() - zero_timer.clock_zero ) / ( (f32)CLOCKS_PER_SEC / 1000000.0 ) ) ;
+}
+
+nv::uint32 nv::get_system_ms()
+{
+#if NV_COMPILER == NV_MSVC
+	LARGE_INTEGER now;
+	QueryPerformanceCounter(&now);
+	LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart;
+	return (uint32) (1000.0 * result / zero_timer.frequency.QuadPart);
+#else
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	return (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000+(now.tv_usec-zero_timer.timeval_zero.tv_usec)/1000;
+#endif
+}
+
+nv::uint32 nv::get_system_us()
+{
+#if NV_COMPILER == NV_MSVC
+	LARGE_INTEGER now;
+	QueryPerformanceCounter(&now);
+	LONGLONG result = now.QuadPart - zero_timer.query_zero.QuadPart;
+	return (uint32) (1000000.0 * result / zero_timer.frequency.QuadPart);
+#else
+	struct timeval now;
+	gettimeofday(&now, NULL);
+	return (now.tv_sec - zero_timer.timeval_zero.tv_sec)*1000000+(now.tv_usec - zero_timer.timeval_zero.tv_usec);
+#endif
+}
