Beispiel #1
0
// called from ---CPU--- thread
bool NetPlayClient::GetNetPads(const u8 pad_nb, GCPadStatus* pad_status)
{
	// The interface for this is extremely silly.
	//
	// Imagine a physical device that links three GameCubes together
	// and emulates NetPlay that way. Which GameCube controls which
	// in-game controllers can be configured on the device (m_pad_map)
	// but which sockets on each individual GameCube should be used
	// to control which players? The solution that Dolphin uses is
	// that we hardcode the knowledge that they go in order, so if
	// you have a 3P game with three GameCubes, then every single
	// controller should be plugged into slot 1.
	//
	// If you have a 4P game, then one of the GameCubes will have
	// a controller plugged into slot 1, and another in slot 2.
	//
	// The slot number is the "local" pad number, and what  player
	// it actually means is the "in-game" pad number.
	//
	// The interface here gives us the status of local pads, and
	// expects to get back "in-game" pad numbers back in response.
	// e.g. it asks "here's the input that slot 1 has, and by the
	// way, what's the state of P1?"
	//
	// We should add this split between "in-game" pads and "local"
	// pads higher up.

	int in_game_num = LocalPadToInGamePad(pad_nb);

	// If this in-game pad is one of ours, then update from the
	// information given.
	if (in_game_num < 4)
	{
		// adjust the buffer either up or down
		// inserting multiple padstates or dropping states
		while (m_pad_buffer[in_game_num].Size() <= m_target_buffer_size)
		{
			// add to buffer
			m_pad_buffer[in_game_num].Push(*pad_status);

			// send
			SendPadState(in_game_num, *pad_status);
		}
	}

	// Now, we need to swap out the local value with the values
	// retrieved from NetPlay. This could be the value we pushed
	// above if we're configured as P1 and the code is trying
	// to retrieve data for slot 1.
	while (!m_pad_buffer[pad_nb].Pop(*pad_status))
	{
		if (!m_is_running.load())
			return false;

		// TODO: use a condition instead of sleeping
		Common::SleepCurrentThread(1);
	}

	if (Movie::IsRecordingInput())
	{
		Movie::RecordInput(pad_status, pad_nb);
		Movie::InputUpdate();
	}
	else
	{
		Movie::CheckPadStatus(pad_status, pad_nb);
	}

	return true;
}
Beispiel #2
0
// called from ---CPU--- thread
bool NetPlayClient::GetNetPads(const int pad_nb, GCPadStatus* pad_status)
{
  // The interface for this is extremely silly.
  //
  // Imagine a physical device that links three GameCubes together
  // and emulates NetPlay that way. Which GameCube controls which
  // in-game controllers can be configured on the device (m_pad_map)
  // but which sockets on each individual GameCube should be used
  // to control which players? The solution that Dolphin uses is
  // that we hardcode the knowledge that they go in order, so if
  // you have a 3P game with three GameCubes, then every single
  // controller should be plugged into slot 1.
  //
  // If you have a 4P game, then one of the GameCubes will have
  // a controller plugged into slot 1, and another in slot 2.
  //
  // The slot number is the "local" pad number, and what player
  // it actually means is the "in-game" pad number.

  // When the 1st in-game pad is polled, we assume the others will
  // will be polled as well. To reduce latency, we poll all local
  // controllers at once and then send the status to the other
  // clients.
  if (IsFirstInGamePad(pad_nb))
  {
    const int num_local_pads = NumLocalPads();
    for (int local_pad = 0; local_pad < num_local_pads; local_pad++)
    {
      switch (SConfig::GetInstance().m_SIDevice[local_pad])
      {
      case SIDEVICE_WIIU_ADAPTER:
        *pad_status = GCAdapter::Input(local_pad);
        break;
      case SIDEVICE_GC_CONTROLLER:
      default:
        *pad_status = Pad::GetStatus(local_pad);
        break;
      }

      int ingame_pad = LocalPadToInGamePad(local_pad);

      // adjust the buffer either up or down
      // inserting multiple padstates or dropping states
      while (m_pad_buffer[ingame_pad].Size() <= m_target_buffer_size)
      {
        // add to buffer
        m_pad_buffer[ingame_pad].Push(*pad_status);

        // send
        SendPadState(ingame_pad, *pad_status);
      }
    }
  }

  // Now, we either use the data pushed earlier, or wait for the
  // other clients to send it to us
  while (m_pad_buffer[pad_nb].Size() == 0)
  {
    if (!m_is_running.IsSet())
    {
      return false;
    }

    m_gc_pad_event.Wait();
  }

  m_pad_buffer[pad_nb].Pop(*pad_status);

  if (Movie::IsRecordingInput())
  {
    Movie::RecordInput(pad_status, pad_nb);
    Movie::InputUpdate();
  }
  else
  {
    Movie::CheckPadStatus(pad_status, pad_nb);
  }

  return true;
}