pcsxr-1.9.92
[pcsx_rearmed.git] / plugins / dfnet / dfnet.c
CommitLineData
ef79bbde
P
1//
2// DF Netplay Plugin
3//
4// Based on netSock 0.2 by linuzappz.
5// The Plugin is free source code.
6//
7
8#include <stdio.h>
9#include <stdlib.h>
10#include <stdarg.h>
11#include <string.h>
12#include <sys/types.h>
13#include <fcntl.h>
14#include <errno.h>
15extern int errno;
16
17#include "dfnet.h"
18
19const unsigned char version = 2; // NET library v2
20const unsigned char revision = 0;
21const unsigned char build = 3; // increase that with each version
22
23static char *libraryName = N_("Socket Driver");
24
25unsigned long CALLBACK PSEgetLibType() {
26 return PSE_LT_NET;
27}
28
29char* CALLBACK PSEgetLibName() {
30 return _(libraryName);
31}
32
33unsigned long CALLBACK PSEgetLibVersion() {
34 return version << 16 | revision << 8 | build;
35}
36
37long CALLBACK NETinit() {
38 return sockInit();
39}
40
41int SEND(const void *buf, int Size, int Mode) {
42 int bytes;
43 int count = 0;
44 const char *pData = (const char *)buf;
45
46 if (Mode & PSE_NET_NONBLOCKING) { // NONBLOCKING
47 int ret;
48
49 FD_ZERO(&wset);
50 FD_SET(sock, &wset);
51
52 ret = select(sock + 1, NULL, &wset, NULL, &tm);
53 if (ret == -1) return -1;
54
55 if (FD_ISSET(sock, &wset)) {
56 return send(sock, pData, Size, 0);
57 } else {
58 return 0;
59 }
60 } else { // BLOCKING
61 while (Size > 0) {
62 bytes = send(sock, pData, Size, 0);
63 if (bytes < 0) return -1;
64 pData += bytes; Size -= bytes;
65 count += bytes;
66 }
67 }
68
69 return count;
70}
71
72int RECV(void *buf, int Size, int Mode) {
73 int bytes;
74 int count = 0;
75 char *pData = (char *)buf;
76
77 if (Mode & PSE_NET_NONBLOCKING) { // NONBLOCKING
78 int ret;
79
80 FD_ZERO(&rset);
81 FD_SET(sock, &rset);
82
83 ret = select(sock, &rset, NULL, NULL, &tm);
84
85 if (FD_ISSET(sock, &rset)) {
86 return recv(sock, pData, Size, 0);
87 } else {
88 return 0;
89 }
90 } else { // BLOCKING
91 while (Size > 0) {
92 bytes = recv(sock, pData, Size, 0);
93 if (bytes == -1) return -1;
94 pData+= bytes; Size-= bytes;
95 count+= bytes;
96 }
97 }
98
99 return count;
100}
101
102long CALLBACK NETopen(unsigned long *gpuDisp) {
103 int ret = sockOpen();
104
105 struct sockaddr_in address;
106
107 if (ret == -1) return -1;
108
109 if (conf.PlayerNum == 1) {
110 int listen_sock, reuse_addr = 1;
111 int ret;
112
113 memset((char *)&address, 0, sizeof (address));
114
115 address.sin_family = AF_INET;
116 address.sin_port = htons(conf.PortNum);
117 address.sin_addr.s_addr = INADDR_ANY;
118
119 listen_sock = socket(AF_INET, SOCK_STREAM, 0);
120 if (listen_sock == -1)
121 return -1;
122
123 setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&reuse_addr, sizeof(reuse_addr));
124
125 if (bind(listen_sock,(struct sockaddr *) &address, sizeof(address)) == -1)
126 return -1;
127
128 if (listen(listen_sock, 1) != 0)
129 return -1;
130
131 sock = -1;
132
133 WaitCancel = 0;
134 sockCreateWaitDlg();
135
136 while (sock < 0) {
137 FD_ZERO(&rset);
138 FD_SET(listen_sock, &rset);
139
140 ret = select(listen_sock + 1, &rset, NULL, NULL, &tm);
141 if (FD_ISSET(listen_sock, &rset)) {
142 sock = accept(listen_sock, NULL, NULL);
143 }
144
145 if (WaitCancel) break;
146 sockDlgUpdate();
147 }
148 close(listen_sock);
149
150 sockDestroyWaitDlg();
151 if (WaitCancel == 1) return -1;
152 } else {
153 memset((char *)&address, 0, sizeof(address));
154 address.sin_family = AF_INET;
155 address.sin_port = htons(conf.PortNum);
156 address.sin_addr.s_addr = inet_addr(conf.ipAddress);
157
158 sock = socket(AF_INET, SOCK_STREAM, 0);
159
160 if (connect(sock, (struct sockaddr *)&address, sizeof(address))!=0) {
161 SysMessage(_("error connecting to %s: %s\n"), conf.ipAddress, strerror(errno));
162 return -1;
163 }
164 }
165
166 PadInit = 0;
167 PadCount = 0;
168 PadSize[0] = -1;
169 PadSize[1] = -1;
170 PadRecvSize = -1;
171 PadSendSize = -1;
172 Ping = sockPing();
173 Ping = (sockPing() + Ping) / 2;
174 Ping = (sockPing() + Ping) / 2;
175
176 if (conf.PlayerNum == 1) {
177 PadCountMax = (int)(((double)Ping / 1000.0) * 60.0);
178 if (PadCountMax <= 0) PadCountMax = 1;
179 SEND(&PadCountMax, 4, PSE_NET_BLOCKING);
180 } else {
181 RECV(&PadCountMax, 4, PSE_NET_BLOCKING);
182 }
183
184 PadSendData = (char *)malloc(PadCountMax * 128);
185 if (PadSendData == NULL) {
186 SysMessage(_("Error allocating memory!\n")); return -1;
187 }
188 memset(PadSendData, 0xff, PadCountMax);
189
190 return ret;
191}
192
193long CALLBACK NETclose() {
194 close(sock);
195
196 return 0;
197}
198
199long CALLBACK NETshutdown() {
200 return sockShutdown();
201}
202
203void CALLBACK NETpause() {
204/* unsigned char Code = 0x80;
205
206 SEND(&Code, 1, PSE_NET_BLOCKING);*/
207}
208
209void CALLBACK NETresume() {
210/* unsigned char Code = 0x80;
211
212 SEND(&Code, 1, PSE_NET_BLOCKING);*/
213}
214
215long CALLBACK NETsendData(void *pData, int Size, int Mode) {
216 return SEND(pData, Size, Mode);
217}
218
219long CALLBACK NETrecvData(void *pData, int Size, int Mode) {
220 return RECV(pData, Size, Mode);
221}
222
223long CALLBACK NETsendPadData(void *pData, int Size) {
224 if (PadSendSize == -1) {
225 PadSendSize = Size;
226
227 if (SEND(&PadSendSize, 1, PSE_NET_BLOCKING) == -1)
228 return -1;
229
230 if (RECV(&PadRecvSize, 1, PSE_NET_BLOCKING) == -1)
231 return -1;
232 }
233
234 memcpy(&PadSendData[PadCount], pData, Size);
235 if (SEND(pData, PadSendSize, PSE_NET_BLOCKING) == -1)
236 return -1;
237
238 return 0;
239}
240
241long CALLBACK NETrecvPadData(void *pData, int Pad) {
242 if (PadInit == 0) {
243 if (conf.PlayerNum == Pad) {
244 memset(pData, 0xff, PadSendSize);
245 } else {
246 memset(pData, 0xff, PadRecvSize);
247 }
248 } else {
249 if (conf.PlayerNum == Pad) {
250 memcpy(pData, &PadSendData[PadCount == 0 ? PadCountMax-1 : PadCount-1], PadSendSize);
251 } else {
252 if (RECV(pData, PadRecvSize, PSE_NET_BLOCKING) == -1)
253 return -1;
254 }
255 }
256
257 if (Pad == 2) {
258 PadCount++;
259 if (PadCount == PadCountMax) {
260 PadCount = 0;
261 PadInit = 1;
262 }
263 }
264
265 return 0;
266}
267
268long CALLBACK NETqueryPlayer() {
269 return conf.PlayerNum;
270}
271
272long CALLBACK NETtest() {
273 return 0;
274}