Files
commandergenius/project/jni/application/lbreakout2/client/paddle.c

375 lines
12 KiB
C

/***************************************************************************
paddle.c - description
-------------------
begin : Fri Sep 7 2001
copyright : (C) 2001 by Michael Speck
email : kulkanie@gmx.net
***************************************************************************/
/***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/
#include "lbreakout.h"
#include "config.h"
#include "paddle.h"
#include "../game/game.h"
/*
====================================================================
Paddle & plasma weapon
====================================================================
*/
extern SDL_Surface *paddle_pic; /* paddle tiles: left, middle, right for each paddle type */
extern SDL_Surface *paddle_shadow;
extern SDL_Surface *weapon_pic;
extern SDL_Surface *ammo_pic;
extern SDL_Surface *weapon_shadow;
extern int paddle_cw, paddle_ch;
int weapon_w = 14;
int weapon_h = 18;
int weapon_fr_num = 4;
float weapon_fpms = 0.006;
/*
====================================================================
Other stuff
====================================================================
*/
extern SDL_Surface *stk_display;
extern SDL_Rect stk_drect;
extern SDL_Surface *offscreen;
extern int shadow_size;
extern Game *game;
extern Config config;
/*
====================================================================
Hide and show paddle on screen.
====================================================================
*/
void paddle_hide( Paddle *paddle )
{
paddle->update_rect.x = paddle->x;
paddle->update_rect.y = paddle->y;
paddle->update_rect.w = paddle->w + shadow_size;
paddle->update_rect.h = paddle->h + shadow_size;
stk_surface_blit( offscreen, paddle->x, paddle->y,
paddle->update_rect.w, paddle->update_rect.h,
stk_display, paddle->x, paddle->y );
/* store rect if it won't be drawn */
if ( paddle->invis )
if ( paddle->invis_delay == 0 )
stk_display_store_rect( &paddle->update_rect );
}
void paddle_show_shadow( Paddle *paddle )
{
int aux_w = 0, i;
int rem_middle_w; /* remaining points to draw in the middle */
if ( paddle->invis ) return;
if ( game->extra_active[EX_DARKNESS] ) return;
stk_surface_clip( stk_display, 0, 0, stk_display->w - BRICK_WIDTH, stk_display->h );
/* left end */
stk_surface_alpha_blit( paddle_shadow, paddle->pic_x_offset,0,paddle_cw, paddle_ch,
stk_display, paddle->x + shadow_size, paddle->y + shadow_size,
SHADOW_ALPHA );
/* middle part */
for ( i = paddle_cw, rem_middle_w = paddle->w - ( paddle_cw << 1 );
rem_middle_w > 0; i += paddle_cw, rem_middle_w -= paddle_cw ) {
if ( rem_middle_w > paddle_cw )
aux_w = paddle_cw;
else
aux_w = rem_middle_w;
stk_surface_alpha_blit( paddle_shadow,
paddle->pic_x_offset+paddle_cw,0,aux_w, paddle_ch,
stk_display, paddle->x + shadow_size + i, paddle->y + shadow_size,
SHADOW_ALPHA );
}
/* right end */
i = paddle->w - paddle_cw;
stk_surface_alpha_blit( paddle_shadow,
paddle->pic_x_offset+(paddle_cw<<1),0,paddle_cw, paddle_ch,
stk_display, paddle->x + shadow_size + i, paddle->y + shadow_size,
SHADOW_ALPHA );
stk_surface_clip( stk_display, 0, 0, 0, 0 );
}
void paddle_show( Paddle *paddle )
{
int i, aux_w = 0;
int rem_middle_w; /* remaining points to draw in the middle */
/* if invisible return or show alpha */
if ( paddle->invis ) {
if ( paddle->invis_delay != 0 )
paddle_alphashow( paddle, 128 );
return;
}
/* paddle */
/* left end */
stk_surface_blit( paddle_pic, paddle->pic_x_offset,paddle->pic_y_offset,
paddle_cw, paddle_ch, stk_display, paddle->x, paddle->y );
/* middle part */
for ( i = paddle_cw, rem_middle_w = paddle->w - ( paddle_cw << 1 );
rem_middle_w > 0; i += paddle_cw, rem_middle_w -= paddle_cw ) {
if ( rem_middle_w > paddle_cw )
aux_w = paddle_cw;
else
aux_w = rem_middle_w;
stk_surface_blit( paddle_pic,
paddle->pic_x_offset+paddle_cw,paddle->pic_y_offset,
aux_w, paddle_ch, stk_display, paddle->x + i, paddle->y );
}
i = paddle->w - paddle_cw;
/* right end */
stk_surface_blit( paddle_pic,
paddle->pic_x_offset+(paddle_cw<<1),paddle->pic_y_offset,
paddle_cw, paddle_ch, stk_display, paddle->x + i, paddle->y );
/* weapon */
if ( paddle->weapon_inst )
stk_surface_blit( weapon_pic,
(int)paddle->weapon_cur * weapon_w, 0, weapon_w, weapon_h,
stk_display, paddle->x + ((paddle->w - weapon_w)>>1), paddle->y );
/* update */
if ( paddle->x < paddle->update_rect.x ) {
/* movement to left */
paddle->update_rect.w += paddle->update_rect.x - paddle->x;
paddle->update_rect.x = paddle->x;
}
else {
/* movement to right */
paddle->update_rect.w += paddle->x - paddle->update_rect.x;
}
stk_display_store_rect( &paddle->update_rect );
}
void paddle_alphashow( Paddle *paddle, int a )
{
int i, aux_w;
int rem_middle_w;
/* left end */
stk_surface_alpha_blit( paddle_pic, paddle->pic_x_offset,paddle->pic_y_offset,
paddle_cw, paddle_ch, stk_display, paddle->x, paddle->y, a );
/* middle part */
for ( i = paddle_cw, rem_middle_w = paddle->w - ( paddle_cw << 1 );
rem_middle_w > 0; i += paddle_cw, rem_middle_w -= paddle_cw ) {
if ( rem_middle_w > paddle_cw )
aux_w = paddle_cw;
else
aux_w = rem_middle_w;
stk_surface_alpha_blit( paddle_pic,
paddle->pic_x_offset+paddle_cw,paddle->pic_y_offset,
aux_w, paddle_ch, stk_display, paddle->x + i, paddle->y, a );
}
i = paddle->w - paddle_cw;
/* right end */
stk_surface_alpha_blit( paddle_pic, paddle->pic_x_offset+(paddle_cw<<1),paddle->pic_y_offset,
paddle_cw, paddle_ch, stk_display, paddle->x + i, paddle->y, a );
if ( paddle->weapon_inst )
stk_surface_alpha_blit( weapon_pic,
(int)paddle->weapon_cur * weapon_w, 0, weapon_w, weapon_h,
stk_display, paddle->x + ((paddle->w - weapon_w)>>1), paddle->y, a );
/* update */
if ( paddle->x < paddle->update_rect.x ) {
/* movement to left */
paddle->update_rect.w += paddle->update_rect.x - paddle->x;
paddle->update_rect.x = paddle->x;
}
else {
/* movement to right */
paddle->update_rect.w += paddle->x - paddle->update_rect.x;
}
stk_display_store_rect( &paddle->update_rect );
}
/*
====================================================================
Update paddle animation (weapon)
====================================================================
*/
void client_paddle_update( Paddle *paddle, int ms )
{
Ball *ball;
int result;
/* invisiblity */
if ( paddle->invis ) /* extra active */
if ( paddle->invis_delay > 0 && (paddle->invis_delay-=ms) <= 0 )
paddle->invis_delay = 0;
if ( paddle->weapon_inst ) {
/* animation */
if ( (paddle->weapon_cur+=ms*weapon_fpms) >= weapon_fr_num)
paddle->weapon_cur -= weapon_fr_num;
}
/* check for resize */
if ( ( result = paddle_resize( paddle, ms ) ) ) {
list_reset( game->balls );
while ( ( ball = list_next( game->balls ) ) )
/* adjust attached balls */
if ( ball->attached && ball->paddle == paddle ) {
if ( result < 0 ) {
/* shrinked */
if ( ball->cur.x > ( paddle->w >> 1 ) ) {
ball->cur.x -= 2;
ball->x = (int)ball->cur.x;
}
}
else {
/* expanded */
if ( ball->cur.x > ( paddle->w >> 1 ) ) {
ball->cur.x += 2;
ball->x = (int)ball->cur.x;
}
}
}
}
}
/*
====================================================================
Handle events (used for local paddle): Update the coordinates
and the state of both fire buttons (left/right). The influence
of that on the weapon is handled in paddle_update() and the
influence on balls is handled in balls_update().
NEW: While the middle button is pressed, the balls will be
accelerated to maximum speed.
This is the local equivalent to comm_update_remote_paddle().
====================================================================
*/
void paddle_handle_events( Paddle *paddle, int ms )
{
Uint8 *keystate;
Uint8 buttonstate;
int xoff, yoff;
int diff, old_paddle_x = paddle->x;
int has_moved = 0;
/* a frozen paddle does nothing */
if ( paddle->frozen ) {
#ifdef PADDLE_FRICTION
paddle->v_x = 0;
#endif
return;
}
/* get SDL input states */
keystate = SDL_GetKeyState(0);
buttonstate = SDL_GetRelativeMouseState( &xoff, &yoff );
/* mouse motion */
if ( xoff != 0 ) {
if ( config.invert ) xoff = -xoff;
paddle->cur_x += config.motion_mod * xoff;
#ifdef MOUSE_WARP
/* reset mouse pointer as current solution does not work for
BeOS */
SDL_EventState( SDL_MOUSEMOTION, SDL_IGNORE );
SDL_WarpMouse(stk_display->w >> 1, stk_display->h >> 1);
SDL_EventState( SDL_MOUSEMOTION, SDL_ENABLE );
#endif
#ifdef PADDLE_FRICTION
paddle->friction_delay = 200;
#endif
has_moved = 1;
}
/* keys */
if ( keystate[config.k_left] ) {
paddle->cur_x -= config.key_speed * (ms << keystate[config.k_turbo]);
paddle->friction_delay = 0; paddle->v_x = 0.0;
has_moved = 1;
}
if ( keystate[config.k_right] ) {
paddle->cur_x += config.key_speed * (ms << keystate[config.k_turbo]);
paddle->friction_delay = 0; paddle->v_x = 0.0;
has_moved = 1;
}
/* update friction delay */
#ifdef PADDLE_FRICTION
if ( paddle->friction_delay > 0 && (paddle->friction_delay-=ms)<=0) {
paddle->friction_delay = 0;
paddle->v_x = 0.0;
}
#endif
/* check paddle when moved */
if ( has_moved ) {
/* check range and set absolute position */
if (paddle->cur_x < BRICK_WIDTH)
paddle->cur_x = BRICK_WIDTH;
if (paddle->cur_x + paddle->w >= stk_display->w - BRICK_WIDTH)
paddle->cur_x = stk_display->w - BRICK_WIDTH - paddle->w;
paddle->x = paddle->cur_x;
/* set paddle speed so that it will modify balls */
#ifdef PADDLE_FRICTION
diff = paddle->x - old_paddle_x;
paddle->v_x = (float)(diff) / ms;
if ( xoff != 0 ) {
/* limit mouse speed */
if (paddle->v_x > 5.0) paddle->v_x = 5.0;
if (paddle->v_x < -5.0) paddle->v_x = -5.0;
paddle->v_x /= 5;
}
#endif
/* visible for some time */
paddle->invis_delay = PADDLE_INVIS_DELAY;
}
/* update the fire flags (left/right) */
if ( buttonstate & SDL_BUTTON(1) || keystate[config.k_lfire] )
paddle->fire_left = 1;
else
paddle->fire_left = 0;
if ( buttonstate & SDL_BUTTON(3) || keystate[config.k_rfire] )
paddle->fire_right = 1;
else
paddle->fire_right = 0;
/* update maxspeed request - handled in ../game/balls.c::balls_update */
paddle->maxballspeed_request_old = paddle->maxballspeed_request;
if ( buttonstate & SDL_BUTTON(2) || keystate[config.k_maxballspeed] )
paddle->maxballspeed_request = 1;
else
paddle->maxballspeed_request = 0;
//printf( "%d\n", paddle->maxballspeed_request );
/* update return key */
if ( buttonstate & SDL_BUTTON(2) || keystate[config.k_return] )
paddle->ball_return_key_pressed = 1;
else
paddle->ball_return_key_pressed = 0;
}
/* draw ammo in network game */
void paddle_ammo_hide( Paddle *paddle )
{
int x;
x = (stk_display->w - paddle->ball_ammo*ammo_pic->w) / 2;
stk_surface_blit( offscreen, x,paddle->ball_ammo_disp_y,
paddle->ball_ammo*ammo_pic->w, ammo_pic->h,
stk_display, x,paddle->ball_ammo_disp_y );
stk_display_store_drect();
}
void paddle_ammo_show( Paddle *paddle )
{
int i, x;
x = (stk_display->w - paddle->ball_ammo*ammo_pic->w) / 2;
for ( i = 0; i < paddle->ball_ammo; i++, x += ammo_pic->w ) {
stk_surface_blit(
ammo_pic, 0,0,-1,-1,
stk_display, x, paddle->ball_ammo_disp_y );
stk_display_store_drect();
}
}