diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index f865c62f4..0594a1770 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -10,8 +10,10 @@ struct TLinkListNode { mPrev = NULL; } - TLinkListNode* getNext() { return mNext; } + TLinkListNode* getNext() const { return mNext; } + TLinkListNode* getPrev() const { return mPrev; } +public: /* 0x0 */ TLinkListNode* mNext; /* 0x4 */ TLinkListNode* mPrev; }; // Size: 0x8 @@ -24,6 +26,17 @@ struct TNodeLinkList { return node != NULL; } + iterator& operator++() { + node = node->getNext(); + return *this; + } + iterator& operator--() { + node = node->getPrev(); + return *this; + } + bool operator==(const iterator& o) { return o.node == node; } + bool operator!=(const iterator& o) { return !(*this == o); } + TLinkListNode* node; }; @@ -34,6 +47,17 @@ struct TNodeLinkList { return node != NULL; } + const_iterator& operator++() { + node = node->getNext(); + return *this; + } + const_iterator& operator--() { + node = node->getPrev(); + return *this; + } + bool operator==(const const_iterator& o) { return o.node == node; } + bool operator!=(const const_iterator& o) { return !(*this == o); } + TLinkListNode* node; }; @@ -45,18 +69,23 @@ struct TNodeLinkList { ocObject_.mPrev = &ocObject_; } - iterator end() { - iterator iter(&ocObject_); + iterator begin() { + iterator iter(ocObject_.getNext()); return iter; } - iterator begin() { - iterator iter(ocObject_.mNext); + iterator end() { + iterator iter(ocObject_.getPrev()); return iter; } const_iterator begin() const { - const_iterator iter(ocObject_.mNext); + const_iterator iter(ocObject_.getNext()); + return iter; + } + + const_iterator end() const { + const_iterator iter(ocObject_.getPrev()); return iter; } @@ -69,8 +98,9 @@ struct TNodeLinkList { iterator Insert(JGadget::TNodeLinkList::iterator, JGadget::TLinkListNode*); iterator Erase(JGadget::TLinkListNode*); void Remove(JGadget::TLinkListNode*); + u32 size() { return count; } - /* 0x00 */ int count; + /* 0x00 */ u32 count; /* 0x04 */ TLinkListNode ocObject_; }; // Size: 0xC @@ -78,20 +108,51 @@ template struct TLinkList : public TNodeLinkList { TLinkList() : TNodeLinkList() {} + static TLinkListNode* Element_toNode(T* element) { return static_cast(element); } + static T* Element_toValue(TLinkListNode* node) { return static_cast(node); } + struct iterator : TNodeLinkList::iterator { iterator(TNodeLinkList::iterator iter) : TNodeLinkList::iterator(iter) {} + iterator(const iterator& o) : TNodeLinkList::iterator(o) {} + + iterator& operator++() { + iterator it(TNodeLinkList::iterator::operator++()); + return it; + } + iterator& operator--() { + iterator it(TNodeLinkList::iterator::operator--()); + return it; + } + + T* operator*() { + return Element_toValue(node); + } + T* operator->() { + return Element_toValue(node); + } }; struct const_iterator : TNodeLinkList::const_iterator { const_iterator(TNodeLinkList::const_iterator iter) : TNodeLinkList::const_iterator(iter) {} + const_iterator(const const_iterator& o) : TNodeLinkList::const_iterator(o) {} + const_iterator& operator++() { - node = node->getNext(); - return *this; + const_iterator it(TNodeLinkList::const_iterator::operator++()); + return it; + } + const_iterator& operator--() { + const_iterator it(TNodeLinkList::const_iterator::operator--()); + return it; + } + + T* operator*() { + return Element_toValue(node); + } + T* operator->() { + return Element_toValue(node); } }; - TLinkListNode* Element_toNode(T* element) const { return &element->ocObject_; } - void Insert(TLinkList::iterator iter, T* element) { TLinkListNode* node = Element_toNode(element); TNodeLinkList::Insert(iter, node); @@ -102,14 +163,14 @@ struct TLinkList : public TNodeLinkList { return ((TNodeLinkList*)this)->Erase(node); } - TLinkList::iterator end() { - TNodeLinkList::iterator node_iter = TNodeLinkList::end(); + TLinkList::iterator begin() { + TNodeLinkList::iterator node_iter = TNodeLinkList::begin(); TLinkList::iterator iter(node_iter); return iter; } - TLinkList::iterator begin() { - TNodeLinkList::iterator node_iter = TNodeLinkList::begin(); + TLinkList::iterator end() { + TNodeLinkList::iterator node_iter = TNodeLinkList::end(); TLinkList::iterator iter(node_iter); return iter; } @@ -120,10 +181,27 @@ struct TLinkList : public TNodeLinkList { return iter; } + TLinkList::const_iterator end() const { + TNodeLinkList::const_iterator node_iter = TNodeLinkList::end(); + TLinkList::const_iterator iter(node_iter); + return iter; + } + void Push_back(T* element) { TLinkList::iterator iter(TLinkList::end()); this->Insert(iter, element); } + + T* front() { + TLinkList::iterator iter(TLinkList::begin()); + return *iter; + } + + T* back() { + TLinkList::iterator iter(TLinkList::end()); + --iter; + return *iter; + } }; template diff --git a/include/JSystem/JUtility/JUTConsole.h b/include/JSystem/JUtility/JUTConsole.h index 5be1e6f47..4672e504a 100644 --- a/include/JSystem/JUtility/JUTConsole.h +++ b/include/JSystem/JUtility/JUTConsole.h @@ -7,7 +7,7 @@ #include "Runtime.PPCEABI.H/__va_arg.h" #include "dolphin/types.h" -class JUTConsole : public JKRDisposer { +class JUTConsole : public JKRDisposer, public JGadget::TLinkListNode { public: enum EConsoleType { ACTIVE = 0, @@ -89,9 +89,6 @@ public: void scrollToLastLine() { scroll(mMaxLines); } void scrollToFirstLine() { scroll(-mMaxLines); } -public: - /* 0x18 */ JGadget::TLinkListNode mListNode; - private: /* 0x20 */ u32 field_0x20; /* 0x24 */ s32 mMaxLines; @@ -133,7 +130,7 @@ public: static JUTConsoleManager* sManager; private: - /* 0x00 */ JGadget::TLinkList mLinkList; + /* 0x00 */ JGadget::TLinkList soLink_; /* 0x0C */ JUTConsole* mActiveConsole; /* 0x10 */ JUTConsole* mDirectConsole; }; // Size: 0x14 diff --git a/src/JSystem/JUtility/JUTConsole.cpp b/src/JSystem/JUtility/JUTConsole.cpp index 618716b36..5548ace77 100644 --- a/src/JSystem/JUtility/JUTConsole.cpp +++ b/src/JSystem/JUtility/JUTConsole.cpp @@ -368,13 +368,34 @@ void JUTConsoleManager::appendConsole(JUTConsole* console) { JUT_ASSERT(0x3bf, sManager != 0 && console != 0); // need to figure out how TLinkList works - JGadget::TLinkListNode node = console->mListNode; - mLinkList.Find(&node); + JUT_ASSERT(0x3c2, soLink_.Find( console ) == soLink_.end()); + + soLink_.Push_back(console); + + if (mActiveConsole == NULL) + mActiveConsole = console; } /* 802CB4C4-802CB674 .text removeConsole__17JUTConsoleManagerFP10JUTConsole */ void JUTConsoleManager::removeConsole(JUTConsole* console) { /* Nonmatching */ + JUT_ASSERT(0x3d6, sManager != 0 && console != 0); + JUT_ASSERT(0x3d9, soLink_.Find( console ) != soLink_.end()); + + if (mActiveConsole == console) { + if (soLink_.size() <= 1) { + mActiveConsole = NULL; + } else { + mActiveConsole = console != soLink_.back() ? soLink_.Element_toValue(console->getNext()) : soLink_.front(); + } + } + + if (JUTGetWarningConsole() == console) + JUTSetWarningConsole(NULL); + if (JUTGetReportConsole() == console) + JUTSetReportConsole(NULL); + + soLink_.Remove(console); } /* 802CB674-802CB740 .text draw__17JUTConsoleManagerCFv */ @@ -382,8 +403,10 @@ void JUTConsoleManager::draw() const { /* Nonmatching */ // need to figure out how TLinkList works - for (JGadget::TLinkList::const_iterator iter = mLinkList.begin(); iter; ++iter) { - const JUTConsole * pConsole = (const JUTConsole*) (&iter.node - offsetof(JUTConsole, mListNode)); + JGadget::TLinkList::const_iterator iter = soLink_.begin(); + JGadget::TLinkList::const_iterator end = soLink_.end(); + for (; iter != end; ++iter) { + JUTConsole* pConsole = *iter; if (pConsole != mActiveConsole) pConsole->doDraw(JUTConsole::INACTIVE); }