Closed inada-s closed 4 years ago
通信対戦メニューの関数テーブル 003c4f50
シーンID? 06 00 で通信対戦メニューへジャンプ 008710D0
003C4F50
接続ボタン押した後
network_connect => modem_connect から関数テーブルをjalr
00359720 dialing10
00359370 dialing10_00
003595A0 dialing10_01
00359600 dialing10_02 (TCP, PPP初期化)
これらの関数を書き換えれば通信できそうである。
アプローチとしては2つあって、ps2devを使ってirxライブラリを作り、ライブラリの関数を呼び出すように書き換える。 もう一つは、pcsx2を自前ビルドして、これらの関数の呼び出しをフックして、自作のコードを呼び出す。
ps2devのほうが将来的に実機で遊べるようにするためには良いだろうが、pcsx2からアプローチしたほうがデバッグしやすそう。
This means Gundam DX (PS2) is a modem-only game?
I never tried to modify a game to use the broadband adapter instead of the modem. Interesting task!
Online revival will be easy, it's plain KDDI:
void Send_LineCheck(void)
{
SetSendCommand((message *)&send_work,0x6001);
SetSendCategory((message *)&send_work,2);
SetSendCommandLen((message *)&send_work);
Write_Socket((message *)&send_work);
return;
}
This means Gundam DX (PS2) is a modem-only game?
YES. When the game released, only Multi-Matching (Not Multi Matching BB) was on service.
I never tried to modify a game to use the broadband adapter instead of the modem.
This task is the first step. I'm going to modify pcsx2 codes so that it can enter online mode to get started with server development.
cpu->write32(0x003c4f58, 0x0015f110);
cpu->write32(0x0035a660, 0x24030002);
dns lookup phase have something tricky..
my dirty work is here. https://github.com/inada-s/pcsx2
Ave_SifCallRpc
is a function to communicate AVE_TCP library.
other Ave_XXX functions are wrapper of Ave_SifCallRpc
.
https://www.retroreversing.com/playStation-2-architecture#example-of-sif-in-action
An example of using the SIF to communicate between both processors is the controller pad libraries. We want to communicate between libpad.a which runs on the Emotion Engine and padman.irx which runs on the I/O Processor. So during the VBlank period the IOP Padman.irx uses SIFDMA to send controller information (such as which buttons are pressed) to the Emotion Engine. The Emotion Engine can then request this information by calling the API scePadRead
If needed to modify the game to make good use of Ethernet adapter,
Either way, both seem to be difficult.
hand-decompiled TcpGetStatus
void TcpGetStatus(a0, a1) {
// stack size = 0x0010
sp[0] = s0
sp[1] = ra
s0 = a1
// dsll32: Doubleword Shift Left Logical Plus 32
a0 = a1 << (16+32)
a2 = s0 + 2
a3 = s0 + 4
// dsra32 a0, a0, 16
a0 = a0 >> (16+32)
v0 = Ave_TcpStat(a0, a1, a2, a3) // Ave_TcpStat is `select(2)` like function
v0 <<= (16+32)
v0 >>= (16+32)
if (0 <= v0) { // bgez 00381eac
v1 = s0[0]
if (v1 < 11) {
v1 >>= 2
switch (v1 + a0) {
case 0: s0[0]=0 break
case 1: v1=1, s0[0]=v1 break
case 2: v1=2, s0[0]=v1 break
case 3: v1=3, s0[0]=v1 break
case 4: v1=4, s0[0]=v1 break
case 5: v1=5, s0[0]=v1 break
case 6: v1=6, s0[0]=v1 break
case 7: v1=7, s0[0]=v1 break
case 8: v1=8, s0[0]=v1 break
case 9: v1=9, s0[0]=v1 break
case 10:v1=10,s0[0]=v1 break
}
} else {
v1 = 7
s0[0] = v1
}
}
ra = sp[1]
s0 = sp[0]
}
// connect_ps2_check
void connect_ps2_check(a0) {
// stack size = 0x0020
ra = sp[0]
a1 = sp + 0x0018
v0 = TcpGetStatus(a0, a1)
if (0 <= v0) {
v0 = sp[0x0018]
v0 ^= 4
v0 = 0 < v0
v0 ^= 1
} else {
v0 = -1
}
ra = sp[0]
}
tcp_init() {
...
a0 = gp[-0x652C] # sock
connect_ps2_check(a0)
}
I modified the pcsx2 code to set breakpoints on functions likely to be involved in network, and to call C ++ callbacks when passing through those functions. In the callbacks, skip the ppp process and bypass tcp's Open / Read / Write to winsock's.
A little progress :)
next task is https://github.com/inada-s/gdxsv/issues/3
You're super fast. I'm still in the process of getting the game. Not an easy task these days.
Probably this is the most difficult phase of creating GDX server.
There is a talk of making a Dreamcast version of the game server, but there are a lot of debug symbols left in the PS2 version of the game, so I plan to develop a server based on the PS2 version.
I believe the Dreamcast and PS2 versions to be served on almost the same game server.