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