375 lines
12 KiB
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();
|
|
}
|
|
}
|
|
|