diff --git a/configure.py b/configure.py index 11bbf4832..15b31a8b9 100644 --- a/configure.py +++ b/configure.py @@ -249,7 +249,8 @@ config.libs = [ Object(Matching, "JSystem/JUtility/JUTGraphFifo.cpp"), Object(Matching, "JSystem/JUtility/JUTFont.cpp"), Object(NonMatching, "JSystem/J2DGraph/J2DGrafContext.cpp"), - Object(NonMatching, "JSystem/J2DGraph/J2DOrthoGraph.cpp"), + Object(Matching, "JSystem/J2DGraph/J2DOrthoGraph.cpp"), + Object(NonMatching, "JSystem/J2DGraph/J2DPane.cpp"), ], }, { diff --git a/include/JSystem/J2DGraph/J2DPane.h b/include/JSystem/J2DGraph/J2DPane.h new file mode 100644 index 000000000..e39ce88aa --- /dev/null +++ b/include/JSystem/J2DGraph/J2DPane.h @@ -0,0 +1,114 @@ +#ifndef J2DPANE_H +#define J2DPANE_H + +#include "JSystem/JGeometry.h" +#include "JSystem/JSupport/JSUList.h" +#include "SSystem/SComponent/c_xyz.h" +#include "dolphin/gx/GXEnum.h" +#include "dolphin/mtx/mtx.h" + +class J2DAnmBase; +class J2DAnmColor; +class J2DAnmTransform; +class J2DAnmTevRegKey; +class J2DAnmTextureSRTKey; +class J2DAnmVisibilityFull; +class J2DAnmVtxColor; +class J2DGrafContext; +class J2DScreen; +class J2DAnmTexPattern; +class JKRArchive; +class JSURandomInputStream; +struct ResFONT; +struct ResTIMG; + +enum J2DRotateAxis { + /* 0x78 */ ROTATE_X = 'x', + /* 0x79 */ ROTATE_Y = 'y', + /* 0x7A */ ROTATE_Z = 'z' +}; + +enum J2DBasePosition { + J2DBasePosition_0, + J2DBasePosition_1, + J2DBasePosition_2, + J2DBasePosition_3, + J2DBasePosition_4, +}; + +struct J2DPaneHeader { + /* 0x0 */ u32 mMagic; + /* 0x4 */ u32 mSize; +}; + +class J2DPane { +public: + J2DPane(); + J2DPane(J2DPane*, bool, u32, const JGeometry::TBox2&); + J2DPane(u32, const JGeometry::TBox2&); + J2DPane(J2DPane* other, JSURandomInputStream* stream, u8 arg3); + J2DPane(J2DPane*, JSURandomInputStream*); + void initiate(); + void initialize(J2DPane*, bool, u64, const JGeometry::TBox2&); + void initialize(u64 tag, const JGeometry::TBox2& dim); + void makePaneStream(J2DPane* other, JSURandomInputStream* stream); + void changeUseTrans(J2DPane* other); + bool appendChild(J2DPane* child); + bool insertChild(J2DPane* before, J2DPane* child); + void draw(f32 a1, f32 a2, const J2DGrafContext* ctx, bool a4); + void place(const JGeometry::TBox2& dim); + JGeometry::TBox2& getBounds(); + void rotate(f32 offsetX, f32 offsetY, J2DRotateAxis axis, f32 angle); + void rotate(f32 angle); + void clip(const JGeometry::TBox2& bounds); + void setBasePosition(J2DBasePosition position); + void setInfluencedAlpha(bool arg1, bool arg2); + JGeometry::TVec3 getGlbVtx(u8 arg1) const; + J2DPane* getFirstChildPane(); + J2DPane* getNextChildPane(); + J2DPane* getParentPane(); + void makePaneExStream(J2DPane* other, JSURandomInputStream* stream); + void* getPointer(JSURandomInputStream* stream, u32 size, JKRArchive* archive); + void animationTransform(); + void updateTransform(const J2DAnmTransform* transform); + + virtual ~J2DPane(); + virtual void move(f32 x, f32 y); + virtual void add(f32 x, f32 y); + virtual void resize(f32 x, f32 y); + virtual bool setConnectParent(bool connected); + virtual void update(); + virtual void calcMtx(); + virtual void drawSelf(f32 arg1, f32 arg2); + virtual void drawSelf(f32 arg1, f32 arg2, Mtx* mtx){}; + virtual void makeMatrix(f32, f32); + virtual J2DPane* search(u32 tag); + virtual u16 getTypeID() { return 16; } + + JSUTree* getFirstChild() { return mPaneTree.getFirstChild(); } + JSUTree* getEndChild() { return mPaneTree.getEndChild(); } + const JSUTree* getPaneTree() { return &mPaneTree; } + u8 getAlpha() const { return mAlpha; } + +public: + /* 0x04 */ u32 mMagic; + /* 0x08 */ int mTag; + /* 0x0C */ JGeometry::TBox2 mBounds; + /* 0x1C */ JGeometry::TBox2 mScreenPos; + /* 0x2C */ JGeometry::TBox2 mBox; + /* 0x3C */ Mtx mMtx; + /* 0x6C */ Mtx mDrawMtx; + /* 0x9C */ cXy mBasePosition; + /* 0xA4 */ f32 mRotation; + /* 0xA8 */ u8 mRotationAxis; + /* 0xA9 */ u8 m2DBasePosition; + /* 0xAA */ bool mVisible; + /* 0xAB */ u8 mCullMode; + /* 0xAC */ u8 mAlpha; + /* 0xAD */ u8 mDrawAlpha; + /* 0xAE */ u8 field_0xae; + /* 0xAF */ u8 field_0xaf; + /* 0xB0 */ JSUTree mPaneTree; +}; + +#endif /* J2DPANE_H */ diff --git a/src/JSystem/J2DGraph/J2DPane.cpp b/src/JSystem/J2DGraph/J2DPane.cpp index 0c9a8f4df..09f060911 100644 --- a/src/JSystem/J2DGraph/J2DPane.cpp +++ b/src/JSystem/J2DGraph/J2DPane.cpp @@ -4,46 +4,141 @@ // #include "JSystem/J2DGraph/J2DPane.h" +#include "JSystem/JSupport/JSURandomInputStream.h" #include "dolphin/types.h" /* 802CF8F4-802CF984 .text __ct__7J2DPaneFv */ -J2DPane::J2DPane() { - /* Nonmatching */ +J2DPane::J2DPane() : mPaneTree(this) { + mMagic = 'PAN1'; + mVisible = true; + mTag = 0; + + mBounds.set(0.f, 0.f, 0.f, 0.f); + initiate(); } /* 802CF984-802CFA44 .text __ct__7J2DPaneFP7J2DPanebUlRCQ29JGeometry8TBox2 */ -J2DPane::J2DPane(J2DPane*, bool, unsigned long, const JGeometry::TBox2&) { - /* Nonmatching */ +J2DPane::J2DPane(J2DPane* pPane, bool visible, u32 tag, const JGeometry::TBox2& bounds) + : mPaneTree(this) { + mMagic = 'PAN1'; + mVisible = visible; + mTag = tag; + mBounds.set(bounds); + if (pPane) { + pPane->mPaneTree.appendChild(&mPaneTree); + } + initiate(); } /* 802CFA44-802CFAE4 .text __ct__7J2DPaneFUlRCQ29JGeometry8TBox2 */ -J2DPane::J2DPane(unsigned long, const JGeometry::TBox2&) { - /* Nonmatching */ +J2DPane::J2DPane(u32 tag, const JGeometry::TBox2& bounds) : mPaneTree(this) { + mMagic = 'PAN1'; + mVisible = true; + mTag = tag; + mBounds.set(bounds); + initiate(); } /* 802CFAE4-802CFB48 .text initiate__7J2DPaneFv */ void J2DPane::initiate() { - /* Nonmatching */ + mBasePosition.x = 0.0f; + mBasePosition.y = 0.0f; + mRotationAxis = ROTATE_Z; + mRotation = 0.0f; + mCullMode = 0; + mAlpha = 0xFF; + field_0xae = 1; + mDrawAlpha = 0xFF; + field_0xaf = 0; + calcMtx(); } /* 802CFB48-802CFC00 .text __ct__7J2DPaneFP7J2DPaneP20JSURandomInputStream */ -J2DPane::J2DPane(J2DPane*, JSURandomInputStream*) { - /* Nonmatching */ +J2DPane::J2DPane(J2DPane* pParentPane, JSURandomInputStream* pStream) : mPaneTree(this) { + J2DPaneHeader header; + + int pos = pStream->getPosition(); + pStream->read(&header, sizeof(header)); + mMagic = header.mMagic; + pos += header.mSize; + makePaneStream(pParentPane, pStream); + pStream->seek(pos, JSUStreamSeekFrom_SET); } /* 802CFC00-802CFEF8 .text makePaneStream__7J2DPaneFP7J2DPaneP20JSURandomInputStream */ -void J2DPane::makePaneStream(J2DPane*, JSURandomInputStream*) { - /* Nonmatching */ +void J2DPane::makePaneStream(J2DPane* pParentPane, JSURandomInputStream* pStream) { + u8 unk; + pStream->read(&unk, 1); + pStream->read(&mVisible, 1); + pStream->skip(2); + mTag = pStream->read32b(); + + f32 x0 = pStream->readS16(); + f32 y0 = pStream->readS16(); + f32 x1 = x0 + pStream->readS16(); + f32 y1 = y0 + pStream->readS16(); + mBounds.set(x0, y0, x1, y1); + + unk -= 6; + mRotation = 0; + if (unk != 0) { + mRotation = pStream->readU16(); + unk--; + } + + if (unk != 0) { + setBasePosition((J2DBasePosition)pStream->readU8()); + unk--; + } else { + setBasePosition(J2DBasePosition_0); + } + + mAlpha = 0xFF; + + if (unk != 0) { + mAlpha = pStream->readU8(); + unk--; + } + + field_0xae = 1; + if (unk != 0) { + field_0xae = pStream->readU8() != 0; + unk--; + } + + pStream->align(4); + if (pParentPane != NULL) { + pParentPane->mPaneTree.appendChild(&mPaneTree); + } + + mCullMode = GX_CULL_NONE; + mDrawAlpha = 0xFF; + field_0xaf = 0; + calcMtx(); } /* 802CFEF8-802CFFD8 .text __dt__7J2DPaneFv */ J2DPane::~J2DPane() { - /* Nonmatching */ + JSUTreeIterator iterator; + for (iterator = mPaneTree.getFirstChild(); iterator != mPaneTree.getEndChild();) { + J2DPane* child = (iterator++).getObject(); + delete child; + } } /* 802CFFD8-802D0078 .text insertChild__7J2DPaneFP7J2DPaneP7J2DPane */ -void J2DPane::insertChild(J2DPane*, J2DPane*) { - /* Nonmatching */ +bool J2DPane::insertChild(J2DPane* pPrev, J2DPane* pChild) { + if (pPrev == NULL || pChild == NULL) + return false; + + bool result = + mPaneTree.insertChild(pPrev != NULL ? &pPrev->mPaneTree : NULL, &pChild->mPaneTree); + + if (result) { + pChild->calcMtx(); + } + + return result; } /* 802D0078-802D054C .text draw__7J2DPaneFffPC14J2DGrafContextb */ @@ -57,18 +152,31 @@ void J2DPane::move(float, float) { } /* 802D05C8-802D0604 .text add__7J2DPaneFff */ -void J2DPane::add(float, float) { - /* Nonmatching */ +void J2DPane::add(f32 px, f32 py) { + move(mBounds.i.x + px, mBounds.i.y + py); } /* 802D0604-802D0680 .text clip__7J2DPaneFRCQ29JGeometry8TBox2 */ -void J2DPane::clip(const JGeometry::TBox2&) { - /* Nonmatching */ +void J2DPane::clip(const JGeometry::TBox2& bounds) { + JGeometry::TBox2 boxA(bounds); + JGeometry::TBox2 boxB(mScreenPos); + boxA.addPos(boxB.i); + mBox.intersect(boxA); } /* 802D0680-802D0714 .text search__7J2DPaneFUl */ -void J2DPane::search(unsigned long) { - /* Nonmatching */ +J2DPane* J2DPane::search(u32 tag) { + if (tag == mTag) { + return this; + } + + JSUTreeIterator iter; + for (iter = mPaneTree.getFirstChild(); iter != mPaneTree.getEndChild(); ++iter) { + if (J2DPane* result = iter.getObject()->search(tag)) { + return result; + } + } + return NULL; } /* 802D0714-802D0800 .text makeMatrix__7J2DPaneFff */ @@ -77,16 +185,37 @@ void J2DPane::makeMatrix(float, float) { } /* 802D0800-802D08D8 .text setBasePosition__7J2DPaneF15J2DBasePosition */ -void J2DPane::setBasePosition(J2DBasePosition) { +void J2DPane::setBasePosition(J2DBasePosition pos) { /* Nonmatching */ + m2DBasePosition = pos; + + if (pos % 3 == 0) { + mBasePosition.x = 0.0f; + } else if (pos % 3 == 1) { + f32 width = mBounds.getWidth(); + mBasePosition.x = 0.5f * width; + } else { + mBasePosition.x = mBounds.getWidth(); + } + + if (pos / 3 == 0) { + mBasePosition.y = 0.0f; + } else if (pos / 3 == 1) { + f32 height = mBounds.getHeight(); + mBasePosition.y = height * 0.5f; + } else { + mBasePosition.y = mBounds.getHeight(); + } + mRotationAxis = ROTATE_Z; + calcMtx(); } /* 802D08D8-802D08DC .text drawSelf__7J2DPaneFffPA3_A4_f */ -void J2DPane::drawSelf(float, float, float(*)[3][4]) { - /* Nonmatching */ -} +// void J2DPane::drawSelf(float, float, float (*)[3][4]) { +// /* Nonmatching */ +// } /* 802D08DC-802D08E4 .text getTypeID__7J2DPaneFv */ -void J2DPane::getTypeID() { - /* Nonmatching */ -} +// u16 J2DPane::getTypeID() { +// /* Nonmatching */ +// }