diff --git a/Source/Core/Core/Src/CoreParameter.cpp b/Source/Core/Core/Src/CoreParameter.cpp
index 5c4a0f6d8b..73718ab962 100644
--- a/Source/Core/Core/Src/CoreParameter.cpp
+++ b/Source/Core/Core/Src/CoreParameter.cpp
@@ -36,6 +36,7 @@ void SCoreStartupParameter::LoadDefaults()
 	bRunCompareServer = false;
 	bLockThreads = true;
 	bWii = false;
+	SelectedLanguage = 0;
 }
 
 
diff --git a/Source/Core/Core/Src/CoreParameter.h b/Source/Core/Core/Src/CoreParameter.h
index 3d78790bb8..f82cdcc63b 100644
--- a/Source/Core/Core/Src/CoreParameter.h
+++ b/Source/Core/Core/Src/CoreParameter.h
@@ -46,6 +46,7 @@ struct SCoreStartupParameter
 
 	bool bRunCompareServer;
 	bool bRunCompareClient;
+	int  SelectedLanguage;
 
 	bool bWii;
 
diff --git a/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp b/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp
index 3db54a5a2b..d6237e19b1 100644
--- a/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp
+++ b/Source/Core/Core/Src/HW/EXI_DeviceIPL.cpp
@@ -108,6 +108,8 @@ CEXIIPL::CEXIIPL() :
     {
         memcpy(m_SRAM, sram_dump, sizeof(m_SRAM));
     }
+    // We Overwrite it here since it's possible on the GC to change the language as you please
+    m_SRAM[0x12] = Core::GetStartupParameter().SelectedLanguage;
 
 	WriteProtectMemory(m_pIPL, ROM_SIZE);
 	m_uAddress = 0;		
diff --git a/Source/Core/DolphinWX/Src/Config.cpp b/Source/Core/DolphinWX/Src/Config.cpp
index cccd1f97a4..87fdd0f0d5 100644
--- a/Source/Core/DolphinWX/Src/Config.cpp
+++ b/Source/Core/DolphinWX/Src/Config.cpp
@@ -72,6 +72,7 @@ void SConfig::SaveSettings()
 		ini.Set("Core", "DefaultGCM",     m_LocalCoreStartupParameter.m_strDefaultGCM);
 		ini.Set("Core", "DVDRoot",        m_LocalCoreStartupParameter.m_strDVDRoot);
 		ini.Set("Core", "OptimizeQuantizers", m_LocalCoreStartupParameter.bOptimizeQuantizers);
+		ini.Set("Core", "SelectedLanguage", m_LocalCoreStartupParameter.SelectedLanguage);
 	}
 
 	ini.Save("Dolphin.ini");
@@ -125,5 +126,6 @@ void SConfig::LoadSettings()
 		ini.Get("Core", "DefaultGCM",  &m_LocalCoreStartupParameter.m_strDefaultGCM);
 		ini.Get("Core", "DVDRoot",     &m_LocalCoreStartupParameter.m_strDVDRoot);
 		ini.Get("Core", "OptimizeQuantizers", &m_LocalCoreStartupParameter.bOptimizeQuantizers, true);
+		ini.Get("Core", "SelectedLanguage", &m_LocalCoreStartupParameter.SelectedLanguage, 0);
 	}
 }
diff --git a/Source/Core/DolphinWX/Src/ConfigMain.cpp b/Source/Core/DolphinWX/Src/ConfigMain.cpp
index ad53060325..5fa554aa3f 100644
--- a/Source/Core/DolphinWX/Src/ConfigMain.cpp
+++ b/Source/Core/DolphinWX/Src/ConfigMain.cpp
@@ -118,6 +118,7 @@ void CConfigMain::CreateGUIControls()
 	arrayStringFor_ConsoleLang.Add(wxT("Dutch"));
 	ConsoleLangText = new wxStaticText(GeneralPage, ID_CONSOLELANG_TEXT, wxT("Console Language:"), wxDefaultPosition, wxDefaultSize);
 	ConsoleLang = new wxChoice(GeneralPage, ID_CONSOLELANG, wxDefaultPosition, wxDefaultSize, arrayStringFor_ConsoleLang, 0, wxDefaultValidator);
+	ConsoleLang->SetSelection(SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage);
 
 	sGeneral = new wxGridBagSizer(0, 0);
 	sGeneral->Add(AllwaysHLEBIOS, wxGBPosition(0, 0), wxGBSpan(1, 2), wxALL, 5);
@@ -277,6 +278,7 @@ void CConfigMain::SkipIdleCheck(wxCommandEvent& WXUNUSED (event))
 
 void CConfigMain::ConsoleLangChanged(wxCommandEvent& WXUNUSED (event))
 {
+	SConfig::GetInstance().m_LocalCoreStartupParameter.SelectedLanguage = ConsoleLang->GetSelection();
 }
 
 void CConfigMain::DefaultISOChanged(wxFileDirPickerEvent& WXUNUSED (event))
diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript b/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript
index 4e216304cd..90678565ab 100644
--- a/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript
+++ b/Source/Plugins/Plugin_Wiimote_Test/Src/SConscript
@@ -15,7 +15,7 @@ files = [
 padenv = env.Clone()
 padenv.Append(
 	CXXFLAGS = [ '-fPIC' ],
-	LIBS = [ 'common' ],
+	LIBS = [ 'common', 'cwiid' ],
 	)
 padenv.SharedLibrary(output, files)
 
diff --git a/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote_Test.cpp b/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote_Test.cpp
index 84c6f1642a..55e84d0980 100644
--- a/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote_Test.cpp
+++ b/Source/Plugins/Plugin_Wiimote_Test/Src/Wiimote_Test.cpp
@@ -6,6 +6,15 @@
 #include "pluginspecs_wiimote.h"
 
 #include "wiimote_hid.h"
+#ifndef _WIN32
+#include <cwiid.h>
+cwiid_wiimote_t *WiiMote;
+bdaddr_t BTAddress;
+cwiid_mesg_callback_t cwiid_callback;
+struct acc_cal wm_cal, nc_cal;
+uint8_t a_x, a_y, a_z;
+bool ButtonA = false;
+#endif
 
 SWiimoteInitialize g_WiimoteInitialize;
 #define VERSION_STRING "0.1"
@@ -153,7 +162,83 @@ extern "C" void DllAbout(HWND _hParent)
 extern "C" void DllConfig(HWND _hParent)
 {
 }
+#ifndef _WIN32
+#define LBLVAL_LEN 6
+void cwiid_acc(struct cwiid_acc_mesg *mesg)
+{
 
+	a_x = mesg->acc[CWIID_X];
+	a_y = mesg->acc[CWIID_Y];
+	a_z = mesg->acc[CWIID_Z];
+	//printf("%d %d %d %f\n", a_x,a_y,a_z,a);
+}
+void cwiid_btn(struct cwiid_btn_mesg *mesg)
+{
+	ButtonA = mesg->buttons & CWIID_BTN_A;
+	printf("Button A is %d\n",ButtonA);
+}
+#define BATTERY_STR_LEN	14	/* "Battery: 100%" + '\0' */
+void cwiid_callback(cwiid_wiimote_t *wiimote, int mesg_count,
+                    union cwiid_mesg mesg_array[], struct timespec *timestamp)
+{
+	int i;
+	char battery[BATTERY_STR_LEN];
+	char *ext_str;
+	static enum cwiid_ext_type ext_type = CWIID_EXT_NONE;
+
+	for (i=0; i < mesg_count; i++) {
+		switch (mesg_array[i].type) {
+		case CWIID_MESG_STATUS:
+			snprintf(battery, BATTERY_STR_LEN,"Battery:%d%%",
+			         (int) (100.0 * mesg_array[i].status_mesg.battery /
+			                CWIID_BATTERY_MAX));
+			switch (mesg_array[i].status_mesg.ext_type) {
+			case CWIID_EXT_NONE:
+				ext_str = "No extension";
+				break;
+			case CWIID_EXT_NUNCHUK:
+				ext_str = "Nunchuk";
+				if (ext_type != CWIID_EXT_NUNCHUK) {
+					if (cwiid_get_acc_cal(wiimote, CWIID_EXT_NUNCHUK,
+					                      &nc_cal)) {
+						LOG(WIIMOTE, "Unable to retrieve Nunchuk accelerometer calibration");
+					}
+				}
+				break;
+			case CWIID_EXT_CLASSIC:
+				ext_str = "Classic controller";
+				break;
+			case CWIID_EXT_UNKNOWN:
+				ext_str = "Unknown extension";
+				break;
+			}
+			ext_type = mesg_array[i].status_mesg.ext_type;
+			break;
+		case CWIID_MESG_BTN:
+			cwiid_btn(&mesg_array[i].btn_mesg);
+			break;
+		case CWIID_MESG_ACC:
+			cwiid_acc(&mesg_array[i].acc_mesg);
+			break;
+		/*case CWIID_MESG_IR:
+			cwiid_ir(&mesg_array[i].ir_mesg);
+			break;
+		case CWIID_MESG_NUNCHUK:
+			cwiid_nunchuk(&mesg_array[i].nunchuk_mesg);
+			break;
+		case CWIID_MESG_CLASSIC:
+			cwiid_classic(&mesg_array[i].classic_mesg);
+			break;*/
+		case CWIID_MESG_ERROR:
+			printf("Error, Disconnecting\n");
+			break;
+		default:
+			printf("Unknown Message %d\n", mesg_array[i].type);
+			break;
+		}
+	}
+}
+#endif
 
 extern "C" void Wiimote_Initialize(SWiimoteInitialize _WiimoteInitialize)
 {
@@ -162,6 +247,17 @@ extern "C" void Wiimote_Initialize(SWiimoteInitialize _WiimoteInitialize)
 	memset(g_Eeprom, 0, WIIMOTE_EEPROM_SIZE);
 	memcpy(g_Eeprom, EepromData_0, sizeof(EepromData_0));
 	memcpy(g_Eeprom + 0x16D0, EepromData_16D0, sizeof(EepromData_16D0));
+	#ifndef _WIN32
+	//Todo: More Error Checking
+		//WiiMote = cwiid_open(&BTAddress, CWIID_FLAG_MESG_IFC);
+		if(!WiiMote)
+			printf( "Couldn't Connect to WiiMote");
+		else{
+			cwiid_set_mesg_callback(WiiMote, &cwiid_callback);
+			cwiid_get_acc_cal(WiiMote, CWIID_EXT_NONE, &wm_cal);
+			cwiid_request_status(WiiMote);
+		}
+	#endif
 
 	g_ReportingMode = 0;
 }
@@ -172,6 +268,10 @@ extern "C" void Wiimote_DoState(void* ptr, int mode) {
 
 extern "C" void Wiimote_Shutdown(void) 
 {
+	#ifdef _WIN32
+		if(!cwiid_disconnect(WiiMote))
+			LOG(WIIMOTE,"Couldn't close WiiMote!\n");
+	#endif
 }
 
 extern "C" void Wiimote_Output(const void* _pData, u32 _Size) {
@@ -202,6 +302,15 @@ extern "C" void Wiimote_Output(const void* _pData, u32 _Size) {
 
 extern "C" void Wiimote_Update() {
 	//LOG(WIIMOTE, "Wiimote_Update");
+#ifndef _WIN32
+	uint8_t rpt_mode;
+	
+	rpt_mode = CWIID_RPT_STATUS | CWIID_RPT_BTN | CWIID_RPT_ACC;
+	if(g_ReportingMode == 0x33)
+		rpt_mode |= CWIID_RPT_IR;
+	if (cwiid_set_rpt_mode(WiiMote, rpt_mode))
+		printf("Error setting Mode\n");
+#endif
 	switch(g_ReportingMode) {
 	case 0:
 		break;
@@ -256,7 +365,22 @@ void WmLeds(wm_leds* leds) {
 	LOG(WIIMOTE, " Set LEDs");
 	LOG(WIIMOTE, "  Leds: %x", leds->leds);
 	LOG(WIIMOTE, "  Rumble: %x", leds->rumble);
-
+	#ifndef _WIN32
+	uint8_t LED_state;
+	printf("%d %d %d %d\n", leds->leds & 0x10, leds->leds & 0x20, leds->leds & 0x30, leds->leds & 0x40);
+	if (WiiMote) {
+		LED_state =
+			(leds->leds & 0x10
+		    ? CWIID_LED1_ON : 0) |
+		  (leds->leds & 0x20
+		    ? CWIID_LED2_ON : 0) |
+		  (leds->leds & 0x30
+		    ? CWIID_LED3_ON : 0) |
+		  (leds->leds & 0x40
+		    ? CWIID_LED4_ON : 0);
+		cwiid_set_led(WiiMote, LED_state);
+	}
+	#endif
 	g_Leds = leds->leds;
 }
 
@@ -284,10 +408,16 @@ void SendReportCoreAccelIr12() {
 	Offset += sizeof(wm_report_core_accel_ir12);
 	memset(pReport, 0, sizeof(wm_report_core_accel_ir12));
 	memset(pReport->ir, 0xFF, sizeof(pReport->ir));
-
+	#ifndef _WIN32
+	pReport->a.x = a_x;
+	pReport->a.y = a_y;
+	pReport->a.z = a_z;
+	pReport->c.a = ButtonA;
+	#else
 	pReport->a.x = 0x81;
 	pReport->a.y = 0x78;
 	pReport->a.z = 0xD9;
+	#endif
 
 	int x0, y0, x1, y1;
 
@@ -342,10 +472,17 @@ void SendReportCoreAccel() {
 	wm_report_core_accel* pReport = (wm_report_core_accel*)(DataFrame + Offset);
 	Offset += sizeof(wm_report_core_accel);
 	memset(pReport, 0, sizeof(wm_report_core_accel));
+	#ifndef _WIN32
+	pReport->a.x = a_x;
+	pReport->a.y = a_y;
+	pReport->a.z = a_z;
+	pReport->c.a = ButtonA;
+	#else
 	pReport->c.a = 1;
 	pReport->a.x = 0x82;
 	pReport->a.y = 0x75;
 	pReport->a.z = 0xD6;
+	#endif
 
 	LOG(WIIMOTE, "  SendReportCoreAccel()");