123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288 |
- /*
- Copyright (C) 2004 Michael Liebscher
- Copyright (C) 2000-2002 by DarkOne the Hacker
- 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.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- */
- /*
- * wolf_sprites.c: Wolfenstein3-D sprite handling.
- *
- * Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
- * Date: 2004
- *
- * Acknowledgement:
- * This code was derived from NewWolf, and was originally
- * written by DarkOne the Hacker.
- *
- */
- #include "../wolfiphone.h"
- /*
- -----------------------------------------------------------------------------
- Function: Sprite_Reset -Reset sprite status.
-
- Parameters: Nothing.
-
- Returns: Nothing.
-
- Notes: Called only when client must reconnect will not set remove flag!
- -----------------------------------------------------------------------------
- */
- PUBLIC void Sprite_Reset( void )
- {
- levelData.numSprites = 0;
- memset( levelData.sprites, 0, sizeof( levelData.sprites ) );
- }
- /*
- -----------------------------------------------------------------------------
- Function: Sprite_RemoveSprite -Remove sprite.
-
- Parameters: sprite_id -[in] sprite id to remove.
-
- Returns: Nothing.
-
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC void Sprite_RemoveSprite( int sprite_id )
- {
- if( sprite_id == -1 )
- {
- return;
- }
- levelData.sprites[ sprite_id ].flags |= SPRT_REMOVE;
- }
- /*
- -----------------------------------------------------------------------------
- Function: Sprite_GetNewSprite -Get sprite index.
-
- Parameters: Nothing.
-
- Returns: "sprite id" index.
-
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC int Sprite_GetNewSprite( void )
- {
- W32 n;
- sprite_t* sprt;
- for( n = 0, sprt = levelData.sprites ; n < levelData.numSprites ; ++n, ++sprt )
- {
- if( sprt->flags & SPRT_REMOVE )
- { // free spot: clear it first
- memset( sprt, 0, sizeof( sprite_t ) );
- return n;
- }
- }
- if( levelData.numSprites >= MAX_SPRITES )
- {
- Com_Printf( "Warning n_of_sprt == MAX_SPRITES\n" );
- return -1;
- }
- return levelData.numSprites++;
- }
- /*
- -----------------------------------------------------------------------------
- Function: Sprite_SetPos -Set sprite position.
-
- Parameters: sprite_id -[in] sprite id to change.
- x, y -[in] new x, y.
- angle -[in] new angle to set.
-
- Returns: Nothing.
-
- Notes:
- -----------------------------------------------------------------------------
- */
- PUBLIC void Sprite_SetPos( int sprite_id, int x, int y, int angle )
- {
- if( sprite_id == -1 )
- {
- return;
- }
- levelData.sprites[ sprite_id ].x = x;
- levelData.sprites[ sprite_id ].y = y;
- levelData.sprites[ sprite_id ].ang = angle;
- levelData.sprites[ sprite_id ].tilex = POS2TILE( x );
- levelData.sprites[ sprite_id ].tiley = POS2TILE( y );
- levelData.sprites[ sprite_id ].flags |= SPRT_CHG_POS;
- if( ! (x & HALFTILE) ) // (x%TILEGLOBAL>=HALFTILE)
- {
- levelData.sprites[ sprite_id ].tilex--;
- }
- if( ! (y & HALFTILE) )
- {
- levelData.sprites[ sprite_id ].tiley--;
- }
- }
- /*
- -----------------------------------------------------------------------------
- Function: Sprite_SetTex -Set sprite texture.
-
- Parameters: sprite_id -[in] sprite id to change.
- index -[in] texture index.
- tex -[in] texture to set as.
-
- Returns: Nothing.
-
- Notes:
- -----------------------------------------------------------------------------
- */
- void CacheTextures( W16 start, W16 end );
- PUBLIC void Sprite_SetTex( int sprite_id, int index, int tex )
- {
- if( sprite_id == -1 )
- {
- return;
- }
- CacheTextures( tex, tex );
- if( index == -1 ) // one texture for each phase
- {
- levelData.sprites[ sprite_id ].tex[ 0 ] = tex;
- levelData.sprites[ sprite_id ].flags |= SPRT_ONE_TEX;
- }
- else
- {
- levelData.sprites[ sprite_id ].tex[ index ] = tex;
- }
-
- levelData.sprites[ sprite_id ].flags |= SPRT_CHG_TEX;
- }
- #define MAXVISABLE 128
- visobj_t vislist[ MAXVISABLE ];
- /*
- -----------------------------------------------------------------------------
- Function: Sprite_CreateVisList -Compare function for vislist sorting.
-
- Parameters: vis1, vis2 -[in] Two values to compare.
-
- Returns:
- <0 elem1 further than elem2
- 0 elem1 equal distance to elem2
- >0 elem1 closer than elem2
-
- Notes:
- -----------------------------------------------------------------------------
- */
- PRIVATE int Sprite_cmpVis( const void *elem1, const void *elem2 )
- {
- // macro to get distance from a void pointer to visobj_t
- #define vis_dist( vis ) ( ((visobj_t *)vis)->dist )
- if( vis_dist( elem1 ) == vis_dist( elem2 ) )
- {
- return 0; // process equal distance
- }
- else
- {
- // if dist > sprite must be first
- return vis_dist( elem1 ) < vis_dist( elem2 ) ? 1 : -1;
- }
- }
- /*
- -----------------------------------------------------------------------------
- Function: Sprite_CreateVisList -Build and sort visibility list of sprites.
-
- Parameters: Nothing.
-
- Returns: Number of visible sprites.
-
- Notes:
- List is sorted from far to near.
- List is based on tile visibility array, made by raycaster.
- Called only by client.
- -----------------------------------------------------------------------------
- */
- PUBLIC int Sprite_CreateVisList( void )
- {
- W32 tx, ty, n, num_visible;
- visobj_t *visptr;
- sprite_t* sprt;
- visptr = vislist;
- num_visible = 0;
- for( n = 0, sprt = levelData.sprites; n < levelData.numSprites; ++n, ++sprt )
- {
- if( sprt->flags & SPRT_REMOVE )
- {
- continue;
- }
- tx = sprt->tilex;
- ty = sprt->tiley;
-
- if( tx > 63 )
- tx = 63;
- if( ty > 63 )
- ty = 63;
-
- // can be in any of 4 surrounding tiles; not 9 - see definition of tilex & tiley
- if( tile_visible[ tx ][ ty ] || tile_visible[ tx + 1 ][ ty ] ||
- tile_visible[ tx ][ ty + 1 ] || tile_visible[ tx + 1 ][ ty + 1 ] )
- { // player spoted it
- visptr->dist = LineLen2Point( sprt->x - Player.position.origin[ 0 ],
- sprt->y-Player.position.origin[ 1 ],
- Player.position.angle ); //FIXME viewport
- visptr->x = sprt->x;
- visptr->y = sprt->y;
- visptr->ang = sprt->ang;
- visptr->tex = sprt->tex[ 0 ]; //FIXME!
- if( ++num_visible > MAXVISABLE )
- {
- break; // vislist full
- }
- visptr++;
- }
- }
- // sorting list
- if( num_visible ) // do not sort if no entries
- {
- qsort( vislist, num_visible, sizeof( visobj_t ), Sprite_cmpVis );
- }
- return num_visible;
- }
|