From b5b433beb5c905c61eb27d20642c9e83e34d9cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=A5=AA=E8=98=AD=E6=A5=93?= Date: Sun, 23 Jun 2024 17:00:26 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0Toast=E6=8F=90=E9=86=92?= =?UTF-8?q?=EF=BC=8C=E4=BC=98=E5=8C=96=E6=89=8B=E6=9F=84=E6=8E=A7=E5=88=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/cpp/GakumasLocalify/Log.cpp | 26 +++ .../cpp/GakumasLocalify/camera/camera.cpp | 199 +++++++++++++++--- .../gakumas/localify/GakumasHookMain.kt | 10 +- 3 files changed, 201 insertions(+), 34 deletions(-) diff --git a/app/src/main/cpp/GakumasLocalify/Log.cpp b/app/src/main/cpp/GakumasLocalify/Log.cpp index 529e962..0ac4db6 100644 --- a/app/src/main/cpp/GakumasLocalify/Log.cpp +++ b/app/src/main/cpp/GakumasLocalify/Log.cpp @@ -100,4 +100,30 @@ namespace GakumasLocal::Log { GetParamStringResult(result); ShowToast(result); } + + void ShowToast(const char* text) { + DebugFmt("Toast: %s", text); + + std::thread([text](){ + auto env = Misc::GetJNIEnv(); + if (!env) { + return; + } + + jclass& kotlinClass = g_gakumasHookMainClass; + if (!kotlinClass) { + g_javaVM->DetachCurrentThread(); + return; + } + jmethodID& methodId = showToastMethodId; + if (!methodId) { + g_javaVM->DetachCurrentThread(); + return; + } + jstring param = env->NewStringUTF(text); + env->CallStaticVoidMethod(kotlinClass, methodId, param); + + g_javaVM->DetachCurrentThread(); + }).detach(); + } } diff --git a/app/src/main/cpp/GakumasLocalify/camera/camera.cpp b/app/src/main/cpp/GakumasLocalify/camera/camera.cpp index 1b154f2..9b6d051 100644 --- a/app/src/main/cpp/GakumasLocalify/camera/camera.cpp +++ b/app/src/main/cpp/GakumasLocalify/camera/camera.cpp @@ -18,6 +18,7 @@ namespace GKCamera { int followCharaIndex = 0; float l_sensitivity = 0.5f; float r_sensitivity = 0.5f; + bool showToast = true; GakumasLocal::Misc::CSEnum bodyPartsEnum("Head", 0xa); // bool rMousePressFlg = false; @@ -251,6 +252,142 @@ namespace GKCamera { } } + void ShowToast(const char *text) { + if (showToast) { + GakumasLocal::Log::ShowToast(text); + } + } + + void JLThumbRight(float value) { + camera_right(value * l_sensitivity * baseCamera.fov / 60); + } + + void JLThumbDown(float value) { + camera_back(value * l_sensitivity * baseCamera.fov / 60); + } + + void JRThumbRight(float value) { + cameraLookat_right(value * r_sensitivity * baseCamera.fov / 60); + ChangeLiveFollowCameraOffsetX(-1 * value * r_sensitivity * baseCamera.fov / 60); + } + + void JRThumbDown(float value) { + cameraLookat_down(value * r_sensitivity * baseCamera.fov / 60); + ChangeLiveFollowCameraOffsetY(-0.1 * value * r_sensitivity * baseCamera.fov / 60); + } + + void JDadUp(){ + reset_camera(); + ShowToast("重置镜头"); + } + + void JDadDown(){ + ShowToast("关闭通知,再次点击开启"); + showToast = !showToast; + } + + void JDadLeft(){ + l_sensitivity = 1.0f; + ShowToast("重置移动灵敏度"); + } + + void JDadRight(){ + r_sensitivity = 1.0f; + ShowToast("重置镜头灵敏度"); + } + + void JAKeyDown() { + if (cameraMode == CameraMode::FOLLOW) { + const auto currPart = bodyPartsEnum.Next(); + if (showToast) { + GakumasLocal::Log::ShowToastFmt("看向:%s (0x%x)", currPart.first.c_str(), + currPart.second); + } + } else { + r_sensitivity *= 0.8f; + } + } + + void JBKeyDown() { + if (cameraMode == CameraMode::FOLLOW) { + const auto currPart = bodyPartsEnum.Last(); + if (showToast) { + GakumasLocal::Log::ShowToastFmt("看向:%s (0x%x)", currPart.first.c_str(), + currPart.second); + } + } else { + r_sensitivity *= 1.2f; + } + } + + void JXKeyDown() { + if (cameraMode == CameraMode::FOLLOW) { + OnLeftDown(); + if (showToast) { + GakumasLocal::Log::ShowToastFmt("注视:%d", followCharaIndex); + } + } else { + l_sensitivity *= 0.8f; + } + } + + void JYKeyDown() { + if (cameraMode == CameraMode::FOLLOW) { + OnRightDown(); + if (showToast) { + GakumasLocal::Log::ShowToastFmt("注视:%d", followCharaIndex); + } + } else { + l_sensitivity *= 1.2f; + } + } + + void JSelectKeyDown() { + switch (cameraMode) { + case CameraMode::FREE: { + cameraMode = CameraMode::FOLLOW; + ShowToast("跟随模式"); + } break; + case CameraMode::FOLLOW: { + cameraMode = CameraMode::FIRST_PERSON; + ShowToast("第一人称模式"); + } break; + case CameraMode::FIRST_PERSON: { + cameraMode = CameraMode::FREE; + ShowToast("无人机模式"); + + } break; + } + } + + void JStartKeyDown() { + switch (cameraMode) { + case CameraMode::FIRST_PERSON: { + if (firstPersonRoll == FirstPersonRoll::ENABLE_ROLL) { + firstPersonRoll = FirstPersonRoll::DISABLE_ROLL; + ShowToast("镜头水平固定"); + } + else { + firstPersonRoll = FirstPersonRoll::ENABLE_ROLL; + ShowToast("镜头水平摇动"); + } + } break; + + case CameraMode::FOLLOW: { + if (followModeY == FollowModeY::APPLY_Y) { + followModeY = FollowModeY::SMOOTH_Y; + ShowToast("平滑升降"); + } + else { + followModeY = FollowModeY::APPLY_Y; + ShowToast("即时升降"); + } + } break; + + default: break; + } + } + UnityResolve::UnityType::Vector3 CalcPositionFromLookAt(const UnityResolve::UnityType::Vector3& target, const UnityResolve::UnityType::Vector3& offset) { // offset: z 远近, y 高低, x角度 @@ -423,24 +560,32 @@ namespace GKCamera { if (cameraMoveState.k) ChangeLiveFollowCameraOffsetY(-offsetMoveStep); if (cameraMoveState.j) ChangeLiveFollowCameraOffsetX(0.8); if (cameraMoveState.l) ChangeLiveFollowCameraOffsetX(-0.8); + // 手柄操作响应 + // 左摇杆 if (std::abs(cameraMoveState.thumb_l_right) > 0.1f) - camera_right(cameraMoveState.thumb_l_right * l_sensitivity); + JLThumbRight(cameraMoveState.thumb_l_right); if (std::abs(cameraMoveState.thumb_l_down) > 0.1f) - camera_back(cameraMoveState.thumb_l_down * l_sensitivity); + JLThumbDown(cameraMoveState.thumb_l_down); + // 右摇杆 if (std::abs(cameraMoveState.thumb_r_right) > 0.1f) - cameraLookat_right(cameraMoveState.thumb_r_right * r_sensitivity); + JRThumbRight(cameraMoveState.thumb_r_right); if (std::abs(cameraMoveState.thumb_r_down) > 0.1f) - cameraLookat_down(cameraMoveState.thumb_r_down * r_sensitivity); + JRThumbDown(cameraMoveState.thumb_r_down); + // 左扳机 if (std::abs(cameraMoveState.lt_button) > 0.1f) - camera_down(cameraMoveState.lt_button * 0.5f); + camera_down(cameraMoveState.lt_button * l_sensitivity * baseCamera.fov / 60); + // 右扳机 if (std::abs(cameraMoveState.rt_button) > 0.1f) - camera_up(cameraMoveState.rt_button * 0.5f); - if (cameraMoveState.dpad_up) ChangeLiveFollowCameraOffsetY(offsetMoveStep); - if (cameraMoveState.dpad_down) ChangeLiveFollowCameraOffsetY(-offsetMoveStep); - if (cameraMoveState.dpad_left) ChangeLiveFollowCameraOffsetX(offsetMoveStep); - if (cameraMoveState.dpad_right) ChangeLiveFollowCameraOffsetX(-offsetMoveStep); - if (cameraMoveState.lb_button) changeCameraFOV(0.5f); - if (cameraMoveState.rb_button) changeCameraFOV(-0.5f); + camera_up(cameraMoveState.rt_button * l_sensitivity * baseCamera.fov / 60); + // 左肩键 + if (cameraMoveState.lb_button) changeCameraFOV(0.5f * r_sensitivity); + // 右肩键 + if (cameraMoveState.rb_button) changeCameraFOV(-0.5f * r_sensitivity); + // 十字键 + if (cameraMoveState.dpad_up) JDadUp(); +// if (cameraMoveState.dpad_down) JDadDown(); + if (cameraMoveState.dpad_left) JDadLeft(); + if (cameraMoveState.dpad_right) JDadRight(); std::this_thread::sleep_for(std::chrono::milliseconds(10)); } }).detach(); @@ -502,21 +647,22 @@ namespace GKCamera { } break; case KEY_F: if (message == WM_KEYDOWN) SwitchCameraMode(); break; case KEY_V: if (message == WM_KEYDOWN) SwitchCameraSubMode(); break; + // 手柄操作响应 case BTN_A: cameraMoveState.a_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) r_sensitivity *= 0.8f; + if (message == WM_KEYDOWN) JAKeyDown(); break; case BTN_B: cameraMoveState.b_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) r_sensitivity *= 1.2f; + if (message == WM_KEYDOWN) JBKeyDown(); break; case BTN_X: cameraMoveState.x_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) l_sensitivity *= 0.8f; + if (message == WM_KEYDOWN) JXKeyDown(); break; case BTN_Y: cameraMoveState.y_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) l_sensitivity *= 1.2f; + if (message == WM_KEYDOWN) JYKeyDown(); break; case BTN_LB: cameraMoveState.lb_button = message == WM_KEYDOWN; @@ -526,22 +672,17 @@ namespace GKCamera { break; case BTN_THUMBL: cameraMoveState.thumb_l_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) reset_camera(); break; case BTN_THUMBR: cameraMoveState.thumb_r_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) { - l_sensitivity = 1.0f; - r_sensitivity = 1.0f; - } break; case BTN_SELECT: cameraMoveState.select_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) SwitchCameraMode(); + if (message == WM_KEYDOWN) JSelectKeyDown(); break; case BTN_START: cameraMoveState.start_button = message == WM_KEYDOWN; - if (message == WM_KEYDOWN) SwitchCameraSubMode(); + if (message == WM_KEYDOWN) JStartKeyDown(); break; case BTN_SHARE: cameraMoveState.share_button = message == WM_KEYDOWN; @@ -578,16 +719,8 @@ namespace GKCamera { cameraMoveState.dpad_left = hatX == -1.0f; cameraMoveState.dpad_right = hatX == 1.0f; - if (rightStickX == 1.0f) { - OnRightDown(); - } else if (rightStickX == -1.0f) { - OnLeftDown(); - } - - if (rightStickY == 1.0f) { - OnDownDown(); - } else if (rightStickY == -1.0f) { - OnUpDown(); + if (cameraMoveState.dpad_down) { + JDadDown(); } // GakumasLocal::Log::InfoFmt( diff --git a/app/src/main/java/io/github/chinosk/gakumas/localify/GakumasHookMain.kt b/app/src/main/java/io/github/chinosk/gakumas/localify/GakumasHookMain.kt index 734bcc0..5a54699 100644 --- a/app/src/main/java/io/github/chinosk/gakumas/localify/GakumasHookMain.kt +++ b/app/src/main/java/io/github/chinosk/gakumas/localify/GakumasHookMain.kt @@ -315,6 +315,9 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit { @JvmStatic external fun loadConfig(configJsonStr: String) + // Toast快速切换内容 + private var toast: Toast? = null + @JvmStatic fun showToast(message: String) { val app = AndroidAppHelper.currentApplication() @@ -322,7 +325,12 @@ class GakumasHookMain : IXposedHookLoadPackage, IXposedHookZygoteInit { if (context != null) { val handler = Handler(Looper.getMainLooper()) handler.post { - Toast.makeText(context, message, Toast.LENGTH_SHORT).show() + // 取消之前的 Toast + toast?.cancel() + // 创建新的 Toast + toast = Toast.makeText(context, message, Toast.LENGTH_SHORT) + // 展示新的 Toast + toast?.show() } } else {