Android: Add support for custom textures and texture dumping (#6144)
* Android: add app UI settings for custom textures and texture dumping. * Android: Bring lodepng_image_interface into jni directory, include it, and add lodepng to CMAKE for linker (Android version doesn't use the src/citra folder) * Android: Add custom texture and texture dumping config.ini settings * Register image interface line added. * Update src/android/app/src/main/res/values/strings.xml Co-authored-by: SachinVin <26602104+SachinVin@users.noreply.github.com> * Update src/android/app/src/main/jni/lodepng_image_interface.cpp Whoops Co-authored-by: SachinVin <26602104+SachinVin@users.noreply.github.com> * clang-format attempt #1 Co-authored-by: SachinVin <26602104+SachinVin@users.noreply.github.com>
This commit is contained in:
parent
a427a80446
commit
2c40b2aa72
10 changed files with 92 additions and 4 deletions
|
@ -21,6 +21,7 @@ public class Settings {
|
|||
public static final String SECTION_CONTROLS = "Controls";
|
||||
public static final String SECTION_RENDERER = "Renderer";
|
||||
public static final String SECTION_LAYOUT = "Layout";
|
||||
public static final String SECTION_UTILITY = "Utility";
|
||||
public static final String SECTION_AUDIO = "Audio";
|
||||
public static final String SECTION_DEBUG = "Debug";
|
||||
|
||||
|
@ -29,7 +30,7 @@ public class Settings {
|
|||
private static final Map<String, List<String>> configFileSectionsMap = new HashMap<>();
|
||||
|
||||
static {
|
||||
configFileSectionsMap.put(SettingsFile.FILE_NAME_CONFIG, Arrays.asList(SECTION_PREMIUM, SECTION_CORE, SECTION_SYSTEM, SECTION_CAMERA, SECTION_CONTROLS, SECTION_RENDERER, SECTION_LAYOUT, SECTION_AUDIO, SECTION_DEBUG));
|
||||
configFileSectionsMap.put(SettingsFile.FILE_NAME_CONFIG, Arrays.asList(SECTION_PREMIUM, SECTION_CORE, SECTION_SYSTEM, SECTION_CAMERA, SECTION_CONTROLS, SECTION_RENDERER, SECTION_LAYOUT, SECTION_UTILITY, SECTION_AUDIO, SECTION_DEBUG));
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -357,11 +357,14 @@ public final class SettingsFragmentPresenter {
|
|||
Setting render3dMode = rendererSection.getSetting(SettingsFile.KEY_RENDER_3D);
|
||||
Setting factor3d = rendererSection.getSetting(SettingsFile.KEY_FACTOR_3D);
|
||||
Setting useDiskShaderCache = rendererSection.getSetting(SettingsFile.KEY_USE_DISK_SHADER_CACHE);
|
||||
|
||||
SettingSection layoutSection = mSettings.getSection(Settings.SECTION_LAYOUT);
|
||||
Setting cardboardScreenSize = layoutSection.getSetting(SettingsFile.KEY_CARDBOARD_SCREEN_SIZE);
|
||||
Setting cardboardXShift = layoutSection.getSetting(SettingsFile.KEY_CARDBOARD_X_SHIFT);
|
||||
Setting cardboardYShift = layoutSection.getSetting(SettingsFile.KEY_CARDBOARD_Y_SHIFT);
|
||||
SettingSection utilitySection = mSettings.getSection(Settings.SECTION_UTILITY);
|
||||
Setting dumpTextures = utilitySection.getSetting(SettingsFile.KEY_DUMP_TEXTURES);
|
||||
Setting customTextures = utilitySection.getSetting(SettingsFile.KEY_CUSTOM_TEXTURES);
|
||||
//Setting preloadTextures = utilitySection.getSetting(SettingsFile.KEY_PRELOAD_TEXTURES);
|
||||
|
||||
sl.add(new HeaderSetting(null, null, R.string.renderer, 0));
|
||||
sl.add(new SliderSetting(SettingsFile.KEY_RESOLUTION_FACTOR, Settings.SECTION_RENDERER, R.string.internal_resolution, R.string.internal_resolution_description, 1, 4, "x", 1, resolutionFactor));
|
||||
|
@ -377,6 +380,12 @@ public final class SettingsFragmentPresenter {
|
|||
sl.add(new SliderSetting(SettingsFile.KEY_CARDBOARD_SCREEN_SIZE, Settings.SECTION_LAYOUT, R.string.cardboard_screen_size, R.string.cardboard_screen_size_description, 30, 100, "%", 85, cardboardScreenSize));
|
||||
sl.add(new SliderSetting(SettingsFile.KEY_CARDBOARD_X_SHIFT, Settings.SECTION_LAYOUT, R.string.cardboard_x_shift, R.string.cardboard_x_shift_description, -100, 100, "%", 0, cardboardXShift));
|
||||
sl.add(new SliderSetting(SettingsFile.KEY_CARDBOARD_Y_SHIFT, Settings.SECTION_LAYOUT, R.string.cardboard_y_shift, R.string.cardboard_y_shift_description, -100, 100, "%", 0, cardboardYShift));
|
||||
|
||||
sl.add(new HeaderSetting(null, null, R.string.utility, 0));
|
||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_DUMP_TEXTURES, Settings.SECTION_UTILITY, R.string.dump_textures, R.string.dump_textures_description, false, dumpTextures));
|
||||
sl.add(new CheckBoxSetting(SettingsFile.KEY_CUSTOM_TEXTURES, Settings.SECTION_UTILITY, R.string.custom_textures, R.string.custom_textures_description, false, customTextures));
|
||||
//Disabled until custom texture implementation gets rewrite, current one overloads RAM and crashes Citra.
|
||||
//sl.add(new CheckBoxSetting(SettingsFile.KEY_PRELOAD_TEXTURES, Settings.SECTION_UTILITY, R.string.preload_textures, R.string.preload_textures_description, false, preloadTextures));
|
||||
}
|
||||
|
||||
private void addAudioSettings(ArrayList<SettingsItem> sl) {
|
||||
|
|
|
@ -64,6 +64,10 @@ public final class SettingsFile {
|
|||
public static final String KEY_CARDBOARD_X_SHIFT = "cardboard_x_shift";
|
||||
public static final String KEY_CARDBOARD_Y_SHIFT = "cardboard_y_shift";
|
||||
|
||||
public static final String KEY_DUMP_TEXTURES = "dump_textures";
|
||||
public static final String KEY_CUSTOM_TEXTURES = "custom_textures";
|
||||
public static final String KEY_PRELOAD_TEXTURES = "preload_textures";
|
||||
|
||||
public static final String KEY_AUDIO_OUTPUT_ENGINE = "output_engine";
|
||||
public static final String KEY_ENABLE_AUDIO_STRETCHING = "enable_audio_stretching";
|
||||
public static final String KEY_VOLUME = "volume";
|
||||
|
|
|
@ -25,6 +25,8 @@ add_library(citra-android SHARED
|
|||
game_settings.h
|
||||
id_cache.cpp
|
||||
id_cache.h
|
||||
lodepng_image_interface.cpp
|
||||
lodepng_image_interface.h
|
||||
mic.cpp
|
||||
mic.h
|
||||
native.cpp
|
||||
|
@ -34,6 +36,6 @@ add_library(citra-android SHARED
|
|||
)
|
||||
|
||||
target_link_libraries(citra-android PRIVATE audio_core common core input_common network)
|
||||
target_link_libraries(citra-android PRIVATE android camera2ndk EGL glad inih jnigraphics log mediandk yuv)
|
||||
target_link_libraries(citra-android PRIVATE android camera2ndk EGL glad inih jnigraphics lodepng log mediandk yuv)
|
||||
|
||||
set(CPACK_PACKAGE_EXECUTABLES ${CPACK_PACKAGE_EXECUTABLES} citra-android)
|
||||
|
|
|
@ -179,6 +179,12 @@ void Config::ReadValues() {
|
|||
Settings::values.cardboard_y_shift =
|
||||
static_cast<int>(sdl2_config->GetInteger("Layout", "cardboard_y_shift", 0));
|
||||
|
||||
// Utility
|
||||
Settings::values.dump_textures = sdl2_config->GetBoolean("Utility", "dump_textures", false);
|
||||
Settings::values.custom_textures = sdl2_config->GetBoolean("Utility", "custom_textures", false);
|
||||
Settings::values.preload_textures =
|
||||
sdl2_config->GetBoolean("Utility", "preload_textures", false);
|
||||
|
||||
// Audio
|
||||
Settings::values.enable_dsp_lle = sdl2_config->GetBoolean("Audio", "enable_dsp_lle", false);
|
||||
Settings::values.enable_dsp_lle_multithread =
|
||||
|
|
|
@ -209,6 +209,19 @@ cardboard_x_shift =
|
|||
# -100 - 100: Screen Y-Coordinate shift as a percentage of empty space. 0 (default)
|
||||
cardboard_y_shift =
|
||||
|
||||
[Utility]
|
||||
# Dumps textures as PNG to dump/textures/[Title ID]/.
|
||||
# 0 (default): Off, 1: On
|
||||
dump_textures =
|
||||
|
||||
# Reads PNG files from load/textures/[Title ID]/ and replaces textures.
|
||||
# 0 (default): Off, 1: On
|
||||
custom_textures =
|
||||
|
||||
# Loads all custom textures into memory before booting.
|
||||
# 0 (default): Off, 1: On
|
||||
preload_textures =
|
||||
|
||||
[Audio]
|
||||
# Whether or not to enable DSP LLE
|
||||
# 0 (default): No, 1: Yes
|
||||
|
|
29
src/android/app/src/main/jni/lodepng_image_interface.cpp
Normal file
29
src/android/app/src/main/jni/lodepng_image_interface.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2019 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <lodepng.h>
|
||||
#include "common/logging/log.h"
|
||||
#include "jni/lodepng_image_interface.h"
|
||||
|
||||
bool LodePNGImageInterface::DecodePNG(std::vector<u8>& dst, u32& width, u32& height,
|
||||
const std::string& path) {
|
||||
u32 lodepng_ret = lodepng::decode(dst, width, height, path);
|
||||
if (lodepng_ret) {
|
||||
LOG_CRITICAL(Frontend, "Failed to decode {} because {}", path,
|
||||
lodepng_error_text(lodepng_ret));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool LodePNGImageInterface::EncodePNG(const std::string& path, const std::vector<u8>& src,
|
||||
u32 width, u32 height) {
|
||||
u32 lodepng_ret = lodepng::encode(path, src, width, height);
|
||||
if (lodepng_ret) {
|
||||
LOG_CRITICAL(Frontend, "Failed to encode {} because {}", path,
|
||||
lodepng_error_text(lodepng_ret));
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
14
src/android/app/src/main/jni/lodepng_image_interface.h
Normal file
14
src/android/app/src/main/jni/lodepng_image_interface.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
// Copyright 2019 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/frontend/image_interface.h"
|
||||
|
||||
class LodePNGImageInterface final : public Frontend::ImageInterface {
|
||||
public:
|
||||
bool DecodePNG(std::vector<u8>& dst, u32& width, u32& height, const std::string& path) override;
|
||||
bool EncodePNG(const std::string& path, const std::vector<u8>& src, u32 width,
|
||||
u32 height) override;
|
||||
};
|
|
@ -38,6 +38,7 @@
|
|||
#include "jni/game_settings.h"
|
||||
#include "jni/id_cache.h"
|
||||
#include "jni/input_manager.h"
|
||||
#include "jni/lodepng_image_interface.h"
|
||||
#include "jni/mic.h"
|
||||
#include "jni/native.h"
|
||||
#include "jni/ndk_motion.h"
|
||||
|
@ -174,6 +175,9 @@ static Core::System::ResultStatus RunCitra(const std::string& filepath) {
|
|||
system.RegisterMiiSelector(std::make_shared<MiiSelector::AndroidMiiSelector>());
|
||||
system.RegisterSoftwareKeyboard(std::make_shared<SoftwareKeyboard::AndroidKeyboard>());
|
||||
|
||||
// Register generic image interface
|
||||
Core::System::GetInstance().RegisterImageInterface(std::make_shared<LodePNGImageInterface>());
|
||||
|
||||
// Register real Mic factory
|
||||
Frontend::Mic::RegisterRealMicFactory(std::make_unique<Mic::AndroidFactory>());
|
||||
|
||||
|
|
|
@ -103,7 +103,13 @@
|
|||
<string name="use_shader_jit">Use shader JIT</string>
|
||||
<string name="use_disk_shader_cache">Use disk shader cache</string>
|
||||
<string name="use_disk_shader_cache_description">Reduce stuttering by storing and loading generated shaders to disk. It cannot be used without Enabling Hardware Shader.</string>
|
||||
|
||||
<string name="utility">Utility</string>
|
||||
<string name="dump_textures">Dump textures</string>
|
||||
<string name="dump_textures_description">Dumps textures to dump/textures/[GAME ID]</string>
|
||||
<string name="custom_textures">Use custom textures</string>
|
||||
<string name="custom_textures_description">Uses custom textures found in load/textures/[GAME ID]</string>
|
||||
<string name="preload_textures">Preload custom textures</string>
|
||||
<string name="preload_textures_description">Loads all custom textures into memory. This feature can use a lot of memory.</string>
|
||||
<!-- Premium strings -->
|
||||
<string name="premium_text">Premium</string>
|
||||
<string name="premium_settings_upsell">Upgrade to Premium and support Citra!</string>
|
||||
|
|
Loading…
Reference in a new issue