mirror of
https://github.com/SSimco/Cemu.git
synced 2024-11-26 23:00:29 +00:00
Refactored native library
This commit is contained in:
parent
35d7ad6414
commit
6026d2ad96
@ -27,7 +27,7 @@ class AndroidFilesystemCallbacks : public FilesystemAndroid::FilesystemCallbacks
|
||||
AndroidFilesystemCallbacks()
|
||||
{
|
||||
JNIUtils::ScopedJNIENV env;
|
||||
m_fileUtilClass = JNIUtils::Scopedjclass("info/cemu/Cemu/utils/FileUtil");
|
||||
m_fileUtilClass = JNIUtils::Scopedjclass("info/cemu/Cemu/nativeinterface/FileCallbacks");
|
||||
m_openContentUriMid = env->GetStaticMethodID(*m_fileUtilClass, "openContentUri", "(Ljava/lang/String;)I");
|
||||
m_listFilesMid = env->GetStaticMethodID(*m_fileUtilClass, "listFiles", "(Ljava/lang/String;)[Ljava/lang/String;");
|
||||
m_isDirectoryMid = env->GetStaticMethodID(*m_fileUtilClass, "isDirectory", "(Ljava/lang/String;)Z");
|
||||
|
@ -1,24 +1,16 @@
|
||||
add_library(CemuAndroid SHARED
|
||||
AndroidAudio.cpp
|
||||
AndroidAudio.h
|
||||
AndroidEmulatedController.cpp
|
||||
AndroidEmulatedController.h
|
||||
AndroidFilesystemCallbacks.h
|
||||
AndroidGameTitleLoadedCallback.h
|
||||
CMakeLists.txt
|
||||
CafeSystemUtils.cpp
|
||||
CafeSystemUtils.h
|
||||
EmulationState.h
|
||||
GameTitleLoader.cpp
|
||||
GameTitleLoader.h
|
||||
Image.cpp
|
||||
Image.h
|
||||
JNIUtils.cpp
|
||||
JNIUtils.h
|
||||
Utils.cpp
|
||||
Utils.h
|
||||
native-lib.cpp
|
||||
stb_image.h
|
||||
NativeEmulation.cpp
|
||||
NativeGameTitles.cpp
|
||||
NativeGraphicPacks.cpp
|
||||
NativeInput.cpp
|
||||
NativeLib.cpp
|
||||
NativeSettings.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(CemuAndroid PRIVATE
|
||||
|
@ -1,55 +0,0 @@
|
||||
#include "CafeSystemUtils.h"
|
||||
|
||||
#include "Cafe/CafeSystem.h"
|
||||
#include "Cafe/TitleList/TitleList.h"
|
||||
|
||||
namespace CafeSystemUtils
|
||||
{
|
||||
void startGame(const fs::path& launchPath)
|
||||
{
|
||||
TitleInfo launchTitle{launchPath};
|
||||
if (launchTitle.IsValid())
|
||||
{
|
||||
// the title might not be in the TitleList, so we add it as a temporary entry
|
||||
CafeTitleList::AddTitleFromPath(launchPath);
|
||||
// title is valid, launch from TitleId
|
||||
TitleId baseTitleId;
|
||||
if (!CafeTitleList::FindBaseTitleId(launchTitle.GetAppTitleId(), baseTitleId))
|
||||
{
|
||||
throw GameBaseFilesNotFoundException();
|
||||
}
|
||||
CafeSystem::STATUS_CODE r = CafeSystem::PrepareForegroundTitle(baseTitleId);
|
||||
if (r != CafeSystem::STATUS_CODE::SUCCESS)
|
||||
{
|
||||
throw UnknownGameFilesException();
|
||||
}
|
||||
}
|
||||
else // if (launchTitle.GetFormat() == TitleInfo::TitleDataFormat::INVALID_STRUCTURE )
|
||||
{
|
||||
// title is invalid, if it's an RPX/ELF we can launch it directly
|
||||
// otherwise it's an error
|
||||
CafeTitleFileType fileType = DetermineCafeSystemFileType(launchPath);
|
||||
if (fileType == CafeTitleFileType::RPX || fileType == CafeTitleFileType::ELF)
|
||||
{
|
||||
CafeSystem::STATUS_CODE r = CafeSystem::PrepareForegroundTitleFromStandaloneRPX(launchPath);
|
||||
if (r != CafeSystem::STATUS_CODE::SUCCESS)
|
||||
{
|
||||
throw UnknownGameFilesException();
|
||||
}
|
||||
}
|
||||
else if (launchTitle.GetInvalidReason() == TitleInfo::InvalidReason::NO_DISC_KEY)
|
||||
{
|
||||
throw NoDiscKeyException();
|
||||
}
|
||||
else if (launchTitle.GetInvalidReason() == TitleInfo::InvalidReason::NO_TITLE_TIK)
|
||||
{
|
||||
throw NoTitleTikException();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw UnknownGameFilesException();
|
||||
}
|
||||
}
|
||||
CafeSystem::LaunchForegroundTitle();
|
||||
}
|
||||
}; // namespace CafeSystemUtils
|
@ -1,51 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cafe/TitleList/TitleId.h"
|
||||
|
||||
namespace CafeSystemUtils
|
||||
{
|
||||
class GameFilesException : public std::exception
|
||||
{
|
||||
public:
|
||||
explicit GameFilesException(const std::string& message)
|
||||
: m_message(message) {}
|
||||
|
||||
const char* what() const noexcept override
|
||||
{
|
||||
return m_message.c_str();
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_message;
|
||||
};
|
||||
|
||||
class GameBaseFilesNotFoundException : public GameFilesException
|
||||
{
|
||||
public:
|
||||
GameBaseFilesNotFoundException()
|
||||
: GameFilesException("Game base files not found.") {}
|
||||
};
|
||||
|
||||
class NoDiscKeyException : public GameFilesException
|
||||
{
|
||||
public:
|
||||
NoDiscKeyException()
|
||||
: GameFilesException("No disc key found.") {}
|
||||
};
|
||||
|
||||
class NoTitleTikException : public GameFilesException
|
||||
{
|
||||
public:
|
||||
NoTitleTikException()
|
||||
: GameFilesException("No title ticket found.") {}
|
||||
};
|
||||
|
||||
class UnknownGameFilesException : public GameFilesException
|
||||
{
|
||||
public:
|
||||
UnknownGameFilesException()
|
||||
: GameFilesException("Unknown error occurred during game launch.") {}
|
||||
};
|
||||
|
||||
void startGame(const fs::path& launchPath);
|
||||
}; // namespace CafeSystemUtils
|
@ -1,360 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <jni.h>
|
||||
|
||||
#include "AndroidAudio.h"
|
||||
#include "AndroidEmulatedController.h"
|
||||
#include "AndroidFilesystemCallbacks.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteOverlay.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h"
|
||||
#include "CafeSystemUtils.h"
|
||||
#include "Cafe/CafeSystem.h"
|
||||
#include "Cemu/GuiSystem/GuiSystem.h"
|
||||
#include "GameTitleLoader.h"
|
||||
#include "Utils.h"
|
||||
#include "input/ControllerFactory.h"
|
||||
#include "input/InputManager.h"
|
||||
#include "input/api/Android/AndroidController.h"
|
||||
#include "input/api/Android/AndroidControllerProvider.h"
|
||||
|
||||
void CemuCommonInit();
|
||||
|
||||
class EmulationState
|
||||
{
|
||||
GameTitleLoader m_gameTitleLoader;
|
||||
std::unordered_map<int64_t, GraphicPackPtr> m_graphicPacks;
|
||||
void fillGraphicPacks()
|
||||
{
|
||||
m_graphicPacks.clear();
|
||||
auto graphicPacks = GraphicPack2::GetGraphicPacks();
|
||||
for (auto&& graphicPack : graphicPacks)
|
||||
{
|
||||
m_graphicPacks[reinterpret_cast<int64_t>(graphicPack.get())] = graphicPack;
|
||||
}
|
||||
}
|
||||
void onTouchEvent(sint32 x, sint32 y, bool isTV, std::optional<bool> status = {})
|
||||
{
|
||||
auto& instance = InputManager::instance();
|
||||
auto& touchInfo = isTV ? instance.m_main_mouse : instance.m_pad_mouse;
|
||||
std::scoped_lock lock(touchInfo.m_mutex);
|
||||
touchInfo.position = {x, y};
|
||||
if (status.has_value())
|
||||
touchInfo.left_down = touchInfo.left_down_toggle = status.value();
|
||||
}
|
||||
WiiUMotionHandler m_wiiUMotionHandler{};
|
||||
long m_lastMotionTimestamp;
|
||||
|
||||
public:
|
||||
void initializeEmulation()
|
||||
{
|
||||
g_config.SetFilename(ActiveSettings::GetConfigPath("settings.xml").generic_wstring());
|
||||
g_config.Load();
|
||||
FilesystemAndroid::setFilesystemCallbacks(std::make_shared<AndroidFilesystemCallbacks>());
|
||||
NetworkConfig::LoadOnce();
|
||||
InputManager::instance().load();
|
||||
auto& instance = InputManager::instance();
|
||||
InitializeGlobalVulkan();
|
||||
createCemuDirectories();
|
||||
LatteOverlay_init();
|
||||
CemuCommonInit();
|
||||
fillGraphicPacks();
|
||||
}
|
||||
|
||||
void initializeActiveSettings(const fs::path& dataPath, const fs::path& cachePath)
|
||||
{
|
||||
std::set<fs::path> failedWriteAccess;
|
||||
ActiveSettings::SetPaths(false, {}, dataPath, dataPath, cachePath, dataPath, failedWriteAccess);
|
||||
}
|
||||
|
||||
void clearSurface(bool isMainCanvas)
|
||||
{
|
||||
if (!isMainCanvas)
|
||||
{
|
||||
auto renderer = static_cast<VulkanRenderer*>(g_renderer.get());
|
||||
if (renderer)
|
||||
renderer->StopUsingPadAndWait();
|
||||
}
|
||||
}
|
||||
|
||||
void notifySurfaceChanged(bool isMainCanvas)
|
||||
{
|
||||
}
|
||||
|
||||
void setSurface(JNIEnv* env, jobject surface, bool isMainCanvas)
|
||||
{
|
||||
cemu_assert_debug(surface != nullptr);
|
||||
auto& windowHandleInfo = isMainCanvas ? GuiSystem::getWindowInfo().canvas_main : GuiSystem::getWindowInfo().canvas_pad;
|
||||
if (windowHandleInfo.surface)
|
||||
{
|
||||
ANativeWindow_release(static_cast<ANativeWindow*>(windowHandleInfo.surface));
|
||||
windowHandleInfo.surface = nullptr;
|
||||
}
|
||||
windowHandleInfo.surface = ANativeWindow_fromSurface(env, surface);
|
||||
int width, height;
|
||||
if (isMainCanvas)
|
||||
GuiSystem::getWindowPhysSize(width, height);
|
||||
else
|
||||
GuiSystem::getPadWindowPhysSize(width, height);
|
||||
VulkanRenderer::GetInstance()->InitializeSurface({width, height}, isMainCanvas);
|
||||
}
|
||||
|
||||
void setSurfaceSize(int width, int height, bool isMainCanvas)
|
||||
{
|
||||
auto& windowInfo = GuiSystem::getWindowInfo();
|
||||
if (isMainCanvas)
|
||||
{
|
||||
windowInfo.width = windowInfo.phys_width = width;
|
||||
windowInfo.height = windowInfo.phys_height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
windowInfo.pad_width = windowInfo.phys_pad_width = width;
|
||||
windowInfo.pad_height = windowInfo.phys_pad_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
void onKeyEvent(const std::string& deviceDescriptor, const std::string& deviceName, int keyCode, bool isPressed)
|
||||
{
|
||||
auto apiProvider = InputManager::instance().get_api_provider(InputAPI::Android);
|
||||
auto androidControllerProvider = dynamic_cast<AndroidControllerProvider*>(apiProvider.get());
|
||||
androidControllerProvider->on_key_event(deviceDescriptor, deviceName, keyCode, isPressed);
|
||||
}
|
||||
|
||||
void onAxisEvent(const std::string& deviceDescriptor, const std::string& deviceName, int axisCode, float value)
|
||||
{
|
||||
auto apiProvider = InputManager::instance().get_api_provider(InputAPI::Android);
|
||||
auto androidControllerProvider = dynamic_cast<AndroidControllerProvider*>(apiProvider.get());
|
||||
androidControllerProvider->on_axis_event(deviceDescriptor, deviceName, axisCode, value);
|
||||
}
|
||||
|
||||
std::optional<std::string> getEmulatedControllerMapping(size_t index, uint64 mappingId)
|
||||
{
|
||||
return AndroidEmulatedController::getAndroidEmulatedController(index).getMapping(mappingId);
|
||||
}
|
||||
|
||||
AndroidEmulatedController& getEmulatedController(size_t index)
|
||||
{
|
||||
return AndroidEmulatedController::getAndroidEmulatedController(index);
|
||||
}
|
||||
|
||||
int getVPADControllersCount()
|
||||
{
|
||||
int vpadCount = 0;
|
||||
for (int i = 0; i < InputManager::kMaxController; i++)
|
||||
{
|
||||
auto emulatedController = AndroidEmulatedController::getAndroidEmulatedController(i).getEmulatedController();
|
||||
if (!emulatedController)
|
||||
continue;
|
||||
if (emulatedController->type() == EmulatedController::Type::VPAD)
|
||||
++vpadCount;
|
||||
}
|
||||
return vpadCount;
|
||||
}
|
||||
|
||||
int getWPADControllersCount()
|
||||
{
|
||||
int wpadCount = 0;
|
||||
for (int i = 0; i < InputManager::kMaxController; i++)
|
||||
{
|
||||
auto emulatedController = AndroidEmulatedController::getAndroidEmulatedController(
|
||||
i)
|
||||
.getEmulatedController();
|
||||
if (!emulatedController)
|
||||
continue;
|
||||
if (emulatedController->type() != EmulatedController::Type::VPAD)
|
||||
++wpadCount;
|
||||
}
|
||||
return wpadCount;
|
||||
}
|
||||
|
||||
EmulatedController::Type getEmulatedControllerType(size_t index)
|
||||
{
|
||||
auto emulatedController = AndroidEmulatedController::getAndroidEmulatedController(index).getEmulatedController();
|
||||
if (emulatedController)
|
||||
return emulatedController->type();
|
||||
throw std::runtime_error(fmt::format("can't get type for emulated controller {}", index));
|
||||
}
|
||||
|
||||
void clearEmulatedControllerMapping(size_t index, uint64 mapping)
|
||||
{
|
||||
AndroidEmulatedController::getAndroidEmulatedController(index).clearMapping(mapping);
|
||||
}
|
||||
|
||||
void setEmulatedControllerType(size_t index, EmulatedController::Type type)
|
||||
{
|
||||
auto& androidEmulatedController = AndroidEmulatedController::getAndroidEmulatedController(index);
|
||||
if (EmulatedController::Type::VPAD <= type && type < EmulatedController::Type::MAX)
|
||||
androidEmulatedController.setType(type);
|
||||
else
|
||||
androidEmulatedController.setDisabled();
|
||||
}
|
||||
|
||||
void initializeRenderer(JNIEnv* env, jobject testSurface)
|
||||
{
|
||||
cemu_assert_debug(testSurface != nullptr);
|
||||
// TODO: cleanup surface
|
||||
GuiSystem::getWindowInfo().window_main.surface = ANativeWindow_fromSurface(env, testSurface);
|
||||
g_renderer = std::make_unique<VulkanRenderer>();
|
||||
}
|
||||
void setReplaceTVWithPadView(bool showDRC)
|
||||
{
|
||||
// Emulate pressing the TAB key for showing DRC instead of TV
|
||||
GuiSystem::getWindowInfo().set_keystate(GuiSystem::PlatformKeyCodes::TAB, showDRC);
|
||||
}
|
||||
void setDPI(float dpi)
|
||||
{
|
||||
auto& windowInfo = GuiSystem::getWindowInfo();
|
||||
windowInfo.dpi_scale = windowInfo.pad_dpi_scale = dpi;
|
||||
}
|
||||
|
||||
bool isEmulatedControllerDisabled(size_t index)
|
||||
{
|
||||
return AndroidEmulatedController::getAndroidEmulatedController(index).getEmulatedController() == nullptr;
|
||||
}
|
||||
|
||||
std::map<uint64, std::string> getEmulatedControllerMappings(size_t index)
|
||||
{
|
||||
return AndroidEmulatedController::getAndroidEmulatedController(index).getMappings();
|
||||
}
|
||||
|
||||
void setControllerMapping(const std::string& deviceDescriptor, const std::string& deviceName, size_t index, uint64 mappingId, uint64 buttonId)
|
||||
{
|
||||
auto apiProvider = InputManager::instance().get_api_provider(InputAPI::Android);
|
||||
auto controller = ControllerFactory::CreateController(InputAPI::Android, deviceDescriptor, deviceName);
|
||||
AndroidEmulatedController::getAndroidEmulatedController(index).setMapping(mappingId, controller, buttonId);
|
||||
}
|
||||
void initializeAudioDevices()
|
||||
{
|
||||
auto& config = g_config.data();
|
||||
if (!config.tv_device.empty())
|
||||
AndroidAudio::createAudioDevice(IAudioAPI::AudioAPI::Cubeb, config.tv_channels, config.tv_volume, true);
|
||||
|
||||
if (!config.pad_device.empty())
|
||||
AndroidAudio::createAudioDevice(IAudioAPI::AudioAPI::Cubeb, config.pad_channels, config.pad_volume, false);
|
||||
}
|
||||
|
||||
void setOnGameTitleLoaded(const std::shared_ptr<GameTitleLoadedCallback>& onGameTitleLoaded)
|
||||
{
|
||||
m_gameTitleLoader.setOnTitleLoaded(onGameTitleLoaded);
|
||||
}
|
||||
|
||||
void addGamesPath(const std::string& gamePath)
|
||||
{
|
||||
auto& gamePaths = g_config.data().game_paths;
|
||||
if (std::any_of(gamePaths.begin(), gamePaths.end(), [&](auto path) { return path == gamePath; }))
|
||||
return;
|
||||
gamePaths.push_back(gamePath);
|
||||
g_config.Save();
|
||||
CafeTitleList::ClearScanPaths();
|
||||
for (auto& it : gamePaths)
|
||||
CafeTitleList::AddScanPath(it);
|
||||
CafeTitleList::Refresh();
|
||||
}
|
||||
|
||||
void removeGamesPath(const std::string& gamePath)
|
||||
{
|
||||
auto& gamePaths = g_config.data().game_paths;
|
||||
std::erase_if(gamePaths, [&](auto path) { return path == gamePath; });
|
||||
g_config.Save();
|
||||
CafeTitleList::ClearScanPaths();
|
||||
for (auto& it : gamePaths)
|
||||
CafeTitleList::AddScanPath(it);
|
||||
CafeTitleList::Refresh();
|
||||
}
|
||||
|
||||
void reloadGameTitles()
|
||||
{
|
||||
m_gameTitleLoader.reloadGameTitles();
|
||||
}
|
||||
|
||||
void startGame(const fs::path& gamePath)
|
||||
{
|
||||
GuiSystem::getWindowInfo().set_keystates_up();
|
||||
initializeAudioDevices();
|
||||
CafeSystemUtils::startGame(gamePath);
|
||||
}
|
||||
|
||||
void refreshGraphicPacks()
|
||||
{
|
||||
if (!CafeSystem::IsTitleRunning())
|
||||
{
|
||||
GraphicPack2::ClearGraphicPacks();
|
||||
GraphicPack2::LoadAll();
|
||||
fillGraphicPacks();
|
||||
}
|
||||
}
|
||||
|
||||
const std::unordered_map<int64_t, GraphicPackPtr>& getGraphicPacks() const
|
||||
{
|
||||
return m_graphicPacks;
|
||||
}
|
||||
|
||||
void setEnabledStateForGraphicPack(int64_t id, bool state)
|
||||
{
|
||||
auto graphicPack = m_graphicPacks.at(id);
|
||||
graphicPack->SetEnabled(state);
|
||||
saveGraphicPackStateToConfig(graphicPack);
|
||||
}
|
||||
|
||||
GraphicPackPtr getGraphicPack(int64_t id) const
|
||||
{
|
||||
return m_graphicPacks.at(id);
|
||||
}
|
||||
void setGraphicPackActivePreset(int64_t id, const std::string& presetCategory, const std::string& preset) const
|
||||
{
|
||||
auto graphicPack = m_graphicPacks.at(id);
|
||||
graphicPack->SetActivePreset(presetCategory, preset);
|
||||
saveGraphicPackStateToConfig(graphicPack);
|
||||
}
|
||||
void saveGraphicPackStateToConfig(GraphicPackPtr graphicPack) const
|
||||
{
|
||||
auto& data = g_config.data();
|
||||
auto filename = _utf8ToPath(graphicPack->GetNormalizedPathString());
|
||||
if (data.graphic_pack_entries.contains(filename))
|
||||
data.graphic_pack_entries.erase(filename);
|
||||
if (graphicPack->IsEnabled())
|
||||
{
|
||||
data.graphic_pack_entries.try_emplace(filename);
|
||||
auto& it = data.graphic_pack_entries[filename];
|
||||
// otherwise store all selected presets
|
||||
for (const auto& preset : graphicPack->GetActivePresets())
|
||||
it.try_emplace(preset->category, preset->name);
|
||||
}
|
||||
else if (graphicPack->IsDefaultEnabled())
|
||||
{
|
||||
// save that its disabled
|
||||
data.graphic_pack_entries.try_emplace(filename);
|
||||
auto& it = data.graphic_pack_entries[filename];
|
||||
it.try_emplace("_disabled", "false");
|
||||
}
|
||||
g_config.Save();
|
||||
}
|
||||
void onTouchMove(sint32 x, sint32 y, bool isTV)
|
||||
{
|
||||
onTouchEvent(x, y, isTV);
|
||||
}
|
||||
void onTouchUp(sint32 x, sint32 y, bool isTV)
|
||||
{
|
||||
onTouchEvent(x, y, isTV, false);
|
||||
}
|
||||
void onTouchDown(sint32 x, sint32 y, bool isTV)
|
||||
{
|
||||
onTouchEvent(x, y, isTV, true);
|
||||
}
|
||||
void onMotion(long timestamp, float gyroX, float gyroY, float gyroZ, float accelX, float accelY, float accelZ)
|
||||
{
|
||||
float deltaTime = (timestamp - m_lastMotionTimestamp) * 1e-9f;
|
||||
m_wiiUMotionHandler.processMotionSample(deltaTime, gyroX, gyroY, gyroZ, accelX * 0.098066f, -accelY * 0.098066f, -accelZ * 0.098066f);
|
||||
m_lastMotionTimestamp = timestamp;
|
||||
auto& deviceMotion = InputManager::instance().m_device_motion;
|
||||
std::scoped_lock lock{deviceMotion.m_mutex};
|
||||
deviceMotion.m_motion_sample = m_wiiUMotionHandler.getMotionSample();
|
||||
}
|
||||
void setMotionEnabled(bool enabled)
|
||||
{
|
||||
auto& deviceMotion = InputManager::instance().m_device_motion;
|
||||
std::scoped_lock lock{deviceMotion.m_mutex};
|
||||
deviceMotion.m_device_motion_enabled = enabled;
|
||||
}
|
||||
};
|
261
src/android/app/src/main/cpp/NativeEmulation.cpp
Normal file
261
src/android/app/src/main/cpp/NativeEmulation.cpp
Normal file
@ -0,0 +1,261 @@
|
||||
#include "JNIUtils.h"
|
||||
#include "AndroidAudio.h"
|
||||
#include "AndroidEmulatedController.h"
|
||||
#include "AndroidFilesystemCallbacks.h"
|
||||
#include "Cafe/HW/Latte/Core/LatteOverlay.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanAPI.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Vulkan/VulkanRenderer.h"
|
||||
#include "Cafe/CafeSystem.h"
|
||||
#include "Cemu/GuiSystem/GuiSystem.h"
|
||||
#include "GameTitleLoader.h"
|
||||
#include "input/ControllerFactory.h"
|
||||
#include "input/InputManager.h"
|
||||
#include "input/api/Android/AndroidController.h"
|
||||
#include "input/api/Android/AndroidControllerProvider.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "Cemu/ncrypto/ncrypto.h"
|
||||
|
||||
// forward declaration from main.cpp
|
||||
void CemuCommonInit();
|
||||
|
||||
namespace NativeEmulation
|
||||
{
|
||||
void initializeAudioDevices()
|
||||
{
|
||||
auto& config = g_config.data();
|
||||
if (!config.tv_device.empty())
|
||||
AndroidAudio::createAudioDevice(IAudioAPI::AudioAPI::Cubeb, config.tv_channels, config.tv_volume, true);
|
||||
|
||||
if (!config.pad_device.empty())
|
||||
AndroidAudio::createAudioDevice(IAudioAPI::AudioAPI::Cubeb, config.pad_channels, config.pad_volume, false);
|
||||
}
|
||||
|
||||
void createCemuDirectories()
|
||||
{
|
||||
std::wstring mlc = ActiveSettings::GetMlcPath().generic_wstring();
|
||||
|
||||
// create sys/usr folder in mlc01
|
||||
const auto sysFolder = fs::path(mlc).append(L"sys");
|
||||
fs::create_directories(sysFolder);
|
||||
|
||||
const auto usrFolder = fs::path(mlc).append(L"usr");
|
||||
fs::create_directories(usrFolder);
|
||||
fs::create_directories(fs::path(usrFolder).append("title/00050000")); // base
|
||||
fs::create_directories(fs::path(usrFolder).append("title/0005000c")); // dlc
|
||||
fs::create_directories(fs::path(usrFolder).append("title/0005000e")); // update
|
||||
|
||||
// Mii Maker save folders {0x500101004A000, 0x500101004A100, 0x500101004A200},
|
||||
fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a000/user/common/db"));
|
||||
fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a100/user/common/db"));
|
||||
fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a200/user/common/db"));
|
||||
|
||||
// lang files
|
||||
auto langDir = fs::path(mlc).append(L"sys/title/0005001b/1005c000/content");
|
||||
fs::create_directories(langDir);
|
||||
|
||||
auto langFile = fs::path(langDir).append("language.txt");
|
||||
if (!fs::exists(langFile))
|
||||
{
|
||||
std::ofstream file(langFile);
|
||||
if (file.is_open())
|
||||
{
|
||||
const char* langStrings[] = {"ja", "en", "fr", "de", "it", "es", "zh", "ko", "nl", "pt", "ru", "zh"};
|
||||
for (const char* lang : langStrings)
|
||||
file << fmt::format(R"("{}",)", lang) << std::endl;
|
||||
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
auto countryFile = fs::path(langDir).append("country.txt");
|
||||
if (!fs::exists(countryFile))
|
||||
{
|
||||
std::ofstream file(countryFile);
|
||||
for (sint32 i = 0; i < 201; i++)
|
||||
{
|
||||
const char* countryCode = NCrypto::GetCountryAsString(i);
|
||||
if (boost::iequals(countryCode, "NN"))
|
||||
file << "NULL," << std::endl;
|
||||
else
|
||||
file << fmt::format(R"("{}",)", countryCode) << std::endl;
|
||||
}
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
|
||||
// cemu directories
|
||||
const auto controllerProfileFolder = ActiveSettings::GetConfigPath(L"controllerProfiles").generic_wstring();
|
||||
if (!fs::exists(controllerProfileFolder))
|
||||
fs::create_directories(controllerProfileFolder);
|
||||
|
||||
const auto memorySearcherFolder = ActiveSettings::GetUserDataPath(L"memorySearcher").generic_wstring();
|
||||
if (!fs::exists(memorySearcherFolder))
|
||||
fs::create_directories(memorySearcherFolder);
|
||||
}
|
||||
enum StartGameResult : sint32
|
||||
{
|
||||
SUCCESSFUL = 0,
|
||||
ERROR_GAME_BASE_FILES_NOT_FOUND = 1,
|
||||
ERROR_NO_DISC_KEY = 2,
|
||||
ERROR_NO_TITLE_TIK = 3,
|
||||
ERROR_UNKNOWN = 4,
|
||||
};
|
||||
StartGameResult startGame(const fs::path& launchPath)
|
||||
{
|
||||
TitleInfo launchTitle{launchPath};
|
||||
if (launchTitle.IsValid())
|
||||
{
|
||||
// the title might not be in the TitleList, so we add it as a temporary entry
|
||||
CafeTitleList::AddTitleFromPath(launchPath);
|
||||
// title is valid, launch from TitleId
|
||||
TitleId baseTitleId;
|
||||
if (!CafeTitleList::FindBaseTitleId(launchTitle.GetAppTitleId(), baseTitleId))
|
||||
{
|
||||
return ERROR_GAME_BASE_FILES_NOT_FOUND;
|
||||
}
|
||||
CafeSystem::STATUS_CODE r = CafeSystem::PrepareForegroundTitle(baseTitleId);
|
||||
if (r != CafeSystem::STATUS_CODE::SUCCESS)
|
||||
{
|
||||
return ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
else // if (launchTitle.GetFormat() == TitleInfo::TitleDataFormat::INVALID_STRUCTURE )
|
||||
{
|
||||
// title is invalid, if it's an RPX/ELF we can launch it directly
|
||||
// otherwise it's an error
|
||||
CafeTitleFileType fileType = DetermineCafeSystemFileType(launchPath);
|
||||
if (fileType == CafeTitleFileType::RPX || fileType == CafeTitleFileType::ELF)
|
||||
{
|
||||
CafeSystem::STATUS_CODE r = CafeSystem::PrepareForegroundTitleFromStandaloneRPX(launchPath);
|
||||
if (r != CafeSystem::STATUS_CODE::SUCCESS)
|
||||
{
|
||||
return ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
else if (launchTitle.GetInvalidReason() == TitleInfo::InvalidReason::NO_DISC_KEY)
|
||||
{
|
||||
return ERROR_NO_DISC_KEY;
|
||||
}
|
||||
else if (launchTitle.GetInvalidReason() == TitleInfo::InvalidReason::NO_TITLE_TIK)
|
||||
{
|
||||
return ERROR_NO_TITLE_TIK;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ERROR_UNKNOWN;
|
||||
}
|
||||
}
|
||||
CafeSystem::LaunchForegroundTitle();
|
||||
return SUCCESSFUL;
|
||||
}
|
||||
} // namespace NativeEmulation
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_setReplaceTVWithPadView([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean swapped)
|
||||
{
|
||||
// Emulate pressing the TAB key for showing DRC instead of TV
|
||||
GuiSystem::getWindowInfo().set_keystate(GuiSystem::PlatformKeyCodes::TAB, swapped);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_initializeActiveSettings(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring data_path, jstring cache_path)
|
||||
{
|
||||
std::string dataPath = JNIUtils::JStringToString(env, data_path);
|
||||
std::string cachePath = JNIUtils::JStringToString(env, cache_path);
|
||||
std::set<fs::path> failedWriteAccess;
|
||||
ActiveSettings::SetPaths(false, {}, dataPath, dataPath, cachePath, dataPath, failedWriteAccess);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_initializeEmulation([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
FilesystemAndroid::setFilesystemCallbacks(std::make_shared<AndroidFilesystemCallbacks>());
|
||||
g_config.SetFilename(ActiveSettings::GetConfigPath("settings.xml").generic_wstring());
|
||||
NativeEmulation::createCemuDirectories();
|
||||
NetworkConfig::LoadOnce();
|
||||
ActiveSettings::Init();
|
||||
LatteOverlay_init();
|
||||
CemuCommonInit();
|
||||
InitializeGlobalVulkan();
|
||||
// TODO: move this
|
||||
// fillGraphicPacks();
|
||||
}
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_initializerRenderer(JNIEnv* env, [[maybe_unused]] jclass clazz, jobject testSurface)
|
||||
{
|
||||
JNIUtils::handleNativeException(env, [&]() {
|
||||
cemu_assert_debug(testSurface != nullptr);
|
||||
// TODO: cleanup surface
|
||||
GuiSystem::getWindowInfo().window_main.surface = ANativeWindow_fromSurface(env, testSurface);
|
||||
g_renderer = std::make_unique<VulkanRenderer>();
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_setDPI([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jfloat dpi)
|
||||
{
|
||||
auto& windowInfo = GuiSystem::getWindowInfo();
|
||||
windowInfo.dpi_scale = windowInfo.pad_dpi_scale = dpi;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_clearSurface([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean is_main_canvas)
|
||||
{
|
||||
if (!is_main_canvas)
|
||||
{
|
||||
auto renderer = static_cast<VulkanRenderer*>(g_renderer.get());
|
||||
if (renderer)
|
||||
renderer->StopUsingPadAndWait();
|
||||
}
|
||||
}
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_recreateRenderSurface([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean is_main_canvas)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_setSurface(JNIEnv* env, [[maybe_unused]] jclass clazz, jobject surface, jboolean is_main_canvas)
|
||||
{
|
||||
JNIUtils::handleNativeException(env, [&]() {
|
||||
cemu_assert_debug(surface != nullptr);
|
||||
auto& windowHandleInfo = is_main_canvas ? GuiSystem::getWindowInfo().canvas_main : GuiSystem::getWindowInfo().canvas_pad;
|
||||
if (windowHandleInfo.surface)
|
||||
{
|
||||
ANativeWindow_release(static_cast<ANativeWindow*>(windowHandleInfo.surface));
|
||||
windowHandleInfo.surface = nullptr;
|
||||
}
|
||||
windowHandleInfo.surface = ANativeWindow_fromSurface(env, surface);
|
||||
int width, height;
|
||||
if (is_main_canvas)
|
||||
GuiSystem::getWindowPhysSize(width, height);
|
||||
else
|
||||
GuiSystem::getPadWindowPhysSize(width, height);
|
||||
VulkanRenderer::GetInstance()->InitializeSurface({width, height}, is_main_canvas);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_setSurfaceSize([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint width, jint height, jboolean is_main_canvas)
|
||||
{
|
||||
auto& windowInfo = GuiSystem::getWindowInfo();
|
||||
if (is_main_canvas)
|
||||
{
|
||||
windowInfo.width = windowInfo.phys_width = width;
|
||||
windowInfo.height = windowInfo.phys_height = height;
|
||||
}
|
||||
else
|
||||
{
|
||||
windowInfo.pad_width = windowInfo.phys_pad_width = width;
|
||||
windowInfo.pad_height = windowInfo.phys_pad_height = height;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeEmulation_startGame([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jstring launchPath)
|
||||
{
|
||||
GuiSystem::getWindowInfo().set_keystates_up();
|
||||
NativeEmulation::initializeAudioDevices();
|
||||
return NativeEmulation::startGame(JNIUtils::JStringToString(env, launchPath));
|
||||
}
|
34
src/android/app/src/main/cpp/NativeGameTitles.cpp
Normal file
34
src/android/app/src/main/cpp/NativeGameTitles.cpp
Normal file
@ -0,0 +1,34 @@
|
||||
#include "JNIUtils.h"
|
||||
#include "GameTitleLoader.h"
|
||||
#include "AndroidGameTitleLoadedCallback.h"
|
||||
|
||||
namespace NativeGameTitles
|
||||
{
|
||||
GameTitleLoader s_gameTitleLoader;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGameTitles_setGameTitleLoadedCallback(JNIEnv* env, [[maybe_unused]] jclass clazz, jobject game_title_loaded_callback)
|
||||
{
|
||||
if (game_title_loaded_callback == nullptr)
|
||||
{
|
||||
NativeGameTitles::s_gameTitleLoader.setOnTitleLoaded(nullptr);
|
||||
return;
|
||||
}
|
||||
jclass gameTitleLoadedCallbackClass = env->GetObjectClass(game_title_loaded_callback);
|
||||
jmethodID onGameTitleLoadedMID = env->GetMethodID(gameTitleLoadedCallbackClass, "onGameTitleLoaded", "(Ljava/lang/String;Ljava/lang/String;[III)V");
|
||||
env->DeleteLocalRef(gameTitleLoadedCallbackClass);
|
||||
NativeGameTitles::s_gameTitleLoader.setOnTitleLoaded(std::make_shared<AndroidGameTitleLoadedCallback>(onGameTitleLoadedMID, game_title_loaded_callback));
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGameTitles_reloadGameTitles([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
NativeGameTitles::s_gameTitleLoader.reloadGameTitles();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGameTitles_getInstalledGamesTitleIds(JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return JNIUtils::createJavaLongArrayList(env, CafeTitleList::GetAllTitleIds());
|
||||
}
|
157
src/android/app/src/main/cpp/NativeGraphicPacks.cpp
Normal file
157
src/android/app/src/main/cpp/NativeGraphicPacks.cpp
Normal file
@ -0,0 +1,157 @@
|
||||
#include "Cafe/CafeSystem.h"
|
||||
#include "config/CemuConfig.h"
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "JNIUtils.h"
|
||||
|
||||
namespace NativeGraphicPacks
|
||||
{
|
||||
std::unordered_map<sint64, GraphicPackPtr> s_graphicPacks;
|
||||
|
||||
void fillGraphicPacks()
|
||||
{
|
||||
s_graphicPacks.clear();
|
||||
auto graphicPacks = GraphicPack2::GetGraphicPacks();
|
||||
for (auto&& graphicPack : graphicPacks)
|
||||
{
|
||||
s_graphicPacks[reinterpret_cast<sint64>(graphicPack.get())] = graphicPack;
|
||||
}
|
||||
}
|
||||
|
||||
void saveGraphicPackStateToConfig(GraphicPackPtr graphicPack)
|
||||
{
|
||||
auto& data = g_config.data();
|
||||
auto filename = _utf8ToPath(graphicPack->GetNormalizedPathString());
|
||||
if (data.graphic_pack_entries.contains(filename))
|
||||
data.graphic_pack_entries.erase(filename);
|
||||
if (graphicPack->IsEnabled())
|
||||
{
|
||||
data.graphic_pack_entries.try_emplace(filename);
|
||||
auto& it = data.graphic_pack_entries[filename];
|
||||
// otherwise store all selected presets
|
||||
for (const auto& preset : graphicPack->GetActivePresets())
|
||||
it.try_emplace(preset->category, preset->name);
|
||||
}
|
||||
else if (graphicPack->IsDefaultEnabled())
|
||||
{
|
||||
// save that its disabled
|
||||
data.graphic_pack_entries.try_emplace(filename);
|
||||
auto& it = data.graphic_pack_entries[filename];
|
||||
it.try_emplace("_disabled", "false");
|
||||
}
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
jobject getGraphicPresets(JNIEnv* env, GraphicPackPtr graphicPack, sint64 id)
|
||||
{
|
||||
auto graphicPackPresetClass = env->FindClass("info/cemu/Cemu/nativeinterface/NativeGraphicPacks$GraphicPackPreset");
|
||||
auto graphicPackPresetCtorId = env->GetMethodID(graphicPackPresetClass, "<init>", "(JLjava/lang/String;Ljava/util/ArrayList;Ljava/lang/String;)V");
|
||||
|
||||
std::vector<std::string> order;
|
||||
auto presets = graphicPack->GetCategorizedPresets(order);
|
||||
|
||||
std::vector<jobject> presetsJobjects;
|
||||
for (const auto& category : order)
|
||||
{
|
||||
const auto& entry = presets[category];
|
||||
// test if any preset is visible and update its status
|
||||
if (std::none_of(entry.cbegin(), entry.cend(), [graphicPack](const auto& p) { return p->visible; }))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
jstring categoryJStr = category.empty() ? nullptr : env->NewStringUTF(category.c_str());
|
||||
std::vector<std::string> presetSelections;
|
||||
std::optional<std::string> activePreset;
|
||||
for (auto& pentry : entry)
|
||||
{
|
||||
if (!pentry->visible)
|
||||
continue;
|
||||
|
||||
presetSelections.push_back(pentry->name);
|
||||
|
||||
if (pentry->active)
|
||||
activePreset = pentry->name;
|
||||
}
|
||||
|
||||
jstring activePresetJstr = nullptr;
|
||||
if (activePreset)
|
||||
activePresetJstr = env->NewStringUTF(activePreset->c_str());
|
||||
else if (!presetSelections.empty())
|
||||
activePresetJstr = env->NewStringUTF(presetSelections.front().c_str());
|
||||
auto presetJObject = env->NewObject(graphicPackPresetClass, graphicPackPresetCtorId, id, categoryJStr, JNIUtils::createJavaStringArrayList(env, presetSelections), activePresetJstr);
|
||||
presetsJobjects.push_back(presetJObject);
|
||||
}
|
||||
return JNIUtils::createArrayList(env, presetsJobjects);
|
||||
}
|
||||
} // namespace NativeGraphicPacks
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGraphicPacks_refreshGraphicPacks([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
if (!CafeSystem::IsTitleRunning())
|
||||
{
|
||||
GraphicPack2::ClearGraphicPacks();
|
||||
GraphicPack2::LoadAll();
|
||||
NativeGraphicPacks::fillGraphicPacks();
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGraphicPacks_getGraphicPackBasicInfos(JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
auto graphicPackInfoClass = env->FindClass("info/cemu/Cemu/nativeinterface/NativeGraphicPacks$GraphicPackBasicInfo");
|
||||
auto graphicPackInfoCtorId = env->GetMethodID(graphicPackInfoClass, "<init>", "(JLjava/lang/String;Ljava/util/ArrayList;)V");
|
||||
|
||||
std::vector<jobject> graphicPackInfoJObjects;
|
||||
for (auto&& graphicPack : NativeGraphicPacks::s_graphicPacks)
|
||||
{
|
||||
jstring virtualPath = env->NewStringUTF(graphicPack.second->GetVirtualPath().c_str());
|
||||
jlong id = graphicPack.first;
|
||||
jobject titleIds = JNIUtils::createJavaLongArrayList(env, graphicPack.second->GetTitleIds());
|
||||
jobject jGraphicPack = env->NewObject(graphicPackInfoClass, graphicPackInfoCtorId, id, virtualPath, titleIds);
|
||||
graphicPackInfoJObjects.push_back(jGraphicPack);
|
||||
}
|
||||
return JNIUtils::createArrayList(env, graphicPackInfoJObjects);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGraphicPacks_getGraphicPack(JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id)
|
||||
{
|
||||
auto graphicPackClass = env->FindClass("info/cemu/Cemu/nativeinterface/NativeGraphicPacks$GraphicPack");
|
||||
auto graphicPackCtorId = env->GetMethodID(graphicPackClass, "<init>", "(JZLjava/lang/String;Ljava/lang/String;Ljava/util/ArrayList;)V");
|
||||
auto graphicPack = NativeGraphicPacks::s_graphicPacks.at(id);
|
||||
|
||||
jstring graphicPackName = env->NewStringUTF(graphicPack->GetName().c_str());
|
||||
jstring graphicPackDescription = env->NewStringUTF(graphicPack->GetDescription().c_str());
|
||||
return env->NewObject(
|
||||
graphicPackClass,
|
||||
graphicPackCtorId,
|
||||
id,
|
||||
graphicPack->IsEnabled(),
|
||||
graphicPackName,
|
||||
graphicPackDescription,
|
||||
NativeGraphicPacks::getGraphicPresets(env, graphicPack, id));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGraphicPacks_setGraphicPackActive([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id, jboolean active)
|
||||
{
|
||||
auto graphicPack = NativeGraphicPacks::s_graphicPacks.at(id);
|
||||
graphicPack->SetEnabled(active);
|
||||
NativeGraphicPacks::saveGraphicPackStateToConfig(graphicPack);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGraphicPacks_setGraphicPackActivePreset([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id, jstring category, jstring preset)
|
||||
{
|
||||
std::string presetCategory = category == nullptr ? "" : JNIUtils::JStringToString(env, category);
|
||||
auto graphicPack = NativeGraphicPacks::s_graphicPacks.at(id);
|
||||
graphicPack->SetActivePreset(presetCategory, JNIUtils::JStringToString(env, preset));
|
||||
NativeGraphicPacks::saveGraphicPackStateToConfig(graphicPack);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeGraphicPacks_getGraphicPackPresets(JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id)
|
||||
{
|
||||
return NativeGraphicPacks::getGraphicPresets(env, NativeGraphicPacks::s_graphicPacks.at(id), id);
|
||||
}
|
190
src/android/app/src/main/cpp/NativeInput.cpp
Normal file
190
src/android/app/src/main/cpp/NativeInput.cpp
Normal file
@ -0,0 +1,190 @@
|
||||
#include "JNIUtils.h"
|
||||
#include "input/ControllerFactory.h"
|
||||
#include "input/InputManager.h"
|
||||
#include "input/api/Android/AndroidController.h"
|
||||
#include "input/api/Android/AndroidControllerProvider.h"
|
||||
#include "AndroidEmulatedController.h"
|
||||
|
||||
namespace NativeInput
|
||||
{
|
||||
WiiUMotionHandler s_wiiUMotionHandler{};
|
||||
long s_lastMotionTimestamp = 0;
|
||||
|
||||
void onTouchEvent(sint32 x, sint32 y, bool isTV, std::optional<bool> status = {})
|
||||
{
|
||||
auto& instance = InputManager::instance();
|
||||
auto& touchInfo = isTV ? instance.m_main_mouse : instance.m_pad_mouse;
|
||||
std::scoped_lock lock(touchInfo.m_mutex);
|
||||
touchInfo.position = {x, y};
|
||||
if (status.has_value())
|
||||
touchInfo.left_down = touchInfo.left_down_toggle = status.value();
|
||||
}
|
||||
} // namespace NativeInput
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onNativeKey(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint key, jboolean is_pressed)
|
||||
{
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
auto apiProvider = InputManager::instance().get_api_provider(InputAPI::Android);
|
||||
auto androidControllerProvider = dynamic_cast<AndroidControllerProvider*>(apiProvider.get());
|
||||
androidControllerProvider->on_key_event(deviceDescriptor, deviceName, key, is_pressed);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onNativeAxis(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint axis, jfloat value)
|
||||
{
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
auto apiProvider = InputManager::instance().get_api_provider(InputAPI::Android);
|
||||
auto androidControllerProvider = dynamic_cast<AndroidControllerProvider*>(apiProvider.get());
|
||||
androidControllerProvider->on_axis_event(deviceDescriptor, deviceName, axis, value);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_setControllerType([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index, jint emulated_controller_type)
|
||||
{
|
||||
auto type = static_cast<EmulatedController::Type>(emulated_controller_type);
|
||||
auto& androidEmulatedController = AndroidEmulatedController::getAndroidEmulatedController(index);
|
||||
if (EmulatedController::Type::VPAD <= type && type < EmulatedController::Type::MAX)
|
||||
androidEmulatedController.setType(type);
|
||||
else
|
||||
androidEmulatedController.setDisabled();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_getControllerType([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index)
|
||||
{
|
||||
auto emulatedController = AndroidEmulatedController::getAndroidEmulatedController(index).getEmulatedController();
|
||||
if (emulatedController)
|
||||
return emulatedController->type();
|
||||
throw std::runtime_error(fmt::format("can't get type for emulated controller {}", index));
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_getWPADControllersCount([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
int wpadCount = 0;
|
||||
for (size_t i = 0; i < InputManager::kMaxController; i++)
|
||||
{
|
||||
auto emulatedController = AndroidEmulatedController::getAndroidEmulatedController(i).getEmulatedController();
|
||||
if (!emulatedController)
|
||||
continue;
|
||||
if (emulatedController->type() != EmulatedController::Type::VPAD)
|
||||
++wpadCount;
|
||||
}
|
||||
return wpadCount;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_getVPADControllersCount([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
int vpadCount = 0;
|
||||
for (size_t i = 0; i < InputManager::kMaxController; i++)
|
||||
{
|
||||
auto emulatedController = AndroidEmulatedController::getAndroidEmulatedController(i).getEmulatedController();
|
||||
if (!emulatedController)
|
||||
continue;
|
||||
if (emulatedController->type() == EmulatedController::Type::VPAD)
|
||||
++vpadCount;
|
||||
}
|
||||
return vpadCount;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_isControllerDisabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index)
|
||||
{
|
||||
return AndroidEmulatedController::getAndroidEmulatedController(index).getEmulatedController() == nullptr;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_setControllerMapping(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint index, jint mapping_id, jint button_id)
|
||||
{
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
auto apiProvider = InputManager::instance().get_api_provider(InputAPI::Android);
|
||||
auto controller = ControllerFactory::CreateController(InputAPI::Android, deviceDescriptor, deviceName);
|
||||
AndroidEmulatedController::getAndroidEmulatedController(index).setMapping(mapping_id, controller, button_id);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jstring JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_getControllerMapping(JNIEnv* env, [[maybe_unused]] jclass clazz, jint index, jint mapping_id)
|
||||
{
|
||||
auto mapping = AndroidEmulatedController::getAndroidEmulatedController(index).getMapping(mapping_id);
|
||||
return env->NewStringUTF(mapping.value_or("").c_str());
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_clearControllerMapping([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index, jint mapping_id)
|
||||
{
|
||||
AndroidEmulatedController::getAndroidEmulatedController(index).clearMapping(mapping_id);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_getControllerMappings(JNIEnv* env, [[maybe_unused]] jclass clazz, jint index)
|
||||
{
|
||||
jclass hashMapClass = env->FindClass("java/util/HashMap");
|
||||
jmethodID hashMapConstructor = env->GetMethodID(hashMapClass, "<init>", "()V");
|
||||
jmethodID hashMapPut = env->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
jclass integerClass = env->FindClass("java/lang/Integer");
|
||||
jmethodID integerConstructor = env->GetMethodID(integerClass, "<init>", "(I)V");
|
||||
jobject hashMapObj = env->NewObject(hashMapClass, hashMapConstructor);
|
||||
auto mappings = AndroidEmulatedController::getAndroidEmulatedController(index).getMappings();
|
||||
for (const auto& pair : mappings)
|
||||
{
|
||||
jint key = pair.first;
|
||||
jstring buttonName = env->NewStringUTF(pair.second.c_str());
|
||||
jobject mappingId = env->NewObject(integerClass, integerConstructor, key);
|
||||
env->CallObjectMethod(hashMapObj, hashMapPut, mappingId, buttonName);
|
||||
}
|
||||
return hashMapObj;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onTouchDown([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint x, jint y, jboolean isTV)
|
||||
{
|
||||
NativeInput::onTouchEvent(x, y, isTV, true);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onTouchUp([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint x, jint y, jboolean isTV)
|
||||
{
|
||||
NativeInput::onTouchEvent(x, y, isTV, false);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onTouchMove([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint x, jint y, jboolean isTV)
|
||||
{
|
||||
NativeInput::onTouchEvent(x, y, isTV);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onMotion([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jlong timestamp, jfloat gyroX, jfloat gyroY, jfloat gyroZ, jfloat accelX, jfloat accelY, jfloat accelZ)
|
||||
{
|
||||
float deltaTime = (timestamp - NativeInput::s_lastMotionTimestamp) * 1e-9f;
|
||||
NativeInput::s_wiiUMotionHandler.processMotionSample(deltaTime, gyroX, gyroY, gyroZ, accelX * 0.098066f, -accelY * 0.098066f, -accelZ * 0.098066f);
|
||||
NativeInput::s_lastMotionTimestamp = timestamp;
|
||||
auto& deviceMotion = InputManager::instance().m_device_motion;
|
||||
std::scoped_lock lock{deviceMotion.m_mutex};
|
||||
deviceMotion.m_motion_sample = NativeInput::s_wiiUMotionHandler.getMotionSample();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_setMotionEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean motionEnabled)
|
||||
{
|
||||
auto& deviceMotion = InputManager::instance().m_device_motion;
|
||||
std::scoped_lock lock{deviceMotion.m_mutex};
|
||||
deviceMotion.m_device_motion_enabled = motionEnabled;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onOverlayButton([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint controllerIndex, jint mappingId, jboolean state)
|
||||
{
|
||||
AndroidEmulatedController::getAndroidEmulatedController(controllerIndex).setButtonValue(mappingId, state);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeInput_onOverlayAxis([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint controllerIndex, jint mappingId, jfloat value)
|
||||
{
|
||||
AndroidEmulatedController::getAndroidEmulatedController(controllerIndex).setAxisValue(mappingId, value);
|
||||
}
|
7
src/android/app/src/main/cpp/NativeLib.cpp
Normal file
7
src/android/app/src/main/cpp/NativeLib.cpp
Normal file
@ -0,0 +1,7 @@
|
||||
#include "JNIUtils.h"
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, [[maybe_unused]] void* reserved)
|
||||
{
|
||||
JNIUtils::g_jvm = vm;
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
271
src/android/app/src/main/cpp/NativeSettings.cpp
Normal file
271
src/android/app/src/main/cpp/NativeSettings.cpp
Normal file
@ -0,0 +1,271 @@
|
||||
#include "JNIUtils.h"
|
||||
#include "config/CemuConfig.h"
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getOverlayPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return static_cast<jint>(g_config.data().overlay.position);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint position)
|
||||
{
|
||||
g_config.data().overlay.position = static_cast<ScreenPosition>(position);
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isOverlayFPSEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.fps;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayFPSEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.fps = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isOverlayDrawCallsPerFrameEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.drawcalls;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayDrawCallsPerFrameEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.drawcalls = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isOverlayCPUUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.cpu_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayCPUUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.cpu_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isOverlayCPUPerCoreUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.cpu_per_core_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayCPUPerCoreUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.cpu_per_core_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isOverlayRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.ram_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.ram_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isOverlayVRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.vram_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayVRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.vram_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isOverlayDebugEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.debug;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setOverlayDebugEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.debug = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getNotificationsPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return static_cast<jint>(g_config.data().notification.position);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setNotificationsPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint position)
|
||||
{
|
||||
g_config.data().notification.position = static_cast<ScreenPosition>(position);
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isNotificationControllerProfilesEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().notification.controller_profiles;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setNotificationControllerProfilesEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().notification.controller_profiles = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isNotificationShaderCompilerEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().notification.shader_compiling;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setNotificationShaderCompilerEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().notification.shader_compiling = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_isNotificationFriendListEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().notification.friends;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setNotificationFriendListEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().notification.friends = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_addGamesPath(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring uri)
|
||||
{
|
||||
auto& gamePaths = g_config.data().game_paths;
|
||||
auto gamePath = JNIUtils::JStringToString(env, uri);
|
||||
if (std::any_of(gamePaths.begin(), gamePaths.end(), [&](auto path) { return path == gamePath; }))
|
||||
return;
|
||||
gamePaths.push_back(gamePath);
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_removeGamesPath(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring uri)
|
||||
{
|
||||
auto gamePath = JNIUtils::JStringToString(env, uri);
|
||||
auto& gamePaths = g_config.data().game_paths;
|
||||
std::erase_if(gamePaths, [&](auto path) { return path == gamePath; });
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getGamesPaths(JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return JNIUtils::createJavaStringArrayList(env, g_config.data().game_paths);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getAsyncShaderCompile([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().async_compile;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setAsyncShaderCompile([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().async_compile = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getVSyncMode([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().vsync;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setVSyncMode([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint vsync_mode)
|
||||
{
|
||||
g_config.data().vsync = vsync_mode;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getAccurateBarriers([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().vk_accurate_barriers;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setAccurateBarriers([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().vk_accurate_barriers = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getAudioDeviceEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean tv)
|
||||
{
|
||||
const auto& device = tv ? g_config.data().tv_device : g_config.data().pad_device;
|
||||
return !device.empty();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setAudioDeviceEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled, jboolean tv)
|
||||
{
|
||||
auto& device = tv ? g_config.data().tv_device : g_config.data().pad_device;
|
||||
if (enabled)
|
||||
device = L"Default";
|
||||
else
|
||||
device.clear();
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getAudioDeviceChannels([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean tv)
|
||||
{
|
||||
const auto& deviceChannels = tv ? g_config.data().tv_channels : g_config.data().pad_channels;
|
||||
return deviceChannels;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setAudioDeviceChannels([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint channels, jboolean tv)
|
||||
{
|
||||
auto& deviceChannels = tv ? g_config.data().tv_channels : g_config.data().pad_channels;
|
||||
deviceChannels = static_cast<AudioChannels>(channels);
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_getAudioDeviceVolume([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean tv)
|
||||
{
|
||||
const auto& deviceVolume = tv ? g_config.data().tv_volume : g_config.data().pad_volume;
|
||||
return deviceVolume;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_nativeinterface_NativeSettings_setAudioDeviceVolume([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint volume, jboolean tv)
|
||||
{
|
||||
auto& deviceVolume = tv ? g_config.data().tv_volume : g_config.data().pad_volume;
|
||||
deviceVolume = volume;
|
||||
g_config.Save();
|
||||
}
|
@ -1,80 +0,0 @@
|
||||
#include "Utils.h"
|
||||
|
||||
#include "Cemu/ncrypto/ncrypto.h"
|
||||
#include "config/ActiveSettings.h"
|
||||
|
||||
void createCemuDirectories()
|
||||
{
|
||||
std::wstring mlc = ActiveSettings::GetMlcPath().generic_wstring();
|
||||
|
||||
// create sys/usr folder in mlc01
|
||||
try
|
||||
{
|
||||
const auto sysFolder = fs::path(mlc).append(L"sys");
|
||||
fs::create_directories(sysFolder);
|
||||
|
||||
const auto usrFolder = fs::path(mlc).append(L"usr");
|
||||
fs::create_directories(usrFolder);
|
||||
fs::create_directories(fs::path(usrFolder).append("title/00050000")); // base
|
||||
fs::create_directories(fs::path(usrFolder).append("title/0005000c")); // dlc
|
||||
fs::create_directories(fs::path(usrFolder).append("title/0005000e")); // update
|
||||
|
||||
// Mii Maker save folders {0x500101004A000, 0x500101004A100, 0x500101004A200},
|
||||
fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a000/user/common/db"));
|
||||
fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a100/user/common/db"));
|
||||
fs::create_directories(fs::path(mlc).append(L"usr/save/00050010/1004a200/user/common/db"));
|
||||
|
||||
// lang files
|
||||
auto langDir = fs::path(mlc).append(L"sys/title/0005001b/1005c000/content");
|
||||
fs::create_directories(langDir);
|
||||
|
||||
auto langFile = fs::path(langDir).append("language.txt");
|
||||
if (!fs::exists(langFile))
|
||||
{
|
||||
std::ofstream file(langFile);
|
||||
if (file.is_open())
|
||||
{
|
||||
const char* langStrings[] = {"ja", "en", "fr", "de", "it", "es", "zh", "ko", "nl", "pt", "ru", "zh"};
|
||||
for (const char* lang : langStrings)
|
||||
file << fmt::format(R"("{}",)", lang) << std::endl;
|
||||
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
|
||||
auto countryFile = fs::path(langDir).append("country.txt");
|
||||
if (!fs::exists(countryFile))
|
||||
{
|
||||
std::ofstream file(countryFile);
|
||||
for (sint32 i = 0; i < 201; i++)
|
||||
{
|
||||
const char* countryCode = NCrypto::GetCountryAsString(i);
|
||||
if (boost::iequals(countryCode, "NN"))
|
||||
file << "NULL," << std::endl;
|
||||
else
|
||||
file << fmt::format(R"("{}",)", countryCode) << std::endl;
|
||||
}
|
||||
file.flush();
|
||||
file.close();
|
||||
}
|
||||
} catch (const std::exception& ex)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// cemu directories
|
||||
try
|
||||
{
|
||||
const auto controllerProfileFolder = ActiveSettings::GetConfigPath(L"controllerProfiles").generic_wstring();
|
||||
if (!fs::exists(controllerProfileFolder))
|
||||
fs::create_directories(controllerProfileFolder);
|
||||
|
||||
const auto memorySearcherFolder = ActiveSettings::GetUserDataPath(L"memorySearcher").generic_wstring();
|
||||
if (!fs::exists(memorySearcherFolder))
|
||||
fs::create_directories(memorySearcherFolder);
|
||||
} catch (const std::exception& ex)
|
||||
{
|
||||
exit(0);
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "config/ActiveSettings.h"
|
||||
#include "Cemu/ncrypto/ncrypto.h"
|
||||
|
||||
void createCemuDirectories();
|
@ -1,638 +0,0 @@
|
||||
#include "Cafe/GraphicPack/GraphicPack2.h"
|
||||
#include "AndroidGameTitleLoadedCallback.h"
|
||||
#include "EmulationState.h"
|
||||
#include "JNIUtils.h"
|
||||
|
||||
EmulationState s_emulationState;
|
||||
|
||||
static_assert(sizeof(TitleId) == sizeof(jlong));
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, [[maybe_unused]] void* reserved)
|
||||
{
|
||||
JNIUtils::g_jvm = vm;
|
||||
return JNI_VERSION_1_6;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setSurface(JNIEnv* env, [[maybe_unused]] jclass clazz, jobject surface, jboolean is_main_canvas)
|
||||
{
|
||||
JNIUtils::handleNativeException(env, [&]() {
|
||||
s_emulationState.setSurface(env, surface, is_main_canvas);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setSurfaceSize([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint width, jint height, jboolean is_main_canvas)
|
||||
{
|
||||
s_emulationState.setSurfaceSize(width, height, is_main_canvas);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_startGame([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jstring launchPath)
|
||||
{
|
||||
using namespace CafeSystemUtils;
|
||||
try
|
||||
{
|
||||
s_emulationState.startGame(JNIUtils::JStringToString(env, launchPath));
|
||||
} catch (const GameBaseFilesNotFoundException& exception)
|
||||
{
|
||||
jclass exceptionClass = env->FindClass("info/cemu/Cemu/NativeLibrary$GameBaseFilesNotFoundException");
|
||||
env->ThrowNew(exceptionClass, exception.what());
|
||||
} catch (const NoDiscKeyException& exception)
|
||||
{
|
||||
jclass exceptionClass = env->FindClass("info/cemu/Cemu/NativeLibrary$NoDiscKeyException");
|
||||
env->ThrowNew(exceptionClass, exception.what());
|
||||
} catch (const NoTitleTikException& exception)
|
||||
{
|
||||
jclass exceptionClass = env->FindClass("info/cemu/Cemu/NativeLibrary$NoTitleTikException");
|
||||
env->ThrowNew(exceptionClass, exception.what());
|
||||
} catch (const std::exception& exception)
|
||||
{
|
||||
jclass exceptionClass = env->FindClass("info/cemu/Cemu/NativeLibrary$UnknownGameFilesException");
|
||||
env->ThrowNew(exceptionClass, exception.what());
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setGameTitleLoadedCallback(JNIEnv* env, [[maybe_unused]] jclass clazz, jobject game_title_loaded_callback)
|
||||
{
|
||||
if (game_title_loaded_callback == nullptr)
|
||||
{
|
||||
s_emulationState.setOnGameTitleLoaded(nullptr);
|
||||
return;
|
||||
}
|
||||
jclass gameTitleLoadedCallbackClass = env->GetObjectClass(game_title_loaded_callback);
|
||||
jmethodID onGameTitleLoadedMID = env->GetMethodID(gameTitleLoadedCallbackClass, "onGameTitleLoaded", "(Ljava/lang/String;Ljava/lang/String;[III)V");
|
||||
env->DeleteLocalRef(gameTitleLoadedCallbackClass);
|
||||
s_emulationState.setOnGameTitleLoaded(std::make_shared<AndroidGameTitleLoadedCallback>(onGameTitleLoadedMID, game_title_loaded_callback));
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_reloadGameTitles([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
s_emulationState.reloadGameTitles();
|
||||
}
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_initializeActiveSettings(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring data_path, jstring cache_path)
|
||||
{
|
||||
std::string dataPath = JNIUtils::JStringToString(env, data_path);
|
||||
std::string cachePath = JNIUtils::JStringToString(env, cache_path);
|
||||
s_emulationState.initializeActiveSettings(dataPath, cachePath);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_initializeEmulation([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
s_emulationState.initializeEmulation();
|
||||
}
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_initializerRenderer(JNIEnv* env, [[maybe_unused]] jclass clazz, jobject testSurface)
|
||||
{
|
||||
JNIUtils::handleNativeException(env, [&]() {
|
||||
s_emulationState.initializeRenderer(env, testSurface);
|
||||
});
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setDPI([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jfloat dpi)
|
||||
{
|
||||
s_emulationState.setDPI(dpi);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_clearSurface([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean is_main_canvas)
|
||||
{
|
||||
s_emulationState.clearSurface(is_main_canvas);
|
||||
}
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_recreateRenderSurface([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean is_main_canvas)
|
||||
{
|
||||
s_emulationState.notifySurfaceChanged(is_main_canvas);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_addGamesPath(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring uri)
|
||||
{
|
||||
s_emulationState.addGamesPath(JNIUtils::JStringToString(env, uri));
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_removeGamesPath(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring uri)
|
||||
{
|
||||
s_emulationState.removeGamesPath(JNIUtils::JStringToString(env, uri));
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getGamesPaths(JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return JNIUtils::createJavaStringArrayList(env, g_config.data().game_paths);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onNativeKey(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint key, jboolean is_pressed)
|
||||
{
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
s_emulationState.onKeyEvent(deviceDescriptor, deviceName, key, is_pressed);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onNativeAxis(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint axis, jfloat value)
|
||||
{
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
s_emulationState.onAxisEvent(deviceDescriptor, deviceName, axis, value);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setControllerType([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index, jint emulated_controller_type)
|
||||
{
|
||||
s_emulationState.setEmulatedControllerType(index, static_cast<EmulatedController::Type>(emulated_controller_type));
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getControllerType([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index)
|
||||
{
|
||||
return s_emulationState.getEmulatedControllerType(index);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getWPADControllersCount([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return s_emulationState.getWPADControllersCount();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getVPADControllersCount([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return s_emulationState.getVPADControllersCount();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isControllerDisabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index)
|
||||
{
|
||||
return s_emulationState.isEmulatedControllerDisabled(index);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setControllerMapping(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint index, jint mapping_id, jint button_id)
|
||||
{
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
s_emulationState.setControllerMapping(deviceDescriptor, deviceName, index, mapping_id, button_id);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jstring JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getControllerMapping(JNIEnv* env, [[maybe_unused]] jclass clazz, jint index, jint mapping_id)
|
||||
{
|
||||
auto mapping = s_emulationState.getEmulatedControllerMapping(index, mapping_id);
|
||||
return env->NewStringUTF(mapping.value_or("").c_str());
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_clearControllerMapping([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint index, jint mapping_id)
|
||||
{
|
||||
s_emulationState.clearEmulatedControllerMapping(index, mapping_id);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getControllerMappings(JNIEnv* env, [[maybe_unused]] jclass clazz, jint index)
|
||||
{
|
||||
jclass hashMapClass = env->FindClass("java/util/HashMap");
|
||||
jmethodID hashMapConstructor = env->GetMethodID(hashMapClass, "<init>", "()V");
|
||||
jmethodID hashMapPut = env->GetMethodID(hashMapClass, "put", "(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;");
|
||||
jclass integerClass = env->FindClass("java/lang/Integer");
|
||||
jmethodID integerConstructor = env->GetMethodID(integerClass, "<init>", "(I)V");
|
||||
jobject hashMapObj = env->NewObject(hashMapClass, hashMapConstructor);
|
||||
auto mappings = s_emulationState.getEmulatedControllerMappings(index);
|
||||
for (const auto& pair : mappings)
|
||||
{
|
||||
jint key = pair.first;
|
||||
jstring buttonName = env->NewStringUTF(pair.second.c_str());
|
||||
jobject mappingId = env->NewObject(integerClass, integerConstructor, key);
|
||||
env->CallObjectMethod(hashMapObj, hashMapPut, mappingId, buttonName);
|
||||
}
|
||||
return hashMapObj;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onKeyEvent(JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint key_code, jboolean is_pressed)
|
||||
{
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
s_emulationState.onKeyEvent(deviceDescriptor, deviceName, key_code, is_pressed);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onAxisEvent([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jstring device_descriptor, jstring device_name, jint axis_code, jfloat value)
|
||||
{
|
||||
auto deviceDescriptor = JNIUtils::JStringToString(env, device_descriptor);
|
||||
auto deviceName = JNIUtils::JStringToString(env, device_name);
|
||||
s_emulationState.onAxisEvent(deviceDescriptor, deviceName, axis_code, value);
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getAsyncShaderCompile([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().async_compile;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setAsyncShaderCompile([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().async_compile = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getVSyncMode([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().vsync;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setVSyncMode([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint vsync_mode)
|
||||
{
|
||||
g_config.data().vsync = vsync_mode;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getAccurateBarriers([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().vk_accurate_barriers;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setAccurateBarriers([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().vk_accurate_barriers = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getAudioDeviceEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean tv)
|
||||
{
|
||||
const auto& device = tv ? g_config.data().tv_device : g_config.data().pad_device;
|
||||
return !device.empty();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setAudioDeviceEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled, jboolean tv)
|
||||
{
|
||||
auto& device = tv ? g_config.data().tv_device : g_config.data().pad_device;
|
||||
if (enabled)
|
||||
device = L"Default";
|
||||
else
|
||||
device.clear();
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getAudioDeviceChannels([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean tv)
|
||||
{
|
||||
const auto& deviceChannels = tv ? g_config.data().tv_channels : g_config.data().pad_channels;
|
||||
return deviceChannels;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setAudioDeviceChannels([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint channels, jboolean tv)
|
||||
{
|
||||
auto& deviceChannels = tv ? g_config.data().tv_channels : g_config.data().pad_channels;
|
||||
deviceChannels = static_cast<AudioChannels>(channels);
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getAudioDeviceVolume([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean tv)
|
||||
{
|
||||
const auto& deviceVolume = tv ? g_config.data().tv_volume : g_config.data().pad_volume;
|
||||
return deviceVolume;
|
||||
}
|
||||
|
||||
extern "C" [[maybe_unused]] JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setAudioDeviceVolume([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint volume, jboolean tv)
|
||||
{
|
||||
auto& deviceVolume = tv ? g_config.data().tv_volume : g_config.data().pad_volume;
|
||||
deviceVolume = volume;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_refreshGraphicPacks([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
s_emulationState.refreshGraphicPacks();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getGraphicPackBasicInfos(JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
auto graphicPackInfoClass = env->FindClass("info/cemu/Cemu/NativeLibrary$GraphicPackBasicInfo");
|
||||
auto graphicPackInfoCtorId = env->GetMethodID(graphicPackInfoClass, "<init>", "(JLjava/lang/String;Ljava/util/ArrayList;)V");
|
||||
|
||||
auto graphicPacks = s_emulationState.getGraphicPacks();
|
||||
std::vector<jobject> graphicPackInfoJObjects;
|
||||
for (auto&& graphicPack : graphicPacks)
|
||||
{
|
||||
jstring virtualPath = env->NewStringUTF(graphicPack.second->GetVirtualPath().c_str());
|
||||
jlong id = graphicPack.first;
|
||||
jobject titleIds = JNIUtils::createJavaLongArrayList(env, graphicPack.second->GetTitleIds());
|
||||
jobject jGraphicPack = env->NewObject(graphicPackInfoClass, graphicPackInfoCtorId, id, virtualPath, titleIds);
|
||||
graphicPackInfoJObjects.push_back(jGraphicPack);
|
||||
}
|
||||
return JNIUtils::createArrayList(env, graphicPackInfoJObjects);
|
||||
}
|
||||
|
||||
jobject getGraphicPresets(JNIEnv* env, GraphicPackPtr graphicPack, int64_t id)
|
||||
{
|
||||
auto graphicPackPresetClass = env->FindClass("info/cemu/Cemu/NativeLibrary$GraphicPackPreset");
|
||||
auto graphicPackPresetCtorId = env->GetMethodID(graphicPackPresetClass, "<init>", "(JLjava/lang/String;Ljava/util/ArrayList;Ljava/lang/String;)V");
|
||||
|
||||
std::vector<std::string> order;
|
||||
auto presets = graphicPack->GetCategorizedPresets(order);
|
||||
|
||||
std::vector<jobject> presetsJobjects;
|
||||
for (const auto& category : order)
|
||||
{
|
||||
const auto& entry = presets[category];
|
||||
// test if any preset is visible and update its status
|
||||
if (std::none_of(entry.cbegin(), entry.cend(), [graphicPack](const auto& p) { return p->visible; }))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
jstring categoryJStr = category.empty() ? nullptr : env->NewStringUTF(category.c_str());
|
||||
std::vector<std::string> presetSelections;
|
||||
std::optional<std::string> activePreset;
|
||||
for (auto& pentry : entry)
|
||||
{
|
||||
if (!pentry->visible)
|
||||
continue;
|
||||
|
||||
presetSelections.push_back(pentry->name);
|
||||
|
||||
if (pentry->active)
|
||||
activePreset = pentry->name;
|
||||
}
|
||||
|
||||
jstring activePresetJstr = nullptr;
|
||||
if (activePreset)
|
||||
activePresetJstr = env->NewStringUTF(activePreset->c_str());
|
||||
else if (!presetSelections.empty())
|
||||
activePresetJstr = env->NewStringUTF(presetSelections.front().c_str());
|
||||
auto presetJObject = env->NewObject(graphicPackPresetClass,
|
||||
graphicPackPresetCtorId,
|
||||
id,
|
||||
categoryJStr,
|
||||
JNIUtils::createJavaStringArrayList(env, presetSelections),
|
||||
activePresetJstr);
|
||||
presetsJobjects.push_back(presetJObject);
|
||||
}
|
||||
return JNIUtils::createArrayList(env, presetsJobjects);
|
||||
}
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getGraphicPack(JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id)
|
||||
{
|
||||
auto graphicPackClass = env->FindClass("info/cemu/Cemu/NativeLibrary$GraphicPack");
|
||||
auto graphicPackCtorId = env->GetMethodID(graphicPackClass, "<init>", "(JZLjava/lang/String;Ljava/lang/String;Ljava/util/ArrayList;)V");
|
||||
auto graphicPack = s_emulationState.getGraphicPack(id);
|
||||
|
||||
jstring graphicPackName = env->NewStringUTF(graphicPack->GetName().c_str());
|
||||
jstring graphicPackDescription = env->NewStringUTF(graphicPack->GetDescription().c_str());
|
||||
return env->NewObject(graphicPackClass,
|
||||
graphicPackCtorId,
|
||||
id,
|
||||
graphicPack->IsEnabled(),
|
||||
graphicPackName,
|
||||
graphicPackDescription,
|
||||
getGraphicPresets(env, graphicPack, id));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setGraphicPackActive([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id, jboolean active)
|
||||
{
|
||||
s_emulationState.setEnabledStateForGraphicPack(id, active);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setGraphicPackActivePreset([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id, jstring category, jstring preset)
|
||||
{
|
||||
std::string presetCategory = category == nullptr ? "" : JNIUtils::JStringToString(env, category);
|
||||
s_emulationState.setGraphicPackActivePreset(id, presetCategory, JNIUtils::JStringToString(env, preset));
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getGraphicPackPresets(JNIEnv* env, [[maybe_unused]] jclass clazz, jlong id)
|
||||
{
|
||||
return getGraphicPresets(env, s_emulationState.getGraphicPack(id), id);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onOverlayButton([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint controllerIndex, jint mappingId, jboolean state)
|
||||
{
|
||||
s_emulationState.getEmulatedController(controllerIndex).setButtonValue(mappingId, state);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onOverlayAxis([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint controllerIndex, jint mappingId, jfloat value)
|
||||
{
|
||||
s_emulationState.getEmulatedController(controllerIndex).setAxisValue(mappingId, value);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getOverlayPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return static_cast<jint>(g_config.data().overlay.position);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint position)
|
||||
{
|
||||
g_config.data().overlay.position = static_cast<ScreenPosition>(position);
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isOverlayFPSEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.fps;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayFPSEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.fps = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isOverlayDrawCallsPerFrameEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.drawcalls;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayDrawCallsPerFrameEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.drawcalls = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isOverlayCPUUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.cpu_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayCPUUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.cpu_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isOverlayCPUPerCoreUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.cpu_per_core_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayCPUPerCoreUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.cpu_per_core_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isOverlayRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.ram_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.ram_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isOverlayVRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.vram_usage;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayVRAMUsageEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.vram_usage = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isOverlayDebugEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().overlay.debug;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setOverlayDebugEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().overlay.debug = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jint JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getNotificationsPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return static_cast<jint>(g_config.data().notification.position);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setNotificationsPosition([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint position)
|
||||
{
|
||||
g_config.data().notification.position = static_cast<ScreenPosition>(position);
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isNotificationControllerProfilesEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().notification.controller_profiles;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setNotificationControllerProfilesEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().notification.controller_profiles = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isNotificationShaderCompilerEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().notification.shader_compiling;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setNotificationShaderCompilerEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().notification.shader_compiling = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jboolean JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_isNotificationFriendListEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return g_config.data().notification.friends;
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setNotificationFriendListEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean enabled)
|
||||
{
|
||||
g_config.data().notification.friends = enabled;
|
||||
g_config.Save();
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setReplaceTVWithPadView([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean swapped)
|
||||
{
|
||||
s_emulationState.setReplaceTVWithPadView(swapped);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onTouchDown([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint x, jint y, jboolean isTV)
|
||||
{
|
||||
s_emulationState.onTouchDown(x, y, isTV);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onTouchUp([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint x, jint y, jboolean isTV)
|
||||
{
|
||||
s_emulationState.onTouchUp(x, y, isTV);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onTouchMove([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jint x, jint y, jboolean isTV)
|
||||
{
|
||||
s_emulationState.onTouchMove(x, y, isTV);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT jobject JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_getInstalledGamesTitleIds(JNIEnv* env, [[maybe_unused]] jclass clazz)
|
||||
{
|
||||
return JNIUtils::createJavaLongArrayList(env, CafeTitleList::GetAllTitleIds());
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_onMotion([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jlong timestamp, jfloat gyroX, jfloat gyroY, jfloat gyroZ, jfloat accelX, jfloat accelY, jfloat accelZ)
|
||||
{
|
||||
s_emulationState.onMotion(timestamp, gyroX, gyroY, gyroZ, accelX, accelY, accelZ);
|
||||
}
|
||||
|
||||
extern "C" JNIEXPORT void JNICALL
|
||||
Java_info_cemu_Cemu_NativeLibrary_setMotionEnabled([[maybe_unused]] JNIEnv* env, [[maybe_unused]] jclass clazz, jboolean motionEnabled)
|
||||
{
|
||||
s_emulationState.setMotionEnabled(motionEnabled);
|
||||
}
|
@ -4,12 +4,15 @@ import android.app.Application;
|
||||
import android.util.DisplayMetrics;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.utils.FileUtil;
|
||||
import info.cemu.Cemu.nativeinterface.NativeEmulation;
|
||||
import info.cemu.Cemu.nativeinterface.NativeGraphicPacks;
|
||||
|
||||
public class CemuApplication extends Application {
|
||||
static {
|
||||
System.loadLibrary("CemuAndroid");
|
||||
}
|
||||
|
||||
private static CemuApplication application;
|
||||
|
||||
public CemuApplication() {
|
||||
@ -31,8 +34,9 @@ public class CemuApplication extends Application {
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
DisplayMetrics displayMetrics = getResources().getDisplayMetrics();
|
||||
NativeLibrary.setDPI(displayMetrics.density);
|
||||
NativeLibrary.initializeActiveSettings(getInternalFolder().toString(), getInternalFolder().toString());
|
||||
NativeLibrary.initializeEmulation();
|
||||
NativeEmulation.setDPI(displayMetrics.density);
|
||||
NativeEmulation.initializeActiveSettings(getInternalFolder().toString(), getInternalFolder().toString());
|
||||
NativeEmulation.initializeEmulation();
|
||||
NativeGraphicPacks.refreshGraphicPacks();
|
||||
}
|
||||
}
|
||||
|
@ -1,412 +0,0 @@
|
||||
package info.cemu.Cemu;
|
||||
|
||||
import android.view.Surface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NativeLibrary {
|
||||
static {
|
||||
System.loadLibrary("CemuAndroid");
|
||||
}
|
||||
|
||||
public static native void setDPI(float dpi);
|
||||
|
||||
public static native void setSurface(Surface surface, boolean isMainCanvas);
|
||||
|
||||
public static native void clearSurface(boolean isMainCanvas);
|
||||
|
||||
public static native void setSurfaceSize(int width, int height, boolean isMainCanvas);
|
||||
|
||||
public static native void initializerRenderer(Surface surface);
|
||||
|
||||
public static class GameFilesException extends RuntimeException {
|
||||
}
|
||||
|
||||
public static class GameBaseFilesNotFoundException extends GameFilesException {
|
||||
}
|
||||
|
||||
public static class NoDiscKeyException extends GameFilesException {
|
||||
}
|
||||
|
||||
public static class NoTitleTikException extends GameFilesException {
|
||||
}
|
||||
|
||||
public static class UnknownGameFilesException extends GameFilesException {
|
||||
}
|
||||
|
||||
public static native void startGame(String launchPath);
|
||||
|
||||
public static native void setReplaceTVWithPadView(boolean swapped);
|
||||
|
||||
public static native void recreateRenderSurface(boolean isMainCanvas);
|
||||
|
||||
public interface GameTitleLoadedCallback {
|
||||
void onGameTitleLoaded(String path, String title, int[] colors, int width, int height);
|
||||
}
|
||||
|
||||
public static native void setGameTitleLoadedCallback(GameTitleLoadedCallback gameTitleLoadedCallback);
|
||||
|
||||
public static native void reloadGameTitles();
|
||||
|
||||
public static native void initializeActiveSettings(String dataPath, String cachePath);
|
||||
|
||||
public static native void initializeEmulation();
|
||||
|
||||
public static native void addGamesPath(String uri);
|
||||
|
||||
public static native void removeGamesPath(String uri);
|
||||
|
||||
public static native ArrayList<String> getGamesPaths();
|
||||
|
||||
public static native void onNativeKey(String deviceDescriptor, String deviceName, int key, boolean isPressed);
|
||||
|
||||
public static native void onNativeAxis(String deviceDescriptor, String deviceName, int axis, float value);
|
||||
|
||||
public static final int VPAD_BUTTON_NONE = 0;
|
||||
public static final int VPAD_BUTTON_A = 1;
|
||||
public static final int VPAD_BUTTON_B = 2;
|
||||
public static final int VPAD_BUTTON_X = 3;
|
||||
public static final int VPAD_BUTTON_Y = 4;
|
||||
public static final int VPAD_BUTTON_L = 5;
|
||||
public static final int VPAD_BUTTON_R = 6;
|
||||
public static final int VPAD_BUTTON_ZL = 7;
|
||||
public static final int VPAD_BUTTON_ZR = 8;
|
||||
public static final int VPAD_BUTTON_PLUS = 9;
|
||||
public static final int VPAD_BUTTON_MINUS = 10;
|
||||
public static final int VPAD_BUTTON_UP = 11;
|
||||
public static final int VPAD_BUTTON_DOWN = 12;
|
||||
public static final int VPAD_BUTTON_LEFT = 13;
|
||||
public static final int VPAD_BUTTON_RIGHT = 14;
|
||||
public static final int VPAD_BUTTON_STICKL = 15;
|
||||
public static final int VPAD_BUTTON_STICKR = 16;
|
||||
public static final int VPAD_BUTTON_STICKL_UP = 17;
|
||||
public static final int VPAD_BUTTON_STICKL_DOWN = 18;
|
||||
public static final int VPAD_BUTTON_STICKL_LEFT = 19;
|
||||
public static final int VPAD_BUTTON_STICKL_RIGHT = 20;
|
||||
public static final int VPAD_BUTTON_STICKR_UP = 21;
|
||||
public static final int VPAD_BUTTON_STICKR_DOWN = 22;
|
||||
public static final int VPAD_BUTTON_STICKR_LEFT = 23;
|
||||
public static final int VPAD_BUTTON_STICKR_RIGHT = 24;
|
||||
public static final int VPAD_BUTTON_MIC = 25;
|
||||
public static final int VPAD_BUTTON_SCREEN = 26;
|
||||
public static final int VPAD_BUTTON_HOME = 27;
|
||||
public static final int VPAD_BUTTON_MAX = 28;
|
||||
|
||||
public static final int PRO_BUTTON_NONE = 0;
|
||||
public static final int PRO_BUTTON_A = 1;
|
||||
public static final int PRO_BUTTON_B = 2;
|
||||
public static final int PRO_BUTTON_X = 3;
|
||||
public static final int PRO_BUTTON_Y = 4;
|
||||
public static final int PRO_BUTTON_L = 5;
|
||||
public static final int PRO_BUTTON_R = 6;
|
||||
public static final int PRO_BUTTON_ZL = 7;
|
||||
public static final int PRO_BUTTON_ZR = 8;
|
||||
public static final int PRO_BUTTON_PLUS = 9;
|
||||
public static final int PRO_BUTTON_MINUS = 10;
|
||||
public static final int PRO_BUTTON_HOME = 11;
|
||||
public static final int PRO_BUTTON_UP = 12;
|
||||
public static final int PRO_BUTTON_DOWN = 13;
|
||||
public static final int PRO_BUTTON_LEFT = 14;
|
||||
public static final int PRO_BUTTON_RIGHT = 15;
|
||||
public static final int PRO_BUTTON_STICKL = 16;
|
||||
public static final int PRO_BUTTON_STICKR = 17;
|
||||
public static final int PRO_BUTTON_STICKL_UP = 18;
|
||||
public static final int PRO_BUTTON_STICKL_DOWN = 19;
|
||||
public static final int PRO_BUTTON_STICKL_LEFT = 20;
|
||||
public static final int PRO_BUTTON_STICKL_RIGHT = 21;
|
||||
public static final int PRO_BUTTON_STICKR_UP = 22;
|
||||
public static final int PRO_BUTTON_STICKR_DOWN = 23;
|
||||
public static final int PRO_BUTTON_STICKR_LEFT = 24;
|
||||
public static final int PRO_BUTTON_STICKR_RIGHT = 25;
|
||||
public static final int PRO_BUTTON_MAX = 26;
|
||||
|
||||
public static final int CLASSIC_BUTTON_NONE = 0;
|
||||
public static final int CLASSIC_BUTTON_A = 1;
|
||||
public static final int CLASSIC_BUTTON_B = 2;
|
||||
public static final int CLASSIC_BUTTON_X = 3;
|
||||
public static final int CLASSIC_BUTTON_Y = 4;
|
||||
public static final int CLASSIC_BUTTON_L = 5;
|
||||
public static final int CLASSIC_BUTTON_R = 6;
|
||||
public static final int CLASSIC_BUTTON_ZL = 7;
|
||||
public static final int CLASSIC_BUTTON_ZR = 8;
|
||||
public static final int CLASSIC_BUTTON_PLUS = 9;
|
||||
public static final int CLASSIC_BUTTON_MINUS = 10;
|
||||
public static final int CLASSIC_BUTTON_HOME = 11;
|
||||
public static final int CLASSIC_BUTTON_UP = 12;
|
||||
public static final int CLASSIC_BUTTON_DOWN = 13;
|
||||
public static final int CLASSIC_BUTTON_LEFT = 14;
|
||||
public static final int CLASSIC_BUTTON_RIGHT = 15;
|
||||
public static final int CLASSIC_BUTTON_STICKL_UP = 16;
|
||||
public static final int CLASSIC_BUTTON_STICKL_DOWN = 17;
|
||||
public static final int CLASSIC_BUTTON_STICKL_LEFT = 18;
|
||||
public static final int CLASSIC_BUTTON_STICKL_RIGHT = 19;
|
||||
public static final int CLASSIC_BUTTON_STICKR_UP = 20;
|
||||
public static final int CLASSIC_BUTTON_STICKR_DOWN = 21;
|
||||
public static final int CLASSIC_BUTTON_STICKR_LEFT = 22;
|
||||
public static final int CLASSIC_BUTTON_STICKR_RIGHT = 23;
|
||||
public static final int CLASSIC_BUTTON_MAX = 24;
|
||||
|
||||
public static final int WIIMOTE_BUTTON_NONE = 0;
|
||||
public static final int WIIMOTE_BUTTON_A = 1;
|
||||
public static final int WIIMOTE_BUTTON_B = 2;
|
||||
public static final int WIIMOTE_BUTTON_1 = 3;
|
||||
public static final int WIIMOTE_BUTTON_2 = 4;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_Z = 5;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_C = 6;
|
||||
public static final int WIIMOTE_BUTTON_PLUS = 7;
|
||||
public static final int WIIMOTE_BUTTON_MINUS = 8;
|
||||
public static final int WIIMOTE_BUTTON_UP = 9;
|
||||
public static final int WIIMOTE_BUTTON_DOWN = 10;
|
||||
public static final int WIIMOTE_BUTTON_LEFT = 11;
|
||||
public static final int WIIMOTE_BUTTON_RIGHT = 12;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_UP = 13;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_DOWN = 14;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_LEFT = 15;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_RIGHT = 16;
|
||||
public static final int WIIMOTE_BUTTON_HOME = 17;
|
||||
public static final int WIIMOTE_BUTTON_MAX = 18;
|
||||
|
||||
public static final int EMULATED_CONTROLLER_TYPE_VPAD = 0;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_PRO = 1;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_CLASSIC = 2;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_WIIMOTE = 3;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_DISABLED = -1;
|
||||
|
||||
public static final int DPAD_UP = 34;
|
||||
public static final int DPAD_DOWN = 35;
|
||||
public static final int DPAD_LEFT = 36;
|
||||
public static final int DPAD_RIGHT = 37;
|
||||
public static final int AXIS_X_POS = 38;
|
||||
public static final int AXIS_Y_POS = 39;
|
||||
public static final int ROTATION_X_POS = 40;
|
||||
public static final int ROTATION_Y_POS = 41;
|
||||
public static final int TRIGGER_X_POS = 42;
|
||||
public static final int TRIGGER_Y_POS = 43;
|
||||
public static final int AXIS_X_NEG = 44;
|
||||
public static final int AXIS_Y_NEG = 45;
|
||||
public static final int ROTATION_X_NEG = 46;
|
||||
public static final int ROTATION_Y_NEG = 47;
|
||||
|
||||
public static final int MAX_CONTROLLERS = 8;
|
||||
public static final int MAX_VPAD_CONTROLLERS = 2;
|
||||
public static final int MAX_WPAD_CONTROLLERS = 7;
|
||||
|
||||
public static native void setControllerType(int index, int emulatedControllerType);
|
||||
|
||||
public static native boolean isControllerDisabled(int index);
|
||||
|
||||
public static native int getControllerType(int index);
|
||||
|
||||
public static native int getWPADControllersCount();
|
||||
|
||||
public static native int getVPADControllersCount();
|
||||
|
||||
public static native void setControllerMapping(String deviceDescriptor, String deviceName, int index, int mappingId, int buttonId);
|
||||
|
||||
public static native void clearControllerMapping(int index, int mappingId);
|
||||
|
||||
public static native String getControllerMapping(int index, int mappingId);
|
||||
|
||||
public static native Map<Integer, String> getControllerMappings(int index);
|
||||
|
||||
public static native void onKeyEvent(String deviceDescriptor, String deviceName, int keyCode, boolean isPressed);
|
||||
|
||||
public static native void onAxisEvent(String deviceDescriptor, String deviceName, int axisCode, float value);
|
||||
|
||||
public static native boolean getAsyncShaderCompile();
|
||||
|
||||
public static native void setAsyncShaderCompile(boolean enabled);
|
||||
|
||||
public static final int VSYNC_MODE_OFF = 0;
|
||||
public static final int VSYNC_MODE_DOUBLE_BUFFERING = 1;
|
||||
public static final int VSYNC_MODE_TRIPLE_BUFFERING = 2;
|
||||
|
||||
public static native int getVSyncMode();
|
||||
|
||||
public static native void setVSyncMode(int vsyncMode);
|
||||
|
||||
public static native boolean getAccurateBarriers();
|
||||
|
||||
public static native void setAccurateBarriers(boolean enabled);
|
||||
|
||||
public static native boolean getAudioDeviceEnabled(boolean tv);
|
||||
|
||||
public static native void setAudioDeviceEnabled(boolean enabled, boolean tv);
|
||||
|
||||
public static final int AUDIO_CHANNELS_MONO = 0;
|
||||
public static final int AUDIO_CHANNELS_STEREO = 1;
|
||||
public static final int AUDIO_CHANNELS_SURROUND = 2;
|
||||
|
||||
public static native void setAudioDeviceChannels(int channels, boolean tv);
|
||||
|
||||
public static native int getAudioDeviceChannels(boolean tv);
|
||||
|
||||
public static final int AUDIO_MIN_VOLUME = 0;
|
||||
public static final int AUDIO_MAX_VOLUME = 100;
|
||||
|
||||
public static native void setAudioDeviceVolume(int volume, boolean tv);
|
||||
|
||||
public static native int getAudioDeviceVolume(boolean tv);
|
||||
|
||||
public record GraphicPackBasicInfo(long id, String virtualPath, ArrayList<Long> titleIds) {
|
||||
}
|
||||
|
||||
public static native ArrayList<Long> getInstalledGamesTitleIds();
|
||||
|
||||
public static native ArrayList<GraphicPackBasicInfo> getGraphicPackBasicInfos();
|
||||
|
||||
public static class GraphicPackPreset {
|
||||
private final long graphicPackId;
|
||||
private final String category;
|
||||
private final ArrayList<String> presets;
|
||||
private String activePreset;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(graphicPackId, category, presets, activePreset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == null) return false;
|
||||
if (object == this) return true;
|
||||
if (object instanceof GraphicPackPreset preset)
|
||||
return this.hashCode() == preset.hashCode();
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphicPackPreset(long graphicPackId, String category, ArrayList<String> presets, String activePreset) {
|
||||
this.graphicPackId = graphicPackId;
|
||||
this.category = category;
|
||||
this.presets = presets;
|
||||
this.activePreset = activePreset;
|
||||
}
|
||||
|
||||
public String getActivePreset() {
|
||||
return activePreset;
|
||||
}
|
||||
|
||||
public void setActivePreset(String activePreset) {
|
||||
if (presets.stream().noneMatch(s -> s.equals(activePreset)))
|
||||
throw new IllegalArgumentException("Trying to set an invalid preset: " + activePreset);
|
||||
setGraphicPackActivePreset(graphicPackId, category, activePreset);
|
||||
this.activePreset = activePreset;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public ArrayList<String> getPresets() {
|
||||
return presets;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GraphicPack {
|
||||
public final long id;
|
||||
protected boolean active;
|
||||
public final String name;
|
||||
public final String description;
|
||||
public List<GraphicPackPreset> presets;
|
||||
|
||||
public GraphicPack(long id, boolean active, String name, String description, ArrayList<GraphicPackPreset> presets) {
|
||||
this.id = id;
|
||||
this.active = active;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.presets = presets;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void reloadPresets() {
|
||||
presets = NativeLibrary.getGraphicPackPresets(id);
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
setGraphicPackActive(id, active);
|
||||
}
|
||||
}
|
||||
|
||||
public static native void refreshGraphicPacks();
|
||||
|
||||
public static native GraphicPack getGraphicPack(long id);
|
||||
|
||||
public static native void setGraphicPackActive(long id, boolean active);
|
||||
|
||||
public static native void setGraphicPackActivePreset(long id, String category, String preset);
|
||||
|
||||
public static native ArrayList<GraphicPackPreset> getGraphicPackPresets(long id);
|
||||
|
||||
public static native void onOverlayButton(int controllerIndex, int mappingId, boolean value);
|
||||
|
||||
public static native void onOverlayAxis(int controllerIndex, int mappingId, float value);
|
||||
|
||||
public static final int OVERLAY_SCREEN_POSITION_DISABLED = 0;
|
||||
public static final int OVERLAY_SCREEN_POSITION_TOP_LEFT = 1;
|
||||
public static final int OVERLAY_SCREEN_POSITION_TOP_CENTER = 2;
|
||||
public static final int OVERLAY_SCREEN_POSITION_TOP_RIGHT = 3;
|
||||
public static final int OVERLAY_SCREEN_POSITION_BOTTOM_LEFT = 4;
|
||||
public static final int OVERLAY_SCREEN_POSITION_BOTTOM_CENTER = 5;
|
||||
public static final int OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT = 6;
|
||||
|
||||
public static native int getOverlayPosition();
|
||||
|
||||
public static native void setOverlayPosition(int position);
|
||||
|
||||
public static native boolean isOverlayFPSEnabled();
|
||||
|
||||
public static native void setOverlayFPSEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayDrawCallsPerFrameEnabled();
|
||||
|
||||
public static native void setOverlayDrawCallsPerFrameEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayCPUUsageEnabled();
|
||||
|
||||
public static native void setOverlayCPUUsageEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayCPUPerCoreUsageEnabled();
|
||||
|
||||
public static native void setOverlayCPUPerCoreUsageEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayRAMUsageEnabled();
|
||||
|
||||
public static native void setOverlayRAMUsageEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayDebugEnabled();
|
||||
|
||||
public static native void setOverlayDebugEnabled(boolean enabled);
|
||||
|
||||
public static native int getNotificationsPosition();
|
||||
|
||||
public static native void setNotificationsPosition(int position);
|
||||
|
||||
public static native boolean isNotificationControllerProfilesEnabled();
|
||||
|
||||
public static native void setNotificationControllerProfilesEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isNotificationShaderCompilerEnabled();
|
||||
|
||||
public static native void setNotificationShaderCompilerEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isNotificationFriendListEnabled();
|
||||
|
||||
public static native void setNotificationFriendListEnabled(boolean enabled);
|
||||
|
||||
public static native void onTouchDown(int x, int y, boolean isTV);
|
||||
|
||||
public static native void onTouchMove(int x, int y, boolean isTV);
|
||||
|
||||
public static native void onTouchUp(int x, int y, boolean isTV);
|
||||
|
||||
public static native void onMotion(long timestamp, float gyroX, float gyroY, float gyroZ, float accelX, float accelY, float accelZ);
|
||||
|
||||
public static native void setMotionEnabled(boolean motionEnabled);
|
||||
}
|
@ -22,13 +22,14 @@ import androidx.appcompat.widget.PopupMenu;
|
||||
import androidx.fragment.app.Fragment;
|
||||
import androidx.lifecycle.ViewModelProvider;
|
||||
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeEmulation;
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.databinding.FragmentEmulationBinding;
|
||||
import info.cemu.Cemu.input.SensorManager;
|
||||
import info.cemu.Cemu.inputoverlay.InputOverlaySettingsProvider;
|
||||
import info.cemu.Cemu.inputoverlay.InputOverlaySurfaceView;
|
||||
import info.cemu.Cemu.nativeinterface.NativeException;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
public class EmulationFragment extends Fragment implements PopupMenu.OnMenuItemClickListener {
|
||||
@ -51,16 +52,16 @@ public class EmulationFragment extends Fragment implements PopupMenu.OnMenuItemC
|
||||
int y = (int) event.getY(pointerIndex);
|
||||
switch (event.getActionMasked()) {
|
||||
case MotionEvent.ACTION_DOWN, MotionEvent.ACTION_POINTER_DOWN -> {
|
||||
NativeLibrary.onTouchDown(x, y, isTV);
|
||||
NativeInput.onTouchDown(x, y, isTV);
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> {
|
||||
currentPointerId = -1;
|
||||
NativeLibrary.onTouchUp(x, y, isTV);
|
||||
NativeInput.onTouchUp(x, y, isTV);
|
||||
return true;
|
||||
}
|
||||
case MotionEvent.ACTION_MOVE -> {
|
||||
NativeLibrary.onTouchMove(x, y, isTV);
|
||||
NativeInput.onTouchMove(x, y, isTV);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -83,11 +84,11 @@ public class EmulationFragment extends Fragment implements PopupMenu.OnMenuItemC
|
||||
@Override
|
||||
public void surfaceChanged(@NonNull SurfaceHolder surfaceHolder, int format, int width, int height) {
|
||||
try {
|
||||
NativeLibrary.setSurfaceSize(width, height, isMainCanvas);
|
||||
NativeEmulation.setSurfaceSize(width, height, isMainCanvas);
|
||||
if (surfaceSet) {
|
||||
return;
|
||||
}
|
||||
NativeLibrary.setSurface(surfaceHolder.getSurface(), isMainCanvas);
|
||||
NativeEmulation.setSurface(surfaceHolder.getSurface(), isMainCanvas);
|
||||
surfaceSet = true;
|
||||
} catch (NativeException exception) {
|
||||
onEmulationError(getString(R.string.failed_create_surface_error, exception.getMessage()));
|
||||
@ -96,7 +97,7 @@ public class EmulationFragment extends Fragment implements PopupMenu.OnMenuItemC
|
||||
|
||||
@Override
|
||||
public void surfaceDestroyed(@NonNull SurfaceHolder surfaceHolder) {
|
||||
NativeLibrary.clearSurface(isMainCanvas);
|
||||
NativeEmulation.clearSurface(isMainCanvas);
|
||||
surfaceSet = false;
|
||||
}
|
||||
}
|
||||
@ -212,7 +213,7 @@ public class EmulationFragment extends Fragment implements PopupMenu.OnMenuItemC
|
||||
}
|
||||
if (itemId == R.id.replace_tv_with_pad) {
|
||||
boolean replaceTVWithPad = !item.isChecked();
|
||||
NativeLibrary.setReplaceTVWithPadView(replaceTVWithPad);
|
||||
NativeEmulation.setReplaceTVWithPadView(replaceTVWithPad);
|
||||
item.setChecked(replaceTVWithPad);
|
||||
return true;
|
||||
}
|
||||
@ -270,7 +271,7 @@ public class EmulationFragment extends Fragment implements PopupMenu.OnMenuItemC
|
||||
}
|
||||
SurfaceView mainCanvas = binding.mainCanvas;
|
||||
try {
|
||||
NativeLibrary.initializerRenderer(testSurface);
|
||||
NativeEmulation.initializerRenderer(testSurface);
|
||||
} catch (NativeException exception) {
|
||||
onEmulationError(getString(R.string.failed_initialize_renderer_error, exception.getMessage()));
|
||||
return binding.getRoot();
|
||||
@ -302,17 +303,17 @@ public class EmulationFragment extends Fragment implements PopupMenu.OnMenuItemC
|
||||
}
|
||||
|
||||
private void startGame() {
|
||||
try {
|
||||
NativeLibrary.startGame(launchPath);
|
||||
} catch (NativeLibrary.GameBaseFilesNotFoundException exception) {
|
||||
onEmulationError(getString(R.string.game_not_found));
|
||||
} catch (NativeLibrary.NoDiscKeyException exception) {
|
||||
onEmulationError(getString(R.string.no_disk_key));
|
||||
} catch (NativeLibrary.NoTitleTikException exception) {
|
||||
onEmulationError(getString(R.string.no_title_tik));
|
||||
} catch (NativeLibrary.GameFilesException exception) {
|
||||
onEmulationError(getString(R.string.game_files_unknown_error, launchPath));
|
||||
}
|
||||
int result = NativeEmulation.startGame(launchPath);
|
||||
if (result == NativeEmulation.START_GAME_SUCCESSFUL)
|
||||
return;
|
||||
int errorMessageId = switch (result) {
|
||||
case NativeEmulation.START_GAME_ERROR_GAME_BASE_FILES_NOT_FOUND ->
|
||||
R.string.game_not_found;
|
||||
case NativeEmulation.START_GAME_ERROR_NO_DISC_KEY -> R.string.no_disk_key;
|
||||
case NativeEmulation.START_GAME_ERROR_NO_TITLE_TIK -> R.string.no_title_tik;
|
||||
default -> R.string.game_files_unknown_error;
|
||||
};
|
||||
onEmulationError(getString(errorMessageId));
|
||||
}
|
||||
|
||||
private void onEmulationError(String errorMessage) {
|
||||
|
@ -34,7 +34,6 @@ public class DocumentsProvider extends android.provider.DocumentsProvider {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private final String[] DEFAULT_ROOT_PROJECTION = {
|
||||
DocumentsContract.Root.COLUMN_ROOT_ID,
|
||||
DocumentsContract.Root.COLUMN_MIME_TYPES,
|
||||
|
@ -1,7 +1,6 @@
|
||||
package info.cemu.Cemu.gameview;
|
||||
|
||||
import android.graphics.Bitmap;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.lifecycle.LiveData;
|
||||
import androidx.lifecycle.MutableLiveData;
|
||||
@ -9,10 +8,8 @@ import androidx.lifecycle.ViewModel;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeGameTitles;
|
||||
|
||||
public class GameViewModel extends ViewModel {
|
||||
private final MutableLiveData<List<Game>> gamesData;
|
||||
@ -25,7 +22,7 @@ public class GameViewModel extends ViewModel {
|
||||
|
||||
public GameViewModel() {
|
||||
this.gamesData = new MutableLiveData<>();
|
||||
NativeLibrary.setGameTitleLoadedCallback((path, title, colors, width, height) -> {
|
||||
NativeGameTitles.setGameTitleLoadedCallback((path, title, colors, width, height) -> {
|
||||
Bitmap icon = null;
|
||||
if (colors != null)
|
||||
icon = Bitmap.createBitmap(colors, width, height, Bitmap.Config.ARGB_8888);
|
||||
@ -39,12 +36,12 @@ public class GameViewModel extends ViewModel {
|
||||
|
||||
@Override
|
||||
protected void onCleared() {
|
||||
NativeLibrary.setGameTitleLoadedCallback(null);
|
||||
NativeGameTitles.setGameTitleLoadedCallback(null);
|
||||
}
|
||||
|
||||
public void refreshGames() {
|
||||
games.clear();
|
||||
gamesData.setValue(null);
|
||||
NativeLibrary.reloadGameTitles();
|
||||
NativeGameTitles.reloadGameTitles();
|
||||
}
|
||||
}
|
||||
|
@ -1,11 +1,10 @@
|
||||
package info.cemu.Cemu.input;
|
||||
|
||||
import android.util.Log;
|
||||
import android.view.InputDevice;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class InputManager {
|
||||
private static class InvalidAxisException extends Exception {
|
||||
@ -17,59 +16,60 @@ public class InputManager {
|
||||
private int getNativeAxisKey(int axis, boolean isPositive) throws InvalidAxisException {
|
||||
if (isPositive) {
|
||||
return switch (axis) {
|
||||
case MotionEvent.AXIS_X -> NativeLibrary.AXIS_X_POS;
|
||||
case MotionEvent.AXIS_Y -> NativeLibrary.AXIS_Y_POS;
|
||||
case MotionEvent.AXIS_RX, MotionEvent.AXIS_Z -> NativeLibrary.ROTATION_X_POS;
|
||||
case MotionEvent.AXIS_RY, MotionEvent.AXIS_RZ -> NativeLibrary.ROTATION_Y_POS;
|
||||
case MotionEvent.AXIS_LTRIGGER -> NativeLibrary.TRIGGER_X_POS;
|
||||
case MotionEvent.AXIS_RTRIGGER -> NativeLibrary.TRIGGER_Y_POS;
|
||||
case MotionEvent.AXIS_HAT_X -> NativeLibrary.DPAD_RIGHT;
|
||||
case MotionEvent.AXIS_HAT_Y -> NativeLibrary.DPAD_DOWN;
|
||||
case MotionEvent.AXIS_X -> NativeInput.AXIS_X_POS;
|
||||
case MotionEvent.AXIS_Y -> NativeInput.AXIS_Y_POS;
|
||||
case MotionEvent.AXIS_RX, MotionEvent.AXIS_Z -> NativeInput.ROTATION_X_POS;
|
||||
case MotionEvent.AXIS_RY, MotionEvent.AXIS_RZ -> NativeInput.ROTATION_Y_POS;
|
||||
case MotionEvent.AXIS_LTRIGGER -> NativeInput.TRIGGER_X_POS;
|
||||
case MotionEvent.AXIS_RTRIGGER -> NativeInput.TRIGGER_Y_POS;
|
||||
case MotionEvent.AXIS_HAT_X -> NativeInput.DPAD_RIGHT;
|
||||
case MotionEvent.AXIS_HAT_Y -> NativeInput.DPAD_DOWN;
|
||||
default -> throw new InvalidAxisException(axis);
|
||||
};
|
||||
} else {
|
||||
return switch (axis) {
|
||||
case MotionEvent.AXIS_X -> NativeLibrary.AXIS_X_NEG;
|
||||
case MotionEvent.AXIS_Y -> NativeLibrary.AXIS_Y_NEG;
|
||||
case MotionEvent.AXIS_RX, MotionEvent.AXIS_Z -> NativeLibrary.ROTATION_X_NEG;
|
||||
case MotionEvent.AXIS_RY, MotionEvent.AXIS_RZ -> NativeLibrary.ROTATION_Y_NEG;
|
||||
case MotionEvent.AXIS_HAT_X -> NativeLibrary.DPAD_LEFT;
|
||||
case MotionEvent.AXIS_HAT_Y -> NativeLibrary.DPAD_UP;
|
||||
case MotionEvent.AXIS_X -> NativeInput.AXIS_X_NEG;
|
||||
case MotionEvent.AXIS_Y -> NativeInput.AXIS_Y_NEG;
|
||||
case MotionEvent.AXIS_RX, MotionEvent.AXIS_Z -> NativeInput.ROTATION_X_NEG;
|
||||
case MotionEvent.AXIS_RY, MotionEvent.AXIS_RZ -> NativeInput.ROTATION_Y_NEG;
|
||||
case MotionEvent.AXIS_HAT_X -> NativeInput.DPAD_LEFT;
|
||||
case MotionEvent.AXIS_HAT_Y -> NativeInput.DPAD_UP;
|
||||
default -> throw new InvalidAxisException(axis);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isMotionEventFromJoystick(MotionEvent event) {
|
||||
return (event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE;
|
||||
private boolean isMotionEventFromJoystickOrGamepad(MotionEvent event) {
|
||||
return (event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK || (event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD;
|
||||
}
|
||||
|
||||
private static final float MIN_ABS_AXIS_VALUE = 0.33f;
|
||||
|
||||
public boolean mapMotionEventToMappingId(int controllerIndex, int mappingId, MotionEvent event) {
|
||||
if (isMotionEventFromJoystick(event)) {
|
||||
InputDevice device = event.getDevice();
|
||||
float maxAbsAxisValue = 0.0f;
|
||||
int maxAxis = -1;
|
||||
int actionPointerIndex = event.getActionIndex();
|
||||
for (InputDevice.MotionRange motionRange : device.getMotionRanges()) {
|
||||
float axisValue = event.getAxisValue(motionRange.getAxis(), actionPointerIndex);
|
||||
int axis;
|
||||
try {
|
||||
axis = getNativeAxisKey(motionRange.getAxis(), axisValue > 0);
|
||||
} catch (InvalidAxisException e) {
|
||||
continue;
|
||||
}
|
||||
if (Math.abs(axisValue) > maxAbsAxisValue) {
|
||||
maxAxis = axis;
|
||||
maxAbsAxisValue = Math.abs(axisValue);
|
||||
}
|
||||
if (!isMotionEventFromJoystickOrGamepad(event)) {
|
||||
return false;
|
||||
}
|
||||
InputDevice device = event.getDevice();
|
||||
float maxAbsAxisValue = 0.0f;
|
||||
int maxAxis = -1;
|
||||
int actionPointerIndex = event.getActionIndex();
|
||||
for (InputDevice.MotionRange motionRange : device.getMotionRanges()) {
|
||||
float axisValue = event.getAxisValue(motionRange.getAxis(), actionPointerIndex);
|
||||
int axis;
|
||||
try {
|
||||
axis = getNativeAxisKey(motionRange.getAxis(), axisValue > 0);
|
||||
} catch (InvalidAxisException e) {
|
||||
continue;
|
||||
}
|
||||
if (maxAbsAxisValue > MIN_ABS_AXIS_VALUE) {
|
||||
NativeLibrary.setControllerMapping(device.getDescriptor(), device.getName(), controllerIndex, mappingId, maxAxis);
|
||||
return true;
|
||||
if (Math.abs(axisValue) > maxAbsAxisValue) {
|
||||
maxAxis = axis;
|
||||
maxAbsAxisValue = Math.abs(axisValue);
|
||||
}
|
||||
}
|
||||
if (maxAbsAxisValue > MIN_ABS_AXIS_VALUE) {
|
||||
NativeInput.setControllerMapping(device.getDescriptor(), device.getName(), controllerIndex, mappingId, maxAxis);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -98,26 +98,26 @@ public class InputManager {
|
||||
InputDevice device = event.getDevice();
|
||||
if (!isController(device))
|
||||
return false;
|
||||
NativeLibrary.onNativeKey(device.getDescriptor(), device.getName(), event.getKeyCode(), event.getAction() == KeyEvent.ACTION_DOWN);
|
||||
NativeInput.onNativeKey(device.getDescriptor(), device.getName(), event.getKeyCode(), event.getAction() == KeyEvent.ACTION_DOWN);
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean onMotionEvent(MotionEvent event) {
|
||||
if (!isMotionEventFromJoystick(event))
|
||||
if (!isMotionEventFromJoystickOrGamepad(event))
|
||||
return false;
|
||||
InputDevice device = event.getDevice();
|
||||
int actionPointerIndex = event.getActionIndex();
|
||||
for (InputDevice.MotionRange motionRange : device.getMotionRanges()) {
|
||||
float axisValue = event.getAxisValue(motionRange.getAxis(), actionPointerIndex);
|
||||
int axis = motionRange.getAxis();
|
||||
NativeLibrary.onNativeAxis(device.getDescriptor(), device.getName(), axis, axisValue);
|
||||
NativeInput.onNativeAxis(device.getDescriptor(), device.getName(), axis, axisValue);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean mapKeyEventToMappingId(int controllerIndex, int mappingId, KeyEvent event) {
|
||||
InputDevice device = event.getDevice();
|
||||
NativeLibrary.setControllerMapping(device.getDescriptor(), device.getName(), controllerIndex, mappingId, event.getKeyCode());
|
||||
NativeInput.setControllerMapping(device.getDescriptor(), device.getName(), controllerIndex, mappingId, event.getKeyCode());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import android.hardware.Sensor;
|
||||
import android.hardware.SensorEvent;
|
||||
import android.hardware.SensorEventListener;
|
||||
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class SensorManager implements SensorEventListener {
|
||||
private final android.hardware.SensorManager sensorManager;
|
||||
@ -28,7 +28,7 @@ public class SensorManager implements SensorEventListener {
|
||||
if (!hasMotionData) {
|
||||
return;
|
||||
}
|
||||
NativeLibrary.setMotionEnabled(true);
|
||||
NativeInput.setMotionEnabled(true);
|
||||
sensorManager.registerListener(this, gyroscope, android.hardware.SensorManager.SENSOR_DELAY_GAME);
|
||||
sensorManager.registerListener(this, accelerometer, android.hardware.SensorManager.SENSOR_DELAY_GAME);
|
||||
}
|
||||
@ -41,7 +41,7 @@ public class SensorManager implements SensorEventListener {
|
||||
if (!hasMotionData) {
|
||||
return;
|
||||
}
|
||||
NativeLibrary.setMotionEnabled(false);
|
||||
NativeInput.setMotionEnabled(false);
|
||||
sensorManager.unregisterListener(this);
|
||||
}
|
||||
|
||||
@ -65,10 +65,10 @@ public class SensorManager implements SensorEventListener {
|
||||
hasAccelData = false;
|
||||
hasGyroData = false;
|
||||
if (isLandscape) {
|
||||
NativeLibrary.onMotion(event.timestamp, gyroY, gyroZ, gyroX, accelY, accelZ, accelX);
|
||||
NativeInput.onMotion(event.timestamp, gyroY, gyroZ, gyroX, accelY, accelZ, accelX);
|
||||
return;
|
||||
}
|
||||
NativeLibrary.onMotion(event.timestamp, gyroX, gyroY, gyroZ, accelX, accelY, accelZ);
|
||||
NativeInput.onMotion(event.timestamp, gyroX, gyroY, gyroZ, accelX, accelY, accelZ);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,8 +1,6 @@
|
||||
package info.cemu.Cemu.inputoverlay;
|
||||
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
@ -17,13 +15,12 @@ import java.util.stream.IntStream;
|
||||
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.databinding.GenericRecyclerViewLayoutBinding;
|
||||
import info.cemu.Cemu.guibasecomponents.ButtonRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.CheckboxRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.SliderRecyclerViewItem;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
|
||||
public class InputOverlaySettingsFragment extends Fragment {
|
||||
@ -75,7 +72,7 @@ public class InputOverlaySettingsFragment extends Fragment {
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(alphaSlider);
|
||||
|
||||
SelectionAdapter<Integer> controllerAdapter = new SelectionAdapter<>(
|
||||
IntStream.range(0, NativeLibrary.MAX_CONTROLLERS)
|
||||
IntStream.range(0, NativeInput.MAX_CONTROLLERS)
|
||||
.mapToObj(i -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(getString(R.string.controller_numbered, i + 1)), i))
|
||||
.collect(Collectors.toList()),
|
||||
overlaySettings.getControllerIndex()
|
||||
|
@ -8,7 +8,7 @@ import android.graphics.Rect;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class InputOverlaySettingsProvider {
|
||||
public enum Input {
|
||||
@ -129,7 +129,7 @@ public class InputOverlaySettingsProvider {
|
||||
int leftJoystickCentreX = (int) (width * 0.25f);
|
||||
int joystickCentreY = (int) (height * 0.55f);
|
||||
int joystickClickRadius = (int) (joystickRadius * 0.7f);
|
||||
|
||||
// TODO: move this to res?
|
||||
return switch (input) {
|
||||
case A -> new Rect(abxyButtonsCentreX + roundButtonRadius,
|
||||
abxyButtonsCentreY - roundButtonRadius,
|
||||
@ -222,7 +222,7 @@ public class InputOverlaySettingsProvider {
|
||||
}
|
||||
|
||||
public void setControllerIndex(int controllerIndex) {
|
||||
this.controllerIndex = Math.min(Math.max(controllerIndex, 0), NativeLibrary.MAX_CONTROLLERS - 1);
|
||||
this.controllerIndex = Math.min(Math.max(controllerIndex, 0), NativeInput.MAX_CONTROLLERS - 1);
|
||||
}
|
||||
|
||||
public int getControllerIndex() {
|
||||
|
@ -14,7 +14,7 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouchListener {
|
||||
public enum InputMode {
|
||||
@ -110,94 +110,94 @@ public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouch
|
||||
|
||||
int overlayButtonToVPADButton(OverlayButton button) {
|
||||
return switch (button) {
|
||||
case A -> NativeLibrary.VPAD_BUTTON_A;
|
||||
case B -> NativeLibrary.VPAD_BUTTON_B;
|
||||
case X -> NativeLibrary.VPAD_BUTTON_X;
|
||||
case Y -> NativeLibrary.VPAD_BUTTON_Y;
|
||||
case PLUS -> NativeLibrary.VPAD_BUTTON_PLUS;
|
||||
case MINUS -> NativeLibrary.VPAD_BUTTON_MINUS;
|
||||
case DPAD_UP -> NativeLibrary.VPAD_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeLibrary.VPAD_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeLibrary.VPAD_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeLibrary.VPAD_BUTTON_RIGHT;
|
||||
case L_STICK -> NativeLibrary.VPAD_BUTTON_STICKL;
|
||||
case R_STICK -> NativeLibrary.VPAD_BUTTON_STICKR;
|
||||
case L -> NativeLibrary.VPAD_BUTTON_L;
|
||||
case R -> NativeLibrary.VPAD_BUTTON_R;
|
||||
case ZR -> NativeLibrary.VPAD_BUTTON_ZR;
|
||||
case ZL -> NativeLibrary.VPAD_BUTTON_ZL;
|
||||
case A -> NativeInput.VPAD_BUTTON_A;
|
||||
case B -> NativeInput.VPAD_BUTTON_B;
|
||||
case X -> NativeInput.VPAD_BUTTON_X;
|
||||
case Y -> NativeInput.VPAD_BUTTON_Y;
|
||||
case PLUS -> NativeInput.VPAD_BUTTON_PLUS;
|
||||
case MINUS -> NativeInput.VPAD_BUTTON_MINUS;
|
||||
case DPAD_UP -> NativeInput.VPAD_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeInput.VPAD_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeInput.VPAD_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeInput.VPAD_BUTTON_RIGHT;
|
||||
case L_STICK -> NativeInput.VPAD_BUTTON_STICKL;
|
||||
case R_STICK -> NativeInput.VPAD_BUTTON_STICKR;
|
||||
case L -> NativeInput.VPAD_BUTTON_L;
|
||||
case R -> NativeInput.VPAD_BUTTON_R;
|
||||
case ZR -> NativeInput.VPAD_BUTTON_ZR;
|
||||
case ZL -> NativeInput.VPAD_BUTTON_ZL;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
|
||||
int overlayButtonToClassicButton(OverlayButton button) {
|
||||
return switch (button) {
|
||||
case A -> NativeLibrary.CLASSIC_BUTTON_A;
|
||||
case B -> NativeLibrary.CLASSIC_BUTTON_B;
|
||||
case X -> NativeLibrary.CLASSIC_BUTTON_X;
|
||||
case Y -> NativeLibrary.CLASSIC_BUTTON_Y;
|
||||
case PLUS -> NativeLibrary.CLASSIC_BUTTON_PLUS;
|
||||
case MINUS -> NativeLibrary.CLASSIC_BUTTON_MINUS;
|
||||
case DPAD_UP -> NativeLibrary.CLASSIC_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeLibrary.CLASSIC_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeLibrary.CLASSIC_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeLibrary.CLASSIC_BUTTON_RIGHT;
|
||||
case L -> NativeLibrary.CLASSIC_BUTTON_L;
|
||||
case R -> NativeLibrary.CLASSIC_BUTTON_R;
|
||||
case ZR -> NativeLibrary.CLASSIC_BUTTON_ZR;
|
||||
case ZL -> NativeLibrary.CLASSIC_BUTTON_ZL;
|
||||
case A -> NativeInput.CLASSIC_BUTTON_A;
|
||||
case B -> NativeInput.CLASSIC_BUTTON_B;
|
||||
case X -> NativeInput.CLASSIC_BUTTON_X;
|
||||
case Y -> NativeInput.CLASSIC_BUTTON_Y;
|
||||
case PLUS -> NativeInput.CLASSIC_BUTTON_PLUS;
|
||||
case MINUS -> NativeInput.CLASSIC_BUTTON_MINUS;
|
||||
case DPAD_UP -> NativeInput.CLASSIC_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeInput.CLASSIC_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeInput.CLASSIC_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeInput.CLASSIC_BUTTON_RIGHT;
|
||||
case L -> NativeInput.CLASSIC_BUTTON_L;
|
||||
case R -> NativeInput.CLASSIC_BUTTON_R;
|
||||
case ZR -> NativeInput.CLASSIC_BUTTON_ZR;
|
||||
case ZL -> NativeInput.CLASSIC_BUTTON_ZL;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
|
||||
int overlayButtonToProButton(OverlayButton button) {
|
||||
return switch (button) {
|
||||
case A -> NativeLibrary.PRO_BUTTON_A;
|
||||
case B -> NativeLibrary.PRO_BUTTON_B;
|
||||
case X -> NativeLibrary.PRO_BUTTON_X;
|
||||
case Y -> NativeLibrary.PRO_BUTTON_Y;
|
||||
case PLUS -> NativeLibrary.PRO_BUTTON_PLUS;
|
||||
case MINUS -> NativeLibrary.PRO_BUTTON_MINUS;
|
||||
case DPAD_UP -> NativeLibrary.PRO_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeLibrary.PRO_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeLibrary.PRO_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeLibrary.PRO_BUTTON_RIGHT;
|
||||
case L_STICK -> NativeLibrary.PRO_BUTTON_STICKL;
|
||||
case R_STICK -> NativeLibrary.PRO_BUTTON_STICKR;
|
||||
case L -> NativeLibrary.PRO_BUTTON_L;
|
||||
case R -> NativeLibrary.PRO_BUTTON_R;
|
||||
case ZR -> NativeLibrary.PRO_BUTTON_ZR;
|
||||
case ZL -> NativeLibrary.PRO_BUTTON_ZL;
|
||||
case A -> NativeInput.PRO_BUTTON_A;
|
||||
case B -> NativeInput.PRO_BUTTON_B;
|
||||
case X -> NativeInput.PRO_BUTTON_X;
|
||||
case Y -> NativeInput.PRO_BUTTON_Y;
|
||||
case PLUS -> NativeInput.PRO_BUTTON_PLUS;
|
||||
case MINUS -> NativeInput.PRO_BUTTON_MINUS;
|
||||
case DPAD_UP -> NativeInput.PRO_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeInput.PRO_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeInput.PRO_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeInput.PRO_BUTTON_RIGHT;
|
||||
case L_STICK -> NativeInput.PRO_BUTTON_STICKL;
|
||||
case R_STICK -> NativeInput.PRO_BUTTON_STICKR;
|
||||
case L -> NativeInput.PRO_BUTTON_L;
|
||||
case R -> NativeInput.PRO_BUTTON_R;
|
||||
case ZR -> NativeInput.PRO_BUTTON_ZR;
|
||||
case ZL -> NativeInput.PRO_BUTTON_ZL;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
|
||||
int overlayButtonToWiimoteButton(OverlayButton button) {
|
||||
return switch (button) {
|
||||
case A -> NativeLibrary.WIIMOTE_BUTTON_A;
|
||||
case B -> NativeLibrary.WIIMOTE_BUTTON_B;
|
||||
case ONE -> NativeLibrary.WIIMOTE_BUTTON_1;
|
||||
case TWO -> NativeLibrary.WIIMOTE_BUTTON_2;
|
||||
case PLUS -> NativeLibrary.WIIMOTE_BUTTON_PLUS;
|
||||
case MINUS -> NativeLibrary.WIIMOTE_BUTTON_MINUS;
|
||||
case HOME -> NativeLibrary.WIIMOTE_BUTTON_HOME;
|
||||
case DPAD_UP -> NativeLibrary.WIIMOTE_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeLibrary.WIIMOTE_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeLibrary.WIIMOTE_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeLibrary.WIIMOTE_BUTTON_RIGHT;
|
||||
case C -> NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_C;
|
||||
case Z -> NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_Z;
|
||||
case A -> NativeInput.WIIMOTE_BUTTON_A;
|
||||
case B -> NativeInput.WIIMOTE_BUTTON_B;
|
||||
case ONE -> NativeInput.WIIMOTE_BUTTON_1;
|
||||
case TWO -> NativeInput.WIIMOTE_BUTTON_2;
|
||||
case PLUS -> NativeInput.WIIMOTE_BUTTON_PLUS;
|
||||
case MINUS -> NativeInput.WIIMOTE_BUTTON_MINUS;
|
||||
case HOME -> NativeInput.WIIMOTE_BUTTON_HOME;
|
||||
case DPAD_UP -> NativeInput.WIIMOTE_BUTTON_UP;
|
||||
case DPAD_DOWN -> NativeInput.WIIMOTE_BUTTON_DOWN;
|
||||
case DPAD_LEFT -> NativeInput.WIIMOTE_BUTTON_LEFT;
|
||||
case DPAD_RIGHT -> NativeInput.WIIMOTE_BUTTON_RIGHT;
|
||||
case C -> NativeInput.WIIMOTE_BUTTON_NUNCHUCK_C;
|
||||
case Z -> NativeInput.WIIMOTE_BUTTON_NUNCHUCK_Z;
|
||||
default -> -1;
|
||||
};
|
||||
}
|
||||
|
||||
void onButtonStateChange(OverlayButton button, boolean state) {
|
||||
int nativeButtonId = switch (nativeControllerType) {
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD -> overlayButtonToVPADButton(button);
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_CLASSIC ->
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_VPAD -> overlayButtonToVPADButton(button);
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_CLASSIC ->
|
||||
overlayButtonToClassicButton(button);
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_PRO -> overlayButtonToProButton(button);
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE ->
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_PRO -> overlayButtonToProButton(button);
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE ->
|
||||
overlayButtonToWiimoteButton(button);
|
||||
default -> -1;
|
||||
};
|
||||
@ -207,61 +207,61 @@ public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouch
|
||||
if (vibrateOnTouch && state) {
|
||||
vibrator.vibrate(buttonTouchVibrationEffect);
|
||||
}
|
||||
NativeLibrary.onOverlayButton(controllerIndex, nativeButtonId, state);
|
||||
NativeInput.onOverlayButton(controllerIndex, nativeButtonId, state);
|
||||
}
|
||||
|
||||
void onOverlayAxis(int axis, float value) {
|
||||
NativeLibrary.onOverlayAxis(controllerIndex, axis, value);
|
||||
NativeInput.onOverlayAxis(controllerIndex, axis, value);
|
||||
}
|
||||
|
||||
void onVPADJoystickStateChange(OverlayJoystick joystick, float up, float down, float left, float right) {
|
||||
if (joystick == OverlayJoystick.LEFT) {
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKL_UP, up);
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKL_DOWN, down);
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKL_LEFT, left);
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKL_RIGHT, right);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKL_UP, up);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKL_DOWN, down);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKL_LEFT, left);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKL_RIGHT, right);
|
||||
} else {
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKR_UP, up);
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKR_DOWN, down);
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKR_LEFT, left);
|
||||
onOverlayAxis(NativeLibrary.VPAD_BUTTON_STICKR_RIGHT, right);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKR_UP, up);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKR_DOWN, down);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKR_LEFT, left);
|
||||
onOverlayAxis(NativeInput.VPAD_BUTTON_STICKR_RIGHT, right);
|
||||
}
|
||||
}
|
||||
|
||||
void onProJoystickStateChange(OverlayJoystick joystick, float up, float down, float left, float right) {
|
||||
if (joystick == OverlayJoystick.LEFT) {
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKL_UP, up);
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKL_DOWN, down);
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKL_LEFT, left);
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKL_RIGHT, right);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKL_UP, up);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKL_DOWN, down);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKL_LEFT, left);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKL_RIGHT, right);
|
||||
} else {
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKR_UP, up);
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKR_DOWN, down);
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKR_LEFT, left);
|
||||
onOverlayAxis(NativeLibrary.PRO_BUTTON_STICKR_RIGHT, right);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKR_UP, up);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKR_DOWN, down);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKR_LEFT, left);
|
||||
onOverlayAxis(NativeInput.PRO_BUTTON_STICKR_RIGHT, right);
|
||||
}
|
||||
}
|
||||
|
||||
void onClassicJoystickStateChange(OverlayJoystick joystick, float up, float down, float left, float right) {
|
||||
if (joystick == OverlayJoystick.LEFT) {
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKL_UP, up);
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKL_DOWN, down);
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKL_LEFT, left);
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKL_RIGHT, right);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKL_UP, up);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKL_DOWN, down);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKL_LEFT, left);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKL_RIGHT, right);
|
||||
} else {
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKR_UP, up);
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKR_DOWN, down);
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKR_LEFT, left);
|
||||
onOverlayAxis(NativeLibrary.CLASSIC_BUTTON_STICKR_RIGHT, right);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKR_UP, up);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKR_DOWN, down);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKR_LEFT, left);
|
||||
onOverlayAxis(NativeInput.CLASSIC_BUTTON_STICKR_RIGHT, right);
|
||||
}
|
||||
}
|
||||
|
||||
void onWiimoteJoystickStateChange(OverlayJoystick joystick, float up, float down, float left, float right) {
|
||||
if (joystick == OverlayJoystick.LEFT) {
|
||||
onOverlayAxis(NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_UP, up);
|
||||
onOverlayAxis(NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_DOWN, down);
|
||||
onOverlayAxis(NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_LEFT, left);
|
||||
onOverlayAxis(NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_RIGHT, right);
|
||||
onOverlayAxis(NativeInput.WIIMOTE_BUTTON_NUNCHUCK_UP, up);
|
||||
onOverlayAxis(NativeInput.WIIMOTE_BUTTON_NUNCHUCK_DOWN, down);
|
||||
onOverlayAxis(NativeInput.WIIMOTE_BUTTON_NUNCHUCK_LEFT, left);
|
||||
onOverlayAxis(NativeInput.WIIMOTE_BUTTON_NUNCHUCK_RIGHT, right);
|
||||
}
|
||||
}
|
||||
|
||||
@ -271,13 +271,13 @@ public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouch
|
||||
float left = x < 0 ? -x : 0;
|
||||
float right = x > 0 ? x : 0;
|
||||
switch (nativeControllerType) {
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD ->
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_VPAD ->
|
||||
onVPADJoystickStateChange(joystick, up, down, left, right);
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_PRO ->
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_PRO ->
|
||||
onProJoystickStateChange(joystick, up, down, left, right);
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_CLASSIC ->
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_CLASSIC ->
|
||||
onClassicJoystickStateChange(joystick, up, down, left, right);
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE ->
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE ->
|
||||
onWiimoteJoystickStateChange(joystick, up, down, left, right);
|
||||
}
|
||||
}
|
||||
@ -291,11 +291,11 @@ public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouch
|
||||
return;
|
||||
}
|
||||
inputs = new ArrayList<>();
|
||||
if (NativeLibrary.isControllerDisabled(controllerIndex)) {
|
||||
if (NativeInput.isControllerDisabled(controllerIndex)) {
|
||||
return;
|
||||
}
|
||||
var resources = getResources();
|
||||
nativeControllerType = NativeLibrary.getControllerType(controllerIndex);
|
||||
nativeControllerType = NativeInput.getControllerType(controllerIndex);
|
||||
|
||||
inputs.add(new RoundButton(
|
||||
resources,
|
||||
@ -314,7 +314,7 @@ public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouch
|
||||
getOverlaySettingsForInput(InputOverlaySettingsProvider.Input.B)
|
||||
));
|
||||
|
||||
if (nativeControllerType != NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
if (nativeControllerType != NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
inputs.add(new RoundButton(
|
||||
resources,
|
||||
R.drawable.button_x_pressed,
|
||||
@ -409,7 +409,7 @@ public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouch
|
||||
getOverlaySettingsForInput(InputOverlaySettingsProvider.Input.LEFT_AXIS)
|
||||
));
|
||||
|
||||
if (nativeControllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
if (nativeControllerType == NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
inputs.add(new RoundButton(
|
||||
resources,
|
||||
R.drawable.button_c_pressed,
|
||||
@ -435,8 +435,8 @@ public class InputOverlaySurfaceView extends SurfaceView implements View.OnTouch
|
||||
getOverlaySettingsForInput(InputOverlaySettingsProvider.Input.HOME)
|
||||
));
|
||||
}
|
||||
if (nativeControllerType != NativeLibrary.EMULATED_CONTROLLER_TYPE_CLASSIC
|
||||
&& nativeControllerType != NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
if (nativeControllerType != NativeInput.EMULATED_CONTROLLER_TYPE_CLASSIC
|
||||
&& nativeControllerType != NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
inputs.add(new RoundButton(
|
||||
resources,
|
||||
R.drawable.button_stick_pressed,
|
||||
|
@ -1,4 +1,4 @@
|
||||
package info.cemu.Cemu.utils;
|
||||
package info.cemu.Cemu.nativeinterface;
|
||||
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
@ -13,7 +13,7 @@ import java.util.ArrayList;
|
||||
|
||||
import info.cemu.Cemu.CemuApplication;
|
||||
|
||||
public class FileUtil {
|
||||
public class FileCallbacks {
|
||||
private static final String PATH_SEPARATOR_ENCODED = "%2F";
|
||||
private static final String PATH_SEPARATOR_DECODED = "/";
|
||||
private static final String COLON_ENCODED = "%3A";
|
||||
@ -46,7 +46,7 @@ public class FileUtil {
|
||||
return fd;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("FileUtil", "Cannot open content uri, error: " + e.getMessage());
|
||||
Log.e("FileCallbacks", "Cannot open content uri, error: " + e.getMessage());
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -62,7 +62,7 @@ public class FileUtil {
|
||||
files.add(toCppPath(documentUri));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e("FileUtil", "Cannot list files: " + e.getMessage());
|
||||
Log.e("FileCallbacks", "Cannot list files: " + e.getMessage());
|
||||
}
|
||||
String[] filesArray = new String[files.size()];
|
||||
filesArray = files.toArray(filesArray);
|
||||
@ -82,7 +82,7 @@ public class FileUtil {
|
||||
try (Cursor cursor = CemuApplication.getApplication().getApplicationContext().getContentResolver().query(fromCppPath(uri), null, null, null, null)) {
|
||||
return cursor != null && cursor.moveToFirst();
|
||||
} catch (Exception e) {
|
||||
Log.e("FileUtil", "Failed checking if file exists: " + e.getMessage());
|
||||
Log.e("FileCallbacks", "Failed checking if file exists: " + e.getMessage());
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package info.cemu.Cemu.nativeinterface;
|
||||
|
||||
import android.view.Surface;
|
||||
|
||||
public class NativeEmulation {
|
||||
public static native void initializeActiveSettings(String dataPath, String cachePath);
|
||||
|
||||
public static native void initializeEmulation();
|
||||
|
||||
public static native void setDPI(float dpi);
|
||||
|
||||
public static native void setSurface(Surface surface, boolean isMainCanvas);
|
||||
|
||||
public static native void clearSurface(boolean isMainCanvas);
|
||||
|
||||
public static native void setSurfaceSize(int width, int height, boolean isMainCanvas);
|
||||
|
||||
public static native void initializerRenderer(Surface surface);
|
||||
|
||||
public static final int START_GAME_SUCCESSFUL = 0;
|
||||
public static final int START_GAME_ERROR_GAME_BASE_FILES_NOT_FOUND = 1;
|
||||
public static final int START_GAME_ERROR_NO_DISC_KEY = 2;
|
||||
public static final int START_GAME_ERROR_NO_TITLE_TIK = 3;
|
||||
public static final int START_GAME_ERROR_UNKNOWN = 4;
|
||||
|
||||
public static native int startGame(String launchPath);
|
||||
|
||||
public static native void setReplaceTVWithPadView(boolean swapped);
|
||||
|
||||
public static native void recreateRenderSurface(boolean isMainCanvas);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package info.cemu.Cemu.nativeinterface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NativeGameTitles {
|
||||
public interface GameTitleLoadedCallback {
|
||||
void onGameTitleLoaded(String path, String title, int[] colors, int width, int height);
|
||||
}
|
||||
|
||||
public static native void setGameTitleLoadedCallback(GameTitleLoadedCallback gameTitleLoadedCallback);
|
||||
|
||||
public static native void reloadGameTitles();
|
||||
|
||||
public static native ArrayList<Long> getInstalledGamesTitleIds();
|
||||
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package info.cemu.Cemu.nativeinterface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
public class NativeGraphicPacks {
|
||||
public record GraphicPackBasicInfo(long id, String virtualPath, ArrayList<Long> titleIds) {
|
||||
}
|
||||
|
||||
public static native ArrayList<GraphicPackBasicInfo> getGraphicPackBasicInfos();
|
||||
|
||||
public static class GraphicPackPreset {
|
||||
private final long graphicPackId;
|
||||
private final String category;
|
||||
private final ArrayList<String> presets;
|
||||
private String activePreset;
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(graphicPackId, category, presets, activePreset);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
if (object == null) return false;
|
||||
if (object == this) return true;
|
||||
if (object instanceof GraphicPackPreset preset)
|
||||
return this.hashCode() == preset.hashCode();
|
||||
return false;
|
||||
}
|
||||
|
||||
public GraphicPackPreset(long graphicPackId, String category, ArrayList<String> presets, String activePreset) {
|
||||
this.graphicPackId = graphicPackId;
|
||||
this.category = category;
|
||||
this.presets = presets;
|
||||
this.activePreset = activePreset;
|
||||
}
|
||||
|
||||
public String getActivePreset() {
|
||||
return activePreset;
|
||||
}
|
||||
|
||||
public void setActivePreset(String activePreset) {
|
||||
if (presets.stream().noneMatch(s -> s.equals(activePreset)))
|
||||
throw new IllegalArgumentException("Trying to set an invalid preset: " + activePreset);
|
||||
setGraphicPackActivePreset(graphicPackId, category, activePreset);
|
||||
this.activePreset = activePreset;
|
||||
}
|
||||
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
public ArrayList<String> getPresets() {
|
||||
return presets;
|
||||
}
|
||||
}
|
||||
|
||||
public static class GraphicPack {
|
||||
public final long id;
|
||||
protected boolean active;
|
||||
public final String name;
|
||||
public final String description;
|
||||
public List<GraphicPackPreset> presets;
|
||||
|
||||
public GraphicPack(long id, boolean active, String name, String description, ArrayList<GraphicPackPreset> presets) {
|
||||
this.id = id;
|
||||
this.active = active;
|
||||
this.name = name;
|
||||
this.description = description;
|
||||
this.presets = presets;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return active;
|
||||
}
|
||||
|
||||
public void reloadPresets() {
|
||||
presets = NativeGraphicPacks.getGraphicPackPresets(id);
|
||||
}
|
||||
|
||||
public void setActive(boolean active) {
|
||||
this.active = active;
|
||||
setGraphicPackActive(id, active);
|
||||
}
|
||||
}
|
||||
|
||||
public static native void refreshGraphicPacks();
|
||||
|
||||
public static native GraphicPack getGraphicPack(long id);
|
||||
|
||||
public static native void setGraphicPackActive(long id, boolean active);
|
||||
|
||||
public static native void setGraphicPackActivePreset(long id, String category, String preset);
|
||||
|
||||
public static native ArrayList<GraphicPackPreset> getGraphicPackPresets(long id);
|
||||
}
|
@ -0,0 +1,169 @@
|
||||
package info.cemu.Cemu.nativeinterface;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class NativeInput {
|
||||
public static final int VPAD_BUTTON_NONE = 0;
|
||||
public static final int VPAD_BUTTON_A = 1;
|
||||
public static final int VPAD_BUTTON_B = 2;
|
||||
public static final int VPAD_BUTTON_X = 3;
|
||||
public static final int VPAD_BUTTON_Y = 4;
|
||||
public static final int VPAD_BUTTON_L = 5;
|
||||
public static final int VPAD_BUTTON_R = 6;
|
||||
public static final int VPAD_BUTTON_ZL = 7;
|
||||
public static final int VPAD_BUTTON_ZR = 8;
|
||||
public static final int VPAD_BUTTON_PLUS = 9;
|
||||
public static final int VPAD_BUTTON_MINUS = 10;
|
||||
public static final int VPAD_BUTTON_UP = 11;
|
||||
public static final int VPAD_BUTTON_DOWN = 12;
|
||||
public static final int VPAD_BUTTON_LEFT = 13;
|
||||
public static final int VPAD_BUTTON_RIGHT = 14;
|
||||
public static final int VPAD_BUTTON_STICKL = 15;
|
||||
public static final int VPAD_BUTTON_STICKR = 16;
|
||||
public static final int VPAD_BUTTON_STICKL_UP = 17;
|
||||
public static final int VPAD_BUTTON_STICKL_DOWN = 18;
|
||||
public static final int VPAD_BUTTON_STICKL_LEFT = 19;
|
||||
public static final int VPAD_BUTTON_STICKL_RIGHT = 20;
|
||||
public static final int VPAD_BUTTON_STICKR_UP = 21;
|
||||
public static final int VPAD_BUTTON_STICKR_DOWN = 22;
|
||||
public static final int VPAD_BUTTON_STICKR_LEFT = 23;
|
||||
public static final int VPAD_BUTTON_STICKR_RIGHT = 24;
|
||||
public static final int VPAD_BUTTON_MIC = 25;
|
||||
public static final int VPAD_BUTTON_SCREEN = 26;
|
||||
public static final int VPAD_BUTTON_HOME = 27;
|
||||
public static final int VPAD_BUTTON_MAX = 28;
|
||||
|
||||
public static final int PRO_BUTTON_NONE = 0;
|
||||
public static final int PRO_BUTTON_A = 1;
|
||||
public static final int PRO_BUTTON_B = 2;
|
||||
public static final int PRO_BUTTON_X = 3;
|
||||
public static final int PRO_BUTTON_Y = 4;
|
||||
public static final int PRO_BUTTON_L = 5;
|
||||
public static final int PRO_BUTTON_R = 6;
|
||||
public static final int PRO_BUTTON_ZL = 7;
|
||||
public static final int PRO_BUTTON_ZR = 8;
|
||||
public static final int PRO_BUTTON_PLUS = 9;
|
||||
public static final int PRO_BUTTON_MINUS = 10;
|
||||
public static final int PRO_BUTTON_HOME = 11;
|
||||
public static final int PRO_BUTTON_UP = 12;
|
||||
public static final int PRO_BUTTON_DOWN = 13;
|
||||
public static final int PRO_BUTTON_LEFT = 14;
|
||||
public static final int PRO_BUTTON_RIGHT = 15;
|
||||
public static final int PRO_BUTTON_STICKL = 16;
|
||||
public static final int PRO_BUTTON_STICKR = 17;
|
||||
public static final int PRO_BUTTON_STICKL_UP = 18;
|
||||
public static final int PRO_BUTTON_STICKL_DOWN = 19;
|
||||
public static final int PRO_BUTTON_STICKL_LEFT = 20;
|
||||
public static final int PRO_BUTTON_STICKL_RIGHT = 21;
|
||||
public static final int PRO_BUTTON_STICKR_UP = 22;
|
||||
public static final int PRO_BUTTON_STICKR_DOWN = 23;
|
||||
public static final int PRO_BUTTON_STICKR_LEFT = 24;
|
||||
public static final int PRO_BUTTON_STICKR_RIGHT = 25;
|
||||
public static final int PRO_BUTTON_MAX = 26;
|
||||
|
||||
public static final int CLASSIC_BUTTON_NONE = 0;
|
||||
public static final int CLASSIC_BUTTON_A = 1;
|
||||
public static final int CLASSIC_BUTTON_B = 2;
|
||||
public static final int CLASSIC_BUTTON_X = 3;
|
||||
public static final int CLASSIC_BUTTON_Y = 4;
|
||||
public static final int CLASSIC_BUTTON_L = 5;
|
||||
public static final int CLASSIC_BUTTON_R = 6;
|
||||
public static final int CLASSIC_BUTTON_ZL = 7;
|
||||
public static final int CLASSIC_BUTTON_ZR = 8;
|
||||
public static final int CLASSIC_BUTTON_PLUS = 9;
|
||||
public static final int CLASSIC_BUTTON_MINUS = 10;
|
||||
public static final int CLASSIC_BUTTON_HOME = 11;
|
||||
public static final int CLASSIC_BUTTON_UP = 12;
|
||||
public static final int CLASSIC_BUTTON_DOWN = 13;
|
||||
public static final int CLASSIC_BUTTON_LEFT = 14;
|
||||
public static final int CLASSIC_BUTTON_RIGHT = 15;
|
||||
public static final int CLASSIC_BUTTON_STICKL_UP = 16;
|
||||
public static final int CLASSIC_BUTTON_STICKL_DOWN = 17;
|
||||
public static final int CLASSIC_BUTTON_STICKL_LEFT = 18;
|
||||
public static final int CLASSIC_BUTTON_STICKL_RIGHT = 19;
|
||||
public static final int CLASSIC_BUTTON_STICKR_UP = 20;
|
||||
public static final int CLASSIC_BUTTON_STICKR_DOWN = 21;
|
||||
public static final int CLASSIC_BUTTON_STICKR_LEFT = 22;
|
||||
public static final int CLASSIC_BUTTON_STICKR_RIGHT = 23;
|
||||
public static final int CLASSIC_BUTTON_MAX = 24;
|
||||
|
||||
public static final int WIIMOTE_BUTTON_NONE = 0;
|
||||
public static final int WIIMOTE_BUTTON_A = 1;
|
||||
public static final int WIIMOTE_BUTTON_B = 2;
|
||||
public static final int WIIMOTE_BUTTON_1 = 3;
|
||||
public static final int WIIMOTE_BUTTON_2 = 4;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_Z = 5;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_C = 6;
|
||||
public static final int WIIMOTE_BUTTON_PLUS = 7;
|
||||
public static final int WIIMOTE_BUTTON_MINUS = 8;
|
||||
public static final int WIIMOTE_BUTTON_UP = 9;
|
||||
public static final int WIIMOTE_BUTTON_DOWN = 10;
|
||||
public static final int WIIMOTE_BUTTON_LEFT = 11;
|
||||
public static final int WIIMOTE_BUTTON_RIGHT = 12;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_UP = 13;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_DOWN = 14;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_LEFT = 15;
|
||||
public static final int WIIMOTE_BUTTON_NUNCHUCK_RIGHT = 16;
|
||||
public static final int WIIMOTE_BUTTON_HOME = 17;
|
||||
public static final int WIIMOTE_BUTTON_MAX = 18;
|
||||
|
||||
public static final int EMULATED_CONTROLLER_TYPE_VPAD = 0;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_PRO = 1;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_CLASSIC = 2;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_WIIMOTE = 3;
|
||||
public static final int EMULATED_CONTROLLER_TYPE_DISABLED = -1;
|
||||
|
||||
public static final int DPAD_UP = 34;
|
||||
public static final int DPAD_DOWN = 35;
|
||||
public static final int DPAD_LEFT = 36;
|
||||
public static final int DPAD_RIGHT = 37;
|
||||
public static final int AXIS_X_POS = 38;
|
||||
public static final int AXIS_Y_POS = 39;
|
||||
public static final int ROTATION_X_POS = 40;
|
||||
public static final int ROTATION_Y_POS = 41;
|
||||
public static final int TRIGGER_X_POS = 42;
|
||||
public static final int TRIGGER_Y_POS = 43;
|
||||
public static final int AXIS_X_NEG = 44;
|
||||
public static final int AXIS_Y_NEG = 45;
|
||||
public static final int ROTATION_X_NEG = 46;
|
||||
public static final int ROTATION_Y_NEG = 47;
|
||||
|
||||
public static final int MAX_CONTROLLERS = 8;
|
||||
public static final int MAX_VPAD_CONTROLLERS = 2;
|
||||
public static final int MAX_WPAD_CONTROLLERS = 7;
|
||||
|
||||
public static native void onNativeKey(String deviceDescriptor, String deviceName, int key, boolean isPressed);
|
||||
|
||||
public static native void onNativeAxis(String deviceDescriptor, String deviceName, int axis, float value);
|
||||
|
||||
public static native void setControllerType(int index, int emulatedControllerType);
|
||||
|
||||
public static native boolean isControllerDisabled(int index);
|
||||
|
||||
public static native int getControllerType(int index);
|
||||
|
||||
public static native int getWPADControllersCount();
|
||||
|
||||
public static native int getVPADControllersCount();
|
||||
|
||||
public static native void setControllerMapping(String deviceDescriptor, String deviceName, int index, int mappingId, int buttonId);
|
||||
|
||||
public static native void clearControllerMapping(int index, int mappingId);
|
||||
|
||||
public static native String getControllerMapping(int index, int mappingId);
|
||||
|
||||
public static native Map<Integer, String> getControllerMappings(int index);
|
||||
|
||||
public static native void onTouchDown(int x, int y, boolean isTV);
|
||||
|
||||
public static native void onTouchMove(int x, int y, boolean isTV);
|
||||
|
||||
public static native void onTouchUp(int x, int y, boolean isTV);
|
||||
|
||||
public static native void onMotion(long timestamp, float gyroX, float gyroY, float gyroZ, float accelX, float accelY, float accelZ);
|
||||
|
||||
public static native void setMotionEnabled(boolean motionEnabled);
|
||||
public static native void onOverlayButton(int controllerIndex, int mappingId, boolean value);
|
||||
|
||||
public static native void onOverlayAxis(int controllerIndex, int mappingId, float value);
|
||||
}
|
@ -0,0 +1,98 @@
|
||||
package info.cemu.Cemu.nativeinterface;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NativeSettings {
|
||||
public static native void addGamesPath(String uri);
|
||||
|
||||
public static native void removeGamesPath(String uri);
|
||||
|
||||
public static native ArrayList<String> getGamesPaths();
|
||||
|
||||
public static native boolean getAsyncShaderCompile();
|
||||
|
||||
public static native void setAsyncShaderCompile(boolean enabled);
|
||||
|
||||
public static final int VSYNC_MODE_OFF = 0;
|
||||
public static final int VSYNC_MODE_DOUBLE_BUFFERING = 1;
|
||||
public static final int VSYNC_MODE_TRIPLE_BUFFERING = 2;
|
||||
|
||||
public static native int getVSyncMode();
|
||||
|
||||
public static native void setVSyncMode(int vsyncMode);
|
||||
|
||||
public static native boolean getAccurateBarriers();
|
||||
|
||||
public static native void setAccurateBarriers(boolean enabled);
|
||||
|
||||
public static native boolean getAudioDeviceEnabled(boolean tv);
|
||||
|
||||
public static native void setAudioDeviceEnabled(boolean enabled, boolean tv);
|
||||
|
||||
public static final int AUDIO_CHANNELS_MONO = 0;
|
||||
public static final int AUDIO_CHANNELS_STEREO = 1;
|
||||
public static final int AUDIO_CHANNELS_SURROUND = 2;
|
||||
|
||||
public static native void setAudioDeviceChannels(int channels, boolean tv);
|
||||
|
||||
public static native int getAudioDeviceChannels(boolean tv);
|
||||
|
||||
public static final int AUDIO_MIN_VOLUME = 0;
|
||||
public static final int AUDIO_MAX_VOLUME = 100;
|
||||
|
||||
public static native void setAudioDeviceVolume(int volume, boolean tv);
|
||||
|
||||
public static native int getAudioDeviceVolume(boolean tv);
|
||||
|
||||
public static final int OVERLAY_SCREEN_POSITION_DISABLED = 0;
|
||||
public static final int OVERLAY_SCREEN_POSITION_TOP_LEFT = 1;
|
||||
public static final int OVERLAY_SCREEN_POSITION_TOP_CENTER = 2;
|
||||
public static final int OVERLAY_SCREEN_POSITION_TOP_RIGHT = 3;
|
||||
public static final int OVERLAY_SCREEN_POSITION_BOTTOM_LEFT = 4;
|
||||
public static final int OVERLAY_SCREEN_POSITION_BOTTOM_CENTER = 5;
|
||||
public static final int OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT = 6;
|
||||
|
||||
public static native int getOverlayPosition();
|
||||
|
||||
public static native void setOverlayPosition(int position);
|
||||
|
||||
public static native boolean isOverlayFPSEnabled();
|
||||
|
||||
public static native void setOverlayFPSEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayDrawCallsPerFrameEnabled();
|
||||
|
||||
public static native void setOverlayDrawCallsPerFrameEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayCPUUsageEnabled();
|
||||
|
||||
public static native void setOverlayCPUUsageEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayCPUPerCoreUsageEnabled();
|
||||
|
||||
public static native void setOverlayCPUPerCoreUsageEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayRAMUsageEnabled();
|
||||
|
||||
public static native void setOverlayRAMUsageEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isOverlayDebugEnabled();
|
||||
|
||||
public static native void setOverlayDebugEnabled(boolean enabled);
|
||||
|
||||
public static native int getNotificationsPosition();
|
||||
|
||||
public static native void setNotificationsPosition(int position);
|
||||
|
||||
public static native boolean isNotificationControllerProfilesEnabled();
|
||||
|
||||
public static native void setNotificationControllerProfilesEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isNotificationShaderCompilerEnabled();
|
||||
|
||||
public static native void setNotificationShaderCompilerEnabled(boolean enabled);
|
||||
|
||||
public static native boolean isNotificationFriendListEnabled();
|
||||
|
||||
public static native void setNotificationFriendListEnabled(boolean enabled);
|
||||
}
|
@ -19,15 +19,15 @@ import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.SliderRecyclerViewItem;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeSettings;
|
||||
|
||||
public class AudioSettingsFragment extends Fragment {
|
||||
|
||||
private static int channelsToResourceNameId(int channels) {
|
||||
return switch (channels) {
|
||||
case NativeLibrary.AUDIO_CHANNELS_MONO -> R.string.mono;
|
||||
case NativeLibrary.AUDIO_CHANNELS_STEREO -> R.string.stereo;
|
||||
case NativeLibrary.AUDIO_CHANNELS_SURROUND -> R.string.surround;
|
||||
case NativeSettings.AUDIO_CHANNELS_MONO -> R.string.mono;
|
||||
case NativeSettings.AUDIO_CHANNELS_STEREO -> R.string.stereo;
|
||||
case NativeSettings.AUDIO_CHANNELS_SURROUND -> R.string.surround;
|
||||
default -> throw new IllegalArgumentException("Invalid channels type: " + channels);
|
||||
};
|
||||
}
|
||||
@ -38,52 +38,52 @@ public class AudioSettingsFragment extends Fragment {
|
||||
GenericRecyclerViewAdapter genericRecyclerViewAdapter = new GenericRecyclerViewAdapter();
|
||||
|
||||
CheckboxRecyclerViewItem tvDeviceCheckbox = new CheckboxRecyclerViewItem(getString(R.string.tv),
|
||||
getString(R.string.tv_audio_description), NativeLibrary.getAudioDeviceEnabled(true),
|
||||
checked -> NativeLibrary.setAudioDeviceEnabled(checked, true));
|
||||
getString(R.string.tv_audio_description), NativeSettings.getAudioDeviceEnabled(true),
|
||||
checked -> NativeSettings.setAudioDeviceEnabled(checked, true));
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(tvDeviceCheckbox);
|
||||
|
||||
var tvChannelsChoices = Stream.of(NativeLibrary.AUDIO_CHANNELS_MONO, NativeLibrary.AUDIO_CHANNELS_STEREO, NativeLibrary.AUDIO_CHANNELS_SURROUND)
|
||||
var tvChannelsChoices = Stream.of(NativeSettings.AUDIO_CHANNELS_MONO, NativeSettings.AUDIO_CHANNELS_STEREO, NativeSettings.AUDIO_CHANNELS_SURROUND)
|
||||
.map(channels -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(channelsToResourceNameId(channels)), channels))
|
||||
.collect(Collectors.toList());
|
||||
int tvChannels = NativeLibrary.getAudioDeviceChannels(true);
|
||||
int tvChannels = NativeSettings.getAudioDeviceChannels(true);
|
||||
SelectionAdapter<Integer> tvChannelsSelectionAdapter = new SelectionAdapter<>(tvChannelsChoices, tvChannels);
|
||||
SingleSelectionRecyclerViewItem<Integer> tvChannelsModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.tv_channels),
|
||||
getString(channelsToResourceNameId(tvChannels)), tvChannelsSelectionAdapter,
|
||||
(channels, selectionRecyclerViewItem) -> {
|
||||
NativeLibrary.setAudioDeviceChannels(channels, true);
|
||||
NativeSettings.setAudioDeviceChannels(channels, true);
|
||||
selectionRecyclerViewItem.setDescription(getString(channelsToResourceNameId(channels)));
|
||||
});
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(tvChannelsModeSelection);
|
||||
|
||||
SliderRecyclerViewItem tvVolumeSlider = new SliderRecyclerViewItem(getString(R.string.tv_volume),
|
||||
NativeLibrary.AUDIO_MIN_VOLUME,
|
||||
NativeLibrary.AUDIO_MAX_VOLUME,
|
||||
NativeLibrary.getAudioDeviceVolume(true),
|
||||
value -> NativeLibrary.setAudioDeviceVolume((int) value, true),
|
||||
NativeSettings.AUDIO_MIN_VOLUME,
|
||||
NativeSettings.AUDIO_MAX_VOLUME,
|
||||
NativeSettings.getAudioDeviceVolume(true),
|
||||
value -> NativeSettings.setAudioDeviceVolume((int) value, true),
|
||||
value -> (int) value + "%");
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(tvVolumeSlider);
|
||||
|
||||
CheckboxRecyclerViewItem padDeviceCheckbox = new CheckboxRecyclerViewItem(getString(R.string.gamepad),
|
||||
getString(R.string.gamepad_audio_description), NativeLibrary.getAudioDeviceEnabled(false),
|
||||
checked -> NativeLibrary.setAudioDeviceEnabled(checked, false));
|
||||
getString(R.string.gamepad_audio_description), NativeSettings.getAudioDeviceEnabled(false),
|
||||
checked -> NativeSettings.setAudioDeviceEnabled(checked, false));
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(padDeviceCheckbox);
|
||||
|
||||
var gamepadChannelsChoices = List.of(new SelectionAdapter.ChoiceItem<>(t -> t.setText(channelsToResourceNameId(NativeLibrary.AUDIO_CHANNELS_STEREO)), NativeLibrary.AUDIO_CHANNELS_STEREO));
|
||||
int gamepadChannels = NativeLibrary.getAudioDeviceChannels(false);
|
||||
var gamepadChannelsChoices = List.of(new SelectionAdapter.ChoiceItem<>(t -> t.setText(channelsToResourceNameId(NativeSettings.AUDIO_CHANNELS_STEREO)), NativeSettings.AUDIO_CHANNELS_STEREO));
|
||||
int gamepadChannels = NativeSettings.getAudioDeviceChannels(false);
|
||||
SelectionAdapter<Integer> gamepadChannelsSelectionAdapter = new SelectionAdapter<>(gamepadChannelsChoices, gamepadChannels);
|
||||
SingleSelectionRecyclerViewItem<Integer> gamepadChannelsModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.gamepad_channels),
|
||||
getString(channelsToResourceNameId(gamepadChannels)), gamepadChannelsSelectionAdapter,
|
||||
(channels, selectionRecyclerViewItem) -> {
|
||||
NativeLibrary.setAudioDeviceChannels(channels, false);
|
||||
NativeSettings.setAudioDeviceChannels(channels, false);
|
||||
selectionRecyclerViewItem.setDescription(getString(channelsToResourceNameId(channels)));
|
||||
});
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(gamepadChannelsModeSelection);
|
||||
|
||||
SliderRecyclerViewItem padVolumeSlider = new SliderRecyclerViewItem(getString(R.string.pad_volume),
|
||||
NativeLibrary.AUDIO_MIN_VOLUME,
|
||||
NativeLibrary.AUDIO_MAX_VOLUME,
|
||||
NativeLibrary.getAudioDeviceVolume(false),
|
||||
value -> NativeLibrary.setAudioDeviceVolume((int) value, false),
|
||||
NativeSettings.AUDIO_MIN_VOLUME,
|
||||
NativeSettings.AUDIO_MAX_VOLUME,
|
||||
NativeSettings.getAudioDeviceVolume(false),
|
||||
value -> NativeSettings.setAudioDeviceVolume((int) value, false),
|
||||
value -> (int) value + "%");
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(padVolumeSlider);
|
||||
|
||||
|
@ -27,7 +27,7 @@ import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeSettings;
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.databinding.GenericRecyclerViewLayoutBinding;
|
||||
|
||||
@ -56,12 +56,12 @@ public class GamePathsFragment extends Fragment {
|
||||
Toast.makeText(requireContext(), R.string.game_path_already_added, Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
NativeLibrary.addGamesPath(gamesPath);
|
||||
NativeSettings.addGamesPath(gamesPath);
|
||||
gamesPaths = Stream.concat(Stream.of(gamesPath), gamesPaths.stream()).collect(Collectors.toList());
|
||||
gamePathAdapter.submitList(gamesPaths);
|
||||
});
|
||||
gamePathAdapter = new GamePathAdapter(path -> {
|
||||
NativeLibrary.removeGamesPath(path);
|
||||
NativeSettings.removeGamesPath(path);
|
||||
gamesPaths = gamesPaths.stream().filter(p -> !p.equals(path)).collect(Collectors.toList());
|
||||
gamePathAdapter.submitList(gamesPaths);
|
||||
});
|
||||
@ -71,7 +71,7 @@ public class GamePathsFragment extends Fragment {
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
GenericRecyclerViewLayoutBinding binding = GenericRecyclerViewLayoutBinding.inflate(inflater, container, false);
|
||||
binding.recyclerView.setAdapter(gamePathAdapter);
|
||||
gamesPaths = NativeLibrary.getGamesPaths();
|
||||
gamesPaths = NativeSettings.getGamesPaths();
|
||||
gamePathAdapter.submitList(gamesPaths);
|
||||
requireActivity().addMenuProvider(new MenuProvider() {
|
||||
@Override
|
||||
|
@ -11,7 +11,7 @@ import com.google.android.material.checkbox.MaterialCheckBox;
|
||||
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.guibasecomponents.RecyclerViewItem;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeGraphicPacks;
|
||||
|
||||
public class GraphicPackRecyclerViewItem implements RecyclerViewItem {
|
||||
private static class GraphicPackViewHolder extends RecyclerView.ViewHolder {
|
||||
@ -28,9 +28,9 @@ public class GraphicPackRecyclerViewItem implements RecyclerViewItem {
|
||||
}
|
||||
|
||||
|
||||
private final NativeLibrary.GraphicPack graphicPack;
|
||||
private final NativeGraphicPacks.GraphicPack graphicPack;
|
||||
|
||||
public GraphicPackRecyclerViewItem(NativeLibrary.GraphicPack graphicPack) {
|
||||
public GraphicPackRecyclerViewItem(NativeGraphicPacks.GraphicPack graphicPack) {
|
||||
this.graphicPack = graphicPack;
|
||||
}
|
||||
|
||||
|
@ -21,7 +21,7 @@ import info.cemu.Cemu.databinding.GenericRecyclerViewLayoutBinding;
|
||||
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.StringSelectionAdapter;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeGraphicPacks;
|
||||
|
||||
public class GraphicPacksFragment extends Fragment {
|
||||
private final GenericRecyclerViewAdapter genericRecyclerViewAdapter = new GenericRecyclerViewAdapter();
|
||||
@ -78,12 +78,12 @@ public class GraphicPacksFragment extends Fragment {
|
||||
|
||||
private void fillData(GraphicPacksRootFragment.GraphicPackDataNode graphicPackDataNode) {
|
||||
genericRecyclerViewAdapter.clearRecyclerViewItems();
|
||||
var graphicPack = NativeLibrary.getGraphicPack(graphicPackDataNode.getId());
|
||||
var graphicPack = NativeGraphicPacks.getGraphicPack(graphicPackDataNode.getId());
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(new GraphicPackRecyclerViewItem(graphicPack));
|
||||
fillPresets(graphicPack);
|
||||
}
|
||||
|
||||
private void fillPresets(NativeLibrary.GraphicPack graphicPack) {
|
||||
private void fillPresets(NativeGraphicPacks.GraphicPack graphicPack) {
|
||||
var recyclerViewItems = new ArrayList<SingleSelectionRecyclerViewItem<String>>();
|
||||
IntStream.range(0, graphicPack.presets.size()).forEach(index -> {
|
||||
var graphicPackPreset = graphicPack.presets.get(index);
|
||||
|
@ -41,10 +41,10 @@ import java.util.Optional;
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.databinding.GenericRecyclerViewLayoutBinding;
|
||||
import info.cemu.Cemu.guibasecomponents.FilterableRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.utils.FileUtil;
|
||||
import info.cemu.Cemu.utils.ZipUtil;
|
||||
import info.cemu.Cemu.nativeinterface.FileCallbacks;
|
||||
import info.cemu.Cemu.nativeinterface.NativeGameTitles;
|
||||
import info.cemu.Cemu.nativeinterface.NativeGraphicPacks;
|
||||
import info.cemu.Cemu.zip.Zip;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.OkHttpClient;
|
||||
@ -144,7 +144,7 @@ public class GraphicPacksRootFragment extends Fragment {
|
||||
}
|
||||
}
|
||||
|
||||
private final ArrayList<Long> installedTitleIds = NativeLibrary.getInstalledGamesTitleIds();
|
||||
private final ArrayList<Long> installedTitleIds = NativeGameTitles.getInstalledGamesTitleIds();
|
||||
private final GraphicPackSectionNode graphicPackSectionRootNode = new GraphicPackSectionNode();
|
||||
private final FilterableRecyclerViewAdapter<GraphicPackItemRecyclerViewItem> genericRecyclerViewAdapter = new FilterableRecyclerViewAdapter<>();
|
||||
private GraphicPackViewModel graphicPackViewModel;
|
||||
@ -240,7 +240,7 @@ public class GraphicPacksRootFragment extends Fragment {
|
||||
}
|
||||
|
||||
private void fillGraphicPacks() {
|
||||
var nativeGraphicPacks = NativeLibrary.getGraphicPackBasicInfos();
|
||||
var nativeGraphicPacks = NativeGraphicPacks.getGraphicPackBasicInfos();
|
||||
graphicPackSectionRootNode.clear();
|
||||
List<GraphicPackDataNode> graphicPackDataNodes = new ArrayList<>();
|
||||
nativeGraphicPacks.forEach(graphicPack -> {
|
||||
@ -329,13 +329,13 @@ public class GraphicPacksRootFragment extends Fragment {
|
||||
public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException {
|
||||
try (ResponseBody responseBody = response.body()) {
|
||||
Path graphicPacksTempDirPath = graphicPacksDirPath.resolve("downloadedGraphicPacksTemp");
|
||||
FileUtil.delete(graphicPacksTempDirPath);
|
||||
ZipUtil.unzip(Objects.requireNonNull(responseBody).byteStream(), graphicPacksTempDirPath.toString());
|
||||
FileCallbacks.delete(graphicPacksTempDirPath);
|
||||
Zip.unzip(Objects.requireNonNull(responseBody).byteStream(), graphicPacksTempDirPath.toString());
|
||||
Files.write(graphicPacksTempDirPath.resolve("version.txt"), version.getBytes(StandardCharsets.UTF_8));
|
||||
Path downloadedGraphicPacksDirPath = graphicPacksDirPath.resolve("downloadedGraphicPacks");
|
||||
FileUtil.delete(downloadedGraphicPacksDirPath);
|
||||
FileCallbacks.delete(downloadedGraphicPacksDirPath);
|
||||
Files.move(graphicPacksTempDirPath, downloadedGraphicPacksDirPath);
|
||||
NativeLibrary.refreshGraphicPacks();
|
||||
NativeGraphicPacks.refreshGraphicPacks();
|
||||
requireActivity().runOnUiThread(() -> fillGraphicPacks());
|
||||
onDownloadFinish(dialog);
|
||||
}
|
||||
|
@ -6,7 +6,6 @@ import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.StringRes;
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
@ -18,14 +17,14 @@ import info.cemu.Cemu.guibasecomponents.CheckboxRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeSettings;
|
||||
|
||||
public class GraphicsSettingsFragment extends Fragment {
|
||||
private static int vsyncModeToResourceNameId(int vsyncMode) {
|
||||
return switch (vsyncMode) {
|
||||
case NativeLibrary.VSYNC_MODE_OFF -> R.string.off;
|
||||
case NativeLibrary.VSYNC_MODE_DOUBLE_BUFFERING -> R.string.double_buffering;
|
||||
case NativeLibrary.VSYNC_MODE_TRIPLE_BUFFERING -> R.string.triple_buffering;
|
||||
case NativeSettings.VSYNC_MODE_OFF -> R.string.off;
|
||||
case NativeSettings.VSYNC_MODE_DOUBLE_BUFFERING -> R.string.double_buffering;
|
||||
case NativeSettings.VSYNC_MODE_TRIPLE_BUFFERING -> R.string.triple_buffering;
|
||||
default -> throw new IllegalArgumentException("Invalid vsync mode: " + vsyncMode);
|
||||
};
|
||||
}
|
||||
@ -36,23 +35,23 @@ public class GraphicsSettingsFragment extends Fragment {
|
||||
|
||||
GenericRecyclerViewAdapter genericRecyclerViewAdapter = new GenericRecyclerViewAdapter();
|
||||
|
||||
CheckboxRecyclerViewItem asyncShaderCheckbox = new CheckboxRecyclerViewItem(getString(R.string.async_shader_compile), getString(R.string.async_shader_compile_description), NativeLibrary.getAsyncShaderCompile(), NativeLibrary::setAsyncShaderCompile);
|
||||
CheckboxRecyclerViewItem asyncShaderCheckbox = new CheckboxRecyclerViewItem(getString(R.string.async_shader_compile), getString(R.string.async_shader_compile_description), NativeSettings.getAsyncShaderCompile(), NativeSettings::setAsyncShaderCompile);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(asyncShaderCheckbox);
|
||||
|
||||
int vsyncMode = NativeLibrary.getVSyncMode();
|
||||
var vsyncChoices = Stream.of(NativeLibrary.VSYNC_MODE_OFF, NativeLibrary.VSYNC_MODE_DOUBLE_BUFFERING, NativeLibrary.VSYNC_MODE_TRIPLE_BUFFERING)
|
||||
int vsyncMode = NativeSettings.getVSyncMode();
|
||||
var vsyncChoices = Stream.of(NativeSettings.VSYNC_MODE_OFF, NativeSettings.VSYNC_MODE_DOUBLE_BUFFERING, NativeSettings.VSYNC_MODE_TRIPLE_BUFFERING)
|
||||
.map(vsync -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(vsyncModeToResourceNameId(vsync)), vsync))
|
||||
.collect(Collectors.toList());
|
||||
SelectionAdapter<Integer> vsyncSelectionAdapter = new SelectionAdapter<>(vsyncChoices, vsyncMode);
|
||||
SingleSelectionRecyclerViewItem<Integer> vsyncModeSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.vsync),
|
||||
getString(vsyncModeToResourceNameId(vsyncMode)), vsyncSelectionAdapter,
|
||||
(vsync, selectionRecyclerViewItem) -> {
|
||||
NativeLibrary.setVSyncMode(vsync);
|
||||
NativeSettings.setVSyncMode(vsync);
|
||||
selectionRecyclerViewItem.setDescription(getString(vsyncModeToResourceNameId(vsync)));
|
||||
});
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(vsyncModeSelection);
|
||||
|
||||
CheckboxRecyclerViewItem accurateBarriersCheckbox = new CheckboxRecyclerViewItem(getString(R.string.accurate_barriers), getString(R.string.accurate_barriers_description), NativeLibrary.getAccurateBarriers(), NativeLibrary::setAccurateBarriers);
|
||||
CheckboxRecyclerViewItem accurateBarriersCheckbox = new CheckboxRecyclerViewItem(getString(R.string.accurate_barriers), getString(R.string.accurate_barriers_description), NativeSettings.getAccurateBarriers(), NativeSettings::setAccurateBarriers);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(accurateBarriersCheckbox);
|
||||
|
||||
binding.recyclerView.setAdapter(genericRecyclerViewAdapter);
|
||||
|
@ -6,122 +6,122 @@ import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class ControllerInputsDataProvider {
|
||||
private int getButtonResourceIdName(int controllerType, int buttonId) {
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD) {
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_VPAD) {
|
||||
return switch (buttonId) {
|
||||
case NativeLibrary.VPAD_BUTTON_A -> R.string.button_a;
|
||||
case NativeLibrary.VPAD_BUTTON_B -> R.string.button_b;
|
||||
case NativeLibrary.VPAD_BUTTON_X -> R.string.button_x;
|
||||
case NativeLibrary.VPAD_BUTTON_Y -> R.string.button_y;
|
||||
case NativeLibrary.VPAD_BUTTON_L -> R.string.button_l;
|
||||
case NativeLibrary.VPAD_BUTTON_R -> R.string.button_r;
|
||||
case NativeLibrary.VPAD_BUTTON_ZL -> R.string.button_zl;
|
||||
case NativeLibrary.VPAD_BUTTON_ZR -> R.string.button_zr;
|
||||
case NativeLibrary.VPAD_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeLibrary.VPAD_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeLibrary.VPAD_BUTTON_UP -> R.string.button_up;
|
||||
case NativeLibrary.VPAD_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeLibrary.VPAD_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeLibrary.VPAD_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKL -> R.string.button_stickl;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKR -> R.string.button_stickr;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKL_UP -> R.string.button_stickl_up;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKL_DOWN -> R.string.button_stickl_down;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKL_LEFT -> R.string.button_stickl_left;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKL_RIGHT -> R.string.button_stickl_right;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKR_UP -> R.string.button_stickr_up;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKR_DOWN -> R.string.button_stickr_down;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKR_LEFT -> R.string.button_stickr_left;
|
||||
case NativeLibrary.VPAD_BUTTON_STICKR_RIGHT -> R.string.button_stickr_right;
|
||||
case NativeLibrary.VPAD_BUTTON_MIC -> R.string.button_mic;
|
||||
case NativeLibrary.VPAD_BUTTON_SCREEN -> R.string.button_screen;
|
||||
case NativeLibrary.VPAD_BUTTON_HOME -> R.string.button_home;
|
||||
case NativeInput.VPAD_BUTTON_A -> R.string.button_a;
|
||||
case NativeInput.VPAD_BUTTON_B -> R.string.button_b;
|
||||
case NativeInput.VPAD_BUTTON_X -> R.string.button_x;
|
||||
case NativeInput.VPAD_BUTTON_Y -> R.string.button_y;
|
||||
case NativeInput.VPAD_BUTTON_L -> R.string.button_l;
|
||||
case NativeInput.VPAD_BUTTON_R -> R.string.button_r;
|
||||
case NativeInput.VPAD_BUTTON_ZL -> R.string.button_zl;
|
||||
case NativeInput.VPAD_BUTTON_ZR -> R.string.button_zr;
|
||||
case NativeInput.VPAD_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeInput.VPAD_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeInput.VPAD_BUTTON_UP -> R.string.button_up;
|
||||
case NativeInput.VPAD_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeInput.VPAD_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeInput.VPAD_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeInput.VPAD_BUTTON_STICKL -> R.string.button_stickl;
|
||||
case NativeInput.VPAD_BUTTON_STICKR -> R.string.button_stickr;
|
||||
case NativeInput.VPAD_BUTTON_STICKL_UP -> R.string.button_stickl_up;
|
||||
case NativeInput.VPAD_BUTTON_STICKL_DOWN -> R.string.button_stickl_down;
|
||||
case NativeInput.VPAD_BUTTON_STICKL_LEFT -> R.string.button_stickl_left;
|
||||
case NativeInput.VPAD_BUTTON_STICKL_RIGHT -> R.string.button_stickl_right;
|
||||
case NativeInput.VPAD_BUTTON_STICKR_UP -> R.string.button_stickr_up;
|
||||
case NativeInput.VPAD_BUTTON_STICKR_DOWN -> R.string.button_stickr_down;
|
||||
case NativeInput.VPAD_BUTTON_STICKR_LEFT -> R.string.button_stickr_left;
|
||||
case NativeInput.VPAD_BUTTON_STICKR_RIGHT -> R.string.button_stickr_right;
|
||||
case NativeInput.VPAD_BUTTON_MIC -> R.string.button_mic;
|
||||
case NativeInput.VPAD_BUTTON_SCREEN -> R.string.button_screen;
|
||||
case NativeInput.VPAD_BUTTON_HOME -> R.string.button_home;
|
||||
default ->
|
||||
throw new IllegalArgumentException("Invalid buttonId " + buttonId + " for controllerType " + controllerType);
|
||||
};
|
||||
}
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_PRO) {
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_PRO) {
|
||||
return switch (buttonId) {
|
||||
case NativeLibrary.PRO_BUTTON_A -> R.string.button_a;
|
||||
case NativeLibrary.PRO_BUTTON_B -> R.string.button_b;
|
||||
case NativeLibrary.PRO_BUTTON_X -> R.string.button_x;
|
||||
case NativeLibrary.PRO_BUTTON_Y -> R.string.button_y;
|
||||
case NativeLibrary.PRO_BUTTON_L -> R.string.button_l;
|
||||
case NativeLibrary.PRO_BUTTON_R -> R.string.button_r;
|
||||
case NativeLibrary.PRO_BUTTON_ZL -> R.string.button_zl;
|
||||
case NativeLibrary.PRO_BUTTON_ZR -> R.string.button_zr;
|
||||
case NativeLibrary.PRO_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeLibrary.PRO_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeLibrary.PRO_BUTTON_HOME -> R.string.button_home;
|
||||
case NativeLibrary.PRO_BUTTON_UP -> R.string.button_up;
|
||||
case NativeLibrary.PRO_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeLibrary.PRO_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeLibrary.PRO_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeLibrary.PRO_BUTTON_STICKL -> R.string.button_stickl;
|
||||
case NativeLibrary.PRO_BUTTON_STICKR -> R.string.button_stickr;
|
||||
case NativeLibrary.PRO_BUTTON_STICKL_UP -> R.string.button_stickl_up;
|
||||
case NativeLibrary.PRO_BUTTON_STICKL_DOWN -> R.string.button_stickl_down;
|
||||
case NativeLibrary.PRO_BUTTON_STICKL_LEFT -> R.string.button_stickl_left;
|
||||
case NativeLibrary.PRO_BUTTON_STICKL_RIGHT -> R.string.button_stickl_right;
|
||||
case NativeLibrary.PRO_BUTTON_STICKR_UP -> R.string.button_stickr_up;
|
||||
case NativeLibrary.PRO_BUTTON_STICKR_DOWN -> R.string.button_stickr_down;
|
||||
case NativeLibrary.PRO_BUTTON_STICKR_LEFT -> R.string.button_stickr_left;
|
||||
case NativeLibrary.PRO_BUTTON_STICKR_RIGHT -> R.string.button_stickr_right;
|
||||
case NativeInput.PRO_BUTTON_A -> R.string.button_a;
|
||||
case NativeInput.PRO_BUTTON_B -> R.string.button_b;
|
||||
case NativeInput.PRO_BUTTON_X -> R.string.button_x;
|
||||
case NativeInput.PRO_BUTTON_Y -> R.string.button_y;
|
||||
case NativeInput.PRO_BUTTON_L -> R.string.button_l;
|
||||
case NativeInput.PRO_BUTTON_R -> R.string.button_r;
|
||||
case NativeInput.PRO_BUTTON_ZL -> R.string.button_zl;
|
||||
case NativeInput.PRO_BUTTON_ZR -> R.string.button_zr;
|
||||
case NativeInput.PRO_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeInput.PRO_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeInput.PRO_BUTTON_HOME -> R.string.button_home;
|
||||
case NativeInput.PRO_BUTTON_UP -> R.string.button_up;
|
||||
case NativeInput.PRO_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeInput.PRO_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeInput.PRO_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeInput.PRO_BUTTON_STICKL -> R.string.button_stickl;
|
||||
case NativeInput.PRO_BUTTON_STICKR -> R.string.button_stickr;
|
||||
case NativeInput.PRO_BUTTON_STICKL_UP -> R.string.button_stickl_up;
|
||||
case NativeInput.PRO_BUTTON_STICKL_DOWN -> R.string.button_stickl_down;
|
||||
case NativeInput.PRO_BUTTON_STICKL_LEFT -> R.string.button_stickl_left;
|
||||
case NativeInput.PRO_BUTTON_STICKL_RIGHT -> R.string.button_stickl_right;
|
||||
case NativeInput.PRO_BUTTON_STICKR_UP -> R.string.button_stickr_up;
|
||||
case NativeInput.PRO_BUTTON_STICKR_DOWN -> R.string.button_stickr_down;
|
||||
case NativeInput.PRO_BUTTON_STICKR_LEFT -> R.string.button_stickr_left;
|
||||
case NativeInput.PRO_BUTTON_STICKR_RIGHT -> R.string.button_stickr_right;
|
||||
default ->
|
||||
throw new IllegalArgumentException("Invalid buttonId " + buttonId + " for controllerType " + controllerType);
|
||||
};
|
||||
}
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_CLASSIC) {
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_CLASSIC) {
|
||||
return switch (buttonId) {
|
||||
case NativeLibrary.CLASSIC_BUTTON_A -> R.string.button_a;
|
||||
case NativeLibrary.CLASSIC_BUTTON_B -> R.string.button_b;
|
||||
case NativeLibrary.CLASSIC_BUTTON_X -> R.string.button_x;
|
||||
case NativeLibrary.CLASSIC_BUTTON_Y -> R.string.button_y;
|
||||
case NativeLibrary.CLASSIC_BUTTON_L -> R.string.button_l;
|
||||
case NativeLibrary.CLASSIC_BUTTON_R -> R.string.button_r;
|
||||
case NativeLibrary.CLASSIC_BUTTON_ZL -> R.string.button_zl;
|
||||
case NativeLibrary.CLASSIC_BUTTON_ZR -> R.string.button_zr;
|
||||
case NativeLibrary.CLASSIC_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeLibrary.CLASSIC_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeLibrary.CLASSIC_BUTTON_HOME -> R.string.button_home;
|
||||
case NativeLibrary.CLASSIC_BUTTON_UP -> R.string.button_up;
|
||||
case NativeLibrary.CLASSIC_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeLibrary.CLASSIC_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeLibrary.CLASSIC_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKL_UP -> R.string.button_stickl_up;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKL_DOWN -> R.string.button_stickl_down;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKL_LEFT -> R.string.button_stickl_left;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKL_RIGHT -> R.string.button_stickl_right;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKR_UP -> R.string.button_stickr_up;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKR_DOWN -> R.string.button_stickr_down;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKR_LEFT -> R.string.button_stickr_left;
|
||||
case NativeLibrary.CLASSIC_BUTTON_STICKR_RIGHT -> R.string.button_stickr_right;
|
||||
case NativeInput.CLASSIC_BUTTON_A -> R.string.button_a;
|
||||
case NativeInput.CLASSIC_BUTTON_B -> R.string.button_b;
|
||||
case NativeInput.CLASSIC_BUTTON_X -> R.string.button_x;
|
||||
case NativeInput.CLASSIC_BUTTON_Y -> R.string.button_y;
|
||||
case NativeInput.CLASSIC_BUTTON_L -> R.string.button_l;
|
||||
case NativeInput.CLASSIC_BUTTON_R -> R.string.button_r;
|
||||
case NativeInput.CLASSIC_BUTTON_ZL -> R.string.button_zl;
|
||||
case NativeInput.CLASSIC_BUTTON_ZR -> R.string.button_zr;
|
||||
case NativeInput.CLASSIC_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeInput.CLASSIC_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeInput.CLASSIC_BUTTON_HOME -> R.string.button_home;
|
||||
case NativeInput.CLASSIC_BUTTON_UP -> R.string.button_up;
|
||||
case NativeInput.CLASSIC_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeInput.CLASSIC_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeInput.CLASSIC_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKL_UP -> R.string.button_stickl_up;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKL_DOWN -> R.string.button_stickl_down;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKL_LEFT -> R.string.button_stickl_left;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKL_RIGHT -> R.string.button_stickl_right;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKR_UP -> R.string.button_stickr_up;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKR_DOWN -> R.string.button_stickr_down;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKR_LEFT -> R.string.button_stickr_left;
|
||||
case NativeInput.CLASSIC_BUTTON_STICKR_RIGHT -> R.string.button_stickr_right;
|
||||
default ->
|
||||
throw new IllegalArgumentException("Invalid buttonId " + buttonId + " for controllerType " + controllerType);
|
||||
};
|
||||
}
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
return switch (buttonId) {
|
||||
case NativeLibrary.WIIMOTE_BUTTON_A -> R.string.button_a;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_B -> R.string.button_b;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_1 -> R.string.button_1;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_2 -> R.string.button_2;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_Z -> R.string.button_nunchuck_z;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_C -> R.string.button_nunchuck_c;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_UP -> R.string.button_up;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_UP -> R.string.button_nunchuck_up;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_DOWN -> R.string.button_nunchuck_down;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_LEFT -> R.string.button_nunchuck_left;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_RIGHT -> R.string.button_nunchuck_right;
|
||||
case NativeLibrary.WIIMOTE_BUTTON_HOME -> R.string.button_home;
|
||||
case NativeInput.WIIMOTE_BUTTON_A -> R.string.button_a;
|
||||
case NativeInput.WIIMOTE_BUTTON_B -> R.string.button_b;
|
||||
case NativeInput.WIIMOTE_BUTTON_1 -> R.string.button_1;
|
||||
case NativeInput.WIIMOTE_BUTTON_2 -> R.string.button_2;
|
||||
case NativeInput.WIIMOTE_BUTTON_NUNCHUCK_Z -> R.string.button_nunchuck_z;
|
||||
case NativeInput.WIIMOTE_BUTTON_NUNCHUCK_C -> R.string.button_nunchuck_c;
|
||||
case NativeInput.WIIMOTE_BUTTON_PLUS -> R.string.button_plus;
|
||||
case NativeInput.WIIMOTE_BUTTON_MINUS -> R.string.button_minus;
|
||||
case NativeInput.WIIMOTE_BUTTON_UP -> R.string.button_up;
|
||||
case NativeInput.WIIMOTE_BUTTON_DOWN -> R.string.button_down;
|
||||
case NativeInput.WIIMOTE_BUTTON_LEFT -> R.string.button_left;
|
||||
case NativeInput.WIIMOTE_BUTTON_RIGHT -> R.string.button_right;
|
||||
case NativeInput.WIIMOTE_BUTTON_NUNCHUCK_UP -> R.string.button_nunchuck_up;
|
||||
case NativeInput.WIIMOTE_BUTTON_NUNCHUCK_DOWN -> R.string.button_nunchuck_down;
|
||||
case NativeInput.WIIMOTE_BUTTON_NUNCHUCK_LEFT -> R.string.button_nunchuck_left;
|
||||
case NativeInput.WIIMOTE_BUTTON_NUNCHUCK_RIGHT -> R.string.button_nunchuck_right;
|
||||
case NativeInput.WIIMOTE_BUTTON_HOME -> R.string.button_home;
|
||||
default ->
|
||||
throw new IllegalArgumentException("Invalid buttonId " + buttonId + " for controllerType " + controllerType);
|
||||
};
|
||||
@ -158,29 +158,29 @@ public class ControllerInputsDataProvider {
|
||||
|
||||
public List<ControllerInputGroup> getControllerInputs(int controllerType, Map<Integer, String> inputs) {
|
||||
List<ControllerInputGroup> controllerInputItems = new ArrayList<>();
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeLibrary.VPAD_BUTTON_A, NativeLibrary.VPAD_BUTTON_B, NativeLibrary.VPAD_BUTTON_X, NativeLibrary.VPAD_BUTTON_Y, NativeLibrary.VPAD_BUTTON_L, NativeLibrary.VPAD_BUTTON_R, NativeLibrary.VPAD_BUTTON_ZL, NativeLibrary.VPAD_BUTTON_ZR, NativeLibrary.VPAD_BUTTON_PLUS, NativeLibrary.VPAD_BUTTON_MINUS), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeLibrary.VPAD_BUTTON_UP, NativeLibrary.VPAD_BUTTON_DOWN, NativeLibrary.VPAD_BUTTON_LEFT, NativeLibrary.VPAD_BUTTON_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.left_axis, controllerType, List.of(NativeLibrary.VPAD_BUTTON_STICKL, NativeLibrary.VPAD_BUTTON_STICKL_UP, NativeLibrary.VPAD_BUTTON_STICKL_DOWN, NativeLibrary.VPAD_BUTTON_STICKL_LEFT, NativeLibrary.VPAD_BUTTON_STICKL_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.right_axis, controllerType, List.of(NativeLibrary.VPAD_BUTTON_STICKR, NativeLibrary.VPAD_BUTTON_STICKR_UP, NativeLibrary.VPAD_BUTTON_STICKR_DOWN, NativeLibrary.VPAD_BUTTON_STICKR_LEFT, NativeLibrary.VPAD_BUTTON_STICKR_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.extra, controllerType, List.of(NativeLibrary.VPAD_BUTTON_MIC, NativeLibrary.VPAD_BUTTON_SCREEN, NativeLibrary.VPAD_BUTTON_HOME), inputs);
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_VPAD) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeInput.VPAD_BUTTON_A, NativeInput.VPAD_BUTTON_B, NativeInput.VPAD_BUTTON_X, NativeInput.VPAD_BUTTON_Y, NativeInput.VPAD_BUTTON_L, NativeInput.VPAD_BUTTON_R, NativeInput.VPAD_BUTTON_ZL, NativeInput.VPAD_BUTTON_ZR, NativeInput.VPAD_BUTTON_PLUS, NativeInput.VPAD_BUTTON_MINUS), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeInput.VPAD_BUTTON_UP, NativeInput.VPAD_BUTTON_DOWN, NativeInput.VPAD_BUTTON_LEFT, NativeInput.VPAD_BUTTON_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.left_axis, controllerType, List.of(NativeInput.VPAD_BUTTON_STICKL, NativeInput.VPAD_BUTTON_STICKL_UP, NativeInput.VPAD_BUTTON_STICKL_DOWN, NativeInput.VPAD_BUTTON_STICKL_LEFT, NativeInput.VPAD_BUTTON_STICKL_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.right_axis, controllerType, List.of(NativeInput.VPAD_BUTTON_STICKR, NativeInput.VPAD_BUTTON_STICKR_UP, NativeInput.VPAD_BUTTON_STICKR_DOWN, NativeInput.VPAD_BUTTON_STICKR_LEFT, NativeInput.VPAD_BUTTON_STICKR_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.extra, controllerType, List.of(NativeInput.VPAD_BUTTON_MIC, NativeInput.VPAD_BUTTON_SCREEN, NativeInput.VPAD_BUTTON_HOME), inputs);
|
||||
}
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_PRO) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeLibrary.PRO_BUTTON_A, NativeLibrary.PRO_BUTTON_B, NativeLibrary.PRO_BUTTON_X, NativeLibrary.PRO_BUTTON_Y, NativeLibrary.PRO_BUTTON_L, NativeLibrary.PRO_BUTTON_R, NativeLibrary.PRO_BUTTON_ZL, NativeLibrary.PRO_BUTTON_ZR, NativeLibrary.PRO_BUTTON_PLUS, NativeLibrary.PRO_BUTTON_MINUS, NativeLibrary.PRO_BUTTON_HOME), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.left_axis, controllerType, List.of(NativeLibrary.PRO_BUTTON_STICKL, NativeLibrary.PRO_BUTTON_STICKL_UP, NativeLibrary.PRO_BUTTON_STICKL_DOWN, NativeLibrary.PRO_BUTTON_STICKL_LEFT, NativeLibrary.PRO_BUTTON_STICKL_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.right_axis, controllerType, List.of(NativeLibrary.PRO_BUTTON_STICKR, NativeLibrary.PRO_BUTTON_STICKR_UP, NativeLibrary.PRO_BUTTON_STICKR_DOWN, NativeLibrary.PRO_BUTTON_STICKR_LEFT, NativeLibrary.PRO_BUTTON_STICKR_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeLibrary.PRO_BUTTON_UP, NativeLibrary.PRO_BUTTON_DOWN, NativeLibrary.PRO_BUTTON_LEFT, NativeLibrary.PRO_BUTTON_RIGHT), inputs);
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_PRO) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeInput.PRO_BUTTON_A, NativeInput.PRO_BUTTON_B, NativeInput.PRO_BUTTON_X, NativeInput.PRO_BUTTON_Y, NativeInput.PRO_BUTTON_L, NativeInput.PRO_BUTTON_R, NativeInput.PRO_BUTTON_ZL, NativeInput.PRO_BUTTON_ZR, NativeInput.PRO_BUTTON_PLUS, NativeInput.PRO_BUTTON_MINUS, NativeInput.PRO_BUTTON_HOME), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.left_axis, controllerType, List.of(NativeInput.PRO_BUTTON_STICKL, NativeInput.PRO_BUTTON_STICKL_UP, NativeInput.PRO_BUTTON_STICKL_DOWN, NativeInput.PRO_BUTTON_STICKL_LEFT, NativeInput.PRO_BUTTON_STICKL_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.right_axis, controllerType, List.of(NativeInput.PRO_BUTTON_STICKR, NativeInput.PRO_BUTTON_STICKR_UP, NativeInput.PRO_BUTTON_STICKR_DOWN, NativeInput.PRO_BUTTON_STICKR_LEFT, NativeInput.PRO_BUTTON_STICKR_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeInput.PRO_BUTTON_UP, NativeInput.PRO_BUTTON_DOWN, NativeInput.PRO_BUTTON_LEFT, NativeInput.PRO_BUTTON_RIGHT), inputs);
|
||||
}
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_CLASSIC) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeLibrary.CLASSIC_BUTTON_A, NativeLibrary.CLASSIC_BUTTON_B, NativeLibrary.CLASSIC_BUTTON_X, NativeLibrary.CLASSIC_BUTTON_Y, NativeLibrary.CLASSIC_BUTTON_L, NativeLibrary.CLASSIC_BUTTON_R, NativeLibrary.CLASSIC_BUTTON_ZL, NativeLibrary.CLASSIC_BUTTON_ZR, NativeLibrary.CLASSIC_BUTTON_PLUS, NativeLibrary.CLASSIC_BUTTON_MINUS, NativeLibrary.CLASSIC_BUTTON_HOME), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.left_axis, controllerType, List.of(NativeLibrary.CLASSIC_BUTTON_STICKL_UP, NativeLibrary.CLASSIC_BUTTON_STICKL_DOWN, NativeLibrary.CLASSIC_BUTTON_STICKL_LEFT, NativeLibrary.CLASSIC_BUTTON_STICKL_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.right_axis, controllerType, List.of(NativeLibrary.CLASSIC_BUTTON_STICKR_UP, NativeLibrary.CLASSIC_BUTTON_STICKR_DOWN, NativeLibrary.CLASSIC_BUTTON_STICKR_LEFT, NativeLibrary.CLASSIC_BUTTON_STICKR_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeLibrary.CLASSIC_BUTTON_UP, NativeLibrary.CLASSIC_BUTTON_DOWN, NativeLibrary.CLASSIC_BUTTON_LEFT, NativeLibrary.CLASSIC_BUTTON_RIGHT), inputs);
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_CLASSIC) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeInput.CLASSIC_BUTTON_A, NativeInput.CLASSIC_BUTTON_B, NativeInput.CLASSIC_BUTTON_X, NativeInput.CLASSIC_BUTTON_Y, NativeInput.CLASSIC_BUTTON_L, NativeInput.CLASSIC_BUTTON_R, NativeInput.CLASSIC_BUTTON_ZL, NativeInput.CLASSIC_BUTTON_ZR, NativeInput.CLASSIC_BUTTON_PLUS, NativeInput.CLASSIC_BUTTON_MINUS, NativeInput.CLASSIC_BUTTON_HOME), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.left_axis, controllerType, List.of(NativeInput.CLASSIC_BUTTON_STICKL_UP, NativeInput.CLASSIC_BUTTON_STICKL_DOWN, NativeInput.CLASSIC_BUTTON_STICKL_LEFT, NativeInput.CLASSIC_BUTTON_STICKL_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.right_axis, controllerType, List.of(NativeInput.CLASSIC_BUTTON_STICKR_UP, NativeInput.CLASSIC_BUTTON_STICKR_DOWN, NativeInput.CLASSIC_BUTTON_STICKR_LEFT, NativeInput.CLASSIC_BUTTON_STICKR_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeInput.CLASSIC_BUTTON_UP, NativeInput.CLASSIC_BUTTON_DOWN, NativeInput.CLASSIC_BUTTON_LEFT, NativeInput.CLASSIC_BUTTON_RIGHT), inputs);
|
||||
}
|
||||
if (controllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeLibrary.WIIMOTE_BUTTON_A, NativeLibrary.WIIMOTE_BUTTON_B, NativeLibrary.WIIMOTE_BUTTON_1, NativeLibrary.WIIMOTE_BUTTON_2, NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_Z, NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_C, NativeLibrary.WIIMOTE_BUTTON_PLUS, NativeLibrary.WIIMOTE_BUTTON_MINUS, NativeLibrary.WIIMOTE_BUTTON_HOME), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeLibrary.WIIMOTE_BUTTON_UP, NativeLibrary.WIIMOTE_BUTTON_DOWN, NativeLibrary.WIIMOTE_BUTTON_LEFT, NativeLibrary.WIIMOTE_BUTTON_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.nunchuck, controllerType, List.of(NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_UP, NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_DOWN, NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_LEFT, NativeLibrary.WIIMOTE_BUTTON_NUNCHUCK_RIGHT), inputs);
|
||||
if (controllerType == NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE) {
|
||||
addControllerInputsGroup(controllerInputItems, R.string.buttons, controllerType, List.of(NativeInput.WIIMOTE_BUTTON_A, NativeInput.WIIMOTE_BUTTON_B, NativeInput.WIIMOTE_BUTTON_1, NativeInput.WIIMOTE_BUTTON_2, NativeInput.WIIMOTE_BUTTON_NUNCHUCK_Z, NativeInput.WIIMOTE_BUTTON_NUNCHUCK_C, NativeInput.WIIMOTE_BUTTON_PLUS, NativeInput.WIIMOTE_BUTTON_MINUS, NativeInput.WIIMOTE_BUTTON_HOME), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.d_pad, controllerType, List.of(NativeInput.WIIMOTE_BUTTON_UP, NativeInput.WIIMOTE_BUTTON_DOWN, NativeInput.WIIMOTE_BUTTON_LEFT, NativeInput.WIIMOTE_BUTTON_RIGHT), inputs);
|
||||
addControllerInputsGroup(controllerInputItems, R.string.nunchuck, controllerType, List.of(NativeInput.WIIMOTE_BUTTON_NUNCHUCK_UP, NativeInput.WIIMOTE_BUTTON_NUNCHUCK_DOWN, NativeInput.WIIMOTE_BUTTON_NUNCHUCK_LEFT, NativeInput.WIIMOTE_BUTTON_NUNCHUCK_RIGHT), inputs);
|
||||
}
|
||||
return controllerInputItems;
|
||||
}
|
||||
|
@ -21,7 +21,7 @@ import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.HeaderRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
|
||||
import info.cemu.Cemu.input.InputManager;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class ControllerInputsFragment extends Fragment {
|
||||
public static final String CONTROLLER_INDEX = "ControllerIndex";
|
||||
@ -35,14 +35,14 @@ public class ControllerInputsFragment extends Fragment {
|
||||
private void onTypeChanged(int controllerType) {
|
||||
if (this.controllerType == controllerType) return;
|
||||
this.controllerType = controllerType;
|
||||
NativeLibrary.setControllerType(controllerIndex, controllerType);
|
||||
NativeInput.setControllerType(controllerIndex, controllerType);
|
||||
genericRecyclerViewAdapter.clearRecyclerViewItems();
|
||||
setControllerInputs(new HashMap<>());
|
||||
}
|
||||
|
||||
private void setControllerInputs(Map<Integer, String> inputs) {
|
||||
emulatedControllerTypeAdapter.setSelectedValue(controllerType);
|
||||
emulatedControllerTypeAdapter.setControllerTypeCounts(NativeLibrary.getVPADControllersCount(), NativeLibrary.getWPADControllersCount());
|
||||
emulatedControllerTypeAdapter.setControllerTypeCounts(NativeInput.getVPADControllersCount(), NativeInput.getWPADControllersCount());
|
||||
String controllerTypeName = getString(ControllerTypeResourceNameMapper.controllerTypeToResourceNameId(controllerType));
|
||||
|
||||
SingleSelectionRecyclerViewItem<Integer> emulatedControllerSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.emulated_controller_label),
|
||||
@ -59,21 +59,21 @@ public class ControllerInputsFragment extends Fragment {
|
||||
MotionDialog inputDialog = new MotionDialog(getContext());
|
||||
inputDialog.setOnKeyListener((dialog, keyCode, keyEvent) -> {
|
||||
if (inputManager.mapKeyEventToMappingId(controllerIndex, buttonId, keyEvent)) {
|
||||
inputItem.setBoundInput(NativeLibrary.getControllerMapping(controllerIndex, buttonId));
|
||||
inputItem.setBoundInput(NativeInput.getControllerMapping(controllerIndex, buttonId));
|
||||
inputDialog.dismiss();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
inputDialog.setOnMotionListener(motionEvent -> {
|
||||
if (inputManager.mapMotionEventToMappingId(controllerIndex, buttonId, motionEvent)) {
|
||||
inputItem.setBoundInput(NativeLibrary.getControllerMapping(controllerIndex, buttonId));
|
||||
inputItem.setBoundInput(NativeInput.getControllerMapping(controllerIndex, buttonId));
|
||||
inputDialog.dismiss();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
inputDialog.setMessage(getString(R.string.inputBindingDialogMessage, getString(buttonResourceIdName)));
|
||||
inputDialog.setButton(AlertDialog.BUTTON_NEUTRAL, getString(R.string.clear), (dialogInterface, i) -> {
|
||||
NativeLibrary.clearControllerMapping(controllerIndex, buttonId);
|
||||
NativeInput.clearControllerMapping(controllerIndex, buttonId);
|
||||
inputItem.clearBoundInput();
|
||||
dialogInterface.dismiss();
|
||||
});
|
||||
@ -94,11 +94,11 @@ public class ControllerInputsFragment extends Fragment {
|
||||
ActionBar actionBar = ((AppCompatActivity) requireActivity()).getSupportActionBar();
|
||||
if (actionBar != null)
|
||||
actionBar.setTitle(getString(R.string.controller_numbered, controllerIndex + 1));
|
||||
if (NativeLibrary.isControllerDisabled(controllerIndex))
|
||||
controllerType = NativeLibrary.EMULATED_CONTROLLER_TYPE_DISABLED;
|
||||
else controllerType = NativeLibrary.getControllerType(controllerIndex);
|
||||
if (NativeInput.isControllerDisabled(controllerIndex))
|
||||
controllerType = NativeInput.EMULATED_CONTROLLER_TYPE_DISABLED;
|
||||
else controllerType = NativeInput.getControllerType(controllerIndex);
|
||||
|
||||
setControllerInputs(NativeLibrary.getControllerMappings(controllerIndex));
|
||||
setControllerInputs(NativeInput.getControllerMappings(controllerIndex));
|
||||
|
||||
var binding = GenericRecyclerViewLayoutBinding.inflate(inflater, container, false);
|
||||
binding.recyclerView.setAdapter(genericRecyclerViewAdapter);
|
||||
|
@ -1,16 +1,16 @@
|
||||
package info.cemu.Cemu.settings.input;
|
||||
|
||||
import info.cemu.Cemu.R;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class ControllerTypeResourceNameMapper {
|
||||
public static int controllerTypeToResourceNameId(int type) {
|
||||
return switch (type) {
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_DISABLED -> R.string.disabled;
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD -> R.string.vpad_controller;
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_PRO -> R.string.pro_controller;
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE -> R.string.wiimote_controller;
|
||||
case NativeLibrary.EMULATED_CONTROLLER_TYPE_CLASSIC -> R.string.classic_controller;
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_DISABLED -> R.string.disabled;
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_VPAD -> R.string.vpad_controller;
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_PRO -> R.string.pro_controller;
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE -> R.string.wiimote_controller;
|
||||
case NativeInput.EMULATED_CONTROLLER_TYPE_CLASSIC -> R.string.classic_controller;
|
||||
default -> throw new IllegalArgumentException("Invalid controller type: " + type);
|
||||
};
|
||||
}
|
||||
|
@ -5,21 +5,21 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class EmulatedControllerTypeAdapter extends SelectionAdapter<Integer> {
|
||||
private int vpadCount = 0;
|
||||
private int wpadCount = 0;
|
||||
|
||||
public EmulatedControllerTypeAdapter() {
|
||||
choiceItems = Stream.of(NativeLibrary.EMULATED_CONTROLLER_TYPE_DISABLED,
|
||||
NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD,
|
||||
NativeLibrary.EMULATED_CONTROLLER_TYPE_PRO,
|
||||
NativeLibrary.EMULATED_CONTROLLER_TYPE_CLASSIC,
|
||||
NativeLibrary.EMULATED_CONTROLLER_TYPE_WIIMOTE)
|
||||
choiceItems = Stream.of(NativeInput.EMULATED_CONTROLLER_TYPE_DISABLED,
|
||||
NativeInput.EMULATED_CONTROLLER_TYPE_VPAD,
|
||||
NativeInput.EMULATED_CONTROLLER_TYPE_PRO,
|
||||
NativeInput.EMULATED_CONTROLLER_TYPE_CLASSIC,
|
||||
NativeInput.EMULATED_CONTROLLER_TYPE_WIIMOTE)
|
||||
.map(type -> new ChoiceItem<>(t->t.setText(ControllerTypeResourceNameMapper.controllerTypeToResourceNameId(type)), type))
|
||||
.collect(Collectors.toList());
|
||||
setSelectedValue(NativeLibrary.EMULATED_CONTROLLER_TYPE_DISABLED);
|
||||
setSelectedValue(NativeInput.EMULATED_CONTROLLER_TYPE_DISABLED);
|
||||
}
|
||||
|
||||
public void setControllerTypeCounts(int vpadCount, int wpadCount) {
|
||||
@ -32,11 +32,11 @@ public class EmulatedControllerTypeAdapter extends SelectionAdapter<Integer> {
|
||||
public boolean isEnabled(int position) {
|
||||
int currentControllerType = getItem(selectedPosition);
|
||||
int type = getItem(position);
|
||||
if (type == NativeLibrary.EMULATED_CONTROLLER_TYPE_DISABLED)
|
||||
if (type == NativeInput.EMULATED_CONTROLLER_TYPE_DISABLED)
|
||||
return true;
|
||||
if (type == NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD)
|
||||
return currentControllerType == NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD || vpadCount < NativeLibrary.MAX_VPAD_CONTROLLERS;
|
||||
boolean isWPAD = currentControllerType != NativeLibrary.EMULATED_CONTROLLER_TYPE_VPAD && currentControllerType != NativeLibrary.EMULATED_CONTROLLER_TYPE_DISABLED;
|
||||
return isWPAD || wpadCount < NativeLibrary.MAX_WPAD_CONTROLLERS;
|
||||
if (type == NativeInput.EMULATED_CONTROLLER_TYPE_VPAD)
|
||||
return currentControllerType == NativeInput.EMULATED_CONTROLLER_TYPE_VPAD || vpadCount < NativeInput.MAX_VPAD_CONTROLLERS;
|
||||
boolean isWPAD = currentControllerType != NativeInput.EMULATED_CONTROLLER_TYPE_VPAD && currentControllerType != NativeInput.EMULATED_CONTROLLER_TYPE_DISABLED;
|
||||
return isWPAD || wpadCount < NativeInput.MAX_WPAD_CONTROLLERS;
|
||||
}
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ import info.cemu.Cemu.databinding.GenericRecyclerViewLayoutBinding;
|
||||
import info.cemu.Cemu.guibasecomponents.ButtonRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SimpleButtonRecyclerViewItem;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeInput;
|
||||
|
||||
public class InputSettingsFragment extends Fragment {
|
||||
|
||||
@ -27,9 +27,9 @@ public class InputSettingsFragment extends Fragment {
|
||||
GenericRecyclerViewAdapter genericRecyclerViewAdapter = new GenericRecyclerViewAdapter();
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(new SimpleButtonRecyclerViewItem(getString(R.string.input_overlay_settings), () -> NavHostFragment.findNavController(InputSettingsFragment.this).navigate(R.id.action_inputSettingsFragment_to_inputOverlaySettingsFragment)));
|
||||
|
||||
for (int index = 0; index < NativeLibrary.MAX_CONTROLLERS; index++) {
|
||||
for (int index = 0; index < NativeInput.MAX_CONTROLLERS; index++) {
|
||||
int controllerIndex = index;
|
||||
int controllerType = NativeLibrary.isControllerDisabled(controllerIndex) ? NativeLibrary.EMULATED_CONTROLLER_TYPE_DISABLED : NativeLibrary.getControllerType(controllerIndex);
|
||||
int controllerType = NativeInput.isControllerDisabled(controllerIndex) ? NativeInput.EMULATED_CONTROLLER_TYPE_DISABLED : NativeInput.getControllerType(controllerIndex);
|
||||
String controllerTypeName = getString(ControllerTypeResourceNameMapper.controllerTypeToResourceNameId(controllerType));
|
||||
ButtonRecyclerViewItem buttonRecyclerViewItem = new ButtonRecyclerViewItem(
|
||||
getString(R.string.controller_numbered, controllerIndex + 1),
|
||||
|
@ -18,25 +18,25 @@ import info.cemu.Cemu.guibasecomponents.GenericRecyclerViewAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.HeaderRecyclerViewItem;
|
||||
import info.cemu.Cemu.guibasecomponents.SelectionAdapter;
|
||||
import info.cemu.Cemu.guibasecomponents.SingleSelectionRecyclerViewItem;
|
||||
import info.cemu.Cemu.NativeLibrary;
|
||||
import info.cemu.Cemu.nativeinterface.NativeSettings;
|
||||
|
||||
|
||||
public class OverlaySettingsFragment extends Fragment {
|
||||
private static int overlayScreenPositionToResourceNameId(int overlayScreenPosition) {
|
||||
return switch (overlayScreenPosition) {
|
||||
case NativeLibrary.OVERLAY_SCREEN_POSITION_DISABLED ->
|
||||
case NativeSettings.OVERLAY_SCREEN_POSITION_DISABLED ->
|
||||
R.string.overlay_position_disabled;
|
||||
case NativeLibrary.OVERLAY_SCREEN_POSITION_TOP_LEFT ->
|
||||
case NativeSettings.OVERLAY_SCREEN_POSITION_TOP_LEFT ->
|
||||
R.string.overlay_position_top_left;
|
||||
case NativeLibrary.OVERLAY_SCREEN_POSITION_TOP_CENTER ->
|
||||
case NativeSettings.OVERLAY_SCREEN_POSITION_TOP_CENTER ->
|
||||
R.string.overlay_position_top_center;
|
||||
case NativeLibrary.OVERLAY_SCREEN_POSITION_TOP_RIGHT ->
|
||||
case NativeSettings.OVERLAY_SCREEN_POSITION_TOP_RIGHT ->
|
||||
R.string.overlay_position_top_right;
|
||||
case NativeLibrary.OVERLAY_SCREEN_POSITION_BOTTOM_LEFT ->
|
||||
case NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_LEFT ->
|
||||
R.string.overlay_position_bottom_left;
|
||||
case NativeLibrary.OVERLAY_SCREEN_POSITION_BOTTOM_CENTER ->
|
||||
case NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_CENTER ->
|
||||
R.string.overlay_position_bottom_center;
|
||||
case NativeLibrary.OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT ->
|
||||
case NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT ->
|
||||
R.string.overlay_position_bottom_right;
|
||||
default ->
|
||||
throw new IllegalArgumentException("Invalid overlay position: " + overlayScreenPosition);
|
||||
@ -50,76 +50,76 @@ public class OverlaySettingsFragment extends Fragment {
|
||||
GenericRecyclerViewAdapter genericRecyclerViewAdapter = new GenericRecyclerViewAdapter();
|
||||
|
||||
var overlayPositionChoices = Stream.of(
|
||||
NativeLibrary.OVERLAY_SCREEN_POSITION_DISABLED,
|
||||
NativeLibrary.OVERLAY_SCREEN_POSITION_TOP_LEFT,
|
||||
NativeLibrary.OVERLAY_SCREEN_POSITION_TOP_CENTER,
|
||||
NativeLibrary.OVERLAY_SCREEN_POSITION_TOP_RIGHT,
|
||||
NativeLibrary.OVERLAY_SCREEN_POSITION_BOTTOM_LEFT,
|
||||
NativeLibrary.OVERLAY_SCREEN_POSITION_BOTTOM_CENTER,
|
||||
NativeLibrary.OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT)
|
||||
NativeSettings.OVERLAY_SCREEN_POSITION_DISABLED,
|
||||
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_LEFT,
|
||||
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_CENTER,
|
||||
NativeSettings.OVERLAY_SCREEN_POSITION_TOP_RIGHT,
|
||||
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_LEFT,
|
||||
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_CENTER,
|
||||
NativeSettings.OVERLAY_SCREEN_POSITION_BOTTOM_RIGHT)
|
||||
.map(position -> new SelectionAdapter.ChoiceItem<>(t -> t.setText(overlayScreenPositionToResourceNameId(position)), position))
|
||||
.collect(Collectors.toList());
|
||||
int overlayPosition = NativeLibrary.getOverlayPosition();
|
||||
int overlayPosition = NativeSettings.getOverlayPosition();
|
||||
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(new HeaderRecyclerViewItem(R.string.overlay));
|
||||
SelectionAdapter<Integer> overlayPositionSelectionAdapter = new SelectionAdapter<>(overlayPositionChoices, overlayPosition);
|
||||
SingleSelectionRecyclerViewItem<Integer> overlayPositionSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.overlay_position),
|
||||
getString(overlayScreenPositionToResourceNameId(overlayPosition)), overlayPositionSelectionAdapter,
|
||||
(position, selectionRecyclerViewItem) -> {
|
||||
NativeLibrary.setOverlayPosition(position);
|
||||
NativeSettings.setOverlayPosition(position);
|
||||
selectionRecyclerViewItem.setDescription(getString(overlayScreenPositionToResourceNameId(position)));
|
||||
});
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(overlayPositionSelection);
|
||||
|
||||
CheckboxRecyclerViewItem overlayFps = new CheckboxRecyclerViewItem(getString(R.string.fps),
|
||||
getString(R.string.fps_overlay_description), NativeLibrary.isOverlayFPSEnabled(),
|
||||
NativeLibrary::setOverlayFPSEnabled);
|
||||
getString(R.string.fps_overlay_description), NativeSettings.isOverlayFPSEnabled(),
|
||||
NativeSettings::setOverlayFPSEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(overlayFps);
|
||||
|
||||
CheckboxRecyclerViewItem drawCallsCheckbox = new CheckboxRecyclerViewItem(getString(R.string.draw_calls_per_frame),
|
||||
getString(R.string.draw_calls_per_frame_overlay_description), NativeLibrary.isOverlayDrawCallsPerFrameEnabled(),
|
||||
NativeLibrary::setOverlayDrawCallsPerFrameEnabled);
|
||||
getString(R.string.draw_calls_per_frame_overlay_description), NativeSettings.isOverlayDrawCallsPerFrameEnabled(),
|
||||
NativeSettings::setOverlayDrawCallsPerFrameEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(drawCallsCheckbox);
|
||||
|
||||
CheckboxRecyclerViewItem cpuUsageCheckbox = new CheckboxRecyclerViewItem(getString(R.string.cpu_usage),
|
||||
getString(R.string.cpu_usage_overlay_description), NativeLibrary.isOverlayCPUUsageEnabled(),
|
||||
NativeLibrary::setOverlayCPUUsageEnabled);
|
||||
getString(R.string.cpu_usage_overlay_description), NativeSettings.isOverlayCPUUsageEnabled(),
|
||||
NativeSettings::setOverlayCPUUsageEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(cpuUsageCheckbox);
|
||||
|
||||
CheckboxRecyclerViewItem ramUsageCheckbox = new CheckboxRecyclerViewItem(getString(R.string.ram_usage),
|
||||
getString(R.string.ram_usage_overlay_description), NativeLibrary.isOverlayRAMUsageEnabled(),
|
||||
NativeLibrary::setOverlayRAMUsageEnabled);
|
||||
getString(R.string.ram_usage_overlay_description), NativeSettings.isOverlayRAMUsageEnabled(),
|
||||
NativeSettings::setOverlayRAMUsageEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(ramUsageCheckbox);
|
||||
|
||||
CheckboxRecyclerViewItem debugCheckbox = new CheckboxRecyclerViewItem(getString(R.string.debug),
|
||||
getString(R.string.debug_overlay_description), NativeLibrary.isOverlayDebugEnabled(),
|
||||
NativeLibrary::setOverlayDebugEnabled);
|
||||
getString(R.string.debug_overlay_description), NativeSettings.isOverlayDebugEnabled(),
|
||||
NativeSettings::setOverlayDebugEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(debugCheckbox);
|
||||
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(new HeaderRecyclerViewItem(R.string.notifications));
|
||||
int notificationsPosition = NativeLibrary.getNotificationsPosition();
|
||||
int notificationsPosition = NativeSettings.getNotificationsPosition();
|
||||
SelectionAdapter<Integer> notificationsPositionSelectionAdapter = new SelectionAdapter<>(overlayPositionChoices, notificationsPosition);
|
||||
SingleSelectionRecyclerViewItem<Integer> notificationsPositionSelection = new SingleSelectionRecyclerViewItem<>(getString(R.string.overlay_position),
|
||||
getString(overlayScreenPositionToResourceNameId(notificationsPosition)), notificationsPositionSelectionAdapter,
|
||||
(position, selectionRecyclerViewItem) -> {
|
||||
NativeLibrary.setNotificationsPosition(position);
|
||||
NativeSettings.setNotificationsPosition(position);
|
||||
selectionRecyclerViewItem.setDescription(getString(overlayScreenPositionToResourceNameId(position)));
|
||||
});
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(notificationsPositionSelection);
|
||||
|
||||
CheckboxRecyclerViewItem controllerProfiles = new CheckboxRecyclerViewItem(getString(R.string.controller_profiles),
|
||||
getString(R.string.controller_profiles_notification_description), NativeLibrary.isNotificationControllerProfilesEnabled(),
|
||||
NativeLibrary::setNotificationControllerProfilesEnabled);
|
||||
getString(R.string.controller_profiles_notification_description), NativeSettings.isNotificationControllerProfilesEnabled(),
|
||||
NativeSettings::setNotificationControllerProfilesEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(controllerProfiles);
|
||||
|
||||
CheckboxRecyclerViewItem shaderCompiler = new CheckboxRecyclerViewItem(getString(R.string.shader_compiler),
|
||||
getString(R.string.shader_compiler_notification_description), NativeLibrary.isNotificationShaderCompilerEnabled(),
|
||||
NativeLibrary::setNotificationShaderCompilerEnabled);
|
||||
getString(R.string.shader_compiler_notification_description), NativeSettings.isNotificationShaderCompilerEnabled(),
|
||||
NativeSettings::setNotificationShaderCompilerEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(shaderCompiler);
|
||||
|
||||
CheckboxRecyclerViewItem friendList = new CheckboxRecyclerViewItem(getString(R.string.friend_list),
|
||||
getString(R.string.friend_list_notification_description), NativeLibrary.isNotificationFriendListEnabled(),
|
||||
NativeLibrary::setNotificationFriendListEnabled);
|
||||
getString(R.string.friend_list_notification_description), NativeSettings.isNotificationFriendListEnabled(),
|
||||
NativeSettings::setNotificationFriendListEnabled);
|
||||
genericRecyclerViewAdapter.addRecyclerViewItem(friendList);
|
||||
|
||||
binding.recyclerView.setAdapter(genericRecyclerViewAdapter);
|
||||
|
@ -1,66 +0,0 @@
|
||||
package info.cemu.Cemu.utils;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.ResponseBody;
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ForwardingSource;
|
||||
import okio.Okio;
|
||||
import okio.Source;
|
||||
|
||||
class ProgressResponseBody extends ResponseBody {
|
||||
|
||||
private final ResponseBody responseBody;
|
||||
private final ProgressListener progressListener;
|
||||
private BufferedSource bufferedSource;
|
||||
|
||||
ProgressResponseBody(ResponseBody responseBody, ProgressListener progressListener) {
|
||||
this.responseBody = responseBody;
|
||||
this.progressListener = progressListener;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MediaType contentType() {
|
||||
return responseBody.contentType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long contentLength() {
|
||||
return responseBody.contentLength();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public BufferedSource source() {
|
||||
if (bufferedSource == null) {
|
||||
bufferedSource = Okio.buffer(source(responseBody.source()));
|
||||
}
|
||||
return bufferedSource;
|
||||
}
|
||||
|
||||
private Source source(Source source) {
|
||||
return new ForwardingSource(source) {
|
||||
long totalBytesRead = 0L;
|
||||
|
||||
@Override
|
||||
public long read(@NonNull Buffer sink, long byteCount) throws IOException {
|
||||
long bytesRead = super.read(sink, byteCount);
|
||||
sink.flush();
|
||||
if (bytesRead == -1)
|
||||
return 100;
|
||||
totalBytesRead += bytesRead;
|
||||
progressListener.update((int) (100f * totalBytesRead / responseBody.contentLength()));
|
||||
return bytesRead;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public interface ProgressListener {
|
||||
void update(int progress);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package info.cemu.Cemu.utils;
|
||||
package info.cemu.Cemu.zip;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
@ -8,7 +8,7 @@ import java.nio.file.Paths;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipInputStream;
|
||||
|
||||
public class ZipUtil {
|
||||
public class Zip {
|
||||
|
||||
public static void unzip(InputStream stream, String targetDir) throws IOException {
|
||||
try (ZipInputStream zipInputStream = new ZipInputStream(stream)) {
|
||||
@ -34,7 +34,7 @@ public class ZipUtil {
|
||||
private static void createDir(String dir) {
|
||||
File f = new File(dir);
|
||||
if (!f.isDirectory()) {
|
||||
f.mkdirs();
|
||||
var ignored = f.mkdirs();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package info.cemu.Cemu;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
@ -17,7 +17,7 @@
|
||||
#include "input/api/GameCube/GameCubeControllerProvider.h"
|
||||
|
||||
#if __ANDROID__
|
||||
#include "input/api/Android//AndroidControllerProvider.h"
|
||||
#include "input/api/Android/AndroidControllerProvider.h"
|
||||
#endif
|
||||
|
||||
#include "input/emulated/VPADController.h"
|
||||
|
Loading…
Reference in New Issue
Block a user