mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-05-24 06:50:43 -04:00
Merge remote-tracking branch 'origin/main' into randomizer
# Conflicts: # files.cmake # src/m_Do/m_Do_main.cpp
This commit is contained in:
@@ -446,6 +446,12 @@ target_link_libraries(dusk PRIVATE aurora::main ${GAME_LIBS} ${JSYSTEM_LINK_LIBR
|
||||
target_precompile_headers(dusk PRIVATE "$<$<COMPILE_LANGUAGE:CXX>:${CMAKE_SOURCE_DIR}/include/dusk_pch.hpp>")
|
||||
if (TARGET crashpad_handler)
|
||||
add_dependencies(dusk crashpad_handler)
|
||||
add_custom_command(TARGET dusk POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||
"$<TARGET_FILE:crashpad_handler>"
|
||||
"$<TARGET_FILE_DIR:dusk>"
|
||||
COMMENT "Copying crashpad handler"
|
||||
)
|
||||
endif ()
|
||||
|
||||
if (ANDROID)
|
||||
|
||||
Vendored
+1
-1
Submodule extern/aurora updated: 449e7bf9b9...211bfb00a8
@@ -1452,6 +1452,7 @@ set(DUSK_FILES
|
||||
src/dusk/imgui/ImGuiMenuTools.hpp
|
||||
src/dusk/imgui/ImGuiMenuRandomizer.cpp
|
||||
src/dusk/imgui/ImGuiMenuRandomizer.hpp
|
||||
src/dusk/imgui/ImGuiActorSpawner.cpp
|
||||
src/dusk/imgui/ImGuiProcessOverlay.cpp
|
||||
src/dusk/imgui/ImGuiCameraOverlay.cpp
|
||||
src/dusk/imgui/ImGuiHeapOverlay.cpp
|
||||
@@ -1496,6 +1497,8 @@ set(DUSK_FILES
|
||||
src/dusk/ui/prelaunch.hpp
|
||||
src/dusk/ui/preset.cpp
|
||||
src/dusk/ui/preset.hpp
|
||||
src/dusk/ui/reporting.cpp
|
||||
src/dusk/ui/reporting.hpp
|
||||
src/dusk/ui/select_button.cpp
|
||||
src/dusk/ui/select_button.hpp
|
||||
src/dusk/ui/settings.cpp
|
||||
|
||||
@@ -1,8 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
namespace dusk {
|
||||
namespace dusk::crash_reporting {
|
||||
|
||||
void InitializeCrashReporting();
|
||||
void ShutdownCrashReporting();
|
||||
enum class Consent {
|
||||
Unavailable,
|
||||
Unknown,
|
||||
Given,
|
||||
Revoked,
|
||||
};
|
||||
|
||||
} // namespace dusk
|
||||
void initialize();
|
||||
void shutdown();
|
||||
Consent get_consent();
|
||||
void set_consent(bool enabled);
|
||||
|
||||
} // namespace dusk::crash_reporting
|
||||
|
||||
@@ -144,6 +144,8 @@ struct UserSettings {
|
||||
ConfigVar<bool> freeCamera;
|
||||
ConfigVar<bool> invertCameraXAxis;
|
||||
ConfigVar<bool> invertCameraYAxis;
|
||||
ConfigVar<bool> invertFirstPersonXAxis;
|
||||
ConfigVar<bool> invertFirstPersonYAxis;
|
||||
ConfigVar<float> freeCameraSensitivity;
|
||||
ConfigVar<bool> debugFlyCam;
|
||||
ConfigVar<bool> debugFlyCamLockEvents;
|
||||
@@ -187,7 +189,6 @@ struct UserSettings {
|
||||
ConfigVar<bool> skipPreLaunchUI;
|
||||
ConfigVar<bool> showPipelineCompilation;
|
||||
ConfigVar<bool> wasPresetChosen;
|
||||
ConfigVar<bool> enableCrashReporting;
|
||||
ConfigVar<bool> checkForUpdates;
|
||||
ConfigVar<int> cardFileType;
|
||||
ConfigVar<bool> enableAdvancedSettings;
|
||||
|
||||
@@ -119,8 +119,8 @@ BOOL daAlink_c::setBodyAngleToCamera() {
|
||||
var_f31 /= dComIfGp_getCameraZoomScale(field_0x317c);
|
||||
}
|
||||
|
||||
shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle));
|
||||
sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle));
|
||||
shape_angle.y = shape_angle.y + (var_f31 * cM_ssin(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f)));
|
||||
sp8 = mBodyAngle.x + (var_f31 * cM_scos(mStickAngle) IF_DUSK(* (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f)));
|
||||
|
||||
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
|
||||
sp8 = mBodyAngle.x;
|
||||
@@ -144,8 +144,8 @@ BOOL daAlink_c::setBodyAngleToCamera() {
|
||||
f32 gy_pitch = 0.f;
|
||||
dusk::gyro::getAimDeltas(gy_yaw, gy_pitch);
|
||||
|
||||
shape_angle.y = shape_angle.y + cM_rad2s(gy_yaw * gyro_scale);
|
||||
sp8 = sp8 + cM_rad2s(gy_pitch * gyro_scale);
|
||||
shape_angle.y = shape_angle.y + cM_rad2s(gy_yaw * gyro_scale * (dusk::getSettings().game.invertFirstPersonXAxis ? -1.0f : 1.0f));
|
||||
sp8 = sp8 + cM_rad2s(gy_pitch * gyro_scale * (dusk::getSettings().game.invertFirstPersonYAxis ? -1.0f : 1.0f));
|
||||
|
||||
if (checkNotItemSinkLimit() && sp8 > 0 && sp8 > mBodyAngle.x) {
|
||||
sp8 = mBodyAngle.x;
|
||||
|
||||
+4
-1
@@ -7648,7 +7648,10 @@ bool dCamera_c::freeCamera() {
|
||||
cXyz camMovement = {mPadInfo.mCStick.mLastPosX, mPadInfo.mCStick.mLastPosY, 0.0f};
|
||||
f32 magnitude = sqrt(mPadInfo.mCStick.mLastPosX * mPadInfo.mCStick.mLastPosX + mPadInfo.mCStick.mLastPosY * mPadInfo.mCStick.mLastPosY);
|
||||
|
||||
if (mPadInfo.mCStick.mLastPosX != 0 || mPadInfo.mCStick.mLastPosY != 0) {
|
||||
// If we aren't in manual cam mode, don't trigger it if the player tries to hit C-up
|
||||
// for first person
|
||||
if (mPadInfo.mCStick.mLastPosX != 0 || mPadInfo.mCStick.mLastPosY < 0 ||
|
||||
(mCamParam.mManualMode == 1 && mPadInfo.mCStick.mLastPosY != 0)) {
|
||||
mCamParam.mManualMode = 1;
|
||||
camMovement = camMovement.normalize();
|
||||
camMovement.y *= dusk::getSettings().game.invertCameraYAxis ? 1.0f : -1.0f;
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
#include "dusk/dusk.h"
|
||||
#include "dusk/logging.h"
|
||||
#include "dusk/main.h"
|
||||
#include "dusk/settings.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <cstdlib>
|
||||
@@ -13,114 +12,83 @@
|
||||
#include <string_view>
|
||||
#include <system_error>
|
||||
|
||||
#include "SDL3/SDL_filesystem.h"
|
||||
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
#include <sentry.h>
|
||||
#endif
|
||||
|
||||
namespace dusk {
|
||||
namespace dusk::crash_reporting {
|
||||
|
||||
namespace {
|
||||
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
bool g_sentryInitialized = false;
|
||||
|
||||
bool IsTruthy(std::string_view value) {
|
||||
return value == "1" || value == "true" || value == "TRUE" || value == "yes"
|
||||
|| value == "YES" || value == "on" || value == "ON";
|
||||
bool truthy(std::string_view value) {
|
||||
return value == "1" || value == "true" || value == "TRUE" || value == "yes" || value == "YES" ||
|
||||
value == "on" || value == "ON";
|
||||
}
|
||||
|
||||
std::string GetEnvOrEmpty(const char* name) {
|
||||
std::string env_or_empty(const char* name) {
|
||||
if (const char* value = std::getenv(name)) {
|
||||
return value;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
bool GetEffectiveEnabled() {
|
||||
const std::string env = GetEnvOrEmpty("DUSK_SENTRY_ENABLED");
|
||||
if (!env.empty()) {
|
||||
return IsTruthy(env);
|
||||
}
|
||||
return getSettings().backend.enableCrashReporting;
|
||||
bool disabled_by_env() {
|
||||
const std::string env = env_or_empty("DUSK_SENTRY_ENABLED");
|
||||
return !env.empty() && !truthy(env);
|
||||
}
|
||||
|
||||
std::string GetEffectiveDsn() {
|
||||
const std::string env = GetEnvOrEmpty("DUSK_SENTRY_DSN");
|
||||
std::string effective_dsn() {
|
||||
const std::string env = env_or_empty("DUSK_SENTRY_DSN");
|
||||
if (!env.empty()) {
|
||||
return env;
|
||||
}
|
||||
return DUSK_SENTRY_DSN;
|
||||
}
|
||||
|
||||
bool GetEffectiveDebug() {
|
||||
const std::string env = GetEnvOrEmpty("DUSK_SENTRY_DEBUG");
|
||||
bool effective_debug() {
|
||||
const std::string env = env_or_empty("DUSK_SENTRY_DEBUG");
|
||||
if (!env.empty()) {
|
||||
return IsTruthy(env);
|
||||
return truthy(env);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GetReleaseName() {
|
||||
std::string release_name() {
|
||||
return std::string(AppName) + "@" DUSK_WC_DESCRIBE;
|
||||
}
|
||||
|
||||
std::filesystem::path GetSentryDatabasePath() {
|
||||
std::filesystem::path sentry_database_path() {
|
||||
return dusk::ConfigPath / "sentry";
|
||||
}
|
||||
|
||||
std::filesystem::path GetLogAttachmentPath() {
|
||||
std::filesystem::path log_attachment_path() {
|
||||
if (const char* logPath = GetLogFilePath()) {
|
||||
return logPath;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
std::filesystem::path GetCrashpadHandlerPath() {
|
||||
const char* basePath = SDL_GetBasePath();
|
||||
if (!basePath) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const std::filesystem::path handlerDir(basePath);
|
||||
#if _WIN32
|
||||
return handlerDir / "crashpad_handler.exe";
|
||||
#else
|
||||
return handlerDir / "crashpad_handler";
|
||||
#endif
|
||||
}
|
||||
|
||||
void ConfigurePathOptions(sentry_options_t* options) {
|
||||
const auto databasePath = GetSentryDatabasePath();
|
||||
void configure_path_options(sentry_options_t* options) {
|
||||
const auto databasePath = sentry_database_path();
|
||||
std::error_code ec;
|
||||
std::filesystem::create_directories(databasePath, ec);
|
||||
if (ec) {
|
||||
DuskLog.warn("Unable to create Sentry database path '{}': {}",
|
||||
databasePath.string(), ec.message());
|
||||
DuskLog.warn(
|
||||
"Unable to create Sentry database path '{}': {}", databasePath.string(), ec.message());
|
||||
}
|
||||
|
||||
#if _WIN32
|
||||
const std::wstring databasePathWide = databasePath.wstring();
|
||||
sentry_options_set_database_pathw(options, databasePathWide.c_str());
|
||||
|
||||
const auto handlerPath = GetCrashpadHandlerPath();
|
||||
if (!handlerPath.empty()) {
|
||||
const std::wstring handlerPathWide = handlerPath.wstring();
|
||||
sentry_options_set_handler_pathw(options, handlerPathWide.c_str());
|
||||
}
|
||||
#else
|
||||
const std::string databasePathUtf8 = databasePath.string();
|
||||
sentry_options_set_database_path(options, databasePathUtf8.c_str());
|
||||
|
||||
const auto handlerPath = GetCrashpadHandlerPath();
|
||||
if (!handlerPath.empty()) {
|
||||
const std::string handlerPathUtf8 = handlerPath.string();
|
||||
sentry_options_set_handler_path(options, handlerPathUtf8.c_str());
|
||||
}
|
||||
#endif
|
||||
|
||||
const auto logPath = GetLogAttachmentPath();
|
||||
const auto logPath = log_attachment_path();
|
||||
if (!logPath.empty()) {
|
||||
#if _WIN32
|
||||
sentry_options_add_attachmentw(options, logPath.wstring().c_str());
|
||||
@@ -133,32 +101,29 @@ void ConfigurePathOptions(sentry_options_t* options) {
|
||||
|
||||
} // namespace
|
||||
|
||||
void InitializeCrashReporting() {
|
||||
void initialize() {
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
if (g_sentryInitialized) {
|
||||
if (g_sentryInitialized || disabled_by_env()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetEffectiveEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string dsn = GetEffectiveDsn();
|
||||
const std::string dsn = effective_dsn();
|
||||
if (dsn.empty()) {
|
||||
DuskLog.warn("Crash reporting is enabled but no Sentry DSN is configured");
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string release = GetReleaseName();
|
||||
const std::string release = release_name();
|
||||
|
||||
sentry_options_t* options = sentry_options_new();
|
||||
sentry_options_set_dsn(options, dsn.c_str());
|
||||
sentry_options_set_release(options, release.c_str());
|
||||
sentry_options_set_environment(options, DUSK_SENTRY_ENVIRONMENT);
|
||||
sentry_options_set_debug(options, GetEffectiveDebug() ? 1 : 0);
|
||||
sentry_options_set_debug(options, effective_debug() ? 1 : 0);
|
||||
sentry_options_set_require_user_consent(options, 1);
|
||||
sentry_options_set_cache_keep(options, 1);
|
||||
sentry_options_set_max_breadcrumbs(options, 100);
|
||||
ConfigurePathOptions(options);
|
||||
configure_path_options(options);
|
||||
|
||||
if (sentry_init(options) != 0) {
|
||||
DuskLog.warn("Failed to initialize Sentry crash reporting");
|
||||
@@ -173,7 +138,7 @@ void InitializeCrashReporting() {
|
||||
#endif
|
||||
}
|
||||
|
||||
void ShutdownCrashReporting() {
|
||||
void shutdown() {
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
if (!g_sentryInitialized) {
|
||||
return;
|
||||
@@ -184,4 +149,40 @@ void ShutdownCrashReporting() {
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace dusk
|
||||
Consent get_consent() {
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
if (!g_sentryInitialized) {
|
||||
return Consent::Unavailable;
|
||||
}
|
||||
|
||||
switch (sentry_user_consent_get()) {
|
||||
case SENTRY_USER_CONSENT_GIVEN:
|
||||
return Consent::Given;
|
||||
case SENTRY_USER_CONSENT_REVOKED:
|
||||
return Consent::Revoked;
|
||||
case SENTRY_USER_CONSENT_UNKNOWN:
|
||||
default:
|
||||
return Consent::Unknown;
|
||||
}
|
||||
#else
|
||||
return Consent::Unavailable;
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_consent(bool enabled) {
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
if (!g_sentryInitialized) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
sentry_user_consent_give();
|
||||
} else {
|
||||
sentry_user_consent_revoke();
|
||||
}
|
||||
#else
|
||||
(void)enabled;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace dusk::crash_reporting
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
#include "imgui.h"
|
||||
|
||||
#include "ImGuiMenuTools.hpp"
|
||||
#include "d/actor/d_a_alink.h"
|
||||
#include "d/d_com_inf_game.h"
|
||||
#include "f_op/f_op_actor_mng.h"
|
||||
#include "SSystem/SComponent/c_sxyz.h"
|
||||
#include "SSystem/SComponent/c_xyz.h"
|
||||
|
||||
namespace dusk {
|
||||
namespace {
|
||||
|
||||
struct ActorSpawnerState {
|
||||
int actorId = 0;
|
||||
int params = -1;
|
||||
int argument = -1;
|
||||
int angleX = 0;
|
||||
int angleY = 0;
|
||||
int angleZ = 0;
|
||||
float scaleX = 1.0f;
|
||||
float scaleY = 1.0f;
|
||||
float scaleZ = 1.0f;
|
||||
bool usePlayerRoom = true;
|
||||
int manualRoom = 0;
|
||||
int spawnCount = 1;
|
||||
bool hasResult = false;
|
||||
unsigned int lastResult = 0;
|
||||
int lastAttempted = 0;
|
||||
};
|
||||
|
||||
ActorSpawnerState s_state;
|
||||
|
||||
} // namespace
|
||||
|
||||
void ImGuiMenuTools::ShowActorSpawner() {
|
||||
if (!m_showActorSpawner) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!ImGui::Begin("Actor Spawner", &m_showActorSpawner)) {
|
||||
ImGui::End();
|
||||
return;
|
||||
}
|
||||
|
||||
daAlink_c* player = (daAlink_c*)dComIfGp_getPlayer(0);
|
||||
|
||||
ImGui::SeparatorText("Actor");
|
||||
ImGui::InputInt("Actor ID", &s_state.actorId);
|
||||
ImGui::InputInt("Params (hex)", &s_state.params, 0, 0, ImGuiInputTextFlags_CharsHexadecimal);
|
||||
ImGui::InputInt("Argument", &s_state.argument);
|
||||
s_state.argument = (s_state.argument < -128) ? -128 : (s_state.argument > 127) ? 127 : s_state.argument;
|
||||
|
||||
ImGui::SeparatorText("Angle");
|
||||
ImGui::InputInt("Angle X", &s_state.angleX);
|
||||
ImGui::InputInt("Angle Y", &s_state.angleY);
|
||||
ImGui::InputInt("Angle Z", &s_state.angleZ);
|
||||
|
||||
ImGui::SeparatorText("Scale");
|
||||
ImGui::InputFloat("Scale X", &s_state.scaleX, 0.1f, 1.0f);
|
||||
ImGui::InputFloat("Scale Y", &s_state.scaleY, 0.1f, 1.0f);
|
||||
ImGui::InputFloat("Scale Z", &s_state.scaleZ, 0.1f, 1.0f);
|
||||
|
||||
ImGui::SeparatorText("Spawn");
|
||||
ImGui::InputInt("Count", &s_state.spawnCount);
|
||||
if (s_state.spawnCount < 1) {
|
||||
s_state.spawnCount = 1;
|
||||
}
|
||||
|
||||
ImGui::SeparatorText("Position");
|
||||
ImGui::Checkbox("Use player room", &s_state.usePlayerRoom);
|
||||
if (!s_state.usePlayerRoom) {
|
||||
ImGui::InputInt("Room No", &s_state.manualRoom);
|
||||
}
|
||||
|
||||
if (player != nullptr) {
|
||||
ImGui::Text("Spawn pos: %.2f, %.2f, %.2f",
|
||||
player->current.pos.x, player->current.pos.y, player->current.pos.z);
|
||||
} else {
|
||||
ImGui::TextDisabled("Player not available");
|
||||
}
|
||||
|
||||
ImGui::Separator();
|
||||
|
||||
bool canSpawn = player != nullptr;
|
||||
if (!canSpawn) {
|
||||
ImGui::BeginDisabled();
|
||||
}
|
||||
|
||||
if (ImGui::Button("Spawn", ImVec2(-1, 0))) {
|
||||
cXyz pos = player->current.pos;
|
||||
csXyz angle;
|
||||
angle.set((s16)s_state.angleX, (s16)s_state.angleY, (s16)s_state.angleZ);
|
||||
cXyz scale(s_state.scaleX, s_state.scaleY, s_state.scaleZ);
|
||||
int roomNo = s_state.usePlayerRoom ? player->current.roomNo : s_state.manualRoom;
|
||||
|
||||
layer_class* savedLayer = fpcLy_CurrentLayer();
|
||||
base_process_class* playScene = fpcM_SearchByName(fpcNm_PLAY_SCENE_e);
|
||||
if (playScene != nullptr) {
|
||||
fpcLy_SetCurrentLayer(&((process_node_class*)playScene)->layer);
|
||||
}
|
||||
|
||||
s_state.lastResult = 0;
|
||||
s_state.lastAttempted = s_state.spawnCount;
|
||||
for (int i = 0; i < s_state.spawnCount; ++i) {
|
||||
unsigned int result = fopAcM_create(
|
||||
(s16)s_state.actorId,
|
||||
(u32)s_state.params,
|
||||
&pos,
|
||||
roomNo,
|
||||
&angle,
|
||||
&scale,
|
||||
(s8)s_state.argument
|
||||
);
|
||||
if (result != 0) {
|
||||
s_state.lastResult = result;
|
||||
}
|
||||
}
|
||||
s_state.hasResult = true;
|
||||
|
||||
fpcLy_SetCurrentLayer(savedLayer);
|
||||
}
|
||||
|
||||
if (!canSpawn) {
|
||||
ImGui::EndDisabled();
|
||||
}
|
||||
|
||||
if (s_state.hasResult) {
|
||||
if (s_state.lastResult != 0) {
|
||||
if (s_state.lastAttempted == 1) {
|
||||
ImGui::Text("Spawned: proc ID %u", s_state.lastResult);
|
||||
} else {
|
||||
ImGui::Text("Spawned %d (last proc ID %u)", s_state.lastAttempted, s_state.lastResult);
|
||||
}
|
||||
} else {
|
||||
ImGui::TextColored(ImVec4(1, 0.4f, 0.4f, 1), "Spawn failed (returned 0)");
|
||||
}
|
||||
}
|
||||
|
||||
ImGui::End();
|
||||
}
|
||||
|
||||
} // namespace dusk
|
||||
@@ -376,6 +376,7 @@ namespace dusk {
|
||||
m_menuTools.ShowAudioDebug();
|
||||
m_menuTools.ShowSaveEditor();
|
||||
m_menuTools.ShowStateShare();
|
||||
m_menuTools.ShowActorSpawner();
|
||||
}
|
||||
m_menuRandomizer.windowRandoStats();
|
||||
m_menuRandomizer.windowRandoGeneration();
|
||||
|
||||
@@ -107,6 +107,7 @@ namespace dusk {
|
||||
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
|
||||
ImGui::MenuItem("Bloom", nullptr, &m_showBloomWindow);
|
||||
ImGui::MenuItem("Stub Log", nullptr, &m_showStubLog);
|
||||
ImGui::MenuItem("Actor Spawner", nullptr, &m_showActorSpawner);
|
||||
|
||||
if (!dusk::IsGameLaunched) {
|
||||
ImGui::EndDisabled();
|
||||
|
||||
@@ -28,6 +28,7 @@ namespace dusk {
|
||||
void ShowSaveEditor();
|
||||
void ShowStateShare();
|
||||
void ShowInputViewer();
|
||||
void ShowActorSpawner();
|
||||
|
||||
private:
|
||||
bool m_showDebugOverlay = false;
|
||||
@@ -70,6 +71,7 @@ namespace dusk {
|
||||
|
||||
bool m_showInputViewer = false;
|
||||
bool m_showInputViewerGyro = false;
|
||||
bool m_showActorSpawner = false;
|
||||
int m_inputOverlayCorner = 3;
|
||||
std::string m_controllerName;
|
||||
};
|
||||
|
||||
@@ -81,6 +81,8 @@ UserSettings g_userSettings = {
|
||||
.freeCamera {"game.freeCamera", false},
|
||||
.invertCameraXAxis {"game.invertCameraXAxis", false},
|
||||
.invertCameraYAxis {"game.invertCameraYAxis", false},
|
||||
.invertFirstPersonXAxis {"game.invertFirstPersonXAxis", false},
|
||||
.invertFirstPersonYAxis {"game.invertFirstPersonYAxis", false},
|
||||
.freeCameraSensitivity {"game.freeCameraSensitivity", 1.0f},
|
||||
.debugFlyCam {"game.debugFlyCam", false},
|
||||
.debugFlyCamLockEvents {"game.debugFlyCamLockEvents", true},
|
||||
@@ -122,7 +124,6 @@ UserSettings g_userSettings = {
|
||||
.skipPreLaunchUI {"backend.skipPreLaunchUI", false},
|
||||
.showPipelineCompilation {"backend.showPipelineCompilation", false},
|
||||
.wasPresetChosen {"backend.wasPresetChosen", false},
|
||||
.enableCrashReporting {"backend.enableCrashReporting", true},
|
||||
.checkForUpdates {"backend.checkForUpdates", true},
|
||||
.cardFileType {"backend.cardFileType", static_cast<int>(CARD_GCIFOLDER)},
|
||||
.enableAdvancedSettings {"backend.enableAdvancedSettings", false},
|
||||
@@ -172,6 +173,8 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.enableMirrorMode);
|
||||
Register(g_userSettings.game.invertCameraXAxis);
|
||||
Register(g_userSettings.game.invertCameraYAxis);
|
||||
Register(g_userSettings.game.invertFirstPersonXAxis);
|
||||
Register(g_userSettings.game.invertFirstPersonYAxis);
|
||||
Register(g_userSettings.game.freeCameraSensitivity);
|
||||
Register(g_userSettings.game.minimalHUD);
|
||||
Register(g_userSettings.game.pauseOnFocusLost);
|
||||
@@ -231,7 +234,6 @@ void registerSettings() {
|
||||
Register(g_userSettings.backend.skipPreLaunchUI);
|
||||
Register(g_userSettings.backend.showPipelineCompilation);
|
||||
Register(g_userSettings.backend.wasPresetChosen);
|
||||
Register(g_userSettings.backend.enableCrashReporting);
|
||||
Register(g_userSettings.backend.checkForUpdates);
|
||||
Register(g_userSettings.backend.cardFileType);
|
||||
Register(g_userSettings.backend.enableAdvancedSettings);
|
||||
|
||||
@@ -208,7 +208,15 @@ bool input_neutral(int port) {
|
||||
bool keyboard_escape_pressed() {
|
||||
int keyCount = 0;
|
||||
const bool* keys = SDL_GetKeyboardState(&keyCount);
|
||||
return keys != nullptr && SDL_SCANCODE_ESCAPE < keyCount && keys[SDL_SCANCODE_ESCAPE];
|
||||
if (keys == nullptr || SDL_SCANCODE_ESCAPE >= keyCount || !keys[SDL_SCANCODE_ESCAPE]) {
|
||||
return false;
|
||||
}
|
||||
for (int i = 0; i < keyCount; ++i) {
|
||||
if (i != SDL_SCANCODE_ESCAPE && keys[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Rml::String keyboard_key_name(s32 scancode) {
|
||||
|
||||
@@ -33,6 +33,7 @@ void applyPresetDusk() {
|
||||
s.game.fastTears.setValue(true);
|
||||
s.game.biggerWallets.setValue(true);
|
||||
s.game.invertCameraXAxis.setValue(true);
|
||||
s.game.invertFirstPersonYAxis.setValue(true);
|
||||
s.game.no2ndFishForCat.setValue(true);
|
||||
s.game.enableAchievementToasts.setValue(true);
|
||||
s.game.enableControllerToasts.setValue(true);
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
|
||||
#include "reporting.hpp"
|
||||
|
||||
#include "button.hpp"
|
||||
#include "dusk/crash_reporting.h"
|
||||
#include "ui.hpp"
|
||||
|
||||
#include <dolphin/gx/GXAurora.h>
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
CrashReportWindow::CrashReportWindow() : WindowSmall("modal", "modal-dialog") {
|
||||
mDialog->SetClass("modal-dialog", true);
|
||||
|
||||
auto* header = append(mDialog, "div");
|
||||
header->SetClass("modal-header", true);
|
||||
|
||||
auto* title = append(header, "div");
|
||||
title->SetClass("modal-title", true);
|
||||
title->SetInnerRML("Send Crash Reports");
|
||||
|
||||
auto* headIcon = append(header, "icon");
|
||||
headIcon->SetClass("question-mark", true);
|
||||
|
||||
auto* intro = append(mDialog, "div");
|
||||
intro->SetClass("modal-body", true);
|
||||
intro->SetInnerRML(
|
||||
"Dusk can automatically send crash reports to the developers. Crash reports contain the "
|
||||
"following:"
|
||||
"<br/>• Operating system version<br/>• CPU architecture<br/>• GPU model & driver version"
|
||||
"<br/>• File paths (may include account username)<br/>• Stack trace<br/><br/>"
|
||||
"This can be changed in the Settings menu at any time.");
|
||||
|
||||
auto* grid = append(mDialog, "div");
|
||||
grid->SetClass("preset-grid", true);
|
||||
|
||||
struct OptionInfo {
|
||||
const char* name;
|
||||
const char* desc;
|
||||
void (*apply)();
|
||||
};
|
||||
|
||||
static constexpr OptionInfo kOptions[] = {
|
||||
{"Enable",
|
||||
"Send crash reports to Dusk developers. Reports will include the information described "
|
||||
"above.",
|
||||
[] { crash_reporting::set_consent(true); }},
|
||||
{"Disable",
|
||||
"Do not send crash reports. This may make it more difficult to resolve issues you "
|
||||
"encounter.",
|
||||
[] { crash_reporting::set_consent(false); }},
|
||||
};
|
||||
|
||||
for (const auto& option : kOptions) {
|
||||
auto* col = append(grid, "div");
|
||||
col->SetClass("preset-col", true);
|
||||
|
||||
auto btn = std::make_unique<Button>(col, Rml::String(option.name));
|
||||
btn->on_nav_command([this, apply = option.apply](Rml::Event&, NavCommand cmd) {
|
||||
if (cmd == NavCommand::Confirm) {
|
||||
apply();
|
||||
hide(true);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
mButtons.push_back(std::move(btn));
|
||||
|
||||
auto* desc = append(col, "div");
|
||||
desc->SetClass("preset-desc", true);
|
||||
desc->SetInnerRML(option.desc);
|
||||
}
|
||||
}
|
||||
|
||||
bool CrashReportWindow::focus() {
|
||||
if (!mButtons.empty()) {
|
||||
return mButtons.back()->focus();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CrashReportWindow::handle_nav_command(Rml::Event& event, NavCommand cmd) {
|
||||
if (cmd == NavCommand::Cancel || cmd == NavCommand::Menu) {
|
||||
return true;
|
||||
}
|
||||
int direction = 0;
|
||||
if (cmd == NavCommand::Left) {
|
||||
direction = -1;
|
||||
} else if (cmd == NavCommand::Right) {
|
||||
direction = 1;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
auto* target = event.GetTargetElement();
|
||||
for (int i = 0; i < static_cast<int>(mButtons.size()); ++i) {
|
||||
if (mButtons[i]->contains(target)) {
|
||||
const int next = i + direction;
|
||||
if (next >= 0 && next < static_cast<int>(mButtons.size())) {
|
||||
if (mButtons[next]->focus()) {
|
||||
mDoAud_seStartMenu(kSoundItemFocus);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace dusk::ui
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
|
||||
#include "component.hpp"
|
||||
#include "window.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace dusk::ui {
|
||||
|
||||
class CrashReportWindow : public WindowSmall {
|
||||
public:
|
||||
CrashReportWindow();
|
||||
|
||||
bool focus() override;
|
||||
|
||||
protected:
|
||||
bool handle_nav_command(Rml::Event& event, NavCommand cmd) override;
|
||||
|
||||
private:
|
||||
std::vector<std::unique_ptr<Component>> mButtons;
|
||||
};
|
||||
|
||||
} // namespace dusk::ui
|
||||
|
||||
#endif
|
||||
+26
-10
@@ -19,6 +19,10 @@
|
||||
#include "prelaunch.hpp"
|
||||
#include "ui.hpp"
|
||||
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
#include "dusk/crash_reporting.h"
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace dusk::ui {
|
||||
@@ -641,6 +645,10 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
config_percent_select(leftPane, rightPane, getSettings().game.freeCameraSensitivity,
|
||||
"Free Camera Sensitivity", "Adjusts twin-stick camera sensitivity.", 50, 200, 5,
|
||||
[] { return !getSettings().game.freeCamera; });
|
||||
addOption("Invert First Person X Axis", getSettings().game.invertFirstPersonXAxis,
|
||||
"Invert horizontal movement while aiming with items or first person camera. Applies to both stick and gyro aiming.");
|
||||
addOption("Invert First Person Y Axis", getSettings().game.invertFirstPersonYAxis,
|
||||
"Invert vertical movement while aiming with items or first person camera. Applies to both stick and gyro aiming.");
|
||||
|
||||
leftPane.add_section("Gyro");
|
||||
leftPane.register_control(
|
||||
@@ -1024,16 +1032,24 @@ SettingsWindow::SettingsWindow(bool prelaunch) : mPrelaunch(prelaunch) {
|
||||
pane.add_rml("<br/>Choose which notifications can be displayed.");
|
||||
});
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
config_bool_select(leftPane, rightPane, getSettings().backend.enableCrashReporting,
|
||||
{.key = "Crash Reporting",
|
||||
.helpText = "Enable automatic reporting of crashes to the developers.<br/><br/>"
|
||||
"Submissions include logs which may contain sensitive information. "
|
||||
"Refrain from "
|
||||
"enabling reporting if you do not agree with the following "
|
||||
"inclusions:<br/><br/> "
|
||||
"- Operating System<br/>- CPU Architecture<br/>- GPU Model & Driver "
|
||||
"Version<br/>"
|
||||
"- Account Username"});
|
||||
auto& crashReporting = leftPane.add_child<BoolButton>(BoolButton::Props{
|
||||
.key = "Crash Reporting",
|
||||
.getValue =
|
||||
[] { return crash_reporting::get_consent() == crash_reporting::Consent::Given; },
|
||||
.setValue = [](bool enabled) { crash_reporting::set_consent(enabled); },
|
||||
.isDisabled =
|
||||
[] {
|
||||
return crash_reporting::get_consent() == crash_reporting::Consent::Unavailable;
|
||||
},
|
||||
.isModified = [] { return false; },
|
||||
});
|
||||
leftPane.register_control(crashReporting, rightPane, [](Pane& pane) {
|
||||
pane.clear();
|
||||
pane.add_rml("Dusk can automatically send crash reports to the developers. Crash "
|
||||
"reports contain the following:<br/>• Operating system version<br/>• CPU "
|
||||
"architecture<br/>• GPU model & driver version<br/>• File paths (may "
|
||||
"include account username)<br/>• Stack trace");
|
||||
});
|
||||
#endif
|
||||
config_bool_select(leftPane, rightPane, getSettings().backend.skipPreLaunchUI,
|
||||
{
|
||||
|
||||
+14
-4
@@ -90,6 +90,10 @@
|
||||
#include <TargetConditionals.h>
|
||||
#endif
|
||||
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
#include "dusk/ui/reporting.hpp"
|
||||
#endif
|
||||
|
||||
#if RANDOMIZER_ONLY
|
||||
#include "dusk/randomizer/generator/randomizer.hpp"
|
||||
#include "dusk/randomizer/generator/test/test.hpp"
|
||||
@@ -709,7 +713,7 @@ int game_main(int argc, char* argv[]) {
|
||||
|
||||
dusk::config::LoadFromUserPreferences();
|
||||
ApplyCVarOverrides(parsed_arg_options["cvar"]);
|
||||
dusk::InitializeCrashReporting();
|
||||
dusk::crash_reporting::initialize();
|
||||
EnsureInitialPipelineCache(dusk::ConfigPath);
|
||||
// TODO: How to handle this?
|
||||
//PADSetDefaultMapping(&defaultPadMapping, PAD_TYPE_STANDARD);
|
||||
@@ -763,7 +767,7 @@ int game_main(int argc, char* argv[]) {
|
||||
// Run ImGui UI loop if Aurora couldn't initialize a backend
|
||||
if (auroraInfo.backend == BACKEND_NULL) {
|
||||
launchUILoop();
|
||||
dusk::ShutdownCrashReporting();
|
||||
dusk::crash_reporting::shutdown();
|
||||
dusk::ShutdownFileLogging();
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
@@ -841,7 +845,7 @@ int game_main(int argc, char* argv[]) {
|
||||
|
||||
// pre game launch ui main loop
|
||||
if (!launchUILoop()) {
|
||||
dusk::ShutdownCrashReporting();
|
||||
dusk::crash_reporting::shutdown();
|
||||
dusk::ShutdownFileLogging();
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
@@ -872,6 +876,12 @@ int game_main(int argc, char* argv[]) {
|
||||
dusk::IsGameLaunched = true;
|
||||
}
|
||||
|
||||
#if DUSK_ENABLE_SENTRY_NATIVE
|
||||
if (dusk::crash_reporting::get_consent() == dusk::crash_reporting::Consent::Unknown) {
|
||||
dusk::ui::push_document(std::make_unique<dusk::ui::CrashReportWindow>());
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!dusk::getSettings().backend.wasPresetChosen) {
|
||||
dusk::ui::push_document(std::make_unique<dusk::ui::PresetWindow>());
|
||||
}
|
||||
@@ -903,7 +913,7 @@ int game_main(int argc, char* argv[]) {
|
||||
|
||||
dusk::MoviePlayerShutdown();
|
||||
|
||||
dusk::ShutdownCrashReporting();
|
||||
dusk::crash_reporting::shutdown();
|
||||
dusk::ShutdownFileLogging();
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
|
||||
Reference in New Issue
Block a user