1) I fixed the emulated Nunchuck in Zelda - TP, however I chose the minimum workable delay time that worked in my PC, in fact it's so short that the Nunchuck still fails sometimes. If you have a very fast PC or something like that so that the Nunchuck still don't work please let me know.

2) I also made the Wiimote work after Stop and Start

3) I changed /Dev/USB to initialize the emulated Wiimote directly after ScanEnable, not wait for any countdown

git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@1814 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
John Peterson
2009-01-07 02:59:19 +00:00
parent 6125efabb1
commit fa27a97fbb
30 changed files with 1346 additions and 893 deletions

View File

@ -121,6 +121,10 @@ bool CBoot::LoadMapFromFilename(const std::string &_rFilename, const char *_game
return success;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Load a GC or Wii BIOS file
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool CBoot::Load_BIOS(const std::string& _rBiosFilename)
{
bool bResult = false;
@ -129,6 +133,7 @@ bool CBoot::Load_BIOS(const std::string& _rBiosFilename)
{
if (pFile->GetSize() >= 1024*1024*2)
{
// Write it to memory
u32 CopySize = (u32)pFile->GetSize() - 0x820;
u8* pData = pFile->Lock(0x820, CopySize);
Memory::WriteBigEData(pData, 0x81300000, CopySize);
@ -143,7 +148,12 @@ bool CBoot::Load_BIOS(const std::string& _rBiosFilename)
delete pFile;
return bResult;
}
/////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Third boot step after BootManager and Core. See Call schedule in BootManager.cpp
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara)
{
const bool bDebugIsoBootup = false;
@ -188,6 +198,7 @@ bool CBoot::BootUp(const SCoreStartupParameter& _StartupPara)
}
else
{
// If we can't load the BIOS file we use the HLE BIOS instead
if (!Load_BIOS(_StartupPara.m_strBios))
{
// fails to load a BIOS so HLE it

View File

@ -41,7 +41,9 @@ void CBoot::RunFunction(u32 _iAddr)
PowerPC::SingleStep();
}
// BIOS HLE:
// __________________________________________________________________________________________________
//
// GameCube BIOS HLE:
// copy the apploader to 0x81200000
// execute the apploader, function by function, using the above utility.
void CBoot::EmulatedBIOS(bool _bDebug)
@ -159,7 +161,7 @@ void CBoot::EmulatedBIOS(bool _bDebug)
// __________________________________________________________________________________________________
//
// BIOS HLE:
// Wii BIOS HLE:
// copy the apploader to 0x81200000
// execute the apploader
//
@ -167,6 +169,7 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
{
LOG(BOOT, "Faking Wii BIOS...");
// See if we have a memory dump to boot
FILE* pDump = fopen(FULL_WII_SYS_DIR "dump_0x0000_0x4000.bin", "rb");
if (pDump != NULL)
{
@ -301,10 +304,11 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
after this check during booting. */
VolumeHandler::ReadToPtr(Memory::GetPointer(0x3180), 0, 4);
Memory::Write_U8(0x80, 0x00003184);
// ================
}
}
// apploader
// Execute the apploader
if (VolumeHandler::IsValid() && VolumeHandler::IsWii())
{
UReg_MSR& m_MSR = ((UReg_MSR&)PowerPC::ppcState.msr);
@ -345,12 +349,16 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
u32 iAppLoaderClose = Memory::ReadUnchecked_U32(iAppLoaderFuncAddr+8);
// iAppLoaderInit
LOG(BOOT, "Call iAppLoaderInit");
LOG(BOOT, "Run iAppLoaderInit");
PowerPC::ppcState.gpr[3] = 0x81300000;
RunFunction(iAppLoaderInit);
// iAppLoaderMain
LOG(BOOT, "Call iAppLoaderMain");
/* Let the apploader load the exe to memory. At this point I get an unknwon IPC command
(command zero) when I load Wii Sports or other games a second time. I don't notice
any side effects however. It's a little disconcerning however that Start after Stop
behaves differently than the first Start after starting Dolphin. It means something
was not reset correctly. */
LOG(BOOT, "Run iAppLoaderMain");
do
{
PowerPC::ppcState.gpr[3] = 0x81300004;
@ -368,7 +376,7 @@ bool CBoot::EmulatedBIOS_Wii(bool _bDebug)
} while(PowerPC::ppcState.gpr[3] != 0x00);
// iAppLoaderClose
LOG(BOOT, "call iAppLoaderClose");
LOG(BOOT, "Run iAppLoaderClose");
RunFunction(iAppLoaderClose);
// Load patches and run startup patches

View File

@ -94,7 +94,6 @@ void Callback_WiimoteInput(u16 _channelID, const void* _pData, u32 _Size);
// For keyboard shortcuts.
void Callback_KeyPress(int key, bool shift, bool control);
TPeekMessages Callback_PeekMessages = NULL;
TUpdateFPSDisplay g_pUpdateFPSDisplay = NULL;
@ -106,6 +105,7 @@ TUpdateFPSDisplay g_pUpdateFPSDisplay = NULL;
void Stop();
bool g_bHwInit = false;
bool g_bRealWiimote = false;
HWND g_pWindowHandle = NULL;
Common::Thread* g_pThread = NULL;
@ -115,13 +115,50 @@ Common::Event emuThreadGoing;
//////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// Display messages and return values
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool PanicAlertToVideo(const char* text, bool yes_no)
{
DisplayMessage(text, 3000);
return true;
}
// Called from GUI thread
void DisplayMessage(const std::string &message, int time_in_ms)
{
PluginVideo::Video_AddMessage(message.c_str(), time_in_ms);
}
void DisplayMessage(const char *message, int time_in_ms)
{
PluginVideo::Video_AddMessage(message, time_in_ms);
}
void Callback_DebuggerBreak()
{
CCPU::EnableStepping(true);
}
const SCoreStartupParameter& GetStartupParameter()
{
return g_CoreStartupParameter;
}
void* GetWindowHandle()
{
return g_pWindowHandle;
}
bool GetRealWiimote()
{
return g_bRealWiimote;
}
/////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// This is called from the GUI thread. See the booting call schedule in BootManager.cpp
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool Init(const SCoreStartupParameter _CoreParameter)
{
if (g_pThread != NULL) {
@ -153,6 +190,7 @@ bool Init(const SCoreStartupParameter _CoreParameter)
emuThreadGoing.Init();
// This will execute EmuThread() further down in this file
g_pThread = new Common::Thread(EmuThread, (void*)&g_CoreStartupParameter);
emuThreadGoing.Wait();
@ -168,16 +206,6 @@ bool Init(const SCoreStartupParameter _CoreParameter)
return true;
}
void DisplayMessage(const std::string &message, int time_in_ms)
{
PluginVideo::Video_AddMessage(message.c_str(), time_in_ms);
}
void DisplayMessage(const char *message, int time_in_ms)
{
PluginVideo::Video_AddMessage(message, time_in_ms);
}
// Called from GUI thread or VI thread
void Stop() // - Hammertime!
@ -213,21 +241,6 @@ void Stop() // - Hammertime!
Host_SetWaitCursor(false);
}
void Callback_DebuggerBreak()
{
CCPU::EnableStepping(true);
}
const SCoreStartupParameter& GetStartupParameter()
{
return g_CoreStartupParameter;
}
void* GetWindowHandle()
{
return g_pWindowHandle;
}
//////////////////////////////////////////////////////////////////////////////////////////
// Create the CPU thread
@ -280,7 +293,7 @@ THREAD_RETURN CpuThread(void *pArg)
//////////////////////////////////////////////////////////////////////////////////////////
// Initalize plugins and create emulation thread
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
/* Call browser: Init():g_pThread(). See the BootManager.cpp file description for a completel
/* Call browser: Init():g_pThread(). See the BootManager.cpp file description for a complete
call schedule. */
THREAD_RETURN EmuThread(void *pArg)
{
@ -348,7 +361,8 @@ THREAD_RETURN EmuThread(void *pArg)
WiimoteInitialize.hWnd = g_pWindowHandle;
WiimoteInitialize.pLog = Callback_WiimoteLog;
WiimoteInitialize.pWiimoteInput = Callback_WiimoteInput;
PluginWiimote::Wiimote_Initialize(WiimoteInitialize);
// Wait for Wiiuse to find the number of connected Wiimotes
g_bRealWiimote = PluginWiimote::Wiimote_Initialize(WiimoteInitialize);
}
// The hardware is initialized.

View File

@ -51,13 +51,14 @@ namespace Core
void SaveState();
void LoadState();
// get core parameters
// Get core parameters
extern SCoreStartupParameter g_CoreStartupParameter; //uck
const SCoreStartupParameter& GetStartupParameter();
// make a screen shot
// Make a screen shot
bool MakeScreenshot(const std::string& _rFilename);
void* GetWindowHandle();
bool GetRealWiimote();
extern bool bReadTrace;
extern bool bWriteTrace;

View File

@ -15,6 +15,51 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
/////////////////////////////////////////////////////////////////////////////
// File description: This file control all system timers
/* -------------
"Time" is measured in frames, not time: These update frequencies are determined by the passage
of frames. So if a game runs slow, on a slow computer for example, these updates will occur
less frequently. This makes sense because almost all console games are controlled by frames
rather than time, so if a game can't keep up with the normal framerate all animations and
actions slows down and the game runs to slow. This is different from PC games that are are
often controlled by time instead and may not have maximum framerates.
However, I'm not sure if the Bluetooth communication for the Wiimote is entirely frame
dependent, the timing problems with the ack command in Zelda - TP may be related to
time rather than frames? For now the IPC_HLE_PERIOD is frame dependet, but bcause of
different conditions on the way to PluginWiimote::Wiimote_Update() the updates may actually
be time related after all, or not?
I'm not sure about this but the text below seems to assume that 60 fps means that the game
runs in the normal intended speed. In that case an update time of [GetTicksPerSecond() / 60]
would mean one update per frame and [GetTicksPerSecond() / 60] would mean four updates per
frame.
IPC_HLE_PERIOD: For the Wiimote this is the call scedule:
IPC_HLE_UpdateCallback() // In this file
// This function seems to call all devices' Update() function four times per frame
WII_IPC_HLE_Interface::Update()
// If the AclFrameQue is empty this will call Wiimote_Update() and make it send
the current input status to the game. I'm not sure if this occurs approximately
once every frame or if the frequency is not exactly tied to rendered frames
CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
PluginWiimote::Wiimote_Update()
// This is also a device updated by WII_IPC_HLE_Interface::Update() but it doesn't
seem to ultimately call PluginWiimote::Wiimote_Update(). However it can be called
by the /dev/usb/oh1 device if the AclFrameQue is empty.
CWII_IPC_HLE_WiiMote::Update()
//////////////////////////*/
/////////////////////////////////////////////////////////////////////////////
// Inlude
// -------------
#include "Common.h"
#include "../PatchEngine.h"
#include "SystemTimers.h"
@ -32,10 +77,15 @@
#include "../IPC_HLE/WII_IPC_HLE.h"
#include "Thread.h"
#include "Timer.h"
/////////////////////////////
namespace SystemTimers
{
/////////////////////////////////////////////////////////////////////////////
// Declarations and definitions
// -------------
u32 CPU_CORE_CLOCK = 486000000u; // 486 mhz (its not 485, stop bugging me!)
s64 fakeDec;
@ -85,6 +135,8 @@ int
// Once every 2 frame-period should be enough.
// Assuming game's frame-finish-watchdog wait more than 2 emulated frame-period before starting its mess.
FAKE_GP_WATCHDOG_PERIOD = GetTicksPerSecond() / 30;
///////////////////////////////////
u32 GetTicksPerSecond()
{

View File

@ -399,8 +399,11 @@ void ExecuteCommand(u32 _Address)
break;
default:
_dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown Command %i (0x%08x)", Command, _Address);
CCPU::Break();
_dbg_assert_msg_(WII_IPC_HLE, 0, "Unknown IPC Command %i (0x%08x)", Command, _Address);
// Break on the same terms as the _dbg_assert_msg_, if LOGGING was defined
#ifdef LOGGING
CCPU::Break();
#endif
break;
}

View File

@ -15,16 +15,28 @@
// Official SVN repository and contact information can be found at
// http://code.google.com/p/dolphin-emu/
//////////////////////////////////////////////////////////////////////////////////////////
// Include
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
#include "WII_IPC_HLE_Device_usb.h"
#include "../Plugins/Plugin_Wiimote.h"
#include "../Core.h" // Local core functions
#include "../Debugger/Debugger_SymbolMap.h"
#include "../Host.h"
#include "../../../../Branches/MusicMod/Common/Src/Console.h"
///////////////////////
// ugly hacks for "SendEventNumberOfCompletedPackets"
// Ugly hacks for "SendEventNumberOfCompletedPackets"
int g_HCICount = 0;
int g_GlobalHandle = 0;
//////////////////////////////////////////////////////////////////////////////////////////
// The device class
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _DeviceID, const std::string& _rDeviceName)
: IWII_IPC_HLE_Device(_DeviceID, _rDeviceName)
, m_PINType(0)
@ -58,6 +70,7 @@ CWII_IPC_HLE_Device_usb_oh1_57e_305::CWII_IPC_HLE_Device_usb_oh1_57e_305(u32 _De
CWII_IPC_HLE_Device_usb_oh1_57e_305::~CWII_IPC_HLE_Device_usb_oh1_57e_305()
{}
///////////////////////////
// ===================================================
@ -290,7 +303,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::SendACLFrame(u16 _ConnectionHandle, u8
// ===================================================
/* This is called from WII_IPC_HLE_Interface::Update() */
/* See IPC_HLE_PERIOD in SystemTimers.cpp for a documentation of this update. */
// ----------------
u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
{
@ -387,19 +400,27 @@ u32 CWII_IPC_HLE_Device_usb_oh1_57e_305::Update()
before we initiate the connection. To avoid doing this for GC games we also
want m_LocalName from CommandWriteLocalName() to be "Wii".
FiRES: TODO find a good solution to do this */
FiRES: TODO find a good solution to do this
JP: Solution to what? When to run SendEventRequestConnection()?
*/
// -------------------------
static bool test = true;
// Why do we need this? 0 worked with the emulated wiimote in all games I tried
static int counter = 1000;
/* I disabled this and disable m_ScanEnable instead to avoid running SendEventRequestConnection()
again. */
//static bool test = true;
if (test && !strcasecmp(m_LocalName, "Wii") && (m_ScanEnable & 0x2))
/* Why do we need this? 0 worked with the emulated wiimote in all games I tried. Do we have to
wait for wiiuse_init() and wiiuse_find() for a real Wiimote here? I'm testing
this new method of not waiting at all if there are no real Wiimotes. Please let me know
if it doesn't work. */
static int counter = (Core::GetRealWiimote() ? 1000 : 0);
if (!strcasecmp(m_LocalName, "Wii") && (m_ScanEnable & 0x2))
{
counter--;
if (counter < 0)
{
test = false;
//test = false;
for (size_t i=0; i < m_WiiMotes.size(); i++)
{
if (m_WiiMotes[i].EventPagingChanged(2))
@ -564,8 +585,15 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRemoteNameReq(bdaddr_t _bd)
return true;
}
/////////////////////////////////////////////////////////////
/* This is called from Update() after ScanEnable has been enabled. */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection(CWII_IPC_HLE_WiiMote& _rWiiMote)
{
// We have to disable scan now to avoid running this function over and over again
m_ScanEnable = 0;
SQueuedEvent Event(sizeof(SHCIEventRequestConnection), 0);
SHCIEventRequestConnection* pEventRequestConnection = (SHCIEventRequestConnection*)Event.m_buffer;
@ -601,6 +629,8 @@ bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestConnection(CWII_IPC_HL
return true;
};
//////////////////////////////
bool CWII_IPC_HLE_Device_usb_oh1_57e_305::SendEventRequestLinkKey(bdaddr_t _bd)
{
@ -1377,7 +1407,9 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWritePageTimeOut(u8* _Input)
}
/////////////////////////////////////////////////////////////
/* This will enable ScanEnable so that Update() can start the Wiimote. */
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteScanEnable(u8* _Input)
{
// Command parameters
@ -1404,7 +1436,7 @@ void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteScanEnable(u8* _Input)
SendEventCommandComplete(HCI_CMD_WRITE_SCAN_ENABLE, &Reply, sizeof(hci_write_scan_enable_rp));
}
/////////////////////////////
void CWII_IPC_HLE_Device_usb_oh1_57e_305::CommandWriteInquiryMode(u8* _Input)

View File

@ -29,7 +29,7 @@ void UnloadPlugin();
// Function Types
typedef void (__cdecl* TGetDllInfo)(PLUGIN_INFO*);
typedef void (__cdecl* TDllConfig)(HWND);
typedef void (__cdecl* TWiimote_Initialize)(SWiimoteInitialize);
typedef bool (__cdecl* TWiimote_Initialize)(SWiimoteInitialize);
typedef void (__cdecl* TWiimote_Shutdown)();
typedef void (__cdecl* TWiimote_Update)();
typedef void (__cdecl* TWiimote_Output)(u16 _channelID, const void* _pData, u32 _Size);