diff --git a/config/ShieldD/splits.txt b/config/ShieldD/splits.txt index 8bf1b4f9372..16628720537 100644 --- a/config/ShieldD/splits.txt +++ b/config/ShieldD/splits.txt @@ -4501,10 +4501,7 @@ PowerPC_EABI_Support/Runtime/Src/__va_arg.c: PowerPC_EABI_Support/Runtime/Src/global_destructor_chain.c: .text start:0x8061B5BC end:0x8061B61C - .sbss start:0x8074D698 end:0x8074D6A8 - -PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/errno.c: - .sbss start:0x8074D6A8 end:0x8074D6B0 + .sbss start:0x8074D698 end:0x8074D6A0 PowerPC_EABI_Support/Runtime/Src/NMWException.cp: extab start:0x800067C0 end:0x80006808 @@ -4537,8 +4534,12 @@ PowerPC_EABI_Support/Runtime/Src/GCN_mem_alloc.c: PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/alloc.c: .text start:0x8061C498 end:0x8061C9AC .rodata start:0x8065EF58 end:0x8065EF70 + .sbss start:0x8074D6A0 end:0x8074D6A8 .bss start:0x8080E550 end:0x8080E588 +PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/errno.c: + .sbss start:0x8074D6A8 end:0x8074D6B0 + PowerPC_EABI_Support/MSL/MSL_C/MSL_Common/Src/ansi_files.c: .text start:0x8061C9AC end:0x8061CABC .data start:0x8073E500 end:0x8073E640 diff --git a/configure.py b/configure.py index 50c0d9eb12d..dbbc4a4e1d1 100644 --- a/configure.py +++ b/configure.py @@ -241,10 +241,12 @@ cflags_runtime = [ "-str reuse,pool,readonly", "-gccinc", "-common off", - "-inline deferred,auto", "-char signed", ] +if config.version != "ShieldD": + cflags_runtime.extend(["-inline deferred,auto"]) + cflags_trk = [ *cflags_base, "-use_lmw_stmw on", @@ -277,7 +279,7 @@ cflags_framework = [ ] if config.version != "ShieldD": - cflags_framework.extend(["-O3,s", "-str reuse,pool,readonly"]) + cflags_framework.extend(["-O3,s", "-sym on", "-str reuse,pool,readonly"]) # REL flags cflags_rel = [ @@ -374,6 +376,7 @@ config.libs = [ Object(MatchingFor("GZ2E01"), "m_Do/m_Do_MemCard.cpp"), Object(MatchingFor("GZ2E01"), "m_Do/m_Do_MemCardRWmng.cpp"), Object(MatchingFor("GZ2E01"), "m_Do/m_Do_machine_exception.cpp"), + Object(NonMatching, "m_Do/m_Do_hostIO.cpp"), ], }, { @@ -937,6 +940,7 @@ config.libs = [ [ Object(MatchingFor("GZ2E01"), "JSystem/JSupport/JSUList.cpp"), Object(MatchingFor("GZ2E01"), "JSystem/JSupport/JSUInputStream.cpp"), + Object(NonMatching, "JSystem/JSupport/JSUOutputStream.cpp"), Object(MatchingFor("GZ2E01"), "JSystem/JSupport/JSUMemoryStream.cpp"), Object(MatchingFor("GZ2E01"), "JSystem/JSupport/JSUFileStream.cpp"), ], @@ -1053,6 +1057,23 @@ config.libs = [ Object(MatchingFor("GZ2E01"), "JSystem/JMath/JMATrigonometric.cpp"), ], ), + JSystemLib( + "JHostIO", + [ + Object(NonMatching, "JSystem/JHostIO/JHIComm.cpp"), + Object(NonMatching, "JSystem/JHostIO/JHICommonMem.cpp"), + Object(NonMatching, "JSystem/JHostIO/JORServer.cpp"), + Object(NonMatching, "JSystem/JHostIO/JOREntry.cpp"), + Object(NonMatching, "JSystem/JHostIO/JORFile.cpp"), + Object(NonMatching, "JSystem/JHostIO/JORMessageBox.cpp"), + Object(NonMatching, "JSystem/JHostIO/JORHostInfo.cpp"), + Object(NonMatching, "JSystem/JHostIO/JORShellExecute.cpp"), + Object(NonMatching, "JSystem/JHostIO/JHIMemBuf.cpp"), + Object(NonMatching, "JSystem/JHostIO/JHIhioASync.cpp"), + Object(NonMatching, "JSystem/JHostIO/JHIMccBuf.cpp"), + Object(NonMatching, "JSystem/JHostIO/JHIRMcc.cpp"), + ], + ), DolphinLib( "base", [ diff --git a/include/JSystem/JGadget/linklist.h b/include/JSystem/JGadget/linklist.h index 4fb6a627dfe..5d0575f0dbf 100644 --- a/include/JSystem/JGadget/linklist.h +++ b/include/JSystem/JGadget/linklist.h @@ -1,7 +1,7 @@ #ifndef LINKLIST_H #define LINKLIST_H -#include "dolphin/types.h" +#include "JSystem/JUtility/JUTAssert.h" namespace JGadget { struct TLinkListNode { @@ -10,6 +10,8 @@ struct TLinkListNode { mPrev = NULL; } + ~TLinkListNode() {} + TLinkListNode* getNext() const { return mNext; } TLinkListNode* getPrev() const { return mPrev; } @@ -177,21 +179,21 @@ struct TLinkList : public TNodeLinkList { /* 0x00 */ TNodeLinkList::const_iterator base; }; - static const TLinkListNode* Element_toNode(const T* element) { - (void)element; // Debug-only assert - return reinterpret_cast(reinterpret_cast(element) - I); + static TLinkListNode* Element_toNode(T* p) { + JUT_ASSERT(0x2F1, p!=0); + return reinterpret_cast(reinterpret_cast(p) - I); } - static TLinkListNode* Element_toNode(T* element) { - (void)element; // Debug-only assert - return reinterpret_cast(reinterpret_cast(element) - I); + static const TLinkListNode* Element_toNode(const T* p) { + JUT_ASSERT(0x2F6, p!=0); + return reinterpret_cast(reinterpret_cast(p) - I); } - static const T* Element_toValue(const TLinkListNode* node) { - (void)node; // Debug-only assert - return reinterpret_cast(reinterpret_cast(node) + I); + static T* Element_toValue(TLinkListNode* p) { + JUT_ASSERT(0x2FB, p!=0); + return reinterpret_cast(reinterpret_cast(p) + I); } - static T* Element_toValue(TLinkListNode* node) { - (void)node; // Debug-only assert - return reinterpret_cast(reinterpret_cast(node) + I); + static const T* Element_toValue(const TLinkListNode* p) { + JUT_ASSERT(0x300, p!=0); + return reinterpret_cast(reinterpret_cast(p) + I); } iterator Insert(iterator iter, T* element) { diff --git a/include/JSystem/JHostIO/JHIComm.h b/include/JSystem/JHostIO/JHIComm.h new file mode 100644 index 00000000000..30f57ff2de4 --- /dev/null +++ b/include/JSystem/JHostIO/JHIComm.h @@ -0,0 +1,100 @@ +#ifndef JHICOMM_H +#define JHICOMM_H + +#include "JSystem/JHostIO/JHICommonMem.h" + +class JHICommBufHeader { +public: + void init(); + void init(JHICommonMem*, u32, u32, u32); + int load(); + + u32 getMsgBufSize(); + + /* 0x00 */ JHICommonMem* mp_memBuffer; + /* 0x04 */ u32 field_0x4; + /* 0x08 */ u32 m_msgBufSize; + /* 0x0C */ u32 field_0xc; + /* 0x10 */ u32 field_0x10; + /* 0x14 */ u32 field_0x14; + /* 0x18 */ u32 field_0x18; + /* 0x1C */ u32 field_0x1c; + /* 0x20 */ u32 field_0x20; + /* 0x24 */ u32 field_0x24; + /* 0x28 */ u32 m_alignment; + /* 0x2C */ u32 field_0x2c; +}; + +class JHICommBufWriter { +public: + struct Header : public JHICommBufHeader { + int load(); + int getRemSize(); + void updatePutAdrs(); + u32 getWritebleSize() const; + void alignPutAdrs(); + void addPutAdrs(int); + u32 getPutAdrs() const; + + /* 0x30 */ u8 field_0x30; + /* 0x31 */ u8 field_0x31; + /* 0x32 */ u8 field_0x32; + /* 0x33 */ u8 field_0x33; + /* 0x34 */ u32 field_0x34; + }; + + JHICommBufWriter(u32, u32, u32 alignment); + int writeBegin(); + void writeEnd(); + int write(void*, int); + + /* 0x00 */ Header m_header; + /* 0x38 */ JHIMemBuf* mp_memBuffer; +}; + +class JHICommBufReader { +public: + struct Header : public JHICommBufHeader { + int load(); + void updateGetAdrs(); + u32 getReadableSize() const; + void addGetAdrs(int); + u32 getGetAdrs() const; + void alignGetAdrs(); + int getContSize(); + + /* 0x30 */ u32 field_0x30; + }; + + JHICommBufReader(u32, u32, u32 alignment); + int readBegin(); + void readEnd(); + int read(void*, int); + + u32 available() { return m_header.load() ? 0xFFFFFFFF : m_header.getReadableSize(); } + + /* 0x00 */ Header m_header; + /* 0x34 */ JHIMemBuf* mp_memBuffer; +}; + +struct JHICmnMem { + u32 sendBegin() { return mp_writeBuf->writeBegin(); } + int sendCont(const void* param_0, int param_1) { return mp_writeBuf->write((void*)param_0, param_1); } + void sendEnd() { mp_writeBuf->writeEnd(); } + + void setBuf(JHICommBufReader* pReader, JHICommBufWriter* pWriter) { + mp_readBuf = pReader; + mp_writeBuf = pWriter; + } + + /* 0x0 */ JHICommBufReader* mp_readBuf; + /* 0x4 */ JHICommBufWriter* mp_writeBuf; + /* 0x8 */ u8 field_0x8; +}; + +struct JHIContext { + JHICommBufReader* mp_reader; + JHICommBufWriter* mp_writer; +}; + +#endif /* JHICOMM_H */ diff --git a/include/JSystem/JHostIO/JHICommonMem.h b/include/JSystem/JHostIO/JHICommonMem.h new file mode 100644 index 00000000000..017e8d2669f --- /dev/null +++ b/include/JSystem/JHostIO/JHICommonMem.h @@ -0,0 +1,77 @@ +#ifndef JHICOMMONMEM_H +#define JHICOMMONMEM_H + +#include + +inline u32 JHIhtonl(u32 v) { +#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + return v; +#else + // todo +#endif +} + +template +struct JHITag { + JHITag(u32 tag) { + m_tag = tag; + mp_data = NULL; + } + + // NONMATCHING - stack stuff + const void* send(const void* param_0, s32 param_1) { + u32 sp10 = JHIhtonl(m_tag); + u32 sp14 = JHIhtonl(param_1); + + if (mp_data->sendBegin() >= param_1 + 8) { + mp_data->sendCont(&sp10, 8); + mp_data->sendCont(param_0, param_1); + mp_data->sendEnd(); + } + + return param_0; + } + + virtual ~JHITag() {} + virtual void receive(const char*, s32); + + /* 0x4 */ u32 m_tag; + /* 0x8 */ T* mp_data; +}; + +class JHIMemBuf; + +class JHICommonMem { +public: + virtual ~JHICommonMem() {} + virtual int create() = 0; + virtual int open() = 0; + virtual void close() = 0; + virtual u8* getPointer() const = 0; + virtual void readIO(u32 position, u32* out_data) const = 0; + virtual u32 readIO(u32 position) const = 0; + virtual void writeIO(u32 position, u32 data) const = 0; + virtual void writeIO(u32 position, u8* src_data, u32 length) const = 0; + + static JHIMemBuf* Instance(); + static JHIMemBuf* instance; +}; + +class JHIMemBuf : public JHICommonMem { +public: + JHIMemBuf(); + + virtual ~JHIMemBuf(); + virtual int create(); + virtual int open(); + virtual void close(); + virtual u8* getPointer() const; + virtual void readIO(u32 position, u32* out_data) const; + virtual u32 readIO(u32 position) const; + virtual void writeIO(u32 position, u32 data) const; + virtual void writeIO(u32 position, u8* src_data, u32 length) const; + + /* 0x4 */ u8* mp_buffer; +}; + +#endif /* JHICOMMONMEM_H */ diff --git a/include/JSystem/JHostIO/JHIMccBuf.h b/include/JSystem/JHostIO/JHIMccBuf.h new file mode 100644 index 00000000000..7343b88376f --- /dev/null +++ b/include/JSystem/JHostIO/JHIMccBuf.h @@ -0,0 +1,77 @@ +#ifndef JORMCCBUF_H_H +#define JORMCCBUF_H_H + +#include "JSystem/JHostIO/JHIComm.h" +#include "JSystem/JKernel/JKRHeap.h" + +class JHIMccBuf { +public: + JHIMccBuf(u16 channel, u16, u32); + + void setHeaderToBuf(u32 data, u32 position, u16 size); + u32 setDataToBuf(void* pData, u16 size); + int readData(u32 position, u32* pOutData); + int readDataFromBuf(void* pBuf, u32 size); + + int JHIRead(u32 channel, u32 offset, void* buffer, u32 size); + int JHIWrite(u32 channel, u32 offset, void* buffer, u32 size); + + int JHIMCCWrite(u32 channel, u32 offset, void* buffer, u32 size); + int JHIMCCRead(u32 channel, u32 offset, void* buffer, u32 size); + + virtual ~JHIMccBuf(); + virtual void initInstance(u16 channel, u16, u32); + virtual void init(); + virtual void initBuf(); + virtual void enablePort() { mPortEnabled = true; } + virtual void disablePort() { mPortEnabled = false; } + virtual bool isPort() { return mPortEnabled; } + + static u8* mTempBuf; + static u16 mRefCount; + + /* 0x04 */ u32 mTag; + /* 0x08 */ u16 field_0x8; + /* 0x0A */ u16 field_0xa; + /* 0x0C */ u16 field_0xc; + /* 0x0E */ u16 mChannel; + /* 0x10 */ u16 field_0x10; + /* 0x14 */ int mReadOffset; + /* 0x18 */ int mWriteOffset; + /* 0x1C */ int field_0x1c; + /* 0x20 */ u32 field_0x20; + /* 0x24 */ u32 mBeginPos; + /* 0x28 */ u32 mEndPos; + /* 0x2C */ bool mPortEnabled; +}; + +class JHIMccBufReader : public JHIMccBuf { +public: + JHIMccBufReader(u16 channel, u16, u32); + virtual ~JHIMccBufReader(); + + u32 available(); + int readBegin(); + int read(void* pBuf); + void readEnd(); +}; + +class JHIMccBufWriter : public JHIMccBuf { +public: + JHIMccBufWriter(u16 channel, u16, u32); + virtual ~JHIMccBufWriter(); + + int writeBegin(); + int write(void* pBuf, u32 size); + void writeEnd(); +}; + +struct JHIMccContext { + JHIMccBufReader* mp_reader; + JHIMccBufWriter* mp_writer; +}; + +void JHIReport(const char* fmt, ...); +void JHIHalt(const char* fmt, ...); + +#endif /* JORMCCBUF_H_H */ diff --git a/include/JSystem/JHostIO/JHIRMcc.h b/include/JSystem/JHostIO/JHIRMcc.h new file mode 100644 index 00000000000..6b79187c56d --- /dev/null +++ b/include/JSystem/JHostIO/JHIRMcc.h @@ -0,0 +1,15 @@ +#ifndef JHIRMCC_H +#define JHIRMCC_H + +#include + +struct JHIMccContext; + +u32 JHIInitInterface(); +bool JHINegotiateInterface(u32); +JHIMccContext JHIGetHiSpeedContext(); +JHIMccContext JHIGetLowSpeedContext(); +BOOL JHIInitMCC(JHIMccContext* pCtx, bool* param_1); +s32 JHIGetHIO2Handle(); + +#endif /* JHIRMCC_H */ diff --git a/include/JSystem/JHostIO/JHIhioASync.h b/include/JSystem/JHostIO/JHIhioASync.h new file mode 100644 index 00000000000..fa9d90ef71d --- /dev/null +++ b/include/JSystem/JHostIO/JHIhioASync.h @@ -0,0 +1,13 @@ +#ifndef JHIHIOASYNC_H +#define JHIHIOASYNC_H + +#include + +struct JHIContext; + +BOOL JHIInit(u32 enabled); +u32 JHIEventLoop(); +BOOL JOR_CHECKINTERFACE(); +void JHISetBuffer(JHIContext* pCtx); + +#endif /* JHIHIOASYNC_H */ diff --git a/include/JSystem/JHostIO/JOREntry.h b/include/JSystem/JHostIO/JOREntry.h new file mode 100644 index 00000000000..dcd63900121 --- /dev/null +++ b/include/JSystem/JHostIO/JOREntry.h @@ -0,0 +1,62 @@ +#ifndef JORENTRY_H +#define JORENTRY_H + +#include "JSystem/JHostIO/JHIComm.h" + +template +class JHIpvector { +public: + JHIpvector() { m_size = 0; } + + s32 size() const { return m_size; } + T& get(u32 i) const { return m_vector[i]; } + + s32 push_back(T p) { + if (m_size >= I) { + return 0; + } + + m_vector[m_size++] = p; + return 1; + } + + /* 0x00 */ T m_vector[I]; + /* 0x28 */ s32 m_size; +}; + +template +class JHIComPortManager { +public: + JHIComPortManager() { + field_0x10040 = 0; + field_0x10041 = 0; + } + + T& getRefPort() { return port; } + + void addTag(JHITag* pTag) { + field_0x8 = this; + field_0xc.push_back(pTag); + } + + static JHIComPortManager* create() { + if (instance == NULL) { + instance = new JHIComPortManager(); + } + + return instance; + } + + static JHIComPortManager* instance; + + /* 0x00000 */ T port; + /* 0x00008 */ JHIComPortManager* field_0x8; + /* 0x0000C */ JHIpvector*, 10> field_0xc; + /* 0x00038 */ u8 field_0x38[0x10000]; + /* 0x10038 */ u32 field_0x10038; + /* 0x1003C */ u32 field_0x1003c; + /* 0x10040 */ u8 field_0x10040; + /* 0x10041 */ u8 field_0x10041; +}; + +#endif /* JORENTRY_H */ diff --git a/include/JSystem/JHostIO/JORFile.h b/include/JSystem/JHostIO/JORFile.h new file mode 100644 index 00000000000..5d06259a488 --- /dev/null +++ b/include/JSystem/JHostIO/JORFile.h @@ -0,0 +1,94 @@ +#ifndef JORFILE_H +#define JORFILE_H + +#include "JSystem/JSupport/JSUMemoryStream.h" + +class JORDir { +public: + void setStatus(u32 status) { m_status = status; } + void setFindHandle(u32 handle) { m_findHandle = handle; } + void setFileAttribute(u32 attribute) { m_fileAttribute = attribute; } + void setLowDateTime(u32 time) { m_lowDateTime = time; } + void setHighDateTime(u32 time) { m_highDateTime = time; } + + char* getFilename() { return m_filename; } + + /* 0x00 */ u32 m_status; + /* 0x04 */ u32 m_findHandle; + /* 0x08 */ u32 m_fileAttribute; + /* 0x0C */ u32 m_lowDateTime; + /* 0x10 */ u32 m_highDateTime; + /* 0x14 */ char* m_filename; +}; + +class JORFile { +public: + enum ECommand { + ECommand_OPEN, + ECommand_CLOSE, + ECommand_READ, + ECommand_WRITE, + }; + + enum EStatus { + EStatus_WAIT, + EStatus_READ_BEGIN, + EStatus_READ_DATA, + EStatus_READ_END, + EStatus_WRITE_BEGIN, + EStatus_WRITE_DATA, + EStatus_WRITE_END, + }; + + enum EFlags { + EFlags_READ = (1 << 0), + EFlags_WRITE = (1 << 1), + EFlags_DEFAULT_EXT = (1 << 4), + EFlags_UNK_0x20 = (1 << 5), + EFlags_HAS_SUFFIX = (1 << 6), + }; + + JORFile(); + + int countMaskSize(const char* mask); + void setBuffer(void* buffer, s32 length); + + char* getFilename() { return mFilename; } + u32 getHandle() const { return mHandle; } + + JSUMemoryOutputStream& getDataStream() { return mDataStream; } + + void setHandle(u32 handle) { mHandle = handle; } + void setFileLength(s32 length) { mFileLength = length; } + void setNFileName(u16 length) { mNFileName = length; } + void setNBaseName(u16 length) { mNBaseName = length; } + void setNExtensionName(u16 length) { mNExtensionName = length; } + void setStatus(s32 status) { mStatus = status; } + + virtual ~JORFile() {} + virtual int open(const char* path, u32 flags, const char* extMask, const char* defaultExt, const char*, const char* fileSuffix); + virtual int open(u32 flags, const char* extMask, const char* defaultExt, const char*, const char* fileSuffix); + virtual void close(); + virtual s32 readData(void* buffer, s32 length); + virtual s32 writeData(const void* buffer, s32 length); + virtual void readBegin_(s32 len); + virtual void readLoop_(); + virtual void writeBegin_(s32 len); + virtual void writeLoop_(const void* pBuffer, s32 size, u32 pos); + virtual void writeDone_(s32 len); + virtual void waitMessage_(); + virtual s32 getFileSize() const; + + /* 0x04 */ u32 mHandle; + /* 0x08 */ s32 mFileLength; + /* 0x0C */ s32 mStatus; + /* 0x10 */ u16 mNFileName; + /* 0x12 */ u16 mNBaseName; + /* 0x14 */ u16 mNExtensionName; + /* 0x16 */ u16 mFlags; + /* 0x18 */ int field_0x18; + /* 0x1C */ JSUMemoryOutputStream mDataStream; + /* 0x30 */ char mFilename[8]; +}; + +#endif /* JORFILE_H */ diff --git a/include/JSystem/JHostIO/JORHostInfo.h b/include/JSystem/JHostIO/JORHostInfo.h new file mode 100644 index 00000000000..2eb43c51844 --- /dev/null +++ b/include/JSystem/JHostIO/JORHostInfo.h @@ -0,0 +1,52 @@ +#ifndef JORHOSTINFO_H +#define JORHOSTINFO_H + +#include + +#define HOSTINFO_REQ_COMPUTER_NAME 0 +#define HOSTINFO_REQ_USERNAME 1 +#define HOSTINFO_REQ_LOCAL_TIME 2 + +class JORHostInfo { +public: + /* 0x0 */ s32 m_result; + + void setResult(s32 result) { m_result = result; } + s32 getResult() { return m_result; } + + JORHostInfo() { m_result = 0; } + virtual ~JORHostInfo() {} +}; + +class JORHostInfo_String : public JORHostInfo { +public: + virtual ~JORHostInfo_String() {} + + JORHostInfo_String() { + m_stringBuffer = NULL; + m_bufferSize = 0; + } + + void setStringBuffer(char* buffer) { m_stringBuffer = buffer; } + void setBufferSize(u32 size) { m_bufferSize = size; } + char* getString() { return m_stringBuffer; } + u32 getBufferSize() { return m_bufferSize; } + + /* 0x8 */ char* m_stringBuffer; + /* 0xC */ u32 m_bufferSize; +}; + +class JORHostInfo_CalendarTime : public JORHostInfo { +public: + JORHostInfo_CalendarTime() { m_calendarTimeBuffer = NULL; } + virtual ~JORHostInfo_CalendarTime() {} + + void setCalendarTimeBuffer(OSCalendarTime* pCalendarTime) { m_calendarTimeBuffer = pCalendarTime; } + OSCalendarTime* getCalendarTime() { return m_calendarTimeBuffer; } + + /* 0x8 */ OSCalendarTime* m_calendarTimeBuffer; +}; + +BOOL JORGetYearDays(int year, int mon); + +#endif /* JORHOSTINFO_H */ diff --git a/include/JSystem/JHostIO/JORMContext.h b/include/JSystem/JHostIO/JORMContext.h new file mode 100644 index 00000000000..68f4135c598 --- /dev/null +++ b/include/JSystem/JHostIO/JORMContext.h @@ -0,0 +1,210 @@ +#ifndef JORMCONTEXT_H +#define JORMCONTEXT_H + +#include +#include "JSystem/JSupport/JSUMemoryStream.h" +#include "JSystem/JHostIO/JORReflexible.h" + +#define MCTX_MSG_RESET 0 +#define MCTX_MSG_GET_ROOT_OBJ 2 +#define MCTX_MSG_GEN_OBJ_INFO 4 +#define MCTX_MSG_INVALID_NODE 5 +#define MCTX_MSG_UPDATE_NODE 8 +#define MCTX_MSG_FIO 9 +#define MCTX_MSG_OPEN_MESSAGE_BOX 10 +#define MCTX_MSG_START_NODE 12 +#define MCTX_MSG_GET_HOST_INFO 14 +#define MCTX_MSG_SHELL_EXEC 15 + +#define MCTX_COMMAND_START_NODE (u32)0 +#define MCTX_COMMAND_END_NODE (u32)1 +#define MCTX_COMMAND_GEN_CONTROL (u32)2 +#define MCTX_COMMAND_GEN_NODE (u32)3 +#define MCTX_COMMAND_START_SELECTOR (u32)4 +#define MCTX_COMMAND_END_SELECTOR (u32)5 +#define MCTX_COMMAND_SELECTOR_ITEM (u32)6 +#define MCTX_COMMAND_INVALID_NODE (u32)7 +#define MCTX_COMMAND_UPDATE_CONTROL (u32)8 + +#define DEFINE_GEN_CHECKBOX(T, kind) \ + void genCheckBox(const char* label, T* pSrc, T mask, u32 style, JOREventListener* pListener, \ + u16 posX, u16 posY, u16 width, u16 height) { \ + genCheckBoxSub(kind, label, (u32)pSrc, style, *pSrc, mask, pListener, posX, posY, width, \ + height); \ + } + +#define DEFINE_GEN_CHECKBOX_ID(T, kind) \ + void genCheckBoxID(const char* label, u32 id, T mask, T initValue, u32 style, \ + JOREventListener* pListener, u16 posX, u16 posY, u16 width, u16 height) { \ + genCheckBoxSub(kind, label, id, style, initValue, mask, pListener, posX, posY, width, \ + height); \ + } + +#define DEFINE_GEN_SLIDER(T, kind) \ + void genSlider(const char* label, T* pSrc, T rangeMin, T rangeMax, u32 style, \ + JOREventListener* pListener, u16 posX, u16 posY, u16 width, u16 height) { \ + genSliderSub(kind, label, (u32)pSrc, style, *pSrc, rangeMin, rangeMax, pListener, posX, \ + posY, width, height); \ + } + +#define DEFINE_GEN_SLIDER_ID(T, kind) \ + void genSliderID(const char* label, u32 id, T data, T rangeMin, T rangeMax, u32 style, \ + JOREventListener* pListener, u16 posX, u16 posY, u16 width, u16 height) { \ + genSliderSub(kind, label, id, style, data, rangeMin, rangeMax, pListener, posX, posY, \ + width, height); \ + } + +namespace jhostio { + enum EKind { + EKind_8B = 0x08, + EKind_16B = 0x10, + EKind_32B = 0x20, + }; + + inline u32 GetEKindSize(u32 param_0) { return param_0 & 0xFF; } +} + +class JORReflexible; +class JORFile; +class JOREventListener; +class JORHostInfo; + +class JORMContext { +public: + JORMContext() : mOutputStream(this, 0x10000) {} + + void bufInit() { mOutputStream.seek(0, JSUStreamSeekFrom_SET); } + void putMsgID(u32 msgID) { mOutputStream << msgID; } + s32 msgSize() { return mOutputStream.getPosition(); } + u8* msgPtr() { return mBuffer; } + + void openFile(JORFile* pFile, u32 flags, const char* path, const char* extMask, u32 maskSize, + const char* defaultExt, const char* param_6, const char* fileSuffix); + void closeFile(JORFile* pFile); + void readBegin(JORFile* pFile, s32 size); + void readData(JORFile* pFile); + void writeBegin(JORFile* pFile, u16 flags, u32 size); + void writeData(JORFile* pFile, const void* pBuffer, s32 size, u32 position); + void writeDone(JORFile* pFile, u32 size); + void sendShellExecuteRequest(void*, const char*, const char*, const char*, const char*, int); + void sendHostInfoRequest(u32 requestType, JORHostInfo* pHostInfo); + void endNode(); + + void genRootNode(const char* label, JORReflexible* obj, u32 param_2, u32 param_3) { + genNodeSub(label, obj, param_2, param_3); + } + + void genNode(const char* label, JORReflexible* obj, u32 param_2, u32 param_3) { + mOutputStream << MCTX_COMMAND_GEN_NODE; + genNodeSub(label, obj, param_2, param_3); + } + + void genNode(JORReflexible* parentObj, u32 param_1, const char* label, JORReflexible* obj, + u32 param_4, u32 param_5) { + ASSERTMSGLINE(97, parentObj != NULL, + "JORMContext: genNode must specify strict( not null node ) parent object\n"); + + mOutputStream << MCTX_COMMAND_GEN_NODE; + mOutputStream << param_1; + putNode(parentObj); + genNodeSub(label, obj, param_4, param_5); + } + + void startNode(JORReflexible* parentObj, u32 param_1, const char* label, JORReflexible* obj, + u32 param_4, u32 param_5) { + ASSERTMSGLINE( + 113, parentObj != NULL, + "JORMContext: startNode must specify strict( not null node ) parent object\n"); + + mOutputStream << MCTX_COMMAND_START_NODE; + mOutputStream << param_1; + putNode(parentObj); + genNodeSub(label, obj, param_4, param_5); + } + + void startNode(const char* label, JORReflexible* obj, u32 param_2, u32 param_3) { + mOutputStream << MCTX_COMMAND_START_NODE; + genNodeSub(label, obj, param_2, param_3); + } + + void genNodeSub(const char* label, JORReflexible* i_node, u32, u32); + void putNode(JORReflexible* obj); + void invalidNode(JORReflexible* i_node, u32); + + void genControl(u32 type, u32 kind, const char* label, u32 style, u32 id, + JOREventListener* pListener, u32 initValue); + + void genSliderSub(u32 kind, const char* label, u32 id, u32 style, s32 initValue, s32 rangeMin, + s32 rangeMax, JOREventListener* pListener, u16 posX, u16 posY, u16 width, + u16 height); + + void genCheckBoxSub(u32 kind, const char* label, u32 id, u32 style, u16 initValue, u16 mask, + JOREventListener* pListener, u16 posX, u16 posY, u16 width, u16 height); + + void startSelectorSub(u32 type, u32 kind, const char* label, u32 id, u32 style, s32 initValue, + JOREventListener* pListener, u16 posX, u16 posY, u16 width, u16 height); + + void endSelectorSub(); + + void genSelectorItemSub(const char* label, s32 itemNo, u32 param_2, u16 posX, u16 posY, + u16 width, u16 height); + + void genButton(const char* label, u32 id, u32 style, JOREventListener* pListener, u16 posX, + u16 posY, u16 width, u16 height); + + void genLabel(const char* label, u32 id, u32 style, JOREventListener* pListener, u16 posX, + u16 posY, u16 width, u16 height); + + void genGroupBox(const char* label, u32 id, u32 style, JOREventListener* pListener, u16 posX, + u16 posY, u16 width, u16 height); + + void genEditBoxID(const char* label, u32 id, const char* string, u16 length, u32 style, + JOREventListener* pListener, u16 posX, u16 posY, u16 width, u16 height); + + /** + * === CHECKBOX === + */ + DEFINE_GEN_CHECKBOX(u8, 0x100 | jhostio::EKind_8B) + DEFINE_GEN_CHECKBOX(u16, 0x100 | jhostio::EKind_16B) + + DEFINE_GEN_CHECKBOX_ID(u16, JORPropertyEvent::EKind_ValueID | 0x100) + + /** + * === SLIDER === + */ + DEFINE_GEN_SLIDER(u8, 0x100 | jhostio::EKind_8B) + DEFINE_GEN_SLIDER(s16, jhostio::EKind_16B) + DEFINE_GEN_SLIDER(f32, JORPropertyEvent::EKind_FloatValue | jhostio::EKind_32B) + DEFINE_GEN_SLIDER(s32, jhostio::EKind_32B) + + DEFINE_GEN_SLIDER_ID(f64, JORPropertyEvent::EKind_ValueID | JORPropertyEvent::EKind_FloatValue) + DEFINE_GEN_SLIDER_ID(int, JORPropertyEvent::EKind_ValueID) + + void genComboBoxItem(const char* label, s32 itemNo) { + genSelectorItemSub(label, itemNo, 0, 0, 0, 0, 0); + } + + void genRadioButtonItem(const char* label, s32 itemNo, u32 param_2, u16 posX, u16 posY, + u16 width, u16 height) { + genSelectorItemSub(label, itemNo, param_2, posX, posY, width, height); + } + + void updateControl(u32 mode, u32 id, u32 param_2); + void updateControl(u32 mode, u32 id, const char* param_2); + void updateSliderSub(u32 mode, u32 id, s32 value, s32 rangeMin, s32 rangeMax, + u32 param_5); + void updateCheckBoxSub(u32 mode, u32 id, u16 value, u16 mask, u32 param_4); + void updateSelectorSub(u32 mode, u32 id, s32 value, u32 param_3); + void updateEditBoxID(u32 mode, u32 id, const char* string, u32 param_3, u16 length); + void editComboBoxItem(u32 param_0, u32 param_1, const char* param_2, s32 param_3, u32 param_4); + + void openMessageBox(void* param_0, u32 style, const char* message, const char* title); + + /* 0x00000 */ u8 mBuffer[0x10000]; + /* 0x10000 */ JSUMemoryOutputStream mOutputStream; +}; + +JORMContext* attachJORMContext(u32); +void releaseJORMContext(JORMContext*); + +#endif /* JORMCONTEXT_H */ diff --git a/include/JSystem/JHostIO/JORReflexible.h b/include/JSystem/JHostIO/JORReflexible.h new file mode 100644 index 00000000000..3a066f70add --- /dev/null +++ b/include/JSystem/JHostIO/JORReflexible.h @@ -0,0 +1,53 @@ +#ifndef JORREFLEXIBLE_H +#define JORREFLEXIBLE_H + +#include + +class JORReflexible; + +struct JOREvent {}; + +struct JORPropertyEvent : JOREvent { + enum EKind { + EKind_HasListener = (1 << 30), + EKind_ValueID = (1 << 29), + EKind_FloatValue = (1 << 9), + }; + + /* 0x00 */ u8 field_0x0[0x4 - 0x0]; + /* 0x04 */ u32 type; + /* 0x08 */ u32 kind; + /* 0x0C */ char* field_0xc; + /* 0x10 */ JORReflexible* field_0x10; // ? + /* 0x14 */ u32 field_0x14; + union { + u32 U32; + u16 U16[2]; + } + /* 0x18 */ field_0x18; +}; + +struct JORGenEvent : JOREvent {}; +struct JORNodeEvent : JOREvent {}; + +struct JORMContext; +struct JORServer; + +class JOREventListener { +public: + virtual void listenPropertyEvent(const JORPropertyEvent*) = 0; +}; + +class JORReflexible : public JOREventListener { +public: + JORReflexible(); + static JORServer* getJORServer(); + + virtual void listenPropertyEvent(const JORPropertyEvent*); + virtual void listen(u32, const JOREvent*); + virtual void genObjectInfo(const JORGenEvent*); + virtual void genMessage(JORMContext*) = 0; + virtual void listenNodeEvent(const JORNodeEvent*); +}; + +#endif /* JORREFLEXIBLE_H */ diff --git a/include/JSystem/JHostIO/JORServer.h b/include/JSystem/JHostIO/JORServer.h new file mode 100644 index 00000000000..3f28539e457 --- /dev/null +++ b/include/JSystem/JHostIO/JORServer.h @@ -0,0 +1,111 @@ +#ifndef JORSERVER_H +#define JORSERVER_H + +#include "JSystem/JHostIO/JORMContext.h" +#include "JSystem/JHostIO/JHIComm.h" +#include "JSystem/JGadget/linklist.h" +#include "JSystem/JUtility/JUTAssert.h" + +void JOR_MESSAGELOOP(); +u32 JORMessageBox(const char* message, const char* title, u32 style); + +struct JOREventCallbackListNode { + JOREventCallbackListNode(u32, u32, bool); + void JORAppend(); + void JORRemove(); + + virtual int JORAct(u32, const char*); + virtual ~JOREventCallbackListNode(); + + /* 0x04 */ JGadget::TLinkListNode m_node; + /* 0x0C */ u32 field_0xc; + /* 0x10 */ u32 field_0x10; +}; + +class JORFile; +class JORDir; +class JORHostInfo_String; +class JORHostInfo_CalendarTime; + +class JORServer : public JHITag { +public: + enum ECommand { + ECommand_GetRootObj = 1, + ECommand_GenObjInfo = 3, + ECommand_NodeEvent = 6, + ECommand_PropertyEvent = 7, + ECommand_FIO = 9, + ECommand_ReadResultS32 = 10, + ECommand_ReadOrEvent = 11, + ECommand_DIR = 13, + ECommand_HostInfo = 14, + ECommand_ReadResultU32 = 15, + }; + + JORServer() : JHITag('ORef'), + m_event(false), + m_eventDone(true), + m_eventFunc(NULL), + m_isEventCallbackListEnabled(false) + {} + + static JORServer* create(); + void receive(const char*, s32); + + JORMContext* attachMCTX(u32); + void releaseMCTX(JORMContext*); + + void appendEventCallbackListNode(JOREventCallbackListNode* p) { + JUT_ASSERT(256, p!=0); + m_eventCallbackList.Push_front(p); + } + + void removeEventCallbackListNode(JOREventCallbackListNode* p) { + JUT_ASSERT(257, p!=0); + m_eventCallbackList.Remove(p); + } + + static void defSetVal(void*, u32, s32); + static void defSetBitVal(void*, u32, u16, u16); + + void fio_openFile_(JSUMemoryInputStream&); + void fio_closeFile_(JSUMemoryInputStream&); + void fio_readData_(JSUMemoryInputStream&); + void fio_writeData_(JSUMemoryInputStream&); + void fio_dispatchMessage_(JSUMemoryInputStream&); + + void dir_findFirstFile_(JSUMemoryInputStream&, JORDir*); + void dir_findNextFile_(JSUMemoryInputStream&, JORDir*); + void dir_browseForFolder_(JSUMemoryInputStream&, JORDir*); + + void readResultS32_(JSUMemoryInputStream&); + void readOrEvent_(JSUMemoryInputStream&); + void dir_dispatchMessage_(JSUMemoryInputStream&); + void hostinfo_dispatchMessage_(JSUMemoryInputStream&); + void hostinfo_recvString_(JSUMemoryInputStream&, JORHostInfo_String*); + void hostinfo_localTime_(JSUMemoryInputStream&, JORHostInfo_CalendarTime*); + void readResultU32_(JSUMemoryInputStream&); + + void sendReset(); + + void setRootNode(const char*, JORReflexible*, u32, u32); + void doneEvent(); + + static JORServer* getInstance() { return instance; } + static JORServer* instance; + + /* 0x0000C */ JORMContext m_context; + /* 0x10020 */ JORReflexible* mp_rootObj; + /* 0x10024 */ char m_rootName[64]; + /* 0x10064 */ u32 field_0x10064; + /* 0x10068 */ u32 field_0x10068; + /* 0x1006C */ bool m_event; + /* 0x1006D */ bool m_eventDone; + /* 0x10070 */ u32 m_eventNum; + /* 0x10074 */ char m_eventName[0x1000]; + /* 0x11074 */ void* m_eventFunc; + /* 0x11078 */ bool m_isEventCallbackListEnabled; + /* 0x1107C */ JGadget::TLinkList m_eventCallbackList; +}; + +#endif /* JORSERVER_H */ diff --git a/include/JSystem/JSupport/JSUInputStream.h b/include/JSystem/JSupport/JSUInputStream.h index 411f8c02ad9..dc35d5ab911 100644 --- a/include/JSystem/JSupport/JSUInputStream.h +++ b/include/JSystem/JSupport/JSUInputStream.h @@ -3,12 +3,6 @@ #include "JSystem/JSupport/JSUIosBase.h" -enum JSUStreamSeekFrom { - JSUStreamSeekFrom_SET = 0, // absolute - JSUStreamSeekFrom_CUR = 1, // relative - JSUStreamSeekFrom_END = 2, // relative to end -}; - /** * @ingroup jsystem-jsupport * @@ -70,18 +64,38 @@ public: return val; } - JSUInputStream* operator>>(u8& dest) { - read(&dest, 1); - return this; + JSUInputStream& operator>>(u32& dest) { + read(&dest, 4); + return *this; } - JSUInputStream* operator>>(s16& dest) { + JSUInputStream& operator>>(u16& dest) { read(&dest, 2); - return this; + return *this; + } + + JSUInputStream& operator>>(u8& dest) { + read(&dest, 1); + return *this; + } + + JSUInputStream& operator>>(s16& dest) { + read(&dest, 2); + return *this; + } + + JSUInputStream& operator>>(char* dest) { + read(dest); + return *this; + } + + s32 read(u32& param_0) { + return read(¶m_0, 4); } // TODO: return value probably wrong /* 802DC298 */ s32 read(void*, s32); + char* read(char*); }; // Size = 0x8 // move? diff --git a/include/JSystem/JSupport/JSUIosBase.h b/include/JSystem/JSupport/JSUIosBase.h index 761c1d61df2..5164cc5a2ad 100644 --- a/include/JSystem/JSupport/JSUIosBase.h +++ b/include/JSystem/JSupport/JSUIosBase.h @@ -3,8 +3,10 @@ #include "dolphin/types.h" -enum EIoState { - IOS_STATE_1 = 1, +enum JSUStreamSeekFrom { + JSUStreamSeekFrom_SET = 0, // absolute + JSUStreamSeekFrom_CUR = 1, // relative + JSUStreamSeekFrom_END = 2, // relative to end }; /** @@ -13,6 +15,11 @@ enum EIoState { */ class JSUIosBase { public: + enum EIoState { + IOS_STATE_1 = 1, + IOS_STATE_2 = 2, + }; + JSUIosBase() { mState = false; } virtual ~JSUIosBase() {} @@ -22,7 +29,7 @@ public: void setState(EIoState state) { mState |= state; } private: - u8 mState; + bool mState; }; // Size = 0x8 #endif diff --git a/include/JSystem/JSupport/JSUMemoryStream.h b/include/JSystem/JSupport/JSUMemoryStream.h index 0ef47035556..51b6fb601ad 100644 --- a/include/JSystem/JSupport/JSUMemoryStream.h +++ b/include/JSystem/JSupport/JSUMemoryStream.h @@ -2,6 +2,7 @@ #define JSUMEMORYSTREAM_H #include "JSystem/JSupport/JSURandomInputStream.h" +#include "JSystem/JSupport/JSURandomOutputStream.h" /** * @ingroup jsystem-jsupport @@ -9,7 +10,7 @@ */ class JSUMemoryInputStream : public JSURandomInputStream { public: - JSUMemoryInputStream(const void* res, u32 size) { setBuffer(res, size); } + JSUMemoryInputStream(const void* res, s32 size) { setBuffer(res, size); } /* 802552B8 */ virtual ~JSUMemoryInputStream() {} /* 802DC520 */ void setBuffer(void const*, s32); @@ -18,10 +19,35 @@ public: /* 802DC628 */ s32 getLength() const; /* 802DC630 */ s32 getPosition() const; + void* getPointer() const { + return (u8*)mBuffer + mPosition; + } + private: /* 0x08 */ const void* mBuffer; /* 0x0C */ s32 mLength; /* 0x10 */ s32 mPosition; }; // Size = 0x14 +class JSUMemoryOutputStream : public JSURandomOutputStream { +public: + JSUMemoryOutputStream() { setBuffer(NULL, 0); } + JSUMemoryOutputStream(void* buffer, s32 len) { setBuffer(buffer, len); } + + void setBuffer(void* buffer, s32 len); + + virtual ~JSUMemoryOutputStream() {} + virtual s32 writeData(const void*, s32); + virtual s32 getLength() const; + virtual s32 getPosition() const; + virtual s32 seek(s32, JSUStreamSeekFrom); + virtual s32 getAvailable() const; + virtual s32 seekPos(s32, JSUStreamSeekFrom); + +private: + /* 0x08 */ void* mBuffer; + /* 0x0C */ s32 mLength; + /* 0x10 */ s32 mPosition; +}; // Size = 0x14 + #endif /* JSUMEMORYSTREAM_H */ diff --git a/include/JSystem/JSupport/JSUOutputStream.h b/include/JSystem/JSupport/JSUOutputStream.h new file mode 100644 index 00000000000..43d9d37ef05 --- /dev/null +++ b/include/JSystem/JSupport/JSUOutputStream.h @@ -0,0 +1,52 @@ +#ifndef JSUOUTPUTSTREAM_H +#define JSUOUTPUTSTREAM_H + +#include "JSystem/JSupport/JSUIosBase.h" + +/** +* @ingroup jsystem-jsupport +* +*/ +class JSUOutputStream : public JSUIosBase { +public: + JSUOutputStream() {} + virtual ~JSUOutputStream(); + + virtual s32 skip(s32, s8) = 0; + virtual s32 writeData(const void*, s32) = 0; + + s32 write(const void*, s32); + void write(const char*); + + JSUOutputStream& operator<<(u32 param_0) { + write(¶m_0, sizeof(u32)); + return *this; + } + + JSUOutputStream& operator<<(s32 param_0) { + write(¶m_0, sizeof(s32)); + return *this; + } + + JSUOutputStream& operator<<(s16 param_0) { + write(¶m_0, sizeof(s16)); + return *this; + } + + JSUOutputStream& operator<<(u16 param_0) { + write(¶m_0, sizeof(u16)); + return *this; + } + + JSUOutputStream& operator<<(u8 param_0) { + write(¶m_0, sizeof(u8)); + return *this; + } + + JSUOutputStream& operator<<(const char* param_0) { + write(param_0); + return *this; + } +}; // Size = 0x8 + +#endif /* JSUOUTPUTSTREAM_H */ diff --git a/include/JSystem/JSupport/JSURandomOutputStream.h b/include/JSystem/JSupport/JSURandomOutputStream.h new file mode 100644 index 00000000000..1b2648fabbf --- /dev/null +++ b/include/JSystem/JSupport/JSURandomOutputStream.h @@ -0,0 +1,24 @@ +#ifndef JSURANDOMOUTPUTSTREAM_H_ +#define JSURANDOMOUTPUTSTREAM_H_ + +#include "JSystem/JSupport/JSUOutputStream.h" + +/** +* @ingroup jsystem-jsupport +* +*/ +class JSURandomOutputStream : public JSUOutputStream { +public: + JSURandomOutputStream() {} + virtual ~JSURandomOutputStream() {} + + /* vt[3] */ virtual s32 skip(s32, s8); + /* vt[4] */ virtual s32 writeData(const void*, s32) = 0; + /* vt[5] */ virtual s32 getLength() const = 0; + /* vt[6] */ virtual s32 getPosition() const = 0; + /* vt[7] */ virtual s32 seek(s32, JSUStreamSeekFrom); + /* vt[8] */ virtual s32 getAvailable() const; + /* vt[9] */ virtual s32 seekPos(s32, JSUStreamSeekFrom) = 0; +}; // Size = 0x8 + +#endif diff --git a/include/JSystem/JUtility/JUTAssert.h b/include/JSystem/JUtility/JUTAssert.h index 213f5df274b..66256e08b71 100644 --- a/include/JSystem/JUtility/JUTAssert.h +++ b/include/JSystem/JUtility/JUTAssert.h @@ -21,7 +21,7 @@ JUTAssertion::setConfirmMessage(JUTAssertion::getSDevice(), __FILE__, LINE, COND, #COND) #else -#define JUT_ASSERT(...) +#define JUT_ASSERT(...) (void)0; #define JUT_PANIC(...) #define JUT_WARN(...) #define JUT_LOG(...) diff --git a/include/m_Do/m_Do_hostIO.h b/include/m_Do/m_Do_hostIO.h index eefdd1288f2..864fd590458 100644 --- a/include/m_Do/m_Do_hostIO.h +++ b/include/m_Do/m_Do_hostIO.h @@ -1,10 +1,76 @@ #ifndef M_DO_M_DO_HOSTIO_H #define M_DO_M_DO_HOSTIO_H +#include "JSystem/JHostIO/JORReflexible.h" +#include "JSystem/JHostIO/JORMContext.h" +#include -class mDoHIO_entry_c { +class mDoHIO_child_c { public: - virtual ~mDoHIO_entry_c() {} + mDoHIO_child_c() { + unk18 = 0; + mPt = NULL; + } + + ~mDoHIO_child_c(); + + void setPt(JORReflexible* i_pt) { mPt = i_pt; } + void setName(const char* i_name) { strncpy(mName, i_name, sizeof(mName)); } + JORReflexible* getPt() { return mPt; } + const char* getName() { return mName; } + + /* 0x00 */ char mName[24]; + /* 0x18 */ u8 unk18; + /* 0x1C */ JORReflexible* mPt; }; +class mDoHIO_entry_c +#ifdef DEBUG +: public JORReflexible +#endif +{ +public: +#ifdef DEBUG + mDoHIO_entry_c(); + void entryHIO(const char* i_name); + void removeHIO(); + + virtual ~mDoHIO_entry_c(); + + /* 0x4 */ s8 mNo; + /* 0x5 */ u8 mCount; +#else + virtual ~mDoHIO_entry_c() {} +#endif +}; + +class mDoHIO_subRoot_c : public JORReflexible { +public: + mDoHIO_subRoot_c() {} + void updateChild(s8); + void deleteChild(s8); + s8 createChild(const char*, JORReflexible*); + + virtual void genMessage(JORMContext*); + virtual ~mDoHIO_subRoot_c(); + + /* 0x4 */ mDoHIO_child_c mChildren[80]; +}; + +class mDoHIO_root_c : public JORReflexible { +public: + mDoHIO_root_c() {} + void update(); + void updateChild(s8); + void deleteChild(s8); + int createChild(const char*, JORReflexible*); + + virtual void genMessage(JORMContext*); + virtual ~mDoHIO_root_c(); + + /* 0x4 */ mDoHIO_subRoot_c mSub; +}; + +extern mDoHIO_root_c mDoHIO_root; + #endif /* M_DO_M_DO_HOSTIO_H */ diff --git a/src/JSystem/JHostIO/JHIComm.cpp b/src/JSystem/JHostIO/JHIComm.cpp new file mode 100644 index 00000000000..e55845f0090 --- /dev/null +++ b/src/JSystem/JHostIO/JHIComm.cpp @@ -0,0 +1,306 @@ +#include "JSystem/JHostIO/JHIComm.h" + +static int min(int a, int b); + +void JHICommBufHeader::init() { + mp_memBuffer->writeIO(field_0x4 + field_0x1c, 0); + mp_memBuffer->writeIO(field_0x4 + field_0x18, 0); + mp_memBuffer->writeIO(field_0x4 + field_0x14, 'IS64'); +} + +void JHICommBufHeader::init(JHICommonMem* buffer, u32 param_1, u32 param_2, u32 alignment) { + m_alignment = alignment; + + if (alignment == 4) { + field_0x14 = 0x00; + field_0x18 = 0x08; + field_0x1c = 0x14; + field_0x20 = 0x18; + field_0x24 = 0x20; + field_0x2c = ~0x3; + } else if (alignment == 32) { + field_0x14 = 0x00; + field_0x18 = 0x20; + field_0x1c = 0x40; + field_0x20 = 0x60; + field_0x24 = 0x80; + field_0x2c = ~0x1F; + } + + mp_memBuffer = buffer; + field_0x4 = field_0x2c & (param_1 + m_alignment - 1); + + u32 var_r30 = field_0x2c & (param_1 + param_2); + m_msgBufSize = var_r30 - field_0x4 - field_0x24; + + init(); +} + +int JHICommBufHeader::load() { + u32 data; + mp_memBuffer->readIO(field_0x4 + field_0x14, &data); + if (data != 'IS64') { + return 1; + } + + mp_memBuffer->readIO(field_0x4 + field_0x18, &field_0xc); + mp_memBuffer->readIO(field_0x4 + field_0x1c, &field_0x10); + return 0; +} + +JHICommBufReader::JHICommBufReader(u32 param_0, u32 param_1, u32 alignment) { + mp_memBuffer = JHICommonMem::Instance(); + m_header.init(mp_memBuffer, param_0, param_1, alignment); +} + +void JHICommBufReader::Header::updateGetAdrs() { + if (field_0xc != field_0x30) { + mp_memBuffer->writeIO(field_0x4 + field_0x18, field_0xc); + } +} + +u32 JHICommBufReader::Header::getReadableSize() const { + u32 size; + if (field_0xc <= field_0x10) { + size = field_0x10 - field_0xc; + } else { + size = m_msgBufSize - (field_0xc - field_0x10); + } + + return size; +} + +int JHICommBufReader::readBegin() { + return m_header.load(); +} + +void JHICommBufReader::readEnd() { + m_header.updateGetAdrs(); +} + +// NONMATCHING - stack / branch issues +int JHICommBufReader::read(void* param_0, int param_1) { + int sp2C = min(param_1, m_header.getReadableSize()); + u32 sp28; + int var_r28 = sp2C; + u8* var_r30 = (u8*)param_0; + + if (var_r28 > 0) { + int sp24 = m_header.getContSize(); + if (sp24 > 0) { + int sp20 = min(var_r28, 4 - sp24); + m_header.alignGetAdrs(); + + mp_memBuffer->readIO(m_header.getGetAdrs(), &sp28); + + int sp1C = sp24; + int sp18 = sp24 + sp20; + for (; sp1C < sp18; sp1C++) { + *var_r30 = sp28 >> ((3 - sp1C) * 8); + var_r30++; + } + + var_r28 -= sp20; + m_header.addGetAdrs(sp24 + sp20); + } + } + + while (var_r28 >= 4) { + mp_memBuffer->readIO(m_header.getGetAdrs(), &sp28); + var_r30[0] = sp28 >> 0x18; + var_r30[1] = sp28 >> 0x10; + var_r30[2] = sp28 >> 0x08; + var_r30[3] = sp28 >> 0x00; + + var_r30 += 4; + var_r28 -= 4; + + m_header.addGetAdrs(4); + } + + if (var_r28 > 0) { + int sp14 = var_r28; + mp_memBuffer->readIO(m_header.getGetAdrs(), &sp28); + + for (int i = 0; i < sp14; i++) { + *var_r30 = sp28 >> ((3 - i) * 8); + var_r30++; + } + + var_r28 -= sp14; + m_header.addGetAdrs(sp14); + } + + return sp2C; +} + +void JHICommBufReader::Header::addGetAdrs(int param_0) { + field_0xc += param_0; + if (field_0xc >= m_msgBufSize) { + field_0xc -= m_msgBufSize; + } +} + +u32 JHICommBufReader::Header::getGetAdrs() const { + return field_0xc + (field_0x4 + field_0x24); +} + +void JHICommBufReader::Header::alignGetAdrs() { + field_0xc &= ~0x3; +} + +int JHICommBufReader::Header::getContSize() { + return field_0xc & 3; +} + +static int min(int a, int b) { + return a < b ? a : b; +} + +JHICommBufWriter::JHICommBufWriter(u32 param_0, u32 param_1, u32 param_2) { + mp_memBuffer = JHICommonMem::Instance(); + m_header.init(mp_memBuffer, param_0, param_1, param_2); +} + +int JHICommBufWriter::Header::load() { + int var_r29 = JHICommBufHeader::load(); + if (var_r29 == 0) { + field_0x34 = field_0x10; + + if (getRemSize() > 0) { + u32 sp8; + mp_memBuffer->readIO(field_0x4 + field_0x20, &sp8); + + field_0x30 = sp8 >> 0x18; + field_0x31 = sp8 >> 0x10; + field_0x32 = sp8 >> 0x08; + field_0x33 = sp8 >> 0x00; + } + } + + return var_r29; +} + +int JHICommBufWriter::Header::getRemSize() { + return field_0x10 & 3; +} + +void JHICommBufWriter::Header::updatePutAdrs() { + if (field_0x10 != field_0x34) { + mp_memBuffer->writeIO(field_0x4 + field_0x1c, field_0x10); + + if (getRemSize() > 0) { + mp_memBuffer->writeIO(field_0x4 + field_0x20, + (field_0x30 << 0x18) | + (field_0x31 << 0x10) | + (field_0x32 << 0x08) | + (field_0x33 << 0x00)); + } + } +} + +u32 JHICommBufWriter::Header::getWritebleSize() const { + u32 var_r31 = field_0xc & ~0x3; + u32 var_r30; + + if (field_0x10 < var_r31) { + var_r30 = var_r31 - field_0x10; + } else { + var_r30 = var_r31 + (m_msgBufSize - field_0x10); + } + + return var_r30 - 4; +} + +int JHICommBufWriter::writeBegin() { + int var_r31; + if (m_header.load() != 0) { + var_r31 = -1; + } else { + var_r31 = m_header.getWritebleSize(); + } + + return var_r31; +} + +void JHICommBufWriter::writeEnd() { + m_header.updatePutAdrs(); +} + +// NONMATCHING - stack / misc issues +int JHICommBufWriter::write(void* param_0, int param_1) { + int sp28 = min(param_1, m_header.getWritebleSize()); + int var_r27 = sp28; + u8* var_r29 = (u8*)param_0; + u8* var_r30 = &m_header.field_0x30; + + if (var_r27 > 0) { + int sp24 = m_header.getRemSize(); + if (sp24 > 0) { + int sp20 = min(4 - sp24, var_r27); + + int sp1C = sp24; + int sp18 = sp24 + sp20; + for (; sp1C < sp18; sp1C++) { + var_r30[sp1C] = *var_r29++; + } + + var_r27 -= sp20; + m_header.alignPutAdrs(); + + mp_memBuffer->writeIO(m_header.getPutAdrs(), + (m_header.field_0x30 << 0x18) | + (m_header.field_0x31 << 0x10) | + (m_header.field_0x32 << 0x08) | + (m_header.field_0x33 << 0x00)); + m_header.addPutAdrs(sp24 + sp20); + } + } + + while (var_r27 >= 4) { + mp_memBuffer->writeIO(m_header.getPutAdrs(), + (var_r29[0] << 0x18) | + (var_r29[1] << 0x10) | + (var_r29[2] << 0x08) | + (var_r29[3] << 0x00)); + + var_r29 += 4; + var_r27 -= 4; + + m_header.addPutAdrs(4); + } + + if (var_r27 > 0) { + int sp14 = var_r27; + + for (int i = 0; i < sp14; i++) { + var_r30[sp14] = *var_r29++; + } + + mp_memBuffer->writeIO(m_header.getPutAdrs(), + (m_header.field_0x30 << 0x18) | + (m_header.field_0x31 << 0x10) | + (m_header.field_0x32 << 0x08) | + (m_header.field_0x33 << 0x00)); + + var_r27 -= sp14; + m_header.addPutAdrs(sp14); + } + + return sp28; +} + +void JHICommBufWriter::Header::addPutAdrs(int param_0) { + field_0x10 += param_0; + if (field_0x10 >= m_msgBufSize) { + field_0x10 -= m_msgBufSize; + } +} + +u32 JHICommBufWriter::Header::getPutAdrs() const { + return field_0x10 + (field_0x4 + field_0x24); +} + +void JHICommBufWriter::Header::alignPutAdrs() { + field_0x10 &= ~0x3; +} diff --git a/src/JSystem/JHostIO/JHICommonMem.cpp b/src/JSystem/JHostIO/JHICommonMem.cpp new file mode 100644 index 00000000000..d4057f18f14 --- /dev/null +++ b/src/JSystem/JHostIO/JHICommonMem.cpp @@ -0,0 +1,16 @@ +#include "JSystem/JHostIO/JHICommonMem.h" + +JHIMemBuf* JHICommonMem::instance; + +JHIMemBuf* JHICommonMem::Instance() { + if (instance == NULL) { + instance = new JHIMemBuf(); + } + + return instance; +} + +JHIMemBuf::JHIMemBuf() { + mp_buffer = NULL; + create(); +} diff --git a/src/JSystem/JHostIO/JHIMccBuf.cpp b/src/JSystem/JHostIO/JHIMccBuf.cpp new file mode 100644 index 00000000000..b9a57637d01 --- /dev/null +++ b/src/JSystem/JHostIO/JHIMccBuf.cpp @@ -0,0 +1,455 @@ +#include "JSystem/JHostIO/JHIMccBuf.h" +#include "JSystem/JKernel/JKRHeap.h" +#include "JSystem/JHostIO/JHIRMcc.h" +#include +#include + +extern "C" int HIO2Read(u32, u32, void*, u32); +extern "C" int HIO2Write(u32, u32, void*, u32); + +void JHIReport(const char* fmt, ...) {} + +void JHIHalt(const char* fmt, ...) {} + +u8* JHIMccBuf::mTempBuf; +u16 JHIMccBuf::mRefCount; + +JHIMccBuf::JHIMccBuf(u16 channel, u16 param_1, u32 param_2) { + initInstance(channel, param_1, param_2); + mRefCount++; +} + +void JHIMccBuf::initInstance(u16 channel, u16 param_1, u32 param_2) { + mTag = 'MCHI'; + field_0x8 = 0x20; + field_0xa = 0x40; + field_0xc = 0x60; + mChannel = channel; + field_0x10 = param_1; + field_0x20 = param_2; + mReadOffset = 0; + mWriteOffset = (int)(param_1 << 13) / 4; + field_0x1c = ((int)(param_1 << 13) / 4) - field_0xc; + mPortEnabled = false; +} + +void JHIMccBuf::init() { + if (mTempBuf != NULL) { + initBuf(); + } else { + mTempBuf = new (32) u8[0x18000]; + if (mTempBuf == NULL) { + JHIHalt("ERROR: JHIMccBuf cannot alloc temp buf.\n"); + } else { + JHIReport("DEBUG: JHIMccBuf alloc at %08x.\n", mTempBuf); + } + + initBuf(); + } +} + +void JHIMccBuf::initBuf() { + setHeaderToBuf(mTag, 0, 0x20); + setHeaderToBuf(field_0xc, field_0x8, 0x20); + setHeaderToBuf(field_0xc, field_0xa, 0x20); + + if (JHIMCCWrite(mChannel, mReadOffset, mTempBuf, 0x60)) { + JHIReport("DEBUG: Write to Channel:%d , Offset:%05x , Size: %d\n", mChannel, mReadOffset, 0x60); + + if (JHIMCCWrite(mChannel, mWriteOffset, mTempBuf, 0x60)) { + JHIReport("DEBUG: Write to Channel:%d , Offset:%05x , Size: %d\n", mChannel, mWriteOffset, 0x60); + } + } +} + +JHIMccBuf::~JHIMccBuf() { + mRefCount--; + if (mRefCount == 0) { + delete[] mTempBuf; + } +} + +void JHIMccBuf::setHeaderToBuf(u32 data, u32 position, u16 size) { + u8* ptr = mTempBuf + position; + ptr[0] = (data >> 0x18) & 0xFF; + ptr[1] = (data >> 0x10) & 0xFF; + ptr[2] = (data >> 0x08) & 0xFF; + ptr[3] = (data >> 0x00) & 0xFF; + + for (int i = 4; i < size; i++) { + ptr[i] = 0; + } +} + +// NONMATCHING - storing var_r28 to stack instead of register +u32 JHIMccBuf::setDataToBuf(void* pData, u16 size) { + u8* temp_buf = mTempBuf; + u32 i; + u8* data_buf = (u8*)pData; + + temp_buf[0] = (mTag >> 0x18) & 0xFF; + temp_buf[1] = (mTag >> 0x10) & 0xFF; + temp_buf[2] = (mTag >> 0x08) & 0xFF; + temp_buf[3] = (mTag >> 0x00) & 0xFF; + temp_buf[4] = (size >> 0x8) & 0xFF; + temp_buf[5] = size & 0xFF; + + for (i = 0; i < size; i++) { + temp_buf[6 + i] = data_buf[i]; + } + + u32 var_r28 = (size + 0x25) & ~0x1F; + for (i = size + 6; i < var_r28; i++) { + temp_buf[i] = 0; + } + + return var_r28; +} + +int JHIMccBuf::readData(u32 position, u32* pOutData) { + u8* temp_buf = mTempBuf; + u32 var_r30 = position; + + if (!JHIMCCRead(mChannel, var_r30, temp_buf, 0x20)) { + return 0; + } + + *pOutData = (temp_buf[0 + (position - var_r30)] << 0x18) | + (temp_buf[1 + (position - var_r30)] << 0x10) | + (temp_buf[2 + (position - var_r30)] << 0x08) | + (temp_buf[3 + (position - var_r30)] << 0x00); + return 1; +} + +int JHIMccBuf::readDataFromBuf(void* pBuf, u32 size) { + u8* temp_buf = mTempBuf; + u8* u_buf = (u8*)pBuf; + + u32 var_r28; + u32 var_r27 = 0; + u32 var_r26 = 0; + u32 var_r30 = 0; + while (var_r30 < size) { + u32 sp10 = (temp_buf[0 + var_r30] << 0x18) | + (temp_buf[1 + var_r30] << 0x10) | + (temp_buf[2 + var_r30] << 0x08) | + (temp_buf[3 + var_r30] << 0x00); + if (sp10 != mTag) { + return 0; + } + + var_r26 = (temp_buf[4 + var_r30] << 0x8) | + (temp_buf[5 + var_r30] << 0x0); + if (u_buf != NULL) { + for (var_r28 = 0; var_r28 < var_r26; var_r28++) { + u_buf[var_r27 + var_r28] = temp_buf[6 + (var_r30 + var_r28)]; + } + } + + var_r30 += (var_r26 + 0x25) & ~0x1F; + var_r27 += var_r26; + var_r26 = 0; + } + + return var_r27; +} + +int JHIMccBuf::JHIRead(u32 channel, u32 offset, void* buffer, u32 size) { + JHIReport("DEBUG: MCCRead(%d, %06x, %08x, %d);\n", channel, offset, buffer, size); + + if (!isPort()) { + memset(buffer, 0, size); + return 0; + } + + int attempts = 0; + DCInvalidateRange(buffer, size); + + if (offset & 3) { + disablePort(); + return 0; + } + + if (offset > (field_0x1c + field_0xc) * 2) { + OS_REPORT("ERROR: Illegal offset specified Error. -HIOWrite()\n"); + OS_REPORT("ERROR: offset: %08x low:%08x high:%08x\n", offset, 0, (field_0x1c + field_0xc) * 2); + disablePort(); + return 0; + } + +#if VERSION < VERSION_SHIELD_DEBUG + while (HIORead(offset + field_0x20, buffer, size) == 0 && attempts < 30) { + attempts++; + } +#else + while (HIO2Read(JHIGetHIO2Handle(), offset + field_0x20, buffer, size) == 0 && attempts < 30) { + attempts++; + } +#endif + + if (attempts >= 30) { + OS_REPORT("ERROR: Communication Error. -HIORead()\n"); + memset(buffer, 0, size); + disablePort(); + return 0; + } + + return 1; +} + +int JHIMccBuf::JHIWrite(u32 channel, u32 offset, void* buffer, u32 size) { + JHIReport("DEBUG: MCCWrite(%d, %06x, %08x, %d);\n", channel, offset, buffer, size); + + if (!isPort()) { + return 0; + } + + int attempts = 0; + DCFlushRange(buffer, size); + + if (offset & 3) { + disablePort(); + return 0; + } + + if (offset > (field_0x1c + field_0xc) * 2) { + OS_REPORT("ERROR: Illegal offset specified Error. -HIOWrite()\n"); + OS_REPORT("ERROR: offset: %08x low:%08x high:%08x\n", offset, 0, (field_0x1c + field_0xc) * 2); + disablePort(); + return 0; + } + +#if VERSION < VERSION_SHIELD_DEBUG + while (HIOWrite(offset + field_0x20, buffer, size) == 0 && attempts < 30) { + attempts++; + } +#else + while (HIO2Write(JHIGetHIO2Handle(), offset + field_0x20, buffer, size) == 0 && attempts < 30) { + attempts++; + } +#endif + + if (attempts >= 30) { + JHIReport("ERROR: Communication Error. -HIOWrite()\n"); + disablePort(); + return 0; + } + + return 1; +} + +int JHIMccBuf::JHIMCCRead(u32 channel, u32 offset, void* buffer, u32 size) { + JHIReport("DEBUG: JHIMCCRead(%d, %06x, %08x, %d);\n", channel, offset, buffer, size); + if (!JHIRead(channel, offset, buffer, size)) { + return 0; + } + + return 1; +} + +int JHIMccBuf::JHIMCCWrite(u32 channel, u32 offset, void* buffer, u32 size) { + JHIReport("DEBUG: JHIMCCWrite(%d, %06x, %08x, %d);\n", channel, offset, buffer, size); + if (!JHIWrite(channel, offset, buffer, size)) { + return 0; + } + + return 1; +} + +JHIMccBufReader::JHIMccBufReader(u16 channel, u16 param_1, u32 param_2) + : JHIMccBuf(channel, param_1, param_2) {} + +JHIMccBufReader::~JHIMccBufReader() {} + +u32 JHIMccBufReader::available() { + u32 var_r30 = 0; + + if (!isPort()) { + return 0; + } + + if (!readData(mReadOffset + field_0x8, &mBeginPos)) { + return 0; + } + + if (!readData(mReadOffset + field_0xa, &mEndPos)) { + return 0; + } + + if (mBeginPos < mEndPos) { + var_r30 = mEndPos - mBeginPos; + } else if (mBeginPos > mEndPos) { + var_r30 = field_0x1c - (mBeginPos - mEndPos); + } + + return var_r30; +} + +int JHIMccBufReader::readBegin() { + if (!isPort()) { + return 0; + } + + if (!readData(mReadOffset + field_0x8, &mBeginPos)) { + return 0; + } + + if (!readData(mReadOffset + field_0xa, &mEndPos)) { + return 0; + } + + JHIReport("DEBUG: readBegin: R:%08x W:%08x\n", mBeginPos, mEndPos); + return 1; +} + +int JHIMccBufReader::read(void* pBuf) { + if (!isPort()) { + return 0; + } + + u32 size; + int var_r28 = 0; + + if (mBeginPos < mEndPos) { + size = mEndPos - mBeginPos; + if (!JHIMCCRead(mChannel, mReadOffset + mBeginPos, mTempBuf, size)) { + return 0; + } + + var_r28 = readDataFromBuf(pBuf, size); + } else if (mBeginPos > mEndPos) { + size = field_0x1c - (mBeginPos - mEndPos); + u32 var_r25 = (field_0xc + field_0x1c); + u32 var_r27 = var_r25 - mBeginPos; + u32 var_r26 = size - var_r27; + + if (!JHIMCCRead(mChannel, mReadOffset + mBeginPos, mTempBuf, var_r27)) { + return 0; + } else if (var_r26 != 0) { + if (!JHIMCCRead(mChannel, mReadOffset + field_0xc, mTempBuf + var_r27, var_r26)) { + return 0; + } + } + + var_r28 = readDataFromBuf(pBuf, size); + } + + return var_r28; +} + +void JHIMccBufReader::readEnd() { + if (isPort()) { + setHeaderToBuf(mEndPos, 0, 0x20); + + JHIReport("DEBUG: readEnd: Point:%08x\n", mEndPos); + + if (!JHIMCCWrite(mChannel, mReadOffset + field_0x8, mTempBuf, 0x20)) { + return; + } + } +} + +JHIMccBufWriter::JHIMccBufWriter(u16 channel, u16 param_1, u32 param_2) + : JHIMccBuf(channel, param_1, param_2) {} + +JHIMccBufWriter::~JHIMccBufWriter() {} + +int JHIMccBufWriter::writeBegin() { + int var_r29 = 0; + + if (!isPort()) { + return 0; + } + + if (!readData(mWriteOffset + field_0x8, &mBeginPos)) { + return 0; + } + + if (!readData(mWriteOffset + field_0xa, &mEndPos)) { + return 0; + } + + u32 var_r30; + if (mBeginPos == field_0xc) { + var_r30 = field_0x1c + field_0xc; + var_r30 -= 0x20; + } else { + var_r30 = mBeginPos - 0x20; + } + + if (mEndPos > var_r30) { + var_r29 = (field_0x1c - (mEndPos - var_r30)) - 0x20; + } else if (mEndPos < var_r30) { + var_r29 = (var_r30 - mEndPos) - 0x20; + } + + JHIReport("DEBUG: writeBegin: R:%08x W:%08x\n", mBeginPos, mEndPos); + return var_r29; +} + +// NONMATCHING - regswap, equivalent +int JHIMccBufWriter::write(void* pBuffer, u32 size) { + if (!isPort()) { + return 0; + } + + u32 var_r29 = setDataToBuf(pBuffer, size); + + u32 var_r27; + if (mBeginPos == field_0xc) { + var_r27 = field_0x1c + field_0xc; + var_r27 -= 0x20; + } else { + var_r27 = mBeginPos - 0x20; + } + + u32 var_r26; + if (mEndPos > var_r27) { + var_r26 = field_0x1c - (mEndPos - var_r27); + u32 var_r28 = (field_0x1c + field_0xc) - mEndPos; + + if (var_r28 >= var_r29) { + if (!JHIMCCWrite(mChannel, mWriteOffset + mEndPos, mTempBuf, var_r29)) { + return 0; + } + + mEndPos += var_r29; + } else { + if (!JHIMCCWrite(mChannel, mWriteOffset + mEndPos, mTempBuf, var_r28)) { + return 0; + } else if (var_r29 - var_r28 != 0) { + if (!JHIMCCWrite(mChannel, mWriteOffset + field_0xc, mTempBuf + var_r28, var_r29 - var_r28)) { + return 0; + } + } + + mEndPos = field_0xc + (var_r29 - var_r28); + } + } else if (mEndPos < var_r27) { + var_r26 = var_r27 - mEndPos; + + if (!JHIMCCWrite(mChannel, mWriteOffset + mEndPos, mTempBuf, var_r29)) { + return 0; + } + + mEndPos += var_r29; + } + + if (mEndPos == field_0xc + field_0x1c) { + mEndPos = field_0xc; + } + + return var_r29; +} + +void JHIMccBufWriter::writeEnd() { + if (isPort()) { + setHeaderToBuf(mEndPos, 0, 0x20); + + JHIReport("DEBUG: writeEnd: Point:%08x\n", mEndPos); + + if (!JHIMCCWrite(mChannel, mWriteOffset + field_0xa, mTempBuf, 0x20)) { + return; + } + } +} diff --git a/src/JSystem/JHostIO/JHIMemBuf.cpp b/src/JSystem/JHostIO/JHIMemBuf.cpp new file mode 100644 index 00000000000..516ccedd51c --- /dev/null +++ b/src/JSystem/JHostIO/JHIMemBuf.cpp @@ -0,0 +1,69 @@ +#include "JSystem/JHostIO/JHICommonMem.h" +#include "JSystem/JKernel/JKRHeap.h" +#include + +int JHIMemBuf::create() { + int rt = 1; + if (mp_buffer == NULL) { + mp_buffer = new (32) u8[0x20000]; + + if (mp_buffer == NULL) { + rt = 0; + OS_REPORT("ERROR: hioSync Alloc Mem NG!\n"); + } else { + OS_REPORT("INFO: hioSync Alloc Mem OK! %08x\n", mp_buffer); + } + } + + return rt; +} + +int JHIMemBuf::open() { + return 1; +} + +void JHIMemBuf::close() { + if (mp_buffer != NULL) { + delete[] mp_buffer; + } +} + +JHIMemBuf::~JHIMemBuf() { + close(); +} + +u8* JHIMemBuf::getPointer() const { + return mp_buffer; +} + +u32 JHIMemBuf::readIO(u32 position) const { + u32 data; + readIO(position, &data); + return data; +} + +void JHIMemBuf::readIO(u32 position, u32* out_data) const { + u8* read_ptr = getPointer() + position; + *out_data = (read_ptr[0] << 0x18) | + (read_ptr[1] << 0x10) | + (read_ptr[2] << 0x08) | + (read_ptr[3] << 0x00); +} + +void JHIMemBuf::writeIO(u32 position, u8* src_data, u32 length) const { + u8* write_ptr = getPointer() + position; + + while (--length != 0) { + *write_ptr = *src_data++; + write_ptr++; + } +} + +void JHIMemBuf::writeIO(u32 position, u32 data) const { + u8* write_ptr = getPointer() + position; + + *write_ptr++ = data >> 0x18; + *write_ptr++ = data >> 0x10; + *write_ptr++ = data >> 0x08; + *write_ptr++ = data >> 0x00; +} diff --git a/src/JSystem/JHostIO/JHIRMcc.cpp b/src/JSystem/JHostIO/JHIRMcc.cpp new file mode 100644 index 00000000000..0edb01506da --- /dev/null +++ b/src/JSystem/JHostIO/JHIRMcc.cpp @@ -0,0 +1,132 @@ +#include "JSystem/JHostIO/JHIMccBuf.h" + +enum HIO2DeviceType { + DEVICE_INVALID = -1, +}; + +typedef BOOL (*HIO2EnumCallback)(HIO2DeviceType); +typedef void (*HIO2DisconnectCallback)(s32); + +extern "C" BOOL HIO2Init(); +extern "C" BOOL HIO2EnumDevices(HIO2EnumCallback); +extern "C" BOOL HIO2Close(s32); +extern "C" s32 HIO2Open(HIO2DeviceType, int, HIO2DisconnectCallback); + +HIO2DeviceType gExiDevice = DEVICE_INVALID; +u8 data_8074bd04 = 1; + +s32 ghHIO2; +JHIMccContext tContext_old; +JHIMccContext tContext_new; +bool data_8074d138; +u8 data_8074d139; + +BOOL JHIhio2CallbackEnum(HIO2DeviceType type) { + gExiDevice = type; + return 0; +} + +void JHIhio2DisconnectCallback(s32) { + gExiDevice = DEVICE_INVALID; +} + +u32 JHIInitInterface() { + if (data_8074bd04) { + if (!HIO2Init()) { + return 0; + } + + if (!HIO2EnumDevices(JHIhio2CallbackEnum)) { + return 0; + } + + data_8074bd04 = 0; + } + + if (gExiDevice == DEVICE_INVALID) { + return 0; + } + + if (data_8074d139 != 0) { + HIO2Close(ghHIO2); + data_8074d139 = 0; + } + + if (data_8074d139 == 0) { + ghHIO2 = HIO2Open(gExiDevice, 0, JHIhio2DisconnectCallback); + if (ghHIO2 == -1) { + return 0; + } + + data_8074d139 = 1; + } + + return 1; +} + +bool JHINegotiateInterface(u32) { + return 0; +} + +JHIMccContext JHIGetHiSpeedContext() { + if (tContext_new.mp_reader == NULL) { + tContext_new.mp_reader = new JHIMccBufReader(1, 0x18, 0x6000); + } + + if (tContext_new.mp_writer == NULL) { + tContext_new.mp_writer = new JHIMccBufWriter(1, 0x18, 0x6000); + } + + return tContext_new; +} + +JHIMccContext JHIGetLowSpeedContext() { + if (tContext_old.mp_reader == NULL) { + tContext_old.mp_reader = new JHIMccBufReader(1, 2, 0); + } + + if (tContext_old.mp_writer == NULL) { + tContext_old.mp_writer = new JHIMccBufWriter(1, 2, 0); + } + + return tContext_old; +} + +BOOL JHIInitMCC(JHIMccContext* pCtx, bool* param_1) { + JHIGetHiSpeedContext(); + JHIGetLowSpeedContext(); + + if (!JHIInitInterface()) { + *pCtx = tContext_old; + return FALSE; + } + + data_8074d138 = JHINegotiateInterface(800); + if (data_8074d138) { + tContext_new.mp_reader->enablePort(); + tContext_new.mp_writer->enablePort(); + tContext_new.mp_reader->init(); + tContext_new.mp_writer->init(); + } else { + tContext_old.mp_reader->enablePort(); + tContext_old.mp_writer->enablePort(); + tContext_old.mp_reader->init(); + tContext_old.mp_writer->init(); + } + + if (param_1 != NULL) { + *param_1 = data_8074d138; + } + + if (data_8074d138) { + *pCtx = tContext_new; + } else { + *pCtx = tContext_old; + } + + return TRUE; +} + +s32 JHIGetHIO2Handle() { + return ghHIO2; +} diff --git a/src/JSystem/JHostIO/JHIhioASync.cpp b/src/JSystem/JHostIO/JHIhioASync.cpp new file mode 100644 index 00000000000..ea469905799 --- /dev/null +++ b/src/JSystem/JHostIO/JHIhioASync.cpp @@ -0,0 +1,167 @@ +#include "JSystem/JHostIO/JHIMccBuf.h" +#include "JSystem/JHostIO/JHIRMcc.h" +#include + +u32 gsEnableHostio; +u32 gsEnableInterface; +u32 gsDataToRead; + +u8* gsReadBuf; +u8* gsWriteBuf; +JHICommBufReader* gsJHIrecvBuf; +JHICommBufWriter* gsJHIsendBuf; + +JHIMccContext gMccContext; + +BOOL JHIInit(u32 enabled) { + gsEnableHostio = enabled; + gsDataToRead = 0; + gsEnableInterface = TRUE; + + if (gsEnableHostio) { + OS_REPORT("INFO:********************************\n"); + OS_REPORT("INFO: Opening Hostio service...\n"); + + if (!JHIInitMCC(&gMccContext, NULL)) { + gsEnableInterface = FALSE; + OS_REPORT("ERROR: Cannot Open HostIO Interface..\n"); + OS_REPORT("INFO: *** Disable JHostIO ***\n"); + } + + gsReadBuf = new (32) u8[0xC000]; + gsWriteBuf = new (32) u8[0xC000]; + + if (gsReadBuf == NULL || gsWriteBuf == NULL) { + gsEnableInterface = FALSE; + OS_REPORT("ERROR: Cannot alloc transport buffer..\n"); + OS_REPORT("INFO: *** Disable JHostIO ***\n"); + } + } + + return gsEnableInterface && gsEnableHostio; +} + +static void dummyString() { + DEAD_STRING("INFO:Quitting Hostio..."); +} + +// NONMATCHING - small branch issue +u32 JHIEventLoop() { + static u32 tNowWrite; + static u32 tNowRead; + static u8* tReadBuf; + static u8* tWriteBuf; + + int var_r30; + u32 available_size; + + if (gsEnableHostio && gsEnableInterface) { + if (tNowRead != 0) { + var_r30 = gsJHIsendBuf->writeBegin(); + if (var_r30 >= tNowRead) { + gsJHIsendBuf->write(tReadBuf, tNowRead); + gsJHIsendBuf->writeEnd(); + tNowRead = 0; + tReadBuf = gsReadBuf; + } else if (var_r30 != 0) { + gsJHIsendBuf->write(tReadBuf, var_r30); + gsJHIsendBuf->writeEnd(); + tNowRead -= var_r30; + tReadBuf += var_r30; + } + } else { + available_size = gMccContext.mp_reader->available(); + if (available_size != 0) { + JHIReport("DEBUG: Dolphin <- PC Data Available : Size:%d\n", available_size); + gMccContext.mp_reader->readBegin(); + + u32 var_r27 = gMccContext.mp_reader->read(gsReadBuf); + if (var_r27 != 0) { + gMccContext.mp_reader->readEnd(); + tNowRead = 0; + tReadBuf = gsReadBuf; + + u32 var_r28 = gsJHIsendBuf->writeBegin(); + if (var_r28 >= var_r27) { + gsJHIsendBuf->write(tReadBuf, var_r27); + gsJHIsendBuf->writeEnd(); + } else { + if (var_r28 != 0) { + gsJHIsendBuf->write(tReadBuf, var_r28); + gsJHIsendBuf->writeEnd(); + } + tNowRead = var_r27 - var_r28; + tReadBuf = gsReadBuf + var_r28; + } + } + } + } + + if (tNowWrite != 0) { + var_r30 = gMccContext.mp_writer->writeBegin(); + if (var_r30 > tNowWrite) { + gMccContext.mp_writer->write(tWriteBuf, tNowWrite); + gMccContext.mp_writer->writeEnd(); + tNowWrite = 0; + tWriteBuf = gsWriteBuf; + } else if (var_r30 != 0) { + gMccContext.mp_writer->write(tWriteBuf, var_r30); + gMccContext.mp_writer->writeEnd(); + tNowWrite -= var_r30; + tWriteBuf += var_r30; + } + } else { + available_size = gsJHIrecvBuf->available(); + if (available_size != 0) { + JHIReport("DEBUG: Dolphin -> PC Data Available : Size:%d\n", available_size); + + u32 temp_r26 = available_size < 0xC000 ? available_size : 0xC000; + gsJHIrecvBuf->readBegin(); + gsJHIrecvBuf->read(gsWriteBuf, temp_r26); + gsJHIrecvBuf->readEnd(); + tNowWrite = 0; + tWriteBuf = gsWriteBuf; + + var_r30 = gMccContext.mp_writer->writeBegin(); + if (var_r30 > temp_r26) { + gMccContext.mp_writer->write(tWriteBuf, temp_r26); + gMccContext.mp_writer->writeEnd(); + } else if (var_r30 != 0) { + gMccContext.mp_writer->write(tWriteBuf, var_r30); + gMccContext.mp_writer->writeEnd(); + tNowWrite = temp_r26 - var_r30; + tWriteBuf = gsWriteBuf + var_r30; + } + } + } + + if (!gMccContext.mp_reader->isPort() || !gMccContext.mp_writer->isPort()) { + gsEnableInterface = 0; + } + } else if (!gsEnableInterface && gsEnableHostio != 0 && JHIInitInterface()) { + OS_REPORT("INFO: JHostIO: Enabled USB2EXI Interface\n"); + bool sp8 = JHINegotiateInterface(800); + if (sp8) { + gMccContext = JHIGetHiSpeedContext(); + } else { + gMccContext = JHIGetLowSpeedContext(); + } + + gMccContext.mp_reader->enablePort(); + gMccContext.mp_writer->enablePort(); + gMccContext.mp_reader->init(); + gMccContext.mp_writer->init(); + gsEnableInterface = TRUE; + } + + return 0; +} + +BOOL JOR_CHECKINTERFACE() { + return (gsEnableInterface && gsEnableHostio) != 0; +} + +void JHISetBuffer(JHIContext* pCtx) { + gsJHIrecvBuf = pCtx->mp_reader; + gsJHIsendBuf = pCtx->mp_writer; +} diff --git a/src/JSystem/JHostIO/JOREntry.cpp b/src/JSystem/JHostIO/JOREntry.cpp new file mode 100644 index 00000000000..5c90b5f77d4 --- /dev/null +++ b/src/JSystem/JHostIO/JOREntry.cpp @@ -0,0 +1,22 @@ +#include "JSystem/JHostIO/JORServer.h" +#include "JSystem/JHostIO/JOREntry.h" +#include "JSystem/JHostIO/JHIhioASync.h" + +void JORInit() { + JHIInit(TRUE); + + JHICommBufWriter* pComWriter = new JHICommBufWriter(0x10000, 0x10000, 4); + JHICommBufReader* pComReader = new JHICommBufReader(0, 0x10000, 4); + + JHIContext ctx; + ctx.mp_reader = new JHICommBufReader(0x10000, 0x10000, 4); + ctx.mp_writer = new JHICommBufWriter(0, 0x10000, 4); + + JHIComPortManager* pPortMng = JHIComPortManager::create(); + pPortMng->getRefPort().setBuf(pComReader, pComWriter); + JHISetBuffer(&ctx); + + JORServer* pServer = JORServer::create(); + pPortMng->addTag(pServer); + pServer->sendReset(); +} diff --git a/src/JSystem/JHostIO/JORFile.cpp b/src/JSystem/JHostIO/JORFile.cpp new file mode 100644 index 00000000000..94a1979443f --- /dev/null +++ b/src/JSystem/JHostIO/JORFile.cpp @@ -0,0 +1,182 @@ +#include "JSystem/JHostIO/JORFile.h" +#include "JSystem/JHostIO/JORServer.h" +#include + +JORFile::JORFile() +: mHandle(0), + mFileLength(0), + mStatus(EStatus_WAIT), + mNFileName(0), + field_0x18(0) {} + +int JORFile::countMaskSize(const char* mask) { + u32 var_r28 = 0; + u32 var_r30 = 0; + + while (true) { + u32 var_r27 = var_r30; + + while (mask[var_r30] != 0) { + var_r30++; + if (var_r30 - var_r27 > 0xFF) { + return 0; + } + } + + var_r30++; + while (mask[var_r30] != 0) { + var_r30++; + if (var_r30 - var_r27 > 0xFF) { + return 0; + } + } + + var_r30++; + if (mask[var_r30] == 0) { + return var_r30 + 1; + } + + var_r28++; + if (var_r28 > 0x28) { + return 0; + } + } +} + +void JORFile::waitMessage_() { + while (mStatus == EStatus_WAIT) { + JOR_MESSAGELOOP(); + } +} + +int JORFile::open(const char* path, u32 flags, const char* extMask, const char* defaultExt, const char* param_4, const char* fileSuffix) { + if (mHandle != 0) { + return 0; + } + + mStatus = EStatus_WAIT; + mFlags = flags; + + if (extMask == NULL) { + extMask = ""; + } + + u32 mask_size = countMaskSize(extMask); + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO); + mctx->openFile(this, mFlags, path, extMask, mask_size, defaultExt, param_4, fileSuffix); + JORServer::getInstance()->releaseMCTX(mctx); + + waitMessage_(); + + if (mHandle == 0) { + return 0; + } + + return 1; +} + +// NONMATCHING, equivalent? +void JORFile::close() { + if (mHandle != 0) { + mStatus = EStatus_WAIT; + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO); + mctx->closeFile(this); + JORServer::getInstance()->releaseMCTX(mctx); + + waitMessage_(); + mHandle = 0; + } +} + +void JORFile::readBegin_(s32 len) { + mStatus = EStatus_WAIT; + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO); + mctx->readBegin(this, len); + JORServer::getInstance()->releaseMCTX(mctx); + + waitMessage_(); +} + +void JORFile::readLoop_() { + mStatus = EStatus_WAIT; + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO); + mctx->readData(this); + JORServer::getInstance()->releaseMCTX(mctx); + + waitMessage_(); +} + +s32 JORFile::readData(void* buffer, s32 length) { + if (mHandle == 0) { + return 0; + } + + s32 len = length == 0 ? mFileLength : length; + setBuffer(buffer, len); + readBegin_(len); + + do { + readLoop_(); + if (mStatus == EStatus_READ_BEGIN) { + setBuffer(NULL, 0); + return 0; + } + } while (mStatus != EStatus_WRITE_END); + + setBuffer(NULL, 0); + DCFlushRange(buffer, len); + return len; +} + +void JORFile::setBuffer(void* buffer, s32 length) { + mDataStream.setBuffer(buffer, length); +} + +void JORFile::writeBegin_(s32 len) { + mStatus = EStatus_WAIT; + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO); + mctx->writeBegin(this, mFlags, len); + JORServer::getInstance()->releaseMCTX(mctx); + + waitMessage_(); +} + +void JORFile::writeLoop_(const void* pBuffer, s32 size, u32 pos) { + mStatus = EStatus_WAIT; + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO); + mctx->writeData(this, pBuffer, size, pos); + JORServer::getInstance()->releaseMCTX(mctx); + + waitMessage_(); +} + +void JORFile::writeDone_(s32 len) { + mStatus = EStatus_WAIT; + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_FIO); + mctx->writeDone(this, len); + JORServer::getInstance()->releaseMCTX(mctx); + + waitMessage_(); +} + +s32 JORFile::writeData(const void* buffer, s32 length) { + if (mHandle == 0) { + return 0; + } + + s32 len = length == 0 ? mFileLength : length; + writeBegin_(len); + + u32 pos = 0; + s32 size = 0; + u8* buf_start = (u8*)buffer; + do { + size = len - pos > 0xF00 ? 0xF00 : len - pos; + writeLoop_(buf_start + pos, size, pos); + + pos += size; + } while (len - pos != 0); + + writeDone_(len); + return len; +} diff --git a/src/JSystem/JHostIO/JORHostInfo.cpp b/src/JSystem/JHostIO/JORHostInfo.cpp new file mode 100644 index 00000000000..6ba8b221bb5 --- /dev/null +++ b/src/JSystem/JHostIO/JORHostInfo.cpp @@ -0,0 +1,56 @@ +#include "JSystem/JHostIO/JORHostInfo.h" +#include "JSystem/JHostIO/JORServer.h" + +// End of each month in standard year +static s32 YearDays[] = { + 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, +}; + +// End of each month in leap year +static s32 LeapYearDays[] = { + 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, +}; + +static BOOL IsLeapYear(int year) { + return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0); +} + +BOOL JORGetYearDays(int year, int mon) { + s32* days = IsLeapYear(year) ? LeapYearDays : YearDays; + return days[mon]; +} + +bool JORGetHostInfo(u32 request_type, JORHostInfo* pHostinfo) { + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_GET_HOST_INFO); + mctx->sendHostInfoRequest(request_type, pHostinfo); + JORServer::getInstance()->releaseMCTX(mctx); + + while (pHostinfo->getResult() == 0) { + JOR_MESSAGELOOP(); + } + + return pHostinfo->getResult() == 1; +} + +void JORGetComputerName(char* buffer, u32 buffer_size) { + JORHostInfo_String string; + string.setStringBuffer(buffer); + string.setBufferSize(buffer_size); + + JORGetHostInfo(HOSTINFO_REQ_COMPUTER_NAME, &string); +} + +void JORGetUserName(char* buffer, u32 buffer_size) { + JORHostInfo_String string; + string.setStringBuffer(buffer); + string.setBufferSize(buffer_size); + + JORGetHostInfo(HOSTINFO_REQ_USERNAME, &string); +} + +void JORGetLocalTime(OSCalendarTime* pCalendarTime) { + JORHostInfo_CalendarTime calendar_time; + calendar_time.setCalendarTimeBuffer(pCalendarTime); + + JORGetHostInfo(HOSTINFO_REQ_LOCAL_TIME, &calendar_time); +} diff --git a/src/JSystem/JHostIO/JORMessageBox.cpp b/src/JSystem/JHostIO/JORMessageBox.cpp new file mode 100644 index 00000000000..16884b4542c --- /dev/null +++ b/src/JSystem/JHostIO/JORMessageBox.cpp @@ -0,0 +1,14 @@ +#include "JSystem/JHostIO/JORServer.h" + +u32 JORMessageBox(const char* message, const char* title, u32 style) { + u32 status = 0; + JORMContext* mctx = JORServer::getInstance()->attachMCTX(MCTX_MSG_OPEN_MESSAGE_BOX); + mctx->openMessageBox(&status, style, message, title); + JORServer::getInstance()->releaseMCTX(mctx); + + while (status == 0) { + JOR_MESSAGELOOP(); + } + + return status; +} diff --git a/src/JSystem/JHostIO/JORServer.cpp b/src/JSystem/JHostIO/JORServer.cpp new file mode 100644 index 00000000000..75935dc2ae2 --- /dev/null +++ b/src/JSystem/JHostIO/JORServer.cpp @@ -0,0 +1,820 @@ +#include "JSystem/JHostIO/JORServer.h" +#include "JSystem/JHostIO/JORReflexible.h" +#include "JSystem/JHostIO/JORFile.h" +#include "JSystem/JHostIO/JORHostInfo.h" +#include "JSystem/JSupport/JSUMemoryStream.h" +#include + +void JOREventCallbackListNode::JORAppend() { + JORServer* pServer = JORServer::getInstance(); + JUT_ASSERT(51, pServer!=0); + pServer->appendEventCallbackListNode(this); +} + +void JOREventCallbackListNode::JORRemove() { + JORServer* pServer = JORServer::getInstance(); + JUT_ASSERT(57, pServer!=0); + pServer->removeEventCallbackListNode(this); +} + +JOREventCallbackListNode::JOREventCallbackListNode(u32 param_0, u32 param_1, bool append) { + field_0xc = param_0; + field_0x10 = param_1; + + if (append) { + JORAppend(); + } +} + +JOREventCallbackListNode::~JOREventCallbackListNode() { + JORRemove(); +} + +void JORReflexible::listen(u32 command, const JOREvent* event) { + switch (command) { + case JORServer::ECommand_GenObjInfo: + genObjectInfo((JORGenEvent*)event); + break; + case JORServer::ECommand_NodeEvent: + listenNodeEvent((JORNodeEvent*)event); + break; + case JORServer::ECommand_PropertyEvent: + listenPropertyEvent((JORPropertyEvent*)event); + break; + } +} + +void JORReflexible::genObjectInfo(const JORGenEvent* event) { + JORMContext* mctx = getJORServer()->attachMCTX(MCTX_MSG_GEN_OBJ_INFO); + mctx->startNode("", this, 0, 0); + genMessage(mctx); + mctx->endNode(); + getJORServer()->releaseMCTX(mctx); +} + +void JORReflexible::listenNodeEvent(const JORNodeEvent*) {} + +void JORReflexible::listenPropertyEvent(const JORPropertyEvent* pEvent) { + if (pEvent->kind & JORPropertyEvent::EKind_HasListener) { + JORServer* pServer = getJORServer(); + + JORPropertyEvent* event = (JORPropertyEvent*)pEvent; + event->kind &= ~JORPropertyEvent::EKind_HasListener; + + switch (pEvent->type) { + case 'RNGf': + case 'RNGi': + case 'RBTN': + case 'CMBX': + if (pEvent->field_0x14 >= 4) { + pEvent->field_0x10->listenPropertyEvent(pEvent); + } + break; + case 'CHBX': + if (pEvent->field_0x14 >= 4) { + pEvent->field_0x10->listenPropertyEvent(pEvent); + } + break; + case 'EDBX': + case 'BUTN': + pEvent->field_0x10->listenPropertyEvent(pEvent); + break; + } + + event->kind |= JORPropertyEvent::EKind_HasListener; + } else if (!(pEvent->kind & JORPropertyEvent::EKind_ValueID)) { + switch (pEvent->type) { + case 'RBTN': + case 'RNGi': + case 'RNGf': + case 'CMBX': + if (pEvent->field_0x14 >= 4) { + JORPropertyEvent* event = (JORPropertyEvent*)pEvent; + JORServer::defSetVal(event->field_0xc, event->kind, event->field_0x18.U32); + } + break; + case 'CHBX': + if (pEvent->field_0x14 >= 4) { + JORPropertyEvent* event = (JORPropertyEvent*)pEvent; + JORServer::defSetBitVal(event->field_0xc, event->kind, (u16)event->field_0x18.U16[0], (u16)event->field_0x18.U16[1]); + } + break; + case 'EDBX': + JORPropertyEvent* event = (JORPropertyEvent*)pEvent; + JSUMemoryInputStream stream(&event->field_0x18, event->field_0x14); + stream >> event->field_0xc; + break; + } + return; + } +} + +JORServer* JORServer::instance; + +JORServer* JORServer::create() { + if (instance == NULL) { + instance = new JORServer(); + } + + return instance; +} + +void JORServer::defSetVal(void* ptr, u32 kind, s32 val) { + switch (jhostio::GetEKindSize(kind)) { + case jhostio::EKind_8B: + *(u8*)ptr = val; + break; + case jhostio::EKind_16B: + *(u16*)ptr = val; + break; + case jhostio::EKind_32B: + *(u32*)ptr = val; + break; + } +} + +void JORServer::defSetBitVal(void* ptr, u32 kind, u16 param_2, u16 param_3) { + param_2 &= param_3; + + switch (jhostio::GetEKindSize(kind)) { + case jhostio::EKind_8B: { + u8* kptr = (u8*)ptr; + *kptr &= (u8)~param_3; + *kptr |= (u8)param_2; + break; + } + case jhostio::EKind_16B: { + u16* kptr = (u16*)ptr; + *kptr &= (u16)~param_3; + *kptr |= param_2; + } + } +} + +JORMContext* JORServer::attachMCTX(u32 msgID) { + m_context.bufInit(); + m_context.putMsgID(msgID); + return &m_context; +} + +void JORServer::releaseMCTX(JORMContext* mctx) { + ASSERTMSGLINE(292, mctx->msgSize() < 0x10000, "JORServer:releaseMCTX: context buffer probably overflowed.\n"); + + if (mctx->msgSize() > 4) { + const void* var_r28 = send(mctx->msgPtr(), mctx->msgSize()); + } +} + +void JORServer::receive(const char* pBuffer, s32 length) { + JSUMemoryInputStream stream(pBuffer, length); + + u32 command; + stream >> command; + + if (!stream.isGood()) { + OS_REPORT("JORServer::receive : データが足りない\n"); + OS_REPORT("JORServer::receive : データが足りない\n"); + return; + } + + switch (command) { + case ECommand_GetRootObj: + if (mp_rootObj != NULL) { + OS_REPORT("Get RootObject ref(%08X)\n", mp_rootObj); + m_context.bufInit(); + m_context.putMsgID(MCTX_MSG_GET_ROOT_OBJ); + m_context.genRootNode(m_rootName, mp_rootObj, field_0x10064, field_0x10068); + send(m_context.msgPtr(), m_context.msgSize()); + } + break; + case ECommand_NodeEvent: { + u32 obj_addr; + stream.read(obj_addr); + JORNodeEvent* pEvent = (JORNodeEvent*)(pBuffer + stream.getPosition()); + stream.skip(4); + + if (stream.isGood()) { + reinterpret_cast(obj_addr)->listen(command, pEvent); + } + } + break; + case ECommand_PropertyEvent: { + u32 obj_addr; + stream.read(obj_addr); + JORPropertyEvent* pEvent = (JORPropertyEvent*)(pBuffer + stream.getPosition()); + stream.skip(0x18); + + if (stream.isGood()) { + stream.skip(pEvent->field_0x14); + } + + if (stream.isGood()) { + reinterpret_cast(obj_addr)->listen(command, pEvent); + } + } + break; + case ECommand_GenObjInfo: { + u32 obj_addr; + stream.read(obj_addr); + + if (stream.isGood()) { + reinterpret_cast(obj_addr)->listen(command, NULL); + } + } + break; + case ECommand_FIO: + fio_dispatchMessage_(stream); + break; + case ECommand_DIR: + dir_dispatchMessage_(stream); + break; + case ECommand_ReadResultS32: + readResultS32_(stream); + break; + case ECommand_HostInfo: + hostinfo_dispatchMessage_(stream); + break; + case ECommand_ReadResultU32: + readResultU32_(stream); + break; + case ECommand_ReadOrEvent: + readOrEvent_(stream); + break; + } +} + +void JORServer::fio_openFile_(JSUMemoryInputStream& stream) { + u32 file_addr; + stream >> file_addr; + JORFile* file = (JORFile*)file_addr; + + u32 handle; + stream >> handle; + + u32 file_len; + stream >> file_len; + + u16 filename_len; + u16 basename_len; + u16 extension_name_len; + stream >> filename_len >> basename_len >> extension_name_len; + + strncpy(file->getFilename(), (const char*)stream.getPointer(), filename_len); + file->getFilename()[filename_len] = 0; + + file->setHandle(handle); + file->setFileLength(file_len); + file->setNFileName((u16)filename_len); + file->setNBaseName((u16)basename_len); + file->setNExtensionName((u16)extension_name_len); + file->setStatus(JORFile::EStatus_READ_DATA); +} + +void JORServer::fio_closeFile_(JSUMemoryInputStream& stream) { + u32 file_addr; + stream >> file_addr; + JORFile* file = (JORFile*)file_addr; + + u32 sp8; + stream >> sp8; + + if (sp8 == 0) { + OS_REPORT("Close Failed!\n"); + } + + file->setStatus(JORFile::EStatus_READ_END); +} + +void JORServer::fio_readData_(JSUMemoryInputStream& stream) { + u32 file_addr; + stream >> file_addr; + JORFile* file = (JORFile*)file_addr; + + u32 status; + stream >> status; + + if (status == JORFile::EStatus_READ_BEGIN) { + file->setStatus(status); + } else if (status == JORFile::EStatus_WRITE_BEGIN) { + file->setStatus(status); + } else if (status == JORFile::EStatus_WRITE_DATA) { + u32 position, data; + stream >> position >> data; + file->getDataStream().seek(position, JSUStreamSeekFrom_SET); + + file->getDataStream().write(stream.getPointer(), data); + file->setStatus(status); + } else if (status == JORFile::EStatus_WRITE_END) { + file->setStatus(status); + } +} + +void JORServer::fio_writeData_(JSUMemoryInputStream& stream) { + u32 file_addr; + stream >> file_addr; + JORFile* file = (JORFile*)file_addr; + + u32 status; + stream >> status; + + file->setStatus(status); +} + +void JORServer::fio_dispatchMessage_(JSUMemoryInputStream& stream) { + u32 command; + stream >> command; + + switch (command) { + case JORFile::ECommand_OPEN: + fio_openFile_(stream); + break; + case JORFile::ECommand_CLOSE: + fio_closeFile_(stream); + break; + case JORFile::ECommand_READ: + fio_readData_(stream); + break; + case JORFile::ECommand_WRITE: + fio_writeData_(stream); + break; + } +} + +void JORServer::dir_dispatchMessage_(JSUMemoryInputStream& stream) { + u32 command, status, dir_addr; + stream >> command >> dir_addr >> status; + + JORDir* dir = (JORDir*)dir_addr; + dir->setStatus(status); + + if (status != 2) { + switch (command) { + case 1: + break; + case 2: + dir_findFirstFile_(stream, dir); + break; + case 3: + dir_findNextFile_(stream, dir); + break; + case 0: + dir_browseForFolder_(stream, dir); + break; + case 5: + dir_browseForFolder_(stream, dir); + break; + } + } +} + +void JORServer::dir_findFirstFile_(JSUMemoryInputStream& stream, JORDir* directory) { + char namebuf[256]; + u32 attribute, lo_time, hi_time, handle; + stream >> handle >> attribute >> lo_time >> hi_time >> namebuf; + + directory->setFindHandle(handle); + directory->setFileAttribute(attribute); + directory->setLowDateTime(lo_time); + directory->setHighDateTime(hi_time); + strncpy(directory->getFilename(), namebuf, sizeof(namebuf) - 1); +} + +void JORServer::dir_findNextFile_(JSUMemoryInputStream& stream, JORDir* directory) { + char namebuf[256]; + u32 attribute, lo_time, hi_time; + stream >> attribute >> lo_time >> hi_time >> namebuf; + + directory->setFileAttribute(attribute); + directory->setLowDateTime(lo_time); + directory->setHighDateTime(hi_time); + strncpy(directory->getFilename(), namebuf, sizeof(namebuf) - 1); +} + +void JORServer::dir_browseForFolder_(JSUMemoryInputStream& stream, JORDir* directory) { + char namebuf[256]; + u32 attribute, lo_time, hi_time; + stream >> attribute >> lo_time >> hi_time >> namebuf; + + directory->setFileAttribute(attribute); + directory->setLowDateTime(lo_time); + directory->setHighDateTime(hi_time); + strncpy(directory->getFilename(), namebuf, sizeof(namebuf) - 1); +} + +void JORServer::hostinfo_dispatchMessage_(JSUMemoryInputStream& stream) { + u32 command, spC, hostinfo_addr; + stream >> command >> hostinfo_addr >> spC; + + JORHostInfo* hostinfo = (JORHostInfo*)hostinfo_addr; + hostinfo->setResult(spC != 0 ? 1 : 2); + + if (spC != 0) { + switch (command) { + case HOSTINFO_REQ_COMPUTER_NAME: + hostinfo_recvString_(stream, (JORHostInfo_String*)hostinfo); + break; + case HOSTINFO_REQ_USERNAME: + hostinfo_recvString_(stream, (JORHostInfo_String*)hostinfo); + break; + case HOSTINFO_REQ_LOCAL_TIME: + hostinfo_localTime_(stream, (JORHostInfo_CalendarTime*)hostinfo); + break; + } + } +} + +void JORServer::hostinfo_recvString_(JSUMemoryInputStream& stream, JORHostInfo_String* pString) { + char buffer[256]; + stream >> buffer; + strncpy(pString->getString(), buffer, pString->getBufferSize()); +} + +void JORServer::hostinfo_localTime_(JSUMemoryInputStream& stream, JORHostInfo_CalendarTime* pCalendarTime) { + u16 year, month, weekday, monthday, hours, minutes, seconds, milliseconds; + stream >> year + >> month + >> weekday + >> monthday + >> hours + >> minutes + >> seconds + >> milliseconds; + + OSCalendarTime* pTime = pCalendarTime->getCalendarTime(); + pTime->seconds = seconds; + pTime->minutes = minutes; + pTime->hours = hours; + pTime->day_of_month = monthday; + pTime->month = month - 1; + pTime->year = year; + pTime->week_day = weekday; + pTime->milliseconds = milliseconds; + pTime->microseconds = 0; + pTime->year_day = monthday + JORGetYearDays(year, month - 1); +} + +void JORServer::sendReset() { + u32 spC = JHIhtonl(0); + send(&spC, 4); +} + +void JORServer::setRootNode(const char* name, JORReflexible* node, u32 param_2, u32 param_3) { + mp_rootObj = node; + if (name == NULL) { + name = "ルート"; + } + + strncpy(m_rootName, name, sizeof(m_rootName) - 1); + m_rootName[sizeof(m_rootName) - 1] = 0; + field_0x10064 = param_2; + field_0x10068 = param_3; +} + +void JORServer::readResultU32_(JSUMemoryInputStream& stream) { + u32 ptr_addr, val; + stream >> ptr_addr >> val; + + u32* ptr = (u32*)ptr_addr; + *ptr = val; +} + +void JORServer::readResultS32_(JSUMemoryInputStream& stream) { + u32 ptr_addr, val; + stream >> ptr_addr >> val; + + s32* ptr = (s32*)ptr_addr; + *ptr = val; +} + +void JORServer::readOrEvent_(JSUMemoryInputStream& stream) { + if (m_eventDone) { + stream >> m_eventNum; + + u16 name_len; + stream >> name_len; + if (name_len >= 0x1000) { + name_len = 0x1000 - 1; + } + + stream.read(m_eventName, name_len); + m_eventName[name_len] = 0; + m_event = true; + } +} + +void JORServer::doneEvent() { + if (!m_eventDone) { + m_eventDone = true; + + u32 sp8 = JHIhtonl(0x10); + send(&sp8, 4); + } +} + +void JORMContext::genNodeSub(const char* name, JORReflexible* node, u32 param_2, u32 param_3) { + mOutputStream << name; + putNode(node); + + mOutputStream << param_2; + + if (param_2 & 4) { + mOutputStream << param_3; + } +} + +void JORMContext::endNode() { + mOutputStream << MCTX_COMMAND_END_NODE; +} + +void JORMContext::invalidNode(JORReflexible* node, u32 param_1) { + mOutputStream << MCTX_COMMAND_INVALID_NODE; + putNode(node); + + mOutputStream << param_1; +} + +void JORMContext::genControl(u32 type, u32 kind, const char* label, u32 style, u32 id, + JOREventListener* pListener, u32 initValue) +{ + mOutputStream << type << kind << label << style << id; + + if (kind & JORPropertyEvent::EKind_HasListener) { + mOutputStream << (u32)pListener; + } + + if ((kind & JORPropertyEvent::EKind_ValueID) && type != 'EDBX') { + kind |= 0x20; + } + + if (jhostio::GetEKindSize(kind) != 0) { + mOutputStream << initValue; + } +} + +void JORMContext::genSliderSub(u32 kind, const char* label, u32 id, u32 style, s32 initValue, s32 rangeMin, + s32 rangeMax, JOREventListener* pListener, u16 posX, u16 posY, + u16 width, u16 height) +{ + if (pListener != NULL) { + kind |= JORPropertyEvent::EKind_HasListener; + } + + mOutputStream << MCTX_COMMAND_GEN_CONTROL; + genControl(kind & JORPropertyEvent::EKind_FloatValue ? 'RNGf' : 'RNGi', kind, label, style, id, pListener, initValue); + + mOutputStream << rangeMin << rangeMax; + mOutputStream << posX << posY << width << height; +} + +void JORMContext::genCheckBoxSub(u32 kind, const char* label, u32 id, u32 style, u16 initValue, u16 mask, + JOREventListener* pListener, u16 posX, u16 posY, u16 width, + u16 height) +{ + if (pListener != NULL) { + kind |= JORPropertyEvent::EKind_HasListener; + } + + mOutputStream << MCTX_COMMAND_GEN_CONTROL; + genControl('CHBX', kind, label, style, id, pListener, (mask << 0x10) | initValue); + + mOutputStream << posX << posY << width << height; +} + +void JORMContext::startSelectorSub(u32 type, u32 kind, const char* label, u32 id, u32 style, s32 initValue, + JOREventListener* pListener, u16 posX, u16 posY, u16 width, + u16 height) +{ + if (pListener != NULL) { + kind |= JORPropertyEvent::EKind_HasListener; + } + + mOutputStream << MCTX_COMMAND_START_SELECTOR; + genControl(type, kind, label, style, id, pListener, initValue); + + mOutputStream << posX << posY << width << height; +} + +void JORMContext::endSelectorSub() { + mOutputStream << MCTX_COMMAND_END_SELECTOR; +} + +void JORMContext::genSelectorItemSub(const char* label, s32 itemNo, u32 param_2, u16 posX, + u16 posY, u16 width, u16 height) +{ + mOutputStream << MCTX_COMMAND_SELECTOR_ITEM << label << (u32)itemNo; + mOutputStream << param_2 << posX << posY << width << height; +} + +void JORMContext::genButton(const char* label, u32 id, u32 style, JOREventListener* pListener, + u16 posX, u16 posY, u16 width, u16 height) +{ + u32 kind = 0; + if (pListener != NULL) { + kind |= JORPropertyEvent::EKind_HasListener; + } + + mOutputStream << MCTX_COMMAND_GEN_CONTROL; + genControl('BUTN', kind, label, style, id, pListener, 0); + + mOutputStream << posX << posY << width << height; +} + +void JORMContext::genLabel(const char* label, u32 id, u32 style, JOREventListener* pListener, + u16 posX, u16 posY, u16 width, u16 height) +{ + u32 kind = 0; + if (pListener != NULL) { + kind |= JORPropertyEvent::EKind_HasListener; + } + + mOutputStream << MCTX_COMMAND_GEN_CONTROL; + genControl('LABL', kind, label, style, id, pListener, 0); + + mOutputStream << posX << posY << width << height; +} + +void JORMContext::genGroupBox(const char* label, u32 id, u32 style, JOREventListener* pListener, + u16 posX, u16 posY, u16 width, u16 height) +{ + u32 kind = 0; + if (pListener != NULL) { + kind |= JORPropertyEvent::EKind_HasListener; + } + + mOutputStream << MCTX_COMMAND_GEN_CONTROL; + genControl('GRBX', kind, label, style, id, pListener, 0); + + mOutputStream << posX << posY << width << height; +} + +void JORMContext::genEditBoxID(const char* label, u32 id, const char* string, u16 length, u32 style, + JOREventListener* pListener, u16 posX, u16 posY, u16 width, u16 height) +{ + u32 kind = 0; + if (pListener != NULL) { + kind |= JORPropertyEvent::EKind_HasListener; + } + + mOutputStream << MCTX_COMMAND_GEN_CONTROL; + genControl('EDBX', kind | JORPropertyEvent::EKind_ValueID, label, style, id, pListener, 0); + + mOutputStream << length << string; + mOutputStream << posX << posY << width << height; +} + +void JORMContext::updateControl(u32 mode, u32 id, u32 param_2) { + mOutputStream << MCTX_COMMAND_UPDATE_CONTROL << mode << id; + + if (mode & 1) { + mOutputStream << param_2; + } +} + +void JORMContext::updateControl(u32 mode, u32 id, const char* param_2) { + if (mode & 2) { + mOutputStream << MCTX_COMMAND_UPDATE_CONTROL << mode << id << param_2; + } +} + +void JORMContext::updateSliderSub(u32 mode, u32 id, s32 value, s32 rangeMin, s32 rangeMax, u32 param_5) { + updateControl(mode, id, param_5); + + if (mode & 2) { + mOutputStream << value; + } + + if (mode & 4) { + mOutputStream << rangeMin << rangeMax; + } +} + +void JORMContext::updateCheckBoxSub(u32 mode, u32 id, u16 value, u16 mask, u32 param_4) { + mOutputStream << MCTX_COMMAND_UPDATE_CONTROL << (mode | JORPropertyEvent::EKind_HasListener) << id << (u32)mask; + + if (mode & 1) { + mOutputStream << param_4; + } + + if (mode & 2) { + mOutputStream << (u32)((mask << 0x10) | value); + } +} + +void JORMContext::updateSelectorSub(u32 mode, u32 id, s32 value, u32 param_3) { + updateControl(mode, id, param_3); + + if (mode & 2) { + mOutputStream << value; + } +} + +void JORMContext::updateEditBoxID(u32 mode, u32 id, const char* string, u32 param_3, u16 length) { + updateControl(mode, id, param_3); + + if (mode & 2) { + mOutputStream << string; + } + + if (mode & 0x10) { + mOutputStream << length; + } +} + +void JORMContext::editComboBoxItem(u32 param_0, u32 id, const char* param_2, s32 param_3, u32 param_4) { + updateControl(8, id, (u32)0); + + mOutputStream << param_0 << param_4 << param_2 << param_3; +} + +void JORMContext::openFile(JORFile* pFile, u32 flags, const char* path, const char* extMask, + u32 maskSize, const char* defaultExt, const char* param_6, const char* fileSuffix) +{ + if (defaultExt != NULL) { + flags |= JORFile::EFlags_DEFAULT_EXT; + } + + if (param_6 != NULL) { + flags |= JORFile::EFlags_UNK_0x20; + } + + if (fileSuffix != NULL) { + flags |= JORFile::EFlags_HAS_SUFFIX; + } + + mOutputStream << (u32)JORFile::ECommand_OPEN << (u32)pFile << flags << path; + mOutputStream << (u16)maskSize; + mOutputStream.write(extMask, maskSize); + + if (defaultExt != NULL) { + mOutputStream << defaultExt; + } + + if (param_6 != NULL) { + mOutputStream << param_6; + } + + if (fileSuffix != NULL) { + mOutputStream << fileSuffix; + } +} + +void JORMContext::closeFile(JORFile* pFile) { + mOutputStream << (u32)JORFile::ECommand_CLOSE << (u32)pFile << pFile->getHandle(); +} + +void JORMContext::readBegin(JORFile* pFile, s32 size) { + mOutputStream << (u32)JORFile::ECommand_READ + << (u32)JORFile::EStatus_READ_BEGIN + << (u32)pFile + << pFile->getHandle() + << (u32)size; +} + +void JORMContext::readData(JORFile* pFile) { + mOutputStream << (u32)JORFile::ECommand_READ + << (u32)JORFile::EStatus_READ_DATA + << (u32)pFile + << pFile->getHandle(); +} + +void JORMContext::writeBegin(JORFile* pFile, u16 flags, u32 size) { + mOutputStream << (u32)JORFile::ECommand_WRITE + << (u32)JORFile::EStatus_WRITE_BEGIN + << (u32)pFile + << pFile->getHandle() + << (u32)size + << (u32)flags; +} + +void JORMContext::writeData(JORFile* pFile, const void* pBuffer, s32 size, u32 position) { + mOutputStream << (u32)JORFile::ECommand_WRITE + << (u32)JORFile::EStatus_WRITE_DATA + << (u32)pFile + << pFile->getHandle() + << (u32)position; + + mOutputStream << (u16)size; + mOutputStream.write(pBuffer, size); +} + +void JORMContext::writeDone(JORFile* pFile, u32 size) { + mOutputStream << (u32)JORFile::ECommand_WRITE + << (u32)JORFile::EStatus_WRITE_END + << (u32)pFile + << pFile->getHandle() + << (u32)size; +} + +void JORMContext::openMessageBox(void* param_0, u32 style, const char* message, const char* title) { + mOutputStream << (u32)param_0 << (u32)style << message << title; +} + +void JORMContext::sendHostInfoRequest(u32 requestType, JORHostInfo* pHostInfo) { + mOutputStream << requestType << (u32)pHostInfo; +} + +void JORMContext::sendShellExecuteRequest(void* param_0, const char* param_1, const char* param_2, + const char* param_3, const char* param_4, int param_5) +{ + mOutputStream << (u32)param_0 << param_1 << param_2 << param_3 << param_4 << (u32)param_5; +} diff --git a/src/JSystem/JHostIO/JORShellExecute.cpp b/src/JSystem/JHostIO/JORShellExecute.cpp new file mode 100644 index 00000000000..ad1b3aeb1e4 --- /dev/null +++ b/src/JSystem/JHostIO/JORShellExecute.cpp @@ -0,0 +1,16 @@ +#include "JSystem/JHostIO/JORServer.h" + +int JORShellExecute(const char* param_0, const char* param_1, const char* param_2, const char* param_3, int param_4) { + int rt = 0; + JORServer* instance = JORServer::getInstance(); + + JORMContext* mctx = instance->attachMCTX(MCTX_MSG_SHELL_EXEC); + mctx->sendShellExecuteRequest(&rt, param_0, param_1, param_2, param_3, param_4); + instance->releaseMCTX(mctx); + + while (rt == 0) { + JOR_MESSAGELOOP(); + } + + return rt; +} diff --git a/src/JSystem/JSupport/JSUInputStream.cpp b/src/JSystem/JSupport/JSUInputStream.cpp index 4e7cbd3fee1..8197bdb1927 100644 --- a/src/JSystem/JSupport/JSUInputStream.cpp +++ b/src/JSystem/JSupport/JSUInputStream.cpp @@ -5,6 +5,7 @@ #include "JSystem/JSupport/JSUInputStream.h" #include "JSystem/JSupport/JSURandomInputStream.h" +#include // // Forward References: @@ -38,7 +39,11 @@ extern void* __vt__20JSURandomInputStream[9] = { }; /* 802DC23C-802DC298 2D6B7C 005C+00 1/0 6/6 0/0 .text __dt__14JSUInputStreamFv */ -JSUInputStream::~JSUInputStream() {} +JSUInputStream::~JSUInputStream() { + if (!isGood()) { + OS_REPORT("JSUInputStream: occur error.\n"); + } +} /* 802DC298-802DC2F0 2D6BD8 0058+00 1/1 20/20 0/0 .text read__14JSUInputStreamFPvl */ s32 JSUInputStream::read(void* buffer, s32 numBytes) { @@ -49,29 +54,46 @@ s32 JSUInputStream::read(void* buffer, s32 numBytes) { return bytesRead; } +char* JSUInputStream::read(char* str) { + u16 sp8; + if (readData(&sp8, sizeof(sp8)) != sizeof(sp8)) { + *str = 0; + setState(IOS_STATE_1); + return 0; + } + + s32 len = readData(str, sp8); + str[len] = 0; + if (len != sp8) { + setState(IOS_STATE_1); + } + return str; +} + /* 802DC2F0-802DC370 2D6C30 0080+00 1/0 0/0 0/0 .text skip__14JSUInputStreamFl */ s32 JSUInputStream::skip(s32 count) { + u8 buffer; s32 skipCount = 0; - u8 buffer[1]; - while (count > skipCount) { - if (readData(&buffer, 1) != 1) { + for (; skipCount < count; skipCount++) { + if (readData(&buffer, sizeof(buffer)) != sizeof(buffer)) { setState(IOS_STATE_1); break; } - skipCount++; } + return skipCount; } /* 802DC370-802DC3FC 2D6CB0 008C+00 0/0 1/1 0/0 .text align__20JSURandomInputStreamFl */ s32 JSURandomInputStream::align(s32 alignment) { + s32 seekLen = 0; s32 currentPos = getPosition(); - s32 offset = (alignment + currentPos); - offset -= 1; - offset &= ~(alignment - 1); + + s32 offset = (alignment - 1 + currentPos) & ~(alignment - 1); s32 alignmentOffset = offset - currentPos; + if (alignmentOffset != 0) { - s32 seekLen = seekPos(offset, JSUStreamSeekFrom_SET); + seekLen = seekPos(offset, JSUStreamSeekFrom_SET); if (seekLen != alignmentOffset) { setState(IOS_STATE_1); } @@ -104,4 +126,4 @@ s32 JSURandomInputStream::seek(s32 param_0, JSUStreamSeekFrom param_1) { s32 seekResult = seekPos(param_0, param_1); clrState(IOS_STATE_1); return seekResult; -} \ No newline at end of file +} diff --git a/src/JSystem/JSupport/JSUMemoryStream.cpp b/src/JSystem/JSupport/JSUMemoryStream.cpp index 0b5f1bc0629..494c3433139 100644 --- a/src/JSystem/JSupport/JSUMemoryStream.cpp +++ b/src/JSystem/JSupport/JSUMemoryStream.cpp @@ -63,4 +63,53 @@ s32 JSUMemoryInputStream::getLength() const { /* 802DC630-802DC638 2D6F70 0008+00 1/0 0/0 0/0 .text getPosition__20JSUMemoryInputStreamCFv */ s32 JSUMemoryInputStream::getPosition() const { return mPosition; -} \ No newline at end of file +} + +void JSUMemoryOutputStream::setBuffer(void* pBuffer, s32 length) { + mBuffer = pBuffer; + mLength = length; + mPosition = 0; +} + +s32 JSUMemoryOutputStream::writeData(const void* pData, s32 length) { + if (mPosition + length > mLength) { + length = mLength - mPosition; + } + + if (length > 0) { + memcpy((void*)((s32)mBuffer + mPosition), pData, length); + mPosition += length; + } + + return length; +} + +s32 JSUMemoryOutputStream::seekPos(s32 pos, JSUStreamSeekFrom seekFrom) { + s32 oldPos = mPosition; + + switch (seekFrom) { + case JSUStreamSeekFrom_SET: + mPosition = pos; + break; + case JSUStreamSeekFrom_END: + mPosition = mLength - pos; + break; + case JSUStreamSeekFrom_CUR: + mPosition += pos; + break; + } + + if (mPosition < 0) { + mPosition = 0; + } + + if (mPosition > mLength) { + mPosition = mLength; + } + + return mPosition - oldPos; +} + +s32 JSUMemoryOutputStream::getLength() const { + return mLength; +} diff --git a/src/JSystem/JSupport/JSUOutputStream.cpp b/src/JSystem/JSupport/JSUOutputStream.cpp new file mode 100644 index 00000000000..c2eb67d1748 --- /dev/null +++ b/src/JSystem/JSupport/JSUOutputStream.cpp @@ -0,0 +1,59 @@ +#include "JSystem/JSupport/JSUOutputStream.h" +#include "JSystem/JSupport/JSURandomOutputStream.h" +#include +#include + +JSUOutputStream::~JSUOutputStream() { + if (!isGood()) { + OS_REPORT("JSUOutputStream: occur error.\n"); + } +} + +s32 JSUOutputStream::write(const void* buffer, s32 numBytes) { + s32 bytesWrote = writeData(buffer, numBytes); + if (bytesWrote != numBytes) { + setState(IOS_STATE_1); + } + return bytesWrote; +} + +void JSUOutputStream::write(const char* str) { + if (str == NULL) { + u16 spA = 0; + if (writeData(&spA, sizeof(spA)) != sizeof(spA)) { + setState(IOS_STATE_1); + } + } else { + int len = strlen(str); + if (len >= 0x10000) { + setState(IOS_STATE_2); + } else { + u16 sp8 = len; + if (writeData(&sp8, sizeof(sp8)) != sizeof(sp8) || writeData(str, len) != len) { + setState(IOS_STATE_1); + } + } + } +} + +s32 JSUOutputStream::skip(s32 count, s8 param_1) { + s32 skipCount = 0; + for (; skipCount < count; skipCount++) { + if (writeData(¶m_1, sizeof(param_1)) != sizeof(param_1)) { + setState(IOS_STATE_1); + break; + } + } + + return skipCount; +} + +s32 JSURandomOutputStream::seek(s32 param_0, JSUStreamSeekFrom param_1) { + s32 seekResult = seekPos(param_0, param_1); + clrState(IOS_STATE_1); + return seekResult; +} + +s32 JSURandomOutputStream::getAvailable() const { + return getLength() - getPosition(); +} diff --git a/src/d/actor/d_a_obj_swturn.cpp b/src/d/actor/d_a_obj_swturn.cpp index ba61fb8a895..be1b6ec0f44 100644 --- a/src/d/actor/d_a_obj_swturn.cpp +++ b/src/d/actor/d_a_obj_swturn.cpp @@ -132,7 +132,7 @@ static char* l_arcName[2] = { /* 80D00EE4-80D00F64 000384 0080+00 1/0 0/0 0/0 .text CreateHeap__13daObjSwTurn_cFv */ int daObjSwTurn_c::CreateHeap() { - J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(l_arcName[mModelType], l_bmd[mModelType]) + J3DModelData* modelData = (J3DModelData*)dComIfG_getObjectRes(l_arcName[mModelType], l_bmd[mModelType]); JUT_ASSERT(347, modelData != 0); mModel = mDoExt_J3DModel__create(modelData, 0x80000, 0x11000084); return mModel != 0 ? TRUE : FALSE; diff --git a/src/d/actor/d_a_tag_chkpoint.cpp b/src/d/actor/d_a_tag_chkpoint.cpp index 986dfe93e78..fa149c5a292 100644 --- a/src/d/actor/d_a_tag_chkpoint.cpp +++ b/src/d/actor/d_a_tag_chkpoint.cpp @@ -4,7 +4,7 @@ */ #include "d/actor/d_a_tag_chkpoint.h" -#include "cmath.h" +#include #include "d/actor/d_a_player.h" /* 8048A6F8-8048A9EC 000078 02F4+00 1/1 0/0 0/0 .text execute__11daTag_Chk_cFv */ diff --git a/src/d/d_meter2_draw.cpp b/src/d/d_meter2_draw.cpp index f3b12eeea41..cb1c344151d 100644 --- a/src/d/d_meter2_draw.cpp +++ b/src/d/d_meter2_draw.cpp @@ -804,7 +804,8 @@ void dMeter2Draw_c::initMagic() { JUT_ASSERT(mpMagicFrameL != 0); mpMagicFrameR = - new CPaneMgr(mpKanteraScreen, 'm_w_r_n', 2, NULL) JUT_ASSERT(mpMagicFrameR != 0); + new CPaneMgr(mpKanteraScreen, 'm_w_r_n', 2, NULL); + JUT_ASSERT(mpMagicFrameR != 0); mpMagicMeter = new CPaneMgr(mpKanteraScreen, 'mm_00', 0, NULL); JUT_ASSERT(mpMagicMeter != 0); diff --git a/src/d/d_msg_object.cpp b/src/d/d_msg_object.cpp index ab6560bab80..5ce6e2690ae 100644 --- a/src/d/d_msg_object.cpp +++ b/src/d/d_msg_object.cpp @@ -1393,7 +1393,7 @@ void dMsgObject_c::talkStartInit() { mpScrnDraw = pData; break; case 7: - pData = new dMsgScrnStaff_c(((jmessage_tReference*)mpRenProc->getReference())->getArrange()) + pData = new dMsgScrnStaff_c(((jmessage_tReference*)mpRenProc->getReference())->getArrange()); JUT_ASSERT(3083, pData != 0); mpScrnDraw = pData; break; diff --git a/src/m_Do/m_Do_hostIO.cpp b/src/m_Do/m_Do_hostIO.cpp new file mode 100644 index 00000000000..61c2cbebd66 --- /dev/null +++ b/src/m_Do/m_Do_hostIO.cpp @@ -0,0 +1,138 @@ +#include "m_Do/m_Do_hostIO.h" +#include + +#ifdef DEBUG + +void mDoHIO_updateChild(s8 i_no); +void mDoHIO_deleteChild(s8 i_no); +s8 mDoHIO_createChild(const char*, JORReflexible*); + +mDoHIO_root_c mDoHIO_root; + +mDoHIO_root_c::~mDoHIO_root_c() {} + +mDoHIO_subRoot_c::~mDoHIO_subRoot_c() {} + +mDoHIO_child_c::~mDoHIO_child_c() {} + +void mDoHIO_root_c::genMessage(JORMContext* i_context) { + i_context->genNode("Node", &mSub, 0, 0); +} + +void mDoHIO_subRoot_c::genMessage(JORMContext* i_context) { + for (int i = 0; i < 80; i++) { + JORReflexible* node = mChildren[i].getPt(); + + if (node != NULL) { + i_context->genNode(mChildren[i].getName(), node, 0, 0); + } + } +} + +void mDoHIO_root_c::update() { + JORMContext* context = attachJORMContext(5); + context->invalidNode(this, 3); + releaseJORMContext(context); +} + +s8 mDoHIO_subRoot_c::createChild(const char* i_name, JORReflexible* i_node) { + for (int i = 0; i < 80; i++) { + if (mChildren[i].getPt() == i_node) { + OSReport_Error("危険:既に登録されているホストIOをふたたび登録\nしようとしているのを発見しました。<%s>%08x\n削除処理が正しく呼ばれていない可能性があります。\n登録と削除は1:1で呼ぶように修正してください。\n", i_name, i_node); + return -1; + } + } + + for (int i = 0; i < 80; i++) { + if (mChildren[i].getPt() == NULL) { + mChildren[i].setName(i_name); + mChildren[i].setPt(i_node); + return i + 1; + } + } + + OSReport_Error("ホストIOの空きエントリがありません。登録できませんでした。<%s>\n", i_name); + return -1; +} + +void mDoHIO_subRoot_c::deleteChild(s8 i_no) { + i_no--; + + if (i_no >= 0) { + if (mChildren[i_no].getPt() == NULL) { + OSReport_Error("危険:削除済みホストIOをさらに削除しようとしています<%s>\n", mChildren[i_no].getName()); + } else { + mChildren[i_no].setPt(NULL); + } + } else { + OSReport_Error("mDoHIO_subRoot_c::deleteChild\n"); + } +} + +void mDoHIO_subRoot_c::updateChild(s8 i_no) { + i_no--; + + if (i_no >= 0) { + JORMContext* context = attachJORMContext(5); + context->invalidNode(mChildren[i_no].getPt(), 3); + releaseJORMContext(context); + } +} + +mDoHIO_entry_c::mDoHIO_entry_c() { + mNo = -1; + mCount = 0; +} + +mDoHIO_entry_c::~mDoHIO_entry_c() { + if (mCount != 0) { + OSReport_Error("~mDoHIO_entry_c mCount=%d mNo=%d\n", mCount, mNo); + mDoHIO_deleteChild(mNo); + mDoHIO_deleteChild(mNo); + } +} + +void mDoHIO_deleteChild(s8 i_no) { + mDoHIO_root.deleteChild(i_no); +} + +void mDoHIO_root_c::deleteChild(s8 i_no) { + mSub.deleteChild(i_no); +} + +void mDoHIO_entry_c::entryHIO(const char* i_name) { + if (mCount >= 127) { + // "mDoHIO_entry_c::entryHIO too many calls\n" + OSReport_Error("mDoHIO_entry_c::entryHIO 呼びすぎです\n"); + return; + } + + if (mNo == -1 && i_name != NULL) { + mNo = mDoHIO_createChild(i_name, this); + } + + mCount++; +} + +void mDoHIO_entry_c::removeHIO() { + if (mCount != 0) { + mCount--; + + if (mCount == 0 && mNo != -1) { + mDoHIO_deleteChild(mNo); + mNo =-1; + } + } else { + OSReport_Error("mDoHIO_entry_c::removeHIO 呼びすぎです\n"); + } +} + +void mDoHIO_updateChild(s8 i_no) { + mDoHIO_root.updateChild(i_no); +} + +void mDoHIO_root_c::updateChild(s8 i_no) { + mSub.updateChild(i_no); +} + +#endif