Example #1
0
// called from ---CPU--- thread
bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size)
{
	NetWiimote nw;
	static u8 previousSize[4] = { 4, 4, 4, 4 };
	{
		std::lock_guard<std::recursive_mutex> lkp(m_crit.players);

		// in game mapping for this local Wiimote
		unsigned int in_game_num = LocalWiimoteToInGameWiimote(_number);
		// does this local Wiimote map in game?
		if (in_game_num < 4)
		{
			if (previousSize[in_game_num] == size)
			{
				nw.assign(data, data + size);
				do
				{
					// add to buffer
					m_wiimote_buffer[in_game_num].Push(nw);

					SendWiimoteState(in_game_num, nw);
				} while (m_wiimote_buffer[in_game_num].Size() <= m_target_buffer_size * 200 / 120); // TODO: add a seperate setting for wiimote buffer?
			}
			else
			{
				while (m_wiimote_buffer[in_game_num].Size() > 0)
				{
					// Reporting mode changed, so previous buffer is no good.
					m_wiimote_buffer[in_game_num].Pop();
				}
				nw.resize(size, 0);

				m_wiimote_buffer[in_game_num].Push(nw);
				m_wiimote_buffer[in_game_num].Push(nw);
				m_wiimote_buffer[in_game_num].Push(nw);
				m_wiimote_buffer[in_game_num].Push(nw);
				m_wiimote_buffer[in_game_num].Push(nw);
				m_wiimote_buffer[in_game_num].Push(nw);
				previousSize[in_game_num] = size;
			}
		}

	} // unlock players

	while (previousSize[_number] == size && !m_wiimote_buffer[_number].Pop(nw))
	{
		// wait for receiving thread to push some data
		Common::SleepCurrentThread(1);
		if (!m_is_running.load())
			return false;
	}

	// Use a blank input, since we may not have any valid input.
	if (previousSize[_number] != size)
	{
		nw.resize(size, 0);
		m_wiimote_buffer[_number].Push(nw);
		m_wiimote_buffer[_number].Push(nw);
		m_wiimote_buffer[_number].Push(nw);
		m_wiimote_buffer[_number].Push(nw);
		m_wiimote_buffer[_number].Push(nw);
	}

	// We should have used a blank input last time, so now we just need to pop through the old buffer, until we reach a good input
	if (nw.size() != size)
	{
		u8 tries = 0;
		// Clear the buffer and wait for new input, since we probably just changed reporting mode.
		while (nw.size() != size)
		{
			while (!m_wiimote_buffer[_number].Pop(nw))
			{
				Common::SleepCurrentThread(1);
				if (!m_is_running.load())
					return false;
			}
			++tries;
			if (tries > m_target_buffer_size * 200 / 120)
				break;
		}

		// If it still mismatches, it surely desynced
		if (size != nw.size())
		{
			PanicAlertT("Netplay has desynced. There is no way to recover from this.");
			return false;
		}
	}

	previousSize[_number] = size;
	memcpy(data, nw.data(), size);
	return true;
}
Example #2
0
// called from ---CPU--- thread
bool NetPlayClient::WiimoteUpdate(int _number, u8* data, const u8 size, u8 reporting_mode)
{
  NetWiimote nw;
  {
    std::lock_guard<std::recursive_mutex> lkp(m_crit.players);

    // Only send data, if this Wiimote is mapped to this player
    if (m_wiimote_map[_number] == m_local_player->pid)
    {
      nw.assign(data, data + size);
      do
      {
        // add to buffer
        m_wiimote_buffer[_number].Push(nw);

        SendWiimoteState(_number, nw);
      } while (m_wiimote_buffer[_number].Size() <=
               m_target_buffer_size * 200 /
                   120);  // TODO: add a seperate setting for wiimote buffer?
    }

  }  // unlock players

  while (m_wiimote_buffer[_number].Size() == 0)
  {
    if (!m_is_running.IsSet())
    {
      return false;
    }

    // wait for receiving thread to push some data
    m_wii_pad_event.Wait();
  }

  m_wiimote_buffer[_number].Pop(nw);

  // If the reporting mode has changed, we just need to pop through the buffer,
  // until we reach a good input
  if (nw[1] != reporting_mode)
  {
    u32 tries = 0;
    while (nw[1] != reporting_mode)
    {
      while (m_wiimote_buffer[_number].Size() == 0)
      {
        if (!m_is_running.IsSet())
        {
          return false;
        }

        // wait for receiving thread to push some data
        m_wii_pad_event.Wait();
      }

      m_wiimote_buffer[_number].Pop(nw);

      ++tries;
      if (tries > m_target_buffer_size * 200 / 120)
        break;
    }

    // If it still mismatches, it surely desynced
    if (nw[1] != reporting_mode)
    {
      PanicAlertT("Netplay has desynced. There is no way to recover from this.");
      return false;
    }
  }

  memcpy(data, nw.data(), size);
  return true;
}