25 unsigned char responsible
; /* responsible for the next fault (if any) */
34 Ball ball
= { GAME_X_MID
, GAME_Y_MID
, BALL_DEFAULT_SPEED
, 0.2, 7.5 };
35 Ball ground
= { 0, 0, 0, 0, 0 };
36 Player player1
= { GAME_X_MIN
-4, GAME_Y_MID
, 0, 0, 1 };
37 Player player2
= { GAME_X_MAX
, GAME_Y_MID
, 0, 0, 0 };
43 werbung
[w
] = rand()%SPONSOR_COUNT
;
54 show_bmp( "data/court.bmp", 0, 0, 255);
56 show_bmp( "data/shadow.bmp", ball
.x
, ball
.y
, 128);
59 show_sprite( SPONSOR_BMP
, werbung
[w
], SPONSOR_COUNT
, 60+50*w
+5*(w
>1), 7, 255);
62 show_sprite( RACKET_BMP
, (!player1
.state
), 4, player1
.x
, player1
.y
, 255);
63 show_sprite( RACKET_BMP
, (!player2
.state
)+2, 4, player2
.x
, player2
.y
, 255);
65 phase
= 1.6*ball
.jump
*get_phase( ball
.x
, GAME_X_MIN
, GAME_X_MAX
, ball
.move_x
);
69 /* after the ball hit the ground, responsibilities change */
70 player1
.responsible
= !(player2
.responsible
= !player2
.responsible
);
78 if( ground
.jump
&& !(i
%10)) ground
.jump
--;
82 show_sprite( "data/ground.bmp", ground
.jump
-1, 3, ground
.x
, ground
.y
, 255);
85 show_bmp( "data/ball.bmp", ball
.x
, ball
.y
-phase
, 255);
87 show_bmp( "data/standings.bmp", 115, 160, 255);
88 show_digit( player1
.score
/10%10, 140, 180, 100);
89 show_digit( player1
.score
%10, 148, 180, 100);
90 show_digit( 10, 156, 180, 100);
91 show_digit( player2
.score
/10%10, 164, 180, 100);
92 show_digit( player2
.score
%10, 172, 180, 100);
97 if( IS_OUT_X(ball
.x
) || IS_OUT_Y(ball
.y
)) {
98 if( (IS_OUT_Y(ball
.y
) && player1
.responsible
) || (!(player1
.state
&& IS_NEAR_Y(player1
.y
, ball
.y
+phase
)) && ball
.x
< GAME_X_MIN
)) {
101 player2
.responsible
= !(player1
.responsible
= 1);
104 ball
.move_x
= fabsf( ball
.move_x
);
105 limit_value( &ball
.move_x
, ball
.move_x
, BALL_DEFAULT_SPEED
);
108 sound_applause_stop();
111 if( (IS_OUT_Y(ball
.y
) && player2
.responsible
) || (!(player2
.state
&& IS_NEAR_Y(player2
.y
, ball
.y
+phase
)) && ball
.x
> GAME_X_MAX
)) {
114 player1
.responsible
= !(player2
.responsible
= 1);
117 ball
.move_x
= -fabsf( ball
.move_x
);
118 limit_value( &ball
.move_x
, -BALL_DEFAULT_SPEED
, ball
.move_x
);
121 sound_applause_stop();
124 if( IS_OUT_X(ball
.x
)) {
125 if( ball
.move_x
< 0) {
127 if( player1
.state
== PLAYER_STATE_MAX
) {
128 ball
.move_x
= PLAYER_POWERSHOT
;
130 ball
.move_x
= 2.5 + 2.0*player1
.state
/PLAYER_STATE_MAX
;
132 ball
.move_y
= get_move_y( player1
.y
, ball
.y
-phase
, PLAYER_AREA
, ball
.move_x
, phase
);
133 ball
.jump
+= 1.0-2.0*(player1
.state
<5);
134 sound_racket( player1
.state
== PLAYER_STATE_MAX
);
137 if( player2
.state
== PLAYER_STATE_MAX
) {
138 ball
.move_x
= -PLAYER_POWERSHOT
;
140 ball
.move_x
= -(2.5 + 2.0*player2
.state
/PLAYER_STATE_MAX
);
142 ball
.move_y
= get_move_y( player2
.y
, ball
.y
-phase
, PLAYER_AREA
, ball
.move_x
, phase
);
143 ball
.jump
+= 1.0-2.0*(player2
.state
<5);
144 sound_racket( player2
.state
== PLAYER_STATE_MAX
);
149 ball
.x
+= ball
.move_x
;
150 ball
.y
+= ball
.move_y
;
152 if( player1
.state
) player1
.state
--;
153 if( player2
.state
) player2
.state
--;
156 limit_value( &player1
.y
, PLAYER_Y_MIN
, PLAYER_Y_MAX
);
157 limit_value( &player2
.y
, PLAYER_Y_MIN
, PLAYER_Y_MAX
);
158 limit_value( &ball
.jump
, BALL_JUMP_MIN
, BALL_JUMP_MAX
);
161 keys
= SDL_GetKeyState( NULL
);
163 if( keys
['2']) player1
.y
-=3;
164 if( keys
['w']) player1
.y
-=2;
165 if( keys
['s']) player1
.y
+=2;
166 if( keys
['x']) player1
.y
+=3;
167 if( keys
['d'] && !player1
.state
) player1
.state
= PLAYER_STATE_MAX
;
169 if( keys
['9']) player2
.y
-=3;
170 if( keys
['o']) player2
.y
-=2;
171 if( keys
['l']) player2
.y
+=2;
172 if( keys
['.']) player2
.y
+=3;
173 if( keys
['k'] && !player2
.state
) player2
.state
= PLAYER_STATE_MAX
;
175 if( keys
['f']) SDL_WM_ToggleFullScreen( screen
);
177 if( keys
[SDLK_ESCAPE
] || keys
['q']) break;
186 void limit_value( float* value
, float min
, float max
) {
189 } else if( *value
> max
) {
194 float get_phase( float x
, float min
, float max
, float direction
) {
197 pos
= (direction
>0)?(1-GROUND_PHASE
):(GROUND_PHASE
);
199 fract
= (x
-min
)/(max
-min
);
203 return fabsf( cosf(PI
*fract
/2));
205 fract
= (pos
-fract
)/(1-pos
);
206 return fabsf( sinf(PI
*fract
/2));
210 float get_move_y( float py
, float by
, float pa
, float move_x
, float phase
) {
211 float pct
, dest
, x_len
, y_len
;
213 printf( "py = %.0f, by = %.0f, pa = %.0f\n", py
, by
, pa
);
215 /* 0.0 .. 1.0 for racket hit position */
216 pct
= ((py
+pa
)-by
)/(2*pa
);
217 limit_value( &pct
, 0.0, 1.0);
219 /* Y destination for ball */
220 dest
= GAME_Y_MIN
+ pct
*(GAME_Y_MAX
-GAME_Y_MIN
);
222 /* lengths for the ball's journey */
223 x_len
= GAME_X_MAX
- GAME_X_MIN
;
224 y_len
= dest
- py
+ phase
;
226 printf( "py = %f, dest = %f, pct = %f, x_len = %f, y_len = %f\n", py
, dest
, pct
, x_len
, y_len
);
228 /* return the should-be value for move_y */
229 return (y_len
*move_x
)/(x_len
);