summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/d/lyt/d2d.cpp6
-rw-r--r--src/egg/gfx/eggFrustum.cpp239
-rw-r--r--src/egg/gfx/eggPostEffectBase.cpp2
-rw-r--r--src/egg/gfx/eggScreen.cpp342
-rw-r--r--src/m/m2d.cpp6
5 files changed, 586 insertions, 9 deletions
diff --git a/src/d/lyt/d2d.cpp b/src/d/lyt/d2d.cpp
index c69bada8..d33c741e 100644
--- a/src/d/lyt/d2d.cpp
+++ b/src/d/lyt/d2d.cpp
@@ -164,7 +164,7 @@ nw4r::lyt::AnimTransform *Layout_c::CreateAnimTransform(const void *animResBuf,
Multi_c::Multi_c() : Base_c(0x80), mLayout(), mDrawInfo(), mpResAcc(nullptr), mFlags(0) {
mDrawInfo.SetLocationAdjustScale(nw4r::math::VEC2(
- (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1) / (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2),
+ (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_4_3) / (f32)EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9),
1.0f
));
mDrawInfo.SetLocationAdjust(true);
@@ -207,8 +207,8 @@ void Multi_c::draw() {
f32 far = 500.0f;
EGG::Screen s;
bool needsAdjust = NeedsScreenAdjustment();
- f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2);
- f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1);
+ f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_UNK_3);
+ f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9);
f32 left = needsAdjust ? f1 * r.left / f2 : r.left;
f32 right = needsAdjust ? f1 * r.right / f2 : r.right;
diff --git a/src/egg/gfx/eggFrustum.cpp b/src/egg/gfx/eggFrustum.cpp
index c060e519..d7c9e039 100644
--- a/src/egg/gfx/eggFrustum.cpp
+++ b/src/egg/gfx/eggFrustum.cpp
@@ -1,3 +1,240 @@
#include "egg/gfx/eggFrustum.h"
-namespace EGG {} // namespace EGG
+#include "egg/gfx/eggGXUtility.h"
+#include "egg/gfx/eggStateGX.h"
+#include "nw4r/math/math_arithmetic.h"
+
+
+void eggFrustum_float_ordering() {
+ 1.0f;
+}
+
+namespace EGG {
+using namespace nw4r;
+
+Frustum::Frustum(ProjectionType proj, const math::VEC2 &size, f32 nearZ, f32 farZ, CanvasMode canvas)
+ : mProjType(proj),
+ mCanvasMode(canvas),
+ mSize(size),
+ mFovY(45.0f),
+ mTanFovY(2.4142134f),
+ mNearZ(nearZ),
+ mFarZ(farZ),
+ mOffset(0.0f, 0.0f),
+ mScale(1.0f, 1.0f, 1.0f),
+ mFlags(FLAG_DIRTY) {}
+
+Frustum::Frustum(const Frustum &other) {
+ CopyFromAnother(other);
+}
+
+void Frustum::ResetOrthographic(f32 t, f32 b, f32 l, f32 r, f32 near, f32 far) {
+ 0.5f;
+ 2.0f;
+
+ mProjType = PROJ_ORTHO;
+ mScale.z = 1.0f;
+ mScale.y = 1.0f;
+ mScale.x = 1.0f;
+ mSize.x = r - l;
+ if (mSize.x < 0.0f) {
+ mScale.x = -1.0f;
+ mSize.x *= -1.0f;
+ }
+
+ mSize.y = t - b;
+ if (mSize.y >= 0.0f) {
+ SetCanvasMode(CANVASMODE_0);
+ mOffset = math::VEC2(0.5f * (r + l), 0.5f * (t + b));
+ } else {
+ SetCanvasMode(CANVASMODE_1);
+ mOffset = math::VEC2(0.0f, t);
+ mSize.y *= -1.0f;
+ }
+ mNearZ = near;
+ mFarZ = far;
+ SetFlag(1);
+}
+
+void Frustum::CopyFromAnother(const Frustum &other) {
+ mProjType = other.mProjType;
+ mCanvasMode = other.mCanvasMode;
+ mSize = other.mSize;
+ mFovY = other.mFovY;
+ mTanFovY = other.mTanFovY;
+ mNearZ = other.mNearZ;
+ mFarZ = other.mFarZ;
+ mOffset = other.mOffset;
+ mScale = other.mScale;
+ mFlags = other.mFlags;
+}
+
+void Frustum::SetFovy(f32 fov) {
+ if (mFovY != fov) {
+ mFovY = fov;
+ f32 sin, cos;
+
+ math::SinCosDeg(&sin, &cos, (f32)(f64)fov / 2.0f);
+ mTanFovY = cos / sin;
+ }
+}
+
+void Frustum::ConvertToCanvasLU(f32 ix, f32 iy, f32 *ox, f32 *oy) const {
+ if (mCanvasMode == CANVASMODE_1) {
+ *ox = ix;
+ *oy = iy;
+ } else if (mCanvasMode == CANVASMODE_0) {
+ *ox = ix + (mSize.x * 0.5f);
+ *oy = -(iy - (mSize.y * 0.5f));
+ }
+}
+
+f32 Frustum::GetScreenSizeToViewSize(f32 p1, f32 p2) const {
+ if (mProjType != PROJ_PERSP) {
+ return p1;
+ }
+ return p1 * math::FAbs(p2) / (mSize.y * 0.5f * mTanFovY);
+}
+
+void Frustum::SetProjectionGX() const {
+ if (mProjType == PROJ_ORTHO) {
+ SetProjectionOrthographicGX_();
+ } else {
+ SetProjectionPerspectiveGX_();
+ }
+}
+
+void Frustum::CopyToG3D(g3d::Camera cam) const {
+ if (mProjType == PROJ_ORTHO) {
+ CopyToG3D_Orthographic_(cam);
+ } else {
+ CopyToG3D_Perspective_(cam);
+ }
+}
+
+void Frustum::SetGlobalScaleOffset(f32 sx, f32 sy, f32 ox, f32 oy) {
+ sGlobalScale.x = sx;
+ sGlobalScale.y = sy;
+ sGlobalOffset.x = ox;
+ sGlobalOffset.y = oy;
+}
+
+void Frustum::GetGlobalScaleOffset(f32 *sx, f32 *sy, f32 *ox, f32 *oy) {
+ *sx = sGlobalScale.x;
+ *sy = sGlobalScale.y;
+ *ox = sGlobalOffset.x;
+ *oy = sGlobalOffset.y;
+}
+
+void Frustum::SetProjectionPerspectiveGX_() const {
+ f32 params[7];
+ GetPerspectiveParam_(params);
+ StateGX::GXSetProjectionv_(params);
+}
+
+void Frustum::SetProjectionOrthographicGX_() const {
+ f32 v[8];
+ GetOrthographicParam_(v);
+ StateGX::GXSetProjectionv_(v);
+}
+
+void Frustum::CopyToG3D_Perspective_(g3d::Camera cam) const {
+ math::MTX44 mtx;
+ f32 ratio = mSize.x / mSize.y;
+ cam.SetPerspective(mFovY, ratio, mNearZ, mFarZ);
+ CalcMtxPerspective_(&mtx);
+ cam.SetProjectionMtxDirectly(&mtx);
+}
+
+void Frustum::CopyToG3D_Orthographic_(g3d::Camera cam) const {
+ f32 t, b, l, r;
+ GetOrthographicParam_(&t, &b, &l, &r);
+ cam.SetOrtho(t, b, l, r, mNearZ, mFarZ);
+}
+
+void Frustum::CalcMtxPerspective_(math::MTX44 *out) const {
+ f32 params[7];
+ GetPerspectiveParam_(params);
+
+ out->m[0][3] = 0.0f;
+ out->m[0][1] = 0.0f;
+ out->m[0][0] = params[1];
+ out->m[0][2] = params[2];
+
+ out->m[1][3] = 0.0f;
+ out->m[1][0] = 0.0f;
+ out->m[1][1] = params[3];
+ out->m[1][2] = params[4];
+
+ out->m[2][1] = 0.0f;
+ out->m[2][0] = 0.0f;
+ out->m[2][2] = params[5];
+ out->m[2][3] = params[6];
+
+ out->m[3][3] = 0.0f;
+ out->m[3][1] = 0.0f;
+ out->m[3][0] = 0.0f;
+ out->m[3][2] = -1.0f;
+}
+
+void Frustum::GetPerspectiveParam_(f32 *p) const {
+ // NONMATCHING - FPR regswaps
+ f32 f1 = 1.0f / (mSize.x * 0.5f);
+ f32 f2 = 1.0f / (mSize.y * 0.5f);
+ p[0] = 0.0f;
+ p[1] = (mTanFovY / (mScale.x * (mSize.x / mSize.y)));
+ p[2] = mOffset.x * f1;
+ p[3] = mTanFovY / mScale.y;
+ p[4] = mOffset.y * f2;
+
+ f32 z = -mNearZ / (mFarZ - mNearZ);
+ p[5] = z;
+ p[6] = mFarZ * z;
+
+ GXUtility::setScaleOffsetPerspective(p, sGlobalScale.x, sGlobalScale.y, sGlobalOffset.x * f1, sGlobalOffset.y * f2);
+}
+
+void Frustum::GetOrthographicParam_(f32 *p) const {
+ f32 t, b, l, r;
+ GetOrthographicParam_(&t, &b, &l, &r);
+
+ f32 invHor = 1.0f / (r - l);
+ f32 invVert = 1.0f / (t - b);
+ f32 invZ = 1.0f / (mFarZ - mNearZ);
+
+ p[0] = 1.0f;
+ p[1] = invHor * 2.0f;
+ p[3] = invVert * 2.0f;
+
+ p[2] = invHor * -(r + l);
+ p[4] = invVert * -(t + b);
+ p[5] = -1.0f * invZ;
+ p[6] = -mFarZ * invZ;
+}
+
+void Frustum::GetOrthographicParam_(f32 *pT, f32 *pB, f32 *pL, f32 *pR) const {
+ f32 adjOffsetX = mOffset.x + sGlobalOffset.x;
+ f32 adjOffsetY = mOffset.y + sGlobalOffset.y;
+
+ if (mCanvasMode == CANVASMODE_0) {
+ const math::VEC2 adjScale(mScale.x * sGlobalScale.x, mScale.y * sGlobalScale.y);
+
+ *pT = adjScale.y * ((0.5f * mSize.y) + adjOffsetY);
+ *pB = adjScale.y * ((-0.5f * mSize.y) + adjOffsetY);
+ *pL = adjScale.x * ((-0.5f * mSize.x) + adjOffsetX);
+ *pR = adjScale.x * ((0.5f * mSize.x) + adjOffsetX);
+ } else if (mCanvasMode == CANVASMODE_1) {
+ f32 adjScaleX = -(sGlobalScale.x - 1.0f) * mSize.x / 2.0f;
+ f32 adjScaleY = -(sGlobalScale.y - 1.0f) * mSize.y / 2.0f;
+
+ *pT = adjScaleY + -sGlobalScale.y * adjOffsetY;
+ *pB = adjScaleY + -sGlobalScale.y * (adjOffsetY + mSize.y * -1.0f * mScale.y);
+ *pL = adjScaleX + sGlobalScale.x * adjOffsetX;
+ *pR = adjScaleX + sGlobalScale.x * (adjOffsetX + mSize.x * mScale.x);
+ }
+}
+
+math::VEC2 Frustum::sGlobalScale(1.0f, 1.0f);
+math::VEC2 Frustum::sGlobalOffset(0.0f, 0.0f);
+
+} // namespace EGG
diff --git a/src/egg/gfx/eggPostEffectBase.cpp b/src/egg/gfx/eggPostEffectBase.cpp
index 9ecead4a..bf824907 100644
--- a/src/egg/gfx/eggPostEffectBase.cpp
+++ b/src/egg/gfx/eggPostEffectBase.cpp
@@ -153,7 +153,7 @@ void PostEffectBase::setProjection(const Screen &screen) {
Screen screenCpy(screen);
screenCpy.SetFlag(Screen::FLAG_0x40);
- screenCpy.SetCanvasMode(Screen::CANVAS_1);
+ screenCpy.SetCanvasMode(Screen::CANVASMODE_1);
screenCpy.SetProjectionType(Screen::PROJ_ORTHO);
screenCpy.SetNearFar(0.0f, 1.0f);
screenCpy.SetScale(sScale);
diff --git a/src/egg/gfx/eggScreen.cpp b/src/egg/gfx/eggScreen.cpp
index 66b80c4e..af26dc25 100644
--- a/src/egg/gfx/eggScreen.cpp
+++ b/src/egg/gfx/eggScreen.cpp
@@ -1,3 +1,343 @@
#include "egg/gfx/eggScreen.h"
-namespace EGG {} // namespace EGG
+#include "common.h"
+#include "egg/gfx/eggDrawGX.h"
+#include "egg/gfx/eggStateGX.h"
+#include "rvl/SC/scapi.h"
+
+
+// ported from OGWS, though this class has evolved a fair bit
+
+using namespace nw4r;
+
+namespace EGG {
+
+Screen::TVMode Screen::sTVMode;
+Screen::TVModeInfo Screen::sTVModeInfo[TV_MODE_MAX] = {
+ {
+ 608, 456,
+ nw4r::math::VEC2(1.0526316f, 1.0f),
+ },
+ {
+ 812, 456,
+ nw4r::math::VEC2(0.7881773, 1.0f),
+ },
+ {
+ 640, 456,
+ nw4r::math::VEC2(1.0f, 1.0f),
+ }
+};
+
+Screen *Screen::spRoot = nullptr;
+
+Screen::ChangeTVModeFunc Screen::sChangeTVModeFunc = nullptr;
+void *Screen::spChangeTVModeFuncInfo = nullptr;
+
+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;
+
+ static Screen defaultRoot;
+ defaultRoot.SetProjectionType(PROJ_ORTHO);
+ defaultRoot.SetCanvasMode(CANVASMODE_1);
+ defaultRoot.SetNearZ(0.0f);
+ defaultRoot.SetFarZ(1.0f);
+ defaultRoot.SetSize(math::VEC2(sTVModeInfo[sTVMode].width, sTVModeInfo[sTVMode].height));
+
+ userRoot = (userRoot == nullptr) ? &defaultRoot : userRoot;
+ spRoot = userRoot;
+ userRoot->mParent = nullptr;
+ SetTVMode(sTVMode);
+}
+
+Screen::Screen()
+ : Frustum(
+ PROJ_PERSP, math::VEC2(sTVModeInfo[sTVMode].width, sTVModeInfo[sTVMode].height), 10.0f, 100000.0f,
+ CANVASMODE_1
+ ) {
+ 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;
+ SetParent(nullptr);
+}
+
+Screen::Screen(f32 x, f32 y, f32 w, f32 h, const Screen *userRoot, CanvasMode canvasMode)
+ : Frustum(PROJ_PERSP, math::VEC2(w, h), 10.0f, 100000.0f, canvasMode) {
+ 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;
+ SetParent(userRoot);
+}
+
+Screen::Screen(const Screen &other)
+ : Frustum(other),
+ mPosition(other.mPosition),
+ mDataEfb(other.mDataEfb),
+ field_0x44(other.field_0x44),
+ field_0x48(other.field_0x48) {
+ SetParent(other.mParent);
+}
+
+void Screen::SetProjectionGX() const {
+ if (!(mFlags & 0x40)) {
+ f32 sx, sy, ox, oy;
+ GetGlobalScaleOffset(&sx, &sy, &ox, &oy);
+
+ SetGlobalScaleOffset(sCanvasScale.x, sCanvasScale.y, sCanvasOffset.x, sCanvasOffset.y);
+ Frustum::SetProjectionGX();
+
+ SetGlobalScaleOffset(sx, sy, ox, oy);
+ } else {
+ Frustum::SetProjectionGX();
+ }
+
+ const DataEfb &efb = GetDataEfb();
+
+ StateGX::GXSetViewport_(efb.vp.x1, efb.vp.y1, efb.vp.x2, efb.vp.y2, efb.vp.z1, efb.vp.z2);
+ StateGX::GXSetScissor_(efb.sc_x, efb.sc_y, efb.sc_w, efb.sc_h);
+ StateGX::GXSetScissorBoxOffset_(efb.sc_ox, efb.sc_oy);
+}
+
+void Screen::CopyToG3D(g3d::Camera cam) const {
+ if (!(mFlags & 0x40)) {
+ f32 sx, sy, ox, oy;
+ GetGlobalScaleOffset(&sx, &sy, &ox, &oy);
+
+ SetGlobalScaleOffset(sCanvasScale.x, sCanvasScale.y, sCanvasOffset.x, sCanvasOffset.y);
+ Frustum::CopyToG3D(cam);
+
+ SetGlobalScaleOffset(sx, sy, ox, oy);
+ } else {
+ Frustum::CopyToG3D(cam);
+ }
+
+ const DataEfb &efb = GetDataEfb();
+
+ f32 x1, x2, y1, y2;
+ f32 z1, z2;
+
+ y2 = efb.vp.y2;
+ x2 = efb.vp.x2;
+
+ y1 = efb.vp.y1;
+ x1 = efb.vp.x1;
+
+ z2 = efb.vp.z2;
+ z1 = efb.vp.z1;
+
+ cam.SetViewport(x1, y1, x2, y2);
+ cam.SetViewportZRange(z1, z2);
+ cam.SetScissor(efb.sc_x, efb.sc_y, efb.sc_w, efb.sc_h);
+ cam.SetScissorBoxOffset(efb.sc_ox, efb.sc_oy);
+}
+
+void Screen::CopyFromAnother(const Screen &other) {
+ Frustum::CopyFromAnother(other);
+
+ mPosition = other.mPosition;
+ field_0x44 = other.field_0x44;
+ field_0x48 = other.field_0x48;
+ mDataEfb = other.mDataEfb;
+ mParent = other.mParent;
+}
+
+void Screen::Reset(f32 x, f32 y, f32 w, f32 h, CanvasMode mode) {
+ mPosition.x = x;
+ mPosition.y = y;
+ mSize.x = w;
+ SetDirty(true);
+ mSize.y = h;
+ SetCanvasMode(mode);
+}
+
+void Screen::SetParent(const Screen *parent) {
+ const Screen *newParent = parent != nullptr ? parent : spRoot;
+
+ if (mParent != newParent) {
+ SetDirty(true);
+ mParent = newParent;
+ }
+}
+
+void Screen::SetUnkFlag8() {
+ if ((mFlags & 0x8) == 0) {
+ SetDirty(true);
+ }
+ mFlags |= 0x8;
+}
+
+void Screen::GetPosSizeInEfb() const {
+ // TODO
+ const TVMode tvMode = (!(mFlags & 0x20)) ? sTVMode : TV_MODE_4_3;
+ const TVModeInfo &tvRatio = sTVModeInfo[tvMode];
+
+ f32 *px = &mDataEfb.vp.x1;
+ f32 *py = &mDataEfb.vp.y1;
+ GetGlobalPos(px, py);
+
+ *px = sCanvasScale.x * *px;
+ *py = sCanvasScale.y * *py;
+
+ *px *= tvRatio.ratios.x;
+ *py *= tvRatio.ratios.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);
+ }
+
+ 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 & 0x2) {
+ *px -= static_cast<s32>(*px) & 0x1;
+ *py -= static_cast<s32>(*py) & 0x1;
+ }
+
+ *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);
+}
+
+const Screen::DataEfb &Screen::GetDataEfb() const {
+ if (IsChangeEfb()) {
+ GetPosSizeInEfb();
+ mDataEfb.vp.z1 = 0.0f;
+ mDataEfb.vp.z2 = 1.0f;
+ SetDirty(false);
+ }
+
+ return mDataEfb;
+}
+
+bool Screen::IsChangeEfb() const {
+ if (mFlags & FLAG_DIRTY) {
+ return true;
+ }
+
+ if (mParent != nullptr) {
+ return mParent->IsChangeEfb();
+ }
+
+ return false;
+}
+
+void Screen::CalcMatrixForDrawQuad(math::MTX34 *mtx, f32 x, f32 y, f32 sx, f32 sy) const {
+ PSMTXScale(*mtx, sx, sy, 1.0f);
+
+ mtx->m[0][3] = x;
+ mtx->m[1][3] = mCanvasMode == CANVASMODE_0 ? y - sy : y;
+ mtx->m[2][3] = 0.0f;
+}
+
+void Screen::FillBufferGX(u32 flags, GXColor color, u32 r6) const {
+ if (flags != 0) {
+ math::MTX34 drawMtx;
+ Screen clone(mPosition.x, mPosition.y, mSize.x, mSize.y, mParent, CANVASMODE_1);
+
+ if ((mFlags & 0x8) != 0) {
+ clone.SetUnkFlag8();
+ }
+
+ clone.SetNearZ(0.0f);
+ clone.SetFarZ(1.0f);
+ clone.SetFlag(0x40);
+ clone.SetProjectionType(PROJ_ORTHO);
+
+ 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);
+ }
+}
+
+void Screen::GetGlobalPos(f32 *ox, f32 *oy) const {
+ f32 px, py;
+ const Screen *parent = GetParent();
+
+ if (parent != nullptr) {
+ parent->GetGlobalPos(&px, &py);
+ parent->ConvertToCanvasLU(mPosition.x, mPosition.y, ox, oy);
+
+ *ox += px;
+ *oy += py;
+ } else {
+
+ *ox = mPosition.x;
+ *oy = mPosition.y;
+ }
+}
+
+void Screen::SetTVMode(TVMode tvMode) {
+ sTVMode = tvMode;
+ if (spRoot != nullptr) {
+ spRoot->SetSizeX(GetSizeXMax());
+ spRoot->SetSizeY(GetSizeYMax());
+ }
+
+ if (sChangeTVModeFunc != nullptr) {
+ sChangeTVModeFunc(spChangeTVModeFuncInfo);
+ }
+}
+
+void Screen::SetTVModeDefault() {
+ SetTVMode(SCGetAspectRatio() == SC_ASPECT_STD ? TV_MODE_4_3 : TV_MODE_16_9);
+}
+
+} // namespace EGG
diff --git a/src/m/m2d.cpp b/src/m/m2d.cpp
index 9f591a69..3f2ec24d 100644
--- a/src/m/m2d.cpp
+++ b/src/m/m2d.cpp
@@ -295,9 +295,9 @@ void Simple_c::draw() {
f32 near = 0.0f;
f32 far = 500.0f;
EGG::Screen s;
- bool needsAdjust = EGG::Screen::GetTVMode() == EGG::Screen::TV_MODE_2;
- f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_2);
- f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_1);
+ bool needsAdjust = EGG::Screen::GetTVMode() == EGG::Screen::TV_MODE_16_9;
+ f32 f1 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_16_9);
+ f32 f2 = EGG::Screen::GetSizeXMax(EGG::Screen::TV_MODE_4_3);
f32 left = needsAdjust ? f1 * r.left / f2 : r.left;
f32 right = needsAdjust ? f1 * r.right / f2 : r.right;