summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakaRikka <38417346+TakaRikka@users.noreply.github.com>2025-01-19 21:05:53 -0800
committerGitHub <noreply@github.com>2025-01-19 22:05:53 -0700
commite0824a15908f4e6ad70d3d0f2364efe043a98c0f (patch)
tree3e85ea5ea5282c7ca3397a3adc1535674fc496aa
parent7137f49bfc9535d95f980fb92552adf7b7c3c3ce (diff)
most of JHostIO / m_Do_hostIO done (#2288)
-rw-r--r--config/ShieldD/splits.txt9
-rw-r--r--configure.py25
-rw-r--r--include/JSystem/JGadget/linklist.h28
-rw-r--r--include/JSystem/JHostIO/JHIComm.h100
-rw-r--r--include/JSystem/JHostIO/JHICommonMem.h77
-rw-r--r--include/JSystem/JHostIO/JHIMccBuf.h77
-rw-r--r--include/JSystem/JHostIO/JHIRMcc.h15
-rw-r--r--include/JSystem/JHostIO/JHIhioASync.h13
-rw-r--r--include/JSystem/JHostIO/JOREntry.h62
-rw-r--r--include/JSystem/JHostIO/JORFile.h94
-rw-r--r--include/JSystem/JHostIO/JORHostInfo.h52
-rw-r--r--include/JSystem/JHostIO/JORMContext.h210
-rw-r--r--include/JSystem/JHostIO/JORReflexible.h53
-rw-r--r--include/JSystem/JHostIO/JORServer.h111
-rw-r--r--include/JSystem/JSupport/JSUInputStream.h34
-rw-r--r--include/JSystem/JSupport/JSUIosBase.h13
-rw-r--r--include/JSystem/JSupport/JSUMemoryStream.h28
-rw-r--r--include/JSystem/JSupport/JSUOutputStream.h52
-rw-r--r--include/JSystem/JSupport/JSURandomOutputStream.h24
-rw-r--r--include/JSystem/JUtility/JUTAssert.h2
-rw-r--r--include/m_Do/m_Do_hostIO.h68
-rw-r--r--src/JSystem/JHostIO/JHIComm.cpp306
-rw-r--r--src/JSystem/JHostIO/JHICommonMem.cpp16
-rw-r--r--src/JSystem/JHostIO/JHIMccBuf.cpp455
-rw-r--r--src/JSystem/JHostIO/JHIMemBuf.cpp69
-rw-r--r--src/JSystem/JHostIO/JHIRMcc.cpp132
-rw-r--r--src/JSystem/JHostIO/JHIhioASync.cpp167
-rw-r--r--src/JSystem/JHostIO/JOREntry.cpp22
-rw-r--r--src/JSystem/JHostIO/JORFile.cpp182
-rw-r--r--src/JSystem/JHostIO/JORHostInfo.cpp56
-rw-r--r--src/JSystem/JHostIO/JORMessageBox.cpp14
-rw-r--r--src/JSystem/JHostIO/JORServer.cpp820
-rw-r--r--src/JSystem/JHostIO/JORShellExecute.cpp16
-rw-r--r--src/JSystem/JSupport/JSUInputStream.cpp42
-rw-r--r--src/JSystem/JSupport/JSUMemoryStream.cpp51
-rw-r--r--src/JSystem/JSupport/JSUOutputStream.cpp59
-rw-r--r--src/d/actor/d_a_obj_swturn.cpp2
-rw-r--r--src/d/actor/d_a_tag_chkpoint.cpp2
-rw-r--r--src/d/d_meter2_draw.cpp3
-rw-r--r--src/d/d_msg_object.cpp2
-rw-r--r--src/m_Do/m_Do_hostIO.cpp138
41 files changed, 3651 insertions, 50 deletions
diff --git a/config/ShieldD/splits.txt b/config/ShieldD/splits.txt
index 8bf1b4f937..1662872053 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 50c0d9eb12..dbbc4a4e1d 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 4fb6a627df..5d0575f0db 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<const TLinkListNode*>(reinterpret_cast<const char*>(element) - I);
+ static TLinkListNode* Element_toNode(T* p) {
+ JUT_ASSERT(0x2F1, p!=0);
+ return reinterpret_cast<TLinkListNode*>(reinterpret_cast<char*>(p) - I);
}
- static TLinkListNode* Element_toNode(T* element) {
- (void)element; // Debug-only assert
- return reinterpret_cast<TLinkListNode*>(reinterpret_cast<char*>(element) - I);
+ static const TLinkListNode* Element_toNode(const T* p) {
+ JUT_ASSERT(0x2F6, p!=0);
+ return reinterpret_cast<const TLinkListNode*>(reinterpret_cast<const char*>(p) - I);
}
- static const T* Element_toValue(const TLinkListNode* node) {
- (void)node; // Debug-only assert
- return reinterpret_cast<const T*>(reinterpret_cast<const char*>(node) + I);
+ static T* Element_toValue(TLinkListNode* p) {
+ JUT_ASSERT(0x2FB, p!=0);
+ return reinterpret_cast<T*>(reinterpret_cast<char*>(p) + I);
}
- static T* Element_toValue(TLinkListNode* node) {
- (void)node; // Debug-only assert
- return reinterpret_cast<T*>(reinterpret_cast<char*>(node) + I);
+ static const T* Element_toValue(const TLinkListNode* p) {
+ JUT_ASSERT(0x300, p!=0);
+ return reinterpret_cast<const T*>(reinterpret_cast<const char*>(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 0000000000..30f57ff2de
--- /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 0000000000..017e8d2669
--- /dev/null
+++ b/include/JSystem/JHostIO/JHICommonMem.h
@@ -0,0 +1,77 @@
+#ifndef JHICOMMONMEM_H
+#define JHICOMMONMEM_H
+
+#include <dolphin/types.h>
+
+inline u32 JHIhtonl(u32 v) {
+#if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+ return v;
+#else
+ // todo
+#endif
+}
+
+template <typename T>
+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 0000000000..7343b88376
--- /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 0000000000..6b79187c56
--- /dev/null
+++ b/include/JSystem/JHostIO/JHIRMcc.h
@@ -0,0 +1,15 @@
+#ifndef JHIRMCC_H
+#define JHIRMCC_H
+
+#include <dolphin.h>
+
+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 0000000000..fa9d90ef71
--- /dev/null
+++ b/include/JSystem/JHostIO/JHIhioASync.h
@@ -0,0 +1,13 @@
+#ifndef JHIHIOASYNC_H
+#define JHIHIOASYNC_H
+
+#include <dolphin/types.h>
+
+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 0000000000..dcd6390012
--- /dev/null
+++ b/include/JSystem/JHostIO/JOREntry.h
@@ -0,0 +1,62 @@
+#ifndef JORENTRY_H
+#define JORENTRY_H
+
+#include "JSystem/JHostIO/JHIComm.h"
+
+template<typename T, int I>
+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<typename T>
+class JHIComPortManager {
+public:
+ JHIComPortManager() {
+ field_0x10040 = 0;
+ field_0x10041 = 0;
+ }
+
+ T& getRefPort() { return port; }
+
+ void addTag(JHITag<T>* pTag) {
+ field_0x8 = this;
+ field_0xc.push_back(pTag);
+ }
+
+ static JHIComPortManager<T>* create() {
+ if (instance == NULL) {
+ instance = new JHIComPortManager<T>();
+ }
+
+ return instance;
+ }
+
+ static JHIComPortManager<T>* instance;
+
+ /* 0x00000 */ T port;
+ /* 0x00008 */ JHIComPortManager<T>* field_0x8;
+ /* 0x0000C */ JHIpvector<JHITag<T>*, 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 0000000000..5d06259a48
--- /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 0000000000..2eb43c5184
--- /dev/null
+++ b/include/JSystem/JHostIO/JORHostInfo.h
@@ -0,0 +1,52 @@
+#ifndef JORHOSTINFO_H
+#define JORHOSTINFO_H
+
+#include <dolphin.h>
+
+#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 0000000000..68f4135c59
--- /dev/null
+++ b/include/JSystem/JHostIO/JORMContext.h
@@ -0,0 +1,210 @@
+#ifndef JORMCONTEXT_H
+#define JORMCONTEXT_H
+
+#include <dolphin.h>
+#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 0000000000..3a066f70ad
--- /dev/null
+++ b/include/JSystem/JHostIO/JORReflexible.h
@@ -0,0 +1,53 @@
+#ifndef JORREFLEXIBLE_H
+#define JORREFLEXIBLE_H
+
+#include <dolphin/types.h>
+
+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 0000000000..3f28539e45
--- /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<JHICmnMem> {
+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<JHICmnMem>('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<JOREventCallbackListNode, -4> m_eventCallbackList;
+};
+
+#endif /* JORSERVER_H */
diff --git a/include/JSystem/JSupport/JSUInputStream.h b/include/JSystem/JSupport/JSUInputStream.h
index 411f8c02ad..dc35d5ab91 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) {
+ JSUInputStream& operator>>(u32& dest) {
+ read(&dest, 4);
+ return *this;
+ }
+
+ JSUInputStream& operator>>(u16& dest) {
+ read(&dest, 2);
+ return *this;
+ }
+
+ JSUInputStream& operator>>(u8& dest) {
read(&dest, 1);
- return this;
+ return *this;
}
- JSUInputStream* operator>>(s16& dest) {
+ JSUInputStream& operator>>(s16& dest) {
read(&dest, 2);
- return this;
+ return *this;
+ }
+
+ JSUInputStream& operator>>(char* dest) {
+ read(dest);
+ return *this;
+ }
+
+ s32 read(u32& param_0) {
+ return read(&param_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 761c1d61df..5164cc5a2a 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 0ef4703555..51b6fb601a 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 0000000000..43d9d37ef0
--- /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(&param_0, sizeof(u32));
+ return *this;
+ }
+
+ JSUOutputStream& operator<<(s32 param_0) {
+ write(&param_0, sizeof(s32));
+ return *this;
+ }
+
+ JSUOutputStream& operator<<(s16 param_0) {
+ write(&param_0, sizeof(s16));
+ return *this;
+ }
+
+ JSUOutputStream& operator<<(u16 param_0) {
+ write(&param_0, sizeof(u16));
+ return *this;
+ }
+
+ JSUOutputStream& operator<<(u8 param_0) {
+ write(&param_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 0000000000..1b2648fabb
--- /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 213f5df274..66256e08b7 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 eefdd1288f..864fd59045 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 <string.h>
-class mDoHIO_entry_c {
+class mDoHIO_child_c {
public:
+ 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 0000000000..e55845f009
--- /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 0000000000..d4057f18f1
--- /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 0000000000..b9a57637d0
--- /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 <dolphin.h>
+#include <cstring.h>
+
+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 0000000000..516ccedd51
--- /dev/null
+++ b/src/JSystem/JHostIO/JHIMemBuf.cpp
@@ -0,0 +1,69 @@
+#include "JSystem/JHostIO/JHICommonMem.h"
+#include "JSystem/JKernel/JKRHeap.h"
+#include <dolphin.h>
+
+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 0000000000..0edb01506d
--- /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 0000000000..ea46990579
--- /dev/null
+++ b/src/JSystem/JHostIO/JHIhioASync.cpp
@@ -0,0 +1,167 @@
+#include "JSystem/JHostIO/JHIMccBuf.h"
+#include "JSystem/JHostIO/JHIRMcc.h"
+#include <dolphin.h>
+
+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 0000000000..5c90b5f77d
--- /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<JHICmnMem>* pPortMng = JHIComPortManager<JHICmnMem>::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 0000000000..94a1979443
--- /dev/null
+++ b/src/JSystem/JHostIO/JORFile.cpp
@@ -0,0 +1,182 @@
+#include "JSystem/JHostIO/JORFile.h"
+#include "JSystem/JHostIO/JORServer.h"
+#include <dolphin.h>
+
+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 0000000000..6ba8b221bb
--- /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 0000000000..16884b4542
--- /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 0000000000..75935dc2ae
--- /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 <string.h>
+
+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<JORReflexible*>(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<JORReflexible*>(obj_addr)->listen(command, pEvent);
+ }
+ }
+ break;
+ case ECommand_GenObjInfo: {
+ u32 obj_addr;
+ stream.read(obj_addr);
+
+ if (stream.isGood()) {
+ reinterpret_cast<JORReflexible*>(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 0000000000..ad1b3aeb1e
--- /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 4e7cbd3fee..8197bdb192 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 <dolphin.h>
//
// 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 0b5f1bc062..494c343313 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 0000000000..c2eb67d174
--- /dev/null
+++ b/src/JSystem/JSupport/JSUOutputStream.cpp
@@ -0,0 +1,59 @@
+#include "JSystem/JSupport/JSUOutputStream.h"
+#include "JSystem/JSupport/JSURandomOutputStream.h"
+#include <dolphin.h>
+#include <cstring.h>
+
+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(&param_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 ba61fb8a89..be1b6ec0f4 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 986dfe93e7..fa149c5a29 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 <cmath.h>
#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 f3b12eeea4..cb1c344151 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 ab6560bab8..5ce6e2690a 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 0000000000..61c2cbebd6
--- /dev/null
+++ b/src/m_Do/m_Do_hostIO.cpp
@@ -0,0 +1,138 @@
+#include "m_Do/m_Do_hostIO.h"
+#include <dolphin.h>
+
+#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