c62d2810 |
1 | /* FCE Ultra - NES/Famicom Emulator |
2 | * |
3 | * Copyright notice for this file: |
4 | * Copyright (C) 2002 Ben Parnell |
5 | * |
6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. |
10 | * |
11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. |
15 | * |
16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | */ |
20 | |
21 | #include <sys/types.h> |
22 | #include <sys/socket.h> |
23 | #include <netinet/in.h> |
24 | #include <arpa/inet.h> |
25 | #include <stdio.h> |
26 | #include <unistd.h> |
27 | #include <netdb.h> |
28 | #include <errno.h> |
29 | |
30 | #ifndef socklen_t |
31 | #define socklen_t int |
32 | #endif |
33 | |
34 | static int Socket=-1; |
35 | #include "main.h" |
36 | #include "unix-netplay.h" |
37 | |
38 | char *netplayhost=0; |
39 | int Port=0xFCE; |
40 | int netplay=0; |
41 | |
42 | int FCEUD_NetworkConnect(void) |
43 | { |
44 | struct sockaddr_in sockn; |
45 | int TSocket; |
46 | |
47 | memset(&sockn,0,sizeof(sockn)); |
48 | sockn.sin_family=AF_INET; |
49 | sockn.sin_port=htons(Port); |
50 | |
51 | if((TSocket=socket(AF_INET, SOCK_STREAM, 0))<0) |
52 | { |
53 | puts("Error creating socket."); |
54 | return(0); |
55 | } |
56 | |
57 | if(netplay==1) /* Be a server. */ |
58 | { |
59 | sockn.sin_addr.s_addr=INADDR_ANY; |
60 | if(bind(TSocket, (struct sockaddr *)&sockn, sizeof(sockn))<0) |
61 | { |
62 | close(TSocket); |
63 | puts("Error binding to socket."); |
64 | return(0); |
65 | } |
66 | if(listen(TSocket, 1)<0) |
67 | { |
68 | puts("Error listening on socket."); |
69 | close(TSocket); |
70 | return(0); |
71 | } |
72 | { |
73 | socklen_t len=sizeof(sockn); |
74 | |
75 | printf("Accepting connection on port %d...\n",Port); |
76 | if((Socket=accept(TSocket,(struct sockaddr *)&sockn,&len))<0 ) |
77 | { |
78 | puts("Error accepting a connection."); |
79 | close(TSocket); |
80 | return(0); |
81 | } |
82 | close(TSocket); |
83 | } |
84 | |
85 | } |
86 | else /* Connect as a client if not a server. */ |
87 | { |
88 | struct hostent *Host; |
89 | |
90 | if((sockn.sin_addr.s_addr=inet_addr(netplayhost))==INADDR_NONE) |
91 | { |
92 | if(!(Host=gethostbyname(netplayhost))) |
93 | { |
94 | puts("Error getting network host entry."); |
95 | return(0); |
96 | } |
97 | memcpy(&sockn.sin_addr,Host->h_addr,Host->h_length); |
98 | } |
99 | printf("Attempting to connect to %s...\n",netplayhost); |
100 | if( connect(TSocket, (struct sockaddr *)&sockn, sizeof(sockn)) <0 ) |
101 | { |
102 | puts("Error connecting to remote host."); |
103 | close(TSocket); |
104 | return(0); |
105 | } |
106 | Socket=TSocket; |
107 | } |
108 | return(1); |
109 | } |
110 | |
111 | /* 0 on failure, 1 on success, -1 if it would block and blocking is not |
112 | specified. |
113 | */ |
114 | |
115 | int FCEUD_NetworkRecvData(uint8 *data, uint32 len, int block) |
116 | { |
117 | if(block) |
118 | { |
119 | int t; |
120 | uint8 temp[32]; |
121 | t=recv(Socket,temp,32,MSG_PEEK|MSG_DONTWAIT); |
122 | if(t==-1) |
123 | { |
124 | if(errno!=EAGAIN) return(0); |
125 | } |
126 | else if(t==32) |
127 | NoWaiting|=2; |
128 | else |
129 | NoWaiting&=~2; |
130 | return(recv(Socket,data,len,0)==len); |
131 | } |
132 | else |
133 | { |
134 | int t=recv(Socket,data,len,MSG_DONTWAIT); |
135 | if(t==-1) |
136 | { |
137 | if(errno==EAGAIN) // Would block |
138 | return(-1); |
139 | return(0); |
140 | } |
141 | return(1); |
142 | } |
143 | } |
144 | |
145 | /* 0 on failure, 1 on success. This function should always block. */ |
146 | |
147 | int FCEUD_NetworkSendData(uint8 *Value, uint32 len) |
148 | { |
149 | return(send(Socket,Value,len,0)==len); |
150 | } |
151 | |
152 | void FCEUD_NetworkClose(void) |
153 | { |
154 | if(Socket>0) |
155 | close(Socket); |
156 | Socket=-1; |
157 | } |
158 | |