dolphin/Source/Android/jni/Input/EmulatedController.cpp
JosJuice 1b55d7c594 Android: Change how the overlay controller setting works
Up until now, there have been two settings on Android that stored the
selected Wii Remote extension: the normal one that's also used on PC,
and a SharedPreferences one that's used by the overlay controls to
determine what controls to show. It is possible for these two to end up
out of sync, and my input changes have made that more likely to happen.

To fix this, let's rework how the overlay controller setting works.
We don't want it to encode the currently selected Wii Remote extension.
However, we can't simply get rid of the setting, because for some Wii
games we need the ability to switch between a GameCube controller and a
Wii Remote. What this commit does is give the user the option to select
any of the 4 GameCube controllers and any of the 4 Wii Remotes. (Before,
controllers 2-4 weren't available in the overlay.) Could be useful for
things like the Psycho Mantis fight in Metal Gear Solid. I'm also
switching from SharedPreferences to Dolphin.ini while I'm at it.
2023-03-07 17:39:34 +01:00

175 lines
6.1 KiB
C++

// Copyright 2022 Dolphin Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <jni.h>
#include "Common/FileUtil.h"
#include "Common/IniFile.h"
#include "Core/HW/GCPad.h"
#include "Core/HW/Wiimote.h"
#include "Core/HW/WiimoteEmu/WiimoteEmu.h"
#include "InputCommon/ControllerEmu/ControlGroup/Attachments.h"
#include "InputCommon/ControllerEmu/ControllerEmu.h"
#include "InputCommon/ControllerInterface/ControllerInterface.h"
#include "InputCommon/InputConfig.h"
#include "jni/AndroidCommon/AndroidCommon.h"
#include "jni/AndroidCommon/IDCache.h"
#include "jni/Input/Control.h"
#include "jni/Input/ControlGroup.h"
#include "jni/Input/ControlReference.h"
#include "jni/Input/NumericSetting.h"
ControllerEmu::EmulatedController* EmulatedControllerFromJava(JNIEnv* env, jobject obj)
{
return reinterpret_cast<ControllerEmu::EmulatedController*>(
env->GetLongField(obj, IDCache::GetEmulatedControllerPointer()));
}
static jobject EmulatedControllerToJava(JNIEnv* env, ControllerEmu::EmulatedController* controller)
{
if (!controller)
return nullptr;
return env->NewObject(IDCache::GetEmulatedControllerClass(),
IDCache::GetEmulatedControllerConstructor(),
reinterpret_cast<jlong>(controller));
}
extern "C" {
JNIEXPORT jstring JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getDefaultDevice(
JNIEnv* env, jobject obj)
{
return ToJString(env, EmulatedControllerFromJava(env, obj)->GetDefaultDevice().ToString());
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_setDefaultDevice(
JNIEnv* env, jobject obj, jstring j_device)
{
return EmulatedControllerFromJava(env, obj)->SetDefaultDevice(GetJString(env, j_device));
}
JNIEXPORT jint JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getGroupCount(
JNIEnv* env, jobject obj)
{
return static_cast<jint>(EmulatedControllerFromJava(env, obj)->groups.size());
}
JNIEXPORT jobject JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getGroup(
JNIEnv* env, jobject obj, jint controller_index)
{
return ControlGroupToJava(env,
EmulatedControllerFromJava(env, obj)->groups[controller_index].get());
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_updateSingleControlReference(
JNIEnv* env, jobject obj, jobject control_reference)
{
return EmulatedControllerFromJava(env, obj)->UpdateSingleControlReference(
g_controller_interface, ControlReferenceFromJava(env, control_reference));
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_loadDefaultSettings(
JNIEnv* env, jobject obj)
{
ControllerEmu::EmulatedController* controller = EmulatedControllerFromJava(env, obj);
controller->LoadDefaults(g_controller_interface);
controller->UpdateReferences(g_controller_interface);
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_clearSettings(
JNIEnv* env, jobject obj)
{
ControllerEmu::EmulatedController* controller = EmulatedControllerFromJava(env, obj);
// Loading an empty IniFile section clears everything.
IniFile::Section section;
controller->LoadConfig(&section);
controller->UpdateReferences(g_controller_interface);
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_loadProfile(
JNIEnv* env, jobject obj, jstring j_path)
{
ControllerEmu::EmulatedController* controller = EmulatedControllerFromJava(env, obj);
IniFile ini;
ini.Load(GetJString(env, j_path));
controller->LoadConfig(ini.GetOrCreateSection("Profile"));
controller->UpdateReferences(g_controller_interface);
}
JNIEXPORT void JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_saveProfile(
JNIEnv* env, jobject obj, jstring j_path)
{
const std::string path = GetJString(env, j_path);
File::CreateFullPath(path);
IniFile ini;
EmulatedControllerFromJava(env, obj)->SaveConfig(ini.GetOrCreateSection("Profile"));
ini.Save(path);
}
JNIEXPORT jobject JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getGcPad(
JNIEnv* env, jclass, jint controller_index)
{
return EmulatedControllerToJava(env, Pad::GetConfig()->GetController(controller_index));
}
JNIEXPORT jobject JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getWiimote(
JNIEnv* env, jclass, jint controller_index)
{
return EmulatedControllerToJava(env, Wiimote::GetConfig()->GetController(controller_index));
}
JNIEXPORT jobject JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getWiimoteAttachment(
JNIEnv* env, jclass, jint controller_index, jint attachment_index)
{
auto* attachments = static_cast<ControllerEmu::Attachments*>(
Wiimote::GetWiimoteGroup(controller_index, WiimoteEmu::WiimoteGroup::Attachments));
return EmulatedControllerToJava(env, attachments->GetAttachmentList()[attachment_index].get());
}
JNIEXPORT jint JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getSelectedWiimoteAttachment(
JNIEnv* env, jclass, jint controller_index)
{
auto* attachments = static_cast<ControllerEmu::Attachments*>(
Wiimote::GetWiimoteGroup(controller_index, WiimoteEmu::WiimoteGroup::Attachments));
return static_cast<jint>(attachments->GetSelectedAttachment());
}
JNIEXPORT jobject JNICALL
Java_org_dolphinemu_dolphinemu_features_input_model_controlleremu_EmulatedController_getSidewaysWiimoteSetting(
JNIEnv* env, jclass, jint controller_index)
{
ControllerEmu::ControlGroup* options =
Wiimote::GetWiimoteGroup(controller_index, WiimoteEmu::WiimoteGroup::Options);
for (auto& setting : options->numeric_settings)
{
if (setting->GetININame() == WiimoteEmu::Wiimote::SIDEWAYS_OPTION)
return NumericSettingToJava(env, setting.get());
}
return nullptr;
}
}