1 /*---------------------------------------------------------------------------*
2 Project: RevolutionDWC Demos
3 File: ./match_lan/src/main.c
4
5 Copyright 2005-2008 Nintendo. All rights reserved.
6
7 These coded instructions, statements, and computer programs contain
8 proprietary information of Nintendo of America Inc. and/or Nintendo
9 Company Ltd., and are protected by Federal copyright law. They may
10 not be disclosed to third parties or copied or duplicated in any form,
11 in whole or in part, without the prior written consent of Nintendo.
12
13 *---------------------------------------------------------------------------*/
14 /**
15 *
16 *
17 * Brief comment: LAN matching demo
18 *
19 * This is a sample program that performs matching within a LAN.
20 * A mesh-type peer-to-peer network on the LAN is constructed and communications are used to exchange positions between the local host and other connected parties.
21 * One's own position can be moved by pressing Up/Down/Left/Right on the +Control Pad.
22 *
23 * Version: 1.4.16 Revised the program so that the AID and other such information is not displayed in the completion callback when matchmaking fails.
24 * Version: 0.0.5 Standardized the format with other matching demos.
25 *
26 */
27
28
29 #include "../../common/include/common.h"
30
31 // Constant Declarations
32 //---------------------------------------------------------
33
34 /// Enumerator that indicates status
35 typedef enum{
36 STATE_INIT,
37 STATE_MATCHING,
38 STATE_COMMUNICATING,
39 STATE_ERROR
40 }LANMATCHTESTSTATE;
41
42 #define MAX_PLAYERS 2 /// Number of connected players, including yourself
43 #define TIMEOUT (60 * 300) /// Timeout duration (frames)
44
45 // Variable Declarations
46 //---------------------------------------------------------
47 static LANMATCHTESTSTATE s_state; /// Status
48 static int s_counter; /// Timeout counter
49
50 // Position data structure exchanged through communications.
51 static struct Position
52 {
53 s32 xpos;
54 s32 ypos;
55 }
56 s_position[ MAX_PLAYERS ]; // Position data saved locally.
57
58 // Function Prototype
59 //---------------------------------------------------------
60 static void matchedCallback( DWCError result );
61 static void recvCallback( s32 aid, u8* buffer, int size );
62 static void sendCallback( int size, s32 aid );
63
64
65
66 /**
67 * The callback function invoked after matching completes.
68 *
69 * Param: result: Matching completion status
70 */
matchedCallback(DWCError result)71 void matchedCallback( DWCError result )
72 {
73
74 DWCDemoPrintf( "MatchedCallback result:%d\n", result );
75
76 if ( result == DWC_ERROR_NONE )
77 {
78
79 DWCDemoPrintf( "Connected to anybody behind same LAN!\n" );
80
81 s_state = STATE_COMMUNICATING;
82
83 DWCDemoPrintf( "aid = %d num = %d\n",
84 DWC_GetMyAIDLanMatch(),
85 DWC_GetConnectNumLanMatch() );
86
87 }
88 else
89 {
90
91 DWCDemoPrintf( "Match Error\n" );
92
93 s_state = STATE_ERROR;
94
95 }
96
97 }
98
99
100 /**
101 * The callback function invoked when receiving data.
102 *
103 * When data is received, set the flag for each AID in g_receivedflag.
104 * Terminate the program if data has been received from all peers.
105 *
106 * Param: aid The data sender's AID
107 * Param: buf Receive buffer
108 * Param: len Received data size
109 */
recvCallback(s32 aid,u8 * buffer,int size)110 void recvCallback( s32 aid, u8* buffer, int size )
111 {
112
113 //
114 // Save the received data.
115 //
116 // Eight bytes of data were sent in; storing a 4-byte X coordinate and a 4-byte Y coordinate.
117 //
118 if ( size == 8 )
119 {
120
121 s_position[ aid ].xpos = (long)ntohl(((u32*)buffer)[0]);
122 s_position[ aid ].ypos = (long)ntohl(((u32*)buffer)[1]);
123
124 DWCDemoPrintf( "[aid:%d] x:% 8d y:% 8d\n",
125 aid,
126 s_position[ aid ].xpos,
127 s_position[ aid ].ypos );
128
129 }
130 else
131 {
132
133 DWCDemoPrintf( "invalid recv data size\n" );
134
135 }
136
137 }
138
139
140 /**
141 * The callback function invoked when sending data.
142 */
sendCallback(int size,s32 aid)143 void sendCallback( int size, s32 aid )
144 {
145 DWCDemoPrintf( "Send Callback aid:%d, size:%d\n", aid, size );
146 }
147
148
149 /**
150 * Main
151 */
DWCDemoMain()152 void DWCDemoMain()
153 {
154
155 int i;
156
157 // Initializes the position data.
158 //------------------------------
159 for ( i=0; i<MAX_PLAYERS; i++ )
160 {
161
162 s_position[ i ].xpos = 0;
163 s_position[ i ].ypos = 0;
164
165 }
166
167 // Initialize LanMatch
168 //------------------------------
169 DWC_InitLanMatch( NULL );
170
171 // Specify the send and receive callback functions
172 DWC_SetRecvLanMatchCallback( recvCallback );
173 DWC_SetSendLanMatchCallback( sendCallback );
174
175
176 // Begin matchmaking
177 //------------------------------
178 DWC_StartLanMatch( MAX_PLAYERS, matchedCallback );
179 s_state = STATE_MATCHING;
180 s_counter = 0;
181
182 // Main loop
183 while (1)
184 {
185
186 DWC_ProcessLanMatch();
187
188 switch ( s_state )
189 {
190
191 // Matchmaking in progress
192 //
193 case STATE_MATCHING:
194
195 if ( s_counter++ > TIMEOUT )
196 {
197 DWCDemoPrintf("[ERROR] timeout\n");
198 s_state = STATE_ERROR;
199 }
200 break;
201
202 // Communicating
203 //
204 case STATE_COMMUNICATING:
205
206 {
207 u32 pad;
208 s32 me;
209 struct Position sendPos;
210
211 // Get one's own AID.
212 me = DWC_GetMyAIDLanMatch();
213
214 // Check input.
215 pad = DWCDemoPadRead();
216
217 if ( pad & DWCDEMO_KEY_UP ) s_position[ me ].ypos--;
218 if ( pad & DWCDEMO_KEY_DOWN ) s_position[ me ].ypos++;
219 if ( pad & DWCDEMO_KEY_LEFT ) s_position[ me ].xpos--;
220 if ( pad & DWCDEMO_KEY_RIGHT ) s_position[ me ].xpos++;
221
222 // Send a new position to the communication partner when there is input.
223 if ( pad & ( DWCDEMO_KEY_UP | DWCDEMO_KEY_DOWN
224 | DWCDEMO_KEY_LEFT | DWCDEMO_KEY_RIGHT ) )
225 {
226
227 int i;
228
229 sendPos.xpos = (s32)htonl((u32)s_position[ me ].xpos);
230 sendPos.ypos = (s32)htonl((u32)s_position[ me ].ypos);
231
232 // Send one's own position to all other parties.
233 for ( i=0; i<DWC_GetConnectNumLanMatch(); i++ )
234 {
235
236 if ( i != me )
237 {
238 DWC_SendLanMatch(
239 i,
240 (const void*)&sendPos,
241 sizeof( s32 ) * 2,
242 TRUE );
243 }
244
245 }
246
247 }
248 }
249 break;
250
251 // Error occurred
252 //
253 case STATE_ERROR:
254
255 goto error;
256
257 }
258
259 DWCDemoUpdate();
260
261 }
262
263 exit:
264
265 // Shut down LanMatch
266 DWC_ShutdownLanMatch();
267
268 return;
269
270 error:
271
272 // Error processing
273 {
274
275 int errorCode;
276 DWCErrorType errorType;
277
278 if ( DWC_GetLastErrorEx( &errorCode, &errorType ) != DWC_ERROR_NONE )
279 {
280
281 DWCDemoPrintf( "DWC_GetLastErrorEx ErrorCode:%d ErrorType:%d\n",
282 errorCode,
283 (int)errorType );
284
285 // Clear the errors.
286 DWC_ClearError();
287
288 }
289
290 }
291
292 // Shut down LanMatch
293 DWC_ShutdownLanMatch();
294
295 return;
296 }
297