Merge remote-tracking branch 'origin/main' into 26-04-04-config

This commit is contained in:
PJB3005
2026-04-05 00:12:17 +02:00
50 changed files with 1094 additions and 364 deletions
+4
View File
@@ -43,3 +43,7 @@ compile_commands.json
# ISOs
*.iso
*.ini
*.controller
pipeline_cache.bin
+7
View File
@@ -140,6 +140,13 @@ target_compile_definitions(dusk PRIVATE TARGET_PC AVOID_UB=1 VERSION=0)
target_include_directories(dusk PRIVATE include)
target_link_libraries(dusk PRIVATE game aurora::main)
add_custom_command(TARGET dusk POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_SOURCE_DIR}/res"
"$<TARGET_FILE_DIR:dusk>/res"
COMMENT "Copying resources"
)
include(extern/aurora/cmake/AuroraCopyRuntimeDLLs.cmake)
aurora_copy_runtime_dlls(dusk game)
+1 -1
+3 -1
View File
@@ -1333,7 +1333,6 @@ set(DOLPHIN_FILES
set(DUSK_FILES
include/dusk/endian_gx.hpp
include/dusk/config.hpp
include/dusk/settings.hpp
src/d/actor/d_a_alink_dusk.cpp
src/dusk/asserts.cpp
src/dusk/config.cpp
@@ -1346,10 +1345,13 @@ set(DUSK_FILES
src/dusk/extras.cpp
src/dusk/io.cpp
src/dusk/globals.cpp
src/dusk/settings.cpp
#src/dusk/m_Do_ext_dusk.cpp
src/dusk/imgui/ImGuiConfig.hpp
src/dusk/imgui/ImGuiConsole.hpp
src/dusk/imgui/ImGuiConsole.cpp
src/dusk/imgui/ImGuiEngine.cpp
src/dusk/imgui/ImGuiEngine.hpp
src/dusk/imgui/ImGuiMenuGame.cpp
src/dusk/imgui/ImGuiMenuGame.hpp
src/dusk/imgui/ImGuiMenuTools.cpp
+4
View File
@@ -48,6 +48,7 @@ public:
void FileSelectClose();
void brightCheckOpen();
void brightCheck();
void doPreLoadSetup();
void changeGameScene();
#if VERSION == VERSION_GCN_PAL
@@ -70,6 +71,9 @@ private:
/* 0x41E */ u8 mWaitTimer;
/* 0x41F */ u8 field_0x41f;
/* 0x420 */ u8 field_0x420;
#if TARGET_PC
bool mShowTvSettingsScreen;
#endif
};
#endif /* D_S_D_S_NAME_H */
+19
View File
@@ -0,0 +1,19 @@
#ifndef DUSK_HOTKEYS_H
#define DUSK_HOTKEYS_H
namespace dusk::hotkeys {
constexpr const char* DO_RESET = "Ctrl+R";
constexpr const char* TOGGLE_FULLSCREEN = "F11";
constexpr const char* SHOW_PROCESS_MANAGEMENT = "F2";
constexpr const char* SHOW_DEBUG_OVERLAY = "F3";
constexpr const char* SHOW_HEAP_VIEWER = "F4";
constexpr const char* SHOW_STUB_LOG = "F5";
constexpr const char* SHOW_CAMERA_DEBUG = "F6";
constexpr const char* SHOW_AUDIO_DEBUG = "F7";
}
#endif // DUSK_HOTKEYS_H
+78
View File
@@ -0,0 +1,78 @@
#ifndef DUSK_CONFIG_H
#define DUSK_CONFIG_H
#include "config_var.hpp"
namespace dusk::settings {
using namespace config;
// Persistent user settings
namespace video {
extern ConfigVar<bool> enableFullscreen;
}
namespace audio {
extern ConfigVar<float> masterVolume;
extern ConfigVar<float> mainMusicVolume;
extern ConfigVar<float> subMusicVolume;
extern ConfigVar<float> soundEffectsVolume;
extern ConfigVar<float> fanfareVolume;
}
namespace game {
// QoL
extern ConfigVar<bool> enableQuickTransform;
extern ConfigVar<bool> hideTvSettingsScreen;
extern ConfigVar<bool> biggerWallets;
extern ConfigVar<bool> noReturnRupees;
extern ConfigVar<bool> disableRupeeCutscenes;
extern ConfigVar<bool> noSwordRecoil;
extern ConfigVar<int> damageMultiplier;
extern ConfigVar<bool> instantDeath;
extern ConfigVar<bool> fastClimbing;
extern ConfigVar<bool> fastTears;
// Preferences
extern ConfigVar<bool> enableMirrorMode;
extern ConfigVar<bool> invertCameraXAxis;
// Graphics
extern ConfigVar<bool> enableBloom;
extern ConfigVar<bool> useWaterProjectionOffset;
// Cheats
extern ConfigVar<bool> enableFastIronBoots;
// Technical
extern ConfigVar<bool> restoreWiiGlitches;
}
void Register();
}
namespace dusk {
// Transient settings
struct CollisionViewSettings {
bool enableTerrainView;
bool enableWireframe;
bool enableAtView;
bool enableTgView;
bool enableCoView;
float terrainViewOpacity;
float colliderViewOpacity;
float drawRange;
};
struct TransientSettings {
CollisionViewSettings collisionView;
};
TransientSettings& getTransientSettings();
}
#endif // DUSK_CONFIG_H
-24
View File
@@ -1,24 +0,0 @@
#ifndef DUSK_SETTINGS_HPP
#define DUSK_SETTINGS_HPP
#include "config_var.hpp"
namespace dusk::settings {
using namespace dusk::config;
namespace enhancements {
extern ConfigVar<bool> FastIronBoots;
extern ConfigVar<bool> InvertCameraXAxis;
extern ConfigVar<bool> QuickTransform;
extern ConfigVar<bool> RestoreWiiGlitches;
extern ConfigVar<bool> EnableBloom;
extern ConfigVar<bool> UseWaterProjectionOffset;
extern ConfigVar<bool> MirrorMode;
void Register();
}
void Register();
}
#endif // DUSK_SETTINGS_HPP
+3 -5
View File
@@ -3,9 +3,7 @@
#include "JSystem/JUtility/JUTGamePad.h"
#include "SSystem/SComponent/c_API_controller_pad.h"
#include "dusk/settings.hpp"
#include "dusk/imgui/ImGuiMenuEnhancements.hpp"
#include "dusk/settings.h"
// Controller Ports 1 - 4
enum { PAD_1, PAD_2, PAD_3, PAD_4 };
@@ -58,7 +56,7 @@ public:
static s16 getStickAngle3D(u32 pad) {
#if TARGET_PC
if (dusk::settings::enhancements::MirrorMode.getValue()) {
if (dusk::settings::game::enableMirrorMode) {
return -getCpadInfo(pad).mMainStickAngle;
} else {
return getCpadInfo(pad).mMainStickAngle;
@@ -70,7 +68,7 @@ public:
static f32 getSubStickX3D(u32 pad) {
#if TARGET_PC
if (dusk::settings::enhancements::MirrorMode.getValue()) {
if (dusk::settings::game::enableMirrorMode) {
return -getCpadInfo(pad).mCStickPosX;
} else {
return getCpadInfo(pad).mCStickPosX;
@@ -82,7 +82,7 @@ public:
/* 0x00 */ u16 mMaterialNum;
/* 0x04 */ J3DMaterialInitData_v21* mpMaterialInitData;
/* 0x08 */ u16* mpMaterialID;
/* 0x08 */ BE(u16)* mpMaterialID;
/* 0x0C */ GXColor* mpMatColor;
/* 0x10 */ u8* mpColorChanNum;
/* 0x14 */ J3DColorChanInfo* mpColorChanInfo;
@@ -91,10 +91,10 @@ public:
/* 0x20 */ J3DTexCoord2Info* mpTexCoord2Info;
/* 0x24 */ J3DTexMtxInfo* mpTexMtxInfo;
/* 0x28 */ J3DTexMtxInfo* field_0x28;
/* 0x2C */ u16* mpTexNo;
/* 0x30 */ GXCullMode* mpCullMode;
/* 0x2C */ BE(u16)* mpTexNo;
/* 0x30 */ BE(GXCullMode)* mpCullMode;
/* 0x34 */ J3DTevOrderInfo* mpTevOrderInfo;
/* 0x38 */ GXColorS10* mpTevColor;
/* 0x38 */ BE(GXColorS10)* mpTevColor;
/* 0x3C */ GXColor* mpTevKColor;
/* 0x40 */ u8* mpTevStageNum;
/* 0x44 */ J3DTevStageInfo* mpTevStageInfo;
@@ -10,7 +10,7 @@
*/
struct JAUAudibleParam {
f32 getDopplerPower() const {
return (u32)((*(u8*)&field_0x0.raw >> 4) & 0xf) * (1.0f / 15.0f);
return field_0x0.bytes.b0_0 * (1.0f / 15.0f);
}
union {
@@ -10,8 +10,8 @@
J3DMaterialFactory_v21::J3DMaterialFactory_v21(J3DMaterialBlock_v21 const& i_block) {
mMaterialNum = i_block.mMaterialNum;
mpMaterialInitData = JSUConvertOffsetToPtr<J3DMaterialInitData_v21>(&i_block, i_block.mpMaterialInitData);
mpMaterialID = JSUConvertOffsetToPtr<u16>(&i_block, i_block.mpMaterialID);
mpCullMode = JSUConvertOffsetToPtr<GXCullMode>(&i_block, i_block.mpCullMode);
mpMaterialID = JSUConvertOffsetToPtr<BE(u16)>(&i_block, i_block.mpMaterialID);
mpCullMode = JSUConvertOffsetToPtr<BE(GXCullMode)>(&i_block, i_block.mpCullMode);
mpMatColor = JSUConvertOffsetToPtr<GXColor>(&i_block, i_block.mpMatColor);
mpColorChanNum = JSUConvertOffsetToPtr<u8>(&i_block, i_block.mpColorChanNum);
mpColorChanInfo = JSUConvertOffsetToPtr<J3DColorChanInfo>(&i_block, i_block.mpColorChanInfo);
@@ -20,9 +20,9 @@ J3DMaterialFactory_v21::J3DMaterialFactory_v21(J3DMaterialBlock_v21 const& i_blo
mpTexCoord2Info = JSUConvertOffsetToPtr<J3DTexCoord2Info>(&i_block, i_block.mpTexCoord2Info);
mpTexMtxInfo = JSUConvertOffsetToPtr<J3DTexMtxInfo>(&i_block, i_block.mpTexMtxInfo);
field_0x28 = JSUConvertOffsetToPtr<J3DTexMtxInfo>(&i_block, i_block.field_0x38);
mpTexNo = JSUConvertOffsetToPtr<u16>(&i_block, i_block.mpTexNo);
mpTexNo = JSUConvertOffsetToPtr<BE(u16)>(&i_block, i_block.mpTexNo);
mpTevOrderInfo = JSUConvertOffsetToPtr<J3DTevOrderInfo>(&i_block, i_block.mpTevOrderInfo);
mpTevColor = JSUConvertOffsetToPtr<GXColorS10>(&i_block, i_block.mpTevColor);
mpTevColor = JSUConvertOffsetToPtr<BE(GXColorS10)>(&i_block, i_block.mpTevColor);
mpTevKColor = JSUConvertOffsetToPtr<GXColor>(&i_block, i_block.mpTevKColor);
mpTevStageNum = JSUConvertOffsetToPtr<u8>(&i_block, i_block.mpTevStageNum);
mpTevStageInfo = JSUConvertOffsetToPtr<J3DTevStageInfo>(&i_block, i_block.mpTevStageInfo);
@@ -260,7 +260,7 @@ J3DGXColorS10 J3DMaterialFactory_v21::newTevColor(int i_idx, int i_no) const {
J3DGXColorS10 dflt = defaultTevColor;
J3DMaterialInitData_v21* mtl_init_data = &mpMaterialInitData[mpMaterialID[i_idx]];
if (mtl_init_data->mTevColorIdx[i_no] != 0xffff) {
return mpTevColor[mtl_init_data->mTevColorIdx[i_no]];
return (GXColorS10)mpTevColor[mtl_init_data->mTevColorIdx[i_no]];
} else {
return dflt;
}
Binary file not shown.
+1 -1
View File
@@ -802,7 +802,7 @@ f32 Z2Audience::calcFxMix_(f32 param_0, int distVolBit) const {
f32 Z2Audience::calcPitch_(Z2AudibleChannel* channel, const Z2Audible* audible, const Z2AudioCamera* camera) const {
JAUAudibleParam audParam = *audible->getAudibleParam();
if ((*(u8*)&audParam.field_0x0.raw >> 4) & 0xf) {
if (audParam.field_0x0.bytes.b0_0) {
JGeometry::TVec3<f32> aTStack_4c;
aTStack_4c.normalize(channel->field_0x14.field_0x00);
JAUAudibleParam audParam = *audible->getAudibleParam();
+3 -5
View File
@@ -54,8 +54,6 @@
#include "res/Object/Alink.h"
#include <cstring>
#include "dusk/settings.hpp"
static int daAlink_Create(fopAc_ac_c* i_this);
static int daAlink_Delete(daAlink_c* i_this);
static int daAlink_Execute(daAlink_c* i_this);
@@ -7512,7 +7510,7 @@ void daAlink_c::setBlendMoveAnime(f32 i_morf) {
BOOL sp24 = checkEventRun();
BOOL sp20 = checkBootsMoveAnime(1);
#if TARGET_PC
if (dusk::settings::enhancements::FastIronBoots.getValue()) {
if (dusk::settings::game::enableFastIronBoots) {
sp20 = FALSE;
}
#endif
@@ -9477,7 +9475,7 @@ void daAlink_c::setStickData() {
mHeavySpeedMultiplier = mpHIO->mItem.mIronBoots.m.mInputFactor;
}
#if TARGET_PC
if (dusk::settings::enhancements::FastIronBoots.getValue()) {
if (dusk::settings::game::enableFastIronBoots) {
mHeavySpeedMultiplier = 1.0f;
}
#endif
@@ -9489,7 +9487,7 @@ void daAlink_c::setStickData() {
mHeavySpeedMultiplier = mpHIO->mItem.mIronBoots.m.mWaterInputFactor;
}
#if TARGET_PC
if (dusk::settings::enhancements::FastIronBoots.getValue()) {
if (dusk::settings::game::enableFastIronBoots) {
mHeavySpeedMultiplier = 1.0f;
}
#endif
+8
View File
@@ -7,6 +7,8 @@
#include "d/actor/d_a_b_gnd.h"
#include "SSystem/SComponent/c_math.h"
#include "dusk/settings.h"
enum daAlink_CutNmParamType {
CUT_NM_PARAM_VERTICAL,
CUT_NM_PARAM_LEFT,
@@ -369,6 +371,12 @@ BOOL daAlink_c::changeCutReverseProc(daAlink_c::daAlink_ANM i_anmID) {
return procCutReverseInit(i_anmID);
}
#if TARGET_PC
if (dusk::settings::game::noSwordRecoil) {
return FALSE;
}
#endif
if (checkNoResetFlg0(FLG0_CUT_AT_FLG) || mEquipItem == dItemNo_COPY_ROD_e) {
cXyz sp28;
Vec sp1C;
+7
View File
@@ -152,6 +152,13 @@ f32 daAlink_c::damageMagnification(BOOL i_checkZoraMag, int param_1) {
base_mag = 1.0f;
}
#if TARGET_PC
base_mag *= dusk::settings::game::damageMultiplier;
if (dusk::settings::game::instantDeath) {
base_mag = 9999.0f;
}
#endif
if (checkWolf() && !checkCargoCarry() && param_1 == 0) {
return 2.0f * base_mag;
}
+9 -3
View File
@@ -23,7 +23,7 @@
#include "d/actor/d_a_npc_tkc.h"
#include <cstring>
#include "dusk/imgui/ImGuiMenuEnhancements.hpp"
#include "dusk/settings.h"
BOOL daAlink_c::checkEventRun() const {
return dComIfGp_event_runCheck() || checkPlayerDemoMode();
@@ -2232,6 +2232,12 @@ void daAlink_c::setGetSubBgm(int i_itemNo) {
}
BOOL daAlink_c::checkTreasureRupeeReturn(int i_itemNo) const {
#if TARGET_PC
if (dusk::settings::game::noReturnRupees) {
return FALSE;
}
#endif
static const int dummy = 0;
if (i_itemNo == dItemNo_LINKS_SAVINGS_e) {
@@ -4301,7 +4307,7 @@ bool daAlink_c::checkAcceptWarp() {
*/
if (mLinkAcch.ChkGroundHit() && !checkModeFlg(MODE_PLAYER_FLY)
#if TARGET_PC
&& (dusk::settings::enhancements::RestoreWiiGlitches.getValue() || !checkNoResetFlg0(FLG0_WATER_IN_MOVE))
&& (dusk::settings::game::restoreWiiGlitches || !checkNoResetFlg0(FLG0_WATER_IN_MOVE))
#elif VERSION != VERSION_WII_USA_R0
&& !checkNoResetFlg0(FLG0_WATER_IN_MOVE)
#endif
@@ -4312,7 +4318,7 @@ bool daAlink_c::checkAcceptWarp() {
*/
if (
#if TARGET_PC
(dusk::settings::enhancements::RestoreWiiGlitches.getValue() || !getSlidePolygon(&plane)) &&
(dusk::settings::game::restoreWiiGlitches || !getSlidePolygon(&plane)) &&
#elif VERSION != VERSION_WII_USA_R0
!getSlidePolygon(&plane) &&
#endif
+2 -3
View File
@@ -3,10 +3,9 @@
#include "d/d_meter2.h"
#include "d/d_meter2_draw.h"
#include "d/d_meter2_info.h"
#include "dusk/imgui/ImGuiMenuEnhancements.hpp"
void daAlink_c::handleQuickTransform() {
if (!dusk::settings::enhancements::QuickTransform.getValue()) {
if (!dusk::settings::game::enableQuickTransform) {
return;
}
@@ -70,4 +69,4 @@ void daAlink_c::handleQuickTransform() {
OSReport("Running quick transform!");
procCoMetamorphoseInit();
}
}
+57 -11
View File
@@ -13,8 +13,15 @@
#include "d/actor/d_a_obj_swhang.h"
f32 daAlink_c::getHangMoveAnmSpeed() {
#if TARGET_PC
return getAnmSpeedStickRate(
dusk::settings::game::fastClimbing ? 2.0f : mpHIO->mWallHang.mWallMove.m.mMinAnmSpeed,
dusk::settings::game::fastClimbing ? 2.0f : mpHIO->mWallHang.mWallMove.m.mMaxAnmSpeed
);
#else
return getAnmSpeedStickRate(mpHIO->mWallHang.mWallMove.m.mMinAnmSpeed,
mpHIO->mWallHang.mWallMove.m.mMaxAnmSpeed);
#endif
}
int daAlink_c::getHangDirectionFromAngle() {
@@ -1209,7 +1216,12 @@ void daAlink_c::setLadderPos(int param_0) {
f32 daAlink_c::getLadderMoveAnmSpeed() {
return getAnmSpeedStickRate(mpHIO->mLadder.m.mMoveMinASpeed,
mpHIO->mLadder.m.mMoveMaxSpeed);
#if TARGET_PC
dusk::settings::game::fastClimbing ? 1.575f : mpHIO->mLadder.m.mMoveMaxSpeed
#else
mpHIO->mLadder.m.mMoveMaxSpeed
#endif
);
}
int daAlink_c::changeLadderMoveProc(int param_0) {
@@ -1304,8 +1316,14 @@ int daAlink_c::procLadderUpStartInit() {
mNormalSpeed = 0.0f;
speedF = 0.0f;
setSingleAnimeBaseSpeed(ANM_LADDER_UP_START, mpHIO->mLadder.m.mClimbUpStartASpeed,
mpHIO->mLadder.m.mClimbUpStartInterp);
setSingleAnimeBaseSpeed(ANM_LADDER_UP_START,
#if TARGET_PC
dusk::settings::game::fastClimbing ? 1.8f : mpHIO->mLadder.m.mClimbUpStartASpeed,
#else
mpHIO->mLadder.m.mClimbUpStartASpeed,
#endif
mpHIO->mLadder.m.mClimbUpStartInterp);
field_0x2f99 = 0x10;
field_0x3588 = l_waitBaseAnime;
dComIfGp_setPlayerStatus0(0, 0x2000000);
@@ -1354,8 +1372,14 @@ int daAlink_c::procLadderUpEndInit(BOOL param_0) {
anm_id = ANM_LADDER_UP_END_RIGHT;
}
setSingleAnimeBaseSpeed(anm_id, mpHIO->mLadder.m.mClimbUpEndASpeed,
mpHIO->mLadder.m.mClimbUpEndInterp);
setSingleAnimeBaseSpeed(anm_id,
#if TARGET_PC
dusk::settings::game::fastClimbing ? 1.765f : mpHIO->mLadder.m.mClimbUpEndASpeed,
#else
mpHIO->mLadder.m.mClimbUpEndASpeed,
#endif
mpHIO->mLadder.m.mClimbUpEndInterp);
field_0x2f99 = 14;
setSpecialGravity(0.0f, maxFallSpeed, 0);
@@ -1413,8 +1437,14 @@ int daAlink_c::procLadderDownStartInit() {
shape_angle.y = field_0x306e + 0x8000;
current.angle.y = field_0x306e;
setSingleAnimeBaseSpeed(ANM_LADDER_DOWN_START, mpHIO->mLadder.m.mClimbDownStartASpeed,
mpHIO->mLadder.m.mClimbDownStartInterp);
setSingleAnimeBaseSpeed(ANM_LADDER_DOWN_START,
#if TARGET_PC
dusk::settings::game::fastClimbing ? 1.8f : mpHIO->mLadder.m.mClimbDownStartASpeed,
#else
mpHIO->mLadder.m.mClimbDownStartASpeed,
#endif
mpHIO->mLadder.m.mClimbDownStartInterp);
field_0x2f99 = 0x10;
field_0x3588 = l_waitBaseAnime;
dComIfGp_setPlayerStatus0(0, 0x2000000);
@@ -1469,8 +1499,14 @@ int daAlink_c::procLadderDownEndInit(BOOL param_0) {
anm_id = ANM_LADDER_DOWN_END_RIGHT;
}
setSingleAnimeBaseSpeed(anm_id, mpHIO->mLadder.m.mClimbDownEndASpeed,
mpHIO->mLadder.m.mClimbDownEndInterp);
setSingleAnimeBaseSpeed(anm_id,
#if TARGET_PC
dusk::settings::game::fastClimbing ? 1.8f : mpHIO->mLadder.m.mClimbDownEndASpeed,
#else
mpHIO->mLadder.m.mClimbDownEndASpeed,
#endif
mpHIO->mLadder.m.mClimbDownEndInterp);
field_0x2f99 = 14;
setSpecialGravity(0.0f, maxFallSpeed, 0);
@@ -1602,12 +1638,22 @@ int daAlink_c::procLadderMove() {
f32 daAlink_c::getClimbMoveUpDownAnmSpeed() {
return getAnmSpeedStickRate(mpHIO->mLadder.m.mWallVerticalMinAnmSpeed,
mpHIO->mLadder.m.mWallVerticalMaxAnmSpeed);
#if TARGET_PC
dusk::settings::game::fastClimbing ? 1.875f : mpHIO->mLadder.m.mWallVerticalMaxAnmSpeed
#else
mpHIO->mLadder.m.mWallVerticalMaxAnmSpeed
#endif
);
}
f32 daAlink_c::getClimbMoveSideAnmSpeed() {
return getAnmSpeedStickRate(mpHIO->mLadder.m.mWallHorizontalMinAnmSpeed,
mpHIO->mLadder.m.mWallHorizontalMaxAnmSpeed);
#if TARGET_PC
dusk::settings::game::fastClimbing ? 2.0f : mpHIO->mLadder.m.mWallHorizontalMaxAnmSpeed
#else
mpHIO->mLadder.m.mWallHorizontalMaxAnmSpeed
#endif
);
}
BOOL daAlink_c::checkClimbCode(cBgS_PolyInfo& i_polyinfo) {
+1 -3
View File
@@ -6,8 +6,6 @@
#include "d/actor/d_a_alink.h"
#include "d/actor/d_a_tag_magne.h"
#include "dusk/imgui/ImGuiMenuEnhancements.hpp"
void daAlink_c::concatMagneBootMtx() {
if (checkMagneBootsOn()) {
mDoMtx_stack_c::concat(mMagneBootMtx);
@@ -351,7 +349,7 @@ int daAlink_c::procMagneBootsFly() {
*/
if (dComIfG_Bgsp().ChkPolySafe(mPolyInfo2)
#if TARGET_PC
&& (dusk::settings::enhancements::RestoreWiiGlitches.getValue() || checkEquipHeavyBoots())
&& (dusk::settings::game::restoreWiiGlitches || checkEquipHeavyBoots())
#elif PLATFORM_GCN || VERSION == VERSION_WII_KOR
&& checkEquipHeavyBoots()
#endif
+16 -1
View File
@@ -16,6 +16,8 @@
#include "f_op/f_op_camera_mng.h"
#include <cstring>
#include "dusk/settings.h"
class daE_YM_HIO_c: public JORReflexible {
public:
daE_YM_HIO_c();
@@ -1066,7 +1068,11 @@ void daE_YM_c::executeDown() {
}
if (mAcch.ChkGroundHit()) {
if (mFlyType != 1) {
#if TARGET_PC
bckSet(6, 0, 0.0f, dusk::settings::game::fastTears && dComIfGp_event_getMode() == 0 ? 2.0f : 1.0f);
#else
bckSet(6, 0, 0.0f, 1.0f);
#endif
}
if (mMode == 1) {
mSound.startCreatureSound(Z2SE_EN_YM_LAND, 0, -1);
@@ -1086,7 +1092,11 @@ void daE_YM_c::executeDown() {
if (current.pos.y < gnd_cross) {
mSound.startCreatureSound(Z2SE_CM_BODYFALL_WATER_M, 0, -1);
mSound.startCreatureSound(Z2SE_EN_YM_MOGAKU, 0, -1);
#if TARGET_PC
bckSet(6, 0, 0.0f, dusk::settings::game::fastTears && dComIfGp_event_getMode() == 0 ? 2.0f : 1.0f);
#else
bckSet(6, 0, 0.0f, 1.0f);
#endif
speedF = 0.0f;
speed.y = gravity = 0.0f;
current.pos.y = gnd_cross;
@@ -1102,8 +1112,13 @@ void daE_YM_c::executeDown() {
f32 gnd_cross_2 = dComIfG_Bgsp().GroundCross(&gnd_chk);
if (gnd_cross_2 == -G_CM3D_F_INF || std::abs(gnd_cross_2 - current.pos.y) > 1000.0f
|| dComIfG_Bgsp().GetGroundCode(gnd_chk) == 4 || dComIfG_Bgsp().GetGroundCode(gnd_chk) == 10
|| dComIfG_Bgsp().GetGroundCode(gnd_chk) == 5) {
|| dComIfG_Bgsp().GetGroundCode(gnd_chk) == 5)
{
#if TARGET_PC
bckSet(6, 0, 0.0f, dusk::settings::game::fastTears && dComIfGp_event_getMode() == 0 ? 2.0f : 1.0f);
#else
bckSet(6, 0, 0.0f, 1.0f);
#endif
mMode = 3;
speedF = 0.0f;
shape_angle.x = -0x8000;
+8
View File
@@ -2709,6 +2709,14 @@ static int daNpc_Henna_Create(fopAc_ac_c* i_this) {
}
i_this->attention_info.flags = (fopAc_AttnFlag_SPEAK_e | fopAc_AttnFlag_TALK_e);
a_this->action = 0;
#if AVOID_UB
a_this->field_0x654 = 0;
a_this->field_0x658 = 0;
a_this->field_0x662 = 0;
a_this->field_0x664 = 0;
#endif
fopAcM_SetMtx(i_this, a_this->mpMorf->getModel()->getBaseTRMtx());
lbl_82_bss_90 = 0;
if (a_this->arg0 == 1) {
+53
View File
@@ -20,6 +20,8 @@
#include "d/actor/d_a_e_ymb.h"
#include "f_op/f_op_camera_mng.h"
#include "dusk/settings.h"
#if DEBUG
daObjDrop_HIO_c l_HIO;
#endif
@@ -261,8 +263,18 @@ int daObjDrop_c::modeParentWait() {
}
mModeAction = 1;
#if TARGET_PC
mModeTimer = dusk::settings::game::fastTears && dComIfGp_event_getMode() == 0 ? 20 : 40;
if (dusk::settings::game::fastTears && dComIfGp_event_getMode() == 0) {
current.pos.y += 100.0f;
} else {
current.pos.y += 300.0f;
}
#else
mModeTimer = 40;
current.pos.y += 300.0f;
#endif
mSound.startSound(Z2SE_OBJ_LIGHTDROP_APPEAR, 0, -1);
break;
case 1:
@@ -272,7 +284,11 @@ int daObjDrop_c::modeParentWait() {
break;
case 2:
createBodyEffect();
#if TARGET_PC
mModeTimer = dusk::settings::game::fastTears && dComIfGp_event_getMode() == 0 ? 5 : 45;
#else
mModeTimer = 45;
#endif
mModeAction = 0;
setMode(MODE_WAIT_e);
break;
@@ -281,6 +297,18 @@ int daObjDrop_c::modeParentWait() {
return 1;
}
#if TARGET_PC
static inline BOOL checkGetCargoRide() {
if ((daPy_getPlayerActorClass()->checkCargoCarry() && strcmp(dComIfGp_getStartStageName(), "F_SP112") == 0) ||
dComIfGs_isLightDropGetFlag(dComIfGp_getStartStageDarkArea()))
{
return true;
}
return false;
}
#endif
int daObjDrop_c::modeWait() {
daPy_py_c* pplayer = daPy_getPlayerActorClass();
@@ -302,7 +330,32 @@ int daObjDrop_c::modeWait() {
case 1:
case 2:
case 50:
#if TARGET_PC
if (dusk::settings::game::fastTears && dComIfGp_event_getMode() == 0) {
f32 player_dist = current.pos.abs(daPy_getPlayerActorClass()->current.pos);
f32 home_dist = current.pos.abs(home.pos);
if (checkGetCargoRide() && player_dist < 1000.0f) {
mTargetPos = pplayer->current.pos;
mTargetPos.y += 100.0f;
f32 temp = 3000.0f - home_dist;
if (temp < 0.0f) {
temp = 0.0f;
}
cLib_chaseF(&speedF, (temp / 3000.0f) * 10.0f * (temp / 3000.0f), 1.0f);
} else {
mTargetPos = home.pos;
cLib_chaseF(&speedF, 2.0f, 0.5f);
}
} else {
cLib_chaseF(&speedF, 7.5f, 0.4f);
}
#else
cLib_chaseF(&speedF, 7.5f, 0.4f);
#endif
if (mModeAction == 1) {
cLib_chasePos(&current.pos, mTargetPos, speedF);
}
+11 -10
View File
@@ -10,12 +10,14 @@
#include "d/d_bg_w.h"
#include "d/d_com_inf_game.h"
#include "f_op/f_op_actor_mng.h"
#include "dusk/offset_ptr.h"
#include "d/d_debug_viewer.h"
#include "d/d_bg_s_capt_poly.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#if TARGET_PC
#include "dusk/offset_ptr.h"
#include "dusk/settings.h"
#endif
#if DEBUG
int g_ground_counter;
@@ -619,8 +621,8 @@ static int poly_draw(dBgS_CaptPoly* capt, cBgD_Vtx_t* vtxList, int v0, int v1, i
GXColor wall_color = {0, 0xFF, 0, 0xFF};
#if TARGET_PC
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
f32 view_opacity = 255 * (collisionViewSettings.m_terrainViewOpacity / 100.0f);
const auto& collisionViewSettings = dusk::getTransientSettings().collisionView;
f32 view_opacity = 255 * (collisionViewSettings.terrainViewOpacity / 100.0f);
ground_color.a = view_opacity;
roof_color.a = view_opacity;
wall_color.a = view_opacity;
@@ -658,16 +660,16 @@ void dBgS::Draw() {
cBgS::Draw();
#if TARGET_PC
#define IMGUI_TOGGLE_HIO_FLAG(status, flag) \
#define DUSK_TOGGLE_HIO_FLAG(status, flag) \
if (status) { \
s_InsideHio.m_flags |= flag; \
} else { \
s_InsideHio.m_flags &= ~flag; \
}
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableTerrainView, dBgS_InsideHIO::FLAG_DISP_POLY_e);
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableWireframe, dBgS_InsideHIO::FLAG_WHITE_WIRE_e);
const auto& collisionViewSettings = dusk::getTransientSettings().collisionView;
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableTerrainView, dBgS_InsideHIO::FLAG_DISP_POLY_e);
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableWireframe, dBgS_InsideHIO::FLAG_WHITE_WIRE_e);
#endif
if (s_InsideHio.ChkDispPoly()) {
@@ -680,8 +682,7 @@ void dBgS::Draw() {
f32 var_f31 = fabsf(s_InsideHio.m_p0.x);
#if TARGET_PC
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
var_f31 = collisionViewSettings.m_drawRange;
var_f31 = collisionViewSettings.drawRange;
#endif
min.x = player->current.pos.x - var_f31;
+1 -3
View File
@@ -28,8 +28,6 @@
#include "d/d_debug_camera.h"
#endif
#include "dusk/imgui/ImGuiMenuEnhancements.hpp"
namespace {
static f32 limitf(f32 value, f32 min, f32 max) {
@@ -766,7 +764,7 @@ void dCamera_c::updatePad() {
var_f31 = mDoCPd_c::getSubStickX3D(mPadID);
#if TARGET_PC
if (dusk::settings::enhancements::InvertCameraXAxis.getValue()) {
if (dusk::settings::game::invertCameraXAxis) {
var_f31 *= -1.0f;
}
#endif
+9 -8
View File
@@ -9,8 +9,9 @@
#include "d/d_com_inf_game.h"
#include "d/d_jnt_col.h"
#include "f_op/f_op_actor_mng.h"
#include "dusk/imgui/ImGuiConsole.hpp"
#if TARGET_PC
#include "dusk/settings.h"
#endif
class dCcS_HIO : public JORReflexible {
public:
@@ -770,19 +771,19 @@ void dCcS::Draw() {
#endif
#if TARGET_PC
#define IMGUI_TOGGLE_HIO_FLAG(status, flag) \
#define DUSK_TOGGLE_HIO_FLAG(status, flag) \
if (status) { \
s_Hio.m_flags |= flag; \
} else { \
s_Hio.m_flags &= ~flag; \
}
dusk::ImGuiMenuTools::CollisionViewSettings collisionViewSettings = dusk::g_imguiConsole.getCollisionViewSettings();
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableAtView, dCcS_HIO::FLAG_AT_ON_e);
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableTgView, dCcS_HIO::FLAG_TG_ON_e);
IMGUI_TOGGLE_HIO_FLAG(collisionViewSettings.m_enableCoView, dCcS_HIO::FLAG_CO_ON_e);
const auto& collisionViewSettings = dusk::getTransientSettings().collisionView;
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableAtView, dCcS_HIO::FLAG_AT_ON_e);
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableTgView, dCcS_HIO::FLAG_TG_ON_e);
DUSK_TOGGLE_HIO_FLAG(collisionViewSettings.enableCoView, dCcS_HIO::FLAG_CO_ON_e);
f32 view_opacity = 255 * (collisionViewSettings.m_colliderViewOpacity / 100.0f);
f32 view_opacity = 255 * (collisionViewSettings.colliderViewOpacity / 100.0f);
#endif
if (s_Hio.CheckAtOn()) {
+2 -2
View File
@@ -32,7 +32,7 @@
#include <cstdlib>
#include <cstring>
#if TARGET_PC
#include "dusk/imgui/ImGuiConsole.hpp"
#include "dusk/settings.h"
#endif
static void GxXFog_set();
@@ -11381,7 +11381,7 @@ void dKy_bg_MAxx_proc(void* bg_model_p) {
C_MTXLightPerspective(sp1D8, dComIfGd_getView()->fovy,
camera_p->view.aspect, 1.0f, 1.0f,
#if TARGET_PC
dusk::settings::enhancements::UseWaterProjectionOffset.getValue() ? -0.01f : 0.0f, 0.0f);
dusk::settings::game::useWaterProjectionOffset ? -0.01f : 0.0f, 0.0f);
#else
-0.01f, 0.0f);
#endif
+60 -24
View File
@@ -17,6 +17,13 @@
#include "m_Do/m_Do_main.h"
#include "f_op/f_op_overlap_mng.h"
#include "dusk/memory.h"
#include "dusk/settings.h"
#if TARGET_PC
#define SHOW_TV_SETTINGS_SCREEN (this->mShowTvSettingsScreen)
#else
#define SHOW_TV_SETTINGS_SCREEN (1)
#endif
static dSn_HIO_c g_snHIO;
@@ -293,13 +300,27 @@ void dScnName_c::FileSelectMain() {
}
void dScnName_c::FileSelectMainNormal() {
#if TARGET_PC
mShowTvSettingsScreen = !dusk::settings::game::hideTvSettingsScreen;
#endif
switch(dFs_c->isSelectEnd()) {
case 1:
mWaitTimer = 15;
mDoGph_gInf_c::setFadeColor(*(JUtility::TColor*)&g_blackColor);
mDoGph_gInf_c::startFadeOut(15);
if (SHOW_TV_SETTINGS_SCREEN) {
mWaitTimer = 15;
mDoGph_gInf_c::setFadeColor(*(JUtility::TColor*)&g_blackColor);
mDoGph_gInf_c::startFadeOut(15);
} else {
mWaitTimer = 1;
}
mProc = dScnName_PROC_FileSelectClose;
field_0x420 = 1;
if (!SHOW_TV_SETTINGS_SCREEN) {
mDoAud_seStart(Z2SE_ENTER_GAME, NULL, 0, 0);
}
break;
}
}
@@ -308,12 +329,17 @@ void dScnName_c::FileSelectClose() {
mWaitTimer--;
if (mWaitTimer == 0) {
mProc = dScnName_PROC_BrightCheckOpen;
mWaitTimer = 15;
mDrawProc = 1;
mDoGph_gInf_c::setFadeColor(*(JUtility::TColor*)&g_blackColor);
mDoGph_gInf_c::startFadeIn(15);
field_0x420 = 0;
if (SHOW_TV_SETTINGS_SCREEN) {
mProc = dScnName_PROC_BrightCheckOpen;
mWaitTimer = 15;
mDrawProc = 1;
mDoGph_gInf_c::setFadeColor(*(JUtility::TColor*)&g_blackColor);
mDoGph_gInf_c::startFadeIn(15);
field_0x420 = 0;
} else {
doPreLoadSetup();
field_0x420 = 0;
}
}
}
@@ -330,24 +356,34 @@ void dScnName_c::brightCheck() {
mBrightCheck->_move();
if (mBrightCheck->isEnd()) {
dComIfGs_setSaveTotalTime(dComIfGs_getTotalTime());
dComIfGs_setSaveStartTime(OSGetTime());
mDoAud_bgmStop(45);
field_0x41f = 0;
mProc = dScnName_PROC_ChangeGameScene;
// Reset rupee "first-time collection" flags so the collection cutscene will play again
dComIfGs_offItemFirstBit(dItemNo_GREEN_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_BLUE_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_YELLOW_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_RED_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_PURPLE_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_ORANGE_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_SILVER_RUPEE_e);
doPreLoadSetup();
}
}
void dScnName_c::doPreLoadSetup() {
dComIfGs_setSaveTotalTime(dComIfGs_getTotalTime());
dComIfGs_setSaveStartTime(OSGetTime());
mDoAud_bgmStop(45);
field_0x41f = 0;
mProc = dScnName_PROC_ChangeGameScene;
#if TARGET_PC
if (dusk::settings::game::disableRupeeCutscenes) {
return;
}
#endif
// Reset rupee "first-time collection" flags so the collection cutscene will play again
dComIfGs_offItemFirstBit(dItemNo_GREEN_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_BLUE_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_YELLOW_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_RED_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_PURPLE_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_ORANGE_RUPEE_e);
dComIfGs_offItemFirstBit(dItemNo_SILVER_RUPEE_e);
}
void dScnName_c::changeGameScene() {
if (!mDoRst::isReset() && !fopOvlpM_IsPeek()) {
dComIfGs_gameStart();
+14
View File
@@ -25,6 +25,8 @@
#include "lingcod/lingcod.h"
#endif
#include "dusk/settings.h"
static u8 dSv_item_rename(u8 i_itemNo) {
switch (i_itemNo) {
case dItemNo_OIL_BOTTLE_2_e:
@@ -111,11 +113,23 @@ u16 dSv_player_status_a_c::getRupeeMax() const {
if (mWalletSize < 3) { // if you make this a default, it wont match. Compiler, pls.
switch (mWalletSize) {
case WALLET:
#if TARGET_PC
return dusk::settings::game::biggerWallets ? 500 : 300;
#else
return 300;
#endif
case BIG_WALLET:
#if TARGET_PC
return dusk::settings::game::biggerWallets ? 1000 : 600;
#else
return 600;
#endif
case GIANT_WALLET:
#if TARGET_PC
return dusk::settings::game::biggerWallets ? 2000 : 1000;
#else
return 1000;
#endif
}
}
+83 -93
View File
@@ -74,19 +74,6 @@ constexpr static int PitchToSampleRate(u16 value) {
return static_cast<int>(static_cast<u64>(SampleRate) * value / 4096);
}
static void UpdateSampleRate(const JASDsp::TChannel& channel, ChannelAuxData& aux) {
auto sampleRate = PitchToSampleRate(channel.mPitch);
const SDL_AudioSpec spec = {
SDL_AUDIO_S16,
1,
sampleRate
};
SDL_SetAudioStreamFormat(aux.resampleStream, &spec, nullptr);
aux.prevPitch = channel.mPitch;
}
/**
* Reset state for a DSP channel between independent playbacks.
*/
@@ -98,8 +85,9 @@ static void ResetChannel(JASDsp::TChannel& channel, ChannelAuxData& aux) {
aux.hist0 = 0;
aux.hist1 = 0;
SDL_ClearAudioStream(aux.resampleStream);
UpdateSampleRate(channel, aux);
aux.decodeBufCount = 0;
aux.resamplePos = 0.0;
aux.resamplePrev = 0;
for (auto& volume : aux.prevVolume) {
volume = NAN;
@@ -196,15 +184,16 @@ static void ReadSampleData(
}
/**
* Read a single *contiguous* chunk of sample data from a channel,
* writes the samples to the channel's resampler stream.
* Read a single *contiguous* chunk of sample data from a channel into outBuf
*
* @returns Amount of samples actually read. Can be greater than the amount requested.
* @returns Amount of samples written to outBuf. May be less than desiredSamples
*/
static int ReadChannelSamplesChunk(
JASDsp::TChannel& channel,
ChannelAuxData& aux,
int desiredSamples) {
int desiredSamples,
s16* outBuf,
int outBufSize) {
assert(desiredSamples >= 0);
@@ -249,61 +238,49 @@ static int ReadChannelSamplesChunk(
channel.mSamplesLeft -= renderSamples;
channel.mSamplePosition += renderSamples;
SDL_PutAudioStreamData(
aux.resampleStream,
renderData + skipSamples,
static_cast<int>(renderSize - skipSamples * sizeof(u16)));
int outputCount = static_cast<int>(renderSamples - skipSamples);
// this should never be hit with the limits on pitch shift (i think) but just in case!!
outputCount = std::min(outputCount, outBufSize);
if (outputCount > 0) {
memcpy(outBuf, renderData + skipSamples, outputCount * sizeof(s16));
}
assert(curSamplePosition % channel.mSamplesPerBlock == 0 || channel.mSamplesLeft == 0);
return static_cast<int>(renderSamples - skipSamples);
return outputCount;
}
/**
* Reads new audio channels from a DSP channel and writes them to the resampler stream.
* Fill decodeBuf with at least `needed` samples, fewer may be written if the channel has no loop and its data ends
*/
static void SDLCALL ReadChannelSamples(
void *userdata,
SDL_AudioStream*,
int additional_amount,
int) {
if (additional_amount == 0) {
return;
}
const auto index = static_cast<u32>(reinterpret_cast<uintptr_t>(userdata));
auto& channel = JASDsp::CH_BUF[index];
auto& aux = ChannelAux[index];
if (channel.mSamplesLeft == 0 && !channel.mLoopFlag) {
// May get called when we're out of data to read.
// This is expected, as we need to drain the resampler channel before we mark the channel as finished.
return;
}
auto samplesRead = ReadChannelSamplesChunk(channel, aux, additional_amount);
additional_amount -= samplesRead;
if (channel.mSamplesLeft == 0) {
// Reached end of buffer.
if (!channel.mLoopFlag) {
return;
static void FillDecodeBuf(JASDsp::TChannel& channel, ChannelAuxData& aux, int needed) {
while (aux.decodeBufCount < needed) {
if (channel.mSamplesLeft == 0) {
if (!channel.mLoopFlag) {
// we aren't a looping channel and there's no samples left, we out of this fuckin loop
break;
} else {
// we are looping, handle loop logic
channel.mSamplesLeft = channel.mEndSample - channel.mLoopStartSample;
channel.mSamplePosition = channel.mLoopStartSample;
aux.hist1 = channel.mpPenult;
aux.hist0 = channel.mpLast;
}
}
channel.mSamplesLeft = channel.mEndSample - channel.mLoopStartSample;
channel.mSamplePosition = channel.mLoopStartSample;
int remainingDecodeSpace = ChannelAuxData::DECODE_BUF_SIZE - aux.decodeBufCount;
if (remainingDecodeSpace == 0) {
break;
}
aux.hist1 = channel.mpPenult;
aux.hist0 = channel.mpLast;
aux.decodeBufCount += ReadChannelSamplesChunk(
channel, aux, std::min(remainingDecodeSpace, needed - aux.decodeBufCount),
aux.decodeBuf + aux.decodeBufCount, remainingDecodeSpace
);
}
if (additional_amount >= 0) {
ReadChannelSamplesChunk(channel, aux, additional_amount);
}
channel.mAramStreamPosition = channel.mWaveAramAddress
+ ConvertSamplesToDataLength(channel, channel.mSamplePosition);
channel.mAramStreamPosition = channel.mWaveAramAddress + ConvertSamplesToDataLength(channel, channel.mSamplePosition);
}
/**
@@ -422,57 +399,70 @@ static void RenderOutputChannel(
prevVolume = targetVolume;
}
/**
* Fetch, decode, resample, output
*/
static void RenderChannel(
JASDsp::TChannel& channel,
ChannelAuxData& channelAux,
OutputSubframe& subframe) {
if (channel.mResetFlag) {
ResetChannel(channel, channelAux);
} else if (channelAux.prevPitch != channel.mPitch) {
UpdateSampleRate(channel, channelAux);
}
DspSubframe audioLoadBuffer = {};
// how many input samples we step per output sample, aka the resampling ratio
f32 step = (f32)PitchToSampleRate(channel.mPitch) / SampleRate;
int wantRead = sizeof(audioLoadBuffer);
auto read = SDL_GetAudioStreamData(
channelAux.resampleStream,
&audioLoadBuffer,
wantRead);
// how many input samples to resample to DSP_SUBFRAME_SIZE output samples
int needed = static_cast<int>(channelAux.resamplePos + DSP_SUBFRAME_SIZE * step) + 2;
if (read < wantRead) {
FillDecodeBuf(channel, channelAux, needed);
// source ran dry, channel is finished
if(channelAux.decodeBufCount < needed) {
channel.mIsFinished = true;
}
auto hasReadSamples = std::span(audioLoadBuffer).subspan(0, wantRead / sizeof(f32));
DspSubframe audioLoadBuffer = {};
f64 pos = channelAux.resamplePos;
s16 prev = channelAux.resamplePrev;
s16 next = channelAux.decodeBufCount > 0 ? channelAux.decodeBuf[0] : prev;
int srcIdx = 0;
// linear resampling and f32 conversion
for (int i = 0; i < DSP_SUBFRAME_SIZE; i++) {
audioLoadBuffer[i] = static_cast<f32>(prev + pos * (next - prev)) / 32768.0f;
pos += step;
while (pos >= 1.0) {
pos -= 1.0;
prev = next;
srcIdx++;
next = srcIdx < channelAux.decodeBufCount ? channelAux.decodeBuf[srcIdx] : prev;
}
}
// save resampler state for the next subframe, prevents popping on pitch change
channelAux.resamplePos = pos;
channelAux.resamplePrev = prev;
// move any remaining samples in the decode buf to the beginning
int remainingDecodeBuf = channelAux.decodeBufCount - srcIdx;
if (remainingDecodeBuf > 0) {
memmove(channelAux.decodeBuf, channelAux.decodeBuf + srcIdx, remainingDecodeBuf * sizeof(s16));
}
channelAux.decodeBufCount = std::max(0, remainingDecodeBuf);
auto hasReadSamples = std::span(audioLoadBuffer).subspan(0, DSP_SUBFRAME_SIZE);
static_assert(OutputSubframe::NUM_CHANNELS == 2, "Keep RenderChannel in sync!");
RenderOutputChannel(channel, channelAux, OutputChannel::LEFT, hasReadSamples, subframe);
RenderOutputChannel(channel, channelAux,OutputChannel::RIGHT, hasReadSamples, subframe);
RenderOutputChannel(channel, channelAux, OutputChannel::RIGHT, hasReadSamples, subframe);
}
void dusk::audio::DspInit() {
constexpr SDL_AudioSpec srcSpec = {
SDL_AUDIO_S16,
1,
SampleRate
};
constexpr SDL_AudioSpec dstSpec = {
SDL_AUDIO_F32,
1,
SampleRate
};
for (u32 i = 0; i < DSP_CHANNELS; i++) {
auto& aux = ChannelAux[i];
aux.resampleStream = SDL_CreateAudioStream(&srcSpec, &dstSpec);
SDL_SetAudioStreamGetCallback(
aux.resampleStream,
ReadChannelSamples,
reinterpret_cast<void*>(static_cast<uintptr_t>(i)));
}
}
void dusk::audio::ApplyVolume(
+11 -2
View File
@@ -26,8 +26,6 @@ namespace dusk::audio {
struct ChannelAuxData {
s16 hist1;
s16 hist0;
SDL_AudioStream* resampleStream;
u16 prevPitch;
// Used for debugging tools.
u32 resetCount;
@@ -43,6 +41,17 @@ namespace dusk::audio {
assert(channel < OutputChannel::OutputChannel_MAX);
return prevVolume[static_cast<int>(channel)];
}
// buffer for decoding before resampling, size is chosen based on how many input samples we would need to fetch for the highest possible pitch
// to fill one subframe of output samples after resampling
static constexpr int DECODE_BUF_SIZE = 2048;
s16 decodeBuf[DECODE_BUF_SIZE];
int decodeBufCount;
// basically stores our position between resamplePrev and decodeBuf[0] so we don't lose that fractional resampler position next subframe
f32 resamplePos;
// last consumed sample from decodeBuf
s16 resamplePrev;
};
extern ChannelAuxData ChannelAux[DSP_CHANNELS];
+4 -3
View File
@@ -50,9 +50,10 @@ static void DisplayDspChannel(int i) {
auto dolby = (channel.mAutoMixerPanDolby & 0xFF) / 127.5f;
auto fxMix = (channel.mAutoMixerFxMix >> 8) / 127.5f;
auto volume = VolumeFromU16(channel.mAutoMixerVolume);
auto pitch = channel.mPitch / 4096.0f;
ImGui::Text(
"Auto mixer active (pan: %f, dolby: %f, fx: %f, volume: %f)",
pan, dolby, fxMix, volume);
"Auto mixer active (pan: %f, dolby: %f, fx: %f, volume: %f, pitch %f)",
pan, dolby, fxMix, volume, pitch);
} else {
ImGui::Text(
"Bus connect: %04X(%.2f),%04X(%.2f),%04X(%.2f),%04X(%.2f),%04X(%.2f),%04X(%.2f)",
@@ -249,4 +250,4 @@ void dusk::ImGuiMenuTools::ShowAudioDebug() {
}
ImGui::End();
}
}
+2 -1
View File
@@ -26,7 +26,8 @@ namespace dusk {
}
ImGui::SetNextWindowBgAlpha(0.65f);
ImGui::SetNextWindowSizeConstraints(ImVec2(300, 0), ImVec2(FLT_MAX, FLT_MAX));
ImGui::SetNextWindowSizeConstraints(ImVec2(300.f * ImGuiScale(), 0),
ImVec2(FLT_MAX, FLT_MAX));
if (!ImGui::Begin("Camera Debug", nullptr, windowFlags)) {
ImGui::End();
+17 -1
View File
@@ -5,13 +5,29 @@
#include "imgui.h"
namespace dusk::config {
inline void ImguiCheckbox(const char* title, ConfigVar<bool>& var) {
inline void ImGuiCheckbox(const char* title, ConfigVar<bool>& var) {
bool copy = var.getValue();
if (ImGui::Checkbox(title, &copy)) {
var.setValue(copy);
Save();
}
}
static void ImGuiSliderFloat(const char* label, ConfigVar<float>& var, float v_min, float v_max, const char* format = "%.3f", ImGuiSliderFlags flags = 0) {
float val = var;
if (ImGui::SliderFloat(label, &val, v_min, v_max, format, flags)) {
var.setValue(val);
Save();
}
}
static void ImGuiSliderInt(const char* label, ConfigVar<int>& var, int v_min, int v_max, const char* format = "%d", ImGuiSliderFlags flags = 0) {
int val = var;
if (ImGui::SliderInt(label, &val, v_min, v_max, format, flags)) {
var.setValue(val);
Save();
}
}
}
#endif // DUSK_IMGUICONFIG_HPP
+89 -4
View File
@@ -1,3 +1,4 @@
#include <algorithm>
#include <array>
#include <numeric>
#include <string_view>
@@ -14,6 +15,7 @@
#include "JSystem/JUtility/JUTGamePad.h"
#if _WIN32
#define NOMINMAX
#include "Windows.h"
#endif
@@ -21,6 +23,8 @@ using namespace std::string_literals;
using namespace std::string_view_literals;
namespace dusk {
float ImGuiScale() { return ImGui::GetIO().DisplayFramebufferScale.x; }
void ImGuiStringViewText(std::string_view text) {
// begin()/end() do not work on MSVC
ImGui::TextUnformatted(text.data(), text.data() + text.size());
@@ -47,7 +51,7 @@ namespace dusk {
ImVec2 workSize = viewport->WorkSize;
ImVec2 windowPos;
ImVec2 windowPosPivot;
constexpr float padding = 10.0f;
const float padding = 10.0f * ImGuiScale();
windowPos.x = (corner & 1) != 0 ? (workPos.x + workSize.x - padding) : (workPos.x + padding);
windowPos.y = (corner & 2) != 0 ? (workPos.y + workSize.y - padding) : (workPos.y + padding);
windowPosPivot.x = (corner & 1) != 0 ? 1.0f : 0.0f;
@@ -172,25 +176,38 @@ namespace dusk {
ImGuiConsole::ImGuiConsole() {}
void ImGuiConsole::draw() {
void ImGuiConsole::PreDraw() {
if (!m_isLaunchInitialized) {
m_toasts.emplace_back("Press F1 to toggle menu"s, 5.f);
m_isLaunchInitialized = true;
}
if (CheckMenuViewToggle(ImGuiKey_F1, m_isHidden)) {
m_menuTools.afterDraw();
ShowToasts();
return;
}
// TODO: we need to be able to render the menu bar & any overlays separately
// The code currently ties them all together, so hiding the menu hides all windows
if (ImGui::BeginMainMenuBar()) {
m_menuGame.draw();
m_menuTools.draw();
m_menuEnhancements.draw();
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 80.0f);
ImGui::SetCursorPosX(ImGui::GetWindowWidth() - 80.0f * ImGuiScale());
ImGuiIO& io = ImGui::GetIO();
ImGuiStringViewText(fmt::format(FMT_STRING("FPS: {:.2f}\n"), io.Framerate));
ImGui::EndMainMenuBar();
}
ShowToasts();
}
void ImGuiConsole::PostDraw() {
m_menuTools.afterDraw();
ShowPipelineProgress();
}
bool ImGuiConsole::CheckMenuViewToggle(ImGuiKey key, bool& active) {
@@ -223,4 +240,72 @@ namespace dusk {
return "Null"sv;
}
}
void ImGuiConsole::ShowToasts() {
if (m_toasts.empty()) {
return;
}
auto& toast = m_toasts.front();
const float dt = ImGui::GetIO().DeltaTime;
toast.remain -= dt;
toast.current += dt;
const ImGuiViewport* viewport = ImGui::GetMainViewport();
const ImVec2 workPos = viewport->WorkPos;
const ImVec2 workSize = viewport->WorkSize;
constexpr float padding = 10.0f;
const ImVec2 windowPos{workPos.x + workSize.x / 2, workPos.y + workSize.y - padding};
ImGui::SetNextWindowPos(windowPos, ImGuiCond_Always, ImVec2{0.5f, 1.f});
const float alpha = std::min({toast.remain, toast.current, 1.f});
ImGui::SetNextWindowBgAlpha(alpha * 0.65f);
ImVec4 textColor = ImGui::GetStyleColorVec4(ImGuiCol_Text);
textColor.w *= alpha;
ImVec4 borderColor = ImGui::GetStyleColorVec4(ImGuiCol_Border);
borderColor.w *= alpha;
ImGui::PushStyleColor(ImGuiCol_Text, textColor);
ImGui::PushStyleColor(ImGuiCol_Border, borderColor);
if (ImGui::Begin("Toast", nullptr,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_AlwaysAutoResize |
ImGuiWindowFlags_NoSavedSettings |
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav |
ImGuiWindowFlags_NoMove))
{
ImGuiStringViewText(toast.message);
}
ImGui::End();
ImGui::PopStyleColor(2);
if (toast.remain <= 0.f) {
m_toasts.pop_front();
}
}
void ImGuiConsole::ShowPipelineProgress() {
const auto* stats = aurora_get_stats();
const u32 queuedPipelines = stats->queuedPipelines;
if (queuedPipelines == 0) {
return;
}
const u32 createdPipelines = stats->createdPipelines;
const u32 totalPipelines = queuedPipelines + createdPipelines;
const auto* viewport = ImGui::GetMainViewport();
const auto padding = viewport->WorkPos.y + 10.f;
const auto halfWidth = viewport->GetWorkCenter().x;
ImGui::SetNextWindowPos(ImVec2{halfWidth, padding}, ImGuiCond_Always, ImVec2{0.5f, 0.f});
ImGui::SetNextWindowSize(ImVec2{halfWidth, 0.f}, ImGuiCond_Always);
ImGui::SetNextWindowBgAlpha(0.65f);
ImGui::Begin("Pipelines", nullptr,
ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove |
ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing);
const auto percent = static_cast<float>(createdPipelines) / static_cast<float>(totalPipelines);
const auto progressStr = fmt::format("Processing pipelines: {} / {}", createdPipelines, totalPipelines);
const auto textSize = ImGui::CalcTextSize(progressStr.data(), progressStr.data() + progressStr.size());
ImGui::NewLine();
ImGui::SameLine(ImGui::GetWindowWidth() / 2.f - textSize.x + textSize.x / 2.f);
ImGuiStringViewText(progressStr);
ImGui::ProgressBar(percent);
ImGui::End();
}
}
+36 -23
View File
@@ -2,41 +2,54 @@
#define DUSK_IMGUI_HPP
#include <aurora/aurora.h>
#include <deque>
#include <string>
#include "imgui.h"
#include "ImGuiMenuEnhancements.hpp"
#include "ImGuiMenuGame.hpp"
#include "ImGuiMenuTools.hpp"
#include "ImGuiMenuEnhancements.hpp"
#include "imgui.h"
namespace dusk {
class ImGuiConsole {
public:
ImGuiConsole();
void draw();
class ImGuiConsole {
public:
ImGuiConsole();
void PreDraw();
void PostDraw();
ImGuiMenuTools::CollisionViewSettings& getCollisionViewSettings() { return m_menuTools.getCollisionViewSettings(); }
static bool CheckMenuViewToggle(ImGuiKey key, bool& active);
static bool CheckMenuViewToggle(ImGuiKey key, bool& active);
private:
struct Toast {
std::string message;
float remain;
float current = 0.f;
Toast(std::string message, float duration) noexcept : message(std::move(message)),
remain(duration) {}
};
private:
bool m_isHidden = false;
bool m_isHidden = true;
bool m_isLaunchInitialized = false;
std::deque<Toast> m_toasts;
ImGuiMenuGame m_menuGame;
ImGuiMenuTools m_menuTools;
ImGuiMenuEnhancements m_menuEnhancements;
ImGuiMenuGame m_menuGame;
ImGuiMenuTools m_menuTools;
ImGuiMenuEnhancements m_menuEnhancements;
};
void ShowToasts();
void ShowPipelineProgress();
};
extern ImGuiConsole g_imguiConsole;
extern ImGuiConsole g_imguiConsole;
std::string_view backend_name(AuroraBackend backend);
std::string BytesToString(size_t bytes);
void SetOverlayWindowLocation(int corner);
bool ShowCornerContextMenu(int& corner, int avoidCorner);
void ImGuiStringViewText(std::string_view text);
void ImGuiBeginGroupPanel(const char* name, const ImVec2& size);
void ImGuiEndGroupPanel();
}
std::string_view backend_name(AuroraBackend backend);
std::string BytesToString(size_t bytes);
void SetOverlayWindowLocation(int corner);
bool ShowCornerContextMenu(int& corner, int avoidCorner);
void ImGuiStringViewText(std::string_view text);
void ImGuiBeginGroupPanel(const char* name, const ImVec2& size);
void ImGuiEndGroupPanel();
float ImGuiScale();
} // namespace dusk
void DuskDebugPad();
+1 -3
View File
@@ -13,8 +13,6 @@ namespace dusk {
ImGui::TextUnformatted(text.c_str());
}
static inline float GetScale() { return ImGui::GetCurrentContext()->CurrentDpiScale; }
void ImGuiMenuGame::windowInputViewer() {
if (!m_showInputViewer) {
return;
@@ -35,7 +33,7 @@ namespace dusk {
ImGui::SetNextWindowBgAlpha(0.65f);
if (ImGui::Begin("Input Viewer", nullptr, windowFlags)) {
float scale = GetScale();
float scale = ImGuiScale();
if (!m_controllerName.empty()) {
TextCenter(m_controllerName);
ImGui::Separator();
+201
View File
@@ -0,0 +1,201 @@
#include "ImGuiEngine.hpp"
#include <SDL3/SDL_filesystem.h>
#include <SDL3/SDL_pixels.h>
#include <SDL3/SDL_surface.h>
#include <aurora/imgui.h>
#include <cmath>
#include <cstring>
#include <string>
#include "dusk/logging.h"
#ifdef IMGUI_ENABLE_FREETYPE
#include "misc/freetype/imgui_freetype.h"
#endif
namespace dusk {
namespace {
std::string GetAssetPath(const char* assetName) {
const char* basePath = SDL_GetBasePath();
if (basePath != nullptr && basePath[0] != '\0') {
return std::string(basePath) + "res/" + assetName;
}
return std::string("res/") + assetName;
}
bool AssetExists(const std::string& path) {
SDL_PathInfo pathInfo{};
return SDL_GetPathInfo(path.c_str(), &pathInfo) && pathInfo.type == SDL_PATHTYPE_FILE;
}
} // namespace
ImFont* ImGuiEngine::fontNormal;
ImFont* ImGuiEngine::fontLarge;
ImTextureID ImGuiEngine::duskIcon;
void ImGuiEngine_Initialize(float scale) {
ImGui::GetCurrentContext();
ImGuiIO& io = ImGui::GetIO();
io.Fonts->Clear();
const std::string fontPath = GetAssetPath("NotoMono-Regular.ttf");
const bool hasFontFile = AssetExists(fontPath);
ImFontConfig fontConfig{};
fontConfig.SizePixels = std::floor(15.f * scale);
snprintf(static_cast<char*>(fontConfig.Name), sizeof(fontConfig.Name),
"Noto Mono Regular, %dpx", static_cast<int>(fontConfig.SizePixels));
ImGuiEngine::fontNormal =
hasFontFile ?
io.Fonts->AddFontFromFileTTF(fontPath.c_str(), fontConfig.SizePixels, &fontConfig) :
nullptr;
if (ImGuiEngine::fontNormal == nullptr) {
if (hasFontFile) {
DuskLog.warn("Failed to load font '{}': {}", fontPath, SDL_GetError());
}
ImGuiEngine::fontNormal = io.Fonts->AddFontDefault(&fontConfig);
}
fontConfig.SizePixels = std::floor(26.f * scale);
#ifdef IMGUI_ENABLE_FREETYPE
fontConfig.FontBuilderFlags |= ImGuiFreeTypeBuilderFlags_Bold;
snprintf(static_cast<char*>(fontConfig.Name), sizeof(fontConfig.Name), "Noto Mono Bold, %dpx",
static_cast<int>(fontConfig.SizePixels));
#else
snprintf(static_cast<char*>(fontConfig.Name), sizeof(fontConfig.Name),
"Noto Mono Regular, %dpx", static_cast<int>(fontConfig.SizePixels));
#endif
ImGuiEngine::fontLarge =
hasFontFile ?
io.Fonts->AddFontFromFileTTF(fontPath.c_str(), fontConfig.SizePixels, &fontConfig) :
nullptr;
if (ImGuiEngine::fontLarge == nullptr) {
if (hasFontFile) {
DuskLog.warn("Failed to load font '{}': {}", fontPath, SDL_GetError());
}
ImGuiEngine::fontLarge = io.Fonts->AddFontDefault(&fontConfig);
}
auto& style = ImGui::GetStyle();
style = {}; // Reset sizes
style.WindowPadding = ImVec2(15, 15);
style.WindowRounding = 5.0f;
style.FrameBorderSize = 1.f;
style.FramePadding = ImVec2(5, 5);
style.FrameRounding = 4.0f;
style.ItemSpacing = ImVec2(12, 8);
style.ItemInnerSpacing = ImVec2(8, 6);
style.IndentSpacing = 25.0f;
style.ScrollbarSize = 15.0f;
style.ScrollbarRounding = 9.0f;
style.GrabMinSize = 5.0f;
style.GrabRounding = 3.0f;
style.PopupBorderSize = 1.f;
style.PopupRounding = 7.0;
style.TabBorderSize = 1.f;
style.TabRounding = 3.f;
auto* colors = style.Colors;
colors[ImGuiCol_Text] = ImVec4(0.95f, 0.96f, 0.98f, 1.00f);
colors[ImGuiCol_TextDisabled] = ImVec4(0.36f, 0.42f, 0.47f, 1.00f);
colors[ImGuiCol_WindowBg] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_ChildBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_PopupBg] = ImVec4(0.08f, 0.08f, 0.08f, 0.94f);
colors[ImGuiCol_Border] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_BorderShadow] = ImVec4(0.00f, 0.00f, 0.00f, 0.00f);
colors[ImGuiCol_FrameBg] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_FrameBgHovered] = ImVec4(0.12f, 0.20f, 0.28f, 1.00f);
colors[ImGuiCol_FrameBgActive] = ImVec4(0.09f, 0.12f, 0.14f, 1.00f);
colors[ImGuiCol_TitleBg] = ImVec4(0.09f, 0.12f, 0.14f, 0.65f);
colors[ImGuiCol_TitleBgActive] = ImVec4(0.08f, 0.10f, 0.12f, 1.00f);
colors[ImGuiCol_TitleBgCollapsed] = ImVec4(0.00f, 0.00f, 0.00f, 0.51f);
colors[ImGuiCol_MenuBarBg] = ImVec4(0.15f, 0.18f, 0.22f, 1.00f);
colors[ImGuiCol_ScrollbarBg] = ImVec4(0.02f, 0.02f, 0.02f, 0.39f);
colors[ImGuiCol_ScrollbarGrab] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_ScrollbarGrabHovered] = ImVec4(0.18f, 0.22f, 0.25f, 1.00f);
colors[ImGuiCol_ScrollbarGrabActive] = ImVec4(0.09f, 0.21f, 0.31f, 1.00f);
colors[ImGuiCol_CheckMark] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
colors[ImGuiCol_SliderGrab] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
colors[ImGuiCol_SliderGrabActive] = ImVec4(0.37f, 0.61f, 1.00f, 1.00f);
colors[ImGuiCol_Button] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_ButtonHovered] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
colors[ImGuiCol_ButtonActive] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f);
colors[ImGuiCol_Header] = ImVec4(0.20f, 0.25f, 0.29f, 0.55f);
colors[ImGuiCol_HeaderHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
colors[ImGuiCol_HeaderActive] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_Separator] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_SeparatorHovered] = ImVec4(0.10f, 0.40f, 0.75f, 0.78f);
colors[ImGuiCol_SeparatorActive] = ImVec4(0.10f, 0.40f, 0.75f, 1.00f);
colors[ImGuiCol_ResizeGrip] = ImVec4(0.26f, 0.59f, 0.98f, 0.25f);
colors[ImGuiCol_ResizeGripHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.67f);
colors[ImGuiCol_ResizeGripActive] = ImVec4(0.26f, 0.59f, 0.98f, 0.95f);
colors[ImGuiCol_Tab] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabHovered] = ImVec4(0.26f, 0.59f, 0.98f, 0.80f);
colors[ImGuiCol_TabActive] = ImVec4(0.20f, 0.25f, 0.29f, 1.00f);
colors[ImGuiCol_TabUnfocused] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_TabUnfocusedActive] = ImVec4(0.11f, 0.15f, 0.17f, 1.00f);
colors[ImGuiCol_PlotLines] = ImVec4(0.61f, 0.61f, 0.61f, 1.00f);
colors[ImGuiCol_PlotLinesHovered] = ImVec4(1.00f, 0.43f, 0.35f, 1.00f);
colors[ImGuiCol_PlotHistogram] = ImVec4(0.06f, 0.53f, 0.98f, 1.00f);
colors[ImGuiCol_PlotHistogramHovered] = ImVec4(0.28f, 0.56f, 1.00f, 1.00f);
colors[ImGuiCol_TextSelectedBg] = ImVec4(0.26f, 0.59f, 0.98f, 0.35f);
colors[ImGuiCol_DragDropTarget] = ImVec4(1.00f, 1.00f, 0.00f, 0.90f);
colors[ImGuiCol_NavHighlight] = ImVec4(0.26f, 0.59f, 0.98f, 1.00f);
colors[ImGuiCol_NavWindowingHighlight] = ImVec4(1.00f, 1.00f, 1.00f, 0.70f);
colors[ImGuiCol_NavWindowingDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.20f);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.80f, 0.80f, 0.80f, 0.35f);
style.ScaleAllSizes(scale);
}
Icon GetIcon() {
const std::string iconPath = GetAssetPath("icon.png");
if (!AssetExists(iconPath)) {
return {};
}
SDL_Surface* loadedSurface = SDL_LoadPNG(iconPath.c_str());
if (loadedSurface == nullptr) {
DuskLog.warn("Failed to load icon '{}': {}", iconPath, SDL_GetError());
return {};
}
SDL_Surface* rgbaSurface = SDL_ConvertSurface(loadedSurface, SDL_PIXELFORMAT_RGBA32);
SDL_DestroySurface(loadedSurface);
if (rgbaSurface == nullptr) {
DuskLog.warn("Failed to convert icon '{}': {}", iconPath, SDL_GetError());
return {};
}
const auto iconWidth = static_cast<uint32_t>(rgbaSurface->w);
const auto iconHeight = static_cast<uint32_t>(rgbaSurface->h);
const size_t rowSize = static_cast<size_t>(iconWidth) * 4;
const size_t size = rowSize * static_cast<size_t>(iconHeight);
auto ptr = std::make_unique<uint8_t[]>(size);
for (uint32_t row = 0; row < iconHeight; ++row) {
const auto* src = static_cast<const uint8_t*>(rgbaSurface->pixels) +
static_cast<size_t>(row) * static_cast<size_t>(rgbaSurface->pitch);
auto* dst = ptr.get() + static_cast<size_t>(row) * rowSize;
std::memcpy(dst, src, rowSize);
}
SDL_DestroySurface(rgbaSurface);
return Icon{
std::move(ptr),
size,
iconWidth,
iconHeight,
};
}
void ImGuiEngine_AddTextures() {
auto icon = GetIcon();
if (icon.data == nullptr || icon.width == 0 || icon.height == 0) {
ImGuiEngine::duskIcon = 0;
return;
}
ImGuiEngine::duskIcon = aurora_imgui_add_texture(icon.width, icon.height, icon.data.get());
}
} // namespace dusk
+25
View File
@@ -0,0 +1,25 @@
#pragma once
#include <memory>
#include "imgui.h"
#include "misc/cpp/imgui_stdlib.h"
namespace dusk {
class ImGuiEngine {
public:
static ImFont* fontNormal;
static ImFont* fontLarge;
static ImTextureID duskIcon;
};
void ImGuiEngine_Initialize(float scale);
void ImGuiEngine_AddTextures();
struct Icon {
std::unique_ptr<uint8_t[]> data;
size_t size;
uint32_t width;
uint32_t height;
};
Icon GetIcon();
} // namespace dusk
+2 -1
View File
@@ -17,7 +17,8 @@ namespace dusk {
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoNav;
ImGui::SetNextWindowBgAlpha(0.65f);
ImGui::SetNextWindowSizeConstraints(ImVec2(300, 0), ImVec2(FLT_MAX, FLT_MAX));
ImGui::SetNextWindowSizeConstraints(ImVec2(300.f * ImGuiScale(), 0),
ImVec2(FLT_MAX, FLT_MAX));
if (!ImGui::Begin("Map Loader", &m_showMapLoader, windowFlags)) {
ImGui::End();
+64 -17
View File
@@ -1,12 +1,8 @@
#include "fmt/format.h"
#include "imgui.h"
#include "aurora/gfx.h"
#include "ImGuiConsole.hpp"
#include "ImGuiMenuEnhancements.hpp"
#include "ImGuiConfig.hpp"
#include "dusk/settings.hpp"
#include <imgui_internal.h>
#include "dusk/settings.h"
namespace dusk {
ImGuiMenuEnhancements::ImGuiMenuEnhancements() {}
@@ -14,26 +10,81 @@ namespace dusk {
void ImGuiMenuEnhancements::draw() {
if (ImGui::BeginMenu("Enhancements")) {
if (ImGui::BeginMenu("Quality of Life")) {
config::ImguiCheckbox("Fast Iron Boots", settings::enhancements::FastIronBoots);
config::ImguiCheckbox("Invert Camera X Axis", settings::enhancements::InvertCameraXAxis);
config::ImguiCheckbox("Quick Transform (R+Y)", settings::enhancements::QuickTransform);
config::ImGuiCheckbox("Quick Transform (R+Y)", settings::game::enableQuickTransform);
config::ImGuiCheckbox("Bigger Wallets", settings::game::biggerWallets);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Wallet sizes are like in the HD version (500, 1000, 2000)");
}
config::ImGuiCheckbox("No Rupee Returns", settings::game::noReturnRupees);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Always collect Rupees even if your Wallet is too full");
}
config::ImGuiCheckbox("Disable Rupee Cutscenes", settings::game::disableRupeeCutscenes);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Rupees won't play cutscenes after you've collected them the first time");
}
config::ImGuiCheckbox("No Sword Recoil", settings::game::noSwordRecoil);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Link won't recoil when his sword hits walls");
}
config::ImGuiCheckbox("Faster Climbing", settings::game::fastClimbing);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Quicker climbing on ladders and vines like the HD version");
}
config::ImGuiCheckbox("Faster Tears of Light", settings::game::fastTears);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Tears of Light dropped by Shadow Insects pop out faster like the HD version");
}
config::ImGuiCheckbox("Hide TV Settings Screen", settings::game::hideTvSettingsScreen);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Hides the TV calibration screen shown when loading a save");
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Preferences")) {
config::ImGuiCheckbox("Mirror Mode", settings::game::enableMirrorMode);
config::ImGuiCheckbox("Invert Camera X Axis", settings::game::invertCameraXAxis);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Graphics")) {
config::ImguiCheckbox("Native Bloom", settings::enhancements::EnableBloom);
config::ImguiCheckbox("Water Projection Offset", settings::enhancements::UseWaterProjectionOffset);
config::ImGuiCheckbox("Native Bloom", settings::game::enableBloom);
config::ImGuiCheckbox("Water Projection Offset", settings::game::useWaterProjectionOffset);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Adds GC-specific -0.01 transS offset\n"
"that causes ~6px ghost artifacts in water reflections");
}
config::ImguiCheckbox("Mirror Mode", settings::enhancements::MirrorMode);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Restorations")) {
config::ImguiCheckbox("Restore Wii 1.0 Glitches", settings::enhancements::RestoreWiiGlitches);
if (ImGui::BeginMenu("Cheats")) {
config::ImGuiCheckbox("Fast Iron Boots", settings::game::enableFastIronBoots);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Difficulty")) {
config::ImGuiSliderInt("Damage Multiplier", settings::game::damageMultiplier, 1, 8, "x%d");
config::ImGuiCheckbox("Instant Death", settings::game::instantDeath);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Any hit will instantly kill you");
}
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Technical")) {
config::ImGuiCheckbox("Restore Wii 1.0 Glitches", settings::game::restoreWiiGlitches);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Restores patched glitches from Wii USA 1.0, the first released version");
}
@@ -41,10 +92,6 @@ namespace dusk {
ImGui::EndMenu();
}
if (ImGui::BeginMenu("Cheats")) {
ImGui::EndMenu();
}
ImGui::EndMenu();
}
}
+37 -31
View File
@@ -1,32 +1,36 @@
#include "fmt/format.h"
#include "imgui.h"
#include "aurora/gfx.h"
#include "ImGuiConsole.hpp"
#include "ImGuiMenuGame.hpp"
#include "ImGuiConfig.hpp"
#include <imgui_internal.h>
#include "JSystem/JUtility/JUTGamePad.h"
#include "d/actor/d_a_alink.h"
#include "dusk/audio/DuskAudioSystem.h"
#include "m_Do/m_Do_audio.h"
#include "dusk/hotkeys.h"
#include "dusk/settings.h"
#include "m_Do/m_Do_controller_pad.h"
namespace dusk {
static void ToggleFullscreen() {
settings::video::enableFullscreen.setValue(!settings::video::enableFullscreen);
VISetWindowFullscreen(settings::video::enableFullscreen);
}
ImGuiMenuGame::ImGuiMenuGame() {}
void ImGuiMenuGame::draw() {
if (ImGui::BeginMenu("Game")) {
if (ImGui::MenuItem("Reset", "Ctrl+R")) {
if (ImGui::MenuItem("Reset", hotkeys::DO_RESET)) {
JUTGamePad::C3ButtonReset::sResetSwitchPushing = true;
}
ImGui::Separator();
if (ImGui::BeginMenu("Graphics")) {
if (ImGui::MenuItem("Toggle Fullscreen", "F11")) {
m_fullscreen = !m_fullscreen;
VISetWindowFullscreen(m_fullscreen);
if (ImGui::MenuItem("Toggle Fullscreen", hotkeys::TOGGLE_FULLSCREEN)) {
ToggleFullscreen();
}
ImGui::EndMenu();
@@ -34,28 +38,28 @@ namespace dusk {
if (ImGui::BeginMenu("Audio")) {
ImGui::Text("Master Volume");
ImGui::SliderFloat("##m_masterVolume", &m_audioSettings.m_masterVolume, 0.0f, 1.0f, "");
config::ImGuiSliderFloat("##masterVolume", settings::audio::masterVolume, 0.0f, 1.0f, "");
/*
// TODO: implement additional settings
ImGui::Text("Main Music Volume");
ImGui::SliderFloat("##m_mainMusicVolume", &m_audioSettings.m_mainMusicVolume, 0.0f, 1.0f, "");
ImGui::SliderFloat("##mainMusicVolume", &getSettings().audio.mainMusicVolume, 0.0f, 1.0f, "");
ImGui::Text("Sub Music Volume");
ImGui::SliderFloat("##m_subMusicVolume", &m_audioSettings.m_subMusicVolume, 0.0f, 1.0f, "");
ImGui::SliderFloat("##subMusicVolume", &getSettings().audio.subMusicVolume, 0.0f, 1.0f, "");
ImGui::Text("Sound Effects Volume");
ImGui::SliderFloat("##m_soundEffectsVolume", &m_audioSettings.m_soundEffectsVolume, 0.0f, 1.0f, "");
ImGui::SliderFloat("##soundEffectsVolume", &getSettings().audio.soundEffectsVolume, 0.0f, 1.0f, "");
ImGui::Text("Fanfare Volume");
ImGui::SliderFloat("##m_fanfareVolume", &m_audioSettings.m_fanfareVolume, 0.0f, 1.0f, "");
ImGui::SliderFloat("##fanfareVolume", &getSettings().audio.fanfareVolume, 0.0f, 1.0f, "");
Z2AudioMgr* audioMgr = Z2AudioMgr::getInterface();
if (audioMgr != nullptr) {
}
*/
audio::SetMasterVolume(m_audioSettings.m_masterVolume);
audio::SetMasterVolume(settings::audio::masterVolume);
ImGui::EndMenu();
}
@@ -78,19 +82,19 @@ namespace dusk {
}
if (ImGui::IsKeyPressed(ImGuiKey_F11)) {
m_fullscreen = !m_fullscreen;
VISetWindowFullscreen(m_fullscreen);
ToggleFullscreen();
}
}
static void drawVirtualStick(const char* id, const ImVec2& stick) {
ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 5, ImGui::GetCursorPos().y));
float scale = ImGuiScale();
ImGui::SetCursorPos(ImVec2(ImGui::GetCursorPos().x + 5 * scale, ImGui::GetCursorPos().y));
ImGui::BeginChild(id, ImVec2(80, 80));
ImGui::BeginChild(id, ImVec2(80 * scale, 80 * scale));
ImDrawList* dl = ImGui::GetWindowDrawList();
ImVec2 p = ImGui::GetCursorScreenPos();
float radius = ImGui::GetCurrentContext()->CurrentDpiScale * 30.0f;
float radius = 30.0f * scale;
ImVec2 pos = ImVec2(p.x + radius, p.y + radius);
constexpr ImU32 stickGray = IM_COL32(150, 150, 150, 255);
@@ -98,7 +102,7 @@ namespace dusk {
constexpr ImU32 red = IM_COL32(230, 0, 0, 255);
dl->AddCircleFilled(pos, radius, stickGray, 8);
dl->AddCircleFilled(ImVec2(pos.x + stick.x * (radius), pos.y + -stick.y * (radius)), 3, red);
dl->AddCircleFilled(ImVec2(pos.x + stick.x * (radius), pos.y + -stick.y * (radius)), 3 * scale, red);
ImGui::EndChild();
}
@@ -139,12 +143,14 @@ namespace dusk {
}
}
float scale = ImGuiScale();
ImGuiWindowFlags windowFlags =
ImGuiWindowFlags_NoResize |
ImGuiWindowFlags_AlwaysAutoResize;
ImGui::SetNextWindowBgAlpha(0.65f);
ImGui::SetNextWindowSizeConstraints(ImVec2(850, 400), ImVec2(850, 400));
ImGui::SetNextWindowSizeConstraints(ImVec2(850 * scale, 400 * scale),
ImVec2(850 * scale, 400 * scale));
if (!ImGui::Begin("Controller Config", &m_showControllerConfig, windowFlags)) {
ImGui::End();
@@ -225,9 +231,9 @@ namespace dusk {
}
// buttons panel
constexpr float uiButtonSize = 40;
const float uiButtonSize = 40 * scale;
ImGuiBeginGroupPanel("Buttons", ImVec2(150, 20));
ImGuiBeginGroupPanel("Buttons", ImVec2(150 * scale, 20 * scale));
u32 buttonCount;
PADButtonMapping* btnMappingList = PADGetButtonMappings(m_controllerConfig.m_selectedPort, &buttonCount);
@@ -251,7 +257,7 @@ namespace dusk {
dispName = fmt::format("{0}##-{1}", PADGetNativeButtonName(btnMappingList[i].nativeButton), i);
}
bool pressed = ImGui::Button(dispName.c_str(),
ImVec2(100.0f, 20.0f));
ImVec2(100.0f * scale, 20.0f * scale));
if (pressed) {
m_controllerConfig.m_isReading = true;
@@ -268,7 +274,7 @@ namespace dusk {
uint32_t axisCount;
PADAxisMapping* axisMappingList = PADGetAxisMappings(m_controllerConfig.m_selectedPort, &axisCount);
ImGuiBeginGroupPanel("Triggers", ImVec2(150, 20));
ImGuiBeginGroupPanel("Triggers", ImVec2(150 * scale, 20 * scale));
PADAxis triggers[] = {PAD_AXIS_TRIGGER_L, PAD_AXIS_TRIGGER_R};
if (axisMappingList != nullptr) {
@@ -291,7 +297,7 @@ namespace dusk {
dispName = fmt::format("{0}##-{1}", PADGetNativeAxisName(axisMappingList[trigger].nativeAxis), trigger);
}
bool pressed = ImGui::Button(dispName.c_str(),
ImVec2(100.0f, 20.0f));
ImVec2(100.0f * scale, 20.0f * scale));
if (pressed) {
m_controllerConfig.m_isReading = true;
@@ -308,7 +314,7 @@ namespace dusk {
int port = m_controllerConfig.m_selectedPort;
// main stick panel
ImGuiBeginGroupPanel("Control Stick", ImVec2(150, 20));
ImGuiBeginGroupPanel("Control Stick", ImVec2(150 * scale, 20 * scale));
drawVirtualStick("##mainStick", ImVec2{ mDoCPd_c::getStickX(port), mDoCPd_c::getStickY(port) });
@@ -345,7 +351,7 @@ namespace dusk {
dispName = fmt::format("{0}##-{1}", PADGetNativeButtonName(axisMappingList[axis].nativeButton), axis);
}
}
bool pressed = ImGui::Button(dispName.c_str(), ImVec2(100.0f, 20.0f));
bool pressed = ImGui::Button(dispName.c_str(), ImVec2(100.0f * scale, 20.0f * scale));
if (pressed) {
m_controllerConfig.m_isReading = true;
@@ -372,7 +378,7 @@ namespace dusk {
ImGui::SameLine();
// sub stick panel
ImGuiBeginGroupPanel("C Stick", ImVec2(150, 20));
ImGuiBeginGroupPanel("C Stick", ImVec2(150 * scale, 20 * scale));
drawVirtualStick("##subStick", ImVec2{ mDoCPd_c::getSubStickX(port), mDoCPd_c::getSubStickY(port) });
@@ -409,7 +415,7 @@ namespace dusk {
dispName = fmt::format("{0}##-{1}", PADGetNativeButtonName(axisMappingList[axis].nativeButton), axis);
}
}
bool pressed = ImGui::Button(fmt::format("{0}##sub{1}", dispName, label).c_str(), ImVec2(100.0f, 20.0f));
bool pressed = ImGui::Button(fmt::format("{0}##sub{1}", dispName, label).c_str(), ImVec2(100.0f * scale, 20.0f * scale));
if (pressed) {
m_controllerConfig.m_isReading = true;
@@ -434,7 +440,7 @@ namespace dusk {
ImGui::SameLine();
// Triggers Panel
ImGuiBeginGroupPanel("Triggers", ImVec2(150, 20));
ImGuiBeginGroupPanel("Triggers", ImVec2(150 * scale, 20 * scale));
if (deadZones != nullptr) {
ImGui::Text("L Threshold");
@@ -460,7 +466,7 @@ namespace dusk {
ImGui::SameLine();
// Options panel
ImGuiBeginGroupPanel("Options", ImVec2(150, 20));
ImGuiBeginGroupPanel("Options", ImVec2(150 * scale, 20 * scale));
if (deadZones != nullptr) {
ImGui::Checkbox("Enable Dead Zones", &deadZones->useDeadzones);
-10
View File
@@ -17,14 +17,6 @@ namespace dusk {
void windowControllerConfig();
private:
struct {
float m_masterVolume = 1.0f;
float m_mainMusicVolume = 1.0f;
float m_subMusicVolume = 1.0f;
float m_soundEffectsVolume = 1.0f;
float m_fanfareVolume = 1.0f;
} m_audioSettings;
struct {
int m_selectedPort = 0;
bool m_isReading = false;
@@ -33,8 +25,6 @@ namespace dusk {
int m_pendingPort = -1;
} m_controllerConfig;
bool m_fullscreen = false;
bool m_showControllerConfig = false;
bool m_showInputViewer = false;
+19 -14
View File
@@ -2,6 +2,7 @@
#include "imgui.h"
#include "aurora/gfx.h"
#include "dusk/hotkeys.h"
#include "ImGuiConsole.hpp"
#include "ImGuiMenuTools.hpp"
@@ -23,28 +24,29 @@ namespace dusk {
ImGui::Separator();
auto& collisionView = getTransientSettings().collisionView;
if (ImGui::BeginMenu("Collision View")) {
ImGui::Checkbox("Enable Terrain view", &m_collisionViewSettings.m_enableTerrainView);
ImGui::Checkbox("Enable wireframe view", &m_collisionViewSettings.m_enableWireframe);
ImGui::SliderFloat("Opacity##terrain", &m_collisionViewSettings.m_terrainViewOpacity, 0.0f, 100.0f);
ImGui::SliderFloat("Draw Range", &m_collisionViewSettings.m_drawRange, 0.0f, 1000.0f);
ImGui::Checkbox("Enable Terrain view", &collisionView.enableTerrainView);
ImGui::Checkbox("Enable wireframe view", &collisionView.enableWireframe);
ImGui::SliderFloat("Opacity##terrain", &collisionView.terrainViewOpacity, 0.0f, 100.0f);
ImGui::SliderFloat("Draw Range", &collisionView.drawRange, 0.0f, 1000.0f);
ImGui::Separator();
ImGui::Checkbox("Enable Attack Collider view", &m_collisionViewSettings.m_enableAtView);
ImGui::Checkbox("Enable Target Collider view", &m_collisionViewSettings.m_enableTgView);
ImGui::Checkbox("Enable Push Collider view", &m_collisionViewSettings.m_enableCoView);
ImGui::SliderFloat("Opacity##colliders", &m_collisionViewSettings.m_colliderViewOpacity, 0.0f, 100.0f);
ImGui::Checkbox("Enable Attack Collider view", &collisionView.enableAtView);
ImGui::Checkbox("Enable Target Collider view", &collisionView.enableTgView);
ImGui::Checkbox("Enable Push Collider view", &collisionView.enableCoView);
ImGui::SliderFloat("Opacity##colliders", &collisionView.colliderViewOpacity, 0.0f, 100.0f);
ImGui::EndMenu();
}
ImGui::MenuItem("Process Management", "F2", &m_showProcessManagement);
ImGui::MenuItem("Debug Overlay", "F3", &m_showDebugOverlay);
ImGui::MenuItem("Heap Viewer", "F4", &m_showHeapOverlay);
ImGui::MenuItem("Stub Log", "F5", &m_showStubLog);
ImGui::MenuItem("Debug Camera", "F6", &m_showCameraOverlay);
ImGui::MenuItem("Process Management", hotkeys::SHOW_PROCESS_MANAGEMENT, &m_showProcessManagement);
ImGui::MenuItem("Debug Overlay", hotkeys::SHOW_DEBUG_OVERLAY, &m_showDebugOverlay);
ImGui::MenuItem("Heap Viewer", hotkeys::SHOW_HEAP_VIEWER, &m_showHeapOverlay);
ImGui::MenuItem("Stub Log", hotkeys::SHOW_STUB_LOG, &m_showStubLog);
ImGui::MenuItem("Debug Camera", hotkeys::SHOW_CAMERA_DEBUG, &m_showCameraOverlay);
ImGui::MenuItem("Map Loader", nullptr, &m_showMapLoader);
ImGui::MenuItem("Player Info", nullptr, &m_showPlayerInfo);
ImGui::MenuItem("Save Editor", nullptr, &m_showSaveEditor);
ImGui::MenuItem("Audio Debug", "F7", &m_showAudioDebug);
ImGui::MenuItem("Audio Debug", hotkeys::SHOW_AUDIO_DEBUG, &m_showAudioDebug);
ImGui::MenuItem("OSReport Force", nullptr, &OSReportReallyForceEnable);
ImGui::EndMenu();
}
@@ -131,6 +133,9 @@ namespace dusk {
BytesToString(stats->lastVertSize + stats->lastUniformSize +
stats->lastIndexSize + stats->lastStorageSize +
stats->lastTextureUploadSize)));
// TODO: persist to config
ShowCornerContextMenu(m_debugOverlayCorner, m_cameraOverlayCorner);
}
ImGui::End();
}
+1 -16
View File
@@ -10,17 +10,6 @@
namespace dusk {
class ImGuiMenuTools {
public:
struct CollisionViewSettings {
bool m_enableTerrainView = false;
bool m_enableWireframe = false;
bool m_enableAtView = false;
bool m_enableTgView = false;
bool m_enableCoView = false;
float m_terrainViewOpacity = 50.0f;
float m_colliderViewOpacity = 50.0f;
float m_drawRange = 100.0f;
};
ImGuiMenuTools();
void draw();
void afterDraw();
@@ -34,11 +23,9 @@ namespace dusk {
void ShowPlayerInfo();
void ShowAudioDebug();
CollisionViewSettings& getCollisionViewSettings() { return m_collisionViewSettings; }
private:
bool m_showDebugOverlay = false;
int m_debugOverlayCorner = 0; // top-left
int m_debugOverlayCorner = 2; // bottom-left
bool m_showCameraOverlay = false;
int m_cameraOverlayCorner = 3;
@@ -67,8 +54,6 @@ namespace dusk {
bool m_isDevelopmentMode = false;
bool m_showPlayerInfo = false;
CollisionViewSettings m_collisionViewSettings;
bool m_showSaveEditor = false;
ImGuiSaveEditor m_saveEditor;
};
+1 -1
View File
@@ -823,7 +823,7 @@ namespace dusk {
for (int e = 0; e < 255; e++) {
ImGui::Text("%03d ", e);
ImGui::SameLine();
for (int i = 8; i >= 0; i--) {
for (int i = 7; i >= 0; i--) {
bool flag = event.mEvent[e] & (1 << i);
if (ImGui::Checkbox(fmt::format("##event{0}{1}", e, i).c_str(), &flag)) {
if (flag)
+93 -24
View File
@@ -1,28 +1,97 @@
#include "dusk/settings.hpp"
#include "dusk/settings.h"
#include "dusk/config.hpp"
namespace dusk::settings::enhancements {
ConfigVar<bool> FastIronBoots("enhancements.fast_iron_boots", false);
ConfigVar<bool> InvertCameraXAxis("enhancements.invert_camera_x_axis", false);
ConfigVar<bool> QuickTransform("enhancements.quick_transform", false);
ConfigVar<bool> RestoreWiiGlitches("enhancements.restore_wii_glitches", false);
ConfigVar<bool> EnableBloom("enhancements.enable_bloom", true);
ConfigVar<bool> UseWaterProjectionOffset("enhancements.use_water_projection_offset", false);
ConfigVar<bool> MirrorMode("enhancements.mirror_mode", false);
void Register() {
Register(FastIronBoots);
Register(InvertCameraXAxis);
Register(QuickTransform);
Register(RestoreWiiGlitches);
Register(EnableBloom);
Register(UseWaterProjectionOffset);
Register(MirrorMode);
}
}
namespace dusk::settings {
void Register() {
enhancements::Register();
}
namespace video {
ConfigVar<bool> enableFullscreen("video.enableFullscreen", false);
}
namespace audio {
ConfigVar<float> masterVolume("audio.masterVolume", 1.0f);
ConfigVar<float> mainMusicVolume("audio.mainMusicVolume", 1.0f);
ConfigVar<float> subMusicVolume("audio.subMusicVolume", 1.0f);
ConfigVar<float> soundEffectsVolume("audio.soundEffectsVolume", 1.0f);
ConfigVar<float> fanfareVolume("audio.fanfareVolume", 1.0f);
}
namespace game {
// Quality of Life
ConfigVar<bool> enableQuickTransform("game.enableQuickTransform", false);
ConfigVar<bool> hideTvSettingsScreen("game.hideTvSettingsScreen", false);
ConfigVar<bool> biggerWallets("game.biggerWallets", false);
ConfigVar<bool> noReturnRupees("game.noReturnRupees", false);
ConfigVar<bool> disableRupeeCutscenes("game.disableRupeeCutscenes", false);
ConfigVar<bool> noSwordRecoil("game.noSwordRecoil", false);
ConfigVar<int> damageMultiplier("game.damageMultiplier", 1);
ConfigVar<bool> instantDeath("game.instantDeath", false);
ConfigVar<bool> fastClimbing("game.fastClimbing", false);
ConfigVar<bool> fastTears("game.fastTears", false);
// Preferences
ConfigVar<bool> enableMirrorMode("game.enableMirrorMode", false);
ConfigVar<bool> invertCameraXAxis("game.invertCameraXAxis", false);
// Graphics
ConfigVar<bool> enableBloom("game.enableBloom", true);
ConfigVar<bool> useWaterProjectionOffset("game.useWaterProjectionOffset", false);
// Cheats
ConfigVar<bool> enableFastIronBoots("game.enableFastIronBoots", false);
// Technical
ConfigVar<bool> restoreWiiGlitches("game.restoreWiiGlitches", false);
}
void Register() {
// Video
Register(video::enableFullscreen);
// Audio
Register(audio::masterVolume);
Register(audio::mainMusicVolume);
Register(audio::subMusicVolume);
Register(audio::soundEffectsVolume);
Register(audio::fanfareVolume);
// Game
Register(game::enableQuickTransform);
Register(game::hideTvSettingsScreen);
Register(game::biggerWallets);
Register(game::noReturnRupees);
Register(game::disableRupeeCutscenes);
Register(game::noSwordRecoil);
Register(game::damageMultiplier);
Register(game::instantDeath);
Register(game::fastClimbing);
Register(game::fastTears);
Register(game::enableMirrorMode);
Register(game::invertCameraXAxis);
Register(game::enableBloom);
Register(game::useWaterProjectionOffset);
Register(game::enableFastIronBoots);
Register(game::restoreWiiGlitches);
}
}
namespace dusk {
// Transient settings
static TransientSettings g_transientSettings = {
.collisionView = {
.enableTerrainView = false,
.enableWireframe = false,
.enableAtView = false,
.enableTgView = false,
.enableCoView = false,
.terrainViewOpacity = 50.0f,
.colliderViewOpacity = 50.0f,
.drawRange = 100.0f,
},
};
TransientSettings& getTransientSettings() {
return g_transientSettings;
}
}
+7 -3
View File
@@ -1163,7 +1163,7 @@ void mDoGph_gInf_c::bloom_c::remove() {
void mDoGph_gInf_c::bloom_c::draw() {
#if TARGET_PC
if (!dusk::settings::enhancements::EnableBloom.getValue()) {
if (!dusk::settings::game::enableBloom) {
return;
}
#endif
@@ -1634,6 +1634,10 @@ int mDoGph_Painter() {
if (wn != 0) sDiagLoggedWindow = true;
}
#if TARGET_PC
dusk::g_imguiConsole.PreDraw();
#endif
#if DEBUG
drawHeapMap();
#endif
@@ -2113,7 +2117,7 @@ int mDoGph_Painter() {
#endif
#if TARGET_PC
if (dusk::settings::enhancements::MirrorMode.getValue())
if (dusk::settings::game::enableMirrorMode)
#elif PLATFORM_WII
if (data_8053a730)
#endif
@@ -2244,7 +2248,7 @@ int mDoGph_Painter() {
#endif
#if TARGET_PC
dusk::g_imguiConsole.draw();
dusk::g_imguiConsole.PostDraw();
#endif
mDoGph_gInf_c::endRender();
+10 -2
View File
@@ -48,6 +48,7 @@
#include "dusk/logging.h"
#include "dusk/time.h"
#include "dusk/main.h"
#include "dusk/imgui/ImGuiEngine.hpp"
#include <aurora/aurora.h>
#include <aurora/event.h>
@@ -57,7 +58,6 @@
#include "cxxopts.hpp"
#include "dusk/config.hpp"
#include "dusk/settings.hpp"
// --- GLOBALS ---
s8 mDoMain::developmentMode = -1;
@@ -158,6 +158,9 @@ void main01(void) {
case AURORA_WINDOW_RESIZED:
mDoGph_gInf_c::setWindowSize(event->windowSize);
break;
case AURORA_DISPLAY_SCALE_CHANGED:
dusk::ImGuiEngine_Initialize(event->windowSize.scale);
break;
case AURORA_EXIT:
goto exit;
}
@@ -227,6 +230,10 @@ static AuroraBackend ParseAuroraBackend(const std::string& value) {
exit(1);
}
static void aurora_imgui_init_callback(const AuroraWindowSize* size) {
dusk::ImGuiEngine_Initialize(size->scale);
}
static void ApplyCVarOverrides(const cxxopts::OptionValue& option) {
if (option.count() == 0) {
return;
@@ -261,6 +268,7 @@ static void ApplyCVarOverrides(const cxxopts::OptionValue& option) {
// =========================================================================
int game_main(int argc, char* argv[]) {
dusk::settings::Register();
dusk::config::FinishRegistration();
cxxopts::ParseResult parsed_arg_options;
@@ -301,12 +309,12 @@ int game_main(int argc, char* argv[]) {
config.windowWidth = 608 * 2;
config.windowHeight = 448 * 2;
config.desiredBackend = ParseAuroraBackend(parsed_arg_options["backend"].as<std::string>());
config.configPath = ".";
config.logCallback = &aurora_log_callback;
config.logLevel = (AuroraLogLevel)parsed_arg_options["log-level"].as<uint8_t>();
config.mem1Size = 256 * 1024 * 1024;
config.mem2Size = 24 * 1024 * 1024;
config.allowJoystickBackgroundEvents = true;
config.imGuiInitCallback = &aurora_imgui_init_callback;
auroraInfo = aurora_initialize(argc, argv, &config);