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