diff --git a/include/JSystem/JGadget/binary.h b/include/JSystem/JGadget/binary.h index 61a949fa8..88fbed304 100644 --- a/include/JSystem/JGadget/binary.h +++ b/include/JSystem/JGadget/binary.h @@ -30,10 +30,6 @@ template struct TParseData_aligned : public TParseData { TParseData_aligned(const void* pContent) : TParseData(pContent) {} void setRaw(const void* p) { - /* if ((u32)p % T != 0) { - JUTWarn w; - w << "misaligned : " << (u32)p; - } */ static_cast(this)->setRaw(p); } }; diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index 189a95a51..01e465fae 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -183,6 +183,10 @@ struct TLinkList_factory : public TLinkList { virtual ~TLinkList_factory() {} virtual T* Do_create() = 0; virtual void Do_destroy(T*) = 0; + void Erase_destroy(T* elem) { + Erase(elem); + Do_destroy(elem); + } }; template diff --git a/include/JSystem/JMessage/control.h b/include/JSystem/JMessage/control.h index f24c1556f..764858c96 100644 --- a/include/JSystem/JMessage/control.h +++ b/include/JSystem/JMessage/control.h @@ -36,11 +36,11 @@ struct TControl { void getResource_groupID(u16) const; void getMessageData(u16, u16) const; - void do_word(u32); + bool do_word(u32); void reset_(); - /* 0x04 */ void* _04; - /* 0x08 */ void* _08; + /* 0x04 */ TResourceContainer* mResourceContainer; + /* 0x08 */ void* mResource; /* 0x0C */ TSequenceProcessor* mBaseProcSeq; /* 0x10 */ TRenderingProcessor* mBaseProcRender; /* 0x14 */ u16 mMessageCode; diff --git a/include/JSystem/JMessage/data.h b/include/JSystem/JMessage/data.h index 04d2634e7..fb5cade33 100644 --- a/include/JSystem/JMessage/data.h +++ b/include/JSystem/JMessage/data.h @@ -1,9 +1,59 @@ #ifndef JMESSAGE_DATA_H #define JMESSAGE_DATA_H +#include "JSystem/JGadget/binary.h" +#include "JSystem/JUtility/JUTDataHeader.h" + namespace JMessage { namespace data { extern const int ga4cSignature; + +struct TParse_THeader : public JGadget::binary::TParseData_aligned<4> { + TParse_THeader(const void* data) : TParseData_aligned(data) {} + + char* get() const { return (char*)getRaw(); } + const void* getContent() const { return (char*)getRaw() + 0x20; } + + u32* get_signature() const { return (u32*)(get() + 0x0); } + u32 get_type() const { return *(u32*)(get() + 0x4); } + u32 get_blockNumber() const { return *(u32*)(get() + 0xC); } + u8 get_encoding() const { return *(u8*)(get() + 0x10); } +}; + +struct TParse_TBlock : public JGadget::binary::TParseData_aligned<4> { + TParse_TBlock(const void* data) : TParseData_aligned(data) {} +}; + +struct JUTMesgInfo { +public: + /* 0x00 */ JUTDataBlockHeader header; + /* 0x08 */ u16 messageEntrySize; + /* 0x0A */ u16 messageEntryNumber; + /* 0x0C */ u16 groupID; + /* 0x0E */ u8 defaultColor; + /* 0x0F */ u8 reserved; +}; + +struct TParse_TBlock_info : public TParse_TBlock { + TParse_TBlock_info(const void* data) : TParse_TBlock(data) {} + + JUTMesgInfo* get() const { return (JUTMesgInfo*)getRaw(); } + char* getContent() const { return (char*)&get()[1]; } + + u16 get_messageEntrySize() const { return get()->messageEntrySize; } + u16 get_messageEntryNumber() const { return get()->messageEntryNumber; } + u16 get_groupID() const { return get()->groupID; } +}; + +struct JUTMesgIDData { +public: + /* 0x00 */ JUTDataBlockHeader mHeader; + /* 0x08 */ u16 numEntries; + /* 0x0A */ u8 format; + /* 0x0B */ u8 info; + /* 0x0C */ u8 reserved[4]; +}; + } // namespace data } // namespace JMessage diff --git a/include/JSystem/JMessage/processor.h b/include/JSystem/JMessage/processor.h index a4c33a367..ac202c114 100644 --- a/include/JSystem/JMessage/processor.h +++ b/include/JSystem/JMessage/processor.h @@ -11,56 +11,46 @@ struct TControl; struct TResource; struct TProcessor { - typedef bool (*OnCharacterEndCallBack)(TProcessor*); +public: + TProcessor(TControl *control) : mControl(control), mCurrent(NULL) {} + + typedef bool (*ProcessorCallBack)(TProcessor*); typedef const char* (*OnSelectBeginCallBack)(TProcessor*); typedef const char* (*ProcessOnSelectCallBack)(TProcessor*); struct TStack_ { TStack_() { clear(); } - TStack_(const TStack_& other) - { - mSize = other.mSize; - for (int i = 0; i < mSize; i++) { + TStack_(const TStack_& other) { + for (int i = 0; i < mNum; i++) { mStack[i] = mStack[i]; } + mNum = other.mNum; } - inline bool empty() const { return mSize == 0; } - inline bool isPushable() const { return mSize < 4; } - inline void clear() { mSize = 0; } - - inline u32 getMaxSize() const { return 4; } - inline u32 getSize() const { return mSize; } - inline const char* getTop() const { return mStack[mSize - 1]; } - - inline void push(const char* str) - { - mStack[mSize] = str; - mSize++; + inline void clear() { mNum = 0; } + inline void push(const char* str) { + mStack[mNum - 1] = str; + mNum++; } + inline bool IsStorable() const { return mNum < 4; } + inline void pop() { mNum--; } + inline const char* top() const { return mStack[mNum - 2]; } + inline bool empty() const { return mNum == 0; } - inline void pop() { mSize--; } - - /* 0x00 */ u32 mSize; - /* 0x04 */ const char* mStack[3]; + /* 0x00 */ const char* mStack[3]; + /* 0x0C */ u32 mNum; }; + // XXX: None of this shows up in the debug map. Is this TStatusData? struct TProcess { - struct TProcessData { - /* 0x00 */ ProcessOnSelectCallBack mSelectCallback; - /* 0x04 */ const char* mBase; - /* 0x08 */ const void* mOffset; - /* 0x0C */ u32 mRest; - }; - TProcess() { reset_normal(); } - void reset_normal() { mEndCallback = process_onCharacterEnd_normal_; } - void reset_select() { mEndCallback = process_onCharacterEnd_select_; } + void reset_normal() { mCallBack = process_onCharacterEnd_normal_; } + void reset_select() { mCallBack = process_onCharacterEnd_select_; } - /* 0x00 */ OnCharacterEndCallBack mEndCallback; - /* 0x04 */ TProcessData mData; + /* 0x00 */ ProcessorCallBack mCallBack; + /* 0x04 */ void* mCallBackWork[4]; }; ~TProcessor(); @@ -90,36 +80,25 @@ struct TProcessor { static const char* process_onSelect_(TProcessor*); void reset_(const char*); - void process_select_limited_(TProcessor*); - void process_select_(TProcessor*); + static const char* process_select_limited_(TProcessor*); + static const char* process_select_(TProcessor*); - int setBegin_messageEntryText(const TResource* resource, const void* entry, const char* param_2) - { - // mResourceCache = resource; - reset_(param_2); - do_begin_(entry, param_2); - return TRUE; - } - - const TResource* getResourceCache() const { return mResourceCache; } - const char* getCurrent() const { return mCurrent; } - const TReference* getReference() const { return mReference; } - - // Unused/inlined: void pushCurrent(const char*); const char* popCurrent(); void on_select_begin(OnSelectBeginCallBack, const void*, const char*, u32); void on_select_end(); void on_select_separate(); void on_tag_(); - void process_character_(); + bool process_character_(); + + const char* getCurrent() const { return mCurrent; } /* 0x00 */ /* vtable */ - /* 0x04 */ const TReference* mReference; - /* 0x08 */ const TResource* mResourceCache; - /* 0x0C */ const char* mCurrent; - /* 0x10 */ TStack_ mStack; - /* 0x24 */ TProcess mProcess; + /* 0x04 */ TControl* mControl; + /* 0x08 */ const char* mCurrent; + /* 0x0C */ void* field_0x0C; + /* 0x0C */ TStack_ mStack; + /* 0x20 */ TProcess mProcess; }; struct TSequenceProcessor : public TProcessor { @@ -130,38 +109,32 @@ struct TSequenceProcessor : public TProcessor { TSequenceProcessor(const TReference*, TControl*); TSequenceProcessor(TControl*); - virtual ~TSequenceProcessor(); // _08 - virtual void do_reset_(const char*); // _28 - virtual bool do_setBegin_isReady_() const; // _2C - virtual void do_begin_(const void*, const char*); // _30 - virtual void do_end_(); // _34 - virtual bool do_tag_(u32, const void*, u32); // _38 - virtual void do_systemTagCode_(u16, const void*, u32); // _3C - virtual void do_begin(const void*, const char*); // _40 - virtual void do_end(); // _44 - virtual bool do_isReady(); // _48 - virtual bool do_jump_isReady(); // _4C - virtual void do_jump(const void*, const char*); // _50 - virtual void do_branch_query(u16); // _54 - virtual int do_branch_queryResult(); // _58 - virtual void do_branch(const void*, const char*); // _5C + /* 0x08 */ virtual ~TSequenceProcessor(); + /* 0x30 */ virtual void do_begin_(const void*, const char*); + /* 0x34 */ virtual void do_end_(); + /* 0x38 */ virtual bool do_tag_(u32, const void*, u32); + /* 0x3C */ virtual void do_systemTagCode_(u16, const void*, u32); + /* 0x40 */ virtual void do_begin(const void*, const char*); + /* 0x44 */ virtual void do_end(); + /* 0x48 */ virtual bool do_isReady(); + /* 0x4C */ virtual bool do_jump_isReady(); + /* 0x50 */ virtual void do_jump(const void*, const char*); + /* 0x54 */ virtual void do_branch_query(u16); + /* 0x58 */ virtual int do_branch_queryResult(); + /* 0x5C */ virtual void do_branch(const void*, const char*); char* process(const char*); bool on_isReady(); - void on_jump_isReady(); + bool on_jump_isReady(); void on_jump(const void*, const char*); - void on_branch_queryResult(); + int on_branch_queryResult(); void on_branch(const void*, const char*); - void process_onJump_limited_(const TSequenceProcessor*); - static void* process_onJump_(const TSequenceProcessor*); - void process_onBranch_limited_(const TSequenceProcessor*, u32); - void process_onBranch_(const TSequenceProcessor*, u32); void reset_(const char*); - void process_jump_limited_(TSequenceProcessor*); - void process_jump_(TSequenceProcessor*); - void process_branch_limited_(TSequenceProcessor*, u32); - void process_branch_(TSequenceProcessor*, u32); + static bool process_jump_limited_(TSequenceProcessor*); + static bool process_jump_(TSequenceProcessor*); + static bool process_branch_limited_(TSequenceProcessor*, u32); + static bool process_branch_(TSequenceProcessor*, u32); // Unused/inlined: const char* toString_status(int); @@ -179,17 +152,18 @@ struct TSequenceProcessor : public TProcessor { } /* 0x00 */ /* TProcessor */ - /* 0x38 */ TControl* _38; - /* 0x3C */ int _3C; - /* 0x40 */ ProcessOnJumpCallBack* _40; - /* 0x44 */ u32 _44; - /* 0x48 */ u32 _48; + /* 0x34 */ int mStatus; }; struct TRenderingProcessor : public TProcessor { TRenderingProcessor(const TReference*); TRenderingProcessor(TControl*); + void setBegin(const void* param_1, const char* param_2) { + reset_(param_2); + do_begin_(param_1, param_2); + } + virtual void do_begin_(const void*, const char*); virtual void do_end_(); virtual bool do_tag_(u32, const void*, u32); @@ -197,7 +171,7 @@ struct TRenderingProcessor : public TProcessor { virtual ~TRenderingProcessor(); virtual void do_begin(const void*, const char*); virtual void do_end(); - + void process(const char*); /* 0x00 */ /* TProcessor */ diff --git a/include/JSystem/JMessage/resource.h b/include/JSystem/JMessage/resource.h index b68acba15..8a8fe8249 100644 --- a/include/JSystem/JMessage/resource.h +++ b/include/JSystem/JMessage/resource.h @@ -1,53 +1,70 @@ #ifndef RESOURCE_H #define RESOURCE_H -#include +#include "JSystem/JGadget/binary.h" +#include "JSystem/JGadget/linklist.h" +#include "JSystem/JMessage/data.h" +#include "JSystem/JUtility/JUTDataHeader.h" namespace JMessage { + namespace data { + struct JUTMesgInfo; + struct JUTMesgIDData; + }; + class TResource { public: - TResource() { - field_0x0 = 0; - field_0x4 = 0; - field_0x8 = 0; - field_0xc = 0; - field_0x10 = 0; - field_0x14 = 0; - field_0x18 = 0; + TResource() : mHeader(NULL), mInfo(NULL) { + mMessageData = NULL; + mStringAttribute = NULL; + mMessageID = NULL; } - int field_0x0; - int field_0x4; - int field_0x8; - int field_0xc; - int field_0x10; - int field_0x14; - int field_0x18; - }; - class TResourceContainer { - public: - int field_0x0; - int field_0x4; - int field_0x8; + void setData_header(const void* p) { mHeader.setRaw(p); } + void setData_block_info(const void* p) { mInfo.setRaw(p); } + void setData_block_messageData(const void* p) { mMessageData = (const char*)p; } + void setData_block_stringAttribute(const void* p) { mStringAttribute = (const char*)p; } + void setData_block_messageID(const void* p) { mMessageID = (data::JUTMesgIDData*)p; } + /* 0x00 */ JGadget::TLinkListNode mLinkNode; + /* 0x08 */ data::TParse_THeader mHeader; + /* 0x0C */ data::TParse_TBlock_info mInfo; + /* 0x10 */ const char* mMessageData; + /* 0x14 */ const char* mStringAttribute; + /* 0x18 */ data::JUTMesgIDData* mMessageID; + }; + + class TResourceContainer : public JGadget::TLinkList_factory { + public: TResourceContainer(); - virtual ~TResourceContainer(); - void Get_groupID(u16); - void SetEncoding(u8); virtual TResource* Do_create(); virtual void Do_destroy(JMessage::TResource*); + + TResource* Get_groupID(u16 groupID); + void SetEncoding(u8); + + bool IsEncodingSettable(u8 encoding) const { + return mEncoding == encoding || encoding == 0; + } + + private: void SetEncoding_(u8); - u8 field_0x10; - bool (*field_0x14)(int); + private: + /* 0x10 */ u8 mEncoding; + /* 0x14 */ bool (*mIsLeadByteFunc)(int); }; - class TParse { + class TParse : public JGadget::binary::TParse_header_block { public: TParse(JMessage::TResourceContainer*); virtual ~TParse(); - virtual void parseHeader_next(const void**, u32*, u32); - virtual void parseBlock_next(const void**, u32*, u32); + virtual bool parseHeader_next(const void**, u32*, u32); + virtual bool parseBlock_next(const void**, u32*, u32); + + public: + /* 0x04 */ TResourceContainer* mResourceContainer; + /* 0x08 */ TResource* mResource; }; } diff --git a/src/JSystem/JMessage/control.cpp b/src/JSystem/JMessage/control.cpp index 710df8078..1cc7ad13a 100644 --- a/src/JSystem/JMessage/control.cpp +++ b/src/JSystem/JMessage/control.cpp @@ -8,15 +8,15 @@ /* 8029E930-8029E970 .text __ct__Q28JMessage8TControlFv */ JMessage::TControl::TControl() - : _04(NULL) - , _08(NULL) + : mResourceContainer(NULL) + , mResource(NULL) , mBaseProcSeq(NULL) , mBaseProcRender(NULL) , mMessageCode(0) , mMessageIndex(0) , mResourceCache(NULL) - , mEntry(NULL) , mMessageBegin(NULL) + , _20(NULL) , mCurrentText(NULL) { /* Nonmatching */ @@ -50,7 +50,6 @@ void JMessage::TControl::reset() { /* 8029EB1C-8029EC00 .text update__Q28JMessage8TControlFv */ bool JMessage::TControl::update() { - /* Nonmatching */ if (!isReady_update_()) { return false; } @@ -66,6 +65,7 @@ bool JMessage::TControl::update() { mMessageBegin = NULL; return false; } + return true; } @@ -76,15 +76,15 @@ void JMessage::TControl::render() { return; } - mBaseProcRender->setBegin_messageEntryText(mResourceCache, mEntry, _20); - mBaseProcRender->mCurrent = _20; + mBaseProcRender->setBegin(mResourceCache, _20); + mBaseProcRender->field_0x0C = mEntry; mBaseProcRender->mStack = mRenderStack; mBaseProcRender->process(mCurrentText); } /* 8029ECCC-8029ECD4 .text do_word__Q28JMessage8TControlFUl */ -void JMessage::TControl::do_word(u32) { - /* Nonmatching */ +bool JMessage::TControl::do_word(u32) { + return false; } /* 8029ECD4-8029ED88 .text setMessageCode_flush___Q28JMessage8TControlFv */ @@ -94,5 +94,9 @@ bool JMessage::TControl::setMessageCode_flush_() { /* 8029ED88-8029EDA4 .text reset___Q28JMessage8TControlFv */ void JMessage::TControl::reset_() { - /* Nonmatching */ + mResourceCache = NULL; + mMessageBegin = NULL; + _20 = NULL; + mCurrentText = NULL; + mRenderStack.clear(); } diff --git a/src/JSystem/JMessage/processor.cpp b/src/JSystem/JMessage/processor.cpp index fbba4fcec..5269317ca 100644 --- a/src/JSystem/JMessage/processor.cpp +++ b/src/JSystem/JMessage/processor.cpp @@ -4,14 +4,14 @@ // #include "JSystem/JMessage/processor.h" -#include "dolphin/types.h" +#include "JSystem/JMessage/control.h" namespace JMessage { namespace { /* 8029EDA4-8029EDCC .text process_setMessageIndex_reserved___Q28JMessage23@unnamed@processor_cpp@FUs */ -void process_setMessageIndex_reserved_(u16) { +bool process_setMessageIndex_reserved_(u16 messageIndex) { /* Nonmatching */ } @@ -28,27 +28,60 @@ void process_setMessage_code_(TControl*, u32) { }; // namespace /* 8029EE6C-8029EEA4 .text pushCurrent__Q28JMessage10TProcessorFPCc */ -void TProcessor::pushCurrent(const char*) { - /* Nonmatching */ +void TProcessor::pushCurrent(const char* v) { + if (v == NULL) + return; + + if (!mStack.IsStorable()) + return; + + mStack.push(mCurrent); + mCurrent = v; } /* 8029EEA4-8029EEC8 .text popCurrent__Q28JMessage10TProcessorFv */ const char* TProcessor::popCurrent() { - /* Nonmatching */ + mCurrent = mStack.top(); + mStack.pop(); } +struct SelectCallbackWork { + /* 0x00 */ TProcessor::OnSelectBeginCallBack mCallBack; + /* 0x04 */ const char* mBase; + /* 0x08 */ const void* mOffset; + /* 0x0C */ u32 mRest; +}; + /* 8029EEC8-8029EF54 .text on_select_begin__Q28JMessage10TProcessorFPFPQ28JMessage10TProcessor_PCcPCvPCcUl */ -void TProcessor::on_select_begin(OnSelectBeginCallBack, const void*, const char*, u32) { /* Nonmatching */ +void TProcessor::on_select_begin(OnSelectBeginCallBack callback, const void* offs, const char* base, u32 rest) { + if (mStack.IsStorable()) { + mProcess.reset_select(); + SelectCallbackWork* work = (SelectCallbackWork*)&mProcess.mCallBackWork; + work->mCallBack = callback; + work->mBase = base; + work->mOffset = offs; + work->mRest = rest; + + const char *v = work->mCallBack(this); + pushCurrent(v); + do_select_begin(rest); + } } /* 8029EF54-8029EFA0 .text on_select_end__Q28JMessage10TProcessorFv */ void TProcessor::on_select_end() { - /* Nonmatching */ + mProcess.reset_normal(); + popCurrent(); + do_select_end(); } /* 8029EFA0-8029EFFC .text on_select_separate__Q28JMessage10TProcessorFv */ void TProcessor::on_select_separate() { - /* Nonmatching */ + popCurrent(); + SelectCallbackWork* work = (SelectCallbackWork*)&mProcess.mCallBackWork; + const char *v = work->mCallBack(this); + pushCurrent(v); + do_select_separate(); } /* 8029EFFC-8029F000 .text do_character__Q28JMessage10TProcessorFi */ @@ -82,13 +115,25 @@ TProcessor::~TProcessor() { } /* 8029F064-8029F080 .text reset___Q28JMessage10TProcessorFPCc */ -void TProcessor::reset_(const char*) { - /* Nonmatching */ +void TProcessor::reset_(const char* v) { + mCurrent = v; + mStack.clear(); + mProcess.reset_normal(); } /* 8029F080-8029F120 .text on_tag___Q28JMessage10TProcessorFv */ void TProcessor::on_tag_() { - /* Nonmatching */ + u32 size; + const u8* current = (const u8*)getCurrent(); + size = current[1]; + + mCurrent = (const char*)current + size; + u32 tag = (current[2] << 16 | current[3] << 8); + tag |= current[4]; + + if (!do_tag(tag, ¤t[5], size - 5)) { + do_tag_(tag, ¤t[5], size - 5); + } } /* 8029F120-8029F248 .text do_tag___Q28JMessage10TProcessorFUlPCvUl */ @@ -102,33 +147,68 @@ void TProcessor::do_systemTagCode_(u16, const void*, u32) { } /* 8029F2A0-8029F37C .text process_character___Q28JMessage10TProcessorFv */ -void TProcessor::process_character_() { +bool TProcessor::process_character_() { /* Nonmatching */ + const char * current = getCurrent(); + switch (current[0]) { + case 0: + if (!mProcess.mCallBack(this)) + return false; + break; + case 0x1A: + on_tag_(); + break; + default: + // mControl->do_word(current[0]); + break; + } + return true; } /* 8029F37C-8029F3C4 .text process_onCharacterEnd_normal___Q28JMessage10TProcessorFPQ28JMessage10TProcessor */ -bool TProcessor::process_onCharacterEnd_normal_(TProcessor*) { - /* Nonmatching */ +bool TProcessor::process_onCharacterEnd_normal_(TProcessor* proc) { + if (!proc->mStack.empty()) { + proc->popCurrent(); + return true; + } else { + proc->do_end_(); + return false; + } } /* 8029F3C4-8029F40C .text process_onCharacterEnd_select___Q28JMessage10TProcessorFPQ28JMessage10TProcessor */ -bool TProcessor::process_onCharacterEnd_select_(TProcessor*) { - /* Nonmatching */ +bool TProcessor::process_onCharacterEnd_select_(TProcessor* proc) { + SelectCallbackWork* work = (SelectCallbackWork*) &proc->mProcess.mCallBackWork; + work->mRest--; + if (work->mRest != 0) { + proc->on_select_separate(); + return true; + } else { + proc->on_select_end(); + return true; + } } /* 8029F40C-8029F428 .text process_select_limited___Q28JMessage10TProcessorFPQ28JMessage10TProcessor */ -void TProcessor::process_select_limited_(TProcessor*) { - /* Nonmatching */ +const char* TProcessor::process_select_limited_(TProcessor* proc) { + SelectCallbackWork* work = (SelectCallbackWork*) &proc->mProcess.mCallBackWork; + u16 offs = ((const u16*)work->mOffset)[0]; + work->mOffset = (const char*)work->mOffset + sizeof(offs); + return &work->mBase[offs]; } /* 8029F428-8029F444 .text process_select___Q28JMessage10TProcessorFPQ28JMessage10TProcessor */ -void TProcessor::process_select_(TProcessor*) { +const char* TProcessor::process_select_(TProcessor* proc) { /* Nonmatching */ + SelectCallbackWork* work = (SelectCallbackWork*) &proc->mProcess.mCallBackWork; + u32 offs = ((const u32*)work->mOffset)[0]; + work->mOffset = (const char*)work->mOffset + sizeof(offs); + return &work->mBase[offs]; } /* 8029F444-8029F480 .text __ct__Q28JMessage18TSequenceProcessorFPQ28JMessage8TControl */ -TSequenceProcessor::TSequenceProcessor(TControl*) { - /* Nonmatching */ +TSequenceProcessor::TSequenceProcessor(TControl* control) : TProcessor(control) { + mStatus = 0; } /* 8029F480-8029F4E0 .text __dt__Q28JMessage18TSequenceProcessorFv */ @@ -142,37 +222,54 @@ char* TSequenceProcessor::process(const char*) { /* 8029F658-8029F684 .text on_isReady__Q28JMessage18TSequenceProcessorFv */ bool TSequenceProcessor::on_isReady() { - /* Nonmatching */ + return do_isReady(); } +struct JumpCallbackWork { + /* 0x00 */ u32 mTarget; +}; + /* 8029F684-8029F698 .text on_jump_register__Q28JMessage18TSequenceProcessorFPFPQ28JMessage18TSequenceProcessor_bUl */ -void TSequenceProcessor::on_jump_register(OnJumpRegisterCallBack*, u32) { - /* Nonmatching */ +void TSequenceProcessor::on_jump_register(OnJumpRegisterCallBack callback, u32 target) { + mStatus = 3; + mProcess.mCallBack = (ProcessorCallBack)callback; + JumpCallbackWork* work = (JumpCallbackWork*) &mProcess.mCallBackWork; + work->mTarget = target; } /* 8029F698-8029F6C4 .text on_jump_isReady__Q28JMessage18TSequenceProcessorFv */ -void TSequenceProcessor::on_jump_isReady() { - /* Nonmatching */ +bool TSequenceProcessor::on_jump_isReady() { + return do_jump_isReady(); } /* 8029F6C4-8029F720 .text on_jump__Q28JMessage18TSequenceProcessorFPCvPCc */ -void TSequenceProcessor::on_jump(const void*, const char*) { - /* Nonmatching */ +void TSequenceProcessor::on_jump(const void* target, const char* v) { + reset_(v); + do_jump(target, v); } +struct BranchCallbackWork { + /* 0x00 */ const void* mOffset; + /* 0x04 */ u32 mRest; +}; + /* 8029F720-8029F730 .text on_branch_register__Q28JMessage18TSequenceProcessorFPFPQ28JMessage18TSequenceProcessorUl_bPCvUl */ -void TSequenceProcessor::on_branch_register(OnBranchRegisterCallBack*, const void*, u32) { - /* Nonmatching */ +void TSequenceProcessor::on_branch_register(OnBranchRegisterCallBack callback, const void* offset, u32 rest) { + mProcess.mCallBack = (ProcessorCallBack)callback; + BranchCallbackWork* work = (BranchCallbackWork*) &mProcess.mCallBackWork; + work->mOffset = offset; + work->mRest = rest; } /* 8029F730-8029F764 .text on_branch_query__Q28JMessage18TSequenceProcessorFUs */ -void TSequenceProcessor::on_branch_query(u16) { - /* Nonmatching */ +void TSequenceProcessor::on_branch_query(u16 branch) { + mStatus = 4; + do_branch_query(branch); } /* 8029F764-8029F790 .text on_branch_queryResult__Q28JMessage18TSequenceProcessorFv */ -void TSequenceProcessor::on_branch_queryResult() { - /* Nonmatching */ +int TSequenceProcessor::on_branch_queryResult() { + return do_branch_queryResult(); } /* 8029F790-8029F7EC .text on_branch__Q28JMessage18TSequenceProcessorFPCvPCc */ @@ -240,9 +337,8 @@ void TSequenceProcessor::do_systemTagCode_(u16 p1, const void* p2, u32 p3) { /* Nonmatching */ switch (p1) { case 6: - _3C = 3; - _40 = &process_onJump_; - _44 = *(u32*)p2; + u32 v = *(u32*)p2; + on_jump_register(process_jump_, v); break; case 0: case 1: @@ -258,27 +354,27 @@ void TSequenceProcessor::do_systemTagCode_(u16 p1, const void* p2, u32 p3) { } /* 8029FA2C-8029FA5C .text process_jump_limited___Q28JMessage18TSequenceProcessorFPQ28JMessage18TSequenceProcessor */ -void TSequenceProcessor::process_jump_limited_(TSequenceProcessor*) { +bool TSequenceProcessor::process_jump_limited_(TSequenceProcessor*) { /* Nonmatching */ } /* 8029FA5C-8029FA88 .text process_jump___Q28JMessage18TSequenceProcessorFPQ28JMessage18TSequenceProcessor */ -void TSequenceProcessor::process_jump_(TSequenceProcessor*) { +bool TSequenceProcessor::process_jump_(TSequenceProcessor*) { /* Nonmatching */ } /* 8029FA88-8029FAB8 .text process_branch_limited___Q28JMessage18TSequenceProcessorFPQ28JMessage18TSequenceProcessorUl */ -void TSequenceProcessor::process_branch_limited_(TSequenceProcessor*, u32) { +bool TSequenceProcessor::process_branch_limited_(TSequenceProcessor*, u32) { /* Nonmatching */ } /* 8029FAB8-8029FAE8 .text process_branch___Q28JMessage18TSequenceProcessorFPQ28JMessage18TSequenceProcessorUl */ -void TSequenceProcessor::process_branch_(TSequenceProcessor*, u32) { +bool TSequenceProcessor::process_branch_(TSequenceProcessor*, u32) { /* Nonmatching */ } /* 8029FAE8-8029FB20 .text __ct__Q28JMessage19TRenderingProcessorFPQ28JMessage8TControl */ -TRenderingProcessor::TRenderingProcessor(TControl*) { +TRenderingProcessor::TRenderingProcessor(TControl* control) : TProcessor(control) { /* Nonmatching */ } diff --git a/src/JSystem/JMessage/resource.cpp b/src/JSystem/JMessage/resource.cpp index adeda9eb3..d5894880e 100644 --- a/src/JSystem/JMessage/resource.cpp +++ b/src/JSystem/JMessage/resource.cpp @@ -4,28 +4,34 @@ // #include "JSystem/JMessage/resource.h" +#include "JSystem/JMessage/data.h" #include "JSystem/JUtility/JUTResFont.h" #include "dolphin/types.h" /* 8029FCC4-8029FD04 .text __ct__Q28JMessage18TResourceContainerFv */ JMessage::TResourceContainer::TResourceContainer() { - /* Nonmatching */ - field_0x10 = 0; - field_0x14 = NULL; + mEncoding = 0; + mIsLeadByteFunc = NULL; } /* 8029FD04-8029FD90 .text Get_groupID__Q28JMessage18TResourceContainerFUs */ -void JMessage::TResourceContainer::Get_groupID(u16) { +JMessage::TResource* JMessage::TResourceContainer::Get_groupID(u16 groupID) { /* Nonmatching */ + for (iterator iter = begin(); iter != end(); ++iter) { + TResource* res = &(*iter); + if (res->mInfo.get_groupID() == groupID) + return res; + } + return NULL; } /* 8029FD90-8029FDC8 .text SetEncoding__Q28JMessage18TResourceContainerFUc */ -void JMessage::TResourceContainer::SetEncoding(u8 param_1) { - if (param_1 == 0) { - field_0x10 = param_1; - field_0x14 = 0; +void JMessage::TResourceContainer::SetEncoding(u8 encoding) { + if (encoding == 0) { + mEncoding = encoding; + mIsLeadByteFunc = NULL; } else { - SetEncoding_(param_1); + SetEncoding_(encoding); } } @@ -52,31 +58,86 @@ namespace JMessage { /* 8029FE38-8029FE68 .text SetEncoding___Q28JMessage18TResourceContainerFUc */ void JMessage::TResourceContainer::SetEncoding_(u8 param_1) { - field_0x10 = param_1; + mEncoding = param_1; u32 r4 = param_1; - field_0x14 = 0; + mIsLeadByteFunc = 0; if (r4 >= 4) { return; } - field_0x14 = gapfnIsLeadByte_[r4]; + mIsLeadByteFunc = gapfnIsLeadByte_[r4]; } /* 8029FE68-8029FE90 .text __ct__Q28JMessage6TParseFPQ28JMessage18TResourceContainer */ -JMessage::TParse::TParse(JMessage::TResourceContainer*) { - /* Nonmatching */ +JMessage::TParse::TParse(JMessage::TResourceContainer* container) : mResourceContainer(container), mResource(NULL) { } /* 8029FE90-8029FEF0 .text __dt__Q28JMessage6TParseFv */ JMessage::TParse::~TParse() { - /* Nonmatching */ } /* 8029FEF0-802A0024 .text parseHeader_next__Q28JMessage6TParseFPPCvPUlUl */ -void JMessage::TParse::parseHeader_next(const void**, u32*, u32) { +bool JMessage::TParse::parseHeader_next(const void** ppData, u32* pOutSize, u32 flag) { /* Nonmatching */ + const void* pData = *ppData; + data::TParse_THeader header(pData); + *ppData = header.getContent(); + *pOutSize = header.get_blockNumber(); + + if (memcmp(header.get_signature(), &data::ga4cSignature, sizeof(data::ga4cSignature)) != 0) + return false; + + if (header.get_type() != 'bmg1') + return false; + + u8 encoding = header.get_encoding(); + if (encoding != 0) { + if (!mResourceContainer->IsEncodingSettable(encoding)) + return false; + + mResourceContainer->SetEncoding(encoding); + } + + if (flag & 0x10) + return true; + + mResource = mResourceContainer->Do_create(); + if (mResource == NULL) + return flag & 0x20 ? true : false; + + mResource->setData_header(header.getRaw()); + mResourceContainer->Push_back(mResource); + return true; } /* 802A0024-802A0170 .text parseBlock_next__Q28JMessage6TParseFPPCvPUlUl */ -void JMessage::TParse::parseBlock_next(const void**, u32*, u32) { +bool JMessage::TParse::parseBlock_next(const void** ppData, u32* pOutSize, u32 flag) { /* Nonmatching */ + JUTDataBlockHeader* pHeader = *(JUTDataBlockHeader**)ppData; + *(char**)ppData += pHeader->mSize; + *pOutSize = pHeader->mSize; + + switch (pHeader->mType) { + case 'INF1': + mResource->setData_block_info(pHeader); + break; + case 'DAT1': + mResource->setData_block_messageData((char*)&pHeader[1]); + TResource* res = mResourceContainer->Get_groupID(mResource->mInfo.get_groupID()); + if (res != mResource && !!(flag & 0x80)) { + mResourceContainer->Erase_destroy(res); + } + break; + case 'STR1': + mResource->setData_block_stringAttribute((char*)&pHeader[1]); + break; + case 'MID1': + mResource->setData_block_messageID(pHeader); + break; + default: + if (!(flag & 0x40)) + return false; + break; + } + + return true; }