diff --git a/src/Main/FrameBuffer.cpp b/src/Main/FrameBuffer.cpp
new file mode 100644
index 0000000..1e3fee5
--- /dev/null
+++ b/src/Main/FrameBuffer.cpp
@@ -0,0 +1,570 @@
+// SwiftShader Software Renderer
+//
+// Copyright(c) 2005-2011 TransGaming Inc.
+//
+// All rights reserved. No part of this software may be copied, distributed, transmitted,
+// transcribed, stored in a retrieval system, translated into any human or computer
+// language by any means, or disclosed to third parties without the explicit written
+// agreement of TransGaming Inc. Without such an agreement, no rights or licenses, express
+// or implied, including but not limited to any patent rights, are granted to you.
+//
+
+#include "FrameBuffer.hpp"
+
+#include "Timer.hpp"
+#include "CPUID.hpp"
+#include "serialvalid.h"
+#include "Surface.hpp"
+#include "Register.hpp"
+#include "Debug.hpp"
+#include "Reactor/Shell.hpp"
+#include "Common/Configurator.hpp"
+
+#include <stdio.h>
+
+extern const int logoWidth;
+extern const int logoHeight;
+extern const unsigned int logoData[];
+
+#define DISPLAY_LOGO NDEBUG & 1
+
+namespace sw
+{
+	extern bool forceWindowed;
+
+	Surface *FrameBuffer::logo;
+	unsigned int *FrameBuffer::logoImage;
+	void *FrameBuffer::cursor;
+	int FrameBuffer::cursorWidth = 0;
+	int FrameBuffer::cursorHeight = 0;
+	int FrameBuffer::cursorHotspotX;
+	int FrameBuffer::cursorHotspotY;
+	int FrameBuffer::cursorPositionX;
+	int FrameBuffer::cursorPositionY;
+	int FrameBuffer::cursorX;
+	int FrameBuffer::cursorY;
+
+	FrameBuffer::FrameBuffer(HWND windowHandle, int width, int height, bool fullscreen)
+	{
+		locked = 0;
+
+		this->windowHandle = windowHandle;
+		this->width = width;
+		this->height = height;
+		bitDepth = 32;
+		HDRdisplay = false;
+		stride = 0;
+
+		if(forceWindowed)
+		{
+			fullscreen = false;
+		}
+
+		windowed = !fullscreen;
+
+		if(!windowed)
+		{
+			// Force fullscreen window style (no borders)
+			originalWindowStyle = GetWindowLong(windowHandle, GWL_STYLE);
+			SetWindowLong(windowHandle, GWL_STYLE, WS_POPUP);
+		}
+
+		HINSTANCE instance = (HINSTANCE)GetWindowLongPtr(windowHandle, GWLP_HINSTANCE);
+		unsigned char one[32 * 32 / sizeof(unsigned char)];
+		memset(one, 0xFFFFFFFF, sizeof(one));
+		unsigned char zero[32 * 32 / sizeof(unsigned char)] = {0};
+		nullCursor = CreateCursor(instance, 0, 0, 32, 32, one, zero);
+		win32Cursor = GetCursor();
+
+		blitFunction = 0;
+		blitRoutine = 0;
+
+		blitState.width = 0;
+		blitState.height = 0;
+		blitState.depth = 0;
+		blitState.cursorWidth = 0;
+		blitState.cursorHeight = 0;
+
+		logo = 0;
+
+		syncEvent = CreateEvent(0, FALSE, FALSE, 0);
+		blitEvent = CreateEvent(0, FALSE, FALSE, 0);
+		FrameBuffer *parameters = this;
+
+		terminate = false;
+		blitThread = CreateThread(0, 1024 * 1024, threadFunction, &parameters, 0, 0);
+		WaitForSingleObject(syncEvent, INFINITE);
+	}
+
+	FrameBuffer::~FrameBuffer()
+	{
+		terminate = true;
+		SetEvent(blitEvent);
+		WaitForSingleObject(blitThread, INFINITE);
+		CloseHandle(blitThread);
+		CloseHandle(blitEvent);
+		CloseHandle(syncEvent);
+
+		delete blitRoutine;
+
+		if(!windowed && GetWindowLong(windowHandle, GWL_STYLE) == WS_POPUP)
+		{
+			SetWindowLong(windowHandle, GWL_STYLE, originalWindowStyle);
+		}
+	}
+
+	void FrameBuffer::updateBounds(HWND windowOverride)
+	{
+		HWND window = windowOverride ? windowOverride : windowHandle;
+
+		if(windowed)
+		{
+			GetClientRect(window, &bounds);
+			ClientToScreen(window, (POINT*)&bounds);
+			ClientToScreen(window, (POINT*)&bounds + 1);
+		}
+		else
+		{
+			SetRect(&bounds, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));
+		}
+	}
+
+	void FrameBuffer::gracefulExit(const char *errorMessage, long result)
+	{
+		char error[256];
+
+		sprintf_s(error, 256, "%s\n(FrameBuffer error code 0x%0.8X)", errorMessage, result);
+
+		MessageBox(0, error, 0, MB_ICONERROR);
+
+		exit(0);
+	}
+
+	int FrameBuffer::getWidth() const
+	{
+		return width;
+	}
+
+	int FrameBuffer::getHeight() const
+	{
+		return height;
+	}
+
+	int FrameBuffer::getStride() const
+	{
+		return stride;
+	}
+
+	void FrameBuffer::setCursorImage(sw::Surface *cursorImage)
+	{
+		if(cursorImage)
+		{
+			cursor = cursorImage->lockExternal(0, 0, 0, sw::LOCK_READONLY, sw::PUBLIC);
+			cursorImage->unlockExternal();
+
+			cursorWidth = cursorImage->getExternalWidth();
+			cursorHeight = cursorImage->getExternalHeight();
+		}
+		else
+		{
+			cursorWidth = 0;
+			cursorHeight = 0;
+		}
+	}
+
+	void FrameBuffer::setCursorOrigin(int x0, int y0)
+	{
+		cursorHotspotX = x0;
+		cursorHotspotY = y0;
+	}
+
+	void FrameBuffer::setCursorPosition(int x, int y)
+	{
+		cursorPositionX = x;
+		cursorPositionY = y;
+	}
+
+	void FrameBuffer::copy(HWND windowOverride, void *source, bool HDR)
+	{
+		if(!source)
+		{
+			return;
+		}
+
+		updateBounds(windowOverride);
+
+		if(!lock())
+		{
+			return;
+		}
+
+		target = source;
+		HDRdisplay = HDR;
+
+		if(cursor)
+		{
+			cursorX = cursorPositionX - cursorHotspotX;
+			cursorY = cursorPositionY - cursorHotspotY;
+
+			HCURSOR oldCursor = SetCursor(nullCursor);
+			
+			if(oldCursor != nullCursor)
+			{
+				win32Cursor = oldCursor;
+			}
+		}
+		else
+		{
+			if(GetCursor() == nullCursor)
+			{
+				SetCursor(win32Cursor);
+			}
+		}
+
+		SetEvent(blitEvent);
+		WaitForSingleObject(syncEvent, INFINITE);
+	
+		unlock();
+	}
+
+	void FrameBuffer::copyLocked()
+	{
+		BlitState update;
+
+		update.width = width;
+		update.height = height;
+		update.depth = bitDepth;
+		update.stride = stride;
+		update.HDR = HDRdisplay;
+		update.cursorWidth = cursorWidth;
+		update.cursorHeight = cursorHeight;
+
+		if(memcmp(&blitState, &update, sizeof(BlitState)) != 0)
+		{
+			blitState = update;
+			delete blitRoutine;
+
+			blitRoutine = copyRoutine(blitState);
+			blitFunction = (void(__cdecl*)(void*, void*))blitRoutine->getEntry();
+		}
+
+		blitFunction(locked, target);
+
+		#ifndef _M_AMD64
+			__asm emms
+		#endif
+	}
+
+	Routine *FrameBuffer::copyRoutine(const BlitState &state)
+	{
+		initializeLogo();
+
+		const int width = state.width;
+		const int height = state.height;
+		const int width2 = (state.width + 1) & ~1;
+		const int dBytes = state.depth / 8;
+		const int dStride = state.stride;
+		const int sBytes = state.HDR ? 8 : 4;
+		const int sStride = sBytes * width2;
+
+	//	char compareApp[32] = SCRAMBLE31(validationApp, APPNAME_SCRAMBLE);
+	//	bool validApp = strcmp(compareApp, registeredApp) == 0;
+		bool validKey = ValidateSerialNumber(validationKey, CHECKSUM_KEY, SERIAL_PREFIX);
+
+		Function<Void, Pointer<Byte>, Pointer<Byte>> function;
+		{
+			Pointer<Byte> dst(function.arg(0));
+			Pointer<Byte> src(function.arg(1));
+
+			For(Int y = 0, y < height, y++)
+			{
+				Pointer<Byte> d = dst + y * dStride;
+				Pointer<Byte> s = src + y * sStride;
+
+				Int x0 = 0;
+
+				#if DISPLAY_LOGO
+					If(!Bool(validKey)/* || !Bool(validApp)*/)
+					{
+						If(y > height - logoHeight)
+						{
+							x0 = logoWidth;
+							s += logoWidth * sBytes;
+							d += logoWidth * dBytes;
+						}
+					}
+				#endif
+
+				if(state.depth == 32)
+				{
+					if(width2 % 4 == 0 && !state.HDR)
+					{
+						For(Int x = x0, x < width2, x += 4)
+						{
+							*Pointer<Int4>(d, 1) = *Pointer<Int4>(s, 16);
+
+							s += 4 * sBytes;
+							d += 4 * dBytes;
+						}
+					}
+					else
+					{
+						For(Int x = x0, x < width2, x += 2)
+						{
+							Int2 c01;
+
+							if(!state.HDR)
+							{
+								c01 = *Pointer<Int2>(s);
+							}
+							else
+							{
+								UShort4 c0 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0xC6)) >> 8;
+								UShort4 c1 = As<UShort4>(Swizzle(*Pointer<Short4>(s + 8), 0xC6)) >> 8;
+									
+								c01 = As<Int2>(Pack(c0, c1));
+							}
+
+							*Pointer<Int2>(d) = c01;
+
+							s += 2 * sBytes;
+							d += 2 * dBytes;
+						}
+					}
+				}
+				else if(state.depth == 24)
+				{
+					For(Int x = x0, x < width, x++)
+					{
+						if(!state.HDR)
+						{
+							*Pointer<Byte>(d + 0) = *Pointer<Byte>(s + 0);
+							*Pointer<Byte>(d + 1) = *Pointer<Byte>(s + 1);
+							*Pointer<Byte>(d + 2) = *Pointer<Byte>(s + 2);
+						}
+						else
+						{
+							*Pointer<Byte>(d + 0) = *Pointer<Byte>(s + 5);
+							*Pointer<Byte>(d + 1) = *Pointer<Byte>(s + 3);
+							*Pointer<Byte>(d + 2) = *Pointer<Byte>(s + 1);
+						}
+
+						s += sBytes;
+						d += dBytes;
+					}
+				}
+				else if(state.depth == 16)
+				{
+					For(Int x = x0, x < width, x++)
+					{
+						Int c;
+							
+						if(!state.HDR)
+						{
+							c = *Pointer<Int>(s);
+						}
+						else
+						{
+							UShort4 cc = As<UShort4>(Swizzle(*Pointer<Short4>(s + 0), 0xC6)) >> 8;
+
+							c = Int(As<Int2>(Pack(cc, cc)));
+						}
+
+						*Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 |
+						                           (c & 0x0000FC00) >> 5 |
+						                           (c & 0x000000F8) >> 3);
+
+						s += sBytes;
+						d += dBytes;
+					}
+				}
+				else ASSERT(false);
+			}
+
+			#if DISPLAY_LOGO
+				If(!Bool(validKey)/* || !Bool(validApp)*/)
+				{
+					UInt hash = UInt(0x0B020C04) + UInt(0xC0F090E0);   // Initial value
+					UInt imageHash = S3TC_SUPPORT ? UInt(0x01010600) + UInt(0xC0302010) : UInt(0x0D030E0B) + UInt(0xB0D01040);
+
+					While(hash != imageHash)
+					{
+						For(y = (height - 1), height - 1 - y < logoHeight, y--)
+						{
+							Pointer<Byte> logo = *Pointer<Pointer<Byte>>(&logoImage) + 4 * (logoHeight - height + y) * logoWidth;
+							Pointer<Byte> s = src + y * sStride;
+							Pointer<Byte> d = dst + y * dStride;
+
+							For(Int x = 0, x < logoWidth, x++)
+							{
+								hash *= 16777619;
+								hash ^= *Pointer<UInt>(logo);
+
+								If(y >= 0 && x < width)
+								{
+									blend(state, d, s, logo);
+								}
+
+								logo += 4;
+								s += sBytes;
+								d += dBytes;
+							}
+						}
+					}
+				}
+			#endif
+
+			Int x0 = *Pointer<Int>(&cursorX);
+			Int y0 = *Pointer<Int>(&cursorY);
+
+			For(Int y1 = 0, y1 < cursorHeight, y1++)
+			{
+				Int y = y0 + y1;
+
+				If(y >= 0 && y < height)
+				{
+					Pointer<Byte> d = dst + y * dStride + x0 * dBytes;
+					Pointer<Byte> s = src + y * sStride + x0 * sBytes;
+					Pointer<Byte> c = *Pointer<Pointer<Byte>>(&cursor) + y1 * cursorWidth * 4;
+
+					For(Int x1 = 0, x1 < cursorWidth, x1++)
+					{
+						Int x = x0 + x1;
+
+						If(x >= 0 && x < width)
+						{
+							blend(state, d, s, c);
+						}
+						
+						c += 4;
+						s += sBytes;
+						d += dBytes;
+					}
+				}
+			}
+
+			Return();
+		}
+
+		return function(L"FrameBuffer");
+	}
+
+	void FrameBuffer::blend(const BlitState &state, const Pointer<Byte> &d, const Pointer<Byte> &s, const Pointer<Byte> &c)
+	{
+		Short4 c1;
+		Short4 c2;
+
+		c1 = UnpackLow(As<Byte8>(c1), *Pointer<Byte8>(c));
+		
+		if(!state.HDR)
+		{
+			c2 = UnpackLow(As<Byte8>(c2), *Pointer<Byte8>(s));
+		}
+		else
+		{
+			c2 = Swizzle(*Pointer<Short4>(s + 0), 0xC6);
+		}
+
+		c1 = As<Short4>(As<UShort4>(c1) >> 9);
+		c2 = As<Short4>(As<UShort4>(c2) >> 9);
+
+		Short4 alpha = Swizzle(c1, 0xFF) & Short4(0xFFFF, 0xFFFF, 0xFFFF, 0x0000);
+
+		c1 = (c1 - c2) * alpha;
+		c1 = c1 >> 7;
+		c1 = c1 + c2;
+		c1 = c1 + c1;
+
+		c1 = As<Short4>(Pack(As<UShort4>(c1), As<UShort4>(c1)));
+
+		if(state.depth == 32)
+		{
+			*Pointer<UInt>(d) = UInt(As<Long>(c1));
+		}
+		else if(state.depth == 24)
+		{
+			Int c = Int(As<Int2>(c1));
+
+			*Pointer<Byte>(d + 0) = Byte(c >> 0);
+			*Pointer<Byte>(d + 1) = Byte(c >> 8);
+			*Pointer<Byte>(d + 2) = Byte(c >> 16);
+		}
+		else if(state.depth == 16)
+		{
+			Int c = Int(As<Int2>(c1));
+
+			*Pointer<Short>(d) = Short((c & 0x00F80000) >> 8 |
+			                           (c & 0x0000FC00) >> 5 |
+			                           (c & 0x000000F8) >> 3);
+		}
+		else ASSERT(false);
+	}
+
+	unsigned long __stdcall FrameBuffer::threadFunction(void *parameters)
+	{
+		FrameBuffer *frameBuffer = *static_cast<FrameBuffer**>(parameters);
+
+		SetEvent(frameBuffer->syncEvent);   // Received parameters
+
+		while(!frameBuffer->terminate)
+		{
+			WaitForSingleObject(frameBuffer->blitEvent, INFINITE);
+
+			if(!frameBuffer->terminate)
+			{
+				frameBuffer->copyLocked();
+
+				SetEvent(frameBuffer->syncEvent);
+			}
+		}
+
+		return 0;
+	}
+
+	void FrameBuffer::initializeLogo()
+	{
+		#if DISPLAY_LOGO
+			if(!logo)
+			{
+				#if S3TC_SUPPORT
+					logo = new Surface(0, logoWidth, logoHeight, 1, FORMAT_DXT5, true, false);
+					void *data = logo->lockExternal(0, 0, 0, LOCK_WRITEONLY, sw::PUBLIC);
+					memcpy(data, logoData, logoWidth * logoHeight);
+					logo->unlockExternal();
+				#else
+					logo = new Surface(0, logoWidth, logoHeight, 1, FORMAT_A8R8G8B8, true, false);
+					void *data = logo->lockExternal(0, 0, 0, LOCK_WRITEONLY, sw::PUBLIC);
+					memcpy(data, logoData, logoWidth * logoHeight * 4);
+					logo->unlockExternal();
+				#endif
+
+				logoImage = (unsigned int*)logo->lockInternal(0, 0, 0, LOCK_READONLY, sw::PUBLIC);
+				logo->unlockInternal();
+			}
+		#endif
+	}
+}
+
+#include "FrameBufferDD.hpp"
+#include "FrameBufferGDI.hpp"
+
+extern "C"
+{
+	sw::FrameBuffer *createFrameBuffer(HWND windowHandle, int width, int height, bool fullscreen)
+	{
+		sw::Configurator ini("SwiftShader.ini");
+		int api = ini.getInteger("Testing", "FrameBufferAPI", 0);
+
+		if(api == 0)
+		{
+			return new sw::FrameBufferDD(windowHandle, width, height, fullscreen);
+		}
+		else if(api == 1)
+		{
+			return new sw::FrameBufferGDI(windowHandle, width, height, fullscreen);
+		}
+		else ASSERT(false);
+
+		return 0;
+	}
+}
\ No newline at end of file
