增加自定义画质设置
This commit is contained in:
parent
acac544183
commit
53cb596845
@ -433,6 +433,48 @@ namespace GakumasLocal::HookMain {
|
|||||||
return VLDOF_IsActive_Orig(_this);
|
return VLDOF_IsActive_Orig(_this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFINE_HOOK(void, CampusQualityManager_set_TargetFrameRate, (void* _this, float value)) {
|
||||||
|
// Log::InfoFmt("CampusQualityManager_set_TargetFrameRate: %f", value);
|
||||||
|
const auto configFps = Config::targetFrameRate;
|
||||||
|
CampusQualityManager_set_TargetFrameRate_Orig(_this, configFps == 0 ? value : (float)configFps);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFINE_HOOK(void, CampusQualityManager_ApplySetting, (void* _this, int qualitySettingsLevel, int maxBufferPixel, float renderScale, int volumeIndex)) {
|
||||||
|
if (Config::targetFrameRate != 0) {
|
||||||
|
CampusQualityManager_set_TargetFrameRate_Orig(_this, Config::targetFrameRate);
|
||||||
|
}
|
||||||
|
if (Config::useCustomeGraphicSettings) {
|
||||||
|
static auto SetReflectionQuality = Il2cppUtils::GetMethod("campus-submodule.Runtime.dll", "Campus.Common",
|
||||||
|
"CampusQualityManager", "SetReflectionQuality");
|
||||||
|
static auto SetLODQuality = Il2cppUtils::GetMethod("campus-submodule.Runtime.dll", "Campus.Common",
|
||||||
|
"CampusQualityManager", "SetLODQuality");
|
||||||
|
|
||||||
|
static auto Enum_GetValues = Il2cppUtils::GetMethod("mscorlib.dll", "System", "Enum", "GetValues");
|
||||||
|
|
||||||
|
static auto QualityLevel_klass = Il2cppUtils::GetClass("campus-submodule.Runtime.dll", "", "QualityLevel");
|
||||||
|
|
||||||
|
static auto values = Enum_GetValues->Invoke<UnityResolve::UnityType::Array<int>*>(QualityLevel_klass->GetType())->ToVector();
|
||||||
|
if (values.empty()) {
|
||||||
|
values = {0x0, 0xa, 0x14, 0x1e, 0x28, 0x64};
|
||||||
|
}
|
||||||
|
if (Config::lodQualityLevel >= values.size()) Config::lodQualityLevel = values.size() - 1;
|
||||||
|
if (Config::reflectionQualityLevel >= values.size()) Config::reflectionQualityLevel = values.size() - 1;
|
||||||
|
|
||||||
|
SetLODQuality->Invoke<void>(_this, values[Config::lodQualityLevel]);
|
||||||
|
SetReflectionQuality->Invoke<void>(_this, values[Config::reflectionQualityLevel]);
|
||||||
|
|
||||||
|
qualitySettingsLevel = Config::qualitySettingsLevel;
|
||||||
|
maxBufferPixel = Config::maxBufferPixel;
|
||||||
|
renderScale = Config::renderScale;
|
||||||
|
volumeIndex = Config::volumeIndex;
|
||||||
|
|
||||||
|
Log::ShowToastFmt("ApplySetting\nqualityLevel: %d, maxBufferPixel: %d\nenderScale: %f, volumeIndex: %d\nLODQualityLv: %d, ReflectionLv: %d",
|
||||||
|
qualitySettingsLevel, maxBufferPixel, renderScale, volumeIndex, Config::lodQualityLevel, Config::reflectionQualityLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
CampusQualityManager_ApplySetting_Orig(_this, qualitySettingsLevel, maxBufferPixel, renderScale, volumeIndex);
|
||||||
|
}
|
||||||
|
|
||||||
void StartInjectFunctions() {
|
void StartInjectFunctions() {
|
||||||
const auto hookInstaller = Plugin::GetInstance().GetHookInstaller();
|
const auto hookInstaller = Plugin::GetInstance().GetHookInstaller();
|
||||||
UnityResolve::Init(xdl_open(hookInstaller->m_il2cppLibraryPath.c_str(), RTLD_NOW), UnityResolve::Mode::Il2Cpp);
|
UnityResolve::Init(xdl_open(hookInstaller->m_il2cppLibraryPath.c_str(), RTLD_NOW), UnityResolve::Mode::Il2Cpp);
|
||||||
@ -488,6 +530,14 @@ namespace GakumasLocal::HookMain {
|
|||||||
Il2cppUtils::GetMethodPointer("Unity.RenderPipelines.Universal.Runtime.dll", "VL.Rendering",
|
Il2cppUtils::GetMethodPointer("Unity.RenderPipelines.Universal.Runtime.dll", "VL.Rendering",
|
||||||
"VLDOF", "IsActive"));
|
"VLDOF", "IsActive"));
|
||||||
|
|
||||||
|
ADD_HOOK(CampusQualityManager_ApplySetting,
|
||||||
|
Il2cppUtils::GetMethodPointer("campus-submodule.Runtime.dll", "Campus.Common",
|
||||||
|
"CampusQualityManager", "ApplySetting"));
|
||||||
|
|
||||||
|
ADD_HOOK(CampusQualityManager_set_TargetFrameRate,
|
||||||
|
Il2cppUtils::GetMethodPointer("campus-submodule.Runtime.dll", "Campus.Common",
|
||||||
|
"CampusQualityManager", "set_TargetFrameRate"));
|
||||||
|
|
||||||
ADD_HOOK(Internal_LogException, Il2cppUtils::il2cpp_resolve_icall(
|
ADD_HOOK(Internal_LogException, Il2cppUtils::il2cpp_resolve_icall(
|
||||||
"UnityEngine.DebugLogHandler::Internal_LogException(System.Exception,UnityEngine.Object)"));
|
"UnityEngine.DebugLogHandler::Internal_LogException(System.Exception,UnityEngine.Object)"));
|
||||||
ADD_HOOK(Internal_Log, Il2cppUtils::il2cpp_resolve_icall(
|
ADD_HOOK(Internal_Log, Il2cppUtils::il2cpp_resolve_icall(
|
||||||
|
@ -1,30 +1,26 @@
|
|||||||
#include "Log.h"
|
#include "Log.h"
|
||||||
#include <android/log.h>
|
#include <android/log.h>
|
||||||
|
#include <Misc.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
std::string format(const char* fmt, ...) {
|
extern JavaVM* g_javaVM;
|
||||||
va_list args;
|
extern jclass g_gakumasHookMainClass;
|
||||||
va_start(args, fmt);
|
extern jmethodID showToastMethodId;
|
||||||
va_list args_copy;
|
|
||||||
va_copy(args_copy, args);
|
|
||||||
|
|
||||||
// 计算格式化后的字符串长度
|
#define GetParamStringResult(name)\
|
||||||
int size = vsnprintf(nullptr, 0, fmt, args_copy) + 1; // 加上额外的终止符空间
|
va_list args;\
|
||||||
va_end(args_copy);
|
va_start(args, fmt);\
|
||||||
|
va_list args_copy;\
|
||||||
// 动态分配缓冲区
|
va_copy(args_copy, args);\
|
||||||
char* buffer = new char[size];
|
int size = vsnprintf(nullptr, 0, fmt, args_copy) + 1;\
|
||||||
|
va_end(args_copy);\
|
||||||
// 格式化字符串
|
char* buffer = new char[size];\
|
||||||
vsnprintf(buffer, size, fmt, args);
|
vsnprintf(buffer, size, fmt, args);\
|
||||||
|
va_end(args);\
|
||||||
va_end(args);
|
std::string name(buffer);\
|
||||||
|
delete[] buffer
|
||||||
std::string result(buffer);
|
|
||||||
delete[] buffer; // 释放缓冲区
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
namespace GakumasLocal::Log {
|
namespace GakumasLocal::Log {
|
||||||
@ -33,26 +29,7 @@ namespace GakumasLocal::Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LogFmt(int prio, const char* fmt, ...) {
|
void LogFmt(int prio, const char* fmt, ...) {
|
||||||
va_list args;
|
GetParamStringResult(result);
|
||||||
va_start(args, fmt);
|
|
||||||
va_list args_copy;
|
|
||||||
va_copy(args_copy, args);
|
|
||||||
|
|
||||||
// 计算格式化后的字符串长度
|
|
||||||
int size = vsnprintf(nullptr, 0, fmt, args_copy) + 1; // 加上额外的终止符空间
|
|
||||||
va_end(args_copy);
|
|
||||||
|
|
||||||
// 动态分配缓冲区
|
|
||||||
char* buffer = new char[size];
|
|
||||||
|
|
||||||
// 格式化字符串
|
|
||||||
vsnprintf(buffer, size, fmt, args);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
std::string result(buffer);
|
|
||||||
delete[] buffer; // 释放缓冲区
|
|
||||||
|
|
||||||
Log(prio, result.c_str());
|
Log(prio, result.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,26 +38,7 @@ namespace GakumasLocal::Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void InfoFmt(const char* fmt, ...) {
|
void InfoFmt(const char* fmt, ...) {
|
||||||
va_list args;
|
GetParamStringResult(result);
|
||||||
va_start(args, fmt);
|
|
||||||
va_list args_copy;
|
|
||||||
va_copy(args_copy, args);
|
|
||||||
|
|
||||||
// 计算格式化后的字符串长度
|
|
||||||
int size = vsnprintf(nullptr, 0, fmt, args_copy) + 1; // 加上额外的终止符空间
|
|
||||||
va_end(args_copy);
|
|
||||||
|
|
||||||
// 动态分配缓冲区
|
|
||||||
char* buffer = new char[size];
|
|
||||||
|
|
||||||
// 格式化字符串
|
|
||||||
vsnprintf(buffer, size, fmt, args);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
std::string result(buffer);
|
|
||||||
delete[] buffer; // 释放缓冲区
|
|
||||||
|
|
||||||
Info(result.c_str());
|
Info(result.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,26 +47,7 @@ namespace GakumasLocal::Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ErrorFmt(const char* fmt, ...) {
|
void ErrorFmt(const char* fmt, ...) {
|
||||||
va_list args;
|
GetParamStringResult(result);
|
||||||
va_start(args, fmt);
|
|
||||||
va_list args_copy;
|
|
||||||
va_copy(args_copy, args);
|
|
||||||
|
|
||||||
// 计算格式化后的字符串长度
|
|
||||||
int size = vsnprintf(nullptr, 0, fmt, args_copy) + 1; // 加上额外的终止符空间
|
|
||||||
va_end(args_copy);
|
|
||||||
|
|
||||||
// 动态分配缓冲区
|
|
||||||
char* buffer = new char[size];
|
|
||||||
|
|
||||||
// 格式化字符串
|
|
||||||
vsnprintf(buffer, size, fmt, args);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
std::string result(buffer);
|
|
||||||
delete[] buffer; // 释放缓冲区
|
|
||||||
|
|
||||||
Error(result.c_str());
|
Error(result.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,50 +56,44 @@ namespace GakumasLocal::Log {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void DebugFmt(const char* fmt, ...) {
|
void DebugFmt(const char* fmt, ...) {
|
||||||
va_list args;
|
GetParamStringResult(result);
|
||||||
va_start(args, fmt);
|
|
||||||
va_list args_copy;
|
|
||||||
va_copy(args_copy, args);
|
|
||||||
|
|
||||||
// 计算格式化后的字符串长度
|
|
||||||
int size = vsnprintf(nullptr, 0, fmt, args_copy) + 1; // 加上额外的终止符空间
|
|
||||||
va_end(args_copy);
|
|
||||||
|
|
||||||
// 动态分配缓冲区
|
|
||||||
char* buffer = new char[size];
|
|
||||||
|
|
||||||
// 格式化字符串
|
|
||||||
vsnprintf(buffer, size, fmt, args);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
std::string result(buffer);
|
|
||||||
delete[] buffer; // 释放缓冲区
|
|
||||||
|
|
||||||
Debug(result.c_str());
|
Debug(result.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void LogUnityLog(int prio, const char* fmt, ...) {
|
void LogUnityLog(int prio, const char* fmt, ...) {
|
||||||
va_list args;
|
GetParamStringResult(result);
|
||||||
va_start(args, fmt);
|
|
||||||
va_list args_copy;
|
|
||||||
va_copy(args_copy, args);
|
|
||||||
|
|
||||||
// 计算格式化后的字符串长度
|
|
||||||
int size = vsnprintf(nullptr, 0, fmt, args_copy) + 1; // 加上额外的终止符空间
|
|
||||||
va_end(args_copy);
|
|
||||||
|
|
||||||
// 动态分配缓冲区
|
|
||||||
char* buffer = new char[size];
|
|
||||||
|
|
||||||
// 格式化字符串
|
|
||||||
vsnprintf(buffer, size, fmt, args);
|
|
||||||
|
|
||||||
va_end(args);
|
|
||||||
|
|
||||||
std::string result(buffer);
|
|
||||||
delete[] buffer; // 释放缓冲区
|
|
||||||
|
|
||||||
__android_log_write(prio, "GakumasLog", result.c_str());
|
__android_log_write(prio, "GakumasLog", result.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShowToast(const std::string& text) {
|
||||||
|
DebugFmt("Toast: %s", text.c_str());
|
||||||
|
|
||||||
|
std::thread([text](){
|
||||||
|
auto env = Misc::GetJNIEnv();
|
||||||
|
if (!env) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
g_javaVM->AttachCurrentThread(&env, nullptr);
|
||||||
|
|
||||||
|
jclass& kotlinClass = g_gakumasHookMainClass;
|
||||||
|
if (!kotlinClass) {
|
||||||
|
g_javaVM->DetachCurrentThread();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
jmethodID& methodId = showToastMethodId;
|
||||||
|
if (!methodId) {
|
||||||
|
g_javaVM->DetachCurrentThread();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
jstring param = env->NewStringUTF(text.c_str());
|
||||||
|
env->CallStaticVoidMethod(kotlinClass, methodId, param);
|
||||||
|
|
||||||
|
g_javaVM->DetachCurrentThread();
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShowToastFmt(const char* fmt, ...) {
|
||||||
|
GetParamStringResult(result);
|
||||||
|
ShowToast(result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@ namespace GakumasLocal::Log {
|
|||||||
void ErrorFmt(const char* fmt, ...);
|
void ErrorFmt(const char* fmt, ...);
|
||||||
void Debug(const char* msg);
|
void Debug(const char* msg);
|
||||||
void DebugFmt(const char* fmt, ...);
|
void DebugFmt(const char* fmt, ...);
|
||||||
|
|
||||||
|
void ShowToast(const char* text);
|
||||||
|
void ShowToastFmt(const char* fmt, ...);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //GAKUMAS_LOCALIFY_LOG_H
|
#endif //GAKUMAS_LOCALIFY_LOG_H
|
||||||
|
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
|
|
||||||
|
extern JavaVM* g_javaVM;
|
||||||
|
|
||||||
|
|
||||||
namespace GakumasLocal::Misc {
|
namespace GakumasLocal::Misc {
|
||||||
@ -14,4 +18,17 @@ namespace GakumasLocal::Misc {
|
|||||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
|
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> utf16conv;
|
||||||
return utf16conv.to_bytes(str.data(), str.data() + str.size());
|
return utf16conv.to_bytes(str.data(), str.data() + str.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEnv* GetJNIEnv() {
|
||||||
|
if (!g_javaVM) return nullptr;
|
||||||
|
JNIEnv* env = nullptr;
|
||||||
|
if (g_javaVM->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
|
||||||
|
int status = g_javaVM->AttachCurrentThread(&env, nullptr);
|
||||||
|
if (status < 0) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return env;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace UmaPyogin::Misc
|
} // namespace UmaPyogin::Misc
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
namespace GakumasLocal {
|
namespace GakumasLocal {
|
||||||
using OpaqueFunctionPointer = void (*)();
|
using OpaqueFunctionPointer = void (*)();
|
||||||
@ -10,6 +11,7 @@ namespace GakumasLocal {
|
|||||||
namespace Misc {
|
namespace Misc {
|
||||||
std::u16string ToUTF16(const std::string_view& str);
|
std::u16string ToUTF16(const std::string_view& str);
|
||||||
std::string ToUTF8(const std::u16string_view& str);
|
std::string ToUTF8(const std::u16string_view& str);
|
||||||
|
JNIEnv* GetJNIEnv();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Misc.h"
|
#include "Misc.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <jni.h>
|
||||||
|
|
||||||
namespace GakumasLocal {
|
namespace GakumasLocal {
|
||||||
struct HookInstaller
|
struct HookInstaller
|
||||||
|
@ -14,6 +14,14 @@ namespace GakumasLocal::Config {
|
|||||||
std::string liveCustomeHeadId = "";
|
std::string liveCustomeHeadId = "";
|
||||||
std::string liveCustomeCostumeId = "";
|
std::string liveCustomeCostumeId = "";
|
||||||
|
|
||||||
|
bool useCustomeGraphicSettings = false;
|
||||||
|
float renderScale = 0.77f;
|
||||||
|
int qualitySettingsLevel = 3;
|
||||||
|
int volumeIndex = 3;
|
||||||
|
int maxBufferPixel = 3384;
|
||||||
|
int reflectionQualityLevel = 4;
|
||||||
|
int lodQualityLevel = 4;
|
||||||
|
|
||||||
void LoadConfig(const std::string& configStr) {
|
void LoadConfig(const std::string& configStr) {
|
||||||
try {
|
try {
|
||||||
const auto config = nlohmann::json::parse(configStr);
|
const auto config = nlohmann::json::parse(configStr);
|
||||||
@ -27,6 +35,13 @@ namespace GakumasLocal::Config {
|
|||||||
GetConfigItem(enableLiveCustomeDress);
|
GetConfigItem(enableLiveCustomeDress);
|
||||||
GetConfigItem(liveCustomeHeadId);
|
GetConfigItem(liveCustomeHeadId);
|
||||||
GetConfigItem(liveCustomeCostumeId);
|
GetConfigItem(liveCustomeCostumeId);
|
||||||
|
GetConfigItem(useCustomeGraphicSettings);
|
||||||
|
GetConfigItem(renderScale);
|
||||||
|
GetConfigItem(qualitySettingsLevel);
|
||||||
|
GetConfigItem(volumeIndex);
|
||||||
|
GetConfigItem(maxBufferPixel);
|
||||||
|
GetConfigItem(reflectionQualityLevel);
|
||||||
|
GetConfigItem(lodQualityLevel);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
|
@ -14,6 +14,15 @@ namespace GakumasLocal::Config {
|
|||||||
extern std::string liveCustomeHeadId;
|
extern std::string liveCustomeHeadId;
|
||||||
extern std::string liveCustomeCostumeId;
|
extern std::string liveCustomeCostumeId;
|
||||||
|
|
||||||
|
extern bool useCustomeGraphicSettings;
|
||||||
|
extern float renderScale;
|
||||||
|
extern int qualitySettingsLevel;
|
||||||
|
extern int volumeIndex;
|
||||||
|
extern int maxBufferPixel;
|
||||||
|
|
||||||
|
extern int reflectionQualityLevel;
|
||||||
|
extern int lodQualityLevel;
|
||||||
|
|
||||||
void LoadConfig(const std::string& configStr);
|
void LoadConfig(const std::string& configStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,6 +9,10 @@
|
|||||||
#include "GakumasLocalify/camera/camera.hpp"
|
#include "GakumasLocalify/camera/camera.hpp"
|
||||||
#include "GakumasLocalify/config/Config.hpp"
|
#include "GakumasLocalify/config/Config.hpp"
|
||||||
|
|
||||||
|
JavaVM* g_javaVM = nullptr;
|
||||||
|
jclass g_gakumasHookMainClass = nullptr;
|
||||||
|
jmethodID showToastMethodId = nullptr;
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class AndroidHookInstaller : public GakumasLocal::HookInstaller
|
class AndroidHookInstaller : public GakumasLocal::HookInstaller
|
||||||
@ -40,11 +44,20 @@ namespace
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
JNI_OnLoad(JavaVM* vm, void* reserved) {
|
||||||
|
g_javaVM = vm;
|
||||||
|
return JNI_VERSION_1_6;
|
||||||
|
}
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
JNIEXPORT void JNICALL
|
JNIEXPORT void JNICALL
|
||||||
Java_io_github_chinosk_gakumas_localify_GakumasHookMain_initHook(JNIEnv *env, jclass clazz, jstring targetLibraryPath,
|
Java_io_github_chinosk_gakumas_localify_GakumasHookMain_initHook(JNIEnv *env, jclass clazz, jstring targetLibraryPath,
|
||||||
jstring localizationFilesDir) {
|
jstring localizationFilesDir) {
|
||||||
|
g_gakumasHookMainClass = clazz;
|
||||||
|
showToastMethodId = env->GetStaticMethodID(clazz, "showToast", "(Ljava/lang/String;)V");
|
||||||
|
|
||||||
const auto targetLibraryPathChars = env->GetStringUTFChars(targetLibraryPath, nullptr);
|
const auto targetLibraryPathChars = env->GetStringUTFChars(targetLibraryPath, nullptr);
|
||||||
const std::string targetLibraryPathStr = targetLibraryPathChars;
|
const std::string targetLibraryPathStr = targetLibraryPathChars;
|
||||||
|
|
||||||
|
@ -22,12 +22,12 @@ import android.widget.Toast
|
|||||||
import de.robv.android.xposed.XposedBridge
|
import de.robv.android.xposed.XposedBridge
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
|
val TAG = "GakumasLocalify"
|
||||||
|
|
||||||
class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
||||||
private lateinit var modulePath: String
|
private lateinit var modulePath: String
|
||||||
private var nativeLibLoadSuccess: Boolean
|
private var nativeLibLoadSuccess: Boolean
|
||||||
private var alreadyInitialized = false
|
private var alreadyInitialized = false
|
||||||
private val TAG = "GakumasLocalify"
|
|
||||||
private val targetPackageName = "com.bandainamcoent.idolmaster_gakuen"
|
private val targetPackageName = "com.bandainamcoent.idolmaster_gakuen"
|
||||||
private val nativeLibName = "MarryKotone"
|
private val nativeLibName = "MarryKotone"
|
||||||
|
|
||||||
@ -115,20 +115,6 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showToast(message: String) {
|
|
||||||
val app = AndroidAppHelper.currentApplication()
|
|
||||||
val context = app?.applicationContext
|
|
||||||
if (context != null) {
|
|
||||||
val handler = Handler(Looper.getMainLooper())
|
|
||||||
handler.post {
|
|
||||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log.e(TAG, "showToast: $message failed: applicationContext is null")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun initGkmsConfig(activity: Activity) {
|
fun initGkmsConfig(activity: Activity) {
|
||||||
val intent = activity.intent
|
val intent = activity.intent
|
||||||
val gkmsData = intent.getStringExtra("gkmsData")
|
val gkmsData = intent.getStringExtra("gkmsData")
|
||||||
@ -160,8 +146,22 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit {
|
|||||||
external fun keyboardEvent(keyCode: Int, action: Int)
|
external fun keyboardEvent(keyCode: Int, action: Int)
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
external fun loadConfig(configJsonStr: String)
|
external fun loadConfig(configJsonStr: String)
|
||||||
}
|
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun showToast(message: String) {
|
||||||
|
val app = AndroidAppHelper.currentApplication()
|
||||||
|
val context = app?.applicationContext
|
||||||
|
if (context != null) {
|
||||||
|
val handler = Handler(Looper.getMainLooper())
|
||||||
|
handler.post {
|
||||||
|
Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log.e(TAG, "showToast: $message failed: applicationContext is null")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
ShadowHook.init(
|
ShadowHook.init(
|
||||||
|
@ -7,6 +7,9 @@ import android.os.Bundle
|
|||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.databinding.DataBindingUtil
|
import androidx.databinding.DataBindingUtil
|
||||||
|
import androidx.databinding.ObservableField
|
||||||
|
import com.google.android.material.textfield.TextInputEditText
|
||||||
|
import com.google.android.material.textfield.TextInputLayout
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonSyntaxException
|
import com.google.gson.JsonSyntaxException
|
||||||
import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding
|
import io.github.chinosk.gakumas.localify.databinding.ActivityMainBinding
|
||||||
@ -23,27 +26,33 @@ interface ConfigListener {
|
|||||||
fun onLiveCustomeDressChanged(value: Boolean)
|
fun onLiveCustomeDressChanged(value: Boolean)
|
||||||
fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
|
fun onUseCustomeGraphicSettingsChanged(value: Boolean)
|
||||||
|
fun onRenderScaleChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
|
fun onQualitySettingsLevelChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
|
fun onVolumeIndexChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
|
fun onMaxBufferPixelChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
|
fun onChangePresetQuality(level: Int)
|
||||||
|
fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
|
fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
class MainActivity : AppCompatActivity(), ConfigListener {
|
class MainActivity : AppCompatActivity(), ConfigListener {
|
||||||
private lateinit var config: GakumasConfig
|
private lateinit var binding: ActivityMainBinding
|
||||||
private val TAG = "GakumasLocalify"
|
private val TAG = "GakumasLocalify"
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_main)
|
setContentView(R.layout.activity_main)
|
||||||
|
|
||||||
|
binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
|
||||||
loadConfig()
|
loadConfig()
|
||||||
|
binding.listener = this
|
||||||
|
|
||||||
val requestData = intent.getStringExtra("gkmsData")
|
val requestData = intent.getStringExtra("gkmsData")
|
||||||
if (requestData != null) {
|
if (requestData != null) {
|
||||||
onClickStartGame()
|
onClickStartGame()
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
val binding = DataBindingUtil.setContentView<ActivityMainBinding>(this, R.layout.activity_main)
|
|
||||||
binding.config = config
|
|
||||||
binding.listener = this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showToast(message: String) {
|
private fun showToast(message: String) {
|
||||||
@ -63,34 +72,33 @@ class MainActivity : AppCompatActivity(), ConfigListener {
|
|||||||
|
|
||||||
private fun loadConfig() {
|
private fun loadConfig() {
|
||||||
val configStr = getConfigContent()
|
val configStr = getConfigContent()
|
||||||
val config = try {
|
binding.config = try {
|
||||||
Gson().fromJson(configStr, GakumasConfig::class.java)
|
Gson().fromJson(configStr, GakumasConfig::class.java)
|
||||||
}
|
}
|
||||||
catch (e: JsonSyntaxException) {
|
catch (e: JsonSyntaxException) {
|
||||||
showToast("配置文件异常,已重置: $e")
|
showToast("配置文件异常,已重置: $e")
|
||||||
Gson().fromJson("{}", GakumasConfig::class.java)
|
Gson().fromJson("{}", GakumasConfig::class.java)
|
||||||
}
|
}
|
||||||
this.config = config
|
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun saveConfig() {
|
private fun saveConfig() {
|
||||||
val configFile = File(filesDir, "gkms-config.json")
|
val configFile = File(filesDir, "gkms-config.json")
|
||||||
configFile.writeText(Gson().toJson(config))
|
configFile.writeText(Gson().toJson(binding.config!!))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEnabledChanged(value: Boolean) {
|
override fun onEnabledChanged(value: Boolean) {
|
||||||
config.enabled = value
|
binding.config!!.enabled = value
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onEnableFreeCameraChanged(value: Boolean) {
|
override fun onEnableFreeCameraChanged(value: Boolean) {
|
||||||
config.enableFreeCamera = value
|
binding.config!!.enableFreeCamera = value
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onUnlockAllLiveChanged(value: Boolean) {
|
override fun onUnlockAllLiveChanged(value: Boolean) {
|
||||||
config.unlockAllLive = value
|
binding.config!!.unlockAllLive = value
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,7 +111,7 @@ class MainActivity : AppCompatActivity(), ConfigListener {
|
|||||||
} else {
|
} else {
|
||||||
valueStr.toInt()
|
valueStr.toInt()
|
||||||
}
|
}
|
||||||
config.targetFrameRate = value
|
binding.config!!.targetFrameRate = value
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
catch (e: Exception) {
|
catch (e: Exception) {
|
||||||
@ -112,17 +120,62 @@ class MainActivity : AppCompatActivity(), ConfigListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onLiveCustomeDressChanged(value: Boolean) {
|
override fun onLiveCustomeDressChanged(value: Boolean) {
|
||||||
config.enableLiveCustomeDress = value
|
binding.config!!.enableLiveCustomeDress = value
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
override fun onLiveCustomeCostumeIdChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
config.liveCustomeCostumeId = s.toString()
|
binding.config!!.liveCustomeCostumeId = s.toString()
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onUseCustomeGraphicSettingsChanged(value: Boolean) {
|
||||||
|
binding.config!!.useCustomeGraphicSettings = value
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRenderScaleChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
binding.config!!.renderScale = try {
|
||||||
|
s.toString().toFloat()
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
0.0f
|
||||||
|
}
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQualitySettingsLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
binding.config!!.qualitySettingsLevel = try {
|
||||||
|
s.toString().toInt()
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onVolumeIndexChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
binding.config!!.volumeIndex = try {
|
||||||
|
s.toString().toInt()
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMaxBufferPixelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
binding.config!!.maxBufferPixel = try {
|
||||||
|
s.toString().toInt()
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
override fun onLiveCustomeHeadIdChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
config.liveCustomeHeadId = s.toString()
|
binding.config!!.liveCustomeHeadId = s.toString()
|
||||||
saveConfig()
|
saveConfig()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,4 +187,78 @@ class MainActivity : AppCompatActivity(), ConfigListener {
|
|||||||
}
|
}
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onReflectionQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
binding.config!!.reflectionQualityLevel = try {
|
||||||
|
val value = s.toString().toInt()
|
||||||
|
if (value > 5) 5 else value
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLodQualityLevelChanged(s: CharSequence, start: Int, before: Int, count: Int) {
|
||||||
|
binding.config!!.lodQualityLevel = try {
|
||||||
|
val value = s.toString().toInt()
|
||||||
|
if (value > 5) 5 else value
|
||||||
|
}
|
||||||
|
catch (e: Exception) {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onChangePresetQuality(level: Int) {
|
||||||
|
when (level) {
|
||||||
|
0 -> {
|
||||||
|
binding.config!!.renderScale = 0.5f
|
||||||
|
binding.config!!.qualitySettingsLevel = 1
|
||||||
|
binding.config!!.volumeIndex = 0
|
||||||
|
binding.config!!.maxBufferPixel = 1024
|
||||||
|
binding.config!!.lodQualityLevel = 1
|
||||||
|
binding.config!!.reflectionQualityLevel = 1
|
||||||
|
}
|
||||||
|
1 -> {
|
||||||
|
binding.config!!.renderScale = 0.59f
|
||||||
|
binding.config!!.qualitySettingsLevel = 1
|
||||||
|
binding.config!!.volumeIndex = 1
|
||||||
|
binding.config!!.maxBufferPixel = 1440
|
||||||
|
binding.config!!.lodQualityLevel = 2
|
||||||
|
binding.config!!.reflectionQualityLevel = 2
|
||||||
|
}
|
||||||
|
2 -> {
|
||||||
|
binding.config!!.renderScale = 0.67f
|
||||||
|
binding.config!!.qualitySettingsLevel = 2
|
||||||
|
binding.config!!.volumeIndex = 2
|
||||||
|
binding.config!!.maxBufferPixel = 2538
|
||||||
|
binding.config!!.lodQualityLevel = 3
|
||||||
|
binding.config!!.reflectionQualityLevel = 3
|
||||||
|
}
|
||||||
|
3 -> {
|
||||||
|
binding.config!!.renderScale = 0.77f
|
||||||
|
binding.config!!.qualitySettingsLevel = 3
|
||||||
|
binding.config!!.volumeIndex = 3
|
||||||
|
binding.config!!.maxBufferPixel = 3384
|
||||||
|
binding.config!!.lodQualityLevel = 4
|
||||||
|
binding.config!!.reflectionQualityLevel = 4
|
||||||
|
}
|
||||||
|
4 -> {
|
||||||
|
binding.config!!.renderScale = 1.0f
|
||||||
|
binding.config!!.qualitySettingsLevel = 5
|
||||||
|
binding.config!!.volumeIndex = 4
|
||||||
|
binding.config!!.maxBufferPixel = 8190
|
||||||
|
binding.config!!.lodQualityLevel = 5
|
||||||
|
binding.config!!.reflectionQualityLevel = 5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.config = binding.config
|
||||||
|
binding.notifyChange()
|
||||||
|
saveConfig()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showTextInputLayoutHint(view: TextInputLayout) {
|
||||||
|
showToast(view.hint.toString())
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package io.github.chinosk.gakumas.localify.models
|
package io.github.chinosk.gakumas.localify.models
|
||||||
|
|
||||||
|
import androidx.databinding.BaseObservable
|
||||||
|
|
||||||
data class GakumasConfig (
|
data class GakumasConfig (
|
||||||
var enabled: Boolean = true,
|
var enabled: Boolean = true,
|
||||||
var enableFreeCamera: Boolean = false,
|
var enableFreeCamera: Boolean = false,
|
||||||
@ -7,6 +9,13 @@ data class GakumasConfig(
|
|||||||
var unlockAllLive: Boolean = false,
|
var unlockAllLive: Boolean = false,
|
||||||
var enableLiveCustomeDress: Boolean = false,
|
var enableLiveCustomeDress: Boolean = false,
|
||||||
var liveCustomeHeadId: String = "",
|
var liveCustomeHeadId: String = "",
|
||||||
var liveCustomeCostumeId: String = ""
|
var liveCustomeCostumeId: String = "",
|
||||||
)
|
|
||||||
|
|
||||||
|
var useCustomeGraphicSettings: Boolean = false,
|
||||||
|
var renderScale: Float = 0.77f,
|
||||||
|
var qualitySettingsLevel: Int = 3,
|
||||||
|
var volumeIndex: Int = 3,
|
||||||
|
var maxBufferPixel: Int = 3384,
|
||||||
|
var reflectionQualityLevel: Int = 4, // 0~5
|
||||||
|
var lodQualityLevel: Int = 4, // 0~5
|
||||||
|
)
|
||||||
|
8
app/src/main/res/drawable/table_row_border.xml
Normal file
8
app/src/main/res/drawable/table_row_border.xml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:shape="rectangle">
|
||||||
|
<stroke
|
||||||
|
android:width="1dp"
|
||||||
|
android:color="#ACACAC"/> <!-- 设置边框宽度和颜色 -->
|
||||||
|
</shape>
|
@ -16,9 +16,17 @@
|
|||||||
android:padding="6sp"
|
android:padding="6sp"
|
||||||
tools:context=".MainActivity">
|
tools:context=".MainActivity">
|
||||||
|
|
||||||
<LinearLayout
|
<ScrollView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
@ -29,9 +37,9 @@
|
|||||||
android:id="@+id/textViewTitle"
|
android:id="@+id/textViewTitle"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/gakumas_localify"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="20sp"
|
android:textSize="20sp" />
|
||||||
android:text="@string/gakumas_localify" />
|
|
||||||
|
|
||||||
<Space
|
<Space
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -63,9 +71,9 @@
|
|||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
app:boxBackgroundColor="@android:color/transparent"
|
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:hint="@string/setFpsTitle" >
|
android:hint="@string/setFpsTitle"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editTextTargetFps"
|
android:id="@+id/editTextTargetFps"
|
||||||
@ -73,11 +81,11 @@
|
|||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
android:inputType="numberSigned"
|
android:inputType="numberSigned"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onTargetFpsChanged(s, st, b, a)}"
|
||||||
android:paddingStart="0dp"
|
android:paddingStart="0dp"
|
||||||
android:paddingEnd="0dp"
|
android:paddingEnd="0dp"
|
||||||
android:paddingBottom="0dp"
|
android:paddingBottom="0dp"
|
||||||
android:text="@={`` + config.targetFrameRate}"
|
android:text="@={`` + config.targetFrameRate}" />
|
||||||
android:onTextChanged="@{(s, st, b, a) -> listener.onTargetFpsChanged(s, st, b, a)}"/>
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
@ -109,6 +117,20 @@
|
|||||||
android:text="@string/unlockAllLive" />
|
android:text="@string/unlockAllLive" />
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@drawable/table_row_border">
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="10sp"
|
||||||
|
android:paddingRight="10sp"
|
||||||
|
android:paddingBottom="10sp"
|
||||||
|
android:stretchColumns="0">
|
||||||
|
|
||||||
<TableRow
|
<TableRow
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
@ -129,20 +151,20 @@
|
|||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
app:boxBackgroundColor="@android:color/transparent"
|
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:hint="@string/live_costume_head_id" >
|
android:hint="@string/live_costume_head_id"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editTextLiveCustomeCharaId"
|
android:id="@+id/editTextLiveCustomeCharaId"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onLiveCustomeHeadIdChanged(s, st, b, a)}"
|
||||||
android:paddingStart="0dp"
|
android:paddingStart="0dp"
|
||||||
android:paddingEnd="0dp"
|
android:paddingEnd="0dp"
|
||||||
android:paddingBottom="0dp"
|
android:paddingBottom="0dp"
|
||||||
android:text="@={config.liveCustomeHeadId}"
|
android:text="@={config.liveCustomeHeadId}" />
|
||||||
android:onTextChanged="@{(s, st, b, a) -> listener.onLiveCustomeHeadIdChanged(s, st, b, a)}"/>
|
|
||||||
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
@ -150,26 +172,305 @@
|
|||||||
<TableRow
|
<TableRow
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputLayout
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="48dp"
|
android:layout_height="48dp"
|
||||||
app:boxBackgroundColor="@android:color/transparent"
|
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
android:hint="@string/live_custome_dress_id" >
|
android:hint="@string/live_custome_dress_id"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
<com.google.android.material.textfield.TextInputEditText
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
android:id="@+id/editTextLiveCustomeCostumeId"
|
android:id="@+id/editTextLiveCustomeCostumeId"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:ems="10"
|
android:ems="10"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onLiveCustomeCostumeIdChanged(s, st, b, a)}"
|
||||||
android:paddingStart="0dp"
|
android:paddingStart="0dp"
|
||||||
android:paddingEnd="0dp"
|
android:paddingEnd="0dp"
|
||||||
android:paddingBottom="0dp"
|
android:paddingBottom="0dp"
|
||||||
android:text="@={config.liveCustomeCostumeId}"
|
android:text="@={config.liveCustomeCostumeId}" />
|
||||||
android:onTextChanged="@{(s, st, b, a) -> listener.onLiveCustomeCostumeIdChanged(s, st, b, a)}"/>
|
|
||||||
</com.google.android.material.textfield.TextInputLayout>
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginTop="4sp"
|
||||||
|
android:background="@drawable/table_row_border">
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingLeft="10sp"
|
||||||
|
android:paddingRight="10sp"
|
||||||
|
android:paddingBottom="10sp"
|
||||||
|
android:stretchColumns="0">
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<com.google.android.material.switchmaterial.SwitchMaterial
|
||||||
|
android:id="@+id/SwitchUseCustomeGraphicSettings"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:checked="@={config.useCustomeGraphicSettings}"
|
||||||
|
android:onCheckedChanged="@{(view, value) -> listener.onUseCustomeGraphicSettingsChanged(value)}"
|
||||||
|
android:text="@string/useCustomeGraphicSettings" />
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/qualityRecordButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_margin="1sp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:minWidth="1sp"
|
||||||
|
android:onClick="@{() -> listener.onChangePresetQuality(4)}"
|
||||||
|
android:text="极高" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/qualityVeryHighButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_margin="1sp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:minWidth="1sp"
|
||||||
|
android:onClick="@{() -> listener.onChangePresetQuality(3)}"
|
||||||
|
android:text="超高" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/qualityHighButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_margin="1sp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:minWidth="1sp"
|
||||||
|
android:onClick="@{() -> listener.onChangePresetQuality(2)}"
|
||||||
|
android:text="高" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/qualityMidButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_margin="1sp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:minWidth="1sp"
|
||||||
|
android:onClick="@{() -> listener.onChangePresetQuality(1)}"
|
||||||
|
android:text="中" />
|
||||||
|
|
||||||
|
<com.google.android.material.button.MaterialButton
|
||||||
|
android:id="@+id/qualityLowButton"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:minWidth="1sp"
|
||||||
|
android:onClick="@{() -> listener.onChangePresetQuality(0)}"
|
||||||
|
android:text="低" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<TableLayout
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/editTextRenderScaleLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="@string/renderscale"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editTextRenderScale"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="0.5/0.59/0.67/0.77/1.0"
|
||||||
|
android:inputType="numberDecimal"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onRenderScaleChanged(s, st, b, a)}"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:text="@={`` + config.renderScale}" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/editTextQualitySettingsLevelLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="QualityLevel (1/1/2/3/5)"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editTextQualitySettingsLevel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="1/1/2/3/5"
|
||||||
|
android:inputType="number"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onQualitySettingsLevelChanged(s, st, b, a)}"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:text="@={`` + config.qualitySettingsLevel}" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/editTextVolumeIndexLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="VolumeIndex (0/1/2/3/4)"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editTextVolumeIndex"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="0/1/2/3/4"
|
||||||
|
android:inputType="number"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onVolumeIndexChanged(s, st, b, a)}"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:text="@={`` + config.volumeIndex}" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:id="@+id/editTextMaxBufferPixelLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="MaxBufferPixel (1024/1440/2538/3384/8190)"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editTextMaxBufferPixel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="1024/1440/2538/3384/8190"
|
||||||
|
android:inputType="number"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onMaxBufferPixelChanged(s, st, b, a)}"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:text="@={`` + config.maxBufferPixel}" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
<TableRow
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:weightSum="2">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="ReflectionLevel (0~5)"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editTextReflectionQualityLevel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="0/1/2/3/4/5"
|
||||||
|
android:inputType="number"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onReflectionQualityLevelChanged(s, st, b, a)}"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:text="@={`` + config.reflectionQualityLevel}" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:background="@android:color/transparent"
|
||||||
|
android:hint="LOD Level (0~5)"
|
||||||
|
app:boxBackgroundColor="@android:color/transparent">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputEditText
|
||||||
|
android:id="@+id/editTextLodQualityLevel"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:ems="10"
|
||||||
|
android:hint="0/1/2/3/4/5"
|
||||||
|
android:inputType="number"
|
||||||
|
android:onTextChanged="@{(s, st, b, a) -> listener.onLodQualityLevelChanged(s, st, b, a)}"
|
||||||
|
android:paddingStart="0dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="0dp"
|
||||||
|
android:text="@={`` + config.lodQualityLevel}" />
|
||||||
|
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
|
</TableLayout>
|
||||||
|
</TableRow>
|
||||||
|
</TableLayout>
|
||||||
|
|
||||||
|
</TableRow>
|
||||||
|
|
||||||
<TableRow
|
<TableRow
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
@ -185,5 +486,7 @@
|
|||||||
|
|
||||||
</TableLayout>
|
</TableLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</layout>
|
</layout>
|
||||||
|
@ -9,4 +9,6 @@
|
|||||||
<string name="liveUseCustomeDress">Live 使用自定义角色</string>
|
<string name="liveUseCustomeDress">Live 使用自定义角色</string>
|
||||||
<string name="live_costume_head_id">Live 自定义头部 ID (例: costume_head_hski-cstm-0002)</string>
|
<string name="live_costume_head_id">Live 自定义头部 ID (例: costume_head_hski-cstm-0002)</string>
|
||||||
<string name="live_custome_dress_id">Live 自定义服装 ID (例: hski-cstm-0002)</string>
|
<string name="live_custome_dress_id">Live 自定义服装 ID (例: hski-cstm-0002)</string>
|
||||||
|
<string name="useCustomeGraphicSettings">使用自定义画质设置</string>
|
||||||
|
<string name="renderscale">RenderScale (0.5/0.59/0.67/0.77/1.0)</string>
|
||||||
</resources>
|
</resources>
|
Loading…
x
Reference in New Issue
Block a user