Lots more work on making the frame aui stuff functional.
[dolphin.git] / Source / Plugins / Plugin_Wiimote / Src / main.cpp
blob88f7b098b78cea4c831c0c9c8a6a8b178c5536ad
1 // Copyright (C) 2003 Dolphin Project.
3 // This program is free software: you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation, version 2.0.
7 // This program is distributed in the hope that it will be useful,
8 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 // GNU General Public License 2.0 for more details.
12 // A copy of the GPL 2.0 should have been included with the program.
13 // If not, see http://www.gnu.org/licenses/
15 // Official SVN repository and contact information can be found at
16 // http://code.google.com/p/dolphin-emu/
19 #include "Common.h" // Common
20 #include "LogManager.h"
21 #include "StringUtil.h"
22 #include "Timer.h"
24 #define EXCLUDEMAIN_H // Avoid certain declarations in main.h
25 #include "EmuDefinitions.h" // Local
26 #include "wiimote_hid.h"
27 #include "main.h"
28 #if defined(HAVE_WX) && HAVE_WX
29 #include "ConfigPadDlg.h"
30 #include "ConfigBasicDlg.h"
32 WiimotePadConfigDialog *m_PadConfigFrame = NULL;
33 WiimoteBasicConfigDialog *m_BasicConfigFrame = NULL;
34 #endif
35 #include "Config.h"
36 #include "pluginspecs_wiimote.h"
37 #include "EmuMain.h"
38 #if HAVE_WIIUSE
39 #include "wiimote_real.h"
40 #endif
42 #if defined(HAVE_X11) && HAVE_X11
43 Display* WMdisplay = NULL;
44 #endif
45 SWiimoteInitialize g_WiimoteInitialize;
46 PLUGIN_GLOBALS* globals = NULL;
48 // General
49 bool g_EmulatorRunning = false;
50 u32 g_ISOId = 0;
51 bool g_SearchDeviceDone = false;
52 bool g_RealWiiMotePresent = false;
54 // Debugging
55 bool g_DebugAccelerometer = false;
56 bool g_DebugData = false;
57 bool g_DebugComm = false;
58 bool g_DebugSoundData = false;
59 bool g_DebugCustom = false;
61 // Update speed
62 int g_UpdateCounter = 0;
63 double g_UpdateTime = 0;
64 int g_UpdateRate = 0;
65 int g_UpdateWriteScreen = 0;
66 std::vector<int> g_UpdateTimeList (5, 0);
68 // Movement recording
69 std::vector<SRecordingAll> VRecording(RECORDING_ROWS);
71 PLUGIN_EMUSTATE g_EmulatorState = PLUGIN_EMUSTATE_STOP;
73 // Standard crap to make wxWidgets happy
74 #ifdef _WIN32
75 HINSTANCE g_hInstance;
77 #if defined(HAVE_WX) && HAVE_WX
78 class wxDLLApp : public wxApp
80 bool OnInit()
82 return true;
85 IMPLEMENT_APP_NO_MAIN(wxDLLApp)
86 WXDLLIMPEXP_BASE void wxSetInstance(HINSTANCE hInst);
87 #endif
89 BOOL APIENTRY DllMain(HINSTANCE hinstDLL, // DLL module handle
90 DWORD dwReason, // reason called
91 LPVOID lpvReserved) // reserved
93 switch (dwReason)
95 case DLL_PROCESS_ATTACH:
97 #if defined(HAVE_WX) && HAVE_WX
98 wxSetInstance((HINSTANCE)hinstDLL);
99 wxInitialize();
100 #endif
102 break;
104 case DLL_PROCESS_DETACH:
106 #if defined(HAVE_WX) && HAVE_WX
107 wxUninitialize();
108 #endif
110 break;
113 g_hInstance = hinstDLL;
114 return TRUE;
116 #endif
118 #if defined(HAVE_WX) && HAVE_WX
119 wxWindow* GetParentedWxWindow(HWND Parent)
121 #ifdef _WIN32
122 wxSetInstance((HINSTANCE)g_hInstance);
123 #endif
124 wxWindow *win = new wxWindow();
125 #ifdef _WIN32
126 win->SetHWND((WXHWND)Parent);
127 win->AdoptAttributesFromHWND();
128 #endif
129 return win;
131 #endif
133 // Exports
134 void GetDllInfo(PLUGIN_INFO* _PluginInfo)
136 _PluginInfo->Version = 0x0100;
137 _PluginInfo->Type = PLUGIN_TYPE_WIIMOTE;
138 #ifdef DEBUGFAST
139 sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin (DebugFast)");
140 #else
141 #ifndef _DEBUG
142 sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin");
143 #else
144 sprintf(_PluginInfo->Name, "Dolphin Wiimote Plugin (Debug)");
145 #endif
146 #endif
149 void SetDllGlobals(PLUGIN_GLOBALS* _pPluginGlobals)
151 globals = _pPluginGlobals;
152 LogManager::SetInstance((LogManager *)globals->logManager);
155 void *DllDebugger(void *_hParent, bool Show)
157 return NULL;
160 void DllConfig(HWND _hParent)
162 #ifdef _WIN32
163 if (WiiMoteReal::g_AutoPairUpInvisibleWindow == NULL)
165 WiiMoteReal::g_AutoPairUpInvisibleWindow = new Common::Thread(WiiMoteReal::RunInvisibleMessageWindow_ThreadFunc, NULL);
166 WiiMoteReal::g_AutoPairUpMonitoring = new Common::Thread(WiiMoteReal::PairUp_ThreadFunc, NULL);
168 #endif
169 if (!g_SearchDeviceDone)
171 // Load settings
172 g_Config.Load();
173 // We do a pad search before creating the dialog
174 WiiMoteEmu::Search_Devices(WiiMoteEmu::joyinfo, WiiMoteEmu::NumPads, WiiMoteEmu::NumGoodPads);
175 g_SearchDeviceDone = true;
179 #if defined(HAVE_WX) && HAVE_WX
180 wxWindow *frame = GetParentedWxWindow(_hParent);
181 m_BasicConfigFrame = new WiimoteBasicConfigDialog(frame);
182 #ifdef _WIN32
183 frame->Disable();
184 m_BasicConfigFrame->ShowModal();
185 frame->Enable();
186 #else
187 m_BasicConfigFrame->ShowModal();
188 #endif
190 #ifdef _WIN32
191 frame->SetFocus();
192 frame->SetHWND(NULL);
193 #endif
195 m_BasicConfigFrame->Destroy();
196 m_BasicConfigFrame = NULL;
197 frame->Destroy();
198 #endif
201 // Start emulation
202 void Initialize(void *init)
204 g_EmulatorRunning = true;
205 g_WiimoteInitialize = *(SWiimoteInitialize *)init;
207 #if defined(HAVE_WX) && HAVE_WX
208 // Load the ISO Id
209 g_ISOId = g_WiimoteInitialize.ISOId;
210 // Load the settings
211 g_Config.Load();
212 #endif
213 #if defined(HAVE_X11) && HAVE_X11
214 WMdisplay = XOpenDisplay(NULL);
215 #endif
217 g_ISOId = g_WiimoteInitialize.ISOId;
218 DEBUG_LOG(WIIMOTE, "ISOId: %08x %s", g_WiimoteInitialize.ISOId, Hex2Ascii(g_WiimoteInitialize.ISOId).c_str());
220 // Load IR settings, as this is a per-game setting and the user might have loaded a different game
221 g_Config.LoadIR();
223 // Run this first so that WiiMoteReal::Initialize() overwrites g_Eeprom
224 WiiMoteEmu::Initialize();
226 /* We will run WiiMoteReal::Initialize() even if we are not using a real
227 wiimote, to check if there is a real wiimote connected. We will initiate
228 wiiuse.dll, but we will return before creating a new thread for it if we
229 find no real Wiimotes. Then g_RealWiiMotePresent will also be
230 false. This function call will be done instantly whether there is a real
231 Wiimote connected or not. It takes no time for Wiiuse to check for
232 connected Wiimotes. */
233 #if HAVE_WIIUSE
235 WiiMoteReal::Initialize();
236 WiiMoteReal::Allocate();
237 #ifdef _WIN32
238 if (WiiMoteReal::g_AutoPairUpInvisibleWindow == NULL)
240 WiiMoteReal::g_AutoPairUpInvisibleWindow = new Common::Thread(WiiMoteReal::RunInvisibleMessageWindow_ThreadFunc, NULL);
241 WiiMoteReal::g_AutoPairUpMonitoring = new Common::Thread(WiiMoteReal::PairUp_ThreadFunc, NULL);
243 #endif
244 #endif
247 // If a game is not running this is called by the Configuration window when it's closed
248 void Shutdown(void)
250 // Not running
251 g_EmulatorRunning = false;
253 // Reset the game ID in all cases
254 g_ISOId = 0;
256 #if HAVE_WIIUSE
257 WiiMoteReal::Shutdown();
258 #endif
259 WiiMoteEmu::Shutdown();
261 #if defined(HAVE_X11) && HAVE_X11
262 if (WMdisplay)
263 XCloseDisplay(WMdisplay);
264 #endif
268 void DoState(unsigned char **ptr, int mode)
270 PointerWrap p(ptr, mode);
272 // TODO: Shorten the list
274 //p.Do(g_EmulatorRunning);
275 //p.Do(g_ISOId);
276 //p.Do(g_RealWiiMotePresent);
277 //p.Do(g_RealWiiMoteInitialized);
278 //p.Do(g_EmulatedWiiMoteInitialized);
279 //p.Do(g_UpdateCounter);
280 //p.Do(g_UpdateTime);
281 //p.Do(g_UpdateRate);
282 //p.Do(g_UpdateWriteScreen);
283 //p.Do(g_UpdateTimeList);
285 #if HAVE_WIIUSE
286 WiiMoteReal::DoState(p);
287 #endif
288 WiiMoteEmu::DoState(p);
290 return;
292 void EmuStateChange(PLUGIN_EMUSTATE newState)
294 g_EmulatorState = newState;
297 #if defined(HAVE_WX) && HAVE_WX
298 // Hack to use wx key events
299 volatile bool wxkeystate[WXK_SPECIAL20];
300 #endif
302 // Set buttons status from keyboard input. Currently this is done from
303 // wxWidgets in the main application.
304 // --------------
305 void Wiimote_Input(u16 _Key, u8 _UpDown)
307 #if defined(__APPLE__) && defined(USE_WX) && USE_WX
308 if (_Key < WXK_SPECIAL20)
310 wxkeystate[_Key] = _UpDown;
312 #endif
315 /* This function produce Wiimote Input (reports from the Wiimote) in response
316 to Output from the Wii. It's called from WII_IPC_HLE_WiiMote.cpp.
318 Switch between real and emulated wiimote: We send all this Input to WiiMoteEmu::InterruptChannel()
319 so that it knows the channel ID and the data reporting mode at all times.
321 void Wiimote_InterruptChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
323 // Decide where to send the message
324 if (WiiMoteEmu::WiiMapping[_number].Source <= 1)
325 WiiMoteEmu::InterruptChannel(_number, _channelID, _pData, _Size);
326 #if HAVE_WIIUSE
327 else if (g_RealWiiMotePresent)
328 WiiMoteReal::InterruptChannel(_number, _channelID, _pData, _Size);
329 #endif
333 // Function: Used for the initial Bluetooth HID handshake.
334 void Wiimote_ControlChannel(int _number, u16 _channelID, const void* _pData, u32 _Size)
336 // Debugging
337 #if defined(_DEBUG) || defined(DEBUGFAST)
338 DEBUG_LOG(WIIMOTE, "Wiimote_ControlChannel");
339 DEBUG_LOG(WIIMOTE, " Channel ID: %04x", _channelID);
340 std::string Temp = ArrayToString((const u8*)_pData, _Size);
341 DEBUG_LOG(WIIMOTE, " Data: %s", Temp.c_str());
342 #endif
344 // Check for custom communication
345 if(_channelID == 99 && *(const u8*)_pData == WIIMOTE_DISCONNECT)
347 WiiMoteEmu::g_ReportingAuto[_number] = false;
348 WARN_LOG(WIIMOTE, "Wiimote: #%i Disconnected", _number);
349 #ifdef _WIN32
350 PostMessage(g_WiimoteInitialize.hWnd, WM_USER, WIIMOTE_DISCONNECT, _number);
351 #endif
352 return;
355 if (WiiMoteEmu::WiiMapping[_number].Source <= 1)
356 WiiMoteEmu::ControlChannel(_number, _channelID, _pData, _Size);
357 #if HAVE_WIIUSE
358 else if (g_RealWiiMotePresent)
359 WiiMoteReal::ControlChannel(_number, _channelID, _pData, _Size);
360 #endif
364 // This sends a Data Report from the Wiimote. See SystemTimers.cpp for the documentation of this update.
365 void Wiimote_Update(int _number)
367 // This functions will send:
368 // Emulated Wiimote: Only data reports 0x30-0x37
369 // Real Wiimote: Both data reports 0x30-0x37 and all other read reports
370 if (WiiMoteEmu::WiiMapping[_number].Source <= 1)
371 WiiMoteEmu::Update(_number);
372 #if HAVE_WIIUSE
373 else if (g_RealWiiMotePresent)
374 WiiMoteReal::Update(_number);
375 #endif
378 // Debugging
379 #ifdef _WIN32
380 if( GetAsyncKeyState(VK_HOME) && g_DebugComm ) g_DebugComm = false; // Page Down
381 else if (GetAsyncKeyState(VK_HOME) && !g_DebugComm ) g_DebugComm = true;
383 if( GetAsyncKeyState(VK_PRIOR) && g_DebugData ) g_DebugData = false; // Page Up
384 else if (GetAsyncKeyState(VK_PRIOR) && !g_DebugData ) g_DebugData = true;
386 if( GetAsyncKeyState(VK_NEXT) && g_DebugAccelerometer ) g_DebugAccelerometer = false; // Home
387 else if (GetAsyncKeyState(VK_NEXT) && !g_DebugAccelerometer ) g_DebugAccelerometer = true;
389 if( GetAsyncKeyState(VK_END) && g_DebugCustom ) { g_DebugCustom = false; DEBUG_LOG(WIIMOTE, "Custom Debug: Off");} // End
390 else if (GetAsyncKeyState(VK_END) && !g_DebugCustom ) {g_DebugCustom = true; DEBUG_LOG(WIIMOTE, "Custom Debug: Off");}
391 #endif
396 unsigned int Wiimote_GetAttachedControllers()
398 unsigned int attached = 0;
399 for (unsigned int i=0; i<4; ++i)
400 if (WiiMoteEmu::WiiMapping[i].Source)
401 attached |= (1 << i);
402 return attached;
406 // Unpair Wiimotes, TODO: Add linux/osx un-pair function
407 unsigned int Wiimote_UnPairWiimotes()
409 #ifdef _WIN32
410 if (g_Config.bUnpairRealWiimote)
411 return WiiMoteReal::WiimotePairUp(true);
412 #endif
413 return 0;
416 // Supporting functions
418 // Check if the render window is in focus
420 bool IsFocus()
422 return g_WiimoteInitialize.pRendererHasFocus();
425 /* Returns a timestamp with three decimals for precise time comparisons. The return format is
426 of the form seconds.milleseconds for example 1234.123. The leding seconds have no particular meaning
427 but are just there to enable use to tell if we have entered a new second or now. */
428 // -----------------