Source release of Wolfenstein 3D Classic Platinum for iOS, 1.0

This commit is contained in:
Travis Bradshaw
2012-01-31 16:46:52 -06:00
commit e20e553baf
1001 changed files with 54065 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,968 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 2001 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_actor_ai.c: Wolfenstein3-D artificial intelligence.
*
* 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"
const char dsounds[ 7 ][ 32 ] =
{
"sfx/025.wav",
"sfx/026.wav",
"sfx/086.wav",
"sfx/088.wav",
"sfx/105.wav",
"sfx/107.wav",
"sfx/109.wav"
};
const char dsodsounds[ 7 ][ 32 ] =
{
"sfx/021.wav",
"sfx/022.wav",
"sfx/052.wav",
"sfx/054.wav",
"sfx/057.wav",
"sfx/059.wav",
"sfx/061.wav"
};
/*
-----------------------------------------------------------------------------
Function: A_DeathScream() -Do a death scream sound depending on actor type.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_DeathScream( entity_t *self )
{
switch( self->type )
{
case en_mutant:
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/033.wav" ), 1, ATTN_NORM, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/037.wav" ), 1, ATTN_NORM, 0 );
}
break;
case en_guard:
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( dsodsounds[ US_RndT() % 6 ] ), 1, ATTN_NORM, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( dsounds[ US_RndT() % 6 ] ), 1, ATTN_NORM, 0 );
}
break;
case en_officer:
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/046.wav" ), 1, ATTN_NORM, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/074.wav" ), 1, ATTN_NORM, 0 );
}
break;
case en_ss:
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/035.wav" ), 1, ATTN_NORM, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/046.wav" ), 1, ATTN_NORM, 0 );
}
break;
case en_dog:
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/031.wav" ), 1, ATTN_NORM, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/035.wav" ), 1, ATTN_NORM, 0 );
}
break;
case en_boss:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/019.wav" ), 1, ATTN_NORM, 0 );
break;
case en_schabbs:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/061.wav" ), 1, ATTN_NORM, 0 );
break;
case en_fake:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/069.wav" ), 1, ATTN_NORM, 0 );
break;
case en_mecha:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/084.wav" ), 1, ATTN_NORM, 0 );
break;
case en_hitler:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/044.wav" ), 1, ATTN_NORM, 0 );
break;
case en_gretel:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/115.wav" ), 1, ATTN_NORM, 0 );
break;
case en_gift:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/091.wav" ), 1, ATTN_NORM, 0 );
break;
case en_fat:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/119.wav" ), 1, ATTN_NORM, 0 );
break;
case en_spectre:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "lsfx/062.wav" ), 1, ATTN_NORM, 0 );
break;
case en_angel:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/098.wav" ), 1, ATTN_NORM, 0 );
break;
case en_trans:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/070.wav" ), 1, ATTN_NORM, 0 );
break;
case en_uber:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/082.wav" ), 1, ATTN_NORM, 0 );
break;
case en_will:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/072.wav" ), 1, ATTN_NORM, 0 );
break;
case en_death:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/090.wav" ), 1, ATTN_NORM, 0 );
break;
}
}
/*
-----------------------------------------------------------------------------
Function: A_FirstSighting() -Puts an actor into attack mode and possibly
reverses the direction if the player is
behind it.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_FirstSighting( entity_t *self )
{
switch( self->type )
{
case en_guard:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/001.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 3; // go faster when chasing player
break;
case en_officer:
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/043.wav" ), 1, ATTN_NORM, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/071.wav" ), 1, ATTN_NORM, 0 );
}
self->speed *= 5; // go faster when chasing player
break;
case en_mutant:
self->speed *= 3; // go faster when chasing player
break;
case en_ss:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/015.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 4; // go faster when chasing player
break;
case en_dog:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/002.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 2; // go faster when chasing player
break;
case en_boss:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/017.wav" ), 1, ATTN_NORM, 0 );
self->speed = SPDPATROL * 3; // go faster when chasing player
break;
case en_gretel:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/112.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 3; // go faster when chasing player
break;
case en_gift:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/096.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 3; // go faster when chasing player
break;
case en_fat:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/102.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 3; // go faster when chasing player
break;
case en_schabbs:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/065.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 3; // go faster when chasing player
break;
case en_fake:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/054.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 3; // go faster when chasing player
break;
case en_mecha:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/040.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 3; // go faster when chasing player
break;
case en_hitler:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/040.wav" ), 1, ATTN_NORM, 0 );
self->speed *= 5; // go faster when chasing player
break;
case en_blinky:
case en_clyde:
case en_pinky:
case en_inky:
self->speed *= 2; // go faster when chasing player
break;
//
// Spear of Destiny
//
case en_spectre:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "lsfx/003.wav" ), 1, ATTN_NORM, 0 );
self->speed = 800; // go faster when chasing player
break;
case en_angel:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/095.wav" ), 1, ATTN_NORM, 0 );
self->speed = 1536; // go faster when chasing player
break;
case en_trans:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/066.wav" ), 1, ATTN_NORM, 0 );
self->speed = 1536; // go faster when chasing player
break;
case en_uber:
self->speed = 3000; // go faster when chasing player
break;
case en_will:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/073.wav" ), 1, ATTN_NORM, 0 );
self->speed = 2048; // go faster when chasing player
break;
case en_death:
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/085.wav" ), 1, ATTN_NORM, 0 );
self->speed = 2048; // go faster when chasing player
break;
default:
return;
}
A_StateChange( self, st_chase1 );
if( self->waitfordoorx )
{
self->waitfordoorx = self->waitfordoory = 0; // ignore the door opening command
}
self->dir = dir8_nodir;
self->flags |= FL_ATTACKMODE | FL_FIRSTATTACK;
}
/*
-----------------------------------------------------------------------------
Function: A_KillActor() -Actor has been killed, so give points and spawn
powerups.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE void A_KillActor( entity_t *self )
{
int tilex, tiley;
tilex = self->tilex = self->x >> TILESHIFT; // drop item on center
tiley = self->tiley = self->y >> TILESHIFT;
switch( self->type )
{
case en_guard:
PL_GivePoints( &Player, 100 );
Powerup_Spawn( tilex, tiley, pow_clip2, r_world );
break;
case en_officer:
PL_GivePoints( &Player, 400 );
Powerup_Spawn( tilex, tiley, pow_clip2, r_world );
break;
case en_mutant:
PL_GivePoints( &Player, 700 );
Powerup_Spawn( tilex, tiley, pow_clip2, r_world );
break;
case en_ss:
PL_GivePoints( &Player, 500 );
if( Player.items & ITEM_WEAPON_3 ) // have a schmeiser?
{
Powerup_Spawn( tilex, tiley, pow_clip2, r_world );
}
else
{
Powerup_Spawn( tilex, tiley, pow_machinegun, r_world );
}
break;
case en_dog:
PL_GivePoints( &Player, 200 );
break;
case en_boss:
PL_GivePoints( &Player, 5000 );
Powerup_Spawn( tilex, tiley, pow_key1, r_world );
break;
case en_gretel:
PL_GivePoints( &Player, 5000 );
Powerup_Spawn( tilex, tiley, pow_key1, r_world );
break;
case en_gift:
PL_GivePoints( &Player, 5000 );
A_StartDeathCam( self );
break;
case en_fat:
PL_GivePoints( &Player, 5000 );
A_StartDeathCam( self );
break;
case en_schabbs:
PL_GivePoints( &Player, 5000 );
A_DeathScream( self );
A_StartDeathCam( self );
break;
case en_fake:
PL_GivePoints( &Player, 2000 );
break;
case en_mecha:
PL_GivePoints( &Player, 5000 );
break;
case en_hitler:
PL_GivePoints( &Player, 5000 );
A_DeathScream( self );
A_StartDeathCam( self );
break;
case en_spectre:
PL_GivePoints( &Player, 200 );
break;
case en_angel:
PL_GivePoints( &Player, 5000 );
break;
case en_trans:
PL_GivePoints( &Player, 5000 );
Powerup_Spawn( tilex, tiley, pow_key1, r_world );
break;
case en_uber:
PL_GivePoints( &Player, 5000 );
Powerup_Spawn( tilex, tiley, pow_key1, r_world );
break;
case en_will:
PL_GivePoints( &Player, 5000 );
Powerup_Spawn( tilex, tiley, pow_key1, r_world );
break;
case en_death:
PL_GivePoints( &Player, 5000 );
Powerup_Spawn( tilex, tiley, pow_key1, r_world );
break;
}
A_StateChange( self, st_die1 );
if ( ++levelstate.killed_monsters == levelstate.total_monsters ) {
iphoneSetNotifyText( "You killed the last enemy!" );
}
self->flags &= ~FL_SHOOTABLE;
self->flags |= FL_NONMARK;
}
/*
-----------------------------------------------------------------------------
Function: A_DamageActor() -Called when the player succesfully hits an enemy.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
Does damage points to enemy ob, either putting it into a stun frame or
killing it.
-----------------------------------------------------------------------------
*/
PUBLIC void A_DamageActor( entity_t *self, int damage )
{
Player.madenoise = 1;
// do double damage if shooting a non attack mode actor
if( ! (self->flags & FL_ATTACKMODE) )
{
damage <<= 1;
}
self->health -= damage;
if( self->health <= 0 )
{
A_KillActor( self );
}
else
{
if( ! (self->flags & FL_ATTACKMODE) )
{
A_FirstSighting( self ); // put into combat mode
}
switch( self->type ) // dogs only have one hit point
{
case en_guard:
case en_officer:
case en_mutant:
case en_ss:
if( self->health & 1 )
{
A_StateChange( self, st_pain );
}
else
{
A_StateChange( self, st_pain1 );
}
break;
}
}
}
///////////////////////////
//
// Hitler
//
///////////////////////////
/*
-----------------------------------------------------------------------------
Function: A_MechaSound -Play Mecha sound.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_MechaSound( entity_t *self )
{
if( areabyplayer[ self->areanumber ] )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "sfx/080.wav" ), 1, ATTN_NORM, 0 );
}
}
/*
-----------------------------------------------------------------------------
Function: A_Slurpie -Play Slurpie sound.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_Slurpie( entity_t *self )
{
Sound_StartSound( NULL, 1, CHAN_VOICE, Sound_RegisterSound( "lsfx/061.wav" ), 1, ATTN_NORM, 0 );
}
/*
-----------------------------------------------------------------------------
Function: A_HitlerMorph() -Spawn new actor, when Mecha Hitler is dead.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_HitlerMorph( entity_t *self )
{
int hitpoints[ 4 ] = { 500, 700, 800, 900 };
entity_t *hitler;
hitler = GetNewActor();
if( ! hitler )
{
return;
}
hitler->x = self->x;//
hitler->y = self->y;//
hitler->distance = self->distance;
hitler->tilex = self->tilex;//
hitler->tiley = self->tiley;//
hitler->angle = self->angle;//
hitler->dir = self->dir;//
hitler->health = hitpoints[ (int)skill->value ];
hitler->areanumber = self->areanumber;
hitler->state = st_chase1;//
hitler->type = en_hitler; //
hitler->speed = SPDPATROL * 5;//
hitler->ticcount = 0;//
hitler->flags=self->flags | FL_SHOOTABLE; //
hitler->sprite = Sprite_GetNewSprite();
if ( ++levelstate.killed_monsters == levelstate.total_monsters ) {
iphoneSetNotifyText( "You killed the last enemy!" );
}
}
///////////////////////////
//
// Angel of Death
//
///////////////////////////
/*
Angel can't shoot more then 3 sparks in a row.
It will get tired!
*/
PRIVATE int angel_temp = 0;
//
/*
-----------------------------------------------------------------------------
Function: A_Breathing -Play Angel of Death Breathing sound.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_Breathing( entity_t *self )
{
Sound_StartSound( NULL, 0, CHAN_VOICE, Sound_RegisterSound( "lsfx/080.wav" ), 1, ATTN_NORM, 0 );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_StartAttack( entity_t *self )
{
angel_temp = 0;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_Relaunch( entity_t *self )
{
if( ++angel_temp == 3 )
{
A_StateChange( self, st_pain );
return;
}
if( US_RndT() & 1 )
{
A_StateChange( self, st_chase1 );
return;
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_Victory( entity_t *self )
{
iphoneStartIntermission( 0 );
}
/*
-----------------------------------------------------------------------------
Function: A_Dormant() -Entity is dormant state.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_Dormant( entity_t *self )
{
int deltax, deltay;
int xl, xh, yl, yh, x, y, n;
deltax = self->x - Player.position.origin[ 0 ];
if( deltax < -MINACTORDIST || deltax > MINACTORDIST )
{
goto moveok;
}
deltay = self->y - Player.position.origin[ 1 ];
if( deltay < -MINACTORDIST || deltay > MINACTORDIST )
{
goto moveok;
}
return;
moveok:
xl = (self->x - MINDIST) >> TILESHIFT;
xh = (self->x + MINDIST) >> TILESHIFT;
yl = (self->y - MINDIST) >> TILESHIFT;
yh = (self->y + MINDIST) >> TILESHIFT;
for( y = yl ; y <= yh ; ++y )
for( x = xl ; x <= xh ; ++x )
{
if( r_world->tilemap[ x ][ y ] & SOLID_TILE )
{
return;
}
for( n = 0 ; n < NumGuards ; ++n )
{
if( Guards[ n ].state >= st_die1 )
{
continue;
}
if( Guards[ n ].tilex == x && Guards[ n ].tiley == y )
{
return; // another guard in path
}
}
}
self->flags |= FL_AMBUSH | FL_SHOOTABLE;
self->flags &= ~FL_ATTACKMODE;
self->dir = dir8_nodir;
A_StateChange( self, st_path1 );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_StartDeathCam( entity_t *self )
{
// the DeathCam feature isn't implimented, but we want to give the animation time
// to play before declaring victory.
iphoneStartIntermission( 50 );
}
/*
-----------------------------------------------------------------------------
Function: A_Smoke() -Rockets emmit smoke.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_Smoke( entity_t *self )
{
entity_t *smoke;
smoke = GetNewActor();
if( ! smoke )
{
return;
}
smoke->x = self->x;
smoke->y = self->y;
smoke->tilex = self->tilex;
smoke->tiley = self->tiley;
smoke->state = st_die1;
smoke->type = (self->type==en_hrocket) ? en_hsmoke : en_smoke;
smoke->ticcount = 6;
smoke->flags = FL_NEVERMARK;
smoke->sprite = Sprite_GetNewSprite();
}
/*
-----------------------------------------------------------------------------
Function: ProjectileTryMove() -Called when projectile is airborne.
Parameters: self -[in] Valid Pointer to an entity_t structure.
lvl -[in] Valid Pointer to LevelData_t structure.
Returns: true if move ok, otherwise false.
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE _boolean ProjectileTryMove( entity_t *self, LevelData_t *lvl )
{
#define PROJSIZE 0x2000
int xl, yl, xh, yh, x, y;
xl = (self->x - PROJSIZE) >> TILESHIFT;
yl = (self->y - PROJSIZE) >> TILESHIFT;
xh = (self->x + PROJSIZE) >> TILESHIFT;
yh = (self->y + PROJSIZE) >> TILESHIFT;
// Checking for solid walls:
for( y = yl ; y <= yh ; ++y )
{
for( x = xl ; x <= xh ; ++x )
{
// FIXME: decide what to do with statics & Doors!
if( lvl->tilemap[ x ][ y ] & (WALL_TILE | BLOCK_TILE) )
{
return false;
}
if( lvl->tilemap[ x ][ y ] & DOOR_TILE )
{
if( Door_Opened( &lvl->Doors, x, y ) != DOOR_FULLOPEN )
{
return false;
}
}
}
}
// FIXME: Projectile will fly through objects (even guards & columns) - must fix to create rocket launcher!
return true;
}
/*
-----------------------------------------------------------------------------
Function: T_Projectile() -Called when projectile is airborne.
Parameters: self -[in] Valid Pointer to an entity_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void T_Projectile( entity_t *self )
{
#define PROJECTILESIZE 0xC000
int deltax, deltay, speed, damage;
speed = self->speed * tics;
deltax = (int)(speed * CosTable[ self->angle ]);
deltay = (int)(speed * SinTable[ self->angle ]);
if( deltax > TILEGLOBAL )
{
deltax = TILEGLOBAL;
}
if( deltax < -TILEGLOBAL )
{
deltax = -TILEGLOBAL; // my
}
if( deltay > TILEGLOBAL)
{
deltay = TILEGLOBAL;
}
if( deltay < -TILEGLOBAL)
{
deltay = -TILEGLOBAL; // my
}
self->x += deltax;
self->y += deltay;
deltax = ABS( self->x-Player.position.origin[ 0 ] );
deltay = ABS( self->y-Player.position.origin[ 1 ] );
if( ! ProjectileTryMove( self, r_world ) )
{
if( self->type == en_rocket || self->type == en_hrocket )
{ // rocket ran into obstacle, draw explosion!
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_WEAPON, Sound_RegisterSound( "lsfx/001.wav" ), 1, ATTN_NORM, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_WEAPON, Sound_RegisterSound( "lsfx/086.wav" ), 1, ATTN_NORM, 0 );
}
A_StateChange( self, st_die1 );
}
else
{
A_StateChange( self, st_remove ); // mark for removal
}
return;
}
if( deltax < PROJECTILESIZE && deltay < PROJECTILESIZE )
{ // hit the player
switch( self->type )
{
case en_needle:
damage = (US_RndT() >> 3) + 20;
break;
case en_rocket:
case en_hrocket:
case en_spark:
damage = (US_RndT()>>3) + 30;
break;
case en_fire:
damage = (US_RndT() >> 3);
break;
default:
damage = 0;
break;
}
PL_Damage( &Player, self, damage );
A_StateChange( self, st_remove ); // mark for removal
return;
}
self->tilex = self->x >> TILESHIFT;
self->tiley = self->y >> TILESHIFT;
}

View File

@@ -0,0 +1,73 @@
/*
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_actor_ai.h: Wolfenstein3-D entity management.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_actor_ai.c.
*/
#ifndef __WOLF_ACTOR_AI_H__
#define __WOLF_ACTOR_AI_H__
#include "wolf_actors.h"
extern void A_DeathScream( entity_t *self );
extern void A_FirstSighting( entity_t *self );
extern void A_DamageActor( entity_t *self, int damage );
// hitler
extern void A_MechaSound( entity_t *self );
extern void A_Slurpie( entity_t *self );
extern void A_HitlerMorph( entity_t *self );
// angel
extern void A_Breathing( entity_t *self );
extern void A_StartAttack( entity_t *self );
extern void A_Relaunch( entity_t *self );
extern void A_Victory( entity_t *self );
// ghost
extern void A_Dormant( entity_t *self );
extern void A_StartDeathCam( entity_t *self );
// missiles
extern void T_Projectile( entity_t *self );
extern void A_Smoke( entity_t *self );
#endif /* __WOLF_ACTOR_AI_H__ */

View File

@@ -0,0 +1,471 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 2001 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_actors.c: Wolfenstein3-D actor manager.
*
* 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"
#include "wolf_act_stat.h"
entity_t Guards[ MAX_GUARDS + 1 ], *New;
W16 NumGuards = 0;
W8 add8dir[ 9 ] = { 4, 5, 6, 7, 0, 1, 2, 3, 0 };
W8 r_add8dir[ 9 ]= { 4, 7, 6, 5, 0, 1, 2, 3, 0 };
/*
-----------------------------------------------------------------------------
Function: A_StateChange -Changes guard's state to that defined in NewState.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void A_StateChange( entity_t *ent, en_state NewState )
{
ent->state = NewState;
assert( ent->type >= 0 && ent->type < NUMENEMIES );
if ( NewState == st_remove ) {
ent->ticcount = 0;
} else {
assert( ent->state >= 0 && ent->state < NUMSTATES );
ent->ticcount = objstate[ ent->type ][ ent->state ].timeout; //0;
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE int DoGuard( entity_t *ent ) // FIXME: revise!
{ // returns 0 if we must remove this Guard from Guards list, otherwise 1;
think_t think;
assert( ent->tilex >= 0 && ent->tilex < 64 );
assert( ent->tiley >= 0 && ent->tiley < 64 );
assert( ent->dir >= 0 && ent->dir <= 8 );
// ticcounts fire discrete actions separate from think functions
if ( ent->ticcount ) {
ent->ticcount -= tics;
while( ent->ticcount <= 0 )
{
assert( ent->type >= 0 && ent->type < NUMENEMIES );
assert( ent->state >= 0 && ent->state < NUMSTATES );
think = objstate[ ent->type ][ ent->state ].action; // end of state action
if( think )
{
think( ent );
if( ent->state == st_remove )
{
return 0;
}
}
ent->state = objstate[ ent->type ][ ent->state ].next_state;
if( ent->state == st_remove )
{
return 0;
}
if( ! objstate[ ent->type ][ ent->state ].timeout )
{
ent->ticcount = 0;
break;
}
ent->ticcount += objstate[ ent->type ][ ent->state ].timeout;
}
}
//
// think
//
assert( ent->type >= 0 && ent->type < NUMENEMIES );
assert( ent->state >= 0 && ent->state < NUMSTATES );
think = objstate[ ent->type ][ ent->state ].think;
if( think )
{
think( ent );
if( ent->state == st_remove )
{
return 0;
}
}
return 1;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE void RemoveActor( entity_t *actor )
{
Sprite_RemoveSprite( actor->sprite );
memmove( actor, actor+1, (int)(&Guards[ NumGuards ]) - (int)(actor+1) );
NumGuards--;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void ProcessGuards( void )
{
int n, tex;
assert( NumGuards < MAX_GUARDS );
for( n = 0 ; n < NumGuards ; ++n )
{
if( ! DoGuard( &Guards[ n ] ) )
{ // remove guard from the game forever!
RemoveActor( &Guards[ n-- ] );
continue;
}
Sprite_SetPos( Guards[ n ].sprite, Guards[ n ].x, Guards[ n ].y, Guards[ n ].angle );
tex = objstate[ Guards[ n ].type ][ Guards[ n ].state ].texture;
if( objstate[ Guards[ n ].type ][ Guards[ n ].state ].rotate )
{
if( Guards[ n ].type == en_rocket || Guards[ n ].type == en_hrocket )
{
tex += r_add8dir[ Get8dir( angle_wise( FINE2RAD(Player.position.angle), FINE2RAD(Guards[ n ].angle) ) ) ];
}
else
{
tex += add8dir[ Get8dir( angle_wise( FINE2RAD(Player.position.angle), FINE2RAD(Guards[ n ].angle) ) ) ];
}
}
Sprite_SetTex( Guards[ n ].sprite, 0, tex );
}
}
/*
-----------------------------------------------------------------------------
Function: ResetGuards -Reset actors status
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void ResetGuards( void )
{
memset( Guards, 0, sizeof( Guards ) );
NumGuards = 0;
New = NULL;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC entity_t *GetNewActor( void )
{
if( NumGuards > MAX_GUARDS )
{
return NULL;
}
memset( &Guards[ NumGuards ], 0, sizeof( Guards[ 0 ] ) );
return &Guards[ NumGuards++ ];
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC entity_t *SpawnActor( enemy_t which, int x, int y, dir4type dir, LevelData_t *lvl )
{
entity_t *new_actor;
new_actor = GetNewActor();
if( ! new_actor )
{
return NULL;
}
new_actor->x = TILE2POS( x );
new_actor->y = TILE2POS( y );
new_actor->tilex = x;
new_actor->tiley = y;
assert( dir >= 0 && dir <= 4 );
new_actor->angle = dir4angle[ dir ];
new_actor->dir = dir4to8[ dir ];
new_actor->areanumber = lvl->areas[ x ][ y ];
// Com_Printf( "Actor at %i,%i had areaNum: %i\n", x, y, new_actor->areanumber );
if ( new_actor->areanumber < 0 ) {
// ambush marker tiles are listed as -3 area
new_actor->areanumber = 0;
}
assert( new_actor->areanumber >= 0 && new_actor->areanumber < NUMAREAS );
new_actor->type = which;
new_actor->health = starthitpoints[ (int)skill->value ][ which ];
new_actor->sprite = Sprite_GetNewSprite();
return new_actor;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void SpawnStand( enemy_t which, int x, int y, int dir, LevelData_t *lvl )
{
entity_t *self;
self = SpawnActor( which, x, y, dir, r_world );
if( ! self )
{
return;
}
self->state = st_stand;
self->speed = SPDPATROL;
self->ticcount = objstate[ which ][ st_stand ].timeout ? US_RndT() % objstate[ which ][ st_stand ].timeout + 1 : 0;
self->flags |= FL_SHOOTABLE;
if( lvl->tilemap[ x ][ y ] & AMBUSH_TILE )
{
self->flags |= FL_AMBUSH;
}
levelstate.total_monsters++;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void SpawnPatrol( enemy_t which, int x, int y, int dir )
{
entity_t *self;
self = SpawnActor( which, x, y, dir, r_world );
if( ! self )
{
return;
}
self->state = st_path1;
self->speed = (which == en_dog) ? SPDDOG : SPDPATROL;
self->distance = TILEGLOBAL;
self->ticcount = objstate[ which ][ st_path1 ].timeout ? US_RndT() % objstate[ which ][ st_path1 ].timeout + 1 : 0;
self->flags |= FL_SHOOTABLE;
levelstate.total_monsters++;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void SpawnDeadGuard( enemy_t which, int x, int y )
{
entity_t *self;
self = SpawnActor( which, x, y, dir4_nodir, r_world );
if( ! self )
{
return;
}
self->state = st_dead;
self->speed = 0;
self->health = 0;
self->ticcount = objstate[ which ][ st_dead ].timeout ? US_RndT() % objstate[ which ][ st_dead ].timeout + 1 : 0;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void SpawnBoss( enemy_t which, int x, int y )
{
entity_t *self;
dir4type face;
switch( which )
{
case en_boss:
case en_schabbs:
case en_fat:
case en_hitler:
face = dir4_south;
break;
case en_fake:
case en_gretel:
case en_gift:
face = dir4_north;
break;
case en_trans:
case en_uber:
case en_will:
case en_death:
case en_angel:
case en_spectre:
face = dir4_nodir;
break;
default:
face = dir4_nodir;
break;
}
self = SpawnActor( which, x, y, face, r_world );
if( ! self )
{
return;
}
self->state = which == en_spectre ? st_path1 : st_stand;
self->speed = SPDPATROL;
self->health = starthitpoints[ (int)skill->value ][ which ];
self->ticcount = objstate[ which ][ st_stand ].timeout ? US_RndT() % objstate[ which ][ st_stand ].timeout + 1 : 0;
self->flags |= FL_SHOOTABLE | FL_AMBUSH;
levelstate.total_monsters++;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void SpawnGhosts( enemy_t which, int x, int y )
{
entity_t *self;
self = SpawnActor( which, x, y, dir4_nodir, r_world );
if( ! self )
{
return;
}
self->state = st_chase1;
self->speed = SPDPATROL * 3;
self->health = starthitpoints[ (int)skill->value ][ which ];
self->ticcount = objstate[ which ][ st_chase1 ].timeout ? US_RndT() % objstate[ which ][ st_chase1 ].timeout + 1: 0;
self->flags |= FL_AMBUSH;
levelstate.total_monsters++;
}

View File

@@ -0,0 +1,172 @@
/*
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_actors.h: Wolfenstein3-D entity management.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_actors.c
*/
#ifndef __WOLF_ACTORS_H__
#define __WOLF_ACTORS_H__
#define SPDPATROL 512
#define SPDDOG 1500
#define FL_SHOOTABLE 1
#define FL_BONUS 2
#define FL_NEVERMARK 4
#define FL_VISABLE 8
#define FL_ATTACKMODE 16
#define FL_FIRSTATTACK 32
#define FL_AMBUSH 64
#define FL_NONMARK 128
#define MAX_GUARDS 255
#define NUMENEMIES 31
#define NUMSTATES 34
#define MINACTORDIST 0x10000 // minimum dist from player center to any actor center
typedef enum
{
en_guard,
en_officer,
en_ss,
en_dog,
en_boss,
en_schabbs,
en_fake,
en_mecha,
en_hitler,
en_mutant,
en_blinky,
en_clyde,
en_pinky,
en_inky,
en_gretel,
en_gift,
en_fat,
// --- Projectiles
en_needle,
en_fire,
en_rocket,
en_smoke,
en_bj,
// --- Spear of destiny!
en_spark,
en_hrocket,
en_hsmoke,
en_spectre,
en_angel,
en_trans,
en_uber,
en_will,
en_death
} enemy_t;
typedef enum
{
st_stand,
st_path1, st_path1s, st_path2, st_path3, st_path3s, st_path4,
st_pain, st_pain1,
st_shoot1, st_shoot2, st_shoot3, st_shoot4, st_shoot5, st_shoot6, st_shoot7, st_shoot8, st_shoot9,
st_chase1, st_chase1s, st_chase2, st_chase3, st_chase3s, st_chase4,
st_die1, st_die2, st_die3, st_die4, st_die5, st_die6, st_die7, st_die8, st_die9,
st_dead,
st_remove
} en_state;
typedef struct entity_s
{
int x, y, angle;
int type;
int health;
int max_health;
int speed;
int ticcount;
int temp2;
int distance;
char tilex, tiley;
char areanumber;
int waitfordoorx, waitfordoory; // waiting on this door if non 0
W8 flags; // FL_SHOOTABLE, etc
en_state state;
dir8type dir;
int sprite;
} entity_t;
typedef void (*think_t)( entity_t *self );
typedef struct
{
char rotate; // 1-if object can be rotated, 0 if one sprite for every direction
int texture; // base object's state texture if rotation is on facing player
int timeout; // after how man ticks change state to .next_state
think_t think; // what to do every frame
think_t action; // what to do once per state
en_state next_state; // next state
} stateinfo;
extern entity_t Guards[ MAX_GUARDS + 1 ];
extern entity_t *New;
extern W16 NumGuards;
extern stateinfo objstate[ NUMENEMIES ][ NUMSTATES ];
extern void ResetGuards(void);
extern entity_t *GetNewActor( void );
extern entity_t *SpawnActor( enemy_t which, int x, int y, dir4type dir, LevelData_t *lvl );
extern void A_StateChange( entity_t *Guard, en_state NewState );
extern void SpawnStand( enemy_t which, int tilex, int tiley, int dir, LevelData_t *lvl );
extern void SpawnPatrol( enemy_t which, int tilex, int tiley, int dir );
extern void SpawnDeadGuard( enemy_t which, int x, int y );
extern void SpawnBoss( enemy_t which, int x, int y );
extern void SpawnGhosts( enemy_t which, int x, int y );
#endif /* __WOLF_ACTORS_H__ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,65 @@
/*
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_ai_com.h: Wolfenstein3-D entity management.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_ai_com.c
*/
#ifndef __WOLF_AI_COM_H__
#define __WOLF_AI_COM_H__
#include "wolf_actors.h"
// common AI functions
extern void T_Stand( entity_t *self );
extern void T_Path( entity_t *self );
extern void T_Ghosts( entity_t *self );
extern void T_Chase( entity_t *self );
extern void T_Bite( entity_t *self );
extern void T_DogChase( entity_t *self );
extern void T_BossChase( entity_t *self );
extern void T_Fake( entity_t *self );
extern void T_Shoot( entity_t *self );
extern void T_UShoot( entity_t *self );
extern void T_Launch( entity_t *self );
#endif /* __WOLF_AI_COM_H__ */

View File

@@ -0,0 +1,170 @@
/*
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_areas.c: Wolfenstein3-D area management.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Acknowledgement:
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
Open doors connect two areas, so sounds will travel between them and sight
will be checked when the player is in a connected area.
Areaconnect is incremented/decremented by each door. If >0 they connect.
Every time a door opens or closes the areabyplayer matrix gets recalculated.
An area is true if it connects with the player's current spor.
*/
#include "../wolfiphone.h"
W8 areaconnect[ NUMAREAS ][ NUMAREAS ];
_boolean areabyplayer[ NUMAREAS ];
/*
-----------------------------------------------------------------------------
Function: Areas_RecursiveConnect() -Scans outward from playerarea,
marking all connected areas.
Parameters: areanumber -[in] area.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE void Areas_RecursiveConnect( int areanumber )
{
int i;
for( i = 0 ; i < NUMAREAS ; ++i )
{
if( areaconnect[ areanumber ][ i ] && ! areabyplayer[ i ] )
{
areabyplayer[ i ] = true;
Areas_RecursiveConnect( i );
}
}
}
/*
-----------------------------------------------------------------------------
Function: Areas_ConnectAreas() -Connect area.
Parameters: areanumber -[in] area.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Areas_ConnectAreas( int areanumber )
{
int c = 0;
int i;
assert( areanumber < NUMAREAS );
memset( areabyplayer, 0, sizeof( areabyplayer ) );
areabyplayer[ areanumber ] = true;
Areas_RecursiveConnect( areanumber );
for ( i = 0 ; i < NUMAREAS ; i++ ) {
if ( areabyplayer[i] ) {
c++;
}
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Areas_InitAreas( int areanumber )
{
memset( areaconnect, 0, sizeof( areaconnect ) );
memset( areabyplayer, 0, sizeof( areabyplayer ) );
areabyplayer[ areanumber ] = true;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Areas_JoinAreas( int area1, int area2 )
{// FIXME: check for overflow!
areaconnect[ area1 ][ area2 ]++;
areaconnect[ area2 ][ area1 ]++;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Areas_DisconnectAreas( int area1, int area2 )
{// FIXME: check for underflow!
areaconnect[ area1 ][ area2 ]--;
areaconnect[ area2 ][ area1 ]--;
}

View File

@@ -0,0 +1,136 @@
/*
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.
*/
#include "../wolfiphone.h"
#define BJRUNSPEED 2048
#define BJJUMPSPEED 680
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
void SpawnBJVictory( void )
{
entity_t *bj;
bj = SpawnActor( en_bj, POS2TILE(Player.position.origin[0]), POS2TILE(Player.position.origin[1]), dir4_north, r_world );
if( ! bj )
{
return;
}
bj->x = Player.position.origin[ 0 ];
bj->y = Player.position.origin[ 1 ];
bj->state = st_path1;
bj->speed = BJRUNSPEED;
bj->flags = FL_NONMARK; // FL_NEVERMARK;
bj->temp2 = 6;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
void T_BJRun( entity_t *Guard )
{
// MoveObj(Guard, Guard->speed);
if( ! Guard->distance )
{
Guard->distance = TILEGLOBAL;
if ( !(--Guard->temp2) )
{
A_StateChange( Guard, st_shoot1 );
Guard->speed = BJJUMPSPEED;
return;
}
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
void T_BJJump( entity_t *Guard )
{
// MoveObj(Guard, Guard->speed);
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
void T_BJYell( entity_t *Guard )
{
Sound_StartSound( NULL, 0, CHAN_VOICE, Sound_RegisterSound( "sfx/082.wav" ), 1, ATTN_NORM, 0 );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
void T_BJDone( entity_t *Guard )
{
Player.playstate = ex_victory; // exit castle tile
}

View File

@@ -0,0 +1,59 @@
/*
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_bj.h: Wolfenstein3-D bj code .
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_bj.c
*/
#ifndef __WOLF_BJ_H__
#define __WOLF_BJ_H__
extern void SpawnBJVictory( void );
extern void T_BJRun( entity_t *Guard );
extern void T_BJJump( entity_t *Guard );
extern void T_BJYell( entity_t *Guard );
extern void T_BJDone( entity_t *Guard );
#endif /* __WOLF_BJ_H__ */

View File

@@ -0,0 +1,94 @@
/*
Copyright (C) 2004 Michael Liebscher
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.
*/
#include "../wolfiphone.h"
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Client_PrepRefresh( const char *r_mapname )
{
char mapname[ 32 ];
if( ! r_mapname || ! *r_mapname )
{
return;
}
if( g_version->value == SPEAROFDESTINY )
{
spritelocation = SODSPRITESDIRNAME;
}
else
{
spritelocation = WL6SPRITESDIRNAME;
}
my_strlcpy( mapname, r_mapname, sizeof( mapname ) ); // skip "maps/"
// !@# fix crash bug if you type something short...
if ( strlen( mapname ) > 4 && !strcmp( mapname + strlen( mapname ) - 4, ".map" ) ) {
mapname[ strlen( mapname ) - 4 ] = '\0'; // cut off ".map"
}
// register models, pics, and skins
R_BeginRegistration( mapname );
if( r_world == NULL )
{
return;
}
Com_Printf( "Map: %s\n", r_world->mapName );
Level_ScanInfoPlane( r_world ); // Spawn items/guards
Com_Printf( "Spawning Entities\n" );
PL_Spawn( r_world->pSpawn, r_world ); // Spawn Player
Com_Printf( "Caching Textures and Sounds\n" );
Level_PrecacheTextures_Sound( r_world );
// clear any lines of console text
Con_ClearNotify();
if( r_world->musicName )
{
Sound_StartBGTrack( r_world->musicName, r_world->musicName );
}
Player.playstate = ex_playing;
}
int tics;

View File

@@ -0,0 +1,506 @@
/*
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_doors.c: Wolfenstein 3-D door management.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Acknowledgement:
* Portion of this code was derived from Wolfenstein 3-D, and was originally
* written by Id Software, Inc.
*
*/
#include "../wolfiphone.h"
#define CLOSEWALL MINDIST // Space between wall & player
#define MAXDOORS 64 // max number of sliding doors
/*
-----------------------------------------------------------------------------
Function: Door_ResetDoors -Resets doors status
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Door_ResetDoors( LevelDoors_t *lvldoors )
{
lvldoors->doornum = 0;
memset( lvldoors->Doors, 0, sizeof( lvldoors->Doors ) );
memset( lvldoors->DoorMap, 0, sizeof( lvldoors->DoorMap ) );
}
/*
-----------------------------------------------------------------------------
Function: Door_SpawnDoor -Spawns door at x, y, position.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC int Door_SpawnDoor( LevelDoors_t *lvldoors, int x, int y, int type )
{
if( lvldoors->doornum >= MAXDOORS )
{
Com_DPrintf( "[%s]: Too many Doors on level! (%d)\n", "wolf_doors.c", lvldoors->doornum );
return 0;
}
switch( type )
{
case 0x5A:
lvldoors->DoorMap[ x ][ y ].type = DOOR_VERT;
lvldoors->DoorMap[ x ][ y ].vertical= true;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DDOOR + 1;
break;
case 0x5B:
lvldoors->DoorMap[ x ][ y ].type = DOOR_HORIZ;
lvldoors->DoorMap[ x ][ y ].vertical = false;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DDOOR;
break;
case 0x5C:
lvldoors->DoorMap[ x ][ y ].type = DOOR_G_VERT;
lvldoors->DoorMap[ x ][ y ].vertical = true;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK + 1;
break;
case 0x5D:
lvldoors->DoorMap[ x ][ y ].type = DOOR_G_HORIZ;
lvldoors->DoorMap[ x ][ y ].vertical = false;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK;
break;
case 0x5E:
lvldoors->DoorMap[ x ][ y ].type = DOOR_S_VERT;
lvldoors->DoorMap[ x ][ y ].vertical = true;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK + 1;
break;
case 0x5F:
lvldoors->DoorMap[ x ][ y ].type = DOOR_S_HORIZ;
lvldoors->DoorMap[ x ][ y ].vertical = false;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DLOCK;
break;
case 0x64:
lvldoors->DoorMap[ x ][ y ].type = DOOR_E_VERT;
lvldoors->DoorMap[ x ][ y ].vertical = true;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DELEV + 1;
break;
case 0x65:
lvldoors->DoorMap[ x ][ y ].type = DOOR_E_HORIZ;
lvldoors->DoorMap[ x ][ y ].vertical = false;
lvldoors->DoorMap[ x ][ y ].texture = TEX_DELEV;
break;
default:
Com_DPrintf( "Door_SpawnDoor: Unknown door type: %d\n", type );
return 0;
}
lvldoors->DoorMap[ x ][ y ].tilex = x;
lvldoors->DoorMap[ x ][ y ].tiley = y;
lvldoors->DoorMap[ x ][ y ].action = dr_closed;
lvldoors->Doors[ lvldoors->doornum ] = &lvldoors->DoorMap[ x ][ y ];
lvldoors->doornum++;
return lvldoors->doornum - 1;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Door_SetAreas( LevelDoors_t *lvldoors, int (*areas)[64] )
{
int n, x, y;
for( n = 0 ; n < lvldoors->doornum ; ++n )
{
x = lvldoors->Doors[ n ]->tilex;
y = lvldoors->Doors[ n ]->tiley;
if( lvldoors->Doors[ n ]->vertical )
{
lvldoors->Doors[ n ]->area1 = areas[ x + 1 ][ y ] >= 0 ? areas[ x + 1 ][ y ] : 0;
lvldoors->Doors[ n ]->area2 = areas[ x - 1 ][ y ] >= 0 ? areas[ x - 1 ][ y ] : 0;
}
else
{
lvldoors->Doors[ n ]->area1 = areas[ x ][ y + 1 ] >= 0 ? areas[ x ][ y + 1 ] : 0;
lvldoors->Doors[ n ]->area2 = areas[ x ][ y - 1 ] >= 0 ? areas[ x ][ y - 1 ] : 0;
}
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE W8 CanCloseDoor( int x, int y, char vert )
{
int n;
if( POS2TILE( Player.position.origin[ 0 ] ) == x &&
POS2TILE( Player.position.origin[ 1 ] ) == y )
{
return 0;
}
if( vert )
{
if( POS2TILE( Player.position.origin[ 1 ] ) == y )
{
if( POS2TILE( Player.position.origin[ 0 ] + CLOSEWALL ) == x )
{
return 0;
}
if( POS2TILE( Player.position.origin[ 0 ] - CLOSEWALL ) == x )
{
return 0;
}
}
for( n = 0 ; n < NumGuards ; ++n )
{
if( Guards[ n ].tilex == x && Guards[ n ].tiley == y )
{
return 0; // guard in door
}
if( Guards[ n ].tilex == x - 1 &&
Guards[ n ].tiley == y &&
POS2TILE( Guards[ n ].x + CLOSEWALL ) == x )
{
return 0; // guard in door
}
if( Guards[ n ].tilex == x + 1 &&
Guards[ n ].tiley == y &&
POS2TILE( Guards[ n ].x - CLOSEWALL ) == x )
{
return 0; // guard in door
}
}
}
else
{
if( POS2TILE( Player.position.origin[ 0 ] ) == x )
{
if( POS2TILE( Player.position.origin[ 1 ] + CLOSEWALL ) == y )
{
return 0;
}
if( POS2TILE( Player.position.origin[ 1 ] - CLOSEWALL ) == y )
{
return 0;
}
}
for( n = 0 ; n < NumGuards ; ++n )
{
if( Guards[ n ].tilex == x && Guards[ n ].tiley == y )
{
return 0; // guard in door
}
if( Guards[ n ].tilex == x &&
Guards[ n ].tiley == y - 1 &&
POS2TILE( Guards[ n ].y + CLOSEWALL ) == y )
{
return 0; // guard in door
}
if( Guards[ n ].tilex == x &&
Guards[ n ].tiley == y + 1 &&
POS2TILE( Guards[ n ].y - CLOSEWALL ) == y )
{
return 0; // guard in door
}
}
}
return 1;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Door_OpenDoor( doors_t *Door )
{
if( Door->action == dr_open )
{
Door->ticcount = 0; // reset opened time
}
else
{
Door->action = dr_opening; // start opening it
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE void Door_ChangeDoorState( doors_t *Door )
{
if( Door->action < dr_opening )
{
Door_OpenDoor( Door );
}
else if( Door->action == dr_open && CanCloseDoor( Door->tilex, Door->tiley, Door->vertical ) )
{
// !@# for the iphone with automatic using, don't allow any door close actions
// Door->action = dr_closing;
// Door->ticcount = DOOR_FULLOPEN;
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Door_ProcessDoors_e( LevelDoors_t *lvldoors, int t_tk, int t_ms )
{
int n;
for( n = 0 ; n < lvldoors->doornum ; ++n )
{
switch( lvldoors->Doors[ n ]->action )
{
case dr_closed: // this door is closed!
continue;
case dr_opening:
if( lvldoors->Doors[ n ]->ticcount >= DOOR_FULLOPEN ) // door fully opened!
{
lvldoors->Doors[ n ]->action = dr_open;
lvldoors->Doors[ n ]->ticcount = 0;
}
else // opening!
{
if( lvldoors->Doors[ n ]->ticcount == 0 )
{ // door is just starting to open, so connect the areas
Areas_JoinAreas( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 );
Areas_ConnectAreas( Player.areanumber );
if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Opening sound!
{
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/010.wav" ), 1, ATTN_STATIC, 0 );
}
}
lvldoors->Doors[n]->ticcount += t_tk;
if( lvldoors->Doors[ n ]->ticcount > DOOR_FULLOPEN )
{
lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN;
}
}
break;
case dr_closing:
if( lvldoors->Doors[ n ]->ticcount <= 0 ) // door fully closed! disconnect areas!
{
Areas_DisconnectAreas( lvldoors->Doors[ n ]->area1, lvldoors->Doors[ n ]->area2 );
Areas_ConnectAreas( Player.areanumber );
lvldoors->Doors[ n ]->ticcount = 0;
lvldoors->Doors[ n ]->action = dr_closed;
}
else // closing!
{
if( lvldoors->Doors[ n ]->ticcount == DOOR_FULLOPEN )
{
if( areabyplayer[ lvldoors->Doors[ n ]->area1 ] ) // Door Closing sound!
{
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/007.wav" ), 1, ATTN_STATIC, 0 );
}
}
lvldoors->Doors[ n ]->ticcount -= t_tk;
if( lvldoors->Doors[ n ]->ticcount < 0 )
{
lvldoors->Doors[ n ]->ticcount = 0;
}
}
break;
case dr_open:
if( lvldoors->Doors[ n ]->ticcount > DOOR_MINOPEN )
{ // If player or something is in door do not close it!
if( ! CanCloseDoor( lvldoors->Doors[ n ]->tilex, lvldoors->Doors[ n ]->tiley, lvldoors->Doors[ n ]->vertical ) )
{
lvldoors->Doors[ n ]->ticcount = DOOR_MINOPEN; // do not close door immediately!
}
}
if( lvldoors->Doors[ n ]->ticcount >= DOOR_TIMEOUT )
{ // Door timeout, time to close it!
lvldoors->Doors[ n ]->action = dr_closing;
lvldoors->Doors[ n ]->ticcount = DOOR_FULLOPEN;
}
else
{ // Increase timeout!
lvldoors->Doors[ n ]->ticcount += t_tk;
}
break;
} // End switch lvldoors->Doors[ n ].action
} // End for n = 0 ; n < lvldoors->doornum ; ++n
}
/*
-----------------------------------------------------------------------------
Function: Door_Opened -Check to see if a door is open.
Parameters:
Returns: DOOR_FULLOPEN Door is opened
0 Door is closed
>0 <DOOR_FULLOPEN Door is partially opened.
Notes:
If there are no doors in tile assume a closed door!
-----------------------------------------------------------------------------
*/
PUBLIC int Door_Opened( LevelDoors_t *lvldoors, int x, int y )
{
return lvldoors->DoorMap[ x ][ y ].action == dr_open ? DOOR_FULLOPEN : lvldoors->DoorMap[ x ][ y ].ticcount;
}
/*
-----------------------------------------------------------------------------
Function: Door_TryUse -Try to use a door with keys that the player has.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC _boolean Door_TryUse( doors_t *Door, int keys )
{
switch( Door->type )
{
case DOOR_VERT:
case DOOR_HORIZ:
case DOOR_E_VERT:
case DOOR_E_HORIZ:
Door_ChangeDoorState( Door ); // does not require key!
break;
case DOOR_G_VERT:
case DOOR_G_HORIZ:
if( keys & ITEM_KEY_1 )
{
Door_ChangeDoorState( Door );
}
else
{
iphoneSetNotifyText( "You need a gold key" );
}
break;
case DOOR_S_VERT:
case DOOR_S_HORIZ:
if( keys & ITEM_KEY_2 )
{
Door_ChangeDoorState( Door );
}
else
{
iphoneSetNotifyText( "You need a silver key" );
}
break;
}
return true; // FIXME
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,285 @@
/*
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_level.h: Wolfenstein3-D level management.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Acknowledgement:
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_areas.c, wolf_doors.c, wolf_level.c and
wolf_pushwalls.c
*/
#ifndef __WOLF_LEVEL_H__
#define __WOLF_LEVEL_H__
///////////////////
//
// Areas
//
///////////////////
#define NUMAREAS 37 // number of areas
#define FIRSTAREA 0x6B // first area in map data (it is by the way a way to the secret floor!)
#define AMBUSHTILE 0x6A // def guard
#define AMBUSH -2
///////////////////
//
// Doors
//
///////////////////
#define MAX_DOORS 256
#define DOOR_TIMEOUT 300
#define DOOR_MINOPEN 50
#define DOOR_FULLOPEN 63
#define DOOR_VERT 255
#define DOOR_HORIZ 254
#define DOOR_E_VERT 253
#define DOOR_E_HORIZ 252
#define DOOR_G_VERT 251
#define DOOR_G_HORIZ 250
#define DOOR_S_VERT 249
#define DOOR_S_HORIZ 248
#define FIRST_DOOR 248
#define LAST_LOCK 251
#define TEX_DOOR 126
// texture IDs used by cache routines
#define TEX_DDOOR (0 + TEX_DOOR) // Simple Door
#define TEX_PLATE (2 + TEX_DOOR) // Door Plate
#define TEX_DELEV (4 + TEX_DOOR) // Elevator Door
#define TEX_DLOCK (6 + TEX_DOOR) // Locked Door
///////////////////
//
// Level
//
///////////////////
#define WALL_TILE 1
#define PUSHWALL_TILE (1 << 20)
#define DOOR_TILE 2
#define SECRET_TILE 4
#define DRESS_TILE 8
#define BLOCK_TILE 16
#define ACTOR_TILE 32
#define DEADACTOR_TILE 64
#define POWERUP_TILE 128
#define AMBUSH_TILE 256
#define EXIT_TILE 512
#define SECRETLEVEL_TILE 1024
#define ELEVATOR_TILE (1 << 11)
#define TILE_IS_E_TURN (1 << 12)
#define TILE_IS_NE_TURN (1 << 13)
#define TILE_IS_N_TURN (1 << 14)
#define TILE_IS_NW_TURN (1 << 15)
#define TILE_IS_W_TURN (1 << 16)
#define TILE_IS_SW_TURN (1 << 17)
#define TILE_IS_S_TURN (1 << 18)
#define TILE_IS_SE_TURN (1 << 19)
#define SOLID_TILE (WALL_TILE | BLOCK_TILE | PUSHWALL_TILE)
#define BLOCKS_MOVE_TILE (WALL_TILE | BLOCK_TILE | PUSHWALL_TILE | ACTOR_TILE)
#define WAYPOINT_TILE (TILE_IS_E_TURN | TILE_IS_NE_TURN | TILE_IS_N_TURN | TILE_IS_NW_TURN | TILE_IS_W_TURN | TILE_IS_SW_TURN | TILE_IS_S_TURN | TILE_IS_SE_TURN )
///////////////////
//
// Doors
//
///////////////////
typedef enum
{
dr_closing = -1,
dr_closed,
dr_opening,
dr_open
} dr_state;
typedef struct
{
int tilex, tiley;
_boolean vertical;
int ticcount;
dr_state action;
int area1, area2;
/*DOOR_VERT 255
DOOR_HORIZ 254
DOOR_E_VERT 253
DOOR_E_HORIZ 252
DOOR_G_VERT 251
DOOR_G_HORIZ 250
DOOR_S_VERT 249
DOOR_S_HORIZ 248*/
int type;
int texture;
} doors_t;
typedef struct
{
int doornum;
doors_t *Doors[ 256 ];
doors_t DoorMap[ 64 ][ 64 ];
} LevelDoors_t;
///////////////////
//
// Level
//
///////////////////
typedef struct
{
char fname[ 32 ]; /* Map filename */
W16 Plane1[ 64 * 64 ]; /* walls */
W16 Plane2[ 64 * 64 ]; /* objects */
W16 Plane3[ 64 * 64 ]; /* other */
long tilemap[ 64 ][ 64 ]; // wall values only
W8 spotvis[ 64 ][ 64 ];
// objtype *actorat[ 64 ][ 64 ];
// this is an array of references to texture descriptions
// the renderer must know what to draw by this number
int wall_tex_x[ 64 ][ 64 ]; // x_wall
int wall_tex_y[ 64 ][ 64 ]; // y_wall
// this is a (0-based) array of area numbers!
// must be all filled by level loading sub
// if -1 it is a wall, if -2 it is a door, if -3 it is unknown
int areas[ 64 ][ 64 ];
LevelDoors_t Doors;
placeonplane_t pSpawn; // player spawn place
char mapName[128]; /* Map name */
char musicName[128]; /* Music file name */
colour3_t ceilingColour, floorColour;
W8 tileEverVisible[ 64 ][ 64 ]; // for automap
} LevelData_t;
typedef struct statinfo_t
{
_boolean block;
int powerup;
} statinfo_t;
extern LevelData_t *r_world;
extern LevelData_t *Level_LoadMap( const char *levelname );
extern void Level_PrecacheTextures_Sound( LevelData_t *lvl );
extern _boolean Level_CheckLine( SW32 x1, SW32 y1, SW32 x2, SW32 y2, LevelData_t *lvl );
extern void Level_ScanInfoPlane( LevelData_t *lvl );
///////////////////
//
// Doors
//
///////////////////
extern void Door_ResetDoors( LevelDoors_t *lvl );
extern int Door_SpawnDoor( LevelDoors_t *lvl, int x, int y, int type );
extern void Door_SetAreas( LevelDoors_t *lvl, int (*areas)[64] );
extern void Door_OpenDoor( doors_t *Door );
extern void Door_ProcessDoors_e( LevelDoors_t *lvl, int t_tk, int t_ms );
extern int Door_Opened( LevelDoors_t *lvl, int x, int y );
extern _boolean Door_TryUse( doors_t *Door, int keys );
///////////////////
//
// Areas
//
///////////////////
extern _boolean areabyplayer[ NUMAREAS ];
extern void Areas_ConnectAreas( int areanumber );
extern void Areas_InitAreas( int areanumber );
extern void Areas_JoinAreas( int area1, int area2 );
extern void Areas_DisconnectAreas( int area1, int area2 );
///////////////////
//
// Push Walls
//
///////////////////
typedef struct
{
_boolean active;
int PWtilesmoved;
int PWpointsmoved;
dir4type dir;
int x, y;
int dx, dy;
int tex_x, tex_y;
} Pwall_t;
extern Pwall_t PWall;
extern void PushWall_Reset( void );
extern _boolean PushWall_Push( int x, int y, dir4type dir );
extern void PushWall_Process( void );
#endif /* __WOLF_LEVEL_H__ */

View File

@@ -0,0 +1,150 @@
/*
Copyright (C) 2004 Michael Liebscher
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_local.h: Wolfenstein3-D init.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_main.c
*/
#ifndef __WOLF_LOCAL_H__
#define __WOLF_LOCAL_H__
// Game Version
#define WOLFENSTEINWL6 0x00
#define SPEAROFDESTINY 0x01
#define TILEGLOBAL 0x10000
#define HALFTILE 0x8000
#define TILESHIFT 16
#define MINDIST (0x5800)
typedef enum difficulty_e
{
gd_baby,
gd_easy,
gd_medium,
gd_hard
} difficulty_t;
//
// this structure is cleared as each map is entered
//
typedef struct
{
int framenum;
float time;
char level_name[ MAX_OSPATH ]; // the descriptive name (Outer Base, etc)
char mapname[ MAX_OSPATH ]; // the server name (base1, etc)
char nextmap[ MAX_OSPATH ]; // go here when fraglimit is hit
// intermission state
W32 levelCompleted; // in case the game was saved at the intermission
W32 floornum;
float fpartime;
char spartime[6];
W32 total_secrets;
W32 found_secrets;
W32 total_treasure;
W32 found_treasure;
W32 total_monsters;
W32 killed_monsters;
} level_locals_t;
extern level_locals_t levelstate;
typedef struct
{
W32 total_secrets;
W32 found_secrets;
W32 total_treasure;
W32 found_treasure;
W32 total_monsters;
W32 killed_monsters;
W32 time;
} LRstruct;
extern LRstruct LevelRatios;
extern cvar_t *g_version;
extern cvar_t *episode;
extern cvar_t *skill;
extern int tics;
W32 floornumber;
extern void Game_Init( void );
extern void Game_Reset( void );
extern void ProcessGuards( void );
#define WL6SPRITESDIRNAME "sprites"
#define SODSPRITESDIRNAME "sodsprites"
extern char *spritelocation;
#endif /* __WOLF_LOCAL_H__ */

View File

@@ -0,0 +1,87 @@
/*
Copyright (C) 2004-2005 Michael Liebscher
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.
*/
#include "../wolfiphone.h"
level_locals_t levelstate;
LRstruct LevelRatios;
cvar_t *g_version; // Wolfenstein or Spear of Destiny
cvar_t *episode;
cvar_t *skill;
char *spritelocation = WL6SPRITESDIRNAME;
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Game_Reset( void )
{
memset( &levelstate, 0, sizeof( levelstate ) );
}
extern void Map_f( void );
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Game_Init( void )
{
Com_Printf( "\n------ Game Init ------\n" );
episode = Cvar_Get( "episode", "0", CVAR_ARCHIVE );
skill = Cvar_Get( "skill", "1", CVAR_ARCHIVE );
g_version = Cvar_Get( "g_version", "0", CVAR_ARCHIVE );
#ifndef EPISODE1
Cmd_AddCommand( "map", Map_f );
#endif
G_Build_Tables();
Powerup_Reset();
Sprite_Reset();
Game_Reset();
PL_Init();
Com_Printf( "\n-----------------------\n" );
}

View File

@@ -0,0 +1,341 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 2000 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_math.c: Wolfenstein 3-D math routines.
*
* 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"
#define XRES 640
#define YRES 480
// ------------------------- * LUTs * -------------------------
double SinTable[ ANG_360 + ANG_90 + 1 ],
*CosTable = SinTable + ANG_90,
TanTable[ ANG_360 + 1 ];
int XnextTable[ ANG_360 + 1 ],
YnextTable[ ANG_360 + 1 ];
int ColumnAngle[ 640 ]; // ViewAngle=PlayerAngle+ColumnAngle[curcolumn]; /in fines/
char dx4dir[5]={1, 0, -1, 0, 0}; // dx & dy based on direction
char dy4dir[5]={0, 1, 0, -1, 0};
char dx8dir[9]={1, 1, 0, -1, -1, -1, 0, 1, 0}; // dx & dy based on direction
char dy8dir[9]={0, 1, 1, 1, 0, -1, -1, -1, 0};
dir4type opposite4[5]={2, 3, 0, 1, 4};
dir8type opposite8[9]={4, 5, 6, 7, 0, 1, 2, 3, 8};
dir8type dir4to8[5]={0, 2, 4, 6, 8};
dir8type diagonal[9][9]=
{
/* east */ {dir8_nodir, dir8_nodir, dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southeast, dir8_nodir, dir8_nodir},
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
/* north */ {dir8_northeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
/* west */ {dir8_nodir, dir8_nodir, dir8_northwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir},
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
/* south */ {dir8_southeast, dir8_nodir, dir8_nodir, dir8_nodir, dir8_southwest, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir},
{dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir, dir8_nodir}
};
// dir of delta tooks dx{-1|0|1}+1 & dy{-1|0|1}+1 and give direction
dir4type dir4d[3][3]={{dir4_nodir, dir4_west , dir4_nodir},
{dir4_south, dir4_nodir, dir4_north},
{dir4_nodir, dir4_east , dir4_nodir}};
int dir8angle[9]={ANG_0, ANG_45, ANG_90, ANG_135, ANG_180, ANG_225, ANG_270, ANG_315, ANG_0};
int dir4angle[5]={ANG_0, ANG_90, ANG_180, ANG_270, ANG_0};
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC int G_Build_Tables( void )
{
double angle, tanfov2, tanval, value;
int n;
for( n = 0 ; n <= ANG_90 ; ++n )
{
angle = FINE2RAD( n );
value = sin( angle );
SinTable[ n ] = SinTable[ ANG_180 - n ] = SinTable[ n + ANG_360 ] = value;
SinTable[ ANG_180 + n ] = SinTable[ ANG_360 - n ] = -value;
}
for( n = 0 ; n <= ANG_360 ; ++n )
{
angle = FINE2RAD( n ); //angle is in radians, n is in FINEs
if( n == ANG_90 || n == ANG_270 )
{
TanTable[ n ] = tan( FINE2RAD( n - 0.5 ) ); // infinity
YnextTable[ n ] = (int)(FLOATTILE * tan( FINE2RAD( n - 0.5 ) )); // infinity
}
else
{
TanTable[ n ] = tan( angle );
YnextTable[ n ] = (int)(FLOATTILE * tan( angle ));
}
if( n == ANG_0 || n == ANG_360 )
XnextTable[ n ] = (int)(FLOATTILE / tan( FINE2RAD( n + 0.5 ) )); // infinity
else if( n == ANG_180 )
XnextTable[ n ] = (int)(FLOATTILE / tan(FINE2RAD( n - 0.5 ) )); // -infinity
else if( n == ANG_90 || n == ANG_270 )
XnextTable[ n ] = 0;
else
XnextTable[ n ] = (int)(FLOATTILE / tan( angle ));
}
tanfov2 = TanDgr( CalcFov( 75, XRES, YRES) / 2.0 ) * ((float)XRES / (float)YRES );
for( n = 0 ; n < XRES ; ++n )
{
tanval = tanfov2 * (-1.0 + 2.0 * (double)n / (double)(XRES-1) );
ColumnAngle[ n ] = (int)RAD2FINE( atan( tanval ) );
}
US_InitRndT( 1 ); // random number generators
return 1;
}
/*
-----------------------------------------------------------------------------
Function: NormalizeAngle -clips angle to [0..360] bounds.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC int NormalizeAngle( int alpha )
{
if( alpha > ANG_360 )
alpha %= ANG_360;
if(alpha<ANG_0)
alpha = ANG_360 - (-alpha) % ANG_360;
return alpha;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC quadrant GetQuadrant( float angle )
{
angle = normalize_angle( angle );
if( angle < M_PI / 2 )
{
return q_first;
}
else if( angle < M_PI )
{
return q_second;
}
else if( angle < 3 * M_PI / 2 )
{
return q_third;
}
else
{
return q_fourth;
}
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC dir4type Get4dir( float angle )
{
angle = normalize_angle( angle + M_PI / 4 );
if( angle < M_PI / 2 )
{
return dir4_east;
}
else if( angle < M_PI )
{
return dir4_north;
}
else if( angle < 3 * M_PI / 2 )
{
return dir4_west;
}
else
{
return dir4_south;
}
}
/*
-----------------------------------------------------------------------------
Function: Get8dir -Get 8 point direction.
Parameters: angle -[in] Radian angle.
Returns: Directional point.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC dir8type Get8dir( float angle )
{
angle = normalize_angle( angle + M_PI / 12 );
if( angle <= (M_PI / 4) )
{
return dir8_east;
}
else if( angle < (M_PI / 2) )
{
return dir8_northeast;
}
else if( angle <= (3 * M_PI / 4) )
{
return dir8_north;
}
else if( angle < M_PI )
{
return dir8_northwest;
}
else if( angle <= (5 * M_PI / 4) )
{
return dir8_west;
}
else if( angle < (3 * M_PI / 2) )
{
return dir8_southwest;
}
else if( angle <= (7 * M_PI / 4) )
{
return dir8_south;
}
else
{
return dir8_southeast;
}
}
/*
-----------------------------------------------------------------------------
Function: Point2LineDist -calculates distance between a point (x, y) and
a line.
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC int Point2LineDist( int x, int y, int a )
{
return ABS( (int)(x * SinTable[ a ] - y * CosTable[ a ]) );
}
/*
-----------------------------------------------------------------------------
Function: LineLen2Point -Calculates line length to the point nearest to (poin)
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC int LineLen2Point( int x, int y, int a )
{
return (int)(x * CosTable[ a ] + y * SinTable[ a ] );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
Function returns angle in radians
point2 = {x,y}
/ |
/ |
/ |
/a______|----------> x
point1 = {x, y}
-----------------------------------------------------------------------------
*/
PUBLIC float TransformPoint( double Point1X, double Point1Y, double Point2X, double Point2Y )
{
float angle;
angle = atan2( Point1Y - Point2Y, Point1X - Point2X );
return normalize_angle( angle );
}

View File

@@ -0,0 +1,147 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 2000 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_math.h: Wolfenstein 3-D math routines.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
*
* Acknowledgement:
* This code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
*
*/
/*
Notes:
This module is implemented by wolf_math.c
*/
#ifndef __WOLF_MATH_H__
#define __WOLF_MATH_H__
#define FLOATTILE 65536.0f
// Angle Direction Types & LUTs (Hard Coded! Please do not mess them)
typedef enum {q_first, q_second, q_third, q_fourth} quadrant;
typedef enum {dir4_east, dir4_north, dir4_west, dir4_south, dir4_nodir} dir4type;
typedef enum { dir8_east, dir8_northeast, dir8_north, dir8_northwest, dir8_west,
dir8_southwest, dir8_south, dir8_southeast, dir8_nodir} dir8type;
extern char dx4dir[5], dy4dir[5], dx8dir[9], dy8dir[9];
extern dir4type opposite4[5], dir4d[3][3];
extern dir8type opposite8[9], dir4to8[5], diagonal[9][9];
extern int dir8angle[9], dir4angle[5];
// ------------------------- * Vectors * -------------------------
// Vectors & angles for 3D-Space
typedef struct
{
long origin[2];
long angle;
} placeonplane_t;
// ------------------------- * Some Macroses * -------------------------
#define max_of_2(a, b) ((a)>(b)?(a):(b))
#define LABS(x) ((long)(x)>0?(x):-(x))
#define TILE2POS(a) (((a)<<TILESHIFT)+HALFTILE)
#define POS2TILE(a) ((a)>>TILESHIFT)
#define POS2TILEf(a) ((a)/FLOATTILE)
// ------------------------- * vvv FINE angles vvv * -------------------------
#define ASTEP 0.0078125f // 1 FINE=x DEGREES
#define ASTEPRAD 0.000136354f // 1 FINE=x RADIANS
#define ANG_1RAD 7333.8598 // 1 RADIAN=x FINES
#define ANG_0 0 //(int)((float)0/ASTEP)
#define ANG_1 128 //(int)((float)1/ASTEP)
#define ANG_6 768 //(int)((float)6/ASTEP)
#define ANG_15 1920 //(int)((float)15/ASTEP)
#define ANG_22_5 2880 //(int)((float)22.5/ASTEP)
#define ANG_30 3840 //(int)((float)30/ASTEP)
#define ANG_45 5760 //(int)((float)45/ASTEP)
#define ANG_67_5 8640 //(int)((float)67.5/ASTEP)
#define ANG_90 11520 //(int)((float)90/ASTEP)
#define ANG_112_5 14400 //(int)((float)112.5/ASTEP)
#define ANG_135 17280 //(int)((float)135/ASTEP)
#define ANG_157_5 20160 //(int)((float)157.5/ASTEP)
#define ANG_180 23040 //(int)((float)180/ASTEP)
#define ANG_202_5 25920 //(int)((float)202.5/ASTEP)
#define ANG_225 28800 //(int)((float)225/ASTEP)
#define ANG_247_5 31680 //(int)((float)247.5/ASTEP)
#define ANG_270 34560 //(int)((float)270/ASTEP)
#define ANG_292_5 37440 //(int)((float)292.5/ASTEP)
#define ANG_315 40320 //(int)((float)225/ASTEP)
#define ANG_337_5 43200 //(int)((float)337.5/ASTEP)
#define ANG_360 46080 //(int)((float)360/ASTEP)
// ------------------------- * ^^^ FINE angles ^^^ * -------------------------
#define FINE2RAD( a ) (((a) * M_PI ) / ANG_180)
#define RAD2FINE( a ) (((a) * ANG_180) / M_PI)
#define FINE2DEG( a ) ((float)(a) / ANG_1) // !@# don't lose precision bits
#define FINE2DEGf( a ) ((a) / (float)ANG_1)
#define DEG2FINE( a ) ((a) * ANG_1)
extern double SinTable[], *CosTable, TanTable[ ANG_360 + 1 ];
extern int XnextTable[ ANG_360 + 1], YnextTable[ ANG_360 + 1 ];
extern int ColumnAngle[640]; //
extern int G_Build_Tables(void);
#define TanDgr( x ) (tan( DEG2RAD( x ) ))
#define SinDgr( x ) (sin( DEG2RAD( x ) ))
#define CosDgr( x ) (cos( DEG2RAD( x ) ))
#define ArcTanDgr( x ) (RAD2DEG( atan( x ) ))
#define ArcSinDgr( x ) (RAD2DEG( asin( x ) ))
#define ArcCosDgr( x ) (RAD2DEG( acos( x ) ))
extern int NormalizeAngle( int angle );
extern int Point2LineDist( int x, int y, int a );
extern int LineLen2Point( int x, int y, int a );
extern quadrant GetQuadrant( float angle );
extern dir4type Get4dir( float angle );
extern dir8type Get8dir( float angle );
extern float TransformPoint( double Point1X, double Point1Y, double Point2X, double Point2Y );
#endif /* __WOLF_MATH_H__ */

View File

@@ -0,0 +1,629 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 2000-2002 by DarkOne the Hacker
Copyright (C) 1997-2001 Id Software, Inc.
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_opengl.c: Wolfenstein3-D OpenGL renderer.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Portion of this code was derived from Quake II, and was originally
* written by Id Software, Inc.
*
*/
#include "../wolfiphone.h"
// width and height in 2D
#define WIDTH_2D 640
#define HEIGHT_2D 480
float cur_x_fov, cur_y_fov; // x & y field of view (in degrees)
float ratio; // viewport width/height
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void GL_SetDefaultState( void )
{
pfglClearColor( 1,0, 0.5 , 0.5 );
pfglCullFace( GL_FRONT );
pfglEnable( GL_TEXTURE_2D );
pfglEnable( GL_ALPHA_TEST );
pfglAlphaFunc( GL_GREATER, 0.666f );
pfglDisable( GL_DEPTH_TEST );
pfglDisable( GL_CULL_FACE );
pfglDisable( GL_BLEND );
pfglColor4f( 1, 1, 1, 1 );
#ifndef IPHONE
pfglPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
#endif
pfglShadeModel( GL_FLAT );
pfglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
GL_UpdateSwapInterval();
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE void R_CheckFOV( void )
{
/*
if(!vid_fov->modified) return;
vid_fov->modified=false;
if( vid_fov->value<1 || vid_fov->value>179)
{
Com_Printf("Wrong FOV: %f\n", vid_fov->value);
Cvar_SetValue(vid_fov->name, (cur_x_fov>=1 && cur_x_fov<=179)?cur_x_fov:DEFAULT_FOV);
}
*/
ratio = (float) viddef.width / (float)viddef.height; // FIXME: move somewhere
cur_x_fov = 75;
cur_y_fov = CalcFov( cur_x_fov, (float)viddef.width, (float)viddef.height );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_SetGL3D( placeonplane_t viewport )
{
R_CheckFOV();
pfglMatrixMode( GL_PROJECTION );
pfglLoadIdentity();
#ifdef IPHONE
pfglRotatef( 90, 0, 0, 1 );
#endif
MYgluPerspective( cur_y_fov - 2.0f, ratio, 0.2f, 64.0f ); // tweak fov in to avoid edge tile clips
pfglMatrixMode( GL_MODELVIEW );
pfglLoadIdentity();
pfglRotatef( (float)(90 - FINE2DEG( viewport.angle )), 0, 1, 0 );
pfglTranslatef( -viewport.origin[ 0 ] / FLOATTILE, 0, viewport.origin[ 1 ] / FLOATTILE );
pfglCullFace( GL_BACK );
pfglEnable( GL_DEPTH_TEST );
pfglEnable( GL_CULL_FACE );
pfglEnable( GL_BLEND );
pfglDisable( GL_BLEND ); // !@# draw all the walls opaque without alpha test
pfglDisable( GL_ALPHA_TEST );
qglDepthMask( GL_TRUE );
// clear depth buffer
pfglClear( GL_DEPTH_BUFFER_BIT );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_DrawBox( int x, int y, int w, int h, W32 color )
{
pfglDisable( GL_TEXTURE_2D );
// pfglEnable( GL_BLEND );
// pfglBlendFunc( GL_SRC_COLOR, GL_DST_COLOR );
pfglColor4ubv( (GLubyte *) & color );
pfglBegin( GL_QUADS );
pfglVertex2i( x, y );
pfglVertex2i( x, y + h);
pfglVertex2i( x + w, y + h );
pfglVertex2i( x + w, y );
pfglEnd();
pfglColor3f( 1, 1, 1 );
// pfglBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
// pfglDisable( GL_BLEND );
pfglEnable( GL_TEXTURE_2D );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
north (y)
__________
| |
west (x) | | east (x)
|________|
south (y)
-----------------------------------------------------------------------------
*/
PUBLIC void R_Draw_Wall( float x, float y, float z1, float z2, int type, int tex )
{
float x1, x2, y1, y2;
texture_t *twall;
switch( type )
{
// X wall
case dir4_east:
x1 = x2 = x + 1;
y1 = -1 - y;
y2 = -y;
break;
case dir4_west:
x1 = x2 = x;
y1 = -y;
y2 = -1 - y;
break;
// Y wall
case dir4_north:
y1 = y2 = -y - 1;
x1 = x;
x2 = x + 1;
break;
case dir4_south:
y1 = y2 = -y;
x1 = x + 1;
x2 = x;
break;
}
assert( tex >= 0 && tex < 1000 );
twall = wallTextures[tex];
if ( !twall ) {
char name[1024];
my_snprintf( name, sizeof( name ), "walls/%.3d.tga", tex );
twall = wallTextures[tex] = TM_FindTexture( name, TT_Wall );
}
R_Bind( twall->texnum );
pfglBegin( GL_QUADS );
pfglTexCoord2f( 1.0, 0.0 ); pfglVertex3f( x1, z2, y1 );
pfglTexCoord2f( 0.0, 0.0 ); pfglVertex3f( x2, z2, y2 );
pfglTexCoord2f( 0.0, 1.0 ); pfglVertex3f( x2, z1, y2 );
pfglTexCoord2f( 1.0, 1.0 ); pfglVertex3f( x1, z1, y1 );
pfglEnd();
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_Draw_Door( int x, int y, float z1, float z2, _boolean vertical, _boolean backside, int tex, int amount )
{
float x1, x2, y1, y2, amt;
texture_t *twall;
if( amount == DOOR_FULLOPEN )
{
return;
}
amt = (float)amount / DOOR_FULLOPEN;
if( vertical )
{
x1 = x2 = (float)x + 0.5f;
y1 = -((float)y - amt);
y2 = -((float)y - amt); // -1
if( backside )
{
y1 -= 1;
}
else
{
y2 -= 1;
}
}
else
{
y1 = y2 = -(float)y - 0.5f;
x1 = (float)x + amt; // +1
x2 = (float)x + amt;
if( backside )
{
x2 += 1;
}
else
{
x1 += 1;
}
}
assert( tex >= 0 && tex < 1000 );
twall = wallTextures[tex];
if ( !twall ) {
char name[1024];
my_snprintf( name, sizeof( name ), "walls/%.3d.tga", tex );
twall = wallTextures[tex] = TM_FindTexture( name, TT_Wall );
}
R_Bind( twall->texnum );
pfglBegin( GL_QUADS );
pfglTexCoord2f( backside ? 0.0f : 1.0f, 0.0 ); pfglVertex3f( x1, z2, y1 );
pfglTexCoord2f( backside ? 1.0f : 0.0f, 0.0 ); pfglVertex3f( x2, z2, y2 );
pfglTexCoord2f( backside ? 1.0f : 0.0f, 1.0 ); pfglVertex3f( x2, z1, y2 );
pfglTexCoord2f( backside ? 0.0f : 1.0f, 1.0 ); pfglVertex3f( x1, z1, y1 );
pfglEnd();
}
/*
-----------------------------------------------------------------------------
Function: R_DrawSprites -Draws all visible sprites.
Parameters: Nothing.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_DrawSprites( void )
{
float sina, cosa;
float Ex, Ey, Dx, Dy;
int n_sprt, n, ang;
texture_t *twall;
extern cvar_t *cropSprites;
// build visible sprites list
n_sprt = Sprite_CreateVisList();
if( ! n_sprt )
{
return; // nothing to draw
}
// prepare values for billboarding
ang = NormalizeAngle( Player.position.angle + ANG_90 );
sina = (float)(0.5 * SinTable[ ang ]);
cosa = (float)(0.5 * CosTable[ ang ]);
//pfglEnable( GL_ALPHA_TEST );
pfglEnable( GL_BLEND );
qglDepthMask( GL_FALSE );
for( n = 0; n < n_sprt; ++n )
{
int texnum = vislist[ n ].tex;
if( vislist[ n ].dist < MINDIST / 2 )
{
continue; // little hack to save speed & z-buffer
}
assert( texnum >= 0 && texnum < 1000 );
twall = spriteTextures[texnum];
if ( !twall ) {
char name[1024];
my_snprintf( name, sizeof( name ), "%s/%.3d.tga", spritelocation, (vislist[ n ].tex) );
twall = spriteTextures[texnum] = TM_FindTexture( name, TT_Wall );
}
R_Bind( twall->texnum );
pfglBegin( GL_QUADS );
if ( cropSprites->value && twall->header.numBounds > 0 ) {
// draw one or two subrects to avoid blending all the empty space
int b;
for ( b = 0 ; b < twall->header.numBounds ; b++ ) {
// include a bit extra for filtering
float x1 = (float)(twall->header.bounds[b][0][0]-1) / (twall->header.uploadWidth-1);
float y1 = (float)(twall->header.bounds[b][0][1]-1) / (twall->header.uploadHeight-1);
float x2 = (float)(twall->header.bounds[b][1][0]+1) / (twall->header.uploadWidth-1);
float y2 = (float)(twall->header.bounds[b][1][1]+1) / (twall->header.uploadHeight-1);
if ( x1 < 0 ) {
x1 = 0;
} else if ( x2 > 1.0 ) {
x2 = 1.0;
}
if ( y1 < 0 ) {
y1 = 0;
} else if ( y2 > 1.0 ) {
y2 = 1.0;
}
Ex = vislist[ n ].x / FLOATTILE + cosa;
Ey = vislist[ n ].y / FLOATTILE + sina;
pfglTexCoord2f( x1, y1 ); pfglVertex3f( Ex - x1 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y1), -Ey + x1 * 2*sina );
pfglTexCoord2f( x1, y2 ); pfglVertex3f( Ex - x1 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y2), -Ey + x1 * 2*sina );
pfglTexCoord2f( x2, y2 ); pfglVertex3f( Ex - x2 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y2), -Ey + x2 * 2*sina );
pfglTexCoord2f( x2, y1 ); pfglVertex3f( Ex - x2 * 2*cosa, -(LOWERZCOORD + (UPPERZCOORD - LOWERZCOORD) * y1), -Ey + x2 * 2*sina );
}
} else {
Ex = Dx = vislist[ n ].x / FLOATTILE;
Ey = Dy = vislist[ n ].y / FLOATTILE;
Ex += cosa; Ey += sina;
Dx -= cosa; Dy -= sina;
pfglTexCoord2f( 0.0, 0.0 ); pfglVertex3f( Ex, UPPERZCOORD, -Ey );
pfglTexCoord2f( 0.0, 1.0 ); pfglVertex3f( Ex, LOWERZCOORD, -Ey );
pfglTexCoord2f( 1.0, 1.0 ); pfglVertex3f( Dx, LOWERZCOORD, -Dy );
pfglTexCoord2f( 1.0, 0.0 ); pfglVertex3f( Dx, UPPERZCOORD, -Dy );
}
pfglEnd();
}
//pfglDisable( GL_ALPHA_TEST ); // !@# reanable just for sprites
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_DrawWeapon( void )
{
char name[ 32 ];
texture_t *tex;
static int w = 128;
static int h = 128;
static int scale = 2;
int x = (viddef.width - (128 * scale)) >> 1;
int y = viddef.height - (128 * scale) - 79;
my_snprintf( name, sizeof( name ), "%s/%d.tga", spritelocation, Player.weapon * 5 + Player.weaponframe + SPR_KNIFEREADY );
tex = TM_FindTexture( name, TT_Pic );
R_Bind( tex->texnum );
pfglAlphaFunc( GL_GREATER, 0.3f );
pfglEnable( GL_BLEND );
pfglBegin( GL_QUADS );
pfglTexCoord2f( 0.0f, 0.0f ); pfglVertex2i( x, y );
pfglTexCoord2f( 1.0f, 0.0f ); pfglVertex2i( x + w * scale, y );
pfglTexCoord2f( 1.0f, 1.0f ); pfglVertex2i( x + w * scale, y + h * scale );
pfglTexCoord2f( 0.0f, 1.0f ); pfglVertex2i( x, y + h * scale );
pfglEnd();
pfglDisable( GL_BLEND );
pfglAlphaFunc( GL_GREATER, 0.666f );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_DrawNumber( int x, int y, int number )
{
texture_t *tex;
int col;
float fcol;
static float w = 0.1f;
int i;
char string[ 20 ];
W32 length;
my_snprintf( string, sizeof( string ), "%d", number );
length = strlen( string );
tex = TM_FindTexture( "pics/N_NUMPIC.tga", TT_Pic );
pfglEnable( GL_TEXTURE_2D );
R_Bind( tex->texnum );
pfglBegin( GL_QUADS );
for( i = length-1 ; i >= 0 ; --i )
{
col = string[ i ] - 48;
fcol = col * w;
pfglTexCoord2f( fcol, 0 ); pfglVertex2i( x, y );
pfglTexCoord2f( fcol+w, 0 ); pfglVertex2i( x+18, y );
pfglTexCoord2f( fcol+w, 1 ); pfglVertex2i( x+18, y+32 );
pfglTexCoord2f( fcol, 1 ); pfglVertex2i( x, y+32 );
x -= 18;
}
pfglEnd();
}
W8 wfont[ ] = {
32, 15, 32, 32, 32, 32, 32, 12, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 16, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32 };
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_put_line( int x, int y, const char *string )
{
texture_t *tex;
int mx = x;
int num;
float frow, fcol;
static float h = 0.25f; // (32 / 128.0f);
static float w = 0.0625f; // (32 / 512.0f);
tex = TM_FindTexture( "pics/L_FONTPIC.tga", TT_Pic );
R_Bind( tex->texnum );
pfglBegin( GL_QUADS );
while( *string )
{
if( *string == '\n' )
{
mx = x;
y += 32;
++string;
continue;
}
num = *string;
num &= 255;
if( (num & 127) == 32 )
{
mx += 32;
++string;
continue; // space
}
frow = ((num >> 4) - 2) * h;
fcol = (num & 15) * w;
pfglTexCoord2f( fcol, frow ); pfglVertex2i( mx, y );
pfglTexCoord2f( fcol+w, frow ); pfglVertex2i( mx+32, y );
pfglTexCoord2f( fcol+w, frow+h ); pfglVertex2i( mx+32, y+32 );
pfglTexCoord2f( fcol, frow+h ); pfglVertex2i( mx, y+32 );
mx += wfont[ (num & 127) - 32 ];
++string;
}
pfglEnd();
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,180 @@
/*
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_player.h: Wolfenstein3-D player management.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
*/
/*
Notes:
This module is implemented by wolf_player.c
*/
#ifndef __WOLF_PLAYER_H__
#define __WOLF_PLAYER_H__
#define ITEM_KEY_1 1
#define ITEM_KEY_2 2
#define ITEM_KEY_3 4
#define ITEM_KEY_4 8
#define ITEM_WEAPON_1 16
#define ITEM_WEAPON_2 32
#define ITEM_WEAPON_3 64
#define ITEM_WEAPON_4 128
#define ITEM_WEAPON_5 256
#define ITEM_WEAPON_6 512
#define ITEM_WEAPON_7 1024
#define ITEM_WEAPON_8 2048
#define ITEM_BACKPACK (1<<12) // doubles carrying capacity
#define ITEM_AUGMENT (1<<13) // adds 50 to maximum health
#define ITEM_UNIFORM (1<<14) // allows you to pass guards
#define ITEM_AUTOMAP (1<<15) // shows unknown map ares in other color (as in DooM)
#define ITEM_FREE (1<<16) // - unused -
enum weapon_e
{
WEAPON_KNIFE,
WEAPON_PISTOL,
WEAPON_AUTO,
WEAPON_CHAIN,
WEAPON_TYPES
};
enum key_e
{
KEY_GOLD,
KEY_SILVER,
KEY_FREE1,
KEY_FREE2,
KEY_TYPES
};
enum ammo_e
{
AMMO_BULLETS,
AMMO_TYPES
};
// flags
#define PL_FLAG_REUSE 1 // use button pressed
#define PL_FLAG_ATTCK 2 // attacking
// debug (cheat codes) flags
#define FL_GODMODE (1<<4)
#define FL_NOTARGET (1<<6)
typedef enum state_e
{
ex_notingame,
ex_playing,
ex_dead,
ex_secretlevel,
ex_victory,
ex_complete
/*
ex_stillplaying,
ex_completed,
ex_died,
ex_warped,
ex_resetgame,
ex_loadedgame,
ex_victorious,
ex_abort,
ex_demodone,
ex_secretlevel
*/
} state_t;
// ------------------------- * types * -------------------------
// Player structure: Holds all info about player
typedef struct player_s
{
usercmd_t cmd; // movement / action command
placeonplane_t position; // player position
int movx, movy, speed;
int tilex, tiley;
// stats
int health, lives, frags;
int armor; // there are 2 types. The better one is indicated by high bit set
int ammo[AMMO_TYPES];
int old_score, score, next_extra;
unsigned items; // (keys, weapon)
int weapon, pendingweapon;
// additional info
int attackframe, attackcount, weaponframe; // attack info
unsigned flags;
int areanumber;
_boolean madenoise; // FIXME: move to flags?
entity_t *LastAttacker;
int faceframe, facecount; // bj's face in the HUD // FIXME decide something!
_boolean face_gotgun, face_ouch;
state_t playstate; // fixme: move to gamestate
} player_t;
extern player_t Player;
extern void PL_Spawn( placeonplane_t location, LevelData_t *lvl );
extern void PL_Process( player_t *self, LevelData_t *lvl );
extern void PL_Damage( player_t *self, entity_t *attacker, int points );
extern _boolean PL_GiveHealth( player_t *self, int points, int max );
extern _boolean PL_GiveAmmo( player_t *self, int type, int ammo );
extern void PL_GiveWeapon( player_t *self, int weapon );
extern void PL_GiveLife( player_t *self );
extern void PL_GivePoints( player_t *self, W32 points );
extern void PL_GiveKey( player_t *self, int key );
extern void PL_NewGame( player_t *self );
extern void PL_NextLevel( player_t *self );
extern _boolean PL_Reborn( player_t *self );
extern void PL_Init( void );
extern void PL_Reset( void );
extern void fire_hit( player_t *self );
extern void fire_lead( player_t *self );
#endif /* __WOLF_PLAYER_H__ */

View File

@@ -0,0 +1,427 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 2000-2001 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_pushwalls.c: Wolfenstein3-D power-up handler.
*
* 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"
typedef struct powerup_s
{
int x, y;
pow_t type;
int sprite;
struct powerup_s *prev, *next;
} powerup_t;
powerup_t *powerups = NULL;
int Pow_Texture[ pow_last ] =
{
SPR_STAT_34, // pow_gibs
SPR_STAT_38, // pow_gibs2
SPR_STAT_6, // pow_alpo
SPR_STAT_25, // pow_firstaid
SPR_STAT_20, // pow_key1
SPR_STAT_21, // pow_key2
// not used
SPR_STAT_20, // pow_key3
SPR_STAT_20, // pow_key4
SPR_STAT_29, // pow_cross
SPR_STAT_30, // pow_chalice
SPR_STAT_31, // pow_bible
SPR_STAT_32, // pow_crown
SPR_STAT_26, // pow_clip
SPR_STAT_26, // pow_clip2
SPR_STAT_27, // pow_machinegun
SPR_STAT_28, // pow_chaingun
SPR_STAT_24, // pow_food
SPR_STAT_33, // pow_fullheal
// spear
SPR_STAT_49, // pow_25clip
SPR_STAT_51, // pow_spear
};
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE powerup_t *Pow_Remove( powerup_t *powerup )
{
powerup_t *next;
if( powerup == NULL )
return NULL;
if( powerup->prev )
powerup->prev->next = powerup->next;
if( powerup->next )
powerup->next->prev = powerup->prev;
next = powerup->next;
if( powerups == powerup )
powerups = next; //fuck!
MM_FREE( powerup );
return next;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE powerup_t *Pow_AddNew( void )
{
powerup_t *newp;
newp = MM_MALLOC( sizeof( powerup_t ) );
newp->prev = NULL;
newp->next = powerups;
if( powerups )
{
powerups->prev = newp;
}
powerups = newp;
return newp;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Powerup_Reset( void )
{
powerup_t *powerup = powerups;
while( powerup )
{
powerup = Pow_Remove( powerup );
}
powerups = NULL;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns: 1 if powerup is picked up, otherwise 0.
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE int Pow_Give( pow_t type )
{
static const char *keynames[] = { "Gold", "Silver", "?", "?" };
switch( type )
{
//
// Keys
//
case pow_key1:
case pow_key2:
case pow_key3:
case pow_key4:
type -= pow_key1;
PL_GiveKey( &Player, type );
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/012.wav" ), 1, ATTN_NORM, 0 );
iphoneSetNotifyText( "%s key\n", keynames[ type ] );
break;
//
// Treasure
//
case pow_cross:
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
PL_GivePoints( &Player, 100 );
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/035.wav" ), 1, ATTN_NORM, 0 );
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
iphoneSetNotifyText( "You found the last treasure!" );
}
break;
case pow_chalice:
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
PL_GivePoints( &Player, 500 );
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/036.wav" ), 1, ATTN_NORM, 0 );
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
iphoneSetNotifyText( "You found the last treasure!" );
}
break;
case pow_bible:
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
PL_GivePoints( &Player, 1000 );
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/037.wav" ), 1, ATTN_NORM, 0 );
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
iphoneSetNotifyText( "You found the last treasure!" );
}
break;
case pow_crown:
PL_GiveHealth( &Player, 1, 150 ); // iphone -- trasure acts as health crumbs
PL_GivePoints( &Player, 5000 );
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/045.wav" ), 1, ATTN_NORM, 0 );
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
iphoneSetNotifyText( "You found the last treasure!" );
}
break;
//
// Health
//
case pow_gibs:
if( ! PL_GiveHealth( &Player, 1, 11 ) )
{
return 0;
}
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/061.wav" ), 1, ATTN_NORM, 0 );
break;
case pow_alpo:
if( ! PL_GiveHealth( &Player, 4, 0 ) )
{
return 0;
}
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 );
break;
case pow_food:
if( ! PL_GiveHealth( &Player, 10, 0 ) )
{
return 0;
}
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/033.wav" ), 1, ATTN_NORM, 0 );
break;
case pow_firstaid:
if( ! PL_GiveHealth( &Player, 25, 0 ) )
{
return 0;
}
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/034.wav" ), 1, ATTN_NORM, 0 );
break;
//
// Weapon & Ammo
//
case pow_clip:
if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 8 ) )
{
return 0;
}
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 );
break;
case pow_clip2:
if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 4 ) )
{
return 0;
}
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/031.wav" ), 1, ATTN_NORM, 0 );
break;
case pow_25clip:
if( ! PL_GiveAmmo( &Player, AMMO_BULLETS, 25 ) )
{
return 0;
}
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/064.wav" ), 1, ATTN_NORM, 0 );
break;
case pow_machinegun:
PL_GiveWeapon( &Player, WEAPON_AUTO );
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/030.wav" ), 1, ATTN_NORM, 0 );
iphoneSetNotifyText( "Machinegun" );
break;
case pow_chaingun:
PL_GiveWeapon( &Player, WEAPON_CHAIN );
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "lsfx/038.wav" ), 1, ATTN_NORM, 0 );
iphoneSetNotifyText( "Chaingun" );
Player.facecount = -100;
Player.face_gotgun = true;
break;
//
// Artifacts
//
case pow_fullheal:
PL_GiveHealth( &Player, 999, 0 );
PL_GiveAmmo( &Player, AMMO_BULLETS, 25 );
PL_GiveLife( &Player );
if ( ++levelstate.found_treasure == levelstate.total_treasure ) {
iphoneSetNotifyText( "You found the last treasure!" );
} else {
iphoneSetNotifyText( "Full Heal" );
}
// no extra lives on iPhone Com_Printf( "Extra life!\n" );
break;
case pow_spear:
{
char szTextMsg[ 256 ];
Sound_StartSound( NULL, 0, CHAN_ITEM, Sound_RegisterSound( "sodsfx/109.wav" ), 1, ATTN_NORM, 0 );
iphoneSetNotifyText( "Spear of Destiny" );
my_snprintf( szTextMsg, sizeof( szTextMsg ),
"loading ; map s%.2d.map\n", 20 );
Cbuf_AddText( szTextMsg );
}
break;
default:
Com_DPrintf( "Warning: Unknown item type: %d\n", type );
break;
}
iphoneStartBonusFlash();
return 1;
}
/*
-----------------------------------------------------------------------------
Function:
Parameters: x, y -[in] In are in TILES.
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Powerup_Spawn( int x, int y, int type, LevelData_t *lvl )
{
powerup_t *newp;
lvl->tilemap[ x ][ y ] |= POWERUP_TILE;
newp = Pow_AddNew();
newp->sprite = Sprite_GetNewSprite();
Sprite_SetPos( newp->sprite, TILE2POS( newp->x = x ), TILE2POS( newp->y = y ), 0 );
newp->type = type;
Sprite_SetTex( newp->sprite, -1, Pow_Texture[ type ] );
lvl->tilemap[ x ][ y ] |= POWERUP_TILE;
// good place to update total treasure count!
}
/*
-----------------------------------------------------------------------------
Function:
Parameters: x, y -[in] In are in TILES.
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Powerup_PickUp( int x, int y )
{
powerup_t *pow;
_boolean p_left = false, p_pick = false;
for( pow = powerups ; pow ; pow = pow->next )
{
check_again:
if( pow->x == x && pow->y == y)
{// got a powerup here
if( Pow_Give( pow->type ) ) //FIXME script
{// picked up this stuff, remove it!
p_pick = true;
Sprite_RemoveSprite( pow->sprite );
pow = Pow_Remove( pow );
if( pow )
goto check_again;
else
break;
}
else
{// player do not need it, so may be next time!
p_left = true;
}
}
}
if( p_left )
{
r_world->tilemap[ x ][ y ] |= POWERUP_TILE;
}
else
{
r_world->tilemap[ x ][ y ] &= ~POWERUP_TILE;
}
}

View File

@@ -0,0 +1,79 @@
/*
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_powerups.h: Wolfenstein3-D power-up handler.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
*/
/*
Notes:
This module is implemented by wolf_powerups.c
*/
#ifndef __WOLF_POWERUPS_H__
#define __WOLF_POWERUPS_H__
typedef enum
{
//please provide description
pow_gibs, // 1% if <=10%; SLURPIESND
pow_gibs2, // 1% if <=10%; SLURPIESND
pow_alpo, // 4% if <100%; HEALTH1SND
pow_firstaid, // 25% if <100%; HEALTH2SND
pow_key1, // gold key; GETKEYSND
pow_key2, // silver key; GETKEYSND
pow_key3, // not used
pow_key4, // not used
pow_cross, // 100pts; BONUS1SND
pow_chalice, // 500pts; BONUS2SND
pow_bible, // 1000pts; BONUS3SND
pow_crown, // 5000pts; BONUS4SND
pow_clip, // 8bul if <99bul; GETAMMOSND
pow_clip2, // 4bul if <99bul; GETAMMOSND
pow_machinegun, // machine gun; GETMACHINESND
pow_chaingun, // gatling gun; GETGATLINGSND
pow_food, // 10% if <100%; HEALTH1SND
pow_fullheal, // 99%, 25bul; BONUS1UPSND
pow_25clip, // 25bul if <99bul; GETAMMOBOXSND
pow_spear, // spear of destiny!
pow_last
// add new types <!only!> here (after last)
} pow_t;
extern void Powerup_Reset( void );
extern void Powerup_Spawn( int x, int y, int type, LevelData_t *lvl );
extern void Powerup_PickUp( int x, int y );
#endif /* __WOLF_POWERUPS_H__ */

View File

@@ -0,0 +1,175 @@
/*
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_pushwalls.c: Wolfenstein3-D push-wall handler.
*
* 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"
Pwall_t PWall;
/*
-----------------------------------------------------------------------------
Function: PushWall_Reset() -Reset pushwall status.
Parameters: Nothing.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void PushWall_Reset(void)
{
memset( &PWall, 0, sizeof( Pwall_t ) );
}
/*
-----------------------------------------------------------------------------
Function: PushWall_Push() -Try to move push-wall.
Parameters: x, y -[in] Coordinates in tilemap.
dir -[in] Direction in which push-wall is intended to move.
Returns: true if push successful, otherwise false.
Notes: Called whenever someone tries to push a secret wall.
-----------------------------------------------------------------------------
*/
PUBLIC _boolean PushWall_Push( int x, int y, dir4type dir )
{
int dx, dy;
if( PWall.active )
{
return false; // another PWall is moving [only one at a time!]
}
dx = dx4dir[ dir ];
dy = dy4dir[ dir ];
if( r_world->tilemap[ x + dx ][ y + dy ] & (SOLID_TILE | DOOR_TILE) )
{ // noway (smth is blocking)
return true;
}
// remove secret flag & make everything needed when pushwall used!
r_world->tilemap[ x ][ y ] &= (~SECRET_TILE);
r_world->tilemap[ x ][ y ] &= (~WALL_TILE);
r_world->tilemap[ x ][ y ] |= PUSHWALL_TILE;
if ( ++levelstate.found_secrets == levelstate.total_secrets ) {
iphoneSetNotifyText( "You found the last secret!" );
} else {
iphoneSetNotifyText( "You found a secret!" );
}
if( g_version->value == SPEAROFDESTINY )
{
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/030.wav" ), 1, ATTN_STATIC, 0 );
}
else
{
Sound_StartSound( NULL, 1, CHAN_AUTO, Sound_RegisterSound( "sfx/034.wav" ), 1, ATTN_STATIC, 0 );
}
// good way to avoid stuckness; [un]comment one more down!
// it makes a tile behind pushwall unpassable
r_world->tilemap[ x + dx ][ y + dy ] |= PUSHWALL_TILE;
r_world->wall_tex_x[ x + dx ][ y + dy ] = r_world->wall_tex_x[ x ][ y ];
r_world->wall_tex_y[ x + dx ][ y + dy ] = r_world->wall_tex_y[ x ][ y ];
// write down PWall info
PWall.active = true;
PWall.PWtilesmoved = PWall.PWpointsmoved = 0;
PWall.dir = dir;
PWall.x = x; PWall.y = y;
PWall.dx = dx; PWall.dy = dy;
PWall.tex_x = r_world->wall_tex_x[ x ][ y ];
PWall.tex_y = r_world->wall_tex_y[ x ][ y ];
return true;
}
/*
-----------------------------------------------------------------------------
Function: PushWall_Process() -Process push-walls.
Parameters: Nothing.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void PushWall_Process( void )
{
if( ! PWall.active )
{
return; // no active PWall to work with
}
PWall.PWpointsmoved += tics;
if( PWall.PWpointsmoved < 128 )
{
return;
}
PWall.PWpointsmoved -= 128;
PWall.PWtilesmoved++;
// Free tile
r_world->tilemap[ PWall.x ][ PWall.y ] &= (~PUSHWALL_TILE);
// Occupy new tile
PWall.x += PWall.dx;
PWall.y += PWall.dy;
// Shall we move further?
if( r_world->tilemap[ PWall.x + PWall.dx ][ PWall.y + PWall.dy ] & (SOLID_TILE | DOOR_TILE | ACTOR_TILE | POWERUP_TILE) ||
PWall.PWtilesmoved == 3 )
{
r_world->tilemap[ PWall.x ][ PWall.y ] &= (~PUSHWALL_TILE); // wall now
r_world->tilemap[ PWall.x ][ PWall.y ] |= WALL_TILE; // wall now
r_world->wall_tex_x[ PWall.x ][ PWall.y ] = PWall.tex_x;
r_world->wall_tex_y[ PWall.x ][ PWall.y ] = PWall.tex_y;
PWall.active = false; // Free Push Wall
}
else
{
r_world->tilemap[ PWall.x + PWall.dx ][ PWall.y + PWall.dy ] |= PUSHWALL_TILE;
}
}

View File

@@ -0,0 +1,370 @@
/*
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_raycast.c: Wolfenstein3-D ray-casting.
*
* 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"
W8 tile_visible[ 64 ][ 64 ]; // can player see this tile?
/*
-----------------------------------------------------------------------------
Function: R_RayCast() -Ray cast viewport.
Parameters: viewport -[in] Position of camera.
lvl -[in] Pointer to valid LevelData_t structure.
Returns: Nothing.
Notes: Marks all visible tiles in tile_visible[] array.
-----------------------------------------------------------------------------
*/
PUBLIC void R_RayCast( placeonplane_t viewport, LevelData_t *lvl )
{
int n, x, y, angle, vx, vy;
r_trace_t trace;
memset( tile_visible, 0, sizeof( tile_visible ) ); // clear tile visible flags
// viewport tile coordinates
x = viewport.origin[ 0 ];
y = viewport.origin[ 1 ];
angle = viewport.angle;
vx = POS2TILE( viewport.origin[ 0 ] );
vy = POS2TILE( viewport.origin[ 1 ] );
trace.tile_vis = tile_visible;
trace.flags = TRACE_SIGHT | TRACE_MARK_MAP;
//
// Ray casting
//
// FIXME: control ray count and make angle init
for( n = 0 ; n < 640 ; ++n )
{
trace.x = x;
trace.y = y;
trace.a = NormalizeAngle( angle + ColumnAngle[ n ] );
R_Trace( &trace, lvl );
}
//
// Rendering
//
for( x = 0 ; x < 64; ++x )
for( y = 0 ; y < 64; ++y )
if( tile_visible[ x ][ y ] )
{
lvl->tileEverVisible[x][y] = 1; // for automap
if( lvl->tilemap[ x ][ y ] & DOOR_TILE )
{
/* door */
if( lvl->Doors.DoorMap[ x ][ y ].action != dr_open )
{
_boolean backside = false;
if( lvl->Doors.DoorMap[ x ][ y ].vertical )
{
if( x < vx )
backside = true;
}
else
{
if( y < vy )
backside = true;
}
R_Draw_Door( x, y, LOWERZCOORD, UPPERZCOORD,
lvl->Doors.DoorMap[ x ][ y ].vertical,
backside,
lvl->Doors.DoorMap[ x ][ y ].texture,
Door_Opened( &lvl->Doors, x, y ) );
}
/* door sides */
if( lvl->Doors.DoorMap[ x ][ y ].vertical )
{
if( y <= vy )
R_Draw_Wall( (float)x, (float)(y-1), LOWERZCOORD, UPPERZCOORD, dir4_north, TEX_PLATE );
if( y >= vy )
R_Draw_Wall( (float)x, (float)(y+1), LOWERZCOORD, UPPERZCOORD, dir4_south, TEX_PLATE );
if( x <= vx && lvl->tilemap[ x - 1 ][ y ] & WALL_TILE )
R_Draw_Wall( (float)(x-1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_east, lvl->wall_tex_x[ x - 1 ][ y ] );
if( x >= vx && lvl->tilemap[ x + 1 ][ y ] & WALL_TILE )
R_Draw_Wall( (float)(x+1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_west, lvl->wall_tex_x[ x + 1 ][ y ] );
}
else
{
if( x <= vx )
R_Draw_Wall((float)(x-1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_east, TEX_PLATE+1);
if( x >= vx )
R_Draw_Wall((float)(x+1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_west, TEX_PLATE+1);
if( y <= vy && lvl->tilemap[ x ][ y - 1 ] & WALL_TILE )
R_Draw_Wall( (float)x, (float)(y-1), LOWERZCOORD, UPPERZCOORD, dir4_north, lvl->wall_tex_y[x][y-1]);
if( y >= vy && lvl->tilemap[ x ][ y + 1 ] & WALL_TILE )
R_Draw_Wall( (float)x, (float)(y+1), LOWERZCOORD, UPPERZCOORD, dir4_south, lvl->wall_tex_y[x][y+1]);
}
}
else
{
/* Push-Wall */
if( (r_world->tilemap[ x ][ y ] & PUSHWALL_TILE) )
{
float dx, dy;
dx = PWall.dx * PWall.PWpointsmoved / 128.0f;
dy = PWall.dy * PWall.PWpointsmoved / 128.0f;
if( PWall.x <= vx )
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_east, PWall.tex_x );
if( PWall.x >= vx )
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_west, PWall.tex_x );
if( PWall.y <= vy )
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_north, PWall.tex_y );
if( PWall.y >= vy )
R_Draw_Wall( (float)PWall.x + dx, (float)PWall.y + dy, LOWERZCOORD, UPPERZCOORD, dir4_south, PWall.tex_y );
}
/* x-wall */
if( x <= vx && r_world->tilemap[ x - 1 ][ y ] & WALL_TILE )
R_Draw_Wall( (float)(x-1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_east, r_world->wall_tex_x[x-1][y]);
if( x >= vx && r_world->tilemap[ x + 1 ][ y ] & WALL_TILE )
R_Draw_Wall( (float)(x+1), (float)y, LOWERZCOORD, UPPERZCOORD, dir4_west, r_world->wall_tex_x[x+1][y]);
/* y-wall */
if( y <= vy && r_world->tilemap[ x ][ y - 1 ] & WALL_TILE )
R_Draw_Wall( (float)x, (float)(y-1), LOWERZCOORD, UPPERZCOORD, dir4_north, r_world->wall_tex_y[x][y-1]);
if( y >= vy && r_world->tilemap[ x ][ y + 1 ] & WALL_TILE )
R_Draw_Wall( (float)x, (float)(y+1), LOWERZCOORD, UPPERZCOORD, dir4_south, r_world->wall_tex_y[x][y+1]);
}
}
}
int x_tile_step[ 4 ] = { 1, -1, -1, 1 };
int y_tile_step[ 4 ] = { 1, 1, -1, -1 };
/*
-----------------------------------------------------------------------------
Function: R_TraceCheck() -Trace ray check.
Parameters:
lvl -[in] Pointer to valid LevelData_t structure.
x, y -[in] In tiles.
Returns: true to stop tracing, false otherwise.
Notes: Tells ray casting if we hit a wall or door and to stop tracing.
-----------------------------------------------------------------------------
*/
PRIVATE _boolean R_TraceCheck( LevelData_t *lvl, int x, int y, int frac, int dfrac, _boolean vert, _boolean flip, r_trace_t *trace )
{
if( lvl->tilemap[ x ][ y ] & WALL_TILE )
{
if( vert )
{
trace->x = (x << TILESHIFT) + (flip ? TILEGLOBAL : 0);
trace->y = (y << TILESHIFT) + frac;
trace->flags |= TRACE_HIT_VERT;
}
else
{
trace->x = (x << TILESHIFT) + frac;
trace->y = (y << TILESHIFT) + (flip ? TILEGLOBAL : 0);
trace->flags &= ~TRACE_HIT_VERT;
}
return true; // wall, stop tracing
}
if( trace->tile_vis )
{
trace->tile_vis[ x ][ y ] = true; // this tile is visible
}
if( lvl->tilemap[ x ][ y ] & DOOR_TILE &&
lvl->Doors.DoorMap[ x ][ y ].action != dr_open )
{
frac += dfrac >> 1;
if( POS2TILE( frac ) )
return false;
if( vert )
{
if( lvl->Doors.DoorMap[ x ][ y ].action != dr_closed &&
(frac >> 10) > DOOR_FULLOPEN - Door_Opened( &lvl->Doors, x, y ) )
{
return false; // opened enough
}
trace->x = TILE2POS( x );
trace->y = (y << TILESHIFT) + frac;
trace->flags |= TRACE_HIT_VERT;
}
else
{
if( lvl->Doors.DoorMap[ x ][ y ].action != dr_closed &&
(frac >> 10) < Door_Opened( &lvl->Doors, x, y ) )
{
return false; // opened enough
}
trace->y = TILE2POS( y );
trace->x = (x << TILESHIFT) + frac;
trace->flags &= ~TRACE_HIT_VERT;
}
trace->flags |= TRACE_HIT_DOOR;
return true; // closed door, stop tracing
}
return false; // no intersection, go on!
}
/*
-----------------------------------------------------------------------------
Function: R_Trace() -Trace ray.
Parameters:
trace -[in] Pointer to valid r_trace_t structure.
lvl -[in] Pointer to valid LevelData_t structure.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_Trace( r_trace_t *trace, LevelData_t *lvl )
{
int xtilestep, ytilestep;
int xstep, ystep;
int xtile, ytile;
int xintercept, yintercept;
int YmapPos, XmapPos;
quadrant q;
// Setup for ray casting
q = GetQuadrant( FINE2RAD( trace->a ) );
xtilestep = x_tile_step[ q ];
ytilestep = y_tile_step[ q ];
xtile = POS2TILE( trace->x ) + xtilestep;
ytile = POS2TILE( trace->y ) + ytilestep;
xstep = ytilestep * XnextTable[ trace->a ];
ystep = xtilestep * YnextTable[ trace->a ];
xintercept = (int)( ( ((ytilestep == -1 ? ytile+1 : ytile) << TILESHIFT) - trace->y ) / TanTable[ trace->a ]) + trace->x;
yintercept = (int)( ( ((xtilestep == -1 ? xtile+1 : xtile) << TILESHIFT) - trace->x ) * TanTable[ trace->a ]) + trace->y;
YmapPos = yintercept >> TILESHIFT; // toXray
XmapPos = xintercept >> TILESHIFT; // toYray
if( trace->tile_vis )
{
// this tile is visible
trace->tile_vis[ POS2TILE( trace->x ) ][ POS2TILE( trace->y ) ] = true;
}
//
// Start of ray-casting
//
while( 1 )
{
//
// Vertical loop // an anologue for X-Ray
//
while( ! (ytilestep == -1 && YmapPos <= ytile) && ! (ytilestep == 1 && YmapPos >= ytile) )
{
if( xtile < 0 || xtile >= 64 || YmapPos < 0 || YmapPos >= 64 )
{
return;
}
if( R_TraceCheck( lvl, xtile, YmapPos, yintercept % TILEGLOBAL, ystep, true, (_boolean)(xtilestep == -1), trace ) )
{
return;
}
// prepare for next step
xtile += xtilestep;
yintercept += ystep;
YmapPos = yintercept >> TILESHIFT;
}
//
// Horizontal loop // an anologue for Y-Ray
//
while( ! (xtilestep == -1 && XmapPos <= xtile) && ! (xtilestep == 1 && XmapPos >= xtile) )
{
if( ytile < 0 || ytile >= 64 || XmapPos < 0 || XmapPos >= 64 )
{
return;
}
if( R_TraceCheck( lvl, XmapPos, ytile, xintercept % TILEGLOBAL, xstep, false, (_boolean)(ytilestep == -1), trace ) )
{
return;
}
// prepare for next step
ytile += ytilestep;
xintercept += xstep;
XmapPos = xintercept >> TILESHIFT;
}
} // end of while( 1 )
}

View File

@@ -0,0 +1,74 @@
/*
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_raycast.h: Wolfenstein3-D ray-casting.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
*/
/*
Notes:
This module is implemented by wolf_raycast.c
*/
#ifndef __WOLF_RAYCAST_H__
#define __WOLF_RAYCAST_H__
// marks
#define TRACE_MARK_MAP 1 // marks traced area in 'AM_AutoMap.vis' array
// obstacle levels
#define TRACE_SIGHT 2 // player sight
#define TRACE_SIGHT_AI 4 // enemy sight
#define TRACE_BULLET 8 // bullet
#define TRACE_OBJECT 16 // object
#define TRACE_HIT_VERT 32 // vertical wall was hit
#define TRACE_HIT_DOOR 64 // door was hit
#define TRACE_HIT_PWALL 128 // pushwall was hit
typedef struct r_trace_s
{
int x, y; // origin
int a; // trace angle
int flags;
W8 (*tile_vis)[ 64 ]; // should point to [ 64 ][ 64 ] array
} r_trace_t;
#define UPPERZCOORD 0.6f
#define LOWERZCOORD -0.6f
extern W8 tile_visible[ 64 ][ 64 ]; // can player see this tile?
extern void R_RayCast( placeonplane_t viewport, LevelData_t *lvl );
extern void R_Trace( r_trace_t *trace, LevelData_t *lvl );
#endif /* __WOLF_RAYCAST_H__ */

View File

@@ -0,0 +1,96 @@
/*
Copyright (C) 2004-2005 Michael Liebscher <johnnycanuck@users.sourceforge.net>
Copyright (C) 1997-2001 Id Software, Inc.
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_renderer.c: Wolfenstein 3-D renderer.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
*
* Acknowledgement:
* Portion of this code was derived from Quake II, and was originally
* written by Id Software, Inc.
*
*/
#include "../wolfiphone.h"
LevelData_t *r_world;
/*
-----------------------------------------------------------------------------
Function: R_BeginRegistration -Start the rendering registration sequence.
Parameters: map -[in] The name of the map to load.
Returns: Nothing.
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void R_BeginRegistration( const char *map )
{
char fullname[ MAX_GAMEPATH ];
if( ! map || ! *map )
{
return;
}
++texture_registration_sequence;
my_snprintf( fullname, sizeof( fullname ), "maps/%s.map", map );
// Door_ResetDoors( &r_world->Doors );
Powerup_Reset();
Sprite_Reset();
Areas_InitAreas( Player.areanumber );
PushWall_Reset();
memset( &levelstate, 0, sizeof( levelstate ) ); // Reset gamestate
ResetGuards();
r_world = Level_LoadMap( fullname );
if( r_world == NULL )
{
Com_Printf( "Could not load map (%s)\n", map );
return;
}
levelstate.floornum = floornumber;
if( g_version->value == SPEAROFDESTINY )
{
if( strlen( map ) >= 2 )
{
levelstate.floornum = atoi( map+1 );
if( levelstate.floornum == 20 )
{
levelstate.floornum = 17;
}
}
}
}

View File

@@ -0,0 +1,64 @@
/*
Copyright (C) 2004 Michael Liebscher
Copyright (C) 1997-2001 Id Software, Inc.
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_renderer.h: Wolfenstein3-D renderer.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from Quake II, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_renderer.c and wolf_opengl.c
*/
#ifndef __WOLF_RENDERER_H__
#define __WOLF_RENDERER_H__
extern void R_SetGL3D( placeonplane_t viewport );
extern void R_DrawBox( int x, int y, int w, int h, W32 color );
extern void R_Draw_Door( int x, int y, float z1, float z2, _boolean vertical, _boolean backside, int tex, int amount );
extern void R_Draw_Wall( float x, float y, float z1, float z2, int type, int tex );
extern void R_DrawSprites( void );
extern void R_DrawPsyched( W32 percent );
extern void R_DrawHUD( void );
extern void R_DrawNumber( int x, int y, int number );
extern void R_DrawWeapon( void );
extern void R_put_line( int x, int y, const char *string );
#endif /* __WOLF_RENDERER_H__ */

View File

@@ -0,0 +1,291 @@
/*
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"
// nobody should see this array!
sprite_t Spr_Sprites[ MAX_SPRITES ];
W32 n_of_sprt;
/*
-----------------------------------------------------------------------------
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 )
{
n_of_sprt = 0;
memset( Spr_Sprites, 0, sizeof( Spr_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;
}
Spr_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 = Spr_Sprites ; n < n_of_sprt ; ++n, ++sprt )
{
if( sprt->flags & SPRT_REMOVE )
{ // free spot: clear it first
memset( sprt, 0, sizeof( sprite_t ) );
return n;
}
}
if( n_of_sprt >= MAX_SPRITES )
{
Com_Printf( "Warning n_of_sprt == MAX_SPRITES\n" );
return -1;
}
return n_of_sprt++;
}
/*
-----------------------------------------------------------------------------
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;
}
Spr_Sprites[ sprite_id ].x = x;
Spr_Sprites[ sprite_id ].y = y;
Spr_Sprites[ sprite_id ].ang = angle;
Spr_Sprites[ sprite_id ].tilex = POS2TILE( x );
Spr_Sprites[ sprite_id ].tiley = POS2TILE( y );
Spr_Sprites[ sprite_id ].flags |= SPRT_CHG_POS;
if( ! (x & HALFTILE) ) // (x%TILEGLOBAL>=HALFTILE)
{
Spr_Sprites[ sprite_id ].tilex--;
}
if( ! (y & HALFTILE) )
{
Spr_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:
-----------------------------------------------------------------------------
*/
PUBLIC void Sprite_SetTex( int sprite_id, int index, int tex )
{
if( sprite_id == -1 )
{
return;
}
if( index == -1 ) // one texture for each phase
{
Spr_Sprites[ sprite_id ].tex[ 0 ] = tex;
Spr_Sprites[ sprite_id ].flags |= SPRT_ONE_TEX;
}
else
{
Spr_Sprites[ sprite_id ].tex[ index ] = tex;
}
Spr_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 = Spr_Sprites; n < n_of_sprt; ++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;
}

View File

@@ -0,0 +1,430 @@
/*
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.h: Wolfenstein3-D sprite handling.
*
* Author: Michael Liebscher <johnnycanuck@users.sourceforge.net>
* Date: 2004
*
* Acknowledgement:
* Portion of this code was derived from NewWolf, and was originally
* written by DarkOne the Hacker.
*
* Portion of this code was derived from Wolfenstein3-D, and was originally
* written by Id Software, Inc.
*
*/
/*
Notes:
This module is implemented by wolf_sprites.c
*/
#ifndef __WOLF_SPRITES_H__
#define __WOLF_SPRITES_H__
//
// sprite constants
//
enum {
SPR_DEMO,
SPR_DEATHCAM,
//
// static sprites
//
SPR_STAT_0, SPR_STAT_1,SPR_STAT_2, SPR_STAT_3,
SPR_STAT_4, SPR_STAT_5,SPR_STAT_6, SPR_STAT_7,
SPR_STAT_8, SPR_STAT_9,SPR_STAT_10,SPR_STAT_11,
SPR_STAT_12,SPR_STAT_13,SPR_STAT_14,SPR_STAT_15,
SPR_STAT_16,SPR_STAT_17,SPR_STAT_18,SPR_STAT_19,
SPR_STAT_20,SPR_STAT_21,SPR_STAT_22,SPR_STAT_23,
SPR_STAT_24,SPR_STAT_25,SPR_STAT_26,SPR_STAT_27,
SPR_STAT_28,SPR_STAT_29,SPR_STAT_30,SPR_STAT_31,
SPR_STAT_32,SPR_STAT_33,SPR_STAT_34,SPR_STAT_35,
SPR_STAT_36,SPR_STAT_37,SPR_STAT_38,SPR_STAT_39,
SPR_STAT_40,SPR_STAT_41,SPR_STAT_42,SPR_STAT_43,
SPR_STAT_44,SPR_STAT_45,SPR_STAT_46,SPR_STAT_47,
SPR_STAT_48,SPR_STAT_49,SPR_STAT_50,SPR_STAT_51,
//
// Guard
//
SPR_GRD_S_1,SPR_GRD_S_2,SPR_GRD_S_3,SPR_GRD_S_4,
SPR_GRD_S_5,SPR_GRD_S_6,SPR_GRD_S_7,SPR_GRD_S_8,
SPR_GRD_W1_1,SPR_GRD_W1_2,SPR_GRD_W1_3,SPR_GRD_W1_4,
SPR_GRD_W1_5,SPR_GRD_W1_6,SPR_GRD_W1_7,SPR_GRD_W1_8,
SPR_GRD_W2_1,SPR_GRD_W2_2,SPR_GRD_W2_3,SPR_GRD_W2_4,
SPR_GRD_W2_5,SPR_GRD_W2_6,SPR_GRD_W2_7,SPR_GRD_W2_8,
SPR_GRD_W3_1,SPR_GRD_W3_2,SPR_GRD_W3_3,SPR_GRD_W3_4,
SPR_GRD_W3_5,SPR_GRD_W3_6,SPR_GRD_W3_7,SPR_GRD_W3_8,
SPR_GRD_W4_1,SPR_GRD_W4_2,SPR_GRD_W4_3,SPR_GRD_W4_4,
SPR_GRD_W4_5,SPR_GRD_W4_6,SPR_GRD_W4_7,SPR_GRD_W4_8,
SPR_GRD_PAIN_1,SPR_GRD_DIE_1,SPR_GRD_DIE_2,SPR_GRD_DIE_3,
SPR_GRD_PAIN_2,SPR_GRD_DEAD,
SPR_GRD_SHOOT1,SPR_GRD_SHOOT2,SPR_GRD_SHOOT3,
//
// Dog
//
SPR_DOG_W1_1,SPR_DOG_W1_2,SPR_DOG_W1_3,SPR_DOG_W1_4,
SPR_DOG_W1_5,SPR_DOG_W1_6,SPR_DOG_W1_7,SPR_DOG_W1_8,
SPR_DOG_W2_1,SPR_DOG_W2_2,SPR_DOG_W2_3,SPR_DOG_W2_4,
SPR_DOG_W2_5,SPR_DOG_W2_6,SPR_DOG_W2_7,SPR_DOG_W2_8,
SPR_DOG_W3_1,SPR_DOG_W3_2,SPR_DOG_W3_3,SPR_DOG_W3_4,
SPR_DOG_W3_5,SPR_DOG_W3_6,SPR_DOG_W3_7,SPR_DOG_W3_8,
SPR_DOG_W4_1,SPR_DOG_W4_2,SPR_DOG_W4_3,SPR_DOG_W4_4,
SPR_DOG_W4_5,SPR_DOG_W4_6,SPR_DOG_W4_7,SPR_DOG_W4_8,
SPR_DOG_DIE_1,SPR_DOG_DIE_2,SPR_DOG_DIE_3,SPR_DOG_DEAD,
SPR_DOG_JUMP1,SPR_DOG_JUMP2,SPR_DOG_JUMP3,
//
// SS
//
SPR_SS_S_1,SPR_SS_S_2,SPR_SS_S_3,SPR_SS_S_4,
SPR_SS_S_5,SPR_SS_S_6,SPR_SS_S_7,SPR_SS_S_8,
SPR_SS_W1_1,SPR_SS_W1_2,SPR_SS_W1_3,SPR_SS_W1_4,
SPR_SS_W1_5,SPR_SS_W1_6,SPR_SS_W1_7,SPR_SS_W1_8,
SPR_SS_W2_1,SPR_SS_W2_2,SPR_SS_W2_3,SPR_SS_W2_4,
SPR_SS_W2_5,SPR_SS_W2_6,SPR_SS_W2_7,SPR_SS_W2_8,
SPR_SS_W3_1,SPR_SS_W3_2,SPR_SS_W3_3,SPR_SS_W3_4,
SPR_SS_W3_5,SPR_SS_W3_6,SPR_SS_W3_7,SPR_SS_W3_8,
SPR_SS_W4_1,SPR_SS_W4_2,SPR_SS_W4_3,SPR_SS_W4_4,
SPR_SS_W4_5,SPR_SS_W4_6,SPR_SS_W4_7,SPR_SS_W4_8,
SPR_SS_PAIN_1,SPR_SS_DIE_1,SPR_SS_DIE_2,SPR_SS_DIE_3,
SPR_SS_PAIN_2,SPR_SS_DEAD,
SPR_SS_SHOOT1,SPR_SS_SHOOT2,SPR_SS_SHOOT3,
//
// Mutant
//
SPR_MUT_S_1,SPR_MUT_S_2,SPR_MUT_S_3,SPR_MUT_S_4,
SPR_MUT_S_5,SPR_MUT_S_6,SPR_MUT_S_7,SPR_MUT_S_8,
SPR_MUT_W1_1,SPR_MUT_W1_2,SPR_MUT_W1_3,SPR_MUT_W1_4,
SPR_MUT_W1_5,SPR_MUT_W1_6,SPR_MUT_W1_7,SPR_MUT_W1_8,
SPR_MUT_W2_1,SPR_MUT_W2_2,SPR_MUT_W2_3,SPR_MUT_W2_4,
SPR_MUT_W2_5,SPR_MUT_W2_6,SPR_MUT_W2_7,SPR_MUT_W2_8,
SPR_MUT_W3_1,SPR_MUT_W3_2,SPR_MUT_W3_3,SPR_MUT_W3_4,
SPR_MUT_W3_5,SPR_MUT_W3_6,SPR_MUT_W3_7,SPR_MUT_W3_8,
SPR_MUT_W4_1,SPR_MUT_W4_2,SPR_MUT_W4_3,SPR_MUT_W4_4,
SPR_MUT_W4_5,SPR_MUT_W4_6,SPR_MUT_W4_7,SPR_MUT_W4_8,
SPR_MUT_PAIN_1,SPR_MUT_DIE_1,SPR_MUT_DIE_2,SPR_MUT_DIE_3,
SPR_MUT_PAIN_2,SPR_MUT_DIE_4,SPR_MUT_DEAD,
SPR_MUT_SHOOT1,SPR_MUT_SHOOT2,SPR_MUT_SHOOT3,SPR_MUT_SHOOT4,
//
// Officer
//
SPR_OFC_S_1,SPR_OFC_S_2,SPR_OFC_S_3,SPR_OFC_S_4,
SPR_OFC_S_5,SPR_OFC_S_6,SPR_OFC_S_7,SPR_OFC_S_8,
SPR_OFC_W1_1,SPR_OFC_W1_2,SPR_OFC_W1_3,SPR_OFC_W1_4,
SPR_OFC_W1_5,SPR_OFC_W1_6,SPR_OFC_W1_7,SPR_OFC_W1_8,
SPR_OFC_W2_1,SPR_OFC_W2_2,SPR_OFC_W2_3,SPR_OFC_W2_4,
SPR_OFC_W2_5,SPR_OFC_W2_6,SPR_OFC_W2_7,SPR_OFC_W2_8,
SPR_OFC_W3_1,SPR_OFC_W3_2,SPR_OFC_W3_3,SPR_OFC_W3_4,
SPR_OFC_W3_5,SPR_OFC_W3_6,SPR_OFC_W3_7,SPR_OFC_W3_8,
SPR_OFC_W4_1,SPR_OFC_W4_2,SPR_OFC_W4_3,SPR_OFC_W4_4,
SPR_OFC_W4_5,SPR_OFC_W4_6,SPR_OFC_W4_7,SPR_OFC_W4_8,
SPR_OFC_PAIN_1,SPR_OFC_DIE_1,SPR_OFC_DIE_2,SPR_OFC_DIE_3,
SPR_OFC_PAIN_2,SPR_OFC_DIE_4,SPR_OFC_DEAD,
SPR_OFC_SHOOT1,SPR_OFC_SHOOT2,SPR_OFC_SHOOT3,
//
// Ghosts
//
SPR_BLINKY_W1,SPR_BLINKY_W2,SPR_PINKY_W1,SPR_PINKY_W2,
SPR_CLYDE_W1,SPR_CLYDE_W2,SPR_INKY_W1,SPR_INKY_W2,
//
// Hans
//
SPR_BOSS_W1,SPR_BOSS_W2,SPR_BOSS_W3,SPR_BOSS_W4,
SPR_BOSS_SHOOT1,SPR_BOSS_SHOOT2,SPR_BOSS_SHOOT3,SPR_BOSS_DEAD,
SPR_BOSS_DIE1,SPR_BOSS_DIE2,SPR_BOSS_DIE3,
//
// Schabbs
//
SPR_SCHABB_W1,SPR_SCHABB_W2,SPR_SCHABB_W3,SPR_SCHABB_W4,
SPR_SCHABB_SHOOT1,SPR_SCHABB_SHOOT2,
SPR_SCHABB_DIE1,SPR_SCHABB_DIE2,SPR_SCHABB_DIE3,SPR_SCHABB_DEAD,
SPR_HYPO1,SPR_HYPO2,SPR_HYPO3,SPR_HYPO4,
//
// Fake
//
SPR_FAKE_W1,SPR_FAKE_W2,SPR_FAKE_W3,SPR_FAKE_W4,
SPR_FAKE_SHOOT,SPR_FIRE1,SPR_FIRE2,
SPR_FAKE_DIE1,SPR_FAKE_DIE2,SPR_FAKE_DIE3,SPR_FAKE_DIE4,
SPR_FAKE_DIE5,SPR_FAKE_DEAD,
//
// Hitler
//
SPR_MECHA_W1,SPR_MECHA_W2,SPR_MECHA_W3,SPR_MECHA_W4,
SPR_MECHA_SHOOT1,SPR_MECHA_SHOOT2,SPR_MECHA_SHOOT3,SPR_MECHA_DEAD,
SPR_MECHA_DIE1,SPR_MECHA_DIE2,SPR_MECHA_DIE3,
SPR_HITLER_W1,SPR_HITLER_W2,SPR_HITLER_W3,SPR_HITLER_W4,
SPR_HITLER_SHOOT1,SPR_HITLER_SHOOT2,SPR_HITLER_SHOOT3,SPR_HITLER_DEAD,
SPR_HITLER_DIE1,SPR_HITLER_DIE2,SPR_HITLER_DIE3,SPR_HITLER_DIE4,
SPR_HITLER_DIE5,SPR_HITLER_DIE6,SPR_HITLER_DIE7,
//
// Giftmacher
//
SPR_GIFT_W1,SPR_GIFT_W2,SPR_GIFT_W3,SPR_GIFT_W4,
SPR_GIFT_SHOOT1,SPR_GIFT_SHOOT2,
SPR_GIFT_DIE1,SPR_GIFT_DIE2,SPR_GIFT_DIE3,SPR_GIFT_DEAD,
//
// Rocket, smoke and small explosion
//
SPR_ROCKET_1,SPR_ROCKET_2,SPR_ROCKET_3,SPR_ROCKET_4,
SPR_ROCKET_5,SPR_ROCKET_6,SPR_ROCKET_7,SPR_ROCKET_8,
SPR_SMOKE_1,SPR_SMOKE_2,SPR_SMOKE_3,SPR_SMOKE_4,
SPR_BOOM_1,SPR_BOOM_2,SPR_BOOM_3,
//
// Angel of Death's DeathSparks(tm)
//
SPR_HROCKET_1,SPR_HROCKET_2,SPR_HROCKET_3,SPR_HROCKET_4,
SPR_HROCKET_5,SPR_HROCKET_6,SPR_HROCKET_7,SPR_HROCKET_8,
SPR_HSMOKE_1,SPR_HSMOKE_2,SPR_HSMOKE_3,SPR_HSMOKE_4,
SPR_HBOOM_1,SPR_HBOOM_2,SPR_HBOOM_3,
SPR_SPARK1,SPR_SPARK2,SPR_SPARK3,SPR_SPARK4,
//
// Gretel
//
SPR_GRETEL_W1,SPR_GRETEL_W2,SPR_GRETEL_W3,SPR_GRETEL_W4,
SPR_GRETEL_SHOOT1,SPR_GRETEL_SHOOT2,SPR_GRETEL_SHOOT3,SPR_GRETEL_DEAD,
SPR_GRETEL_DIE1,SPR_GRETEL_DIE2,SPR_GRETEL_DIE3,
//
// Fat Face
//
SPR_FAT_W1,SPR_FAT_W2,SPR_FAT_W3,SPR_FAT_W4,
SPR_FAT_SHOOT1,SPR_FAT_SHOOT2,SPR_FAT_SHOOT3,SPR_FAT_SHOOT4,
SPR_FAT_DIE1,SPR_FAT_DIE2,SPR_FAT_DIE3,SPR_FAT_DEAD,
//
// bj
//
SPR_BJ_W1,SPR_BJ_W2,SPR_BJ_W3,SPR_BJ_W4,
SPR_BJ_JUMP1,SPR_BJ_JUMP2,SPR_BJ_JUMP3,SPR_BJ_JUMP4,
//
// SPEAR OF DESTINY
//
//
// Trans Grosse
//
SPR_TRANS_W1,SPR_TRANS_W2,SPR_TRANS_W3,SPR_TRANS_W4,
SPR_TRANS_SHOOT1,SPR_TRANS_SHOOT2,SPR_TRANS_SHOOT3,SPR_TRANS_DEAD,
SPR_TRANS_DIE1,SPR_TRANS_DIE2,SPR_TRANS_DIE3,
//
// Wilhelm
//
SPR_WILL_W1,SPR_WILL_W2,SPR_WILL_W3,SPR_WILL_W4,
SPR_WILL_SHOOT1,SPR_WILL_SHOOT2,SPR_WILL_SHOOT3,SPR_WILL_SHOOT4,
SPR_WILL_DIE1,SPR_WILL_DIE2,SPR_WILL_DIE3,SPR_WILL_DEAD,
//
// UberMutant
//
SPR_UBER_W1,SPR_UBER_W2,SPR_UBER_W3,SPR_UBER_W4,
SPR_UBER_SHOOT1,SPR_UBER_SHOOT2,SPR_UBER_SHOOT3,SPR_UBER_SHOOT4,
SPR_UBER_DIE1,SPR_UBER_DIE2,SPR_UBER_DIE3,SPR_UBER_DIE4,
SPR_UBER_DEAD,
//
// Death Knight
//
SPR_DEATH_W1,SPR_DEATH_W2,SPR_DEATH_W3,SPR_DEATH_W4,
SPR_DEATH_SHOOT1,SPR_DEATH_SHOOT2,SPR_DEATH_SHOOT3,SPR_DEATH_SHOOT4,
SPR_DEATH_DIE1,SPR_DEATH_DIE2,SPR_DEATH_DIE3,SPR_DEATH_DIE4,
SPR_DEATH_DIE5,SPR_DEATH_DIE6,SPR_DEATH_DEAD,
//
// Ghost
//
SPR_SPECTRE_W1,SPR_SPECTRE_W2,SPR_SPECTRE_W3,SPR_SPECTRE_W4,
SPR_SPECTRE_F1,SPR_SPECTRE_F2,SPR_SPECTRE_F3,SPR_SPECTRE_F4,
//
// Angel of Death
//
SPR_ANGEL_W1,SPR_ANGEL_W2,SPR_ANGEL_W3,SPR_ANGEL_W4,
SPR_ANGEL_SHOOT1,SPR_ANGEL_SHOOT2,SPR_ANGEL_TIRED1,SPR_ANGEL_TIRED2,
SPR_ANGEL_DIE1,SPR_ANGEL_DIE2,SPR_ANGEL_DIE3,SPR_ANGEL_DIE4,
SPR_ANGEL_DIE5,SPR_ANGEL_DIE6,SPR_ANGEL_DIE7,SPR_ANGEL_DEAD,
//
// player attack frames
//
SPR_KNIFEREADY,SPR_KNIFEATK1,SPR_KNIFEATK2,SPR_KNIFEATK3,
SPR_KNIFEATK4,
SPR_PISTOLREADY,SPR_PISTOLATK1,SPR_PISTOLATK2,SPR_PISTOLATK3,
SPR_PISTOLATK4,
SPR_MACHINEGUNREADY,SPR_MACHINEGUNATK1,SPR_MACHINEGUNATK2,MACHINEGUNATK3,
SPR_MACHINEGUNATK4,
SPR_CHAINREADY,SPR_CHAINATK1,SPR_CHAINATK2,SPR_CHAINATK3,
SPR_CHAINATK4,
};
#define SPRT_ONE_TEX 1
#define SPRT_NO_ROT 2
#define SPRT_CHG_POS 4
#define SPRT_CHG_TEX 8
#define SPRT_REMOVE 16
typedef struct sprite_s
{
vec3_t position;
int x, y, ang;
// very clever to make it not just (x>>TILESHIFT)
// but also (x>>TILESHIFT)-1 if (x%TILEWIDTH)<HALFTILE
// so we will check only 4 files instead of 9 as Carmack did!
int tilex, tiley;
// controls appearence of this sprite:
// SPRT_ONE_TEX: use one texture for each rotation
// SPRT_NO_ROT: do not rotate sprite (fence)
// SPRT_CHG_POS
// SPRT_CHG_TEX
// SPRT_REMOVE
int flags;
// 8 textures: one for each rotation phase!
// if SPRT_ONE_TEX flag use tex with index 0!
int tex[ 8 ];
} sprite_t;
// total sprites on level in a moment
#define MAX_SPRITES 1024
extern sprite_t Spr_Sprites[ MAX_SPRITES ];
extern W32 n_of_sprt;
typedef struct visobj_s
{
int viewx, viewheight; // obsolete, but will do in software rendering!
int dist; // how we will sort them
int x, y; // position in game space! (for OpenGL)
int ang; // for md2 rotation
int tex; // texture to draw (renderer must know what to draw by this number!
} visobj_t;
extern visobj_t vislist[];
extern void Sprite_Reset( void );
extern void Sprite_RemoveSprite( int sprite_id );
extern int Sprite_GetNewSprite( void );
extern void Sprite_SetPos( int sprite_id, int x, int y, int angle );
extern void Sprite_SetTex( int sprite_id, int index, int tex );
extern int Sprite_CreateVisList( void );
#endif /* __WOLF_SPRITES_H__ */

View File

@@ -0,0 +1,95 @@
/*
Copyright (C) 2004 Michael Liebscher
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.
*/
#include "../wolfiphone.h"
extern void Client_PrepRefresh( const char *r_mapname );
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PRIVATE void SV_GameMap_f( void )
{
char *map;
char r_mapname[ 32 ];
if( Cmd_Argc() != 2 )
{
Com_Printf( "USAGE: gamemap <map>\n" );
return;
}
// Com_DPrintf( "SV_GameMap( %s )\n", Cmd_Argv( 1 ) );
FS_CreatePath( va( "%s/save/current/", FS_Gamedir() ) );
// check for clearing the current savegame
map = Cmd_Argv( 1 );
// start up the next map
my_strlcpy( r_mapname, Cmd_Argv( 1 ), sizeof( r_mapname ) );
Client_PrepRefresh( r_mapname );
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void Map_f( void )
{
char *map;
char expanded[ MAX_GAMEPATH ];
// Check to make sure the level exists.
map = Cmd_Argv( 1 );
if( ! strstr( map, "." ) )
{
my_snprintf( expanded, sizeof( expanded ), "maps/%s.map", map );
}
else
{
my_snprintf( expanded, sizeof( expanded ), "maps/%s", map );
}
//sv.state = ss_dead; // don't save current level when changing
// SV_WipeSavegame( "current" );
SV_GameMap_f();
}

View File

@@ -0,0 +1,194 @@
/*
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.
*/
#include "../wolfiphone.h"
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void fire_hit( player_t *self )
{
entity_t *closest;
int dist, d1, n, shot_dist, damage;
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "lsfx/023.wav" ), 1, ATTN_NORM, 0 );
// actually fire
dist = 0x7fffffff;
closest = NULL;
for( n = 0 ; n < NumGuards ; ++n )
{
if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
{
shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
if( shot_dist > (2 * TILEGLOBAL / 3) )
{
continue; // miss
}
d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
if( d1 < 0 || d1 > dist )
{
continue;
}
if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
{
//if( ! CheckLine( &Guards[ n ] ) )
continue; // obscured
}
dist = d1;
closest = &Guards[ n ];
}
}
if( ! closest || dist > TILE2POS( 1 ) )
{
return; // missed if further than 1.5 tiles
}
damage = US_RndT() >> 4;
A_DamageActor( closest, damage ); // hit something
}
/*
-----------------------------------------------------------------------------
Function:
Parameters:
Returns:
Notes:
-----------------------------------------------------------------------------
*/
PUBLIC void fire_lead( player_t *self )
{
entity_t *closest;
int damage;
int dx, dy, dist;
int d1, shot_dist, n;
switch( self->weapon )
{
case WEAPON_PISTOL:
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/012.wav" ), 1, ATTN_NORM, 0 );
break;
case WEAPON_AUTO:
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/011.wav" ), 1, ATTN_NORM, 0 );
break;
case WEAPON_CHAIN:
Sound_StartSound( NULL, 0, CHAN_WEAPON, Sound_RegisterSound( "sfx/013.wav" ), 1, ATTN_NORM, 0 );
break;
}
self->madenoise = true;
dist = 0x7fffffffl;
closest = NULL;
for( n = 0 ; n < NumGuards; ++n )
{
if( Guards[ n ].flags & FL_SHOOTABLE ) // && Guards[n].flags&FL_VISABLE
{
shot_dist = Point2LineDist( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
if( shot_dist > (2 * TILEGLOBAL / 3) )
{
continue; // miss
}
d1 = LineLen2Point( Guards[ n ].x - self->position.origin[ 0 ], Guards[ n ].y - self->position.origin[ 1 ], self->position.angle );
if( d1 < 0 || d1 > dist )
{
continue;
}
if( ! Level_CheckLine( Guards[ n ].x, Guards[ n ].y, Player.position.origin[0], Player.position.origin[1], r_world ) )
{
//if( ! CheckLine( &Guards[ n ] ) )
continue; // obscured
}
dist = d1;
closest = &Guards[ n ];
}
}
if( ! closest ) // missed
{
r_trace_t trace;
trace.a = NormalizeAngle( self->position.angle - DEG2FINE( 2 ) + rand() % (DEG2FINE( 4 ) ) );
trace.x = self->position.origin[ 0 ];
trace.y = self->position.origin[ 1 ];
trace.flags = TRACE_BULLET;
trace.tile_vis = NULL;
R_Trace( &trace, r_world );
if( trace.flags & TRACE_HIT_DOOR )
{
Sound_StartSound( NULL, 0, CHAN_AUTO, Sound_RegisterSound( "lsfx/028.wav" ), 1, ATTN_NORM, 0 );
}
return;
}
// hit something
dx = ABS( closest->tilex - self->tilex );
dy = ABS( closest->tiley - self->tiley );
dist = max_of_2( dx, dy );
if( dist < 2 )
{
damage = US_RndT() / 4;
}
else if( dist < 4 )
{
damage = US_RndT() / 6;
}
else
{
if( US_RndT() / 12 < dist )
{
return; // missed
}
damage = US_RndT() / 6;
}
A_DamageActor( closest, damage );
}