mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-07-08 20:24:47 -04:00
Merge branch 'main' of https://github.com/TwilitRealm/dusk into randomizer
This commit is contained in:
@@ -22,7 +22,8 @@
|
||||
build-essential curl git ninja-build clang lld zlib1g-dev libcurl4-openssl-dev \
|
||||
libglu1-mesa-dev libdbus-1-dev libvulkan-dev libxi-dev libxrandr-dev libasound2-dev libpulse-dev \
|
||||
libudev-dev libpng-dev libncurses5-dev cmake libx11-xcb-dev python3 python-is-python3 \
|
||||
libclang-dev libfreetype-dev libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev
|
||||
libclang-dev libfreetype-dev libxinerama-dev libxcursor-dev python3-markupsafe libgtk-3-dev \
|
||||
libxss-dev libxtst-dev
|
||||
```
|
||||
* Arch Linux packages
|
||||
```
|
||||
|
||||
@@ -119,8 +119,7 @@ public:
|
||||
|
||||
public:
|
||||
/* 0x56C */ dBgS_ObjAcch mAcch;
|
||||
/* 0x744 */ char field_0x744;
|
||||
/* 0x745 */ u8 field_0x745[0x74c - 0x745];
|
||||
/* 0x744 */ char field_0x744[8];
|
||||
/* 0x74C */ request_of_phase_process_class mPhase;
|
||||
/* 0x754 */ mDoExt_McaMorfSO* mpModelMorf;
|
||||
/* 0x758 */ Z2Creature mSound;
|
||||
|
||||
@@ -12,6 +12,27 @@ public:
|
||||
/* 0xf4 */ s16 angle;
|
||||
};
|
||||
|
||||
class daObjCatDoor_Attr_c {
|
||||
public:
|
||||
/* 0x0 */ s16 speed;
|
||||
/* 0x2 */ s16 decay_rate;
|
||||
};
|
||||
|
||||
class daObjCatDoor_Hio_c : public mDoHIO_entry_c {
|
||||
public:
|
||||
daObjCatDoor_Hio_c();
|
||||
~daObjCatDoor_Hio_c();
|
||||
|
||||
void genMessage(JORMContext*);
|
||||
|
||||
void ct();
|
||||
void dt();
|
||||
void default_set();
|
||||
|
||||
/* 0x8 */ int field_0x8;
|
||||
/* 0xC */ daObjCatDoor_Attr_c m_attr;
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup actors-objects
|
||||
* @class daObjCatDoor_c
|
||||
@@ -24,7 +45,7 @@ class daObjCatDoor_c : public fopAc_ac_c {
|
||||
public:
|
||||
inline ~daObjCatDoor_c();
|
||||
|
||||
const s16* attr() const;
|
||||
const daObjCatDoor_Attr_c* attr() const;
|
||||
void initBaseMtx();
|
||||
void setBaseMtx();
|
||||
void calcOpen();
|
||||
@@ -45,7 +66,7 @@ public:
|
||||
}
|
||||
|
||||
void setDoorOpen() {
|
||||
mRotSpeed = attr()[1];
|
||||
mRotSpeed = attr()->decay_rate;
|
||||
dBgW* bgw1 = &mDoor1.bgw;
|
||||
if (bgw1->ChkUsed()) {
|
||||
dComIfG_Bgsp().Release(bgw1);
|
||||
@@ -67,7 +88,7 @@ private:
|
||||
/* 0x790 */ s16 mRotSpeed;
|
||||
|
||||
public:
|
||||
static u32 const M_attr;
|
||||
static const daObjCatDoor_Attr_c M_attr;
|
||||
};
|
||||
|
||||
#endif /* D_A_OBJ_CATDOOR_H */
|
||||
|
||||
@@ -64,7 +64,8 @@ struct UserSettings {
|
||||
|
||||
// Input
|
||||
ConfigVar<bool> enableGyroAim;
|
||||
ConfigVar<float> gyroAimSensitivity;
|
||||
ConfigVar<float> gyroAimSensitivityX;
|
||||
ConfigVar<float> gyroAimSensitivityY;
|
||||
ConfigVar<bool> gyroAimInvertPitch;
|
||||
ConfigVar<bool> gyroAimInvertYaw;
|
||||
|
||||
|
||||
@@ -31,6 +31,9 @@ public:
|
||||
void create();
|
||||
void remove();
|
||||
void draw();
|
||||
#if TARGET_PC
|
||||
void draw2();
|
||||
#endif
|
||||
|
||||
u8 getEnable() { return mEnable; }
|
||||
void setEnable(u8 i_enable) { mEnable = i_enable; }
|
||||
|
||||
@@ -10,35 +10,38 @@
|
||||
|
||||
static const char* l_arcName = "CatDoor";
|
||||
|
||||
u32 const daObjCatDoor_c::M_attr = 0x001E0578;
|
||||
const daObjCatDoor_Attr_c daObjCatDoor_c::M_attr = {
|
||||
30,
|
||||
1400,
|
||||
};
|
||||
|
||||
daObjCatDoor_c::~daObjCatDoor_c() {
|
||||
if (mDoor1.bgw.ChkUsed()) {
|
||||
dComIfG_Bgsp().Release(&mDoor1.bgw);
|
||||
}
|
||||
|
||||
if (mDoor2.bgw.ChkUsed()) {
|
||||
dComIfG_Bgsp().Release(&mDoor2.bgw);
|
||||
}
|
||||
|
||||
dComIfG_resDelete(&mPhaseReq, l_arcName);
|
||||
}
|
||||
|
||||
int daObjCatDoor_c::createHeap() {
|
||||
J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(l_arcName, 4);
|
||||
JUT_ASSERT(174, modelData != NULL);
|
||||
|
||||
ASSERT(modelData != NULL);
|
||||
mDoor1.pmodel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084);
|
||||
mDoor2.pmodel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084);
|
||||
if (mDoor1.pmodel == NULL || mDoor2.pmodel == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cBgD_t* cbgd = (cBgD_t*)dComIfG_getObjectRes(l_arcName, 7);
|
||||
if (mDoor1.bgw.Set(cbgd, 1, &mDoor1.mtx)) {
|
||||
if (mDoor1.bgw.Set((cBgD_t*)dComIfG_getObjectRes(l_arcName, 7), 1, &mDoor1.mtx)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
cBgD_t* cbgd2 = (cBgD_t*)dComIfG_getObjectRes(l_arcName, 7);
|
||||
if (mDoor2.bgw.Set(cbgd2, 1, &mDoor2.mtx)) {
|
||||
if (mDoor2.bgw.Set((cBgD_t*)dComIfG_getObjectRes(l_arcName, 7), 1, &mDoor2.mtx)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -48,9 +51,9 @@ int daObjCatDoor_c::createHeap() {
|
||||
int daObjCatDoor_c::draw() {
|
||||
g_env_light.settingTevStruct(0x10, ¤t.pos, &tevStr);
|
||||
|
||||
fopAc_ac_c* p1 = static_cast<fopAc_ac_c*>(this);
|
||||
g_env_light.setLightTevColorType_MAJI(mDoor1.pmodel, &p1->tevStr);
|
||||
g_env_light.setLightTevColorType_MAJI(mDoor2.pmodel, &p1->tevStr);
|
||||
fopAc_ac_c* actor = (fopAc_ac_c*)this;
|
||||
g_env_light.setLightTevColorType_MAJI(mDoor1.pmodel, &actor->tevStr);
|
||||
g_env_light.setLightTevColorType_MAJI(mDoor2.pmodel, &actor->tevStr);
|
||||
|
||||
dComIfGd_setListBG();
|
||||
mDoExt_modelUpdateDL(mDoor1.pmodel);
|
||||
@@ -60,22 +63,22 @@ int daObjCatDoor_c::draw() {
|
||||
}
|
||||
|
||||
int daObjCatDoor_c::execute() {
|
||||
if (dComIfGs_isSwitch(fopAcM_GetParam(this) & 0xFF, fopAcM_GetHomeRoomNo(this)) ||
|
||||
mRotSpeed == 0)
|
||||
{
|
||||
if (fopAcM_isSwitch(this, getSwitchNo()) || mRotSpeed == 0) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
calcOpen();
|
||||
setBaseMtx();
|
||||
return 1;
|
||||
}
|
||||
|
||||
const s16* daObjCatDoor_c::attr() const {
|
||||
return (const s16*)&daObjCatDoor_c::M_attr;
|
||||
const daObjCatDoor_Attr_c* daObjCatDoor_c::attr() const {
|
||||
return &daObjCatDoor_c::M_attr;
|
||||
}
|
||||
|
||||
static int createSolidHeap(fopAc_ac_c* i_this) {
|
||||
return static_cast<daObjCatDoor_c*>(i_this)->createHeap();
|
||||
static int createSolidHeap(fopAc_ac_c* actor) {
|
||||
daObjCatDoor_c* i_this = (daObjCatDoor_c*)actor;
|
||||
return i_this->createHeap();
|
||||
}
|
||||
|
||||
int daObjCatDoor_c::create() {
|
||||
@@ -84,7 +87,7 @@ int daObjCatDoor_c::create() {
|
||||
int phase_state = dComIfG_resLoad(&mPhaseReq, l_arcName);
|
||||
if (phase_state == cPhs_COMPLEATE_e) {
|
||||
if (!fopAcM_entrySolidHeap(this, createSolidHeap, 0x2520)) {
|
||||
phase_state = cPhs_ERROR_e;
|
||||
return cPhs_ERROR_e;
|
||||
} else {
|
||||
create_init();
|
||||
}
|
||||
@@ -93,7 +96,8 @@ int daObjCatDoor_c::create() {
|
||||
}
|
||||
|
||||
void daObjCatDoor_c::create_init() {
|
||||
ASSERT(getSwitchNo() != 0xff);
|
||||
JUT_ASSERT(295, getSwitchNo() != 0xff);
|
||||
|
||||
fopAcM_setCullSizeBox(this, -200.0f, 0.0f, -20.0f, 200.0f, 260.0f, 100.0f);
|
||||
if (fopAcM_isSwitch(this, getSwitchNo())) {
|
||||
mDoor1.angle = 0x8800;
|
||||
@@ -106,37 +110,40 @@ void daObjCatDoor_c::create_init() {
|
||||
mDoor2.bgw.SetRoomId(fopAcM_GetRoomNo(this));
|
||||
dComIfG_Bgsp().Regist(&mDoor2.bgw, this);
|
||||
}
|
||||
|
||||
initBaseMtx();
|
||||
}
|
||||
|
||||
void daObjCatDoor_c::initBaseMtx() {
|
||||
cullMtx = mMtx;
|
||||
fopAcM_SetMtx(this, mMtx);
|
||||
mDoMtx_stack_c::transS(current.pos);
|
||||
mDoMtx_YrotM(mDoMtx_stack_c::get(), shape_angle.y);
|
||||
mDoMtx_copy(mDoMtx_stack_c::get(), mMtx);
|
||||
mDoMtx_stack_c::YrotM(shape_angle.y);
|
||||
cMtx_copy(mDoMtx_stack_c::get(), mMtx);
|
||||
setBaseMtx();
|
||||
}
|
||||
|
||||
void daObjCatDoor_c::setBaseMtx() {
|
||||
mDoMtx_stack_c::transS(current.pos);
|
||||
mDoMtx_YrotM(mDoMtx_stack_c::get(), shape_angle.y);
|
||||
mDoMtx_stack_c::YrotM(shape_angle.y);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
daObjCatDoor_Door_c* door = i == 0 ? &mDoor1 : &mDoor2;
|
||||
f32 xOff = i == 0 ? -97.0f : 97.0f;
|
||||
s16 rot = i == 0 ? door->angle : s16(door->angle + 0x8000);
|
||||
|
||||
mDoMtx_stack_c::push();
|
||||
mDoMtx_stack_c::transM(xOff, 0.0, 0.0);
|
||||
mDoMtx_YrotM(mDoMtx_stack_c::get(), (s16)rot);
|
||||
mDoMtx_copy(mDoMtx_stack_c::get(), door->pmodel->mBaseTransformMtx);
|
||||
mDoMtx_copy(mDoMtx_stack_c::get(), door->mtx);
|
||||
mDoMtx_stack_c::YrotM((s16)rot);
|
||||
door->pmodel->setBaseTRMtx(mDoMtx_stack_c::get());
|
||||
cMtx_copy(mDoMtx_stack_c::get(), door->mtx);
|
||||
door->bgw.Move();
|
||||
mDoMtx_stack_c::pop();
|
||||
}
|
||||
}
|
||||
|
||||
void daObjCatDoor_c::calcOpen() {
|
||||
s16 prev = mRotSpeed;
|
||||
int res = cLib_chaseS(&mRotSpeed, 0, *attr());
|
||||
s16 prev = (s16)mRotSpeed;
|
||||
int res = cLib_chaseS(&mRotSpeed, 0, attr()->speed);
|
||||
for (int i = 0; i < 2; i++) {
|
||||
daObjCatDoor_Door_c* door = i == 0 ? &mDoor1 : &mDoor2;
|
||||
if (i == 0) {
|
||||
@@ -159,20 +166,20 @@ static int daObjCatDoor_Execute(daObjCatDoor_c* i_this) {
|
||||
return static_cast<daObjCatDoor_c*>(i_this)->execute();
|
||||
}
|
||||
|
||||
static BOOL daObjCatDoor_IsDelete(daObjCatDoor_c* i_this) {
|
||||
return TRUE;
|
||||
static int daObjCatDoor_IsDelete(daObjCatDoor_c* i_this) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int daObjCatDoor_Delete(daObjCatDoor_c* i_this) {
|
||||
fopAcM_GetID(i_this);
|
||||
fpc_ProcID id = fopAcM_GetID(i_this);
|
||||
i_this->~daObjCatDoor_c();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int daObjCatDoor_Create(fopAc_ac_c* i_this) {
|
||||
fopAcM_GetID(i_this);
|
||||
daObjCatDoor_c* a_this = static_cast<daObjCatDoor_c*>(i_this);
|
||||
return a_this->create();
|
||||
static int daObjCatDoor_Create(fopAc_ac_c* actor) {
|
||||
daObjCatDoor_c* i_this = (daObjCatDoor_c*)actor;
|
||||
fpc_ProcID id = fopAcM_GetID(actor);
|
||||
return i_this->create();
|
||||
}
|
||||
|
||||
static actor_method_class l_daObjCatDoor_Method = {
|
||||
|
||||
@@ -539,7 +539,7 @@ const char* daObj_GrA_c::getResName() {
|
||||
|
||||
u8 daObj_GrA_c::getMode() {
|
||||
u32 uVar1 = fopAcM_GetParam(this) >> 28 & 3;
|
||||
strcpy(&field_0x744, "Obj_grA");
|
||||
strcpy(field_0x744, "Obj_grA");
|
||||
|
||||
switch (uVar1) {
|
||||
case 1:
|
||||
|
||||
@@ -61,9 +61,8 @@ void read(float dt, bool context_active) {
|
||||
float yaw_rate = apply_deadband(s_smooth_gy);
|
||||
float pitch_rate = apply_deadband(s_smooth_gx);
|
||||
|
||||
const float sens = dusk::getSettings().game.gyroAimSensitivity;
|
||||
s_pending_yaw_rad += yaw_rate * dt * sens;
|
||||
s_pending_pitch_rad += pitch_rate * dt * sens;
|
||||
s_pending_yaw_rad += yaw_rate * dt * dusk::getSettings().game.gyroAimSensitivityX;
|
||||
s_pending_pitch_rad += pitch_rate * dt * dusk::getSettings().game.gyroAimSensitivityY;
|
||||
}
|
||||
|
||||
void consumeAimDeltas(float& out_yaw_rad, float& out_pitch_rad) {
|
||||
|
||||
@@ -60,7 +60,7 @@ inline ImFont* CreateFont(float size, const std::string& fontPath, std::string_v
|
||||
|
||||
void ImGuiEngine_Initialize(float scale) {
|
||||
// Round font scale to nearest integer
|
||||
scale = std::ceilf(scale);
|
||||
scale = std::ceil(scale);
|
||||
|
||||
ImGui::GetCurrentContext();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
||||
@@ -119,7 +119,8 @@ namespace dusk {
|
||||
"Slingshot, Gale Boomerang, Hero's Bow, Clawshot(s), Ball and Chain, and Dominion Rod.");
|
||||
}
|
||||
|
||||
config::ImGuiSliderFloat("Gyro Sensitivity", getSettings().game.gyroAimSensitivity, 0.25f, 4.0f, "%.2f");
|
||||
config::ImGuiSliderFloat("Gyro Pitch Sensitivity", getSettings().game.gyroAimSensitivityY, 0.25f, 4.0f, "%.2f");
|
||||
config::ImGuiSliderFloat("Gyro Yaw Sensitivity", getSettings().game.gyroAimSensitivityX, 0.25f, 4.0f, "%.2f");
|
||||
config::ImGuiCheckbox("Invert Gyro Pitch", getSettings().game.gyroAimInvertPitch);
|
||||
config::ImGuiCheckbox("Invert Gyro Yaw", getSettings().game.gyroAimInvertYaw);
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ UserSettings g_userSettings = {
|
||||
|
||||
// Input
|
||||
.enableGyroAim {"game.enableGyroAim", false},
|
||||
.gyroAimSensitivity {"game.gyroAimSensitivity", 1.0f},
|
||||
.gyroAimSensitivityX {"game.gyroAimSensitivityX", 1.0f},
|
||||
.gyroAimSensitivityY {"game.gyroAimSensitivityY", 1.0f},
|
||||
.gyroAimInvertPitch {"game.gyroAimInvertPitch", false},
|
||||
.gyroAimInvertYaw {"game.gyroAimInvertYaw", false},
|
||||
|
||||
@@ -126,7 +127,8 @@ void registerSettings() {
|
||||
Register(g_userSettings.game.fastSpinner);
|
||||
Register(g_userSettings.game.enableFrameInterpolation);
|
||||
Register(g_userSettings.game.enableGyroAim);
|
||||
Register(g_userSettings.game.gyroAimSensitivity);
|
||||
Register(g_userSettings.game.gyroAimSensitivityX);
|
||||
Register(g_userSettings.game.gyroAimSensitivityY);
|
||||
Register(g_userSettings.game.gyroAimInvertPitch);
|
||||
Register(g_userSettings.game.gyroAimInvertYaw);
|
||||
|
||||
|
||||
+262
-15
@@ -1232,12 +1232,12 @@ void mDoGph_drawFilterQuad(s8 param_0, s8 param_1) {
|
||||
void mDoGph_gInf_c::bloom_c::create() {
|
||||
if (m_buffer == NULL) {
|
||||
#ifdef TARGET_PC
|
||||
u32 size = 0x20; // No need to allocate memory for texture
|
||||
m_buffer = (void*)1;
|
||||
#else
|
||||
u32 size = GXGetTexBufferSize(FB_WIDTH / 2, FB_HEIGHT / 2, GX_TF_RGBA8, GX_FALSE, 0);
|
||||
#endif
|
||||
m_buffer = mDoExt_getArchiveHeap()->alloc(size, -32);
|
||||
JUT_ASSERT(1621, m_buffer != NULL);
|
||||
#endif
|
||||
|
||||
mEnable = false;
|
||||
mMode = 0;
|
||||
@@ -1249,20 +1249,267 @@ void mDoGph_gInf_c::bloom_c::create() {
|
||||
}
|
||||
|
||||
void mDoGph_gInf_c::bloom_c::remove() {
|
||||
#if !TARGET_PC
|
||||
if (m_buffer != NULL) {
|
||||
mDoExt_getArchiveHeap()->free(m_buffer);
|
||||
m_buffer = NULL;
|
||||
}
|
||||
#endif
|
||||
mMonoColor.a = 0;
|
||||
}
|
||||
|
||||
void mDoGph_gInf_c::bloom_c::draw() {
|
||||
#if TARGET_PC
|
||||
static void CopyToTexObj(GXTexObj* pDst, uintptr_t texID, int dstWidth, int dstHeight, GXTexFmt dstFmt = GX_TF_RGBA8) {
|
||||
GXSetTexCopyDst(dstWidth, dstHeight, dstFmt, FALSE);
|
||||
GXCopyTex((void*)texID, false);
|
||||
GXInitTexObj(pDst, (void*)texID, dstWidth, dstHeight, dstFmt, GX_CLAMP, GX_CLAMP, GX_FALSE);
|
||||
GXInitTexObjLOD(pDst, GX_LINEAR, GX_LINEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
|
||||
}
|
||||
|
||||
void mDoGph_gInf_c::bloom_c::draw2() {
|
||||
ZoneScoped;
|
||||
// if (!dusk::getSettings().game.enableBloom) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
bool enabled = mEnable;
|
||||
if (mMonoColor.a == 0 && !enabled)
|
||||
return;
|
||||
|
||||
f32 width = mDoGph_gInf_c::getWidth();
|
||||
f32 height = mDoGph_gInf_c::getHeight();
|
||||
|
||||
GXLoadTexObj(getFrameBufferTexObj(), GX_TEXMAP0);
|
||||
GXSetNumChans(0);
|
||||
GXSetNumTexGens(1);
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_GREEN);
|
||||
GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
|
||||
GXSetZCompLoc(1);
|
||||
GXSetZMode(0, GX_ALWAYS, 0);
|
||||
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0);
|
||||
GXSetFog(GX_FOG_NONE, 0.0f, 0.0f, 0.0f, 0.0f, g_clearColor);
|
||||
GXSetFogRangeAdj(0, 0, 0);
|
||||
GXSetCullMode(GX_CULL_NONE);
|
||||
GXSetDither(1);
|
||||
Mtx44 ortho;
|
||||
C_MTXOrtho(ortho, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 10.0f);
|
||||
GXLoadPosMtxImm(cMtx_getIdentity(), 0);
|
||||
GXSetProjection(ortho, GX_ORTHOGRAPHIC);
|
||||
GXSetCurrentMtx(0);
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
||||
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_S8, 0);
|
||||
|
||||
// Set up viewports for our pyramid.
|
||||
enum { MaxDivNum = 10 };
|
||||
enum {
|
||||
Pass0,
|
||||
FinalPass,
|
||||
BlurPass0, BlurPassN = BlurPass0 + MaxDivNum,
|
||||
MaxTexNum,
|
||||
};
|
||||
scissor_class divPorts[MaxDivNum];
|
||||
divPorts[0] = {0.0f, 0.0f, 1.0f, 1.0f}; // full-size texture
|
||||
divPorts[1] = {0.0f, 0.0f, 0.5f, 0.5f}; // bloom texture (wide enough, half-tall)
|
||||
divPorts[2] = {0.5f, 0.0f, 0.25f, 0.25f};
|
||||
for (int i = 3; i < ARRAY_SIZE(divPorts); i++) {
|
||||
auto& port = divPorts[i];
|
||||
auto const& prev = divPorts[i - 1];
|
||||
port.x_orig = prev.x_orig;
|
||||
port.y_orig = prev.y_orig + prev.height;
|
||||
port.width = prev.width * 0.5f;
|
||||
port.height = prev.height * 0.5f;
|
||||
}
|
||||
|
||||
auto divCopySrc = [&](int divNo) {
|
||||
auto const& port = divPorts[divNo];
|
||||
GXSetTexCopySrc(port.x_orig * width, port.y_orig * height, port.width * width, port.height * height);
|
||||
};
|
||||
|
||||
TGXTexObj tmpTex[MaxTexNum];
|
||||
auto divCopyTex = [&](uintptr_t texNo, int divNo) -> GXTexObj * {
|
||||
auto const& port = divPorts[divNo];
|
||||
CopyToTexObj(&tmpTex[texNo], texNo, port.width * width, port.height * height);
|
||||
return &tmpTex[texNo];
|
||||
};
|
||||
|
||||
auto divQuad = [&](int divNo) {
|
||||
auto const& port = divPorts[divNo];
|
||||
f32 x0 = port.x_orig, y0 = port.y_orig;
|
||||
f32 x1 = x0 + port.width, y1 = y0 + port.height;
|
||||
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
|
||||
GXPosition3f32(x0, y0, -5);
|
||||
GXTexCoord2s8(0, 0);
|
||||
GXPosition3f32(x1, y0, -5);
|
||||
GXTexCoord2s8(1, 0);
|
||||
GXPosition3f32(x1, y1, -5);
|
||||
GXTexCoord2s8(1, 1);
|
||||
GXPosition3f32(x0, y1, -5);
|
||||
GXTexCoord2s8(0, 1);
|
||||
GXEnd();
|
||||
};
|
||||
|
||||
if (mMonoColor.a != 0) {
|
||||
GXSetNumTevStages(1);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C2, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A2);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP1, GX_TEV_SWAP1);
|
||||
GXSetTevColor(GX_TEVREG2, mMonoColor);
|
||||
GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_OR);
|
||||
divQuad(0);
|
||||
}
|
||||
|
||||
if (enabled) {
|
||||
GXCreateFrameBuffer(width * 0.75f, height * 0.5f);
|
||||
GXSetViewport(0.0f, 0.0f, width, height, 0.1f, 1.0f); // use oversized viewport to make the math easier
|
||||
|
||||
GXSetNumTevStages(3);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_TEXC, GX_CC_TEXA, GX_CC_HALF, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP1, GX_TEV_SWAP1);
|
||||
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_TEXC, GX_CC_CPREV, GX_CC_HALF, GX_CC_C0);
|
||||
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP3, GX_TEV_SWAP3);
|
||||
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_OR);
|
||||
GXColorS10 tevColor0 = {(s16)-mPoint, (s16)-mPoint, (s16)-mPoint, 0x40};
|
||||
GXSetTevColorS10(GX_TEVREG0, tevColor0);
|
||||
GXPixModeSync();
|
||||
|
||||
// Create thresholded 1/2 image.
|
||||
divQuad(1);
|
||||
|
||||
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
||||
GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
||||
|
||||
// Downsample and filter from 1/2 EFB into 1/4.
|
||||
divCopySrc(1);
|
||||
GXTexObj* texPass0 = divCopyTex(Pass0, 2);
|
||||
GXLoadTexObj(texPass0, GX_TEXMAP0);
|
||||
|
||||
f32 blurScale = mBlureSize * ((448.0f / getHeight()) / 6400.0f);
|
||||
|
||||
// Setup blur filter TEV.
|
||||
GXSetNumTexGens(8);
|
||||
|
||||
auto SetupBlurMtx = [](float scale) {
|
||||
u32 texMtxID = GX_TEXMTX0;
|
||||
int angle = 0;
|
||||
for (int texCoord = (int)GX_TEXCOORD0; texCoord < (int)GX_MAX_TEXCOORD; texCoord++) {
|
||||
GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, texMtxID);
|
||||
mDoMtx_stack_c::transS((scale * cM_scos(angle)) * getInvScale(),
|
||||
scale * cM_ssin(angle), 0.0f);
|
||||
GXLoadTexMtxImm(mDoMtx_stack_c::get(), texMtxID, GX_MTX2x4);
|
||||
texMtxID += 3;
|
||||
angle += 0x2000;
|
||||
}
|
||||
};
|
||||
|
||||
GXSetNumTevStages(8);
|
||||
for (int stage = 0; stage < 8; stage++) {
|
||||
GXTevStageID tevStage = (GXTevStageID)stage;
|
||||
GXSetTevOrder(tevStage, (GXTexCoordID)stage, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(tevStage, GX_CC_ZERO, GX_CC_TEXC, GX_CC_A1, stage == 0 ? GX_CC_ZERO : GX_CC_CPREV);
|
||||
GXSetTevColorOp(tevStage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(tevStage, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0);
|
||||
GXSetTevAlphaOp(tevStage, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
}
|
||||
|
||||
// Successively downsample and apply blurs.
|
||||
int divStart = 2;
|
||||
int divNum = 6;
|
||||
|
||||
// Distribute the brightness through each pass.
|
||||
int totalNumPasses = (divNum - divStart) * 2; // down, up
|
||||
float brightnessF32 = (mBlureRatio / 255.0f);
|
||||
float brightnessPerPass = 255.0f * powf(brightnessF32, 1.0f / totalNumPasses);
|
||||
GXSetTevColorS10(GX_TEVREG1, {0, 0, 0, s16(brightnessPerPass / 8)});
|
||||
|
||||
for (int i = divStart; i < divNum; i++) {
|
||||
float blurStrength = 1.0f + (i - divStart) * 5.0f;
|
||||
SetupBlurMtx(blurScale * blurStrength);
|
||||
|
||||
// Apply blur filter.
|
||||
divQuad(i);
|
||||
|
||||
// Copy to next layer.
|
||||
divCopySrc(i);
|
||||
|
||||
// Set up for the next pass down.
|
||||
GXTexObj * blurTex = divCopyTex(BlurPass0 + i, i + 1);
|
||||
GXLoadTexObj(blurTex, GX_TEXMAP0);
|
||||
}
|
||||
|
||||
// All the way down at the bottom. Instead of blurring the bottom layer by itself, we blur when going up to the next layer.
|
||||
// The remaining upscales are all just normal alpha blending.
|
||||
divQuad(divNum);
|
||||
|
||||
// Now successively alpha blend back up, don't blur anymore.
|
||||
GXSetNumTevStages(1);
|
||||
GXSetTevColorS10(GX_TEVREG1, {0, 0, 0, s16(brightnessPerPass)});
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
GXSetBlendMode(GX_BM_BLEND, GX_BL_ONE, GX_BL_ONE, GX_LO_OR);
|
||||
for (int i = divNum; i > divStart; i--) {
|
||||
divCopySrc(i);
|
||||
GXTexObj* upTex = divCopyTex(BlurPass0 + i, i);
|
||||
GXLoadTexObj(upTex, GX_TEXMAP0);
|
||||
divQuad(i - 1);
|
||||
}
|
||||
|
||||
// Now that we've upsampled and filtered our final bloom, copy 1/4 buffer.
|
||||
divCopySrc(2);
|
||||
GXTexObj* texFinal = divCopyTex(FinalPass, 2);
|
||||
GXLoadTexObj(texFinal, GX_TEXMAP0);
|
||||
|
||||
GXRestoreFrameBuffer();
|
||||
GXSetViewport(0.0f, 0.0f, width, height, 0.0f, 1.0f);
|
||||
|
||||
// Now blend our bloom into the real FB.
|
||||
GXSetTevColor(GX_TEVREG0, mBlendColor);
|
||||
GXSetNumTevStages(1);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_A0);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetBlendMode(GX_BM_BLEND, mMode == 1 ? GX_BL_INVDSTCLR : GX_BL_ONE, GX_BL_SRCALPHA,
|
||||
GX_LO_OR);
|
||||
GXPixModeSync();
|
||||
GXInvalidateTexAll();
|
||||
divQuad(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void mDoGph_gInf_c::bloom_c::draw() {
|
||||
ZoneScoped;
|
||||
if (!dusk::getSettings().game.enableBloom) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool s_bloom2 = false;
|
||||
if (s_bloom2) {
|
||||
draw2();
|
||||
return;
|
||||
}
|
||||
|
||||
bool enabled = mEnable && m_buffer != NULL;
|
||||
if (mMonoColor.a != 0 || enabled) {
|
||||
#if TARGET_PC
|
||||
@@ -1376,24 +1623,24 @@ void mDoGph_gInf_c::bloom_c::draw() {
|
||||
GXLoadTexObj(&tmp_tex1, GX_TEXMAP0);
|
||||
|
||||
GXSetNumTexGens(8);
|
||||
u32 iVar11 = 0x1e;
|
||||
int sVar10 = 0;
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c);
|
||||
u32 texMtxID = GX_TEXMTX0;
|
||||
int angle = 0;
|
||||
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
|
||||
for (int texCoord = (int)GX_TEXCOORD1; texCoord < (int)GX_MAX_TEXCOORD; texCoord++) {
|
||||
GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, iVar11);
|
||||
|
||||
GXSetTexCoordGen((GXTexCoordID)texCoord, GX_TG_MTX2x4, GX_TG_TEX0, texMtxID);
|
||||
|
||||
#if TARGET_PC
|
||||
f32 dVar15 = mBlureSize * ((448.0f / getHeight()) / 6400.0f);
|
||||
f32 dVar15 = mBlureSize * ((448.0f / height) / 6400.0f);
|
||||
#else
|
||||
f32 dVar15 = mBlureSize * (1.0f / 6400.0f);
|
||||
#endif
|
||||
|
||||
mDoMtx_stack_c::transS((dVar15 * cM_scos(sVar10)) * getInvScale(),
|
||||
dVar15 * cM_ssin(sVar10), 0.0f);
|
||||
GXLoadTexMtxImm(mDoMtx_stack_c::get(), iVar11, GX_MTX2x4);
|
||||
mDoMtx_stack_c::transS((dVar15 * cM_scos(angle)) * getInvScale(),
|
||||
dVar15 * cM_ssin(angle), 0.0f);
|
||||
GXLoadTexMtxImm(mDoMtx_stack_c::get(), texMtxID, GX_MTX2x4);
|
||||
|
||||
iVar11 += 3;
|
||||
sVar10 += 0x2492;
|
||||
texMtxID += 3;
|
||||
angle += 0x2492;
|
||||
}
|
||||
GXSetNumTevStages(8);
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
|
||||
Reference in New Issue
Block a user