This commit is contained in:
robojumper
2025-03-21 10:56:05 +01:00
parent e2c2ec6c2d
commit 641c56b24a
4 changed files with 98 additions and 82 deletions
+7 -7
View File
@@ -26732,7 +26732,7 @@ CopyFromAnother__Q23EGG6ScreenFRCQ23EGG6Screen = .text:0x804B24C0; // type:funct
Reset__Q23EGG6ScreenFffffQ33EGG7Frustum10CanvasMode = .text:0x804B2590; // type:function size:0x38
SetParent__Q23EGG6ScreenFPCQ23EGG6Screen = .text:0x804B25D0; // type:function size:0x30
SetUnkFlag8__Q23EGG6ScreenFv = .text:0x804B2600; // type:function size:0x24
OnDirectEfb__Q23EGG6ScreenFv = .text:0x804B2630; // type:function size:0x4D8
OnDirectEfb__Q23EGG6ScreenCFv = .text:0x804B2630; // type:function size:0x4D8
GetDataEfb__Q23EGG6ScreenCFv = .text:0x804B2B10; // type:function size:0x5C
IsChangeEfb__Q23EGG6ScreenCFv = .text:0x804B2B70; // type:function size:0x2C
CalcMatrixForDrawQuad__Q23EGG6ScreenCFPQ34nw4r4math5MTX34ffff = .text:0x804B2BA0; // type:function size:0xA8
@@ -26740,7 +26740,7 @@ FillBufferGX__Q23EGG6ScreenCFUl8_GXColorUl = .text:0x804B2C50; // type:function
GetGlobalPos__Q23EGG6ScreenCFPfPf = .text:0x804B2D40; // type:function size:0xB0
SetTVMode__Q23EGG6ScreenFQ33EGG6Screen6TVMode = .text:0x804B2DF0; // type:function size:0xB0
SetTVModeDefault__Q23EGG6ScreenFv = .text:0x804B2EA0; // type:function size:0x34
FUN_804b2ee0 = .text:0x804B2EE0; // type:function size:0x14C
fn_804B2EE0__Q23EGG6ScreenCFPfPfff = .text:0x804B2EE0; // type:function size:0x14C
__sinit_\eggScreen_cpp = .text:0x804B3030; // type:function size:0x84 scope:local
__ct__Q23EGG16ScreenEffectBaseFv = .text:0x804B30C0; // type:function size:0x18
__sinit_\eggScreenEffectBase_cpp = .text:0x804B30E0; // type:function size:0xC scope:local
@@ -41174,11 +41174,11 @@ lbl_80576861 = .sbss:0x80576861; // type:object size:0x7 data:byte
lbl_80576868 = .sbss:0x80576868; // type:object size:0x8 data:float
sTVMode__Q23EGG6Screen = .sbss:0x80576870; // type:object size:0x4 data:4byte
spRoot__Q23EGG6Screen = .sbss:0x80576874; // type:object size:0x4 data:4byte
lbl_80576878 = .sbss:0x80576878; // type:object size:0x4 data:4byte
lbl_8057687C = .sbss:0x8057687C; // type:object size:0x4 data:4byte
lbl_80576880 = .sbss:0x80576880; // type:object size:0x4 data:float
lbl_80576888 = .sbss:0x80576888; // type:object size:0x4 data:float
lbl_80576890 = .sbss:0x80576890; // type:object size:0x8 data:byte
sChangeTVModeFunc__Q23EGG6Screen = .sbss:0x80576878; // type:object size:0x4 data:4byte
spChangeTVModeFuncInfo__Q23EGG6Screen = .sbss:0x8057687C; // type:object size:0x4 data:4byte
sCanvasScale__Q23EGG6Screen = .sbss:0x80576880; // type:object size:0x8 data:float
sCanvasOffset__Q23EGG6Screen = .sbss:0x80576888; // type:object size:0x8 data:float
@GUARD@Initialize__Q23EGG6ScreenFPCUsPCUsPQ23EGG6Screen@defaultRoot = .sbss:0x80576890; // type:object size:0x1 data:byte
lbl_80576898 = .sbss:0x80576898; // type:object size:0x8 data:4byte
s_widthEfb__Q23EGG7StateGX = .sbss:0x805768A0; // type:object size:0x2 data:2byte
s_heightEfb__Q23EGG7StateGX = .sbss:0x805768A2; // type:object size:0x2 data:2byte
+6 -4
View File
@@ -8,6 +8,10 @@ class Frustum {
public:
enum Flag {
FLAG_DIRTY = (1 << 0),
FLAG_0x02 = (1 << 1),
FLAG_0x04 = (1 << 2),
FLAG_0x08 = (1 << 3),
FLAG_0x20 = (1 << 5),
FLAG_0x40 = (1 << 6),
};
@@ -102,10 +106,8 @@ public:
}
void SetSize(const nw4r::math::VEC2 &size) {
// ???
mSize.x = size.x;
SetDirty(true);
mSize.y = size.y;
SetSizeX(size.x);
SetSizeY(size.y);
}
void SetNearZ(f32 nearZ) {
+27 -4
View File
@@ -3,12 +3,18 @@
#include "egg/egg_types.h"
#include "egg/gfx/eggFrustum.h"
#include "egg/gfx/eggStateGX.h"
namespace EGG {
class Screen : public Frustum {
public:
enum TVMode { TV_MODE_4_3, TV_MODE_16_9, TV_MODE_UNK_3, TV_MODE_MAX };
enum TVMode {
TV_MODE_4_3,
TV_MODE_16_9,
TV_MODE_UNK_3,
TV_MODE_MAX
};
typedef void (*ChangeTVModeFunc)(void *);
@@ -69,6 +75,14 @@ public:
return sTVMode;
}
TVMode GetComputedTVMode() const {
if ((mFlags & FLAG_0x20) == 0) {
return (mFlags & FLAG_0x08) == 0 ? sTVMode : TV_MODE_UNK_3;
} else {
return TV_MODE_4_3;
}
}
Screen();
Screen(f32, f32, f32, f32, const Screen *, CanvasMode);
Screen(const Screen &);
@@ -85,18 +99,27 @@ public:
void CopyFromAnother(const Screen &other);
void Reset(f32, f32, f32, f32, CanvasMode);
void GetPosSizeInEfb() const;
void OnDirectEfb() const;
const DataEfb &GetDataEfb() const;
bool IsChangeEfb() const;
void CalcMatrixForDrawQuad(nw4r::math::MTX34 *, f32, f32, f32, f32) const;
void FillBufferGX(u32, GXColor, u32) const;
void GetGlobalPos(f32 *, f32 *) const;
void fn_804B2EE0(f32 *, f32 *, f32, f32) const;
f32 ScaleByX(f32 val) const {
return val * StateGX::s_widthEfb / GetSizeXMax(GetComputedTVMode());
}
f32 ScaleByY(f32 val) const {
return val * StateGX::s_heightEfb / GetSizeYMax(GetComputedTVMode());
}
private:
const Screen *mParent; // at 0x3C
nw4r::math::VEC2 mPosition; // at 0x40
nw4r::math::VEC2 field_0x44;
nw4r::math::VEC2 field_0x48;
nw4r::math::VEC2 field_0x48; // at 0x48
nw4r::math::VEC2 field_0x50; // at 0x50
mutable DataEfb mDataEfb; // at 0x58
static TVMode sTVMode;
+58 -67
View File
@@ -5,7 +5,6 @@
#include "egg/gfx/eggStateGX.h"
#include "rvl/SC/scapi.h"
// ported from OGWS, though this class has evolved a fair bit
using namespace nw4r;
@@ -37,22 +36,21 @@ math::VEC2 Screen::sCanvasScale(1.0f, 1.0f);
math::VEC2 Screen::sCanvasOffset(0.0f, 0.0f);
void Screen::Initialize(const u16 *maxX, const u16 *maxY, Screen *userRoot) {
sTVModeInfo[TV_MODE_4_3].width = maxX[0];
sTVModeInfo[TV_MODE_4_3].height = maxY[0];
sTVModeInfo[TV_MODE_4_3].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_4_3].width;
sTVModeInfo[TV_MODE_4_3].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_4_3].height;
sTVModeInfo[TV_MODE_16_9].width = maxX[1];
sTVModeInfo[TV_MODE_16_9].height = maxY[1];
sTVModeInfo[TV_MODE_16_9].ratios.x = (f32)StateGX::s_widthEfb / (f32)sTVModeInfo[TV_MODE_16_9].width;
sTVModeInfo[TV_MODE_16_9].ratios.y = (f32)StateGX::s_heightEfb / (f32)sTVModeInfo[TV_MODE_16_9].height;
sTVModeInfo[TV_MODE_UNK_3].width = StateGX::s_widthEfb;
sTVModeInfo[TV_MODE_UNK_3].height = StateGX::s_heightEfb;
sTVModeInfo[TV_MODE_UNK_3].ratios.x = 1.0f;
sTVModeInfo[TV_MODE_UNK_3].ratios.y = 1.0f;
@@ -77,10 +75,10 @@ Screen::Screen()
mParent = nullptr;
mPosition.x = 0.0f;
mPosition.y = 0.0f;
field_0x44.x = 0.0f;
field_0x44.y = 0.0f;
field_0x48.x = 0.0f;
field_0x48.y = 0.0f;
field_0x50.x = 0.0f;
field_0x50.y = 0.0f;
SetParent(nullptr);
}
@@ -89,10 +87,10 @@ Screen::Screen(f32 x, f32 y, f32 w, f32 h, const Screen *userRoot, CanvasMode ca
mParent = nullptr;
mPosition.x = x;
mPosition.y = y;
field_0x44.x = 0.0f;
field_0x44.y = 0.0f;
field_0x48.x = 0.0f;
field_0x48.y = 0.0f;
field_0x50.x = 0.0f;
field_0x50.y = 0.0f;
SetParent(userRoot);
}
@@ -100,8 +98,8 @@ Screen::Screen(const Screen &other)
: Frustum(other),
mPosition(other.mPosition),
mDataEfb(other.mDataEfb),
field_0x44(other.field_0x44),
field_0x48(other.field_0x48) {
field_0x48(other.field_0x48),
field_0x50(other.field_0x50) {
SetParent(other.mParent);
}
@@ -162,8 +160,8 @@ void Screen::CopyFromAnother(const Screen &other) {
Frustum::CopyFromAnother(other);
mPosition = other.mPosition;
field_0x44 = other.field_0x44;
field_0x48 = other.field_0x48;
field_0x50 = other.field_0x50;
mDataEfb = other.mDataEfb;
mParent = other.mParent;
}
@@ -187,77 +185,64 @@ void Screen::SetParent(const Screen *parent) {
}
void Screen::SetUnkFlag8() {
if ((mFlags & 0x8) == 0) {
if ((mFlags & FLAG_0x08) == 0) {
SetDirty(true);
}
mFlags |= 0x8;
mFlags |= FLAG_0x08;
}
void Screen::GetPosSizeInEfb() const {
// TODO
const TVMode tvMode = (!(mFlags & 0x20)) ? sTVMode : TV_MODE_4_3;
const TVModeInfo &tvRatio = sTVModeInfo[tvMode];
void Screen::OnDirectEfb() const {
f32 &x1 = mDataEfb.vp.x1;
f32 &y1 = mDataEfb.vp.y1;
if (mParent == nullptr) {
x1 = mPosition.x * sCanvasScale.x;
y1 = mPosition.y * sCanvasScale.y;
} else {
mParent->fn_804B2EE0(&x1, &y1, mPosition.x, mPosition.y);
}
f32 *px = &mDataEfb.vp.x1;
f32 *py = &mDataEfb.vp.y1;
GetGlobalPos(px, py);
// TODO: Make this work without temporaries?
*px = sCanvasScale.x * *px;
*py = sCanvasScale.y * *py;
*px *= tvRatio.ratios.x;
*py *= tvRatio.ratios.y;
mDataEfb.sc_x = x1 + ScaleByX(field_0x48.x);
mDataEfb.sc_y = y1 + ScaleByY(field_0x48.y);
mDataEfb.sc_oy = 0;
mDataEfb.sc_ox = 0;
const f32 x = *px;
if (x < 0.0f) {
*px = 0.0f;
const s32 lx = static_cast<s32>(-x);
mDataEfb.sc_ox = lx - (lx & 0x1);
if (x1 < 0.0f) {
int x1_i = x1;
int x1_in = -x1_i;
mDataEfb.sc_ox = (x1_in - (x1_in & 1));
x1 = x1 - x1_i;
}
if (y1 < 0.0f) {
int y1_i = y1;
int y1_in = -y1_i;
mDataEfb.sc_oy = (y1_in - (y1_in & 1));
y1 = y1 - y1_i;
}
const f32 y = *py;
if (y < 0.0f) {
*py = 0.0f;
const s32 ly = static_cast<s32>(-y);
mDataEfb.sc_oy = ly - (ly & 0x1);
if ((mFlags & FLAG_0x02) != 0) {
x1 = x1 - (((int)x1) & 1);
y1 = y1 - (((int)y1) & 1);
}
if (mFlags & 0x2) {
*px -= static_cast<s32>(*px) & 0x1;
*py -= static_cast<s32>(*py) & 0x1;
mDataEfb.vp.x2 = ScaleByX(mSize.x);
mDataEfb.vp.y2 = ScaleByY(mSize.y);
if ((mFlags & FLAG_0x04) != 0) {
mDataEfb.vp.x2 -= ((int)mDataEfb.vp.x2 & 3);
mDataEfb.vp.y2 -= ((int)mDataEfb.vp.y2 & 3);
}
mDataEfb.vp.x2 = (int)mDataEfb.vp.x2;
mDataEfb.vp.y2 = (int)mDataEfb.vp.y2;
*px = static_cast<s32>(*px);
*py = static_cast<s32>(*py);
mDataEfb.vp.x2 = mSize.x;
mDataEfb.vp.y2 = mSize.y;
if (!(mFlags & 0x8)) {
mDataEfb.vp.x2 = mSize.x * tvRatio.ratios.x;
mDataEfb.vp.y2 = mSize.y * tvRatio.ratios.y;
}
if (mFlags & 0x4) {
mDataEfb.vp.x2 -= static_cast<s32>(mDataEfb.vp.x2) & 0x3;
mDataEfb.vp.y2 -= static_cast<s32>(mDataEfb.vp.y2) & 0x3;
}
mDataEfb.vp.x2 = (mDataEfb.vp.x2 >= 0.0f) ? mDataEfb.vp.x2 : 0.0f;
mDataEfb.vp.y2 = (mDataEfb.vp.y2 >= 0.0f) ? mDataEfb.vp.y2 : 0.0f;
mDataEfb.vp.x2 = static_cast<s32>(mDataEfb.vp.x2);
mDataEfb.vp.y2 = static_cast<s32>(mDataEfb.vp.y2);
mDataEfb.sc_w = mDataEfb.vp.x2 - ScaleByX(field_0x48.x + field_0x50.x);
mDataEfb.sc_h = mDataEfb.vp.y2 - ScaleByY(field_0x48.y + field_0x50.y);
}
const Screen::DataEfb &Screen::GetDataEfb() const {
if (IsChangeEfb()) {
GetPosSizeInEfb();
OnDirectEfb();
mDataEfb.vp.z1 = 0.0f;
mDataEfb.vp.z2 = 1.0f;
SetDirty(false);
@@ -303,7 +288,7 @@ void Screen::FillBufferGX(u32 flags, GXColor color, u32 r6) const {
clone.SetProjectionGX();
clone.CalcMatrixForDrawQuad(&drawMtx, 0.0f, 0.0f, mSize.x, mSize.y);
// Ugh
DrawGX::ClearEfb(drawMtx, (flags & 1) != 0, (flags & 2) != 0, (flags & 4) != 0, color, true);
DrawGX::ClearEfb(drawMtx, (flags & 1), (flags & 2), (flags & 4), color, true);
}
}
@@ -318,7 +303,6 @@ void Screen::GetGlobalPos(f32 *ox, f32 *oy) const {
*ox += px;
*oy += py;
} else {
*ox = mPosition.x;
*oy = mPosition.y;
}
@@ -340,4 +324,11 @@ void Screen::SetTVModeDefault() {
SetTVMode(SCGetAspectRatio() == SC_ASPECT_STD ? TV_MODE_4_3 : TV_MODE_16_9);
}
void Screen::fn_804B2EE0(f32 *ox, f32 *oy, f32 a, f32 b) const {
GetGlobalPos(ox, oy);
ConvertToCanvasLU(a, b, &a, &b);
*ox = ScaleByX((*ox + a));
*oy = ScaleByY((*oy + b));
}
} // namespace EGG