1 /*---------------------------------------------------------------------------*
2 Project: NitroSDK - WM - demos - dataShare-Model
3 File: ball.h
4
5 Copyright 2007 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 $Log: ball.h,v $
14 Revision 1.1 2007/10/26 12:15:26 yosizaki
15 Initial upload.
16
17 $NoKeywords: $
18 *---------------------------------------------------------------------------*/
19
20 #ifndef BALL_H_
21 #define BALL_H_
22
23
24 #ifdef __cplusplus
25 extern "C" {
26 #endif
27
28
29 /*===========================================================================*/
30
31 #define BALL_PLAYER_MAX 16
32 #define BALL_RADIUS 4
33 #define BALL_FIELD_WIDTH 256
34 #define BALL_FIELD_HEIGHT 192
35 #define BALL_VELOCITY_ONE 10
36 #define BALL_VELOCITY_ACCEL 5
37 #define BALL_VELOCITY_DECREASE 1
38 #define BALL_VELOCITY_MAX (BALL_VELOCITY_ONE * 6)
39 #define BALL_VELOCITY_BOOST (BALL_VELOCITY_ONE * 3)
40
41 #define BALL_BUTTON_A 0x0001 // A
42 #define BALL_BUTTON_B 0x0002 // B
43 #define BALL_BUTTON_SELECT 0x0004 // SELECT
44 #define BALL_BUTTON_START 0x0008 // START
45 #define BALL_BUTTON_KEY_RIGHT 0x0010 // RIGHT on the +Control Pad
46 #define BALL_BUTTON_KEY_LEFT 0x0020 // LEFT on the +Control Pad
47 #define BALL_BUTTON_KEY_UP 0x0040 // UP on the +Control Pad
48 #define BALL_BUTTON_KEY_DOWN 0x0080 // DOWN on the +Control Pad
49 #define BALL_BUTTON_R 0x0100 // R
50 #define BALL_BUTTON_L 0x0200 // L
51 #define BALL_BUTTON_X 0x0400 // X
52 #define BALL_BUTTON_Y 0x0800 // Y
53
54 #ifndef SDK_INLINE
55 #define SDK_INLINE static inline
56 #endif
57
58 /*===========================================================================*/
59
60 typedef struct BallData
61 {
62 int x;
63 int y;
64 int vx;
65 int vy;
66 u16 plt;
67 u16 chr;
68 }
69 BallData;
70
71 typedef struct SharedContext
72 {
73 BallData ball[BALL_PLAYER_MAX];
74 u8 disabledPlt; // The palette number when not connected
75 u8 connectedPlt; // The palette number when connected
76 u8 ownPlt; // The palette number used by the local host itself
77 u8 padding[1];
78 }
79 SharedContext;
80
81
82 /*===========================================================================*/
83
84 static SharedContext shared[1];
85
86
87 /*===========================================================================*/
88
InitBall(const char * chrArray,u8 disabledPlt,u8 connectedPlt,u8 ownPlt)89 SDK_INLINE void InitBall(const char *chrArray,
90 u8 disabledPlt, u8 connectedPlt, u8 ownPlt)
91 {
92 int i;
93 if (chrArray == 0)
94 {
95 chrArray = "0123456789ABCDEF";
96 }
97 for (i = 0; i < BALL_PLAYER_MAX; ++i)
98 {
99 shared->ball[i].x = (190 + (i % 4) * 5);
100 shared->ball[i].y = (40 + i * 8);
101 shared->ball[i].vx = 0;
102 shared->ball[i].vy = 0;
103 shared->ball[i].plt = disabledPlt;
104 shared->ball[i].chr = chrArray[i];
105 }
106 shared->disabledPlt = disabledPlt;
107 shared->connectedPlt = connectedPlt;
108 shared->ownPlt = ownPlt;
109 }
110
InputBallKey(int aid,int key)111 SDK_INLINE void InputBallKey(int aid, int key)
112 {
113 if ((aid >= 0) && (aid < BALL_PLAYER_MAX))
114 {
115 if ((key & BALL_BUTTON_KEY_RIGHT) != 0)
116 {
117 if (shared->ball[aid].vx == 0)
118 {
119 shared->ball[aid].vx += BALL_VELOCITY_BOOST;
120 }
121 else if (shared->ball[aid].vx < +BALL_VELOCITY_MAX)
122 {
123 shared->ball[aid].vx += BALL_VELOCITY_ACCEL;
124 }
125 }
126 else if ((key & BALL_BUTTON_KEY_LEFT) != 0)
127 {
128 if (shared->ball[aid].vx == 0)
129 {
130 shared->ball[aid].vx -= BALL_VELOCITY_BOOST;
131 }
132 else if (shared->ball[aid].vx > -BALL_VELOCITY_MAX)
133 {
134 shared->ball[aid].vx -= BALL_VELOCITY_ACCEL;
135 }
136 }
137 if ((key & BALL_BUTTON_KEY_DOWN) != 0)
138 {
139 if (shared->ball[aid].vy == 0)
140 {
141 shared->ball[aid].vy += BALL_VELOCITY_BOOST;
142 }
143 else if (shared->ball[aid].vy < +BALL_VELOCITY_MAX)
144 {
145 shared->ball[aid].vy += BALL_VELOCITY_ACCEL;
146 }
147 }
148 if ((key & BALL_BUTTON_KEY_UP) != 0)
149 {
150 if (shared->ball[aid].vy == 0)
151 {
152 shared->ball[aid].vy -= BALL_VELOCITY_BOOST;
153 }
154 else if (shared->ball[aid].vy > -BALL_VELOCITY_MAX)
155 {
156 shared->ball[aid].vy -= BALL_VELOCITY_ACCEL;
157 }
158 }
159 shared->ball[aid].plt = shared->connectedPlt;
160 }
161 }
162
UpdateBalls(u16 ownAID)163 SDK_INLINE void UpdateBalls(u16 ownAID)
164 {
165 int i, j;
166 int bound = 0;
167 if ((ownAID >= 0) && (ownAID < BALL_PLAYER_MAX))
168 {
169 shared->ball[ownAID].plt = shared->ownPlt;
170 }
171 // Acceleration/deceleration and outer wall collision detection
172 for (i = 0; i < BALL_PLAYER_MAX; ++i)
173 {
174 int x = shared->ball[i].x;
175 int y = shared->ball[i].y;
176 x += shared->ball[i].vx / BALL_VELOCITY_ONE;
177 y += shared->ball[i].vy / BALL_VELOCITY_ONE;
178 if ((x < 0) || (x > BALL_FIELD_WIDTH - BALL_RADIUS * 2))
179 {
180 shared->ball[i].vx *= -1;
181 bound |= (1 << i);
182 }
183 else if (shared->ball[i].vx != 0)
184 {
185 shared->ball[i].vx -= (shared->ball[i].vx > 0) ? +BALL_VELOCITY_DECREASE : -BALL_VELOCITY_DECREASE;
186 }
187 if ((y < 0) || (y > BALL_FIELD_HEIGHT - BALL_RADIUS * 2))
188 {
189 shared->ball[i].vy *= -1;
190 bound |= (1 << i);
191 }
192 else if (shared->ball[i].vy != 0)
193 {
194 shared->ball[i].vy -= (shared->ball[i].vy > 0) ? +BALL_VELOCITY_DECREASE : -BALL_VELOCITY_DECREASE;
195 }
196 if ((bound & (1 << i)) == 0)
197 {
198 shared->ball[i].x = x;
199 shared->ball[i].y = y;
200 for (j = 0; j < BALL_PLAYER_MAX; ++j)
201 {
202 if (j != i)
203 {
204 int dx = shared->ball[j].x - x;
205 int dy = shared->ball[j].y - y;
206 if (dx * dx + dy * dy < (BALL_RADIUS * 2) * (BALL_RADIUS * 2))
207 {
208 BOOL target_bound = ((bound & (1 << j)) != 0);
209 int vx1 = shared->ball[i].vx;
210 int vy1 = shared->ball[i].vy;
211 int vx2, vy2;
212 if (!target_bound)
213 {
214 vx2 = shared->ball[j].vx;
215 vy2 = shared->ball[j].vy;
216 }
217 else
218 {
219 vx2 = 0;
220 vy2 = 0;
221 }
222 {
223 int dvx = vx2 - vx1;
224 int dvy = vy2 - vy1;
225 int dx2 = dx * dx;
226 int dy2 = dy * dy;
227 int mag2 = dx2 + dy2;
228 int crs = dx * dy;
229 shared->ball[i].vx = ((vx1 * dy2 + vx2 * dx2) + dvy * crs) / mag2;
230 shared->ball[i].vy = ((vy1 * dx2 + vy2 * dy2) + dvx * crs) / mag2;
231 if (!target_bound)
232 {
233 shared->ball[j].vx = ((vx1 * dx2 + vx2 * dy2) - dvy * crs) / mag2;
234 shared->ball[j].vy = ((vy1 * dx2 + vy2 * dy2) - dvx * crs) / mag2;
235 bound |= (1 << j);
236 }
237 }
238 bound |= (1 << i);
239 break;
240 }
241 }
242 }
243 }
244 }
245 }
246
247 /*===========================================================================*/
248
249 #ifdef __cplusplus
250 } /* extern "C" */
251 #endif
252
253 #endif /* BALL_H_ */
254
255 /*---------------------------------------------------------------------------*
256 End of file
257 *---------------------------------------------------------------------------*/
258