diff --git a/Source/Core/Common/Src/ConsoleListener.cpp b/Source/Core/Common/Src/ConsoleListener.cpp
index 163bcdefb0..7da35eefd5 100644
--- a/Source/Core/Common/Src/ConsoleListener.cpp
+++ b/Source/Core/Common/Src/ConsoleListener.cpp
@@ -57,23 +57,12 @@ void ConsoleListener::Open(int Width, int Height, const char *Title)
 #ifdef _WIN32
 	// Open the console window and create the window handle for GetStdHandle()
 	AllocConsole();
-
 	// Save the window handle that AllocConsole() created
 	hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
-
 	// Set the console window title
 	SetConsoleTitle(Title);
-
-	// Set the total letter space to MAX_BYTES
-	int LWidth = Width / 8;
-	int LBufHeight = floor((float)(MAX_BYTES / (LWidth + 1)));
-	COORD co = {LWidth, LBufHeight};
-	SetConsoleScreenBufferSize(hConsole, co);
-
-	/* Set the window size in number of letters. The height is hard coded here
-	because it can be changed with MoveWindow() later */
-	SMALL_RECT coo = {0,0, (LWidth - 1), 50}; // Top, left, right, bottom
-	SetConsoleWindowInfo(hConsole, TRUE, &coo);
+	// Set letter space
+	LetterSpace(80, 4000);
 #endif
 }
 
@@ -104,68 +93,175 @@ bool ConsoleListener::IsOpen()
 ////////////////////////////////////////////////////////////////////////////////////////////////////////
 // Size
 // ������������������
+/*
+Short documentation:
+	LetterSpace: SetConsoleScreenBufferSize and SetConsoleWindowInfo are dependent on each other, that's the
+	reason for the additional checks.
+*/
+void ConsoleListener::BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst)
+{
+#ifdef _WIN32
+	bool SB, SW;
+
+	if (BufferFirst)
+	{
+		// Change screen buffer size
+		COORD Co = {BufferWidth, BufferHeight};
+		SB = SetConsoleScreenBufferSize(hConsole, Co);
+		// Change the screen buffer window size
+		SMALL_RECT coo = {0,0,ScreenWidth, ScreenHeight}; // top, left, right, bottom
+		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
+	}
+	else
+	{
+		// Change the screen buffer window size
+		SMALL_RECT coo = {0,0, ScreenWidth, ScreenHeight}; // top, left, right, bottom
+		SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
+		// Change screen buffer size
+		COORD Co = {BufferWidth, BufferHeight};
+		SB = SetConsoleScreenBufferSize(hConsole, Co);
+	}
+#endif
+}
 void ConsoleListener::LetterSpace(int Width, int Height)
 {
 #ifdef _WIN32
-
 	// Get console info
 	CONSOLE_SCREEN_BUFFER_INFO ConInfo;
 	GetConsoleScreenBufferInfo(hConsole, &ConInfo);
 
-	// Change the screen buffer window size
-	SMALL_RECT coo = {0,0, Width, Height}; // top, left, right, bottom
-	bool SW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
+	//
+	int OldBufferWidth = ConInfo.dwSize.X;
+	int OldBufferHeight = ConInfo.dwSize.Y;
+	int OldScreenWidth = (ConInfo.srWindow.Right - ConInfo.srWindow.Left);
+	int OldScreenHeight = (ConInfo.srWindow.Bottom - ConInfo.srWindow.Top);
+	//
+	int NewBufferWidth = Width;
+	int NewBufferHeight = Height;
+	int NewScreenWidth = NewBufferWidth - 1;
+	int NewScreenHeight = OldScreenHeight;
 
-	// Change screen buffer to the screen buffer window size
-	COORD Co = {Width + 1, Height + 1};
-	bool SB = SetConsoleScreenBufferSize(hConsole, Co);
+	// Width
+	BufferWidthHeight(NewBufferWidth, OldBufferHeight, NewScreenWidth, OldScreenHeight, (NewBufferWidth > OldScreenWidth-1));
+	// Height
+	BufferWidthHeight(NewBufferWidth, NewBufferHeight, NewScreenWidth, NewScreenHeight, (NewBufferHeight > OldScreenHeight-1));
 
 	// Resize the window too
-	MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(Height*12 + 50), true);
-
-	// Logging
-	//printf("LetterSpace(): L:%i T:%i Iconic:%i\n", ConsoleLeft, ConsoleTop, ConsoleIconic);
+	//MoveWindow(GetConsoleWindow(), 200,200, (Width*8 + 50),(NewScreenHeight*12 + 200), true);
 #endif
 }
+#ifdef _WIN32
+COORD ConsoleListener::GetCoordinates(int BytesRead, int BufferWidth)
+{
+	COORD Ret = {0, 0};
+	// Full rows
+	int Step = floor((float)BytesRead / (float)BufferWidth);
+	Ret.Y += Step;
+	// Partial row
+	Ret.X = BytesRead - (BufferWidth * Step);
+	return Ret;
+}
+#endif
 void ConsoleListener::PixelSpace(int Left, int Top, int Width, int Height, bool Resize)
 {
 #ifdef _WIN32
 	// Check size
 	if (Width < 8 || Height < 12) return;
 
+	bool DBef = true;
+	bool DAft = true;
+	std::string SLog = "";
+
+	HWND hWnd = GetConsoleWindow();
+	HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
+
 	// Get console info
 	CONSOLE_SCREEN_BUFFER_INFO ConInfo;
 	GetConsoleScreenBufferInfo(hConsole, &ConInfo);
-	// Letter space
-	int LWidth = floor((float)(Width / 8));
-	int LHeight = floor((float)(Height / 12));	
-	int LBufHeight = floor((float)(MAX_BYTES / (LWidth + 1)));
+	DWORD BufferSize = ConInfo.dwSize.X * ConInfo.dwSize.Y;
 
-	// Check size
-	DWORD dwConSize = ConInfo.dwSize.X * ConInfo.dwSize.Y;
-	if (dwConSize > MAX_BYTES) return;
-	// Read the current text
-	char Str[MAX_BYTES];	
+	// ---------------------------------------------------------------------
+	//  Save the current text
+	// ������������������������
 	DWORD cCharsRead = 0;
 	COORD coordScreen = { 0, 0 };
-	ReadConsoleOutputCharacter(hConsole, Str, dwConSize, coordScreen, &cCharsRead);
 
-	// Change the screen buffer window size
-	SMALL_RECT coo = {0,0, LWidth, LHeight}; // top, left, right, bottom
-	bool bW = SetConsoleWindowInfo(hConsole, TRUE, &coo);
-	// Change screen buffer to the screen buffer window size
-	COORD Co = {LWidth + 1, LBufHeight};
-	bool bB = SetConsoleScreenBufferSize(hConsole, Co);
+	std::vector<char*> Str;
+	std::vector<WORD*> Attr;
+	// ReadConsoleOutputAttribute seems to have a limit at this level
+	const int MAX_BYTES = 1024 * 16;
+	int ReadBufferSize = MAX_BYTES - 32;
+	DWORD cAttrRead = ReadBufferSize;
+	int BytesRead = 0;
+	int i = 0;
+	int LastAttrRead = 0;
+	while(BytesRead < BufferSize)
+	{
+		Str.push_back(new char[MAX_BYTES]);
+		if (!ReadConsoleOutputCharacter(hConsole, Str[i], ReadBufferSize, coordScreen, &cCharsRead))
+			SLog += StringFromFormat("WriteConsoleOutputCharacter error");
+		Attr.push_back(new WORD[MAX_BYTES]);
+		if (!ReadConsoleOutputAttribute(hConsole, Attr[i], ReadBufferSize, coordScreen, &cAttrRead))
+			SLog += StringFromFormat("WriteConsoleOutputAttribute error");
 
-	// Redraw the text
+		// Break on error
+		if (cAttrRead == 0) break;
+		BytesRead += cAttrRead;
+		i++;
+		coordScreen = GetCoordinates(BytesRead, ConInfo.dwSize.X);
+		LastAttrRead = cAttrRead;
+	}
+	// ---------------------------------------------------------------------
+
+
+	// ---------------------------------------------------------------------
+	//  Modify the buffer proportions
+	// ������������������������
+	// Letter space
+	int LWidth = floor((float)Width / 8.0) - 1.0;
+	int LHeight = floor((float)Height / 12.0) - 1.0;	
+	int LBufWidth = LWidth + 1;
+	int LBufHeight = floor((float)BufferSize / (float)LBufWidth);
+	// Change screen buffer size
+	LetterSpace(LBufWidth, LBufHeight);
+	// ---------------------------------------------------------------------
+
+
+	// ---------------------------------------------------------------------
+	//  Redraw the text
+	// ������������������������
+	ClearScreen(true);	
+	coordScreen.Y = 0;
+	coordScreen.X = 0;
 	DWORD cCharsWritten = 0;
-	WriteConsoleOutputCharacter(hConsole, Str, cCharsRead, coordScreen, &cCharsWritten);
+
+	int BytesWritten = 0;
+	DWORD cAttrWritten = 0;
+	for (int i = 0; i < Attr.size(); i++)
+	{
+		if (!WriteConsoleOutputCharacter(hConsole, Str[i], ReadBufferSize, coordScreen, &cCharsWritten))
+			SLog += StringFromFormat("WriteConsoleOutputCharacter error");
+		if (!WriteConsoleOutputAttribute(hConsole, Attr[i], ReadBufferSize, coordScreen, &cAttrWritten))
+			SLog += StringFromFormat("WriteConsoleOutputAttribute error");
+
+		BytesWritten += cAttrWritten;
+		coordScreen = GetCoordinates(BytesWritten, LBufWidth);
+	}	
+	// ---------------------------------------------------------------------
+
+
+	// ---------------------------------------------------------------------
+	//  Update cursor
+	// ������������������������
+	int OldCursor = ConInfo.dwCursorPosition.Y * ConInfo.dwSize.X + ConInfo.dwCursorPosition.X;
+	COORD Coo = GetCoordinates(OldCursor, LBufWidth);
+	SetConsoleCursorPosition(hConsole, Coo);
+	// ---------------------------------------------------------------------
+
+	if (SLog.length() > 0) Log(LogTypes::LNOTICE, SLog.c_str());
 
 	// Resize the window too
-	if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 50),(Height + 50), true);
-
-	// Logging
-	//Log(LogTypes::LNOTICE, StringFromFormat("\n\n\n\nMaxBytes: %i, WxH:%ix%i, Consize: %i, Read: %i, Written: %i\n\n", MAX_BYTES, LWidth, LHeight, dwConSize, cCharsRead, cCharsWritten).c_str());
+	if (Resize) MoveWindow(GetConsoleWindow(), Left,Top, (Width + 100),Height, true);
 #endif
 }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -226,7 +322,7 @@ void ConsoleListener::Log(LogTypes::LOG_LEVELS Level, const char *Text)
 }
 
 // Clear console screen
-void ConsoleListener::ClearScreen()
+void ConsoleListener::ClearScreen(bool Cursor)
 { 
 #if defined(_WIN32)
 	COORD coordScreen = { 0, 0 }; 
@@ -243,7 +339,7 @@ void ConsoleListener::ClearScreen()
 	GetConsoleScreenBufferInfo(hConsole, &csbi); 
 	FillConsoleOutputAttribute(hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten);
 	// Reset cursor
-	SetConsoleCursorPosition(hConsole, coordScreen); 
+	if (Cursor) SetConsoleCursorPosition(hConsole, coordScreen); 
 #endif
 }
 ////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/Source/Core/Common/Src/Log.h b/Source/Core/Common/Src/Log.h
index 21bbbbf1cc..bb58bc06fb 100644
--- a/Source/Core/Common/Src/Log.h
+++ b/Source/Core/Common/Src/Log.h
@@ -82,6 +82,7 @@ enum LOG_LEVELS {
 	LWARNING = WARNING_LEVEL,
 	LINFO = INFO_LEVEL,
 	LDEBUG = DEBUG_LEVEL,
+	LCUSTOM = CUSTOM_LEVEL,
 };
 
 }  // namespace
diff --git a/Source/Core/Common/Src/LogManager.h b/Source/Core/Common/Src/LogManager.h
index 28845ba054..d461390922 100644
--- a/Source/Core/Common/Src/LogManager.h
+++ b/Source/Core/Common/Src/LogManager.h
@@ -78,10 +78,14 @@ public:
 	void Close();
 	bool IsOpen();
 	void LetterSpace(int Width, int Height);
+	void BufferWidthHeight(int BufferWidth, int BufferHeight, int ScreenWidth, int ScreenHeight, bool BufferFirst);
 	void PixelSpace(int Left, int Top, int Width, int Height, bool);
+	#ifdef _WIN32
+	COORD GetCoordinates(int BytesRead, int BufferWidth);
+	#endif
 	void Log(LogTypes::LOG_LEVELS, const char *Text);
 	//void Log(LogTypes::LOG_LEVELS, const char *Text, ...);
-	void ClearScreen();
+	void ClearScreen(bool Cursor = true);
 
 	const char *getName() const { return "Console"; }
 
@@ -89,7 +93,6 @@ private:
 #ifdef _WIN32
 	HWND GetHwnd(void);
 	HANDLE hConsole;
-	static const int MAX_BYTES = 1024 * 30;
 #endif
 };
 
diff --git a/Source/Core/DolphinWX/Src/Frame.cpp b/Source/Core/DolphinWX/Src/Frame.cpp
index c88a617521..9980970238 100644
--- a/Source/Core/DolphinWX/Src/Frame.cpp
+++ b/Source/Core/DolphinWX/Src/Frame.cpp
@@ -82,6 +82,22 @@ extern "C" {
 };
 
 
+//////////////////////////////////////////////////////////////////////////////////////////
+// Empty wxPanel
+// ��������������
+BEGIN_EVENT_TABLE(CEmptyPanel, wxPanel)
+END_EVENT_TABLE()
+
+CEmptyPanel::CEmptyPanel(
+			wxWindow *parent,
+			wxWindowID id
+			)
+	: wxPanel(parent, id)
+{
+}
+//////////////////////////////////////////////////////////////////////////////////////////
+
+
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 /* Windows functions. Setting the cursor with wxSetCursor() did not work in this instance.
    Probably because it's somehow reset from the WndProc() in the child window */
diff --git a/Source/Core/DolphinWX/Src/Frame.h b/Source/Core/DolphinWX/Src/Frame.h
index 5d12aaf4e3..f2ae784865 100644
--- a/Source/Core/DolphinWX/Src/Frame.h
+++ b/Source/Core/DolphinWX/Src/Frame.h
@@ -276,4 +276,17 @@ class CFrame : public wxFrame
 		DECLARE_EVENT_TABLE();
 };
 
+
+class CEmptyPanel : public wxPanel
+{
+	public:
+		CEmptyPanel(
+			wxWindow* parent,
+			wxWindowID id = wxID_ANY
+			);
+
+	private:
+		DECLARE_EVENT_TABLE();
+};
+
 #endif  // __FRAME_H_
diff --git a/Source/Core/DolphinWX/Src/FrameTools.cpp b/Source/Core/DolphinWX/Src/FrameTools.cpp
index 48fc991d0b..be1785641c 100644
--- a/Source/Core/DolphinWX/Src/FrameTools.cpp
+++ b/Source/Core/DolphinWX/Src/FrameTools.cpp
@@ -755,12 +755,49 @@ void CFrame::ResizeConsole()
 		{
 			if (m_NB[i]->GetPageText(j).IsSameAs(wxT("Console")))
 			{
+				#ifdef _WIN32
+				// ----------------------------------------------------------
+				// Get OS version
+				// ������������������
+				int wxBorder, Border, LowerBorder, MenuBar, ScrollBar, WidthReduction;
+				OSVERSIONINFO osvi;
+				ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
+				osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+				GetVersionEx(&osvi);
+				if (osvi.dwMajorVersion == 6) // Vista (same as 7?)
+				{
+					wxBorder = 2;
+					Border = 4;
+					LowerBorder = 6;
+					MenuBar = 30; // Including upper border				
+					ScrollBar = 19;
+				}
+				else // XP
+				{
+					wxBorder = 2;
+					Border = 4;
+					LowerBorder = 6;
+					MenuBar = 30;					
+					ScrollBar = 19;
+				}
+				WidthReduction = 30 - Border;
+				// --------------------------------
 				// Get the client size
-				int X = m_NB[i]->GetClientSize().GetX() - 35;
-				int Y = m_NB[i]->GetClientSize().GetY() - 70;
+				int X = m_NB[i]->GetClientSize().GetX();
+				int Y = m_NB[i]->GetClientSize().GetY();
+				int InternalWidth = X - wxBorder*2 - ScrollBar;
+				int InternalHeight = Y - wxBorder*2;
+				int WindowWidth = InternalWidth + Border*2;
+				int WindowHeight = InternalHeight;
 				// Resize buffer
 				ConsoleListener* Console = LogManager::GetInstance()->getConsoleListener();
-				Console->PixelSpace(0,0, X,Y, false);
+				Console->Log(LogTypes::LNOTICE, StringFromFormat("Window WxH:%i %i\n", X, Y).c_str());
+				Console->PixelSpace(0,0, InternalWidth,InternalHeight, false);
+				// Move the window to hide the border
+				MoveWindow(GetConsoleWindow(), -Border-wxBorder,-MenuBar-wxBorder, WindowWidth + 100,WindowHeight, true);
+				// Move it to the bottom of the view order so that it doesn't hide the notebook tabs
+				// ...
+				#endif
 			}
 		}	
 	}
@@ -1150,7 +1187,12 @@ void CFrame::ToggleConsole(bool Show, int i)
 		// Can we remove the border?
 		//Win->SetWindowStyleFlag(wxNO_BORDER);
 		//SetWindowLong(GetConsoleWindow(), GWL_STYLE, WS_VISIBLE);
-		if (Win) m_NB[i]->AddPage(Win, wxT("Console"), true, aNormalFile );
+		// Create parent window
+		CEmptyPanel * ConsoleParent = new CEmptyPanel(this);
+		::SetParent(GetConsoleWindow(), (HWND)ConsoleParent->GetHWND());
+		//Win->SetParent(ConsoleParent);
+		//if (Win) m_NB[i]->AddPage(Win, wxT("Console"), true, aNormalFile );
+		if (Win) m_NB[i]->AddPage(ConsoleParent, wxT("Console"), true, aNormalFile );
 		#endif
 	}
 	else // hide