Merge remote-tracking branch 'origin/main' into android-building

This commit is contained in:
CraftyBoss
2026-04-12 02:53:05 -07:00
102 changed files with 2316 additions and 412 deletions
+3
View File
@@ -1340,6 +1340,7 @@ set(DUSK_FILES
src/dusk/config.cpp
src/dusk/settings.cpp
src/dusk/logging.cpp
src/dusk/frame_interpolation.cpp
src/dusk/layout.cpp
src/dusk/stubs.cpp
src/dusk/endian.cpp
@@ -1362,6 +1363,8 @@ set(DUSK_FILES
src/dusk/imgui/ImGuiMenuEnhancements.hpp
src/dusk/imgui/ImGuiPreLaunchWindow.cpp
src/dusk/imgui/ImGuiPreLaunchWindow.hpp
src/dusk/imgui/ImGuiFirstRunPreset.hpp
src/dusk/imgui/ImGuiFirstRunPreset.cpp
src/dusk/imgui/ImGuiProcessOverlay.cpp
src/dusk/imgui/ImGuiCameraOverlay.cpp
src/dusk/imgui/ImGuiHeapOverlay.cpp
+6
View File
@@ -71,10 +71,16 @@ private:
/* 0xA30 */ dCcD_Sph mSphere2;
/* 0xB68 */ dCcD_Sph mAtSph;
/* 0xCA0 */ dCcU_AtInfo mAtInfo;
#if AVOID_UB
/* 0xCC4 */ u32 mKeys[8];
/* 0xCE4 */ u8 mHIOInit;
/* 0xCE5 */ u8 field_0xce5[0xCE8 - 0xCE5];
#else
// !@bug Seems that the orig developers didn't size mKeys correctly, as ideally it should be len=8, not len=7:
/* 0xCC4 */ u32 mKeys[7];
/* 0xCE0 */ u8 mHIOInit;
/* 0xCE1 */ u8 field_0xce1[0xCE8 - 0xCE1];
#endif
};
STATIC_ASSERT(sizeof(daE_FB_c) == 0xce8);
+1 -2
View File
@@ -39,8 +39,7 @@ public:
/* 0x680 */ s16 mPlayerAngleY;
/* 0x684 */ f32 mPlayerDistanceLimit;
/* 0x688 */ u8 field24_0x688[2];
/* 0x68A */ s16 mActionTimer[3];
/* 0x690 */ s16 mExecuteState;
/* 0x68A */ s16 mActionTimer[4];
/* 0x692 */ s16 mInvincibilityTimer;
/* 0x694 */ s8 mAttentionOFF;
/* 0x695 */ s8 mTKBallSpawned;
+1 -2
View File
@@ -159,8 +159,7 @@ private:
/* 0x00958 */ mDoExt_3DlineMat1_c mRope;
/* 0x00994 */ cXyz field_0x994[100];
/* 0x00E44 */ csXyz field_0xe44[100];
/* 0x0109C */ u8 mRopeCutStatus[10];
/* 0x010A6 */ u8 field_0x10A6[0x01100 - 0x010A6];
/* 0x0109C */ u8 mRopeCutStatus[100];
/* 0x01100 */ u8 mDrawRopes;
/* 0x01101 */ u8 field_0x1101[0x01104 - 0x01101];
/* 0x01104 */ f32 field_0x1104[10];
+3
View File
@@ -196,6 +196,9 @@ public:
void copyReinPos();
void setReinPosHandSubstance(int);
void setReinPosNormalSubstance();
#if TARGET_PC
void lerpControlPoints(f32 alpha);
#endif
void bgCheck();
bool checkSpecialWallHitSubstance(cXyz const&) const;
void setServiceWaitTimer();
+6 -7
View File
@@ -128,10 +128,10 @@ public:
/* 0x0760 */ f32 field_0x760;
/* 0x0764 */ cXyz field_0x764;
/* 0x0770 */ mg_line_s mg_line; // below to mg_hook_s part of mg_line_s?
/* 0x0C20 */ f32 field_0xc20[98];
/* 0x0DA8 */ u8 field_0xDA8[0x0DB0 - 0x0DA8];
/* 0x0DB0 */ f32 field_0xdb0[98];
/* 0x0F38 */ u8 field_0xF38[0x0F40 - 0x0F38];
/* 0x0C20 */ f32 field_0xc20[99];
/* 0x0DA8 */ u8 field_0xDAC[0x0DB0 - 0x0DAC];
/* 0x0DB0 */ f32 field_0xdb0[99];
/* 0x0F3C */ u8 field_0xF38[0x0F40 - 0x0F3C];
/* 0x0F40 */ mDoExt_3DlineMat0_c linemat;
/* 0x0F5C */ f32 field_0xf5c;
/* 0x0F60 */ f32 field_0xf60;
@@ -183,9 +183,8 @@ public:
/* 0x102F */ u8 field_0x102f;
/* 0x1030 */ J3DModel* esa_model[2];
/* 0x1038 */ u8 field_0x1038[0x103C - 0x1038];
/* 0x103C */ s16 field_0x103c[8];
/* 0x104C */ u8 field_0x104C[0x104E - 0x104C];
/* 0x104E */ s16 field_0x104e[8];
/* 0x103C */ s16 field_0x103c[9];
/* 0x104E */ s16 field_0x104e[9];
/* 0x1060 */ cXyz hook_pos;
/* 0x106C */ cXyz field_0x106c;
/* 0x1078 */ cXyz field_0x1078;
+1 -4
View File
@@ -25,10 +25,7 @@ public:
/* 0x1C */ f32 max_speed; // 最大速度 - Maximum Speed
/* 0x20 */ f32 spring_constant; // バネ係数 - Spring Constant
/* 0x24 */ f32 damp_coeff[1]; // 減衰係数 - Damp Coefficient
/* 0x28 */ f32 field_0x28[1];
/* 0x2C */ f32 field_0x2c;
/* 0x30 */ f32 field_0x30;
/* 0x34 */ f32 field_0x34;
/* 0x28 */ f32 field_0x28[4];
/* 0x38 */ f32 vert_swing_width; // 縦揺れ幅 - Vertical Swing Width
/* 0x3C */ f32 shake_dist; // 揺れ距離 - Shake Distance
/* 0x40 */ f32 jump_dist; // 跳ね距離 - Jump Distance
+1 -2
View File
@@ -32,8 +32,7 @@ public:
/* 0x620 */ s16 field_0x620;
/* 0x624 */ mDoExt_McaMorf* mpMorf;
/* 0x628 */ mDoExt_btkAnm* mpBtkAnms[3];
/* 0x634 */ mDoExt_btpAnm* mpBtpAnms[3];
/* 0x640 */ u8 field_0x640[0x654 - 0x640];
/* 0x634 */ mDoExt_btpAnm* mpBtpAnms[8];
/* 0x654 */ s32 field_0x654;
/* 0x658 */ s32 field_0x658;
/* 0x65C */ s32 mAnmResIndex;
+1 -2
View File
@@ -24,8 +24,7 @@ struct lf_s {
/* 0x44 */ f32 field_0x44;
/* 0x48 */ f32 field_0x48;
/* 0x4C */ s16 field_0x4c[2];
/* 0x50 */ s16 field_0x50[2];
/* 0x54 */ u8 field_0x54[4];
/* 0x50 */ s16 field_0x50[4];
/* 0x58 */ f32 field_0x58;
/* 0x5C */ f32 field_0x5c;
/* 0x60 */ f32 field_0x60;
+1 -3
View File
@@ -28,11 +28,9 @@ public:
/* 0x580 */ s16 field_0x580[2];
/* 0x584*/ dCcD_Stts mStts;
/* 0x5c0 */ dCcD_Sph mSph;
/* 0x6f8 */ u32 field_0x6f8[4];
/* 0x6fc */ u8 field_0x6fc[0x70c - 0x708]; // Undefined
/* 0x6f8 */ u32 field_0x6f8[5];
/* 0x70c */ LIGHT_INFLUENCE mLightObj;
/* 0x72c */ u8 field_0x72c;
/* 0x72d */ u8 field_0x72d[0x730 - 0x72d]; //Undefined
};
STATIC_ASSERT(sizeof(obj_maki_class) == 0x730);
+1 -2
View File
@@ -55,8 +55,7 @@ private:
/* 0x710 */ bool mIsHitByBoomerang;
/* 0x711 */ u8 mAction;
/* 0x712 */ u8 field_0x712;
/* 0x714 */ s16 field_0x714[2];
/* 0x718 */ s16 field_0x718;
/* 0x714 */ s16 field_0x714[3];
/* 0x71C */ f32 field_0x71c;
/* 0x720 */ f32 field_0x720;
/* 0x724 */ s16 field_0x724;
+16 -2
View File
@@ -4833,12 +4833,26 @@ inline void dComIfGd_drawXluListDark() {
inline void dComIfGd_drawXluListInvisible() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawXluListInvisible();
#ifdef TARGET_PC
if (dusk::getSettings().game.enableWaterRefraction &&
!dusk::getSettings().game.enableFrameInterpolation) {
#endif
g_dComIfG_gameInfo.drawlist.drawXluListInvisible();
#ifdef TARGET_PC
}
#endif
}
inline void dComIfGd_drawOpaListInvisible() {
ZoneScoped;
g_dComIfG_gameInfo.drawlist.drawOpaListInvisible();
#ifdef TARGET_PC
if (dusk::getSettings().game.enableWaterRefraction &&
!dusk::getSettings().game.enableFrameInterpolation) {
#endif
g_dComIfG_gameInfo.drawlist.drawOpaListInvisible();
#ifdef TARGET_PC
}
#endif
}
inline void dComIfGd_drawXluListZxlu() {
+4
View File
@@ -435,6 +435,10 @@ public:
m3DLineMatSortPacket[param_1->getMaterialID()].setMatDark(param_1);
}
#if TARGET_PC
void refresh3DlineMats(const cXyz& eye);
#endif
void peekZdata() { mPeekZ.peekData(); }
void entryZSortListZxlu(J3DPacket* i_packet, cXyz& param_1) {
entryZSortXluDrawList(mDrawBuffers[DB_LIST_Z_XLU], i_packet, param_1);
+3
View File
@@ -152,6 +152,9 @@ public:
void setRegionCursor(u8 i_value) { mRegionCursor = i_value; }
void setMapDrawFlag(bool i_flag) { mMapDrawFlag = i_flag; }
void resetDrug() { field_0x1238 = 0; }
#if TARGET_PC
void resetScrollArrowMask() { field_0x122d = 0; }
#endif
void offArrowDrawFlag() { mArrowDrawFlag = false; }
void onArrowDrawFlag() { mArrowDrawFlag = true; }
+3 -8
View File
@@ -104,12 +104,8 @@ public:
/* 0x18 */ f32 mWindowPosX;
/* 0x1C */ f32 mWindowPosY;
/* 0x20 */ f32 mWindowScale;
/* 0x24 */ f32 mOptionTypeBGPosX[4];
/* 0x34 */ f32 mTVsettingPosX;
/* 0x38 */ f32 mPointerCalibrationPosX;
/* 0x3C */ f32 mOptionTypeBGPosY[4];
/* 0x4C */ f32 mTVsettingPosY;
/* 0x50 */ f32 mPointerCalibrationPosY;
/* 0x24 */ f32 mOptionTypeBGPosX[6];
/* 0x3C */ f32 mOptionTypeBGPosY[6];
/* 0x54 */ f32 mBarScale[2]; // 0: mSelectBarScale | 1: mUnselectBarScale
/* 0x5C */ f32 mBackgroundPosY;
/* 0x60 */ f32 mArrowOffsetX;
@@ -547,8 +543,7 @@ public:
/* 0x1C */ f32 mVesselTalkPosY;
/* 0x20 */ f32 mVesselPosX_4x3;
/* 0x24 */ f32 mVesselPosY_4x3;
/* 0x28 */ f32 mVesselAlpha[3];
/* 0x34 */ f32 mDropAlpha;
/* 0x28 */ f32 mVesselAlpha[4];
/* 0x38 */ JUtility::TColor mDropOnColorWhite;
/* 0x3C */ JUtility::TColor mDropOnColorBlack;
/* 0x40 */ JUtility::TColor mDropOffColorWhite;
+39
View File
@@ -0,0 +1,39 @@
#ifndef DUSK_FRAME_INTERP_H
#define DUSK_FRAME_INTERP_H
#include <dolphin/mtx.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
struct cXyz;
#ifdef __cplusplus
namespace dusk {
namespace frame_interp {
void ensure_initialized();
void begin_record();
void end_record();
void interpolate(float step);
float get_interpolation_step();
void notify_sim_tick_complete();
uint32_t begin_presentation_ui_pass();
uint32_t get_presentation_ui_advance_ticks();
void end_presentation_ui_pass();
void open_child(const void* key, int32_t id);
void close_child();
void record_final_mtx_raw(const Mtx* dest, const Mtx src);
bool lookup_replacement(const void* source, Mtx out);
bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out);
void camera_eye_from_view_mtx(MtxP view_mtx, cXyz* o_eye);
} // namespace frame_interp
} // namespace dusk
#endif
#endif
+3
View File
@@ -5,6 +5,7 @@
#include <dolphin/gx/GXAurora.h>
#include <dolphin/gx/GXExtra.h>
#include "tracy/Tracy.hpp"
#define GX_DEBUG_GROUP(name, ...) \
do { \
@@ -51,4 +52,6 @@ struct GXScopedDebugGroup {
}
};
#define GX_AND_TRACY_SCOPED(name) GXScopedDebugGroup scope(name); ZoneScopedN(name);
#endif // DUSK_GX_HELPER_H
+4 -1
View File
@@ -52,7 +52,9 @@ struct UserSettings {
// Graphics
ConfigVar<bool> enableBloom;
ConfigVar<bool> useWaterProjectionOffset;
ConfigVar<bool> enableWaterRefraction;
ConfigVar<bool> enableFrameInterpolation;
ConfigVar<int> shadowResolutionMultiplier;
// Audio
ConfigVar<bool> noLowHpSound;
@@ -76,6 +78,7 @@ struct UserSettings {
ConfigVar<std::string> graphicsBackend;
ConfigVar<bool> skipPreLaunchUI;
ConfigVar<bool> showPipelineCompilation;
ConfigVar<bool> wasPresetChosen;
} backend;
};
+3 -5
View File
@@ -15,12 +15,10 @@
#include <Windows.h>
#include <shellapi.h>
#include <intrin.h>
#else
#include "SDL3/SDL_timer.h"
#endif
#include "dusk/logging.h"
constexpr auto DUSK_FRAME_PERIOD = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double>(1001.0 / 30000.0));
class Limiter {
using delta_clock = std::chrono::high_resolution_clock;
using duration_t = std::chrono::nanoseconds;
@@ -101,7 +99,7 @@ private:
} while (current.QuadPart - start.QuadPart < ticksToWait);
}
#else
void NanoSleep(const duration_t duration) { std::this_thread::sleep_for(duration); }
void NanoSleep(const duration_t duration) { SDL_DelayPrecise(duration.count()); }
#endif
};
+19
View File
@@ -541,6 +541,9 @@ public:
virtual int getMaterialID() = 0;
virtual void setMaterial() = 0;
virtual void draw() = 0;
#if TARGET_PC
virtual void refreshGeometryForPresentationEye(const cXyz& eye) {}
#endif
/* 0x4 */ mDoExt_3DlineMat_c* field_0x4;
};
@@ -582,11 +585,19 @@ class dKy_tevstr_c;
class mDoExt_3DlineMat1_c : public mDoExt_3DlineMat_c {
public:
int init(u16, u16, ResTIMG*, int);
#if TARGET_PC
void update(int, GXColor&, dKy_tevstr_c*, const cXyz* presentationEye = nullptr);
void update(int, f32, GXColor&, u16, dKy_tevstr_c*, const cXyz* presentationEye = nullptr);
#else
void update(int, GXColor&, dKy_tevstr_c*);
void update(int, f32, GXColor&, u16, dKy_tevstr_c*);
#endif
int getMaterialID() { return 1; }
void setMaterial();
void draw();
#if TARGET_PC
void refreshGeometryForPresentationEye(const cXyz& eye) override;
#endif
cXyz* getPos(int i_idx) { return mpLines[i_idx].field_0x0; }
f32* getSize(int i_idx) { return mpLines[i_idx].field_0x4; }
@@ -600,6 +611,11 @@ private:
/* 0x34 */ u16 field_0x34;
/* 0x36 */ u8 mIsDrawn;
/* 0x38 */ mDoExt_3Dline_c* mpLines;
#if TARGET_PC
u8 mInterpLineKind;
f32 mInterpLineF;
u16 mInterpLineU16;
#endif
};
class mDoExt_3DlineMat2_c : public mDoExt_3DlineMat1_c {
@@ -616,6 +632,9 @@ public:
void setMatDark(mDoExt_3DlineMat_c* i_mat) { setMat(i_mat); }
void setMat(mDoExt_3DlineMat_c*);
#if TARGET_PC
mDoExt_3DlineMat_c* getFirstMat() const { return mp3DlineMat; }
#endif
virtual void draw();
virtual ~mDoExt_3DlineMatSortPacket() {}
+6 -3
View File
@@ -8,12 +8,14 @@
#include <aurora/aurora.h>
#endif
#define FB_WIDTH_BASE (608)
#define FB_HEIGHT_BASE (448)
#if WIDESCREEN_SUPPORT && !TARGET_PC
#define FB_WIDTH (640)
#define FB_HEIGHT (456)
#else
#define FB_WIDTH (608)
#define FB_HEIGHT (448)
#define FB_WIDTH FB_WIDTH_BASE
#define FB_HEIGHT FB_HEIGHT_BASE
#endif
int mDoGph_Create();
@@ -237,6 +239,7 @@ public:
static void* getZbufferTex() { return mZbufferTex; }
static void setFadeRate(f32 rate) { mFadeRate = rate; }
static f32 getFadeRate() { return mFadeRate; }
static f32 getFadeSpeed() { return mFadeSpeed; }
static bloom_c* getBloom() { return &m_bloom; }
static GXColor& getFadeColor() { return mFadeColor; }
static GXColor& getBackColor() { return mBackColor; }
@@ -275,7 +278,7 @@ public:
#if TARGET_PC
static void onWide(f32 width, f32 height);
#else
#else
static void onWide();
#endif
@@ -3,6 +3,7 @@
#include "JSystem/J3DGraphAnimator/J3DSkinDeform.h"
#include "JSystem/J3DGraphBase/J3DPacket.h"
#include "dusk/frame_interpolation.h"
#include <types.h>
enum J3DMdlFlag {
@@ -101,7 +102,14 @@ public:
void setUserArea(uintptr_t area) { mUserArea = area; }
uintptr_t getUserArea() const { return mUserArea; }
Vec* getBaseScale() { return &mBaseScale; }
void setAnmMtx(int jointNo, Mtx m) { mMtxBuffer->setAnmMtx(jointNo, m); }
void setAnmMtx(int jointNo, Mtx m) {
mMtxBuffer->setAnmMtx(jointNo, m);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(
reinterpret_cast<const Mtx*>(mMtxBuffer->getAnmMtx(jointNo)),
mMtxBuffer->getAnmMtx(jointNo));
#endif
}
MtxP getAnmMtx(int jointNo) { return mMtxBuffer->getAnmMtx(jointNo); }
MtxP getWeightAnmMtx(int i) { return mMtxBuffer->getWeightAnmMtx(i); }
J3DSkinDeform* getSkinDeform() { return mSkinDeform; }
@@ -113,9 +113,6 @@ struct J3DFogInfo {
bool operator==(J3DFogInfo&) const;
J3DFogInfo& operator=(const J3DFogInfo&);
// TODO: Fog data should be converted from big endian (probably?)
// Not sure TP uses it.
/* 0x00 */ u8 mType;
/* 0x01 */ u8 mAdjEnable;
/* 0x02 */ u16 mCenter;
@@ -6,6 +6,7 @@
#include "JSystem/J3DAssert.h"
#include "JSystem/JMath/JMath.h"
#include "dusk/frame_interpolation.h"
#include "dusk/endian.h"
enum J3DSysDrawBuf {
@@ -188,7 +189,15 @@ struct J3DSys {
Mtx& getModelDrawMtx(u16 no) { return mModelDrawMtx[no]; }
J3DShapePacket* getShapePacket() { return mShapePacket; }
void setViewMtx(const Mtx m) { MTXCopy(m, mViewMtx); }
void setViewMtx(const Mtx m) {
#ifdef TARGET_PC
Mtx patched;
if (dusk::frame_interp::lookup_replacement(m, patched)) {
m = patched;
}
#endif
MTXCopy(m, mViewMtx);
}
J3DModel* getModel() { return mModel; }
@@ -101,6 +101,10 @@ public:
void setDrawDoneMethod(EDrawDone drawDone) { mDrawDoneMethod = drawDone; }
void setFader(JUTFader* fader) { mFader = fader; }
#ifdef TARGET_PC
// For frame interpolation
void setFaderSimSteps(u32 steps);
#endif
void resetFader() { setFader(NULL); }
JUTFader* getFader() const { return mFader; }
void setClearColor(JUtility::TColor color) { mClearColor = color; }
+1 -1
View File
@@ -1418,7 +1418,7 @@ bool J2DTevBlock8::insertTexture(u32 param_0, ResTIMG const* p_timg, JUTPalette*
} else {
texture->storeTIMG(p_timg, p_tlut);
}
bool local_38[4];
bool local_38[8];
for (u8 i = 0; i < 8; i++) {
local_38[i] = (mUndeleteFlag & 1 << i) != 0;
}
+2
View File
@@ -511,6 +511,7 @@ void J2DPicture::drawSelf(f32 param_0, f32 param_1) {
}
void J2DPicture::drawSelf(f32 param_0, f32 param_1, Mtx* param_2) {
GX_AND_TRACY_SCOPED("J2DPicture::drawSelf")
if (mTexture[0] != NULL && mTextureNum != 0) {
drawFullSet(mGlobalBounds.i.x + param_0, mGlobalBounds.i.y + param_1,
getWidth(), getHeight(), param_2);
@@ -527,6 +528,7 @@ void J2DPicture::drawFullSet(f32 param_0, f32 param_1, f32 param_2, f32 param_3,
void J2DPicture::draw(f32 x, f32 y, f32 width, f32 height, bool mirrorX, bool mirrorY,
bool rotate90) {
GX_AND_TRACY_SCOPED("J2DPicture::draw")
if (isVisible() && mTextureNum != 0 && mTexture[0] != NULL) {
f32 x2 = x + width;
f32 y2 = y + height;
@@ -78,8 +78,21 @@ bool J2DPictureEx::prepareTexture(u8 param_0) {
return true;
}
#if TARGET_PC
bool checkAlphaCull(const J2DPictureEx* pic) {
return pic->mColorAlpha == 0;
}
#endif
void J2DPictureEx::drawSelf(f32 param_0, f32 param_1, f32 (*param_2)[3][4]) {
GX_AND_TRACY_SCOPED("J2DPictureEx::drawSelf")
if (mMaterial != NULL) {
#if TARGET_PC
if (checkAlphaCull(this)) {
return;
}
#endif
mMaterial->setGX();
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
+2
View File
@@ -278,6 +278,8 @@ J2DPane* J2DScreen::searchUserInfo(u64 tag) {
}
void J2DScreen::drawSelf(f32 param_0, f32 param_1, Mtx* param_2) {
GX_AND_TRACY_SCOPED("J2DScreen::drawSelf")
JUtility::TColor color(mColor);
u8 alpha = (color.a * mAlpha) / 255;
+2
View File
@@ -391,6 +391,8 @@ void J2DTextBox::drawSelf(f32 param_0, f32 param_1) {
}
void J2DTextBox::drawSelf(f32 param_0, f32 param_1, Mtx* p_mtx) {
GX_AND_TRACY_SCOPED("J2DTextBox::drawSelf")
Mtx m;
J2DPrint print(mFont, mCharSpacing, mLineSpacing, mCharColor, mGradientColor, mBlackColor,
@@ -93,6 +93,7 @@ J2DTextBoxEx::~J2DTextBoxEx() {
}
void J2DTextBoxEx::drawSelf(f32 param_0, f32 param_1, Mtx* p_mtx) {
GX_AND_TRACY_SCOPED("J2DTextBoxEx::drawSelf")
Mtx m;
JUTFont* font = NULL;
+2
View File
@@ -410,6 +410,8 @@ void J2DWindow::drawSelf(f32 param_0, f32 param_1) {
}
void J2DWindow::drawSelf(f32 param_0, f32 param_1, Mtx* param_2) {
GX_AND_TRACY_SCOPED("J2DWindow::drawSelf")
JGeometry::TBox2<f32> stack_50(mBounds);
stack_50.addPos(JGeometry::TVec2<f32>(param_0, param_1));
if (stack_50.getWidth() >= field_0x140 && stack_50.getHeight() >= field_0x142) {
@@ -122,6 +122,7 @@ J2DWindowEx::~J2DWindowEx() {
}
void J2DWindowEx::drawSelf(f32 param_0, f32 param_1, f32 (*param_2)[3][4]) {
GX_AND_TRACY_SCOPED("J2DWindowEx::drawSelf")
JGeometry::TBox2<f32> aTStack_50(mBounds);
Mtx auStack_40;
aTStack_50.addPos(JGeometry::TVec2<f32>(param_0, param_1));
@@ -8,6 +8,7 @@
#include "JSystem/J3DGraphBase/J3DShapeMtx.h"
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "dusk/frame_interpolation.h"
#define J3D_ASSERTMSG(LINE, COND, MSG) JUT_ASSERT_MSG(LINE, (COND) != 0, MSG)
#define J3D_WARN1(LINE, MSG, ARG1) JUT_WARN(LINE, MSG, ARG1)
@@ -448,6 +449,16 @@ void J3DModel::calc() {
if (mCalcCallBack != NULL) {
mCalcCallBack(this, 0);
}
#ifdef TARGET_PC
for (u16 i = 0; i < mModelData->getJointNum(); ++i) {
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(getAnmMtx(i)), getAnmMtx(i));
}
for (u16 i = 0; i < mModelData->getWEvlpMtxNum(); ++i) {
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(getWeightAnmMtx(i)), getWeightAnmMtx(i));
}
#endif
}
void J3DModel::entry() {
@@ -484,11 +495,17 @@ void J3DModel::viewCalc() {
if (getMtxCalcMode() == 2) {
J3DCalcViewBaseMtx(j3dSys.getViewMtx(), mBaseScale, mBaseTransformMtx,
(MtxP)&mInternalView);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(&mInternalView, mInternalView);
#endif
}
} else if (isCpuSkinningOn()) {
if (getMtxCalcMode() == 2) {
J3DCalcViewBaseMtx(j3dSys.getViewMtx(), mBaseScale, mBaseTransformMtx,
(MtxP)&mInternalView);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(&mInternalView, mInternalView);
#endif
}
} else if (checkFlag(J3DMdlFlag_SkinPosCpu)) {
mMtxBuffer->calcDrawMtx(getMtxCalcMode(), mBaseScale, mBaseTransformMtx);
@@ -509,6 +526,12 @@ void J3DModel::viewCalc() {
DCStoreRange(getNrmMtxPtr(), mModelData->getDrawMtxNum() * sizeof(Mtx33));
}
#ifdef TARGET_PC
for (u16 i = 0; i < mModelData->getDrawMtxNum(); ++i) {
dusk::frame_interp::record_final_mtx_raw(&getDrawMtxPtr()[i], getDrawMtxPtr()[i]);
}
#endif
prepareShapePackets();
}
+24 -9
View File
@@ -6,9 +6,20 @@
#include "JSystem/J3DGraphBase/J3DMatBlock.h"
#include "JSystem/J3DGraphBase/J3DSys.h"
#include "JSystem/J3DGraphBase/J3DTexture.h"
#include "dusk/frame_interpolation.h"
u16 J3DShapeMtx::sMtxLoadCache[10];
#ifdef TARGET_PC
static void J3DFrameInterpConcat(MtxP lhs, MtxP rhs, Mtx out) {
if (!dusk::frame_interp::lookup_concat_replacement(lhs, rhs, out)) {
MTXConcat(lhs, rhs, out);
}
}
#else
#define J3DFrameInterpConcat MTXConcat
#endif
void J3DShapeMtx::resetMtxLoadCache() {
sMtxLoadCache[0] =
sMtxLoadCache[1] =
@@ -290,7 +301,7 @@ void J3DDifferedTexMtx::loadExecute(f32 const (*param_0)[4]) {
void J3DShapeMtxConcatView::loadMtxConcatView_PNGP(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DFrameInterpConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::load(m);
J3DFifoLoadPosMtxImm(m, slot * 3);
loadNrmMtx(slot, drw, m);
@@ -298,7 +309,7 @@ void J3DShapeMtxConcatView::loadMtxConcatView_PNGP(int slot, u16 drw) const {
void J3DShapeMtxConcatView::loadMtxConcatView_PCPU(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DFrameInterpConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::load(m);
J3DFifoLoadPosMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
loadNrmMtx(slot, drw, m);
@@ -306,7 +317,7 @@ void J3DShapeMtxConcatView::loadMtxConcatView_PCPU(int slot, u16 drw) const {
void J3DShapeMtxConcatView::loadMtxConcatView_NCPU(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DFrameInterpConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::load(m);
J3DFifoLoadPosMtxImm(m, slot * 3);
J3DFifoLoadNrmMtxImm(*j3dSys.getShapePacket()->getBaseMtxPtr(), slot * 3);
@@ -318,7 +329,7 @@ void J3DShapeMtxConcatView::loadMtxConcatView_NCPU(int slot, u16 drw) const {
void J3DShapeMtxConcatView::loadMtxConcatView_PNCPU(int slot, u16 drw) const {
if (J3DDifferedTexMtx::sTexGenBlock != NULL) {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DFrameInterpConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DDifferedTexMtx::loadExecute(m);
}
@@ -331,7 +342,7 @@ void J3DShapeMtxConcatView::loadMtxConcatView_PNCPU(int slot, u16 drw) const {
void J3DShapeMtxConcatView::loadMtxConcatView_PNGP_LOD(int slot, u16 drw) const {
Mtx m;
MTXConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
J3DFrameInterpConcat(*j3dSys.getShapePacket()->getBaseMtxPtr(), j3dSys.getModelDrawMtx(drw), m);
Mtx copy;
j3dSys.getModel()->getModelData()->getInvJointMtx(drw).to_host(copy);
MTXConcat(m, copy, m);
@@ -490,9 +501,11 @@ void J3DShapeMtxBBoardConcatView::load() const {
u16 draw_mtx_index = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex);
if (j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex) == 0) {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(draw_mtx_index), mtx);
J3DFrameInterpConcat(j3dSys.getViewMtx(),
j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(draw_mtx_index), mtx);
} else {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getWeightAnmMtx(draw_mtx_index), mtx);
J3DFrameInterpConcat(j3dSys.getViewMtx(),
j3dSys.getModel()->getWeightAnmMtx(draw_mtx_index), mtx);
}
J3DCalcBBoardMtx(mtx);
@@ -521,9 +534,11 @@ void J3DShapeMtxYBBoardConcatView::load() const {
u16 draw_mtx_index = j3dSys.getModel()->getModelData()->getDrawMtxIndex(mUseMtxIndex);
if (j3dSys.getModel()->getModelData()->getDrawMtxFlag(mUseMtxIndex) == 0) {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(draw_mtx_index), mtx1);
J3DFrameInterpConcat(j3dSys.getViewMtx(),
j3dSys.getModel()->getMtxBuffer()->getUserAnmMtx(draw_mtx_index), mtx1);
} else {
MTXConcat(j3dSys.getViewMtx(), j3dSys.getModel()->getWeightAnmMtx(draw_mtx_index), mtx1);
J3DFrameInterpConcat(j3dSys.getViewMtx(),
j3dSys.getModel()->getWeightAnmMtx(draw_mtx_index), mtx1);
}
J3DCalcYBBoardMtx(mtx1);
@@ -9,6 +9,7 @@
#include "JSystem/JMath/JMath.h"
#include "JSystem/JSupport/JSupport.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "dusk/logging.h"
J3DMaterialFactory::J3DMaterialFactory(J3DMaterialBlock const& i_block) {
mMaterialNum = i_block.mMaterialNum;
@@ -656,7 +657,13 @@ J3DIndTexOrder J3DMaterialFactory::newIndTexOrder(int i_idx, int i_no) const {
J3DIndTexMtx J3DMaterialFactory::newIndTexMtx(int i_idx, int i_no) const {
J3DIndTexMtx dflt;
if (mpIndInitData[i_idx].mEnabled == true) {
#if TARGET_LITTLE_ENDIAN
J3DIndTexMtxInfo indTexMtxInfo = mpIndInitData[i_idx].mIndTexMtxInfo[i_no];
be_swap(indTexMtxInfo.field_0x0);
return indTexMtxInfo;
#else
return J3DIndTexMtx(mpIndInitData[i_idx].mIndTexMtxInfo[i_no]);
#endif
} else {
return dflt;
}
@@ -684,7 +691,19 @@ J3DFog J3DMaterialFactory::newFog(int i_idx) const {
J3DFog fog;
J3DMaterialInitData* mtl_init_data = &mpMaterialInitData[mpMaterialID[i_idx]];
if (mtl_init_data->mFogIdx != 0xffff) {
#if TARGET_LITTLE_ENDIAN
J3DFogInfo fogInfo = mpFogInfo[mtl_init_data->mFogIdx];
be_swap(fogInfo.mCenter);
be_swap(fogInfo.mStartZ);
be_swap(fogInfo.mEndZ);
be_swap(fogInfo.mNearZ);
be_swap(fogInfo.mFarZ);
for (int i = 0; i < 10; i++)
be_swap(fogInfo.mFogAdjTable.r[i]);
fog.setFogInfo(fogInfo);
#else
fog.setFogInfo(mpFogInfo[mtl_init_data->mFogIdx]);
#endif
}
return fog;
}
+73 -29
View File
@@ -1,26 +1,30 @@
#include "JSystem/JSystem.h" // IWYU pragma: keep
#include <dolphin/gx.h>
#include <dolphin/vi.h>
#include <gx.h>
#include <stdint.h>
#include <vi.h>
#include "SDL3/SDL_timer.h"
#include "JSystem/J2DGraph/J2DOrthoGraph.h"
#include "JSystem/JFramework/JFWDisplay.h"
#include "JSystem/J2DGraph/J2DOrthoGraph.h"
#include "JSystem/JKernel/JKRHeap.h"
#include "JSystem/JUtility/JUTAssert.h"
#include "JSystem/JUtility/JUTConsole.h"
#include "JSystem/JUtility/JUTDbPrint.h"
#include "JSystem/JUtility/JUTProcBar.h"
#include "aurora/aurora.h"
#include <gx.h>
#include <vi.h>
#include "global.h"
#include <stdint.h>
#ifdef TARGET_PC
#include "dusk/dusk.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
#include "dusk/settings.h"
#include "global.h"
#include "dusk/time.h"
#include "SDL3/SDL_timer.h"
#include "tracy/Tracy.hpp"
#include <chrono>
#endif
void JFWDisplay::ctor_subroutine(bool enableAlpha) {
mEnableAlpha = enableAlpha;
mClamp = GX_CLAMP_TOP | GX_CLAMP_BOTTOM;
@@ -201,6 +205,14 @@ void JFWDisplay::preGX() {
}
}
#ifdef TARGET_PC
static s32 s_faderSimSteps = -1;
void JFWDisplay::setFaderSimSteps(u32 steps) {
s_faderSimSteps = static_cast<s32>(steps);
}
#endif
void JFWDisplay::endGX() {
s32 bufferNum = JUTXfb::getManager()->getBufferNum();
u16 width = JUTVideo::getManager()->getFbWidth();
@@ -211,7 +223,26 @@ void JFWDisplay::endGX() {
if (mFader != NULL) {
ortho.setPort();
#ifdef TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
u32 advance_count = 1;
if (s_faderSimSteps >= 0) {
advance_count = static_cast<u32>(s_faderSimSteps);
s_faderSimSteps = -1;
}
for (u32 i = 0; i < advance_count; i++) {
mFader->control();
}
if (mFader->getStatus() != 1) {
mFader->draw();
}
} else {
mFader->control();
mFader->draw();
}
#else
mFader->control();
#endif
}
ortho.setPort();
JUTDbPrint::getManager()->flush();
@@ -350,49 +381,63 @@ void JFWDisplay::waitBlanking(int param_0) {
}
}
#if TARGET_PC
constexpr auto FRAME_PERIOD = std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::duration<double>(1001.0 / 30000.0));
constexpr auto RETRACE_PERIOD = FRAME_PERIOD / 2;
static void waitPrecise(Limiter& limiter, Uint64 targetNs) {
const auto sleepTime = limiter.SleepTime(std::chrono::nanoseconds(targetNs));
dusk::frameUsagePct =
100.0f * (1.0f - static_cast<float>(sleepTime.count()) / static_cast<float>(targetNs));
limiter.Sleep(std::chrono::nanoseconds(targetNs));
}
#endif
static void waitForTick(u32 p1, u16 p2) {
ZoneScopedC(tracy::Color::DimGray);
#if TARGET_PC
#if TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
return;
}
if (dusk::getTransientSettings().skipFrameRateLimit) {
p1 = OS_TIMER_CLOCK / 120;
}
#endif
ZoneScopedC(tracy::Color::DimGray);
#endif
if (p1 != 0)
{
if (p1 != 0) {
#if TARGET_PC
static Limiter limiter;
waitPrecise(limiter, static_cast<Uint64>(OSTicksToMicroseconds(p1)) * 1000ULL);
#else
static OSTime nextTick = OSGetTime();
OSTime time = OSGetTime();
OSTime waitTime = (nextTick > time) ? (nextTick - time) : 0;
while (time < nextTick) {
JFWDisplay::getManager()->threadSleep((nextTick - time));
time = OSGetTime();
}
dusk::frameUsagePct = 100.0f * (1.0f - (float)waitTime / (float)p1);
nextTick = time + p1;
#endif
} else {
static u32 nextCount = VIGetRetraceCount();
u32 uVar1 = (p2 == 0) ? 1 : p2;
#if TARGET_PC
static Limiter limiter;
waitPrecise(limiter, static_cast<Uint64>((RETRACE_PERIOD * uVar1).count()));
#else
static u32 nextCount = VIGetRetraceCount();
OSMessage msg;
do {
if (!OSReceiveMessage(JUTVideo::getManager()->getMessageQueue(), &msg,
OS_MESSAGE_BLOCK))
{
OS_MESSAGE_BLOCK)) {
msg = 0;
}
} while (((intptr_t)msg - (intptr_t)nextCount) < 0);
dusk::frameUsagePct = 100.0f;
nextCount = (intptr_t)msg + uVar1;
#endif
}
}
JSUList<JFWAlarm> JFWAlarm::sList(false);
#if TARGET_PC
void JFWDisplay::threadSleep(s64 time) {
SDL_DelayNS(OSTicksToMicroseconds(time) * 1'000);
}
#else
static void JFWThreadAlarmHandler(OSAlarm* p_alarm, OSContext* p_ctx) {
JFWAlarm* alarm = static_cast<JFWAlarm*>(p_alarm);
alarm->removeLink();
@@ -410,7 +455,6 @@ void JFWDisplay::threadSleep(s64 time) {
OSSuspendThread(alarm.getThread());
OSRestoreInterrupts(status);
}
#endif
static void dummy() {
JUTXfb::getManager()->setDisplayingXfbIndex(0);
@@ -450,7 +494,7 @@ void JFWDisplay::clearEfb(GXColor color) {
void JFWDisplay::clearEfb(int param_0, int param_1, int param_2, int param_3, GXColor color) {
STUB_RET();
u16 width;
u16 height;
Mtx44 mtx;
+16 -12
View File
@@ -19,24 +19,24 @@ JUTFader::JUTFader(int x, int y, int width, int height, JUtility::TColor pColor)
void JUTFader::control() {
if (0 <= mEStatus && mEStatus-- == 0) {
mStatus = field_0x24;
}
mStatus = field_0x24;
}
if (mStatus == 1) {
return;
}
if (mStatus == 1) {
return;
}
switch (mStatus) {
switch (mStatus) {
case 0:
mColor.a = 0xFF;
break;
case 2:
#if AVOID_UB
#if AVOID_UB
if (field_0x8 == 0) {
mStatus = 1;
break;
}
#endif
#endif
mColor.a = 0xFF - ((++field_0xa * 0xFF) / field_0x8);
if (field_0xa >= field_0x8) {
@@ -45,12 +45,12 @@ void JUTFader::control() {
break;
case 3:
#if AVOID_UB
#if AVOID_UB
if (field_0x8 == 0) {
mStatus = 0;
break;
}
#endif
#endif
mColor.a = ((++field_0xa * 0xFF) / field_0x8);
if (field_0xa >= field_0x8) {
@@ -58,8 +58,12 @@ void JUTFader::control() {
}
break;
}
draw();
}
#ifndef TARGET_PC
// Frame interpolation: draw call moved to JFWDisplay
draw();
#endif
}
void JUTFader::draw() {
+2 -2
View File
@@ -435,10 +435,10 @@ void JUTResFont::loadImage(int code, GXTexMapID id){
mHeight = cellRow * cellH;
#if TARGET_PC
const auto found = mGlyphTextures->textures.find(code);
const auto found = mGlyphTextures->textures.find(pageIdx);
GXTexObj* texObj;
if (found == mGlyphTextures->textures.end()) {
texObj = &mGlyphTextures->textures[code];
texObj = &mGlyphTextures->textures[pageIdx];
void* pImg = &mpGlyphBlocks[i]->data[pageIdx * mpGlyphBlocks[i]->textureSize];
GXInitTexObj(texObj, pImg, mpGlyphBlocks[i]->textureWidth,
mpGlyphBlocks[i]->textureHeight, (GXTexFmt)(u16)mpGlyphBlocks[i]->textureFormat,
+2
View File
@@ -182,7 +182,9 @@ void JUTVideo::postRetraceProc(u32 retrace_count) {
sManager->mPostCallback(retrace_count);
}
#ifndef TARGET_PC // Not read by JFWDisplay waitForTick
OSSendMessage(&sManager->mMessageQueue, (OSMessage)(uintptr_t)VIGetRetraceCount(), OS_MESSAGE_NOBLOCK);
#endif
}
void JUTVideo::setRenderMode(GXRenderModeObj const* pObj) {
+5
View File
@@ -14,6 +14,7 @@
#include "os_report.h"
#include "dusk/logging.h"
#if !TARGET_PC
DynamicModuleControlBase* DynamicModuleControlBase::mFirst;
DynamicModuleControlBase* DynamicModuleControlBase::mLast;
@@ -139,6 +140,7 @@ DynamicModuleControl::DynamicModuleControl(char const* name) {
mSize = 0;
mAsyncLoadCallback = NULL;
}
#endif
u32 DynamicModuleControl::sAllocBytes;
@@ -169,6 +171,7 @@ bool DynamicModuleControl::initialize() {
return true;
}
#if !TARGET_PC
bool DynamicModuleControl::callback(void* moduleControlPtr) {
DynamicModuleControl* moduleControl = (DynamicModuleControl*)moduleControlPtr;
return moduleControl->do_load();
@@ -484,3 +487,5 @@ extern "C" void ModuleDestructorsX(void (*const *dtors)()) {
dtors++;
}
}
#endif
+8
View File
@@ -898,6 +898,9 @@ BOOL cDyl_IsLinked(s16 i_ProfName) {
}
BOOL cDyl_Unlink(s16 i_ProfName) {
#if TARGET_PC
return FALSE;
#else
#if DEBUG
cCc_Check();
#endif
@@ -911,9 +914,13 @@ BOOL cDyl_Unlink(s16 i_ProfName) {
}
return FALSE;
#endif
}
int cDyl_LinkASync(s16 i_ProfName) {
#if TARGET_PC
return cPhs_COMPLEATE_e;
#else
#if DEBUG
cCc_Check();
#endif
@@ -953,6 +960,7 @@ int cDyl_LinkASync(s16 i_ProfName) {
}
return cPhs_COMPLEATE_e;
#endif
}
static int cDyl_InitCallback(void* param_0) {
+24 -10
View File
@@ -850,7 +850,7 @@ daAlink_FaceTexData const daAlink_c::m_faceTexDataTable[] = {
{dRes_ID_ALANM_BTP_FDAM01_e, dRes_ID_ALANM_BTK_FFINISHA_e},
{dRes_ID_ALANM_BTP_FFINISHA_e, dRes_ID_ALANM_BTK_FFINISHED_e},
{dRes_ID_ALANM_BTP_FARELORD_e, dRes_ID_ALANM_BTK_FARELORD_e},
{dRes_ID_ALANM_BTP_FARELORDTAME_e, dRes_ID_ALANM_BTK_FARELORDTAME_e},
{dRes_ID_ALANM_BTP_FARELORDTAME_e, dRes_ID_ALANM_BTK_FARELORDTAME_e},
{dRes_ID_ALANM_BTP_FPUSHW_e, dRes_ID_ALANM_BTK_FPUSHW_e},
{dRes_ID_ALANM_BTP_FPULLW_e, dRes_ID_ALANM_BTK_FPULLW_e},
{dRes_ID_ALANM_BTP_FWAITST_e, dRes_ID_ALANM_BTK_FWAITST_e},
@@ -1001,7 +1001,7 @@ daAlink_FaceTexData const daAlink_c::m_faceTexDataTable[] = {
{dRes_ID_ALANM_BTP_WL_FSWIMDIEA_e, dRes_ID_ALANM_BTK_WL_FA_e},
{dRes_ID_ALANM_BTP_WL_FSWIMDIEP_e, dRes_ID_ALANM_BTK_WL_FA_e},
{dRes_ID_ALANM_BTP_WL_FMDSHOCK_e, dRes_ID_ALANM_BTK_WL_FMDSHOCK_e},
{dRes_ID_ALANM_BTP_WL_FENTRANCE_e, dRes_ID_ALANM_BTK_WL_FENTRANCE_e},
{dRes_ID_ALANM_BTP_WL_FENTRANCE_e, dRes_ID_ALANM_BTK_WL_FENTRANCE_e},
{dRes_ID_ALANM_BTP_WL_FHOWLC_e, dRes_ID_ALANM_BTK_WL_FA_e},
{dRes_ID_ALANM_BTP_WL_FC_e, dRes_ID_ALANM_BTK_WL_FA_e},
};
@@ -4943,7 +4943,7 @@ int daAlink_c::create() {
if (dComIfG_resLoad(&mShieldPhaseReq, mShieldArcName, mpShieldArcHeap) != cPhs_COMPLEATE_e) {
return cPhs_INIT_e;
}
u32 heapSize = 0x3E930;
heapSize |= 0x80000000;
heapSize |= 0x40000000;
@@ -5885,7 +5885,7 @@ void daAlink_c::setItemMatrix(int param_0) {
|| (mProcID == PROC_CUT_REVERSE && mProcVar2.field_0x300c != 0)
|| mProcID == PROC_GUARD_BREAK
|| (mEquipItem == 0x103 && !checkEndResetFlg1(ERFLG1_SHIELD_BACKBONE) && !checkModeFlg(0x400))
)
)
{
mShieldModel->setBaseTRMtx(mpLinkModel->getAnmMtx(mRightItemJntNo));
@@ -5949,9 +5949,23 @@ void daAlink_c::setItemMatrix(int param_0) {
mpLinkBootModels[0]->setAnmMtx(3, mpLinkModel->getAnmMtx(0x15));
mDoMtx_stack_c::XrotS(-0x8000);
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(1));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x19), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(2));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x1A), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(3));
#ifdef TARGET_PC
if (dusk::getSettings().game.enableFrameInterpolation) {
Mtx boot_mtx;
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), boot_mtx);
mpLinkBootModels[1]->setAnmMtx(1, boot_mtx);
mDoMtx_concat(mpLinkModel->getAnmMtx(0x19), mDoMtx_stack_c::get(), boot_mtx);
mpLinkBootModels[1]->setAnmMtx(2, boot_mtx);
mDoMtx_concat(mpLinkModel->getAnmMtx(0x1A), mDoMtx_stack_c::get(), boot_mtx);
mpLinkBootModels[1]->setAnmMtx(3, boot_mtx);
} else {
#endif
mDoMtx_concat(mpLinkModel->getAnmMtx(0x18), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(1));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x19), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(2));
mDoMtx_concat(mpLinkModel->getAnmMtx(0x1A), mDoMtx_stack_c::get(), mpLinkBootModels[1]->getAnmMtx(3));
#ifdef TARGET_PC
}
#endif
}
if (!checkNoResetFlg2(FLG2_STATUS_WINDOW_DRAW)) {
@@ -6279,7 +6293,7 @@ void daAlink_c::setWolfAtCollision() {
void daAlink_c::resetAtCollision(BOOL param_0) {
if (checkNoResetFlg0(FLG0_CUT_AT_FLG)) {
if (param_0
if (param_0
&& !setSwordHitVibration(&mAtCps[0])
&& !setSwordHitVibration(&mAtCps[1])
&& !setSwordHitVibration(&mAtCps[2])
@@ -14055,7 +14069,7 @@ void daAlink_c::setMetamorphoseModel(BOOL i_isChangeToWolf) {
JKRHeap* heap = setItemHeap();
mHeldItemModel = initModel(loadAramBmd(dRes_ID_ALANM_BMD_AL_WF_e, 0x6000), 0);
if (!mItemBck.init(bck, FALSE, 2, 1.0f, 0, -1, false)) {
JUT_ASSERT(20842, FALSE);
}
@@ -16727,7 +16741,7 @@ int daAlink_c::procAutoJump() {
#if VERSION == VERSION_SHIELD_DEBUG
if (!checkStageName("F_SP115") && mGrabItemAcKeep.getActor() != NULL) {
if ((fopAcM_GetName(mGrabItemAcKeep.getActor()) == fpcNm_NI_e && ((ni_class*)mGrabItemAcKeep.getActor())->checkGold() != TRUE) ||
(fopAcM_GetName(mGrabItemAcKeep.getActor()) == fpcNm_NPC_TKJ2_e))
(fopAcM_GetName(mGrabItemAcKeep.getActor()) == fpcNm_NPC_TKJ2_e))
{
mMaxSpeed = mpHIO->mAutoJump.m.mCuccoJumpMaxSpeed;
field_0x3478 = mpHIO->mAutoJump.m.mCuccoFallMaxSpeed;
+12 -5
View File
@@ -9,11 +9,6 @@ void daAlink_c::handleQuickTransform() {
return;
}
// Ensure that link is not in a cutscene.
if (checkEventRun()) {
return;
}
// Check to see if Link has the ability to transform.
if (!dComIfGs_isEventBit(dSv_event_flag_c::M_077)) {
return;
@@ -30,8 +25,20 @@ void daAlink_c::handleQuickTransform() {
return;
}
// Ensure that link is not in a cutscene.
if (checkEventRun()) {
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return;
}
mDoCPd_c::getCpadInfo(PAD_1).mPressedButtonFlags = 0;
// Don't allow quick transform while in the STAR tent.
if (checkStageName("R_SP161")) {
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
return;
}
// Ensure that the Z Button is not dimmed
if (meterDrawPtr->getButtonZAlpha() != 1.f) {
Z2GetAudioMgr()->seStart(Z2SE_SYS_ERROR, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
+2 -2
View File
@@ -398,7 +398,7 @@ static int daE_TK2_Execute(e_tk2_class* i_this) {
cXyz cStack_94;
cXyz cStack_a0;
if (i_this->mExecuteState == 0x00) {
if (i_this->mActionTimer[3] == 0x00) {
dBgS_ObjGndChk_Spl ground_check;
cStack_94 = actor->current.pos;
cStack_94.y += 200.0f;
@@ -602,7 +602,7 @@ static int daE_TK2_Create(fopAc_ac_c* actor) {
i_this->mSound.init(&actor->current.pos, &actor->eyePos, 0x3, 0x1);
i_this->mSound.setEnemyName("E_tk2");
i_this->mAtInfo.mpSound = &i_this->mSound;
i_this->mExecuteState = 0x14;
i_this->mActionTimer[3] = 0x14;
daE_TK2_Execute(i_this);
}
return phase;
+25
View File
@@ -167,6 +167,30 @@ static dCcD_SrcSph cc_vt_magic_src = {
} // mSphAttr
};
// !@bug The i<40 loops that index these arrays read one element past the end; on
// GC/Wii the OOB reads land on adjacent rodata instead of a defined value.
#if AVOID_UB
static u8 va_tag_set_size[40] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
0x02, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02,
0x00,
};
static u8 va_tag_set_num[40] = {
0x01, 0x0C, 0x16, 0x1F, 0x21, 0x2A, 0x2B, 0x02, 0x04, 0x0D, 0x0F, 0x15, 0x18,
0x20, 0x2C, 0x03, 0x05, 0x06, 0x0B, 0x10, 0x17, 0x19, 0x1A, 0x22, 0x24, 0x29,
0x2D, 0x34, 0x49, 0x52, 0x36, 0x3E, 0x54, 0x5C, 0x39, 0x41, 0x4C, 0x56, 0x5E,
0x00,
};
static f32 va_tag_offset[40] = {
20.0f, 20.0f, 20.0f, 20.0f, 20.0f, 0.0f, 40.0f, 0.0f, 30.0f, 10.0f, 0.0f, 0.0f, 20.0f,
0.0f, 10.0f, 20.0f, 40.0f, 0.0f, 20.0f, 0.0f, 0.0f, 20.0f, 0.0f, 10.0f, 0.0f, 0.0f,
20.0f, 10.0f, 20.0f, 30.0f, 0.0f, 10.0f, 20.0f, 0.0f, 0.0f, 10.0f, 20.0f, 30.0f, 0.0f,
0.0f,
};
#else
static u8 va_tag_set_size[39] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
@@ -184,6 +208,7 @@ static f32 va_tag_offset[39] = {
0.0f, 10.0f, 20.0f, 40.0f, 0.0f, 20.0f, 0.0f, 0.0f, 20.0f, 0.0f, 10.0f, 0.0f, 0.0f,
20.0f, 10.0f, 20.0f, 30.0f, 0.0f, 10.0f, 20.0f, 0.0f, 0.0f, 10.0f, 20.0f, 30.0f, 0.0f,
};
#endif
} // namespace
+53
View File
@@ -20,6 +20,21 @@
#include <cmath>
#include <cstring>
#if TARGET_PC
#include "dusk/dusk.h"
namespace {
// FRAME INTERP NOTE: Sim tick control point snapshots for interpolation
constexpr int kHorseReinSimMax = 75;
cXyz s_horseReinSimPrev[kHorseReinSimMax];
cXyz s_horseReinSimCurr[kHorseReinSimMax];
int s_horseReinSimNumPrev;
int s_horseReinSimNumCurr;
bool s_horseReinSimPrevValid;
bool s_horseReinSimCurrValid;
} // namespace
#endif
#define ANM_HS_BACK_WALK 6
#define ANM_HS_WALK_START 7
#define ANM_HS_EXCITEMENT 8
@@ -3016,6 +3031,20 @@ void daHorse_c::copyReinPos() {
for (i = rein->field_0x8[0] - 1; i >= 0; i--, pos_p++) {
*pos_p = rein->field_0x0[0][i];
}
#if TARGET_PC
if (field_0x1204 > 0) {
if (s_horseReinSimCurrValid && s_horseReinSimNumCurr > 0) {
memcpy(s_horseReinSimPrev, s_horseReinSimCurr, s_horseReinSimNumCurr * sizeof(cXyz));
s_horseReinSimNumPrev = s_horseReinSimNumCurr;
s_horseReinSimPrevValid = true;
}
memcpy(s_horseReinSimCurr, m_reinLine.getPos(0), field_0x1204 * sizeof(cXyz));
s_horseReinSimNumCurr = field_0x1204;
s_horseReinSimCurrValid = true;
} else {
s_horseReinSimCurrValid = false;
}
#endif
}
void daHorse_c::setReinPosHandSubstance(int param_0) {
@@ -3127,6 +3156,30 @@ void daHorse_c::setReinPosNormalSubstance() {
copyReinPos();
}
#if TARGET_PC
void daHorse_c::lerpControlPoints(f32 alpha) {
// FRAME INTERP NOTE: Currently only lerping points for Epona's reins. Need a more global solution.
if (!dusk::getSettings().game.enableFrameInterpolation || !s_horseReinSimPrevValid || !s_horseReinSimCurrValid) {
return;
}
const int nCurr = s_horseReinSimNumCurr;
const int nPrev = s_horseReinSimNumPrev;
if (nCurr <= 0) {
return;
}
int n = nPrev < nCurr ? nPrev : nCurr;
if (n <= 0 || n > kHorseReinSimMax) {
return;
}
cXyz* dst = m_reinLine.getPos(0);
for (int i = 0; i < n; i++) {
const cXyz& p0 = s_horseReinSimPrev[i];
const cXyz& p1 = s_horseReinSimCurr[i];
dst[i] = p0 + (p1 - p0) * alpha;
}
}
#endif
void daHorse_c::bgCheck() {
if (m_procID != PROC_LARGE_DAMAGE_e) {
static cXyz localCenterPos(0.0f, 100.0f, 0.0f);
+7
View File
@@ -14,6 +14,7 @@
#include "d/d_msg_object.h"
#include "d/d_s_play.h"
#include "d/d_debug_viewer.h"
#include "dusk/frame_interpolation.h"
static f32 dummy_lit_3777(int idx, u8 foo) {
Vec dummy_vec = {0.0f, 0.0f, 0.0f};
@@ -1052,6 +1053,12 @@ void daMidna_c::setBodyPartMatrix() {
mpModel->setAnmMtx(i, mpShadowModel->getAnmMtx(i));
}
mpModel->calcWeightEnvelopeMtx();
#ifdef TARGET_PC
// Frame interpolation: Record weight envelopes for Midna here, as they are otherwise missed causing distortion
for (u16 i = 0; i < mpModel->getModelData()->getWEvlpMtxNum(); i++) {
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(mpModel->getWeightAnmMtx(i)), mpModel->getWeightAnmMtx(i));
}
#endif
}
mDoMtx_stack_c::transS(mpShadowModel->getAnmMtx(JNT_BACKBONE1)[0][3],
-8
View File
@@ -300,19 +300,11 @@ int daGrdWater_c::Draw() {
J3DTexMtxInfo* mtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo();
if (mtxInfo != NULL) {
Mtx afStack_50;
#if TARGET_PC
C_MTXLightPerspective(afStack_50, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect,
1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0.0f);
#else
C_MTXLightPerspective(afStack_50, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect,
1.0f, 1.0f, -0.01f, 0.0f);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(afStack_50);
#endif
mtxInfo->setEffectMtx(afStack_50);
modelData2->simpleCalcMaterial(0, (MtxP)j3dDefaultMtx);
}
-7
View File
@@ -371,15 +371,8 @@ int daLv3Water_c::Draw() {
texMtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo();
if (texMtxInfo != NULL) {
Mtx lightProjMtx;
#if TARGET_PC
C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy,
dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0.0f);
#else
C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy,
dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0.0f);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx);
#endif
-7
View File
@@ -197,14 +197,7 @@ int daLv3Water2_c::Draw() {
texMtxInfo = &btkMaterial->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo();
if(texMtxInfo) {
Mtx lightProjMtx;
#if TARGET_PC
C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy,
dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0);
#else
C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx);
#endif
-7
View File
@@ -27,15 +27,8 @@ static int daObj_Lv3waterB_Draw(obj_lv3WaterB_class* i_this) {
J3DTexMtxInfo* tex_mtx_info = &material_p->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo();
if (tex_mtx_info != NULL) {
Mtx m;
#if TARGET_PC
C_MTXLightPerspective(m, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f, 1.0f,
dusk::getSettings().game.useWaterProjectionOffset ? -0.015f : 0.0f, 0.0f);
#else
C_MTXLightPerspective(m, dComIfGd_getView()->fovy, dComIfGd_getView()->aspect, 1.0f,
1.0f, -0.015f, 0.0f);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(m);
#endif
-7
View File
@@ -313,15 +313,8 @@ int daObjRotStair_c::Draw() {
J3DTexMtxInfo* texMtxInfo = &material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo();
if (texMtxInfo != NULL) {
Mtx lightMtx;
#if TARGET_PC
C_MTXLightPerspective(lightMtx, dComIfGd_getView()->fovy,
dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0);
#else
C_MTXLightPerspective(lightMtx, dComIfGd_getView()->fovy,
dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(lightMtx);
#endif
+2 -2
View File
@@ -411,7 +411,7 @@ void daObjTOMBO_c::BoomChk() {
speedF = 5.0f;
field_0x71c = 5.0f;
mIsHitByBoomerang = false;
field_0x718 = 100;
field_0x714[2] = 100;
mpMorf->setAnm((J3DAnmTransform*)dComIfG_getObjectRes("Tombo", 6), 2, 5.0f, 1.0f,
0.0f, -1.0f);
home.pos = current.pos;
@@ -422,7 +422,7 @@ void daObjTOMBO_c::BoomChk() {
mIsHitByBoomerang = false;
speedF = 5.0f;
field_0x71c = 5.0f;
field_0x718 = 100;
field_0x714[2] = 100;
mpMorf->setAnm((J3DAnmTransform*)dComIfG_getObjectRes("Tombo", 6), 2, 5.0f, 1.0f,
0.0f, -1.0f);
current.pos.y = old.pos.y = playerPos.y + 100.0f;
-7
View File
@@ -36,15 +36,8 @@ static int daObj_Tp_Draw(obj_tp_class* i_this) {
&material->getTexGenBlock()->getTexMtx(0)->getTexMtxInfo();
if (texMtxInfo != NULL) {
Mtx lightProjMtx;
#if TARGET_PC
C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy,
dComIfGd_getView()->aspect, 1.0f, 1.0f, dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0);
#else
C_MTXLightPerspective(lightProjMtx, dComIfGd_getView()->fovy,
dComIfGd_getView()->aspect, 1.0f, 1.0f, -0.01f, 0);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomLightProjection(lightProjMtx);
#endif
+13 -7
View File
@@ -122,7 +122,7 @@ static procFunc daTitleProc[6] = {
int daTitle_c::create() {
fopAcM_ct(this, daTitle_c);
int phase_state = dComIfG_resLoad(&mPhaseReq, l_arcName);
if (phase_state != cPhs_COMPLEATE_e) {
return phase_state;
@@ -152,15 +152,21 @@ int daTitle_c::createHeapCallBack(fopAc_ac_c* actor) {
}
int daTitle_c::Execute() {
#if PLATFORM_WII || PLATFORM_SHIELD
#if PLATFORM_WII || PLATFORM_SHIELD
mDoGph_gInf_c::resetDimming();
#endif
#endif
if (fopOvlpM_IsPeek()) {
return 1;
}
dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
#ifdef TARGET_PC
if (!dusk::getSettings().game.enableFrameInterpolation) {
#endif
dMenu_Collect3D_c::setViewPortOffsetY(0.0f);
#ifdef TARGET_PC
}
#endif
if (mDoRst::isReset()) {
return 1;
@@ -169,9 +175,9 @@ int daTitle_c::Execute() {
(this->*daTitleProc[mProcID])();
KeyWaitAnm();
#if VERSION == VERSION_SHIELD_DEBUG
#if VERSION == VERSION_SHIELD_DEBUG
KeyWaitPosMove();
#endif
#endif
return 1;
}
@@ -390,7 +396,7 @@ int daTitle_c::Delete() {
dComIfG_resDelete(&mPhaseReq, l_arcName);
JKR_DELETE(mTitle.Scr);
JKR_DELETE(field_0x600);
mpMount->getArchive()->removeResourceAll();
JKRUnmountArchive(mpMount->getArchive());
mpMount->destroy();
+25 -2
View File
@@ -5,6 +5,8 @@
#include "JSystem/J3DGraphBase/J3DDrawBuffer.h"
#include "SSystem/SComponent/c_counter.h"
#include "dusk/frame_interpolation.h"
#if TARGET_PC
const u16 l_J_Ohana00_64TEX__width = 64;
const u16 l_J_Ohana00_64TEX__height = 64;
@@ -695,7 +697,16 @@ void dFlower_packet_c::draw() {
GXSetChanAmbColor(GX_COLOR0A0, sp64);
if (!cLib_checkBit<u8>(sp44->m_state, 4) && !cLib_checkBit<u8>(sp44->m_state, 0x40)) {
GXLoadPosMtxImm(sp44->m_modelMtx, 0);
#ifdef TARGET_PC
Mtx flower_mtx;
if (dusk::frame_interp::lookup_replacement(reinterpret_cast<const void*>(&sp44->m_modelMtx), flower_mtx)) {
GXLoadPosMtxImm(flower_mtx, 0);
} else {
#endif
GXLoadPosMtxImm(sp44->m_modelMtx, 0);
#ifdef TARGET_PC
}
#endif
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
#if TARGET_PC
@@ -841,7 +852,16 @@ void dFlower_packet_c::draw() {
sp30++;
if (!cLib_checkBit<u8>(sp34->m_state, 4) && cLib_checkBit<u8>(sp34->m_state, 0x40)) {
GXLoadPosMtxImm(sp34->m_modelMtx, 0);
#ifdef TARGET_PC
Mtx flower_mtx;
if (dusk::frame_interp::lookup_replacement(reinterpret_cast<const void*>(&sp34->m_modelMtx), flower_mtx)) {
GXLoadPosMtxImm(flower_mtx, 0);
} else {
#endif
GXLoadPosMtxImm(sp34->m_modelMtx, 0);
#ifdef TARGET_PC
}
#endif
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
#if TARGET_PC
@@ -973,6 +993,9 @@ void dFlower_packet_c::update() {
mDoMtx_stack_c::copy(temp_r28);
mDoMtx_stack_c::scaleM(temp_f31, temp_f31, temp_f31);
cMtx_concat(j3dSys.getViewMtx(), temp_r28, data_p->m_modelMtx);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(&data_p->m_modelMtx), data_p->m_modelMtx);
#endif
}
}
+15 -1
View File
@@ -11,6 +11,8 @@
#include "d/d_camera.h"
#include "f_op/f_op_camera_mng.h"
#include "dusk/frame_interpolation.h"
const u16 l_M_Hijiki00TEX__width = 31;
const u16 l_M_Hijiki00TEX__height = 31;
const u16 l_M_kusa05_RGBATEX__width = 31;
@@ -751,7 +753,16 @@ void dGrass_packet_c::draw() {
GXSetChanAmbColor(GX_COLOR0A0, sp38);
if (!cLib_checkBit<u8>(var_r29->field_0x01, 2)) {
GXLoadPosMtxImm(var_r29->m_modelMtx, 0);
#ifdef TARGET_PC
Mtx grass_mtx;
if (dusk::frame_interp::lookup_replacement(reinterpret_cast<const void*>(&var_r29->m_modelMtx), grass_mtx)) {
GXLoadPosMtxImm(grass_mtx, 0);
} else {
#endif
GXLoadPosMtxImm(var_r29->m_modelMtx, 0);
#ifdef TARGET_PC
}
#endif
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
if (var_r29->field_0x05 <= 3 || var_r29->field_0x05 >= 10) {
if (var_r29->field_0x02 < -1) {
@@ -1006,6 +1017,9 @@ void dGrass_packet_c::update() {
mDoMtx_stack_c::scaleM(scale, scale, scale);
cMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::get(), data_p->m_modelMtx);
}
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(&data_p->m_modelMtx), data_p->m_modelMtx);
#endif
}
}
data_p++;
+10 -5
View File
@@ -20,6 +20,7 @@
#include "m_Do/m_Do_controller_pad.h"
#include "m_Do/m_Do_graphic.h"
#include "m_Do/m_Do_lib.h"
#include "dusk/frame_interpolation.h"
#include <cmath>
#include <cstring>
@@ -2179,9 +2180,9 @@ fopAc_ac_c* dCamera_c::getParamTargetActor(s32 param_0) {
daAlink_c* player = daAlink_getAlinkActorClass();
fopAc_ac_c* result;
u32* name = (u32*)(mCamTypeData[param_0].name + 16);
BE(u32)* name = (BE(u32)*)(mCamTypeData[param_0].name + 16);
//name += 16;
switch (*name) {
switch ((u32)*name) {
case '@LOC':
result = dComIfGp_getAttention()->LockonTarget(0);
break;
@@ -11030,16 +11031,20 @@ static int camera_draw(camera_process_class* i_this) {
int trim_height = body->TrimHeight();
#if TARGET_PC
#if TARGET_PC
trim_height *= viewport->height / FB_HEIGHT;
window->setScissor(0.0f, trim_height, viewport->width, viewport->height - trim_height * 2.0f);
#else
#else
window->setScissor(0.0f, trim_height, FB_WIDTH, FB_HEIGHT - trim_height * 2.0f);
#endif
#endif
C_MTXPerspective(process->view.projMtx, process->view.fovy, process->view.aspect, process->view.near_, process->view.far_);
mDoMtx_lookAt(process->view.viewMtx, &process->view.lookat.eye, &process->view.lookat.center,
&process->view.lookat.up, process->view.bank);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(reinterpret_cast<const Mtx*>(process->view.viewMtx),
process->view.viewMtx);
#endif
#if WIDESCREEN_SUPPORT
mDoGph_gInf_c::setWideZoomProjection(process->view.projMtx);
+1 -1
View File
@@ -1018,7 +1018,7 @@ bool dComIfG_inf_c::baseCsr_c::navi_c::draw(f32 param_1, f32 param_2, u8 param_3
f32 f27 = f31 - field_0x5c;
field_0x58 = f29;
field_0x5c = f31;
cXyz spdc(param_1 - 304.0f, param_2 - 224.0f, 0.0f);
cXyz spdc(param_1 - FB_WIDTH_BASE / 2, param_2 - FB_HEIGHT_BASE / 2, 0.0f);
f32 target = param_3 != 0 ? 1.5f : 0.0f;
+103 -9
View File
@@ -10,7 +10,13 @@
#include "SSystem/SComponent/c_math.h"
#include "d/d_com_inf_game.h"
#include "d/d_drawlist.h"
#include <typeindex>
#include "absl/container/flat_hash_map.h"
#include "client/TracyScoped.hpp"
#include "d/d_s_play.h"
#include "dusk/frame_interpolation.h"
#include "dusk/gx_helper.h"
#include "dusk/logging.h"
#include "m_Do/m_Do_graphic.h"
@@ -1089,7 +1095,16 @@ void dDlst_shadowReal_c::draw() {
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXSetCurrentMtx(GX_PNMTX0);
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
#ifdef TARGET_PC
Mtx receiver_proj_mtx;
if (dusk::frame_interp::lookup_replacement(&mReceiverProjMtx, receiver_proj_mtx)) {
GXLoadTexMtxImm(receiver_proj_mtx, GX_TEXMTX0, GX_MTX3x4);
} else {
#endif
GXLoadTexMtxImm(mReceiverProjMtx, GX_TEXMTX0, GX_MTX3x4);
#ifdef TARGET_PC
}
#endif
mShadowRealPoly.draw();
}
@@ -1247,6 +1262,10 @@ u8 dDlst_shadowReal_c::setShadowRealMtx(cXyz* param_0, cXyz* param_1, f32 param_
C_MTXOrtho(mRenderProjMtx, param_2, -param_2, -param_2, param_2, 1.0f, 10000.0f);
C_MTXLightOrtho(mReceiverProjMtx, param_2, -param_2, -param_2, param_2, 0.5f, -0.5f, 0.5f, 0.5f);
cMtx_concat(mReceiverProjMtx, mViewMtx, mReceiverProjMtx);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(&mViewMtx, mViewMtx);
dusk::frame_interp::record_final_mtx_raw(&mReceiverProjMtx, mReceiverProjMtx);
#endif
return r29;
}
@@ -1309,13 +1328,31 @@ void dDlst_shadowSimple_c::draw() {
GXSetTevColor(GX_TEVREG0, l_color);
GXClearVtxDesc();
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
GXLoadPosMtxImm(mVolumeMtx, GX_PNMTX0);
#ifdef TARGET_PC
Mtx volume_mtx;
if (dusk::frame_interp::lookup_replacement(&mVolumeMtx, volume_mtx)) {
GXLoadPosMtxImm(volume_mtx, GX_PNMTX0);
} else {
#endif
GXLoadPosMtxImm(mVolumeMtx, GX_PNMTX0);
#ifdef TARGET_PC
}
#endif
GXSetCurrentMtx(GX_PNMTX0);
GXCallDisplayList(l_frontMat, 0x40);
GXCallDisplayList(l_shadowVolumeDL, 0x40);
GXCallDisplayList(l_backSubMat, 0x20);
GXCallDisplayList(l_shadowVolumeDL, 0x40);
GXLoadPosMtxImm(mMtx, GX_PNMTX1);
#ifdef TARGET_PC
Mtx shadow_mtx;
if (dusk::frame_interp::lookup_replacement(&mMtx, shadow_mtx)) {
GXLoadPosMtxImm(shadow_mtx, GX_PNMTX1);
} else {
#endif
GXLoadPosMtxImm(mMtx, GX_PNMTX1);
#ifdef TARGET_PC
}
#endif
GXSetCurrentMtx(GX_PNMTX1);
if (mpTexObj != NULL) {
@@ -1394,13 +1431,21 @@ void dDlst_shadowSimple_c::set(cXyz* param_0, f32 param_1, f32 param_2, cXyz* pa
mDoMtx_stack_c::YrotM(param_4);
mDoMtx_stack_c::scaleM(param_2, 1.0f, param_2 * param_5);
cMtx_concat(j3dSys.getViewMtx(), mDoMtx_stack_c::get(), mMtx);
#ifdef TARGET_PC
dusk::frame_interp::record_final_mtx_raw(&mVolumeMtx, mVolumeMtx);
dusk::frame_interp::record_final_mtx_raw(&mMtx, mMtx);
#endif
mpTexObj = param_6;
}
void dDlst_shadowControl_c::init() {
#if TARGET_PC
// Increase shadow map resolution
static u16 l_realImageSize[2] = {1024, 512};
u16 l_realImageSize[2] =
{
192 * dusk::getSettings().game.shadowResolutionMultiplier,
64 * dusk::getSettings().game.shadowResolutionMultiplier
};
#else
static u16 l_realImageSize[2] = {192, 64};
#endif
@@ -1439,7 +1484,19 @@ void dDlst_shadowControl_c::reset() {
#endif
}
#if TARGET_PC
int lastShadowValue = 0;
#endif
void dDlst_shadowControl_c::imageDraw(Mtx param_0) {
#if TARGET_PC
if (lastShadowValue != dusk::getSettings().game.shadowResolutionMultiplier) {
reset();
init();
lastShadowValue = dusk::getSettings().game.shadowResolutionMultiplier;
}
#endif
static u8 l_matDL[] ATTRIBUTE_ALIGN(32) = {
0x10, 0x00, 0x00, 0x10, 0x0E, 0x00, 0x00, 0x04, 0x00, 0x10, 0x00, 0x00, 0x10, 0x10,
0x00, 0x00, 0x04, 0x00, 0x61, 0x28, 0x38, 0x00, 0x00, 0x61, 0xC0, 0x08, 0xFF, 0xF2,
@@ -1541,7 +1598,16 @@ void dDlst_shadowControl_c::draw(Mtx param_0) {
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX3x4, GX_TG_POS, GX_TEXMTX0);
GXSetNumTevStages(1);
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
GXLoadPosMtxImm(param_0, GX_PNMTX0);
#ifdef TARGET_PC
Mtx draw_mtx;
if (dusk::frame_interp::lookup_replacement(param_0, draw_mtx)) {
GXLoadPosMtxImm(draw_mtx, GX_PNMTX0);
} else {
#endif
GXLoadPosMtxImm(param_0, GX_PNMTX0);
#ifdef TARGET_PC
}
#endif
GXColor matColor = {0, 0, 0, 0x20};
GXSetChanMatColor(GX_ALPHA0, matColor);
@@ -1878,14 +1944,32 @@ int dDlst_list_c::set(dDlst_base_c**& p_start, dDlst_base_c**& p_end, dDlst_base
return 1;
}
#if TARGET_PC && (TRACY_ENABLE || PARTIAL_DEBUG)
static absl::flat_hash_map<std::type_index, const char*> typeDrawNames;
static const char* getTypeDrawName(dDlst_base_c* dlst) {
const auto& info = typeid(*dlst);
auto& elem = typeDrawNames[info];
if (elem) [[likely]] {
return elem;
}
const auto size = snprintf(nullptr, 0, "%s::draw()", info.name());
// Note: pointer is intentionally never freed, Tracy needs it.
const auto buf = static_cast<char*>(malloc(size+1));
snprintf(buf, size+1, "%s::draw()", info.name());
elem = buf;
return buf;
}
#endif
void dDlst_list_c::draw(dDlst_base_c** p_start, dDlst_base_c** p_end) {
for (; p_start < p_end; p_start++) {
dDlst_base_c* dlst = *p_start;
#if DEBUG && TARGET_PC
char buf[64];
snprintf(buf, sizeof(buf), "%s::draw()", typeid(dlst).name());
GXScopedDebugGroup scope(buf);
#if TARGET_PC && (TRACY_ENABLE || PARTIAL_DEBUG)
const auto name = getTypeDrawName(dlst);
GXScopedDebugGroup scope(name);
#endif
dlst->draw();
}
@@ -1933,3 +2017,13 @@ void dDlst_list_c::calcWipe() {
dComIfGd_set2DXlu(&mWipeDlst);
}
}
#if TARGET_PC
void dDlst_list_c::refresh3DlineMats(const cXyz& eye) {
for (int i = 0; i < 3; i++) {
for (mDoExt_3DlineMat_c* mat = m3DLineMatSortPacket[i].getFirstMat(); mat != NULL; mat = mat->field_0x4) {
mat->refreshGeometryForPresentationEye(eye);
}
}
}
#endif
+1 -1
View File
@@ -5585,7 +5585,7 @@ void dFile_select3D_c::toItem3Dpos(f32 param_0, f32 param_1, f32 param_2, cXyz*
Mtx adStack_98;
Mtx auStack_c8;
param_0 = (2.0f * ((param_0 - mDoGph_gInf_c::getMinXF()) / mDoGph_gInf_c::getWidthF()) - 1.0f);
param_1 = (2.0f * ((param_1 - -100.0f) / 448.0f) - 1.0f);
param_1 = (2.0f * ((param_1 - -100.0f) / FB_HEIGHT_BASE) - 1.0f);
calcViewMtx(adStack_98);
cMtx_inverse(adStack_98, auStack_c8);
f32 tangent = std::tan(M_PI / 8.0f);
+2 -1
View File
@@ -1,11 +1,12 @@
#include "d/d_jcam_editor.h"
#include "m_Do/m_Do_graphic.h"
#include "m_Do/m_Do_hostIO.h"
#include "m_Do/m_Do_ext.h"
dJcame_c* dJcame_c::m_myObj;
dJcame_c::dJcame_c(const JStage::TSystem* i_system, f32 param_1, JUTGamePad& i_pad) {
mOrthoGraph = JKR_NEW J2DOrthoGraph(0.0f, 0.0f, 608.0f, 448.0f, -1.0f, 1.0f);
mOrthoGraph = JKR_NEW J2DOrthoGraph(0.0f, 0.0f, FB_WIDTH_BASE, FB_HEIGHT_BASE, -1.0f, 1.0f);
mFont = JKR_NEW JUTResFont((ResFONT*)JUTResFONT_Ascfont_fix12, NULL);
mHeap = JKRExpHeap::create(0x100000, JKRHeap::getRootHeap2(), false);
+2 -6
View File
@@ -10994,9 +10994,9 @@ void dKy_depth_dist_set(void* process_p) {
if ((sp30.x >= 0.0f && sp30.x < FB_WIDTH) && (sp30.y >= 0.0f &&
#if DEBUG
sp30.y < 608.0f
sp30.y < FB_WIDTH_BASE
#else
sp30.y < 600.0f
sp30.y < (FB_WIDTH_BASE - 8)
#endif
)) {
cXyz sp18;
@@ -11393,11 +11393,7 @@ void dKy_bg_MAxx_proc(void* bg_model_p) {
if (mat_name[6] == '2') {
C_MTXLightPerspective(sp1D8, dComIfGd_getView()->fovy,
camera_p->view.aspect, 1.0f, 1.0f,
#if TARGET_PC
dusk::getSettings().game.useWaterProjectionOffset ? -0.01f : 0.0f, 0.0f);
#else
-0.01f, 0.0f);
#endif
} else {
C_MTXLightPerspective(sp1D8, dComIfGd_getView()->fovy,
camera_p->view.aspect, 0.49f, -0.49f, 0.5f, 0.5f);
+1 -1
View File
@@ -2708,7 +2708,7 @@ void dMenu_Collect3D_c::toItem3Dpos(f32 param_0, f32 param_1, f32 param_2, cXyz*
Mtx auStack_c8;
param_0 =
(2.0f * ((param_0 - mDoGph_gInf_c::getMinXF()) / mDoGph_gInf_c::getWidthF()) - 1.0f);
param_1 = (2.0f * ((param_1 - -100.0f) / 448.0f) - 1.0f);
param_1 = (2.0f * ((param_1 - -100.0f) / FB_HEIGHT_BASE) - 1.0f);
calcViewMtx(adStack_98);
MTXInverse(adStack_98, auStack_c8);
f32 tangent = tan(0.39269909262657166);
+18 -12
View File
@@ -229,17 +229,17 @@ dMenu_Fmap_c::dMenu_Fmap_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
}
if (i_panDirection == 1) {
mTransX = -608.0f;
mTransX = -FB_WIDTH_BASE;
mTransY = 0.0f;
} else if (i_panDirection == 3) {
mTransX = 608.0f;
mTransX = FB_WIDTH_BASE;
mTransY = 0.0f;
} else if (i_panDirection == 2) {
mTransX = 0.0f;
mTransY = -448.0f;
mTransY = -FB_HEIGHT_BASE;
} else if (i_panDirection == 0) {
mTransX = 0.0f;
mTransY = 448.0f;
mTransY = FB_HEIGHT_BASE;
} else {
mTransX = 0.0f;
mTransY = 0.0f;
@@ -1133,6 +1133,12 @@ void dMenu_Fmap_c::zoom_region_to_spot_proc() {
void dMenu_Fmap_c::zoom_spot_to_region_init() {
mZoomLevel = 10;
field_0x1ec = 1.0f;
#if TARGET_PC
// Frame interp note: field_0x122d used to be set every draw, causing flickering. Do it here instead.
if (dusk::getSettings().game.enableFrameInterpolation) {
mpDraw2DBack->resetScrollArrowMask();
}
#endif
Z2GetAudioMgr()->seStart(Z2SE_SY_MAP_ZOOMOUT, NULL, 0, 0, 1.0f, 1.0f, -1.0f, -1.0f, 0);
}
@@ -1705,17 +1711,17 @@ bool dMenu_Fmap_c::isOpen() {
f32 ratio = (f32)mDisplayFrame / (f32)display_frame_num;
if (mPanDirection == 1) {
mTransX = (1.0f - ratio) * -608.0f;
mTransX = (1.0f - ratio) * -FB_WIDTH_BASE;
mTransY = 0.0f;
} else if (mPanDirection == 3) {
mTransX = (1.0f - ratio) * 608.0f;
mTransX = (1.0f - ratio) * FB_WIDTH_BASE;
mTransY = 0.0f;
} else if (mPanDirection == 2) {
mTransX = 0.0f;
mTransY = (1.0f - ratio) * -448.0f;
mTransY = (1.0f - ratio) * -FB_HEIGHT_BASE;
} else if (mPanDirection == 0) {
mTransX = 0.0f;
mTransY = (1.0f - ratio) * 448.0f;
mTransY = (1.0f - ratio) * FB_HEIGHT_BASE;
}
mAlphaRatio = ratio;
@@ -1755,17 +1761,17 @@ bool dMenu_Fmap_c::isClose() {
}
if (mPanDirection == 1) {
mTransX = (1.0f - ratio) * 608.0f;
mTransX = (1.0f - ratio) * FB_WIDTH_BASE;
mTransY = 0.0f;
} else if (mPanDirection == 3) {
mTransX = (1.0f - ratio) * -608.0f;
mTransX = (1.0f - ratio) * -FB_WIDTH_BASE;
mTransY = 0.0f;
} else if (mPanDirection == 2) {
mTransX = 0.0f;
mTransY = (1.0f - ratio) * 448.0f;
mTransY = (1.0f - ratio) * FB_HEIGHT_BASE;
} else if (mPanDirection == 0) {
mTransX = 0.0f;
mTransY = (1.0f - ratio) * -448.0f;
mTransY = (1.0f - ratio) * -FB_HEIGHT_BASE;
}
mAlphaRatio = ratio;
+16 -3
View File
@@ -17,6 +17,7 @@
#include "d/d_msg_scrn_explain.h"
#include "m_Do/m_Do_graphic.h"
#include "d/actor/d_a_midna.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
dMenu_Fmap2DBack_c::dMenu_Fmap2DBack_c() {
@@ -390,11 +391,17 @@ void dMenu_Fmap2DBack_c::draw() {
(mArrowPos3DZ + control_ypos + fVar3) - fVar5, &mArrowPos2DX,
&mArrowPos2DY);
field_0x11e0 -= g_fmapHIO.mCursorSpeed;
#ifdef TARGET_PC
for (u32 i = 0; i < dusk::frame_interp::get_presentation_ui_advance_ticks(); ++i) {
#endif
field_0x11e0 -= g_fmapHIO.mCursorSpeed;
if (field_0x11e0 < 0.0f) {
field_0x11e0 += 360.0f;
if (field_0x11e0 < 0.0f) {
field_0x11e0 += 360.0f;
}
#ifdef TARGET_PC
}
#endif
mpPointParent->getPanePtr()->rotate(mpPointParent->getSizeX() / 2.0f,
mpPointParent->getSizeY() / 2.0f, ROTATE_Z,
@@ -425,7 +432,13 @@ void dMenu_Fmap2DBack_c::draw() {
if (field_0x122d) {
mpMeterHaihai->drawHaihai(field_0x122d);
#if TARGET_PC
if (!dusk::getSettings().game.enableFrameInterpolation) {
field_0x122d = 0;
}
#else
field_0x122d = 0;
#endif
}
if (g_fmapHIO.mRangeCheck && !g_fmapHIO.mRangeCheckDrawPriority) {
+3
View File
@@ -183,6 +183,9 @@ void dMenu_Insect_c::_draw() {
mpExpScreen->draw(0.0f, 0.0f, grafPort);
mpSelect_c->setOffsetX(g_drawHIO.mInsectListScreen.mConfirmOptionPosX_4x3);
// the magic numbers here are correlated with the framebuffer size, but
// were likely either chosen by hand or had multiple arithmetic
// operations applied which cannot easily be reverse engineered
mpSelect_c->translate(g_drawHIO.mInsectListScreen.mConfirmOptionPosX_4x3 + 486.0f,
g_drawHIO.mInsectListScreen.mConfirmOptionPosY_4x3 + 209.0f);
mpSelect_c->draw(0.0f, 0.0f);
+3
View File
@@ -330,6 +330,9 @@ void dMenu_ItemExplain_c::draw(J2DOrthoGraph* i_graph) {
mpInfoString->drawOutFontLocal((J2DTextBox*)mpInfoText->getPanePtr(), -1.0f);
drawKantera();
if (mpSelect_c != NULL) {
// the magic numbers here are correlated with the framebuffer size, but
// were likely either chosen by hand or had multiple arithmetic
// operations applied which cannot easily be reverse engineered
mpSelect_c->translate(486.0f, 209.0f);
mpSelect_c->draw(0.0f, 0.0f);
}
+18 -18
View File
@@ -87,16 +87,16 @@ dMenu_Ring_c::dMenu_Ring_c(JKRExpHeap* i_heap, STControl* i_stick, CSTControl* i
mPikariFlashingSpeed = 0.0f;
if (mRingOrigin == 0) {
mCenterPosX = 0.0f;
mCenterPosY = 448.0f;
mCenterPosY = FB_HEIGHT_BASE;
} else if (mRingOrigin == 2) {
mCenterPosX = 0.0f;
mCenterPosY = -448.0f;
mCenterPosY = -FB_HEIGHT_BASE;
}
if (mRingOrigin == 3) {
mCenterPosX = 608.0f;
mCenterPosX = FB_WIDTH_BASE;
mCenterPosY = 0.0f;
} else if (mRingOrigin == 1) {
mCenterPosX = -608.0f;
mCenterPosX = -FB_WIDTH_BASE;
mCenterPosY = 0.0f;
} else {
mCenterPosX = 0.0f;
@@ -644,15 +644,15 @@ bool dMenu_Ring_c::isOpen() {
mAlphaRate = (f32)mOpenCloseFrames / (f32)g_ringHIO.mOpenFrames;
if (mRingOrigin == 0) {
mCenterPosX = 0.0f;
mCenterPosY = (1.0f - mAlphaRate) * 448.0f;
mCenterPosY = (1.0f - mAlphaRate) * FB_HEIGHT_BASE;
} else if (mRingOrigin == 2) {
mCenterPosX = 0.0f;
mCenterPosY = (1.0f - mAlphaRate) * -448.0f;
mCenterPosY = (1.0f - mAlphaRate) * -FB_HEIGHT_BASE;
} else if (mRingOrigin == 3) {
mCenterPosX = (1.0f - mAlphaRate) * 608.0f;
mCenterPosX = (1.0f - mAlphaRate) * FB_WIDTH_BASE;
mCenterPosY = 0.0f;
} else if (mRingOrigin == 1) {
mCenterPosX = (1.0f - mAlphaRate) * -608.0f;
mCenterPosX = (1.0f - mAlphaRate) * -FB_WIDTH_BASE;
mCenterPosY = 0.0f;
}
if (mOpenCloseFrames >= g_ringHIO.mOpenFrames) {
@@ -715,15 +715,15 @@ bool dMenu_Ring_c::isClose() {
}
if (mRingOrigin == 0) {
mCenterPosX = 0.0f;
mCenterPosY = (1.0f - mAlphaRate) * -448.0f;
mCenterPosY = (1.0f - mAlphaRate) * -FB_HEIGHT_BASE;
} else if (mRingOrigin == 2) {
mCenterPosX = 0.0f;
mCenterPosY = (1.0f - mAlphaRate) * 448.0f;
mCenterPosY = (1.0f - mAlphaRate) * FB_HEIGHT_BASE;
} else if (mRingOrigin == 3) {
mCenterPosX = (1.0f - mAlphaRate) * -608.0f;
mCenterPosX = (1.0f - mAlphaRate) * -FB_WIDTH_BASE;
mCenterPosY = 0.0f;
} else if (mRingOrigin == 1) {
mCenterPosX = (1.0f - mAlphaRate) * 608.0f;
mCenterPosX = (1.0f - mAlphaRate) * FB_WIDTH_BASE;
mCenterPosY = 0.0f;
}
mpDrawCursor->setPos(mItemSlotPosX[mCurrentSlot] + mCenterPosX,
@@ -855,11 +855,11 @@ s16 dMenu_Ring_c::calcStickAngle(STControl* i_stick, u8 param_1) {
}
void dMenu_Ring_c::setRotate() {
clacEllipsePlotAverage(mItemsTotal, g_ringHIO.mItemRingPosX + 304.0f,
g_ringHIO.mItemRingPosY + 224.0f);
clacEllipsePlotAverage(mItemsTotal, g_ringHIO.mItemRingPosX + FB_WIDTH_BASE / 2,
g_ringHIO.mItemRingPosY + FB_HEIGHT_BASE / 2);
for (int i = 0; i < mItemsTotal; i++) {
field_0x63e[i] = cM_atan2s(mItemSlotPosX[i] - (304.0f + g_ringHIO.mItemRingPosX),
mItemSlotPosY[i] - (224.0f + g_ringHIO.mItemRingPosY));
field_0x63e[i] = cM_atan2s(mItemSlotPosX[i] - (FB_WIDTH_BASE / 2 + g_ringHIO.mItemRingPosX),
mItemSlotPosY[i] - (FB_HEIGHT_BASE / 2 + g_ringHIO.mItemRingPosY));
}
}
@@ -1446,9 +1446,9 @@ void dMenu_Ring_c::stick_move_proc() {
setStatus(field_0x6b2);
} else {
f32 itemRingPosX =
g_ringHIO.mItemRingPosX + 304.0f + mRingRadiusH * cM_ssin(field_0x66e);
g_ringHIO.mItemRingPosX + FB_WIDTH_BASE / 2 + mRingRadiusH * cM_ssin(field_0x66e);
f32 itemRingPosY =
g_ringHIO.mItemRingPosY + 224.0f + mRingRadiusV * cM_scos(field_0x66e);
g_ringHIO.mItemRingPosY + FB_HEIGHT_BASE / 2 + mRingRadiusV * cM_scos(field_0x66e);
mpDrawCursor->setPos(itemRingPosX, itemRingPosY);
}
}
+54 -34
View File
@@ -20,6 +20,7 @@
#include "d/d_msg_class.h"
#include "d/d_msg_object.h"
#include "d/d_pane_class.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
dMeter2Draw_c::dMeter2Draw_c(JKRExpHeap* mp_heap) {
@@ -636,38 +637,49 @@ void dMeter2Draw_c::draw() {
if (field_0x756 >= 0) {
var_f29 = g_drawHIO.mLightDrop.mDropPikariAnimSpeed_Completed;
int temp_r5_2 = g_drawHIO.mLightDrop.mPikariInterval * 15;
#ifdef TARGET_PC
// Set even if not advancing
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
if (field_0x756 <= temp_r5_2) {
int temp_r4 = (field_0x756 % g_drawHIO.mLightDrop.mPikariInterval);
int temp_r3_5 = field_0x756 / g_drawHIO.mLightDrop.mPikariInterval;
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (field_0x756 <= temp_r5_2) {
int temp_r4 = (field_0x756 % g_drawHIO.mLightDrop.mPikariInterval);
int temp_r3_5 = field_0x756 / g_drawHIO.mLightDrop.mPikariInterval;
if (temp_r4 == 0 && field_0x62c[temp_r3_5] == 0.0f) {
field_0x62c[temp_r3_5] = 18.0f;
}
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
field_0x756++;
} else {
int temp_r5_3 = temp_r5_2 + 1;
if (field_0x756 == temp_r5_3) {
if (field_0x62c[15] == 0.0f) {
field_0x756++;
if (temp_r4 == 0 && field_0x62c[temp_r3_5] == 0.0f) {
field_0x62c[temp_r3_5] = 18.0f;
}
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
} else if (field_0x756 >= g_drawHIO.mLightDrop.field_0x54 + temp_r5_3) {
for (int i = 0; i < 16; i++) {
field_0x62c[i] = 18.0f - var_f29;
field_0x66c[i] = 18.0f - g_drawHIO.mLightDrop.mPikariLoopAnimSpeed;
}
field_0x756 = -1;
} else {
field_0x756++;
} else {
int temp_r5_3 = temp_r5_2 + 1;
if (field_0x756 == temp_r5_3) {
if (field_0x62c[15] == 0.0f) {
field_0x756++;
}
var_f28 = g_drawHIO.mLightDrop.mPikariScaleComplete;
} else if (field_0x756 >= g_drawHIO.mLightDrop.field_0x54 + temp_r5_3) {
for (int i = 0; i < 16; i++) {
field_0x62c[i] = 18.0f - var_f29;
field_0x66c[i] = 18.0f - g_drawHIO.mLightDrop.mPikariLoopAnimSpeed;
}
field_0x756 = -1;
#ifdef TARGET_PC
break;
#endif
} else {
field_0x756++;
}
}
}
#ifdef TARGET_PC
}
#endif
for (int i = 0; i < 16; i++) {
if (field_0x66c[i] > 0.0f) {
@@ -1336,20 +1348,27 @@ void dMeter2Draw_c::drawPikari(f32 i_posX, f32 i_posY, f32* i_framep, f32 i_scal
if (param_9 != 3 && param_9 != 4 && param_9 != 5 && dMsgObject_isTalkNowCheck()) {
*i_framep = 0.0f;
} else {
*i_framep += param_8;
if (*i_framep > var_f31) {
if (param_9 == 1 || param_9 == 2 || param_9 == 3) {
*i_framep = 18.0f;
} else {
*i_framep = 0.0f;
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
*i_framep += param_8;
if (*i_framep > var_f31) {
if (param_9 == 1 || param_9 == 2 || param_9 == 3) {
*i_framep = 18.0f;
} else {
*i_framep = 0.0f;
}
}
}
if (*i_framep == 18.0f && param_9 == 1) {
mDoAud_seStart(Z2SE_NAVI_BLINK, NULL, 0, 0);
} else if (*i_framep == 18.0f && param_9 == 2) {
mDoAud_seStart(Z2SE_SY_ITEM_COMBINE_ICON, NULL, 0, 0);
if (*i_framep == 18.0f && param_9 == 1) {
mDoAud_seStart(Z2SE_NAVI_BLINK, NULL, 0, 0);
} else if (*i_framep == 18.0f && param_9 == 2) {
mDoAud_seStart(Z2SE_SY_ITEM_COMBINE_ICON, NULL, 0, 0);
}
#ifdef TARGET_PC
}
#endif
playPikariBckAnimation(*i_framep);
playPikariBpkAnimation(*i_framep);
@@ -1543,6 +1562,7 @@ void dMeter2Draw_c::setAlphaLifeAnimeMax() {
}
void dMeter2Draw_c::drawKanteraScreen(u8 i_meterType) {
GX_AND_TRACY_SCOPED("drawKanteraScreen");
J2DGrafContext* graf_ctx = dComIfGp_getCurrentGrafPort();
mpMagicParent->setAlphaRate(mMeterAlphaRate[i_meterType]);
+4 -4
View File
@@ -205,11 +205,11 @@ void dMeter2Info_c::init() {
unk_0x5c = 0.0f;
unk_0x60 = 1.0f;
unk_0x64 = 30.0f;
unk_0x68 = 304.0f;
unk_0x6c = 224.0f;
unk_0x68 = FB_WIDTH_BASE / 2;
unk_0x6c = FB_HEIGHT_BASE / 2;
m2DWidth = 608.0f;
m2DHeight = 448.0f;
m2DWidth = FB_WIDTH_BASE;
m2DHeight = FB_HEIGHT_BASE;
m2DPosH = 0.0f;
m2DPosV = 0.0f;
unk_0x80 = 0.0f;
+9 -9
View File
@@ -197,11 +197,11 @@ void dMeter_drawOptionHIO_c::genMessage(JORMContext* mctx) {
mctx->genSlider("位置X", &mOptionTypeBGPosX[3], -300.0f, 300.0f);
mctx->genSlider("位置Y", &mOptionTypeBGPosY[3], -300.0f, 300.0f);
mctx->genLabel("*****テレビ画面の設定*****", 0);
mctx->genSlider("位置X", &mTVsettingPosX, -300.0f, 300.0f);
mctx->genSlider("位置Y", &mTVsettingPosY, -300.0f, 300.0f);
mctx->genSlider("位置X", &mOptionTypeBGPosX[4], -300.0f, 300.0f);
mctx->genSlider("位置Y", &mOptionTypeBGPosY[4], -300.0f, 300.0f);
mctx->genLabel("*****キャリブレーション*****", 0);
mctx->genSlider("位置X", &mPointerCalibrationPosX, -300.0f, 300.0f);
mctx->genSlider("位置Y", &mPointerCalibrationPosY, -300.0f, 300.0f);
mctx->genSlider("位置X", &mOptionTypeBGPosX[5], -300.0f, 300.0f);
mctx->genSlider("位置Y", &mOptionTypeBGPosY[5], -300.0f, 300.0f);
mctx->genLabel("*****設定確認*****", 0);
mctx->genSlider("背景アルファ", &mBackgroundAlpha, 0, 255);
mctx->genSlider("位置Y", &mBackgroundPosY, -300.0f, 300.0f);
@@ -1493,7 +1493,7 @@ dMeter_drawLightDropHIO_c::dMeter_drawLightDropHIO_c() {
mPikariInterval = 1;
field_0x54 = 0xFFF1;
mVesselAlpha[2] = 0.5f;
mDropAlpha = 1.0f;
mVesselAlpha[3] = 1.0f;
mDropOnColorBlack.set(30, 255, 255, 0);
mDropOnColorWhite.set(255, 255, 255, 255);
@@ -1554,7 +1554,7 @@ void dMeter_drawLightDropHIO_c::genMessage(JORMContext* mctx) {
mctx->genSlider("位置調整Y(会話)", &mVesselTalkPosY, -300.0f, 300.0f);
mctx->genSlider("アルファ(会話)", &mVesselAlpha[1], 0.0f, 1.0f);
mctx->genSlider("アルファ(器)", &mVesselAlpha[2], 0.0f, 1.0f);
mctx->genSlider("アルファ(雫)", &mDropAlpha, 0.0f, 1.0f);
mctx->genSlider("アルファ(雫)", &mVesselAlpha[3], 0.0f, 1.0f);
mctx->genLabel("***光の器ゲット後***", 0);
mctx->genSlider("拡大縮小", &mDropGetScale, 0.0f, 3.0f);
mctx->genSlider("拡縮アニメフレーム数", &mDropGetScaleAnimFrameNum, 0, 30);
@@ -4010,9 +4010,9 @@ void dMeter_fmapHIO_c::genMessage(JORMContext* mctx) {
mctx->genSlider("リージョン拡大表示範囲", &mRegionZoomRange, 1000.0, 1000000.0);
mctx->genCheckBox("表示基準領域枠表示", (u8*)&mDisplayReferenceArea, 0x1);
mctx->genCheckBox("スクロール範囲を表示基準", (u8*)&field_0x308, 0x1);
mctx->genSlider("左上座標X", &mMapTopLeftPosX, 0.0, 608.0);
mctx->genSlider("左上座標Y", &mMapTopLeftPosY, 0.0, 448.0);
mctx->genSlider("領域幅", &mMapScale, 0.0, 608.0);
mctx->genSlider("左上座標X", &mMapTopLeftPosX, 0.0, FB_WIDTH_BASE);
mctx->genSlider("左上座標Y", &mMapTopLeftPosY, 0.0, FB_HEIGHT_BASE);
mctx->genSlider("領域幅", &mMapScale, 0.0, FB_WIDTH_BASE);
mctx->genLabel("\n*** スクロール速度境界 ***", 0);
mctx->genSlider("0~遅", &mScrollSpeedSlowBound, 0.0, 1.0);
mctx->genSlider("遅~速", &mScrollSpeedFastBound, 0.0, 1.0);
+1 -1
View File
@@ -1035,7 +1035,7 @@ void dMeterButton_c::screenInitButton() {
}
field_0x4b0 = 0;
mParentCenterX = (608.0f / 2) - mpParent->getInitCenterPosX();
mParentCenterX = (FB_WIDTH_BASE / 2.0f) - mpParent->getInitCenterPosX();
paneTrans(mpParent, mParentCenterX, 0.0f, 0xFF);
mpButtonA = JKR_NEW CPaneMgr(mpButtonScreen, MULTI_CHAR('abtn_n'), 2, NULL);
+6 -6
View File
@@ -99,28 +99,28 @@ void dMeterHaihai_c::draw() {
}
if (direction & DIR_DOWN_e || i_forceDraw) {
mpParent->getPanePtr()->translate(x_pos[0] + 304.0f, y_pos[0] + 224.0f);
mpParent->getPanePtr()->translate(x_pos[0] + FB_WIDTH_BASE / 2, y_pos[0] + FB_HEIGHT_BASE / 2);
mpParent->getPanePtr()->rotate(mpParent->getPanePtr()->getWidth() / 2,
mpParent->getPanePtr()->getHeight() / 2, ROTATE_Z, 0.0f);
mpHaihaiScreen->draw(0.0f, 0.0f, dComIfGp_getCurrentGrafPort());
}
if (direction & DIR_RIGHT_e || i_forceDraw) {
mpParent->getPanePtr()->translate(x_pos[1] + 304.0f, y_pos[1] + 224.0f);
mpParent->getPanePtr()->translate(x_pos[1] + FB_WIDTH_BASE / 2, y_pos[1] + FB_HEIGHT_BASE / 2);
mpParent->getPanePtr()->rotate(mpParent->getPanePtr()->getWidth() / 2,
mpParent->getPanePtr()->getHeight() / 2, ROTATE_Z, 90.0f);
mpHaihaiScreen->draw(0.0f, 0.0f, dComIfGp_getCurrentGrafPort());
}
if (direction & DIR_UP_e || i_forceDraw) {
mpParent->getPanePtr()->translate(x_pos[0] + 304.0f, 224.0f - y_pos[0]);
mpParent->getPanePtr()->translate(x_pos[0] + FB_WIDTH_BASE / 2, FB_HEIGHT_BASE / 2 - y_pos[0]);
mpParent->getPanePtr()->rotate(mpParent->getPanePtr()->getWidth() / 2,
mpParent->getPanePtr()->getHeight() / 2, ROTATE_Z, 180.0f);
mpHaihaiScreen->draw(0.0f, 0.0f, dComIfGp_getCurrentGrafPort());
}
if (direction & DIR_LEFT_e || i_forceDraw) {
mpParent->getPanePtr()->translate(304.0f - x_pos[1], y_pos[1] + 224.0f);
mpParent->getPanePtr()->translate(FB_WIDTH_BASE / 2 - x_pos[1], y_pos[1] + FB_HEIGHT_BASE / 2);
mpParent->getPanePtr()->rotate(mpParent->getPanePtr()->getWidth() / 2,
mpParent->getPanePtr()->getHeight() / 2, ROTATE_Z, 270.0f);
mpHaihaiScreen->draw(0.0f, 0.0f, dComIfGp_getCurrentGrafPort());
@@ -128,8 +128,8 @@ void dMeterHaihai_c::draw() {
}
void dMeterHaihai_c::drawHaihai(u8 i_direction) {
f32 center_x = 304.0f;
f32 center_y = 224.0f;
f32 center_x = FB_WIDTH_BASE / 2;
f32 center_y = FB_HEIGHT_BASE / 2;
if (mType == 1) {
center_x += (3.0f + g_drawHIO.mScrollArrowCenterPosX);
+6
View File
@@ -2234,7 +2234,13 @@ int dMsgFlow_c::event027(mesg_flow_node_event* i_flowNode_p, fopAc_ac_c* i_speak
u16 prm0;
getParam(&prm0, &prm1, i_flowNode_p->params);
// !@bug aParam8 is undersized; getParam always writes 4 bytes, stomping the
// 2 bytes past the buffer. Harmless on GC/Wii (MWCC stack layout absorbs it).
#if AVOID_UB
u8 aParam8[4];
#else
u8 aParam8[2];
#endif
getParam(aParam8, i_flowNode_p->params);
JUT_ASSERT(4509, (aParam8[0] >= 0 && aParam8[0] <= dSv_player_item_c::BOMB_BAG_MAX) || (aParam8[0] == 4));
+8 -5
View File
@@ -70,7 +70,7 @@ dMsgScrnExplain_c::dMsgScrnExplain_c(STControl* i_stick, u8 param_1, bool i_isUs
mpTxScreen = JKR_NEW J2DScreen();
JUT_ASSERT(102, mpTxScreen != NULL);
field_0x48 = 608.0f;
field_0x48 = FB_WIDTH_BASE;
if (param_1 == 1 || param_1 == 3) {
#if PLATFORM_GCN
@@ -309,7 +309,7 @@ void dMsgScrnExplain_c::draw(J2DOrthoGraph* i_graf) {
}
if (mpBackTex != NULL) {
mpBackTex->draw(0.0f, 0.0f, 608.0f, 448.0f, false, false, false);
mpBackTex->draw(0.0f, 0.0f, FB_WIDTH_BASE, FB_HEIGHT_BASE, false, false, false);
}
if (field_0x66 != 2 && field_0x66 != 3) {
@@ -330,6 +330,9 @@ void dMsgScrnExplain_c::draw(J2DOrthoGraph* i_graf) {
strcpy(((J2DTextBox*)mpTm_c[0]->getPanePtr())->getStringPtr(), string_buf);
if (mpSelect_c != NULL && (field_0x64 == 1 || field_0x64 == 2)) {
// the magic numbers here are relative to the framebuffer size, but were likely
// either chosen by hand or had multiple arithmetic operations applied which
// cannot easily be reverse engineered
f32 y_offset = 0.0f;
if (field_0x66 == 2) {
y_offset = -100.0f;
@@ -385,7 +388,7 @@ void dMsgScrnExplain_c::open_request_proc() {
void dMsgScrnExplain_c::open_init() {
field_0x5a = 0;
field_0x48 = 608.0f;
field_0x48 = FB_WIDTH_BASE;
for (int i = 0; i < 2; i++) {
mpRoot_c[i]->setAlphaRate(0.0f);
}
@@ -403,7 +406,7 @@ void dMsgScrnExplain_c::open_proc() {
}
}
field_0x48 = 608.0f * getAlphaRatio();
field_0x48 = FB_WIDTH_BASE * getAlphaRatio();
for (int i = 0; i < 2; i++) {
mpRoot_c[i]->setAlphaRate(1.0f - getAlphaRatio());
}
@@ -583,7 +586,7 @@ void dMsgScrnExplain_c::close_proc() {
}
}
field_0x48 = 608.0f * getAlphaRatio();
field_0x48 = FB_WIDTH_BASE * getAlphaRatio();
for (int i = 0; i < 2; i++) {
mpRoot_c[i]->setAlphaRate(1.0f - getAlphaRatio());
}
+3
View File
@@ -609,6 +609,9 @@ void dMsgScrnItem_c::fukiPosCalc(u8 param_1) {
field_0x180 = 0.0f;
field_0x19c = param_1;
f32 yOffset;
// the magic numbers here are correlated with the framebuffer size, but
// were likely either chosen by hand or had multiple arithmetic
// operations applied which cannot easily be reverse engineered
switch(field_0x19c) {
case 1:
yOffset = g_MsgObject_HIO_c.mBoxPos[2][3];
+21 -6
View File
@@ -6,6 +6,7 @@
#include "JSystem/J2DGraph/J2DScreen.h"
#include "d/d_com_inf_game.h"
#include "d/d_pane_class.h"
#include "dusk/frame_interpolation.h"
class dMsgScrnLight_HIO_c {
public:
@@ -202,10 +203,17 @@ void dMsgScrnLight_c::draw(f32* i_anmFrame, f32 i_posX, f32 i_posY, f32 i_scaleX
}
if (mPlayAnim) {
*i_anmFrame += 1.0f;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
*i_anmFrame += 1.0f;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
}
#ifdef TARGET_PC
}
#endif
mBckFrame = *i_anmFrame;
mBpkFrame = *i_anmFrame;
@@ -220,11 +228,18 @@ void dMsgScrnLight_c::draw(f32* i_anmFrame, f32 i_posX, f32 i_posY, f32 i_scaleX
mpParent_c->setBlackWhite(i_black, i_white);
if (mPlayAnim) {
*i_anmFrame += i_anmRate;
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
*i_anmFrame += i_anmRate;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
if (*i_anmFrame >= mpBck->getFrameMax()) {
*i_anmFrame = 0.0f;
}
#ifdef TARGET_PC
}
#endif
mBckFrame = *i_anmFrame;
mBpkFrame = *i_anmFrame;
+7 -4
View File
@@ -454,11 +454,11 @@ void dMsgScrnTalk_c::fukiPosCalc(u8 param_1) {
#if TARGET_PC
mDoLib_project(&msgActor->pos, &local_70, {0, 0, FB_WIDTH, FB_HEIGHT});
#else
mDoLib_project(&msgActor->pos, &local_70,);
mDoLib_project(&msgActor->pos, &local_70);
#endif
if (local_70.x >= 0.0f && local_70.x <= 608.0f && local_70.y >= 0.0f &&
local_70.y <= 448.0f)
if (local_70.x >= 0.0f && local_70.x <= FB_WIDTH_BASE && local_70.y >= 0.0f &&
local_70.y <= FB_HEIGHT_BASE)
{
f3y = 0.5f * (cStack_7c.y + local_70.y);
} else {
@@ -493,6 +493,9 @@ void dMsgScrnTalk_c::fukiPosCalc(u8 param_1) {
field_0xf0 = 0.0f;
field_0x488 = param_1;
f32 dVar15;
// the magic numbers here are correlated with the framebuffer size, but
// were likely either chosen by hand or had multiple arithmetic
// operations applied which cannot easily be reverse engineered
switch (field_0x488) {
case 1:
dVar15 = g_MsgObject_HIO_c.mBoxPos[2][0];
+6 -5
View File
@@ -1176,19 +1176,20 @@ void dScnLogo_c::logoInitWii() {
break;
}
width = 608;
height = 456;
// this uses the standard width but the widescreen height?
width = FB_WIDTH_BASE;
height = FB_HEIGHT;
}
JUT_ASSERT(2309, timg != NULL);
mStrapImg = JKR_NEW dDlst_2D_c(timg, 304 - (width / 2), 224 - (height / 2), width, height, 255);
mStrapImg = JKR_NEW dDlst_2D_c(timg, (FB_WIDTH_BASE / 2) - (width / 2), (FB_HEIGHT_BASE / 2) - (height / 2), width, height, 255);
#if VERSION == VERSION_SHIELD
timg = (ResTIMG*)dComIfG_getObjectRes("LogoUsWii", 5);
mNvLogo = JKR_NEW dDlst_2D_c(timg, 304 - (width / 2), 224 - (height / 2), width, height, 255);
mNvLogo = JKR_NEW dDlst_2D_c(timg, (FB_WIDTH_BASE / 2) - (width / 2), (FB_HEIGHT_BASE / 2) - (height / 2), width, height, 255);
timg = (ResTIMG*)dComIfG_getObjectRes("LogoUsWii", 4);
mMocImg = JKR_NEW dDlst_2D_c(timg, 304 - (width / 2), 224 - (height / 2), width, height, 255);
mMocImg = JKR_NEW dDlst_2D_c(timg, (FB_WIDTH_BASE / 2) - (width / 2), (FB_HEIGHT_BASE / 2) - (height / 2), width, height, 255);
#endif
OS_REPORT("\x1b[32m%d archiveHeap->getTotalFreeSize %08x\n\x1b[m", 2316, archiveHeap->getTotalFreeSize());
+2
View File
@@ -39,7 +39,9 @@
#include "JSystem/JKernel/JKRAram.h"
#include "JSystem/JKernel/JKRAramArchive.h"
#if TARGET_PC
#include "dusk/memory.h"
#endif
#if DEBUG
#include "d/d_s_menu.h"
+11 -11
View File
@@ -136,24 +136,24 @@ void dScope_c::draw() {
u8 alpha = mAlpha * 255.0f;
if (dComIfGp_checkPlayerStatus0(0, 0x1000)) {
J2DDrawLine(304.0f, mDoGph_gInf_c::getMinYF(), 304.0f, mDoGph_gInf_c::getMaxYF(),
JUtility::TColor(255, 0, 0, alpha), 6);
J2DDrawLine(mDoGph_gInf_c::getMinXF(), 224.0f, mDoGph_gInf_c::getMaxXF(), 224.0f,
JUtility::TColor(255, 0, 0, alpha), 6);
J2DDrawLine(FB_WIDTH_BASE / 2, mDoGph_gInf_c::getMinYF(), FB_WIDTH_BASE / 2,
mDoGph_gInf_c::getMaxYF(), JUtility::TColor(255, 0, 0, alpha), 6);
J2DDrawLine(mDoGph_gInf_c::getMinXF(), FB_HEIGHT_BASE / 2, mDoGph_gInf_c::getMaxXF(),
FB_HEIGHT_BASE / 2, JUtility::TColor(255, 0, 0, alpha), 6);
}
mpWipeTex->setAlpha(alpha);
mpBlackTex->setAlpha(alpha);
f32 temp_f29 = 304.0f - temp_f31;
f32 temp_f28 = 304.0f + temp_f31;
f32 temp_f27 = 224.0f - temp_f30;
f32 temp_f26 = 224.0f + temp_f30;
f32 temp_f29 = FB_WIDTH_BASE / 2 - temp_f31;
f32 temp_f28 = FB_WIDTH_BASE / 2 + temp_f31;
f32 temp_f27 = FB_HEIGHT_BASE / 2 - temp_f30;
f32 temp_f26 = FB_HEIGHT_BASE / 2 + temp_f30;
mpWipeTex->draw(temp_f29, temp_f27, temp_f31, temp_f30, false, false, false);
mpWipeTex->draw(304.0f, temp_f27, temp_f31, temp_f30, true, false, false);
mpWipeTex->draw(temp_f29, 224.0f, temp_f31, temp_f30, false, true, false);
mpWipeTex->draw(304.0f, 224.0f, temp_f31, temp_f30, true, true, false);
mpWipeTex->draw(FB_WIDTH_BASE / 2, temp_f27, temp_f31, temp_f30, true, false, false);
mpWipeTex->draw(temp_f29, FB_HEIGHT_BASE / 2, temp_f31, temp_f30, false, true, false);
mpWipeTex->draw(FB_WIDTH_BASE / 2, FB_HEIGHT_BASE / 2, temp_f31, temp_f30, true, true, false);
mpBlackTex->draw(mDoGph_gInf_c::getMinXF(), mDoGph_gInf_c::getMinYF(),
mDoGph_gInf_c::getWidthF(), temp_f27 - mDoGph_gInf_c::getMinYF(), false, false,
+48 -19
View File
@@ -5,6 +5,7 @@
#include "d/d_com_inf_game.h"
#include "JSystem/J2DGraph/J2DAnimation.h"
#include "JSystem/J2DGraph/J2DAnmLoader.h"
#include "dusk/frame_interpolation.h"
#include <cstring>
dSelect_cursorHIO_c::dSelect_cursorHIO_c() {
@@ -270,15 +271,22 @@ void dSelect_cursor_c::update() {
if (mUpdateFlag) {
if (field_0x30) {
if (chkPlayAnime(0)) {
if (mNameIdx == 1) {
field_0x44 += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x44 += fVar1;
}
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (mNameIdx == 1) {
field_0x44 += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x44 += fVar1;
}
if (field_0x44 >= field_0x30->getFrameMax()) {
field_0x44 -= field_0x30->getFrameMax();
if (field_0x44 >= field_0x30->getFrameMax()) {
field_0x44 -= field_0x30->getFrameMax();
}
#ifdef TARGET_PC
}
#endif
field_0x30->setFrame(field_0x44);
setBpkAnimation(field_0x30);
@@ -294,14 +302,21 @@ void dSelect_cursor_c::update() {
for (int i = 0; i < 2; i++) {
if (field_0x34[i]) {
if ((i == 0 && chkPlayAnime(2)) || (i == 1 && chkPlayAnime(3))) {
if (mNameIdx == 1) {
field_0x48[i] += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x48[i] += fVar1;
}
if (field_0x48[i] >= field_0x34[i]->getFrameMax()) {
field_0x48[i] -= field_0x34[i]->getFrameMax();
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (mNameIdx == 1) {
field_0x48[i] += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x48[i] += fVar1;
}
if (field_0x48[i] >= field_0x34[i]->getFrameMax()) {
field_0x48[i] -= field_0x34[i]->getFrameMax();
}
#ifdef TARGET_PC
}
#endif
field_0x34[i]->setFrame(field_0x48[i]);
}
@@ -310,7 +325,11 @@ void dSelect_cursor_c::update() {
}
if (field_0x2C && chkPlayAnime(1)) {
if (mNameIdx == 1) {
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
if (mNameIdx == 1) {
field_0x40 += mpCursorHIO->field_0x8 * fVar1;
} else {
field_0x40 += fVar1;
@@ -318,14 +337,24 @@ void dSelect_cursor_c::update() {
if (field_0x40 >= field_0x2C->getFrameMax()) {
field_0x40 -= field_0x2C->getFrameMax();
}
field_0x2C->setFrame(field_0x40);
setBckAnimation(field_0x2C);
#ifdef TARGET_PC
}
#endif
field_0x2C->setFrame(field_0x40);
setBckAnimation(field_0x2C);
}
if (chkPlayAnime(1) && mNameIdx == 0) {
setCursorAnimation();
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 tick = 0; tick < ui_advance_ticks; ++tick) {
#endif
setCursorAnimation();
#ifdef TARGET_PC
}
#endif
}
mpScreen->animation();
+18 -8
View File
@@ -2,21 +2,31 @@
#include "d/d_select_icon.h"
#include "JSystem/J2DGraph/J2DAnimation.h"
#include "dusk/frame_interpolation.h"
dSi_HIO_c::dSi_HIO_c() {}
void dSelect_icon_c::animation() {
if (field_0x10->getAlpha() != 0) {
field_0x20 += field_0x2c;
if (field_0x20 >= field_0x1c->getFrameMax()) {
field_0x20 = 0.0f;
}
field_0x1c->setFrame(field_0x20);
#ifdef TARGET_PC
const u32 ui_advance_ticks = dusk::frame_interp::get_presentation_ui_advance_ticks();
for (u32 i = 0; i < ui_advance_ticks; ++i) {
#endif
field_0x20 += field_0x2c;
if (field_0x20 >= field_0x1c->getFrameMax()) {
field_0x20 = 0.0f;
}
field_0x1c->setFrame(field_0x20);
field_0x28 += field_0x2c;
if (field_0x28 >= field_0x24->getFrameMax()) {
field_0x28 = 0.0f;
field_0x28 += field_0x2c;
if (field_0x28 >= field_0x24->getFrameMax()) {
field_0x28 = 0.0f;
}
#ifdef TARGET_PC
}
// Set even if not advancing
field_0x1c->setFrame(field_0x20);
#endif
field_0x24->setFrame(field_0x28);
field_0x8->animation();
+409
View File
@@ -0,0 +1,409 @@
#include "dusk/frame_interpolation.h"
#include <algorithm>
#include <cmath>
#include <cstdint>
#include <memory>
#include <unordered_map>
#include <vector>
namespace {
enum class Op : uint8_t {
OpenChild,
FinalMtx,
};
struct Label {
const void* key = nullptr;
int32_t id = 0;
bool operator==(const Label& other) const {
return key == other.key && id == other.id;
}
};
struct Data {
Label child_label{};
size_t child_index = 0;
Mtx matrix{};
const Mtx* dest = nullptr;
};
struct Path;
struct ChildBucket {
Label label{};
std::vector<std::unique_ptr<Path>> nodes;
};
struct OpBucket {
Op op = Op::OpenChild;
std::vector<Data> values;
};
struct Path {
std::vector<ChildBucket> children;
std::vector<OpBucket> ops;
std::vector<std::pair<Op, size_t>> items;
};
struct Recording {
Path root;
};
struct MatrixValue {
Mtx value;
};
using FinalMtxLookup = std::unordered_map<const Mtx*, const Data*>;
bool s_initialized = false;
bool g_enabled = false;
bool g_recording = false;
bool g_interpolating = false;
float g_step = 0.0f;
uint32_t g_pending_presentation_ui_ticks = 0;
uint32_t g_current_presentation_ui_ticks = 0;
Recording g_current_recording;
Recording g_previous_recording;
std::vector<Path*> g_current_path;
std::unordered_map<const Mtx*, MatrixValue> g_replacements;
inline void copy_matrix(const Mtx src, Mtx dst) {
MTXCopy(src, dst);
}
inline void concat_matrix(const Mtx lhs, const Mtx rhs, Mtx out) {
MTXConcat(lhs, rhs, out);
}
inline void lerp_matrix(Mtx out, const Mtx lhs, const Mtx rhs, float step) {
const float old_weight = 1.0f - step;
for (size_t row = 0; row < 3; ++row) {
for (size_t col = 0; col < 4; ++col) {
out[row][col] = lhs[row][col] * old_weight + rhs[row][col] * step;
}
}
}
inline bool matrix_differs(const Mtx lhs, const Mtx rhs, float epsilon = 0.0001f) {
for (size_t row = 0; row < 3; ++row) {
for (size_t col = 0; col < 4; ++col) {
if (std::abs(lhs[row][col] - rhs[row][col]) > epsilon) {
return true;
}
}
}
return false;
}
Data& append_op(Op op) {
auto& items = g_current_path.back()->items;
auto& buckets = g_current_path.back()->ops;
auto it = std::find_if(buckets.begin(), buckets.end(),
[op](const OpBucket& bucket) { return bucket.op == op; });
if (it == buckets.end()) {
buckets.push_back({op, {}});
it = buckets.end() - 1;
}
items.emplace_back(op, it->values.size());
return it->values.emplace_back();
}
const Data* find_matching_data(const Path& path, Op op, size_t index) {
auto it = std::find_if(path.ops.begin(), path.ops.end(),
[op](const OpBucket& bucket) { return bucket.op == op; });
if (it == path.ops.end() || index >= it->values.size()) {
return nullptr;
}
return &it->values[index];
}
const OpBucket* find_op_bucket(const Path& path, Op op) {
auto it = std::find_if(path.ops.begin(), path.ops.end(),
[op](const OpBucket& bucket) { return bucket.op == op; });
if (it == path.ops.end()) {
return nullptr;
}
return &*it;
}
void build_final_mtx_lookup(const Path& path, FinalMtxLookup& lookup) {
lookup.clear();
const OpBucket* bucket = find_op_bucket(path, Op::FinalMtx);
if (bucket == nullptr) {
return;
}
for (const Data& data : bucket->values) {
if (data.dest == nullptr) {
continue;
}
lookup[data.dest] = &data;
}
}
const Data* find_matching_final_mtx(const FinalMtxLookup& lookup, const Data& new_data) {
if (new_data.dest == nullptr) {
return nullptr;
}
auto it = lookup.find(new_data.dest);
if (it == lookup.end()) {
return nullptr;
}
return it->second;
}
ChildBucket& get_child_bucket(Path& path, const Label& label) {
auto it = std::find_if(path.children.begin(), path.children.end(),
[&label](const ChildBucket& bucket) { return bucket.label == label; });
if (it == path.children.end()) {
path.children.push_back({});
it = path.children.end() - 1;
it->label = label;
}
return *it;
}
const ChildBucket* find_child_bucket(const Path& path, const Label& label) {
auto it = std::find_if(path.children.begin(), path.children.end(),
[&label](const ChildBucket& bucket) { return bucket.label == label; });
if (it == path.children.end()) {
return nullptr;
}
return &*it;
}
void store_replacement(const Data& old_data, const Data& new_data, float step) {
if (new_data.dest == nullptr) {
return;
}
auto& replacement = g_replacements[new_data.dest];
lerp_matrix(replacement.value, old_data.matrix, new_data.matrix, step);
}
void interpolate_branch(const Path& old_path, const Path& new_path, float step) {
FinalMtxLookup old_final_mtx_lookup;
build_final_mtx_lookup(old_path, old_final_mtx_lookup);
for (const auto& item : new_path.items) {
const Op op = item.first;
const size_t index = item.second;
const Data* new_data = find_matching_data(new_path, op, index);
if (new_data == nullptr) {
continue;
}
if (op == Op::OpenChild) {
const ChildBucket* new_children = find_child_bucket(new_path, new_data->child_label);
if (new_children == nullptr || new_data->child_index >= new_children->nodes.size())
{
continue;
}
const Path& new_child = *new_children->nodes[new_data->child_index];
const ChildBucket* old_children = find_child_bucket(old_path, new_data->child_label);
if (old_children != nullptr && new_data->child_index < old_children->nodes.size())
{
interpolate_branch(*old_children->nodes[new_data->child_index], new_child, step);
} else {
interpolate_branch(new_child, new_child, step);
}
continue;
}
const Data* indexed_old_data = find_matching_data(old_path, op, index);
const Data* old_data = op == Op::FinalMtx ? find_matching_final_mtx(old_final_mtx_lookup, *new_data) : indexed_old_data;
if (op == Op::FinalMtx) {
store_replacement(old_data != nullptr ? *old_data : *new_data, *new_data, step);
}
}
}
const Mtx* resolve_replacement(const Mtx* source, Mtx* scratch) {
if (!g_interpolating || source == nullptr) {
return source;
}
auto it = g_replacements.find(source);
if (it == g_replacements.end()) {
return source;
}
copy_matrix(it->second.value, *scratch);
return scratch;
}
bool has_recording_data(const Recording& recording) {
return !recording.root.items.empty() || !recording.root.children.empty();
}
void clear_replacements() {
g_replacements.clear();
}
} // namespace
namespace dusk {
namespace frame_interp {
void ensure_initialized() {
g_enabled = getSettings().game.enableFrameInterpolation;
s_initialized = true;
}
void begin_record() {
ensure_initialized();
if (!g_enabled) {
g_interpolating = false;
g_previous_recording = {};
g_current_recording = {};
g_current_path.clear();
clear_replacements();
return;
}
g_previous_recording = std::move(g_current_recording);
g_current_recording = {};
g_current_path.clear();
g_current_path.push_back(&g_current_recording.root);
g_recording = true;
g_interpolating = false;
clear_replacements();
}
void end_record() {
g_recording = false;
}
void interpolate(float step) {
ensure_initialized();
clear_replacements();
g_step = std::clamp(step, 0.0f, 1.0f);
g_interpolating = g_enabled && !g_recording && has_recording_data(g_current_recording);
if (!g_interpolating) {
return;
}
if (!has_recording_data(g_previous_recording)) {
interpolate_branch(g_current_recording.root, g_current_recording.root, g_step);
return;
}
interpolate_branch(g_previous_recording.root, g_current_recording.root, g_step);
}
float get_interpolation_step() {
return g_step;
}
void notify_sim_tick_complete() {
ensure_initialized();
g_pending_presentation_ui_ticks++;
}
uint32_t begin_presentation_ui_pass() {
ensure_initialized();
g_current_presentation_ui_ticks = g_pending_presentation_ui_ticks;
g_pending_presentation_ui_ticks = 0;
return g_current_presentation_ui_ticks;
}
uint32_t get_presentation_ui_advance_ticks() {
if (!s_initialized) {
return 0;
}
if (!g_enabled) {
return 1;
}
return g_current_presentation_ui_ticks;
}
void end_presentation_ui_pass() {
if (!s_initialized) {
return;
}
g_current_presentation_ui_ticks = 0;
}
void open_child(const void* key, int32_t id) {
if (!s_initialized || !g_recording) {
return;
}
Label label{key, id};
auto& siblings = get_child_bucket(*g_current_path.back(), label).nodes;
Data& data = append_op(Op::OpenChild);
data.child_label = label;
data.child_index = siblings.size();
siblings.emplace_back(std::make_unique<Path>());
g_current_path.push_back(siblings.back().get());
}
void close_child() {
if (!s_initialized || !g_recording || g_current_path.size() <= 1) {
return;
}
g_current_path.pop_back();
}
void record_final_mtx_raw(const Mtx* dest, const Mtx src) {
if (!s_initialized || !g_recording || dest == nullptr) {
return;
}
Data& data = append_op(Op::FinalMtx);
data.dest = dest;
copy_matrix(src, data.matrix);
}
bool lookup_replacement(const void* source, Mtx out) {
if (!s_initialized || !g_interpolating || source == nullptr) {
return false;
}
auto it = g_replacements.find(reinterpret_cast<const Mtx*>(source));
if (it == g_replacements.end()) {
return false;
}
copy_matrix(it->second.value, out);
return true;
}
bool lookup_concat_replacement(const void* lhs, const void* rhs, Mtx out) {
if (!s_initialized || !g_interpolating || lhs == nullptr || rhs == nullptr) {
return false;
}
Mtx lhs_scratch;
Mtx rhs_scratch;
const Mtx* resolved_lhs = resolve_replacement(reinterpret_cast<const Mtx*>(lhs), &lhs_scratch);
const Mtx* resolved_rhs = resolve_replacement(reinterpret_cast<const Mtx*>(rhs), &rhs_scratch);
if (resolved_lhs == reinterpret_cast<const Mtx*>(lhs) &&
resolved_rhs == reinterpret_cast<const Mtx*>(rhs))
{
return false;
}
concat_matrix(*resolved_lhs, *resolved_rhs, out);
return true;
}
// TODO: Is there already a built-in function for this?
void camera_eye_from_view_mtx(MtxP view_mtx, cXyz* o_eye) {
o_eye->x = -(view_mtx[0][0] * view_mtx[0][3] + view_mtx[1][0] * view_mtx[1][3] + view_mtx[2][0] * view_mtx[2][3]);
o_eye->y = -(view_mtx[0][1] * view_mtx[0][3] + view_mtx[1][1] * view_mtx[1][3] + view_mtx[2][1] * view_mtx[2][3]);
o_eye->z = -(view_mtx[0][2] * view_mtx[0][3] + view_mtx[1][2] * view_mtx[1][3] + view_mtx[2][2] * view_mtx[2][3]);
}
} // namespace frame_interp
} // namespace dusk
+10 -4
View File
@@ -206,10 +206,6 @@ namespace dusk {
void ImGuiConsole::PreDraw() {
ZoneScoped;
if (dusk::IsGameLaunched && !m_isLaunchInitialized) {
m_toasts.emplace_back("Press F1 to toggle menu"s, 5.f);
m_isLaunchInitialized = true;
}
UpdateSettings();
@@ -241,6 +237,16 @@ namespace dusk {
m_preLaunchWindow.draw();
}
if (!getSettings().backend.wasPresetChosen) {
m_firstRunPreset.draw();
return;
}
if (dusk::IsGameLaunched && !m_isLaunchInitialized) {
m_toasts.emplace_back("Press F1 to toggle menu"s, 5.f);
m_isLaunchInitialized = true;
}
m_menuGame.windowControllerConfig();
m_menuGame.windowInputViewer();
if (dusk::IsGameLaunched) {
+2
View File
@@ -6,6 +6,7 @@
#include <string>
#include <string_view>
#include "ImGuiFirstRunPreset.hpp"
#include "ImGuiMenuEnhancements.hpp"
#include "ImGuiMenuGame.hpp"
#include "ImGuiMenuTools.hpp"
@@ -35,6 +36,7 @@ private:
bool m_isLaunchInitialized = false;
std::deque<Toast> m_toasts;
ImGuiFirstRunPreset m_firstRunPreset;
ImGuiMenuGame m_menuGame;
ImGuiMenuEnhancements m_menuEnhancements;
ImGuiPreLaunchWindow m_preLaunchWindow;
+1 -1
View File
@@ -144,7 +144,7 @@ void ImGuiEngine_Initialize(float scale) {
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);
colors[ImGuiCol_ModalWindowDimBg] = ImVec4(0.00f, 0.00f, 0.00f, 0.60f);
}
Image GetImage(const std::string& path) {
+132
View File
@@ -0,0 +1,132 @@
#include "ImGuiFirstRunPreset.hpp"
#include "imgui.h"
#include "ImGuiConsole.hpp"
#include "ImGuiEngine.hpp"
#include "dusk/settings.h"
#include "dusk/config.hpp"
#include <dusk/dusk.h>
namespace dusk {
static void ApplyPresetClassic() {
auto& s = getSettings();
s.video.lockAspectRatio.setValue(true);
VILockAspectRatio(defaultAspectRatioW, defaultAspectRatioH);
}
static void ApplyPresetHD() {
auto& s = getSettings();
s.game.hideTvSettingsScreen.setValue(true);
s.game.noReturnRupees.setValue(true);
s.game.disableRupeeCutscenes.setValue(true);
s.game.noSwordRecoil.setValue(true);
s.game.fastClimbing.setValue(true);
s.game.noMissClimbing.setValue(true);
s.game.fastTears.setValue(true);
s.game.biggerWallets.setValue(true);
s.game.invertCameraXAxis.setValue(true);
}
static void ApplyPresetDusk() {
ApplyPresetHD();
auto& s = getSettings();
s.game.enableQuickTransform.setValue(true);
s.game.instantSaves.setValue(true);
s.game.midnasLamentNonStop.setValue(true);
s.game.enableFrameInterpolation.setValue(true);
}
// =========================================================================
void ImGuiFirstRunPreset::draw() {
const char* modalTitle = "Welcome to Dusk!";
if (m_done) return;
if (!m_opened) {
ImGui::OpenPopup(modalTitle);
m_opened = true;
}
const ImGuiViewport* viewport = ImGui::GetMainViewport();
ImGui::SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::SetNextWindowSize(ImVec2(800.0f * ImGuiScale(), 0.0f), ImGuiCond_Always);
if (!ImGui::BeginPopupModal(modalTitle, nullptr, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoMove)) {
// force the user to actually pick one, and not just hit escape to skip the dialog
m_opened = false;
return;
}
ImGui::TextWrapped("Choose a preset to get started. You can change any setting later from the Enhancements menu.");
ImGui::Spacing();
ImGui::Separator();
ImGui::Spacing();
int chosen = -1;
if (ImGui::BeginTable("##presets", 5, ImGuiTableFlags_None)) {
ImGui::TableSetupColumn(nullptr, ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn(nullptr, ImGuiTableColumnFlags_WidthFixed, 16.0f * ImGuiScale());
ImGui::TableSetupColumn(nullptr, ImGuiTableColumnFlags_WidthStretch);
ImGui::TableSetupColumn(nullptr, ImGuiTableColumnFlags_WidthFixed, 16.0f * ImGuiScale());
ImGui::TableSetupColumn(nullptr, ImGuiTableColumnFlags_WidthStretch);
ImGui::TableNextRow();
ImGui::PushFont(ImGuiEngine::fontLarge);
ImGui::TableSetColumnIndex(0);
if (ImGui::Button("Classic##btn", ImVec2(ImGui::GetContentRegionAvail().x, 80.0f * ImGuiScale()))) {
chosen = 0;
}
ImGui::TableSetColumnIndex(2);
if (ImGui::Button("HD##btn", ImVec2(ImGui::GetContentRegionAvail().x, 80.0f * ImGuiScale()))) {
chosen = 1;
}
ImGui::TableSetColumnIndex(4);
if (ImGui::Button("Dusk##btn", ImVec2(ImGui::GetContentRegionAvail().x, 80.0f * ImGuiScale())))
{
chosen = 2;
}
ImGui::PopFont();
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::Spacing();
ImGui::TextWrapped("All enhancements disabled to match the GameCube version. Good for speedrunning or simple nostalgia!");
ImGui::TableSetColumnIndex(2);
ImGui::Spacing();
ImGui::TextWrapped("Some enhancements enabled to match the HD version. A good starting point for most players!");
ImGui::TableSetColumnIndex(4);
ImGui::Spacing();
ImGui::TextWrapped("More enhancements enabled than the HD preset. Veteran players will appreciate the additional tweaks!");
ImGui::EndTable();
}
if (chosen >= 0) {
if (chosen == 0) ApplyPresetClassic();
if (chosen == 1) ApplyPresetHD();
if (chosen == 2) ApplyPresetDusk();
getSettings().backend.wasPresetChosen.setValue(true);
config::Save();
m_done = true;
ImGui::CloseCurrentPopup();
}
ImGui::EndPopup();
}
} // namespace dusk
+14
View File
@@ -0,0 +1,14 @@
#pragma once
namespace dusk {
class ImGuiFirstRunPreset {
public:
void draw();
private:
bool m_opened = false;
bool m_done = false;
};
} // namespace dusk
+33 -20
View File
@@ -14,48 +14,48 @@ namespace dusk {
config::ImGuiCheckbox("Bigger Wallets", getSettings().game.biggerWallets);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Wallet sizes are like in the HD version (500, 1000, 2000)");
ImGui::SetTooltip("Wallet sizes are like in the HD version. (500, 1000, 2000)");
}
config::ImGuiCheckbox("No Rupee Returns", getSettings().game.noReturnRupees);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Always collect Rupees even if your Wallet is too full");
ImGui::SetTooltip("Always collect Rupees even if your Wallet is too full.");
}
config::ImGuiCheckbox("Disable Rupee Cutscenes", getSettings().game.disableRupeeCutscenes);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Rupees won't play cutscenes after you've collected them the first time");
ImGui::SetTooltip("Rupees won't play cutscenes after you've collected them the first time.");
}
config::ImGuiCheckbox("No Sword Recoil", getSettings().game.noSwordRecoil);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Link won't recoil when his sword hits walls");
ImGui::SetTooltip("Link won't recoil when his sword hits walls.");
}
config::ImGuiCheckbox("Faster Climbing", getSettings().game.fastClimbing);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Quicker climbing on ladders and vines like the HD version");
ImGui::SetTooltip("Quicker climbing on ladders and vines like the HD version.");
}
config::ImGuiCheckbox("No Climbing Miss Animation", getSettings().game.noMissClimbing);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Prevents Link from playing a struggle animation\n"
"when using the Clawshot on vines at a weird angle");
"when grabbing ledges or climbing on vines.");
}
config::ImGuiCheckbox("Faster Tears of Light", getSettings().game.fastTears);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Tears of Light dropped by Shadow Insects pop out faster like the HD version");
ImGui::SetTooltip("Tears of Light dropped by Shadow Insects pop out faster like the HD version.");
}
config::ImGuiCheckbox("Hide TV Settings Screen", getSettings().game.hideTvSettingsScreen);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Hides the TV calibration screen shown when loading a save");
ImGui::SetTooltip("Hides the TV calibration screen shown when loading a save.");
}
config::ImGuiCheckbox("Instant Saves", getSettings().game.instantSaves);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Skip the delay when writing to the Memory Card");
ImGui::SetTooltip("Skip the delay when writing to the Memory Card.");
}
ImGui::EndMenu();
@@ -64,7 +64,7 @@ namespace dusk {
if (ImGui::BeginMenu("Preferences")) {
config::ImGuiCheckbox("Mirror Mode", getSettings().game.enableMirrorMode);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Mirrors the world, matching the Wii version of the game");
ImGui::SetTooltip("Mirrors the world, matching the Wii version of the game.");
}
config::ImGuiCheckbox("Invert Camera X Axis", getSettings().game.invertCameraXAxis);
@@ -73,12 +73,21 @@ namespace dusk {
}
if (ImGui::BeginMenu("Graphics")) {
config::ImGuiCheckbox("Native Bloom", getSettings().game.enableBloom);
config::ImGuiCheckbox("Unlock Framerate", getSettings().game.enableFrameInterpolation);
const bool frameInterpolationHovered = ImGui::IsItemHovered();
config::ImGuiCheckbox("Water Projection Offset", getSettings().game.useWaterProjectionOffset);
ImGui::SameLine();
ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1.0f, 0.72f, 0.2f, 1.0f));
ImGui::TextUnformatted("[EXPERIMENTAL]");
ImGui::PopStyleColor();
if (frameInterpolationHovered || ImGui::IsItemHovered()) {
ImGui::SetTooltip("Uses inter-frame interpolation to enable higher frame rates.\nVisual artifacts, animation glitches, or instability may occur.");
}
config::ImGuiSliderInt("Shadow Resolution", getSettings().game.shadowResolutionMultiplier, 1, 8, "x%d");
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Adds GC-specific -0.01 transS offset\n"
"that causes ~6px ghost artifacts in water reflections");
ImGui::SetTooltip("Improves the shadow resolution, making them higher quality.");
}
ImGui::EndMenu();
@@ -87,12 +96,12 @@ namespace dusk {
if (ImGui::BeginMenu("Audio")) {
config::ImGuiCheckbox("No Low HP Sound", getSettings().game.noLowHpSound);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Disable the beeping sound when having low health");
ImGui::SetTooltip("Disable the beeping sound when having low health.");
}
config::ImGuiCheckbox("Non-Stop Midna's Lament", getSettings().game.midnasLamentNonStop);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Prevents enemy music while Midna's Lament is playing");
ImGui::SetTooltip("Prevents enemy music while Midna's Lament is playing.");
}
ImGui::EndMenu();
@@ -103,7 +112,7 @@ namespace dusk {
config::ImGuiCheckbox("Can Transform Anywhere", getSettings().game.canTransformAnywhere);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Allows you to transform even if NPCs are looking");
ImGui::SetTooltip("Allows you to transform even if NPCs are looking.");
}
config::ImGuiCheckbox("Fast Spinner", getSettings().game.fastSpinner);
@@ -124,7 +133,7 @@ namespace dusk {
config::ImGuiCheckbox("Instant Death", getSettings().game.instantDeath);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Any hit will instantly kill you");
ImGui::SetTooltip("Any hit will instantly kill you.");
}
ImGui::EndMenu();
@@ -134,7 +143,7 @@ namespace dusk {
config::ImGuiCheckbox("Restore Wii 1.0 Glitches", getSettings().game.restoreWiiGlitches);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Restores patched glitches from Wii USA 1.0,\n"
"the first released version");
"the first released version.");
}
ImGui::EndMenu();
@@ -142,6 +151,10 @@ namespace dusk {
if (ImGui::BeginMenu("Tools")) {
config::ImGuiCheckbox("Enable Turbo Key", getSettings().game.enableTurboKeybind);
if (ImGui::IsItemHovered()) {
ImGui::SetTooltip("Holding TAB will speed up the game.\n"
"This will not work with the \"Unlock Framerate\" enhancement.");
}
ImGui::EndMenu();
}
+4
View File
@@ -62,6 +62,10 @@ namespace dusk {
config::Save();
}
config::ImGuiCheckbox("Native Bloom", getSettings().game.enableBloom);
config::ImGuiCheckbox("Enable Water Refraction", getSettings().game.enableWaterRefraction);
ImGui::EndMenu();
}
+521 -1
View File
@@ -7,6 +7,8 @@
#include "d/d_com_inf_game.h"
#include "d/d_item_data.h"
#include "d/d_meter2_info.h"
#include "d/d_save.h"
#include <map>
@@ -280,6 +282,132 @@ namespace dusk {
{ dItemNo_NONE_e, {"None"} },
};
static constexpr int BUG_SPECIES_COUNT = 12;
static const u8 sBugItemIds[BUG_SPECIES_COUNT * 2] = {
dItemNo_M_ANT_e, dItemNo_F_ANT_e,
dItemNo_M_MAYFLY_e, dItemNo_F_MAYFLY_e,
dItemNo_M_BEETLE_e, dItemNo_F_BEETLE_e,
dItemNo_M_MANTIS_e, dItemNo_F_MANTIS_e,
dItemNo_M_STAG_BEETLE_e, dItemNo_F_STAG_BEETLE_e,
dItemNo_M_DANGOMUSHI_e, dItemNo_F_DANGOMUSHI_e,
dItemNo_M_BUTTERFLY_e, dItemNo_F_BUTTERFLY_e,
dItemNo_M_LADYBUG_e, dItemNo_F_LADYBUG_e,
dItemNo_M_SNAIL_e, dItemNo_F_SNAIL_e,
dItemNo_M_NANAFUSHI_e, dItemNo_F_NANAFUSHI_e,
dItemNo_M_GRASSHOPPER_e, dItemNo_F_GRASSHOPPER_e,
dItemNo_M_DRAGONFLY_e, dItemNo_F_DRAGONFLY_e,
};
static const u16 sBugTurnInFlags[BUG_SPECIES_COUNT * 2] = {
dSv_event_flag_c::F_0421, dSv_event_flag_c::F_0422,
dSv_event_flag_c::F_0423, dSv_event_flag_c::F_0424,
dSv_event_flag_c::F_0401, dSv_event_flag_c::F_0402,
dSv_event_flag_c::F_0413, dSv_event_flag_c::F_0414,
dSv_event_flag_c::F_0405, dSv_event_flag_c::F_0406,
dSv_event_flag_c::F_0411, dSv_event_flag_c::F_0412,
dSv_event_flag_c::F_0403, dSv_event_flag_c::F_0404,
dSv_event_flag_c::F_0415, dSv_event_flag_c::F_0416,
dSv_event_flag_c::F_0417, dSv_event_flag_c::F_0418,
dSv_event_flag_c::F_0409, dSv_event_flag_c::F_0410,
dSv_event_flag_c::F_0407, dSv_event_flag_c::F_0408,
dSv_event_flag_c::F_0419, dSv_event_flag_c::F_0420,
};
static const char* sBugSpeciesNames[BUG_SPECIES_COUNT] = {
"Ant", "Dayfly", "Beetle", "Mantis",
"Stag Beetle", "Pill Bug", "Butterfly", "Ladybug",
"Snail", "Phasmid", "Grasshopper", "Dragonfly",
};
static constexpr int HIDDEN_SKILL_COUNT = 7;
static const u16 sHiddenSkillFlags[HIDDEN_SKILL_COUNT] = {
dSv_event_flag_c::F_0339, dSv_event_flag_c::F_0338,
dSv_event_flag_c::F_0340, dSv_event_flag_c::F_0341,
dSv_event_flag_c::F_0342, dSv_event_flag_c::F_0343,
dSv_event_flag_c::F_0344,
};
static const char* sHiddenSkillNames[HIDDEN_SKILL_COUNT] = {
"Ending Blow", "Shield Attack", "Back Slice", "Helm Splitter",
"Mortal Draw", "Jump Strike", "Great Spin",
};
static constexpr int LETTER_COUNT = 16;
static const char* sLetterSenders[LETTER_COUNT] = {
"Renado", "Ooccoo 1", "Ooccoo 2", "The Postman",
"Kakariko Goods", "Barnes 1", "Barnes 2", "Barnes Bombs",
"Malo Mart", "Telma", "Purlo", "From Jr.",
"Princess Agitha", "Lanayru Tourism", "Shad", "Yeta",
};
static constexpr int FISH_COUNT = 6;
static const struct {
u8 index;
const char* name;
} sFishSpecies[FISH_COUNT] = {
{ 3, "Ordon Catfish" },
{ 5, "Greengill" },
{ 4, "Reekfish" },
{ 0, "Hyrule Bass" },
{ 2, "Hylian Pike" },
{ 1, "Hylian Loach" },
};
static const char* sSwordNames[4] = {
"Ordon Sword", "Master Sword", "Wooden Sword", "Light Sword",
};
static const char* sShieldNames[3] = {
"Wooden Shield", "Ordon Shield", "Hylian Shield",
};
static const char* sFusedShadowNames[3] = {
"Forest Temple",
"Goron Mines",
"Lakebed Temple",
};
static const struct {
u8 index;
const char* name;
} sMirrorShards[3] = {
{ 1, "Snowpeak Ruins" },
{ 2, "Temple of Time" },
{ 3, "City in the Sky" },
};
static const struct {
u8 slot;
u8 item;
} sDefaultInventory[] = {
{ SLOT_0, dItemNo_BOOMERANG_e },
{ SLOT_1, dItemNo_KANTERA_e },
{ SLOT_2, dItemNo_SPINNER_e },
{ SLOT_3, dItemNo_HVY_BOOTS_e },
{ SLOT_4, dItemNo_BOW_e },
{ SLOT_5, dItemNo_HAWK_EYE_e },
{ SLOT_6, dItemNo_IRONBALL_e },
{ SLOT_8, dItemNo_COPY_ROD_e },
{ SLOT_9, dItemNo_HOOKSHOT_e },
{ SLOT_10, dItemNo_W_HOOKSHOT_e },
{ SLOT_11, dItemNo_EMPTY_BOTTLE_e },
{ SLOT_12, dItemNo_EMPTY_BOTTLE_e },
{ SLOT_13, dItemNo_EMPTY_BOTTLE_e },
{ SLOT_14, dItemNo_EMPTY_BOTTLE_e },
{ SLOT_15, dItemNo_NORMAL_BOMB_e },
{ SLOT_16, dItemNo_WATER_BOMB_e },
{ SLOT_17, dItemNo_POKE_BOMB_e },
{ SLOT_18, dItemNo_DUNGEON_EXIT_e },
{ SLOT_20, dItemNo_FISHING_ROD_1_e},
{ SLOT_21, dItemNo_HORSE_FLUTE_e },
{ SLOT_22, dItemNo_ANCIENT_DOCUMENT_e },
{ SLOT_23, dItemNo_PACHINKO_e },
};
ImGuiSaveEditor::ImGuiSaveEditor() {}
void ImGuiSaveEditor::draw(bool& open) {
@@ -307,7 +435,7 @@ namespace dusk {
}
if (ImGui::BeginTabItem("Collection")) {
//DrawFlagsTab();
drawCollectionTab();
ImGui::EndTabItem();
}
@@ -675,9 +803,30 @@ namespace dusk {
}
}
static u8 getSlotDefault(int slot) {
for (size_t i = 0; i < sizeof(sDefaultInventory) / sizeof(sDefaultInventory[0]); i++) {
if (sDefaultInventory[i].slot == slot) {
return sDefaultInventory[i].item;
}
}
return dItemNo_NONE_e;
}
void ImGuiSaveEditor::drawInventoryTab() {
dSv_player_item_c& item = dComIfGs_getSaveData()->getPlayer().getItem();
if (ImGui::Button("Default All##inv_default_all")) {
for (int slot = 0; slot < 24; slot++) {
dComIfGs_setItem(slot, getSlotDefault(slot));
}
}
ImGui::SameLine();
if (ImGui::Button("Clear All##inv_clear_all")) {
for (int slot = 0; slot < 24; slot++) {
dComIfGs_setItem(slot, dItemNo_NONE_e);
}
}
ImGuiBeginGroupPanel("Items", { 200, 100 });
for (int slot = 0; slot < 24; slot++) {
ImGui::Text("Slot %02d: ", slot);
@@ -696,12 +845,369 @@ namespace dusk {
}
ImGui::EndCombo();
}
ImGui::SameLine();
if (ImGui::SmallButton(fmt::format("Default##slot_d_{}", slot).c_str())) {
dComIfGs_setItem(slot, getSlotDefault(slot));
}
ImGui::SameLine();
if (ImGui::SmallButton(fmt::format("Clear##slot_c_{}", slot).c_str())) {
dComIfGs_setItem(slot, dItemNo_NONE_e);
}
}
ImGuiEndGroupPanel();
}
static inline void setItemFirstBit(u8 itemNo, bool owned) {
if (owned) {
dComIfGs_onItemFirstBit(itemNo);
} else {
dComIfGs_offItemFirstBit(itemNo);
}
}
static inline void setEventBit(u16 flag, bool on) {
if (on) {
dComIfGs_onEventBit(flag);
} else {
dComIfGs_offEventBit(flag);
}
}
static void setLetterGetFlag(int idx, bool received) {
dSv_letter_info_c& info = dComIfGs_getSaveData()->getPlayer().getLetterInfo();
if (received) {
if (dComIfGs_isLetterGetFlag(idx)) return;
dComIfGs_onLetterGetFlag(idx);
u8 slot = dMeter2Info_getRecieveLetterNum() - 1;
if (slot < 64) {
dComIfGs_setGetNumber(slot, (u8)(idx + 1));
}
} else {
if (!dComIfGs_isLetterGetFlag(idx)) return;
info.mLetterGetFlags[idx >> 5] &= ~(1u << (idx & 0x1F));
for (int j = 0; j < 64; j++) {
if (dComIfGs_getGetNumber(j) == idx + 1) {
for (int k = j; k < 63; k++) {
dComIfGs_setGetNumber(k, dComIfGs_getGetNumber(k + 1));
}
dComIfGs_setGetNumber(63, 0);
break;
}
}
}
}
void ImGuiSaveEditor::drawCollectionTab() {
if (ImGui::TreeNode("Equipment")) {
if (ImGui::TreeNode("Swords")) {
for (int i = 0; i < 4; i++) {
bool got = dComIfGs_isCollectSword((u8)i) != 0;
if (ImGui::Checkbox(fmt::format("{0}##sword_{1}", sSwordNames[i], i).c_str(), &got)) {
if (got) dComIfGs_setCollectSword((u8)i);
else dComIfGs_offCollectSword((u8)i);
}
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Shields")) {
for (int i = 0; i < 3; i++) {
bool got = dComIfGs_isCollectShield((u8)i) != 0;
if (ImGui::Checkbox(fmt::format("{0}##shield_{1}", sShieldNames[i], i).c_str(), &got)) {
if (got) dComIfGs_setCollectShield((u8)i);
else dComIfGs_offCollectShield((u8)i);
}
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Tunics")) {
bool ordonClothes = dComIfGs_isItemFirstBit(dItemNo_WEAR_CASUAL_e) != 0;
if (ImGui::Checkbox("Ordon Clothes##tunic_ordon", &ordonClothes)) {
setItemFirstBit(dItemNo_WEAR_CASUAL_e, ordonClothes);
}
bool greenTunic = dComIfGs_isCollectClothes(KOKIRI_CLOTHES_FLAG) != 0;
if (ImGui::Checkbox("Hero's Clothes##tunic_green", &greenTunic)) {
if (greenTunic) dComIfGs_setCollectClothes(KOKIRI_CLOTHES_FLAG);
else dComIfGs_offCollectClothes(KOKIRI_CLOTHES_FLAG);
}
bool zoraArmor = dComIfGs_isItemFirstBit(dItemNo_WEAR_ZORA_e) != 0;
if (ImGui::Checkbox("Zora Armor##tunic_zora", &zoraArmor)) {
setItemFirstBit(dItemNo_WEAR_ZORA_e, zoraArmor);
}
bool magicArmor = dComIfGs_isItemFirstBit(dItemNo_ARMOR_e) != 0;
if (ImGui::Checkbox("Magic Armor##tunic_magic", &magicArmor)) {
setItemFirstBit(dItemNo_ARMOR_e, magicArmor);
}
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Key Items")) {
if (ImGui::TreeNode("Fused Shadows")) {
for (int i = 0; i < 3; i++) {
bool got = dComIfGs_isCollectCrystal((u8)i) != 0;
if (ImGui::Checkbox(
fmt::format("{0}##fs_{1}", sFusedShadowNames[i], i).c_str(), &got)) {
if (got) dComIfGs_onCollectCrystal((u8)i);
else dComIfGs_offCollectCrystal((u8)i);
}
}
ImGui::Spacing();
if (ImGui::Button("All##fs_all")) {
for (int i = 0; i < 3; i++) dComIfGs_onCollectCrystal((u8)i);
}
ImGui::SameLine();
if (ImGui::Button("None##fs_clear")) {
for (int i = 0; i < 3; i++) dComIfGs_offCollectCrystal((u8)i);
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Mirror Shards")) {
for (int i = 0; i < 3; i++) {
u8 idx = sMirrorShards[i].index;
bool got = dComIfGs_isCollectMirror(idx) != 0;
if (ImGui::Checkbox(
fmt::format("{0}##ms_{1}", sMirrorShards[i].name, i).c_str(), &got)) {
if (got) dComIfGs_onCollectMirror(idx);
else dComIfGs_offCollectMirror(idx);
}
}
ImGui::Spacing();
if (ImGui::Button("All##ms_all")) {
for (int i = 0; i < 3; i++) dComIfGs_onCollectMirror(sMirrorShards[i].index);
}
ImGui::SameLine();
if (ImGui::Button("None##ms_clear")) {
for (int i = 0; i < 3; i++) dComIfGs_offCollectMirror(sMirrorShards[i].index);
}
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Heart Pieces & Poe Souls")) {
if (ImGui::TreeNode("Poe Souls")) {
int poeCount = dComIfGs_getPohSpiritNum();
ImGui::Text("Collected:");
ImGui::SameLine();
ImGui::SetNextItemWidth(100.0f);
if (ImGui::InputInt("##poe_count", &poeCount)) {
if (poeCount < 0) poeCount = 0;
if (poeCount > 60) poeCount = 60;
dComIfGs_setPohSpiritNum((u8)poeCount);
}
ImGui::SameLine();
ImGui::TextDisabled("/ 60");
ImGui::Spacing();
if (ImGui::Button("All 60##poe_all")) {
dComIfGs_setPohSpiritNum(60);
}
ImGui::SameLine();
if (ImGui::Button("Clear##poe_clear")) {
dComIfGs_setPohSpiritNum(0);
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Heart Pieces")) {
int maxLife = dComIfGs_getMaxLife();
int hearts = maxLife / 5;
int pieces = maxLife % 5;
ImGui::Text("Max Life:");
ImGui::SameLine();
ImGui::SetNextItemWidth(160.0f);
if (ImGui::InputInt("##max_life", &maxLife, 1, 5)) {
if (maxLife < 15) maxLife = 15;
if (maxLife > 100) maxLife = 100;
dComIfGs_setMaxLife((u8)maxLife);
u16 maxHealth = (dComIfGs_getMaxLife() / 5) * 4;
if (dComIfGs_getLife() > maxHealth) {
dComIfGs_setLife(maxHealth);
}
}
ImGui::SameLine();
ImGui::TextDisabled("(%d hearts + %d pieces)", hearts, pieces);
ImGui::Spacing();
if (ImGui::Button("3 Hearts##hp_min")) {
dComIfGs_setMaxLife(15);
dComIfGs_setLife(12);
}
ImGui::SameLine();
if (ImGui::Button("20 Hearts##hp_max")) {
dComIfGs_setMaxLife(100);
dComIfGs_setLife(80);
}
ImGui::TreePop();
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Golden Bugs")) {
if (ImGui::BeginTable("GoldenBugTable", 5,
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Species");
ImGui::TableSetupColumn("Male");
ImGui::TableSetupColumn("Female");
ImGui::TableSetupColumn("M \xe2\x86\x92 Agitha"); // M → Agitha
ImGui::TableSetupColumn("F \xe2\x86\x92 Agitha"); // F → Agitha
ImGui::TableHeadersRow();
for (int species = 0; species < BUG_SPECIES_COUNT; species++) {
int maleIdx = species * 2;
int femaleIdx = species * 2 + 1;
u8 maleItem = sBugItemIds[maleIdx];
u8 femaleItem = sBugItemIds[femaleIdx];
u16 maleFlag = sBugTurnInFlags[maleIdx];
u16 femaleFlag = sBugTurnInFlags[femaleIdx];
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextUnformatted(sBugSpeciesNames[species]);
ImGui::TableSetColumnIndex(1);
bool maleOwned = dComIfGs_isItemFirstBit(maleItem) != 0;
if (ImGui::Checkbox(fmt::format("##bugM_own_{}", species).c_str(), &maleOwned)) {
setItemFirstBit(maleItem, maleOwned);
}
ImGui::TableSetColumnIndex(2);
bool femaleOwned = dComIfGs_isItemFirstBit(femaleItem) != 0;
if (ImGui::Checkbox(fmt::format("##bugF_own_{}", species).c_str(), &femaleOwned)) {
setItemFirstBit(femaleItem, femaleOwned);
}
ImGui::TableSetColumnIndex(3);
bool maleGiven = dComIfGs_isEventBit(maleFlag) != 0;
if (ImGui::Checkbox(fmt::format("##bugM_giv_{}", species).c_str(), &maleGiven)) {
setEventBit(maleFlag, maleGiven);
}
ImGui::TableSetColumnIndex(4);
bool femaleGiven = dComIfGs_isEventBit(femaleFlag) != 0;
if (ImGui::Checkbox(fmt::format("##bugF_giv_{}", species).c_str(), &femaleGiven)) {
setEventBit(femaleFlag, femaleGiven);
}
}
ImGui::EndTable();
}
ImGui::Spacing();
if (ImGui::Button("Collect All##bugs_all")) {
for (int i = 0; i < BUG_SPECIES_COUNT * 2; i++) {
dComIfGs_onItemFirstBit(sBugItemIds[i]);
}
}
ImGui::SameLine();
if (ImGui::Button("Clear All##bugs_clear")) {
for (int i = 0; i < BUG_SPECIES_COUNT * 2; i++) {
dComIfGs_offItemFirstBit(sBugItemIds[i]);
dComIfGs_offEventBit(sBugTurnInFlags[i]);
}
}
ImGui::SameLine();
if (ImGui::Button("Give All to Agitha##bugs_giveall")) {
for (int i = 0; i < BUG_SPECIES_COUNT * 2; i++) {
dComIfGs_onEventBit(sBugTurnInFlags[i]);
}
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Hidden Skills")) {
for (int i = 0; i < HIDDEN_SKILL_COUNT; i++) {
bool learned = dComIfGs_isEventBit(sHiddenSkillFlags[i]) != 0;
if (ImGui::Checkbox(
fmt::format("{0}##skill_{1}", sHiddenSkillNames[i], i).c_str(), &learned)) {
setEventBit(sHiddenSkillFlags[i], learned);
}
}
ImGui::Spacing();
if (ImGui::Button("Learn All##skills_all")) {
for (int i = 0; i < HIDDEN_SKILL_COUNT; i++) {
dComIfGs_onEventBit(sHiddenSkillFlags[i]);
}
}
ImGui::SameLine();
if (ImGui::Button("Forget All##skills_clear")) {
for (int i = 0; i < HIDDEN_SKILL_COUNT; i++) {
dComIfGs_offEventBit(sHiddenSkillFlags[i]);
}
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Collection Logs")) {
if (ImGui::TreeNode("Postman Letters")) {
for (int i = 0; i < LETTER_COUNT; i++) {
bool had = dComIfGs_isLetterGetFlag(i) != 0;
if (ImGui::Checkbox(
fmt::format("{0}##letter_{1}", sLetterSenders[i], i).c_str(), &had)) {
setLetterGetFlag(i, had);
}
}
ImGui::Spacing();
if (ImGui::Button("Receive All##letters_all")) {
for (int i = 0; i < LETTER_COUNT; i++) setLetterGetFlag(i, true);
}
ImGui::SameLine();
if (ImGui::Button("Clear All##letters_clear")) {
for (int i = 0; i < LETTER_COUNT; i++) setLetterGetFlag(i, false);
}
ImGui::TreePop();
}
if (ImGui::TreeNode("Fishing Log")) {
dSv_fishing_info_c& fish = dComIfGs_getSaveData()->getPlayer().getFishingInfo();
if (ImGui::BeginTable("FishTable", 3,
ImGuiTableFlags_SizingFixedFit | ImGuiTableFlags_RowBg)) {
ImGui::TableSetupColumn("Species");
ImGui::TableSetupColumn("Caught");
ImGui::TableSetupColumn("Biggest (cm)");
ImGui::TableHeadersRow();
for (int i = 0; i < FISH_COUNT; i++) {
u8 idx = sFishSpecies[i].index;
ImGui::TableNextRow();
ImGui::TableSetColumnIndex(0);
ImGui::TextUnformatted(sFishSpecies[i].name);
ImGui::TableSetColumnIndex(1);
int count = dComIfGs_getFishNum(idx);
ImGui::SetNextItemWidth(100.0f);
if (ImGui::InputInt(fmt::format("##fish_c_{}", i).c_str(), &count, 1, 10)) {
if (count < 0) count = 0;
if (count > 999) count = 999;
fish.mFishCount[idx] = (u16)count;
}
ImGui::TableSetColumnIndex(2);
int size = dComIfGs_getFishSize(idx);
ImGui::SetNextItemWidth(100.0f);
if (ImGui::InputInt(fmt::format("##fish_s_{}", i).c_str(), &size, 1, 10)) {
if (size < 0) size = 0;
if (size > 255) size = 255;
dComIfGs_setFishSize(idx, (u8)size);
}
}
ImGui::EndTable();
}
ImGui::TreePop();
}
ImGui::TreePop();
}
}
void drawFlagList(const char* id, BE(u32)& flags) {
u32 tempFlagField = flags;
@@ -845,5 +1351,19 @@ namespace dusk {
if (ImGui::BeginCombo("Target Type", "Hold")) {
ImGui::EndCombo();
}
static const char* kSoundModeNames[] = { "Mono", "Stereo", "Surround" };
const char* current = (config.mSoundMode < 3) ? kSoundModeNames[config.mSoundMode]
: "Unknown";
if (ImGui::BeginCombo("Sound", current)) {
for (u8 i = 0; i < 3; i++) {
bool selected = (config.mSoundMode == i);
if (ImGui::Selectable(kSoundModeNames[i], selected)) {
config.mSoundMode = i;
}
if (selected) ImGui::SetItemDefaultFocus();
}
ImGui::EndCombo();
}
}
}
+1
View File
@@ -15,6 +15,7 @@ namespace dusk {
void drawPlayerStatusTab();
void drawLocationTab();
void drawInventoryTab();
void drawCollectionTab();
void drawFlagsTab();
void drawConfigTab();
+10 -4
View File
@@ -40,7 +40,9 @@ UserSettings g_userSettings = {
// Graphics
.enableBloom {"game.enableBloom", true},
.useWaterProjectionOffset {"game.useWaterProjectionOffset", false},
.enableWaterRefraction {"game.enableWaterRefraction", true},
.enableFrameInterpolation = {"game.enableFrameInterpolation", false},
.shadowResolutionMultiplier {"game.shadowResolutionMultiplier", 1},
// Audio
.noLowHpSound {"game.noLowHpSound", false},
@@ -56,14 +58,15 @@ UserSettings g_userSettings = {
.restoreWiiGlitches {"game.restoreWiiGlitches", false},
// Controls
.enableTurboKeybind {"game.enableTurboKeybind", true},
.enableTurboKeybind {"game.enableTurboKeybind", false},
},
.backend = {
.isoPath {"backend.isoPath", ""},
.graphicsBackend {"backend.graphicsBackend", "auto"},
.skipPreLaunchUI {"backend.skipPreLaunchUI", false},
.showPipelineCompilation{"backend.showPipelineCompilation", false}
.showPipelineCompilation {"backend.showPipelineCompilation", false},
.wasPresetChosen {"backend.wasPresetChosen", false}
}
};
@@ -100,7 +103,8 @@ void registerSettings() {
Register(g_userSettings.game.enableMirrorMode);
Register(g_userSettings.game.invertCameraXAxis);
Register(g_userSettings.game.enableBloom);
Register(g_userSettings.game.useWaterProjectionOffset);
Register(g_userSettings.game.enableWaterRefraction);
Register(g_userSettings.game.shadowResolutionMultiplier);
Register(g_userSettings.game.enableFastIronBoots);
Register(g_userSettings.game.canTransformAnywhere);
Register(g_userSettings.game.freeMagicArmor);
@@ -110,11 +114,13 @@ void registerSettings() {
Register(g_userSettings.game.midnasLamentNonStop);
Register(g_userSettings.game.enableTurboKeybind);
Register(g_userSettings.game.fastSpinner);
Register(g_userSettings.game.enableFrameInterpolation);
Register(g_userSettings.backend.isoPath);
Register(g_userSettings.backend.graphicsBackend);
Register(g_userSettings.backend.skipPreLaunchUI);
Register(g_userSettings.backend.showPipelineCompilation);
Register(g_userSettings.backend.wasPresetChosen);
}
// Transient settings
+17 -1
View File
@@ -14,6 +14,7 @@
#include "d/actor/d_a_midna.h"
#include "d/d_model.h"
#include "d/d_tresure.h"
#include "dusk/frame_interpolation.h"
#include "dusk/logging.h"
#include "f_op/f_op_camera_mng.h"
#include "f_op/f_op_draw_tag.h"
@@ -722,6 +723,17 @@ void fapGm_After() {
fopCamM_Management();
}
#ifdef TARGET_PC
static void fapGm_Before() {
dusk::frame_interp::begin_record();
}
static void fapGm_AfterRecord() {
dusk::frame_interp::end_record();
fapGm_After();
}
#endif
void fapGm_Execute() {
ZoneScoped;
static u32 sExecCount = 0;
@@ -752,7 +764,11 @@ void fapGm_Execute() {
}
#endif
fpcM_Management(NULL, fapGm_After);
#ifdef TARGET_PC
fpcM_Management(fapGm_Before, fapGm_AfterRecord);
#else
fpcM_ManagementFunc(NULL, fapGm_After);
#endif
cCt_Counter(0);
}
+7
View File
@@ -8,6 +8,7 @@
#include "f_pc/f_pc_leaf.h"
#include "f_pc/f_pc_node.h"
#include "f_pc/f_pc_pause.h"
#include "dusk/frame_interpolation.h"
#include <cstdio>
#include "dusk/logging.h"
@@ -25,7 +26,13 @@ int fpcDw_Execute(base_process_class* i_proc) {
}
fpcLy_SetCurrentLayer(i_proc->layer_tag.layer);
#ifdef TARGET_PC
dusk::frame_interp::open_child(i_proc, 0);
#endif
ret = draw_func(i_proc);
#ifdef TARGET_PC
dusk::frame_interp::close_child();
#endif
fpcLy_SetCurrentLayer(save_layer);
return ret;
}
+8 -3
View File
@@ -20,7 +20,6 @@
#include "f_pc/f_pc_pause.h"
#include "f_pc/f_pc_priority.h"
#include "m_Do/m_Do_controller_pad.h"
#include <cstdio>
#include "tracy/Tracy.hpp"
@@ -64,7 +63,14 @@ void fpcM_Management(fpcM_ManagementFunc i_preExecuteFn, fpcM_ManagementFunc i_p
l_dvdError = false;
}
cAPIGph_Painter();
#ifdef TARGET_PC
// Frame interpolation: call moved to m_Do_main
if (!dusk::getSettings().game.enableFrameInterpolation) {
#endif
cAPIGph_Painter();
#ifdef TARGET_PC
}
#endif
if (!dPa_control_c::isStatus(1)) {
fpcDt_Handler();
@@ -153,4 +159,3 @@ void* fpcM_JudgeInLayer(fpc_ProcID i_layerID, fpcCtIt_JudgeFunc i_judgeFunc, voi
return NULL;
}
+74 -5
View File
@@ -2398,7 +2398,12 @@ void mDoExt_3DlineMat0_c::draw() {
var_r28++;
}
field_0x16 ^= (u8)1;
#if TARGET_PC
if (!dusk::getSettings().game.enableFrameInterpolation)
#endif
{
field_0x16 ^= (u8)1;
}
}
void mDoExt_3DlineMat0_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3,
@@ -2648,6 +2653,9 @@ int mDoExt_3DlineMat1_c::init(u16 param_0, u16 param_1, ResTIMG* param_2, int pa
field_0x4 = 0;
mIsDrawn = 0;
#if TARGET_PC
mInterpLineKind = 0;
#endif
GXInitTexObj(&mTextureObject, (void*)((intptr_t)param_2 + param_2->imageOffset), param_2->width,
param_2->height, (GXTexFmt)param_2->format, (GXTexWrapMode)param_2->wrapS,
@@ -2720,11 +2728,19 @@ void mDoExt_3DlineMat1_c::draw() {
lines++;
}
GXSetTexCoordScaleManually(GX_TEXCOORD0, 0, 0, 0);
mIsDrawn ^= (u8)1;
#if TARGET_PC
if (!dusk::getSettings().game.enableFrameInterpolation)
#endif
{
mIsDrawn ^= (u8)1;
}
}
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3,
dKy_tevstr_c* param_4) {
#if TARGET_PC
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3, dKy_tevstr_c* param_4, const cXyz* presentationEye) {
#else
void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16 param_3, dKy_tevstr_c* param_4) {
#endif
mColor = param_2;
this->mpTevStr = param_4;
if (param_0 < 0) {
@@ -2734,6 +2750,13 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
} else {
field_0x34 = param_0;
}
#if TARGET_PC
mInterpLineKind = 1;
mInterpLineF = param_1;
mInterpLineU16 = param_3;
#endif
view_class* sp_3c = dComIfGd_getView();
mDoExt_3Dline_c* sp_38 = mpLines;
f32 local_f27 = param_3 != 0 ? param_1 / param_3 : 0.0f;
@@ -2787,7 +2810,12 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
local_f31 += local_f30 * 0.02f * (8.0f / param_1);
}
#if TARGET_PC
const cXyz& lineEye = (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation) ? *presentationEye : sp_3c->lookat.eye;
sp_13c = *local_r27 - lineEye;
#else
sp_13c = *local_r27 - sp_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
@@ -2822,7 +2850,11 @@ void mDoExt_3DlineMat1_c::update(int param_0, f32 param_1, GXColor& param_2, u16
local_f31 += local_f30 * 0.02f * (8.0f / param_1);
}
#if TARGET_PC
sp_13c = local_r27[0] - lineEye;
#else
sp_13c = local_r27[0] - sp_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
@@ -2894,7 +2926,11 @@ void mDoExt_3DlineMat2_c::setMaterial() {
GXLoadNrmMtxImm(cMtx_getIdentity(), 0);
}
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4) {
#if TARGET_PC
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4, const cXyz* presentationEye) {
#else
void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* param_4
#endif
mColor = param_2;
this->mpTevStr = param_4;
if (param_0 < 0) {
@@ -2904,6 +2940,11 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
} else {
field_0x34 = param_0;
}
#if TARGET_PC
mInterpLineKind = 2;
#endif
view_class* stack_3c = dComIfGd_getView();
mDoExt_3Dline_c* sp_38 = mpLines;
f32 local_f30;
@@ -2929,6 +2970,12 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
for (s32 sp_14 = 0; sp_14 < mNumLines; sp_14++) {
local_r27 = sp_38[0].field_0x0;
size_p = sp_38->field_0x4;
#if TARGET_PC
if (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation && size_p == NULL) {
sp_38 += 1;
continue;
}
#endif
JUT_ASSERT(5875, size_p != NULL);
sp_24 = sp_38->field_0x8[mIsDrawn];
sp_28 = sp_24;
@@ -2942,7 +2989,12 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
sp_130 = local_r27[1] - local_r27[0];
local_f30 = sp_130.abs();
local_f31 += local_f30 * 0.1f;
#if TARGET_PC
const cXyz& lineEye = (presentationEye != nullptr && dusk::getSettings().game.enableFrameInterpolation) ? *presentationEye : stack_3c->lookat.eye;
sp_13c = local_r27[0] - lineEye;
#else
sp_13c = local_r27[0] - stack_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
local_r30->x = sp_130.x * 64.0f;
@@ -2964,7 +3016,11 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
sp_130 = local_r27[1] - local_r27[0];
local_f30 = sp_130.abs();
local_f31 += local_f30 * 0.1f;
#if TARGET_PC
sp_13c = local_r27[0] - lineEye;
#else
sp_13c = local_r27[0] - stack_3c->lookat.eye;
#endif
sp_130 = sp_130.outprod(sp_13c);
sp_130.normalizeZP();
local_r30 += 2;
@@ -3008,6 +3064,19 @@ void mDoExt_3DlineMat1_c::update(int param_0, GXColor& param_2, dKy_tevstr_c* pa
}
}
#if TARGET_PC
void mDoExt_3DlineMat1_c::refreshGeometryForPresentationEye(const cXyz& eye) {
if (!dusk::getSettings().game.enableFrameInterpolation) {
return;
}
if (mInterpLineKind == 1) {
update(field_0x34, mInterpLineF, mColor, mInterpLineU16, mpTevStr, &eye);
} else if (mInterpLineKind == 2) {
update(field_0x34, mColor, mpTevStr, &eye);
}
}
#endif
void mDoExt_3DlineMatSortPacket::setMat(mDoExt_3DlineMat_c* i_3DlineMat) {
if (mp3DlineMat == NULL) {
dComIfGd_getListPacket()->entryImm(this, 0);

Some files were not shown because too many files have changed in this diff Show More