diff --git a/configure.py b/configure.py index 40d3586ae..364480f3e 100644 --- a/configure.py +++ b/configure.py @@ -199,6 +199,8 @@ def ActorRel(rel_name, status): "cflags": CFLAGS_FRAMEWORK, "host": True, "objects": [ + NonMatching("JSystem/JFramework/JFWDisplay.cpp"), + NonMatching("JSystem/JFramework/JFWSystem.cpp"), Matching ("JSystem/JKernel/JKRFile.cpp"), Matching ("JSystem/JSupport/JSUList.cpp"), NonMatching("JSystem/JSupport/JSUInputStream.cpp"), diff --git a/include/JSystem/J2DGraph/J2DGrafContext.h b/include/JSystem/J2DGraph/J2DGrafContext.h new file mode 100644 index 000000000..1d41b5098 --- /dev/null +++ b/include/JSystem/J2DGraph/J2DGrafContext.h @@ -0,0 +1,61 @@ +#ifndef J2DGRAFCONTEXT_H +#define J2DGRAFCONTEXT_H + +#include "JSystem/JGeometry.h" +#include "JSystem/JUtility/TColor.h" +#include "dolphin/mtx/mtx.h" +#include "dolphin/types.h" + +class J2DGrafContext { +public: + struct Blend { + /* 0x0 */ u8 mType; + /* 0x1 */ u8 mSrcFactor; + /* 0x2 */ u8 mDstFactor; + }; + + + /* 802E8B08 */ J2DGrafContext(f32 x, f32 y, f32 width, f32 height); + /* 802E90C0 */ void scissor(JGeometry::TBox2 const& bounds); + void setColor(JUtility::TColor c) { this->setColor(c, c, c, c); } + /* 802E9118 */ void setColor(JUtility::TColor colorTL, JUtility::TColor colorTR, + JUtility::TColor colorBR, JUtility::TColor colorBL); + /* 802E9234 */ void setLineWidth(u8); + /* 802E9260 */ void fillBox(JGeometry::TBox2 const& box); + /* 802E9368 */ void drawFrame(JGeometry::TBox2 const& box); + /* 802E9488 */ void line(JGeometry::TVec2 start, JGeometry::TVec2 end); + /* 802E9564 */ void lineTo(JGeometry::TVec2 pos); + void lineTo(f32 x, f32 y) { this->lineTo(JGeometry::TVec2(x, y)); } + void moveTo(f32 x, f32 y) { this->moveTo(JGeometry::TVec2(x, y)); } + + void moveTo(JGeometry::TVec2 pos) { mPrevPos = pos; } + + /* 802E95D4 */ virtual ~J2DGrafContext() {} + /* 802E90E4 */ virtual void place(JGeometry::TBox2 const& bounds); + /* 802E961C */ virtual void place(f32 x, f32 y, f32 width, f32 height) { + JGeometry::TBox2 box(x, y, x + width, y + height); + this->place(box); + } + /* 802E8BB4 */ virtual void setPort(); + /* 802E8C44 */ virtual void setup2D(); + /* 802E8E20 */ virtual void setScissor(); + /* 802E9664 */ virtual s32 getGrafType() const { return 0; } + /* 802E966C */ virtual void setLookat() {} + +public: + /* 0x04 */ JGeometry::TBox2 mBounds; + /* 0x14 */ JGeometry::TBox2 mScissorBounds; + /* 0x24 */ JUtility::TColor mColorTL; + /* 0x28 */ JUtility::TColor mColorTR; + /* 0x2C */ JUtility::TColor mColorBR; + /* 0x30 */ JUtility::TColor mColorBL; + /* 0x34 */ u8 mLineWidth; + /* 0x38 */ JGeometry::TVec2 mPrevPos; + /* 0x40 */ Mtx44 mMtx44; + /* 0x80 */ Mtx mPosMtx; + /* 0xB0 */ Blend field_0xb0; + /* 0xB3 */ Blend mLinePart; + /* 0xB6 */ Blend mBoxPart; +}; + +#endif /* J2DGRAFCONTEXT_H */ diff --git a/include/JSystem/J2DGraph/J2DOrthoGraph.h b/include/JSystem/J2DGraph/J2DOrthoGraph.h new file mode 100644 index 000000000..bebf56ba1 --- /dev/null +++ b/include/JSystem/J2DGraph/J2DOrthoGraph.h @@ -0,0 +1,39 @@ +#ifndef J2DORTHOGRAPH_H +#define J2DORTHOGRAPH_H + +#include "JSystem/J2DGraph/J2DGrafContext.h" + +class J2DOrthoGraph : public J2DGrafContext { +public: + J2DOrthoGraph(); + J2DOrthoGraph(f32 x, f32 y, f32 width, f32 height, f32 far, f32 near); + void setOrtho(JGeometry::TBox2 const& bounds, f32 far, f32 near); + void scissorBounds(JGeometry::TBox2*, JGeometry::TBox2 const*); + + virtual ~J2DOrthoGraph() {} + virtual void setPort(); + virtual s32 getGrafType() const { return 1; } + virtual void setLookat(); + + f32 getWidthPower() const { return mBounds.getWidth() / mOrtho.getWidth(); } + f32 getHeightPower() const { return mBounds.getHeight() / mOrtho.getHeight(); } + + void setOrtho(f32 x, f32 y, f32 width, f32 height, f32 far, f32 near) { + JGeometry::TBox2 ortho(x, y, x + width, y + height); + setOrtho(ortho, far, near); + } + +private: + /* 0xBC */ JGeometry::TBox2 mOrtho; + /* 0xCC */ f32 mNear; + /* 0xD0 */ f32 mFar; +}; + +void J2DDrawLine(f32 x1, f32 y1, f32 x2, f32 y2, JUtility::TColor color, + int line_width); +void J2DFillBox(f32 x, f32 y, f32 width, f32 height, JUtility::TColor color); +void J2DFillBox(JGeometry::TBox2 const& box, JUtility::TColor color); +void J2DDrawFrame(f32 x, f32 y, f32 width, f32 height, JUtility::TColor color, u8 line_width); +void J2DDrawFrame(JGeometry::TBox2 const& box, JUtility::TColor color, u8 line_width); + +#endif /* J2DORTHOGRAPH_H */ diff --git a/include/JSystem/JFramework/JFWDisplay.h b/include/JSystem/JFramework/JFWDisplay.h new file mode 100644 index 000000000..24576aa43 --- /dev/null +++ b/include/JSystem/JFramework/JFWDisplay.h @@ -0,0 +1,123 @@ +#ifndef JFWDISPLAY_H +#define JFWDISPLAY_H + +#include "JSystem/JSupport/JSUList.h" +#include "JSystem/JUtility/JUTDirectPrint.h" +#include "JSystem/JUtility/JUTFader.h" +#include "JSystem/JUtility/JUTXfb.h" +#include "dolphin/os/OSAlarm.h" +#include "dolphin/types.h" + +typedef struct _GXColor GXColor; +typedef struct _GXRenderModeObj GXRenderModeObj; +class JKRHeap; + +typedef void (*JFWDisplayUnkFunc)(void); + +extern bool JFWAutoAbortGfx; + +class JFWAlarm : public OSAlarm { +public: + JFWAlarm() /* : mLink(this) */ {} + ~JFWAlarm() {} + void createAlarm() { OSCreateAlarm(this); } + void cancelAlarm() { OSCancelAlarm(this); } + //void removeLink() { sList.remove(&mLink); } + //void appendLink() { sList.append(&mLink); } + OSThread* getThread() const { return mThread; } + void setThread(OSThread* thread) { mThread = thread; } + + static JSUList sList; + +public: + /* 0x30 */ OSThread* mThread; +}; + +class JFWDisplay { +public: + enum EDrawDone { + /* 0x0 */ UNK_METHOD_0 = 0, + /* 0x1 */ UNK_METHOD_1 = 1 + }; + + /* 80272040 */ void ctor_subroutine(const _GXRenderModeObj*, bool enableAlpha); + /* 802720F8 */ JFWDisplay(const _GXRenderModeObj*, JKRHeap*, JUTXfb::EXfbNumber, bool); + /* 802721DC */ static JFWDisplay* createManager(JKRHeap*, JUTXfb::EXfbNumber, bool); + /* 802722B8 */ void prepareCopyDisp(); + /* 802723AC */ void drawendXfb_single(); + /* 802723F4 */ void exchangeXfb_double(); + /* 802724FC */ void exchangeXfb_triple(); + /* 80272574 */ void copyXfb_triple(); + /* 802725F8 */ void preGX(); + /* 8027268C */ void endGX(); + /* 80272C60 */ void waitBlanking(int); + /* 80272E10 */ void threadSleep(s64); + /* 80272EB8 */ void clearEfb_init(); + /* 80272F9C */ void clearEfb(int param_0, int param_1, int param_2, int param_3, GXColor color); + /* 80272F2C */ void clearEfb(); + /* 80272F58 */ void clearEfb(_GXColor color); + /* 8027331C */ void calcCombinationRatio(); + + /* 80272798 */ virtual void beginRender(); + /* 80272A04 */ virtual void endRender(); + /* 80272AB0 */ virtual void endFrame(); + /* 80272160 */ virtual ~JFWDisplay(); + + static JFWDisplay* getManager() { return sManager; } + + int startFadeOut(int param_0) { + if (mpFader != NULL) { + return mpFader->startFadeOut(param_0); + } + return 1; + } + + int startFadeIn(int param_0) { + if (mpFader != NULL) { + return mpFader->startFadeIn(param_0); + } + return 1; + } + + void setTickRate(u32 rate) { + mTickRate = rate; + mFrameRate = 0; + } + + void setDrawDoneMethod(EDrawDone drawDone) { mDrawDoneMethod = drawDone; } + void setFader(JUTFader* fader) { mpFader = fader; } + void setClearColor(JUtility::TColor color) { mClearColor = color; } + + static JFWDisplay* sManager; + +private: + /* 0x04 */ JUTFader* mpFader; + /* 0x08 */ const _GXRenderModeObj* mpRenderMode; + /* 0x0C */ JUtility::TColor mClearColor; + /* 0x10 */ u32 mZClear; + /* 0x14 */ JUTXfb* mXfbManager; + /* 0x18 */ u16 mGamma; + /* 0x1C */ EDrawDone mDrawDoneMethod; + /* 0x20 */ u16 mFrameRate; + /* 0x24 */ u32 mTickRate; + /* 0x28 */ bool mEnableAlpha; + /* 0x2A */ u16 mClamp; + /* 0x2C */ f32 mCombinationRatio; + /* 0x30 */ u32 field_0x30; + /* 0x34 */ u32 field_0x34; + /* 0x38 */ u32 field_0x38; + /* 0x3C */ s16 field_0x3C; + /* 0x3E */ u8 field_0x3E; +}; + +inline void JUTChangeFrameBuffer(void* buffer, u16 height, u16 width) { + JUTDirectPrint::getManager()->changeFrameBuffer(buffer, width, height); +} + +static void JFWDrawDoneAlarm(); +static void JFWGXDrawDoneAutoAbort(); +static void JFWGXAbortAlarmHandler(OSAlarm* p_alarm, OSContext* p_ctx); +static void waitForTick(u32 p1, u16 p2); +static void diagnoseGpHang(); + +#endif /* JFWDISPLAY_H */ diff --git a/include/JSystem/JFramework/JFWSystem.h b/include/JSystem/JFramework/JFWSystem.h new file mode 100644 index 000000000..3ff249b83 --- /dev/null +++ b/include/JSystem/JFramework/JFWSystem.h @@ -0,0 +1,46 @@ +#ifndef JFWSYSTEM_H +#define JFWSYSTEM_H + +#include "dolphin/types.h" + +typedef struct _GXRenderModeObj GXRenderModeObj; +class JKRExpHeap; +class JKRThread; +class JUTConsole; +class JUTConsoleManager; +class JUTDbPrint; +class JUTResFont; +struct ResFONT; + +struct JFWSystem { + struct CSetUpParam { + static s32 maxStdHeaps; + static u32 sysHeapSize; + static u32 fifoBufSize; + static u32 aramAudioBufSize; + static u32 aramGraphBufSize; + static u32 streamPriority; + static u32 decompPriority; + static u32 aPiecePriority; + static ResFONT* systemFontRes; + static GXRenderModeObj* renderMode; + static u32 exConsoleBufferSize; + }; + + static void firstInit(); + static void init(); + + static JUTConsole* getSystemConsole() { return systemConsole; } + static JKRExpHeap* getSystemHeap() { return systemHeap; } + + static JKRExpHeap* rootHeap; + static JKRExpHeap* systemHeap; + static JKRThread* mainThread; + static JUTDbPrint* debugPrint; + static JUTResFont* systemFont; + static JUTConsoleManager* systemConsoleManager; + static JUTConsole* systemConsole; + static bool sInitCalled; +}; + +#endif /* JFWSYSTEM_H */ diff --git a/include/JSystem/JKernel/JKRAram.h b/include/JSystem/JKernel/JKRAram.h index 039641f1c..171072f39 100644 --- a/include/JSystem/JKernel/JKRAram.h +++ b/include/JSystem/JKernel/JKRAram.h @@ -23,14 +23,14 @@ class JKRAram : public JKRThread { //private: /* 0x00 */ // vtable /* 0x04 */ // JKRThread - /* 0x7C */ u32 mAudioMemoryPtr; - /* 0x80 */ u32 mAudioMemorySize; - /* 0x84 */ u32 mGraphMemoryPtr; - /* 0x88 */ u32 mGraphMemorySize; - /* 0x8C */ u32 mAramMemoryPtr; - /* 0x90 */ u32 mAramMemorySize; - /* 0x94 */ JKRAramHeap* mAramHeap; - /* 0x98 */ u32 mStackArray[3]; + /* 0x68 */ u32 mAudioMemoryPtr; + /* 0x6C */ u32 mAudioMemorySize; + /* 0x70 */ u32 mGraphMemoryPtr; + /* 0x74 */ u32 mGraphMemorySize; + /* 0x78 */ u32 mAramMemoryPtr; + /* 0x7C */ u32 mAramMemorySize; + /* 0x80 */ JKRAramHeap* mAramHeap; + /* 0x84 */ u32 mStackArray[3]; public: static JKRAram* create(u32, u32, long, long, long); diff --git a/include/JSystem/JKernel/JKRThread.h b/include/JSystem/JKernel/JKRThread.h index c2b89de84..f56a9231e 100644 --- a/include/JSystem/JKernel/JKRThread.h +++ b/include/JSystem/JKernel/JKRThread.h @@ -64,7 +64,6 @@ class JKRThread : JKRDisposer { OSThread* getThreadRecord() const { return mThreadRecord; } void* getStack() const { return mStackMemory; } - TLoad* getLoadInfo() { return &mLoadInfo; } JKRHeap* getCurrentHeap() const { return mCurrentHeap; } s32 getCurrentHeapError() const { return mCurrentHeapError; } @@ -105,9 +104,8 @@ class JKRThread : JKRDisposer { /* 0x54 */ s32 mMessageCount; /* 0x58 */ void* mStackMemory; /* 0x5C */ u32 mStackSize; - /* 0x60 */ TLoad mLoadInfo; - /* 0x74 */ JKRHeap* mCurrentHeap; - /* 0x78 */ s32 mCurrentHeapError; + /* 0x60 */ JKRHeap* mCurrentHeap; + /* 0x64 */ s32 mCurrentHeapError; public: static void* start(void* param_1); diff --git a/include/JSystem/JUtility/JUTConsole.h b/include/JSystem/JUtility/JUTConsole.h index 6b154047e..3915b9033 100644 --- a/include/JSystem/JUtility/JUTConsole.h +++ b/include/JSystem/JUtility/JUTConsole.h @@ -110,12 +110,11 @@ class JUTConsole : public JKRDisposer { /* 0x58 */ int mOutput; /* 0x5C */ JUtility::TColor field_0x5c; /* 0x60 */ JUtility::TColor field_0x60; - /* 0x64 */ int field_0x64; - /* 0x68 */ bool mVisible; - /* 0x69 */ bool field_0x69; - /* 0x6A */ bool field_0x6a; - /* 0x6B */ bool field_0x6b; -}; // Size: 0x6C + /* 0x64 */ bool mVisible; + /* 0x65 */ bool field_0x65; + /* 0x66 */ bool field_0x66; + /* 0x67 */ bool field_0x67; +}; // Size: 0x68 class JUTConsoleManager { public: diff --git a/include/JSystem/JUtility/JUTException.h b/include/JSystem/JUtility/JUTException.h index 99da12c7c..0380caf3c 100644 --- a/include/JSystem/JUtility/JUTException.h +++ b/include/JSystem/JUtility/JUTException.h @@ -119,19 +119,19 @@ class JUTException : public JKRThread { static u32 fpscr; private: - /* 0x7C */ JUTExternalFB* mFrameMemory; - /* 0x80 */ JUTDirectPrint* mDirectPrint; - /* 0x84 */ JUTGamePad* mGamePad; - /* 0x88 */ JUTGamePad::EPadPort mGamePadPort; - /* 0x8C */ s32 mPrintWaitTime0; - /* 0x90 */ s32 mPrintWaitTime1; - /* 0x94 */ u32 mTraceSuppress; - /* 0x98 */ u32 field_0x98; - /* 0x9C */ u32 mPrintFlags; - /* 0xA0 */ u32 mStackPointer; + /* 0x68 */ JUTExternalFB* mFrameMemory; + /* 0x6C */ JUTDirectPrint* mDirectPrint; + /* 0x70 */ JUTGamePad* mGamePad; + /* 0x74 */ JUTGamePad::EPadPort mGamePadPort; + /* 0x78 */ s32 mPrintWaitTime0; + /* 0x7C */ s32 mPrintWaitTime1; + /* 0x80 */ u32 mTraceSuppress; + /* 0x84 */ u32 field_0x98; + /* 0x88 */ u32 mPrintFlags; + /* 0x8C */ u32 mStackPointer; }; -STATIC_ASSERT(sizeof(JUTException) == 0xA4); +STATIC_ASSERT(sizeof(JUTException) == 0x90); struct JUTWarn { JUTWarn& operator<<(const char*) { return *this; } diff --git a/include/JSystem/JUtility/JUTXfb.h b/include/JSystem/JUtility/JUTXfb.h index 682529e04..6ceeb6a0c 100644 --- a/include/JSystem/JUtility/JUTXfb.h +++ b/include/JSystem/JUtility/JUTXfb.h @@ -20,7 +20,7 @@ class JUTXfb { /* 802E5260 */ JUTXfb(_GXRenderModeObj const*, JKRHeap*, JUTXfb::EXfbNumber); /* 802E5308 */ ~JUTXfb(); /* 802E5378 */ void delXfb(int); - /* 802E53B8 */ static JUTXfb* createManager(JKRHeap*, JUTXfb::EXfbNumber); + /* 802E53B8 */ static JUTXfb* createManager(const _GXRenderModeObj*, JKRHeap*, JUTXfb::EXfbNumber); /* 802E5424 */ static void destroyManager(); /* 802E5454 */ void initiate(u16, u16, JKRHeap*, JUTXfb::EXfbNumber); diff --git a/src/JSystem/JFramework/JFWDisplay.cpp b/src/JSystem/JFramework/JFWDisplay.cpp index 404a2f9e0..c3e664c21 100644 --- a/src/JSystem/JFramework/JFWDisplay.cpp +++ b/src/JSystem/JFramework/JFWDisplay.cpp @@ -4,134 +4,546 @@ // #include "JSystem/JFramework/JFWDisplay.h" +#include "JSystem/J2DGraph/J2DOrthoGraph.h" +#include "JSystem/JUtility/JUTAssert.h" +#include "JSystem/JUtility/JUTConsole.h" +#include "JSystem/JUtility/JUTDbPrint.h" +#include "JSystem/JUtility/JUTProcBar.h" +#include "dolphin/gx/GX.h" +#include "dolphin/os/OS.h" #include "dolphin/types.h" +JFWDisplay* JFWDisplay::sManager = 0; + +bool JFWAutoAbortGfx = true; +Mtx e_mtx = { + {1.0f, 0.0f, 0.0f, 0.0f}, + {0.0f, 1.0f, 0.0f, 0.0f}, + {0.0f, 0.0f, 1.0f, 0.0f}, +}; +static GXTexObj clear_z_tobj; +u8 clear_z_TX[64] __attribute__((aligned(32))) = { + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, + 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +}; + + /* 802551C0-8025527C .text ctor_subroutine__10JFWDisplayFPC16_GXRenderModeObjb */ -void JFWDisplay::ctor_subroutine(const _GXRenderModeObj*, bool) { - /* Nonmatching */ +void JFWDisplay::ctor_subroutine(const _GXRenderModeObj* mode, bool enableAlpha) { + mEnableAlpha = enableAlpha; + mClamp = 3; + + mClearColor.r = 0; + mClearColor.g = 0; + mClearColor.b = 0; + mClearColor.a = 0; + + mZClear = 0xFFFFFF; + + mpRenderMode = mode != 0 ? mode : JUTVideo::sManager->getRenderMode(); + + mGamma = 0; + mpFader = 0; + mFrameRate = 1; + mTickRate = 0; + mCombinationRatio = 0.0f; + field_0x34 = 0; + field_0x30 = OSGetTick(); + field_0x38 = 0; + field_0x3C = 0; + field_0x3E = 0; + mDrawDoneMethod = UNK_METHOD_0; + clearEfb_init(); + JUTProcBar::create(); + JUTProcBar::clear(); } /* 8025527C-802552EC .text __ct__10JFWDisplayFPC16_GXRenderModeObjP7JKRHeapQ26JUTXfb10EXfbNumberb */ -JFWDisplay::JFWDisplay(const _GXRenderModeObj*, JKRHeap*, JUTXfb::EXfbNumber, bool) { - /* Nonmatching */ +JFWDisplay::JFWDisplay(const _GXRenderModeObj* mode, JKRHeap* p_heap, JUTXfb::EXfbNumber xfb_num, bool enableAlpha) { + ctor_subroutine(mode, enableAlpha); + mXfbManager = JUTXfb::createManager(mode, p_heap, xfb_num); } /* 802552EC-80255354 .text __dt__10JFWDisplayFv */ JFWDisplay::~JFWDisplay() { - /* Nonmatching */ + waitBlanking(2); + JUTProcBar::destroy(); + JUTXfb::destroyManager(); } /* 80255354-802553EC .text createManager__10JFWDisplayFP7JKRHeapQ26JUTXfb10EXfbNumberb */ -void JFWDisplay::createManager(JKRHeap*, JUTXfb::EXfbNumber, bool) { - /* Nonmatching */ +JFWDisplay* JFWDisplay::createManager(JKRHeap* p_heap, JUTXfb::EXfbNumber xfb_num, bool enableAlpha) { + JUT_CONFIRM(243, sManager == 0); + if(sManager == 0) { + sManager = new JFWDisplay(0, p_heap, xfb_num, enableAlpha); + } + + return sManager; +} + +static dummyFunc() { + OSReport("sManager"); + OSReport("mTemporarySingle"); } /* 802553EC-80255444 .text callDirectDraw__Fv */ void callDirectDraw() { - /* Nonmatching */ + JUTChangeFrameBuffer(JUTXfb::getManager()->getDrawingXfb(), JUTVideo::getManager()->getEfbHeight(), JUTVideo::getManager()->getFbWidth()); + JUTAssertion::flushMessage(); } /* 80255444-80255528 .text prepareCopyDisp__10JFWDisplayFv */ void JFWDisplay::prepareCopyDisp() { - /* Nonmatching */ + _GXRenderModeObj* renderObj = JUTVideo::getManager()->getRenderMode(); + u16 width, height; + JUTVideo::getManager()->getBounds(width, height); + u16 xfb_height = renderObj->xfb_height; + f32 y_scaleF = GXGetYScaleFactor(height, renderObj->xfb_height); + + GXSetCopyClear(mClearColor, mZClear); + GXSetDispCopySrc(0, 0, width, height); + GXSetDispCopyDst(width, xfb_height); + GXSetDispCopyYScale(y_scaleF); + VIFlush(); + GXSetCopyFilter((GXBool)renderObj->antialiasing, renderObj->sample_pattern, GX_ENABLE, renderObj->vfilter); + GXSetCopyClamp((GXFBClamp)mClamp); + GXSetDispCopyGamma((GXGamma)mGamma); + GXSetZMode(GX_ENABLE, GX_LEQUAL, GX_ENABLE); + if (mEnableAlpha) { + GXSetAlphaUpdate(GX_ENABLE); + } } /* 80255528-80255570 .text drawendXfb_single__10JFWDisplayFv */ void JFWDisplay::drawendXfb_single() { - /* Nonmatching */ + JUTXfb* manager = JUTXfb::getManager(); + if (manager->getDrawingXfbIndex() >= 0) { + prepareCopyDisp(); + JFWGXDrawDoneAutoAbort(); + GXFlush(); + manager->setDrawnXfbIndex(manager->getDrawingXfbIndex()); + } } /* 80255570-80255658 .text exchangeXfb_double__10JFWDisplayFv */ void JFWDisplay::exchangeXfb_double() { - /* Nonmatching */ + JUTXfb* xfbMng = JUTXfb::getManager(); + + if(xfbMng->getDrawnXfbIndex() == xfbMng->getDisplayingXfbIndex()) { + if(0 <= xfbMng->getDrawingXfbIndex()) { + prepareCopyDisp(); + GXCopyDisp(xfbMng->getDrawingXfb(), (GXBool)1); + if(mDrawDoneMethod == 0) { + GXDrawDone(); + JUTVideo::dummyNoDrawWait(); + } + else { + JUTVideo::drawDoneStart(); + } + + if(mDrawDoneMethod == 0) { + callDirectDraw(); + } + } + + const u32 idx = xfbMng->getDrawingXfbIndex(); + xfbMng->setDrawnXfbIndex(idx); + xfbMng->setDrawingXfbIndex(((idx >> 31) - 1) & (idx ^ 1)); //not sure what this math is doing + } + else { + clearEfb(mClearColor); + if(xfbMng->getDrawingXfbIndex() < 0) { + xfbMng->setDrawingXfbIndex(0); + } + } } /* 80255658-802556D0 .text exchangeXfb_triple__10JFWDisplayFv */ void JFWDisplay::exchangeXfb_triple() { - /* Nonmatching */ + JUTXfb* xfbMng = JUTXfb::getManager(); + + if (xfbMng->getDrawingXfbIndex() >= 0) { + callDirectDraw(); + } + + xfbMng->setDrawnXfbIndex(xfbMng->getDrawingXfbIndex()); + + s16 drawing_idx = xfbMng->getDrawingXfbIndex() + 1; + do { + if (drawing_idx >= 3 || drawing_idx < 0) { + drawing_idx = 0; + } + } while (drawing_idx == xfbMng->getDisplayingXfbIndex()); + xfbMng->setDrawingXfbIndex(drawing_idx); } /* 802556D0-80255730 .text copyXfb_triple__10JFWDisplayFv */ void JFWDisplay::copyXfb_triple() { - /* Nonmatching */ + JUTXfb* xfbMng = JUTXfb::getManager(); + + if (xfbMng->getDrawingXfbIndex() >= 0) { + prepareCopyDisp(); + GXCopyDisp(xfbMng->getDrawingXfb(), GX_TRUE); + GXPixModeSync(); + } } /* 80255730-802557C0 .text preGX__10JFWDisplayFv */ void JFWDisplay::preGX() { - /* Nonmatching */ + GXInvalidateTexAll(); + GXInvalidateVtxCache(); + + if (mpRenderMode->antialiasing) { + GXSetPixelFmt(GX_PF_RGB565_Z16, GX_ZC_LINEAR); + GXSetDither(GX_ENABLE); + } else { + if (mEnableAlpha) { + GXSetPixelFmt(GX_PF_RGBA6_Z24, GX_ZC_LINEAR); + GXSetDither(GX_ENABLE); + } else { + GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR); + GXSetDither(GX_DISABLE); + } + } } /* 802557C0-802558CC .text endGX__10JFWDisplayFv */ void JFWDisplay::endGX() { - /* Nonmatching */ + u16 width, height; + JUTVideo::getManager()->getBounds(width, height); + + J2DOrthoGraph ortho(0.0f, 0.0f, width, height, -1.0f, 1.0f); + + if (mpFader != NULL) { + ortho.setPort(); + mpFader->control(); + } + ortho.setPort(); + JUTDbPrint::getManager()->flush(); + + if (JUTConsoleManager::getManager() != NULL) { + ortho.setPort(); + JUTConsoleManager::getManager()->draw(); + } + + ortho.setPort(); + JUTProcBar::getManager()->draw(); + + if (mDrawDoneMethod != UNK_METHOD_0 || JUTXfb::getManager()->getBufferNum() == 1) { + JUTAssertion::flushMessage_dbPrint(); + } + GXFlush(); } /* 802558CC-80255AB8 .text beginRender__10JFWDisplayFv */ void JFWDisplay::beginRender() { - /* Nonmatching */ + JUTProcBar::getManager()->wholeLoopEnd(); + JUTProcBar::getManager()->wholeLoopStart(); + JUTProcBar::getManager()->idleStart(); + + waitForTick(mTickRate, mFrameRate); + JUTVideo::getManager()->waitRetraceIfNeed(); + + OSTick tick = OSGetTick(); + field_0x34 = tick - field_0x30; + field_0x30 = tick; + field_0x38 = field_0x30 - JUTVideo::getVideoLastTick(); + + JUTProcBar::getManager()->idleEnd(); + + if (true) { + JUTProcBar::getManager()->gpStart(); + + JUTXfb* xfbMng = JUTXfb::getManager(); + switch (xfbMng->getBufferNum()) { + case 1: + if (xfbMng->getSDrawingFlag() != 2) { + xfbMng->setSDrawingFlag(1); + clearEfb(mClearColor); + } else { + xfbMng->setSDrawingFlag(1); + } + xfbMng->setDrawingXfbIndex(field_0x3C); + break; + case 2: + exchangeXfb_double(); + break; + case 3: + exchangeXfb_triple(); + break; + default: + break; + } + } + + preGX(); } /* 80255AB8-80255B58 .text endRender__10JFWDisplayFv */ void JFWDisplay::endRender() { - /* Nonmatching */ + endGX(); + + switch (JUTXfb::getManager()->getBufferNum()) { + case 1: + drawendXfb_single(); + case 2: + break; + case 3: + copyXfb_triple(); + default: + break; + } + + JUTProcBar::getManager()->cpuStart(); + calcCombinationRatio(); } /* 80255B58-80255CE4 .text endFrame__10JFWDisplayFv */ void JFWDisplay::endFrame() { - /* Nonmatching */ + JUTProcBar::getManager()->cpuEnd(); + + JUTProcBar::getManager()->gpWaitStart(); + switch (JUTXfb::getManager()->getBufferNum()) { + case 1: + break; + case 2: + JFWGXDrawDoneAutoAbort(); + GXFlush(); + break; + case 3: + JFWGXDrawDoneAutoAbort(); + GXFlush(); + break; + default: + break; + } + + JUTProcBar::getManager()->gpWaitEnd(); + JUTProcBar::getManager()->gpEnd(); + + static u32 prevFrame = VIGetRetraceCount(); + u32 retrace_cnt = VIGetRetraceCount(); + JUTProcBar::getManager()->setCostFrame(retrace_cnt - prevFrame); + prevFrame = retrace_cnt; } /* 80255CE4-80255D34 .text waitBlanking__10JFWDisplayFi */ -void JFWDisplay::waitBlanking(int) { - /* Nonmatching */ +void JFWDisplay::waitBlanking(int duration) { + while (duration-- > 0) { + waitForTick(mTickRate, mFrameRate); + } } /* 80255D34-80255E54 .text waitForTick__FUlUs */ -void waitForTick(unsigned long, unsigned short) { - /* Nonmatching */ +void waitForTick(u32 p1, u16 p2) { + if (p1 != 0) { + static s64 nextTick = OSGetTime(); + s64 time = OSGetTime(); + while (time < nextTick) { + JFWDisplay::getManager()->threadSleep((nextTick - time)); + time = OSGetTime(); + } + nextTick = time + p1; + } + else { + static u32 nextCount = VIGetRetraceCount(); + u32 uVar1 = (p2 == 0) ? 1 : p2; + OSMessage msg; + do { + if (!OSReceiveMessage(JUTVideo::getManager()->getMessageQueue(), &msg, OS_MESSAGE_BLOCK)) { + msg = 0; + } + } while (((int)msg - (int)nextCount) < 0); + nextCount = (int)msg + uVar1; + } } /* 80255E54-80255E78 .text JFWThreadAlarmHandler__FP7OSAlarmP9OSContext */ -void JFWThreadAlarmHandler(OSAlarm*, OSContext*) { - /* Nonmatching */ +void JFWThreadAlarmHandler(OSAlarm* p_alarm, OSContext* p_ctx) { + JFWAlarm* alarm = static_cast(p_alarm); + OSResumeThread(alarm->getThread()); } /* 80255E78-80255EEC .text threadSleep__10JFWDisplayFx */ -void JFWDisplay::threadSleep(long long) { - /* Nonmatching */ +void JFWDisplay::threadSleep(s64 time) { + JFWAlarm alarm; + OSCreateAlarm(&alarm); + alarm.setThread(OSGetCurrentThread()); + s32 status = OSDisableInterrupts(); + OSSetAlarm(&alarm, time, JFWThreadAlarmHandler); + OSSuspendThread(alarm.getThread()); + OSRestoreInterrupts(status); } /* 80255EEC-80255F60 .text clearEfb_init__10JFWDisplayFv */ void JFWDisplay::clearEfb_init() { - /* Nonmatching */ + GXInitTexObj(&clear_z_tobj, &clear_z_TX, 4, 4, GX_TF_Z24X8, GX_REPEAT,GX_REPEAT, false); + GXInitTexObjLOD(&clear_z_tobj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1); } /* 80255F60-80255FA0 .text clearEfb__10JFWDisplayF8_GXColor */ -void JFWDisplay::clearEfb(_GXColor) { - /* Nonmatching */ +void JFWDisplay::clearEfb(_GXColor color) { + int height = mpRenderMode->efb_height; + int width = mpRenderMode->fb_width; + + clearEfb(0, 0, width, height, color); } /* 80255FA0-8025631C .text clearEfb__10JFWDisplayFiiii8_GXColor */ -void JFWDisplay::clearEfb(int, int, int, int, _GXColor) { - /* Nonmatching */ +void JFWDisplay::clearEfb(int param_0, int param_1, int param_2, int param_3, GXColor color) { + Mtx44 mtx; + u16 height = mpRenderMode->efb_height; + u16 width = mpRenderMode->fb_width; + + C_MTXOrtho(mtx, 0.0f, height, 0.0f, width, 0.0f, 1.0f); + GXSetProjection(mtx, GX_ORTHOGRAPHIC); + GXSetViewport(0.0f, 0.0f, width, height, 0.0f, 1.0f); + GXSetScissor(0, 0, width, height); + + GXLoadPosMtxImm(e_mtx, GX_PNMTX0); + GXSetCurrentMtx(0); + GXClearVtxDesc(); + GXSetVtxDesc(GX_VA_POS, GX_DIRECT); + GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGBX8, 0); + GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGB565, 0); + GXSetNumChans(0); + GXSetChanCtrl(GX_COLOR0A0, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetChanCtrl(GX_COLOR1A1, GX_DISABLE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); + GXSetNumTexGens(1); + GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 60, GX_DISABLE, 125); + GXLoadTexObj(&clear_z_tobj, GX_TEXMAP0); + GXSetNumTevStages(1); + GXSetTevColor(GX_TEVREG0, color); + GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL); + GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_C0); + GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_ENABLE, 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_ENABLE, GX_TEVPREV); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_OR, GX_ALWAYS, 0); + GXSetZTexture(GX_ZT_REPLACE, GX_TF_Z24X8, 0); + GXSetZCompLoc(GX_DISABLE); + GXSetBlendMode(GX_BM_NONE, GX_BL_ZERO, GX_BL_ZERO, GX_LO_NOOP); + + if (mEnableAlpha) { + GXSetAlphaUpdate(GX_ENABLE); + GXSetDstAlpha(GX_ENABLE, 0x00); + } + GXSetZMode(GX_ENABLE, GX_ALWAYS, GX_ENABLE); + GXSetCullMode(GX_CULL_BACK); + + GXBegin(GX_QUADS, GX_VTXFMT0, 4); + GXPosition2u16(param_0, param_1); + GXTexCoord2u8(0, 0); + + GXPosition2u16(param_0 + param_2, param_1); + GXTexCoord2u8(1, 0); + + GXPosition2u16(param_0 + param_2, param_1 + param_3); + GXTexCoord2u8(1, 1); + + GXPosition2u16(param_0, param_1 + param_3); + GXTexCoord2u8(0, 1); + + GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z24X8, 0); + GXSetZCompLoc(GX_ENABLE); + if (mEnableAlpha) { + GXSetDstAlpha(GX_DISABLE, 0x00); + } } /* 8025631C-802563A8 .text calcCombinationRatio__10JFWDisplayFv */ void JFWDisplay::calcCombinationRatio() { - /* Nonmatching */ + u32 vidInterval = JUTVideo::getVideoInterval(); + s32 unk34 = field_0x34 * 2; + + s32 i = vidInterval; + for (; i < unk34; i += vidInterval) { + } + + s32 tmp = (i - unk34) - field_0x38; + if (tmp < 0) { + tmp += vidInterval; + } + mCombinationRatio = (f32)tmp / (f32)field_0x34; + if (mCombinationRatio > 1.0f) { + mCombinationRatio = 1.0f; + } } /* 802563A8-8025640C .text JFWGXDrawDoneAutoAbort__Fv */ void JFWGXDrawDoneAutoAbort() { - /* Nonmatching */ + if(JFWAutoAbortGfx != 0) { + OSAlarm alarm; + OSCreateAlarm(&alarm); + OSSetAlarm(&alarm, __OSBusClock >> 2, JFWGXAbortAlarmHandler); + GXDrawDone(); + OSCancelAlarm(&alarm); + } + else { + GXDrawDone(); + } } /* 8025640C-802564D4 .text JFWGXAbortAlarmHandler__FP7OSAlarmP9OSContext */ void JFWGXAbortAlarmHandler(OSAlarm*, OSContext*) { - /* Nonmatching */ + diagnoseGpHang(); + if(JFWAutoAbortGfx != true) { + OSReport("自動復帰しません\n"); + JUT_WARN(1350, "GP FREEZE!"); + JUT_ASSERT(1351, 0); + } + else { + OSReport("GXAbortFrame() を呼び出し、復帰します\n"); + JUT_WARN(1355, "GP FREEZE! AUTO RESUME"); + GXAbortFrame(); + GXSetDrawDone(); + } } /* 802564D4-802566B8 .text diagnoseGpHang__Fv */ void diagnoseGpHang() { - /* Nonmatching */ + u32 sp28; + u32 sp24; + u32 sp20; + u32 sp1C; + u32 sp18; + u32 sp14; + u32 sp10; + u32 spC; + bool readIdle; + bool commandIdle; + bool sp8; + + GXReadXfRasMetric(&sp24, &sp28, &sp1C, &sp20); + GXReadXfRasMetric(&sp14, &sp18, &spC, &sp10); + + u32 temp_r31 = sp28 == sp18; + u32 temp_r30 = sp24 == sp14; + u32 temp_r0 = sp20 != sp10; + u32 temp_r0_2 = sp1C != spC; + + GXGetGPStatus((GXBool*)&sp8, (GXBool*)&sp8, (GXBool*)&readIdle, (GXBool*)&commandIdle, + (GXBool*)&sp8); + + OSReport("GP status %d%d%d%d%d%d --> ", readIdle, commandIdle, temp_r31, temp_r30, temp_r0, + temp_r0_2); + + if (!temp_r30 && temp_r0) { + OSReport("GP hang due to XF stall bug.\n"); + } else if (!temp_r31 && temp_r30 && temp_r0) { + OSReport("GP hang due to unterminated primitive.\n"); + } else if (!commandIdle && temp_r31 && temp_r30 && temp_r0) { + OSReport("GP hang due to illegal instruction.\n"); + } else if (readIdle && commandIdle && temp_r31 && temp_r30 && temp_r0 && temp_r0_2) { + OSReport("GP appears to be not hung (waiting for input).\n"); + } else { + OSReport("GP is in unknown state.\n"); + } +} + +static dummyFunc2() { + OSReport("\0\0\0\0\0\0"); } diff --git a/src/JSystem/JFramework/JFWSystem.cpp b/src/JSystem/JFramework/JFWSystem.cpp index 3528170a2..4ba5d8094 100644 --- a/src/JSystem/JFramework/JFWSystem.cpp +++ b/src/JSystem/JFramework/JFWSystem.cpp @@ -4,14 +4,100 @@ // #include "JSystem/JFramework/JFWSystem.h" +#include "JSystem/JKernel/JKRExpHeap.h" +#include "JSystem/JKernel/JKRAram.h" +#include "JSystem/JUtility/JUTAssert.h" +#include "JSystem/JUtility/JUTVideo.h" +#include "JSystem/JUtility/JUTGraphFifo.h" +#include "JSystem/JUtility/JUTGamePad.h" +#include "JSystem/JUtility/JUTDirectPrint.h" +#include "JSystem/JUtility/JUTException.h" +#include "JSystem/JUtility/JUTResFont.h" +#include "JSystem/JUtility/JUTDbPrint.h" +#include "JSystem/JUtility/JUTConsole.h" +#include "dolphin/os/OS.h" +#include "dolphin/dvd/dvd.h" +#include "dolphin/gx/GXFrameBuf.h" #include "dolphin/types.h" -/* 80254DD0-80254E54 .text firstInit__9JFWSystemFv */ +s32 JFWSystem::CSetUpParam::maxStdHeaps = 2; +u32 JFWSystem::CSetUpParam::sysHeapSize = 0x400000; +u32 JFWSystem::CSetUpParam::fifoBufSize = 0x40000; +u32 JFWSystem::CSetUpParam::aramAudioBufSize = 0x800000; +u32 JFWSystem::CSetUpParam::aramGraphBufSize = 0x600000; +u32 JFWSystem::CSetUpParam::streamPriority = 8; +u32 JFWSystem::CSetUpParam::decompPriority = 7; +u32 JFWSystem::CSetUpParam::aPiecePriority = 6; +ResFONT* JFWSystem::CSetUpParam::systemFontRes = (ResFONT*)0x8036CA40; //using JUTResFONT_Ascfont_fix12 makes the pointer null +GXRenderModeObj* JFWSystem::CSetUpParam::renderMode = (GXRenderModeObj*)0x803A1AB8; //using GXNtsc480IntDf makes the pointer null +u32 JFWSystem::CSetUpParam::exConsoleBufferSize = 0x24F8; + +JKRExpHeap* JFWSystem::rootHeap = 0; +JKRExpHeap* JFWSystem::systemHeap = 0; +JKRThread* JFWSystem::mainThread = 0; +JUTDbPrint* JFWSystem::debugPrint = 0; +JUTResFont* JFWSystem::systemFont = 0; +JUTConsoleManager* JFWSystem::systemConsoleManager = 0; +JUTConsole* JFWSystem::systemConsole = 0; +bool JFWSystem::sInitCalled = false; + void JFWSystem::firstInit() { - /* Nonmatching */ + JUT_ASSERT(80, rootHeap == 0); + + OSInit(); + DVDInit(); + rootHeap = JKRExpHeap::createRoot(CSetUpParam::maxStdHeaps, false); + systemHeap = JKRExpHeap::create(CSetUpParam::sysHeapSize, rootHeap, false); + + return; } -/* 80254E54-802551C0 .text init__9JFWSystemFv */ void JFWSystem::init() { /* Nonmatching */ + JUT_ASSERT(101, sInitCalled == false); + + if(rootHeap == 0) { + firstInit(); + } + + sInitCalled = true; + + JKRAram::create(CSetUpParam::aramAudioBufSize,CSetUpParam::aramGraphBufSize, CSetUpParam::streamPriority,CSetUpParam::decompPriority, CSetUpParam::aPiecePriority); + mainThread = new JKRThread(OSGetCurrentThread(), 4); + + JUTVideo::createManager(CSetUpParam::renderMode); + JUTCreateFifo(CSetUpParam::fifoBufSize); + + JUTGamePad::init(); + + JUTDirectPrint* dirPrint = JUTDirectPrint::start(); + JUTAssertion::create(); + JUTException::create(dirPrint); + + systemFont = new JUTResFont(CSetUpParam::systemFontRes, 0); + + debugPrint = JUTDbPrint::start(0, 0); + debugPrint->changeFont(systemFont); + + systemConsoleManager = JUTConsoleManager::createManager(0); + systemConsole = JUTConsole::create(0x3C, 200, 0); + systemConsole->setFont(systemFont); + if(CSetUpParam::renderMode->efb_height < 300) { + systemConsole->setFontSize(systemFont->getWidth() * 0.85f, systemFont->getHeight() * 0.5f); + systemConsole->setPosition(20, 25); + } + else { + systemConsole->setFontSize(systemFont->getWidth() * 0.85f, systemFont->getHeight()); + systemConsole->setPosition(20, 50); + } + systemConsole->setHeight(25); + systemConsole->setVisible(false); + systemConsole->setOutput(3); + JUTSetReportConsole(systemConsole); + JUTSetWarningConsole(systemConsole); + + void* buf = systemHeap->alloc(CSetUpParam::exConsoleBufferSize, 4); + JUTException::createConsole(buf, CSetUpParam::exConsoleBufferSize); + + return; }