forked from len0rd/rockbox
Patch #2969 - Doom! Currently only working on the H300.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9312 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
fff7d6157d
commit
47f4a458d6
130 changed files with 65584 additions and 1 deletions
468
apps/plugins/doom/p_ceilng.c
Normal file
468
apps/plugins/doom/p_ceilng.c
Normal file
|
@ -0,0 +1,468 @@
|
|||
/* Emacs style mode select -*- C++ -*-
|
||||
*-----------------------------------------------------------------------------
|
||||
*
|
||||
*
|
||||
* PrBoom a Doom port merged with LxDoom and LSDLDoom
|
||||
* based on BOOM, a modified and improved DOOM engine
|
||||
* Copyright (C) 1999 by
|
||||
* id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
|
||||
* Copyright (C) 1999-2000 by
|
||||
* Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* DESCRIPTION:
|
||||
* Ceiling aninmation (lowering, crushing, raising)
|
||||
*
|
||||
*-----------------------------------------------------------------------------*/
|
||||
|
||||
#include "doomstat.h"
|
||||
#include "r_main.h"
|
||||
#include "p_spec.h"
|
||||
#include "p_tick.h"
|
||||
#include "s_sound.h"
|
||||
#include "sounds.h"
|
||||
#include "z_zone.h"
|
||||
#include "doomdef.h"
|
||||
#define PU_LEVSPEC 51 // a special thinker in a level
|
||||
#include "rockmacros.h"
|
||||
|
||||
// the list of ceilings moving currently, including crushers
|
||||
ceilinglist_t *activeceilings;
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Ceiling action routine and linedef type handler
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
//
|
||||
// T_MoveCeiling
|
||||
//
|
||||
// Action routine that moves ceilings. Called once per tick.
|
||||
//
|
||||
// Passed a ceiling_t structure that contains all the info about the move.
|
||||
// see P_SPEC.H for fields. No return.
|
||||
//
|
||||
// jff 02/08/98 all cases with labels beginning with gen added to support
|
||||
// generalized line type behaviors.
|
||||
//
|
||||
void T_MoveCeiling (ceiling_t* ceiling)
|
||||
{
|
||||
result_e res;
|
||||
|
||||
switch(ceiling->direction)
|
||||
{
|
||||
case 0:
|
||||
// If ceiling in stasis, do nothing
|
||||
break;
|
||||
|
||||
case 1:
|
||||
// Ceiling is moving up
|
||||
res = T_MovePlane
|
||||
(
|
||||
ceiling->sector,
|
||||
ceiling->speed,
|
||||
ceiling->topheight,
|
||||
false,
|
||||
1,
|
||||
ceiling->direction
|
||||
);
|
||||
|
||||
// if not a silent crusher, make moving sound
|
||||
if (!(leveltime&7))
|
||||
{
|
||||
switch(ceiling->type)
|
||||
{
|
||||
case silentCrushAndRaise:
|
||||
case genSilentCrusher:
|
||||
break;
|
||||
default:
|
||||
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_stnmov);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// handle reaching destination height
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch(ceiling->type)
|
||||
{
|
||||
// plain movers are just removed
|
||||
case raiseToHighest:
|
||||
case genCeiling:
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
|
||||
// movers with texture change, change the texture then get removed
|
||||
case genCeilingChgT:
|
||||
case genCeilingChg0:
|
||||
ceiling->sector->special = ceiling->newspecial;
|
||||
//jff 3/14/98 transfer old special field as well
|
||||
ceiling->sector->oldspecial = ceiling->oldspecial;
|
||||
case genCeilingChg:
|
||||
ceiling->sector->ceilingpic = ceiling->texture;
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
|
||||
// crushers reverse direction at the top
|
||||
case silentCrushAndRaise:
|
||||
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_pstop);
|
||||
case genSilentCrusher:
|
||||
case genCrusher:
|
||||
case fastCrushAndRaise:
|
||||
case crushAndRaise:
|
||||
ceiling->direction = -1;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case -1:
|
||||
// Ceiling moving down
|
||||
res = T_MovePlane
|
||||
(
|
||||
ceiling->sector,
|
||||
ceiling->speed,
|
||||
ceiling->bottomheight,
|
||||
ceiling->crush,
|
||||
1,
|
||||
ceiling->direction
|
||||
);
|
||||
|
||||
// if not silent crusher type make moving sound
|
||||
if (!(leveltime&7))
|
||||
{
|
||||
switch(ceiling->type)
|
||||
{
|
||||
case silentCrushAndRaise:
|
||||
case genSilentCrusher:
|
||||
break;
|
||||
default:
|
||||
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_stnmov);
|
||||
}
|
||||
}
|
||||
|
||||
// handle reaching destination height
|
||||
if (res == pastdest)
|
||||
{
|
||||
switch(ceiling->type)
|
||||
{
|
||||
// 02/09/98 jff change slow crushers' speed back to normal
|
||||
// start back up
|
||||
case genSilentCrusher:
|
||||
case genCrusher:
|
||||
if (ceiling->oldspeed<CEILSPEED*3)
|
||||
ceiling->speed = ceiling->oldspeed;
|
||||
ceiling->direction = 1; //jff 2/22/98 make it go back up!
|
||||
break;
|
||||
|
||||
// make platform stop at bottom of all crusher strokes
|
||||
// except generalized ones, reset speed, start back up
|
||||
case silentCrushAndRaise:
|
||||
S_StartSound((mobj_t *)&ceiling->sector->soundorg,sfx_pstop);
|
||||
case crushAndRaise:
|
||||
ceiling->speed = CEILSPEED;
|
||||
case fastCrushAndRaise:
|
||||
ceiling->direction = 1;
|
||||
break;
|
||||
|
||||
// in the case of ceiling mover/changer, change the texture
|
||||
// then remove the active ceiling
|
||||
case genCeilingChgT:
|
||||
case genCeilingChg0:
|
||||
ceiling->sector->special = ceiling->newspecial;
|
||||
//jff add to fix bug in special transfers from changes
|
||||
ceiling->sector->oldspecial = ceiling->oldspecial;
|
||||
case genCeilingChg:
|
||||
ceiling->sector->ceilingpic = ceiling->texture;
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
|
||||
// all other case, just remove the active ceiling
|
||||
case lowerAndCrush:
|
||||
case lowerToFloor:
|
||||
case lowerToLowest:
|
||||
case lowerToMaxFloor:
|
||||
case genCeiling:
|
||||
P_RemoveActiveCeiling(ceiling);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else // ( res != pastdest )
|
||||
{
|
||||
// handle the crusher encountering an obstacle
|
||||
if (res == crushed)
|
||||
{
|
||||
switch(ceiling->type)
|
||||
{
|
||||
//jff 02/08/98 slow down slow crushers on obstacle
|
||||
case genCrusher:
|
||||
case genSilentCrusher:
|
||||
if (ceiling->oldspeed < CEILSPEED*3)
|
||||
ceiling->speed = CEILSPEED / 8;
|
||||
break;
|
||||
case silentCrushAndRaise:
|
||||
case crushAndRaise:
|
||||
case lowerAndCrush:
|
||||
ceiling->speed = CEILSPEED / 8;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// EV_DoCeiling
|
||||
//
|
||||
// Move a ceiling up/down or start a crusher
|
||||
//
|
||||
// Passed the linedef activating the function and the type of function desired
|
||||
// returns true if a thinker started
|
||||
//
|
||||
int EV_DoCeiling
|
||||
( line_t* line,
|
||||
ceiling_e type )
|
||||
{
|
||||
int secnum;
|
||||
int rtn;
|
||||
sector_t* sec;
|
||||
ceiling_t* ceiling;
|
||||
|
||||
secnum = -1;
|
||||
rtn = 0;
|
||||
|
||||
// Reactivate in-stasis ceilings...for certain types.
|
||||
// This restarts a crusher after it has been stopped
|
||||
switch(type)
|
||||
{
|
||||
case fastCrushAndRaise:
|
||||
case silentCrushAndRaise:
|
||||
case crushAndRaise:
|
||||
//jff 4/5/98 return if activated
|
||||
rtn = P_ActivateInStasisCeiling(line);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// affects all sectors with the same tag as the linedef
|
||||
while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
|
||||
{
|
||||
sec = §ors[secnum];
|
||||
|
||||
// if ceiling already moving, don't start a second function on it
|
||||
if (P_SectorActive(ceiling_special,sec)) //jff 2/22/98
|
||||
continue;
|
||||
|
||||
// create a new ceiling thinker
|
||||
rtn = 1;
|
||||
ceiling = Z_Malloc (sizeof(*ceiling), PU_LEVSPEC, 0);
|
||||
P_AddThinker (&ceiling->thinker);
|
||||
sec->ceilingdata = ceiling; //jff 2/22/98
|
||||
ceiling->thinker.function = T_MoveCeiling;
|
||||
ceiling->sector = sec;
|
||||
ceiling->crush = false;
|
||||
|
||||
// setup ceiling structure according to type of function
|
||||
switch(type)
|
||||
{
|
||||
case fastCrushAndRaise:
|
||||
ceiling->crush = true;
|
||||
ceiling->topheight = sec->ceilingheight;
|
||||
ceiling->bottomheight = sec->floorheight + (8*FRACUNIT);
|
||||
ceiling->direction = -1;
|
||||
ceiling->speed = CEILSPEED * 2;
|
||||
break;
|
||||
|
||||
case silentCrushAndRaise:
|
||||
case crushAndRaise:
|
||||
ceiling->crush = true;
|
||||
ceiling->topheight = sec->ceilingheight;
|
||||
case lowerAndCrush:
|
||||
case lowerToFloor:
|
||||
ceiling->bottomheight = sec->floorheight;
|
||||
if (type != lowerToFloor)
|
||||
ceiling->bottomheight += 8*FRACUNIT;
|
||||
ceiling->direction = -1;
|
||||
ceiling->speed = CEILSPEED;
|
||||
break;
|
||||
|
||||
case raiseToHighest:
|
||||
ceiling->topheight = P_FindHighestCeilingSurrounding(sec);
|
||||
ceiling->direction = 1;
|
||||
ceiling->speed = CEILSPEED;
|
||||
break;
|
||||
|
||||
case lowerToLowest:
|
||||
ceiling->bottomheight = P_FindLowestCeilingSurrounding(sec);
|
||||
ceiling->direction = -1;
|
||||
ceiling->speed = CEILSPEED;
|
||||
break;
|
||||
|
||||
case lowerToMaxFloor:
|
||||
ceiling->bottomheight = P_FindHighestFloorSurrounding(sec);
|
||||
ceiling->direction = -1;
|
||||
ceiling->speed = CEILSPEED;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// add the ceiling to the active list
|
||||
ceiling->tag = sec->tag;
|
||||
ceiling->type = type;
|
||||
P_AddActiveCeiling(ceiling);
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Active ceiling list primitives
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
|
||||
// jff 2/22/98 - modified Lee's plat code to work for ceilings
|
||||
//
|
||||
// The following were all rewritten by Lee Killough
|
||||
// to use the new structure which places no limits
|
||||
// on active ceilings. It also avoids spending as much
|
||||
// time searching for active ceilings. Previously a
|
||||
// fixed-size array was used, with NULL indicating
|
||||
// empty entries, while now a doubly-linked list
|
||||
// is used.
|
||||
|
||||
//
|
||||
// P_ActivateInStasisCeiling()
|
||||
//
|
||||
// Reactivates all stopped crushers with the right tag
|
||||
//
|
||||
// Passed the line reactivating the crusher
|
||||
// Returns true if a ceiling reactivated
|
||||
//
|
||||
//jff 4/5/98 return if activated
|
||||
int P_ActivateInStasisCeiling(line_t *line)
|
||||
{
|
||||
ceilinglist_t *cl;
|
||||
int rtn=0;
|
||||
|
||||
for (cl=activeceilings; cl; cl=cl->next)
|
||||
{
|
||||
ceiling_t *ceiling = cl->ceiling;
|
||||
if (ceiling->tag == line->tag && ceiling->direction == 0)
|
||||
{
|
||||
ceiling->direction = ceiling->olddirection;
|
||||
ceiling->thinker.function = T_MoveCeiling;
|
||||
//jff 4/5/98 return if activated
|
||||
rtn=1;
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//
|
||||
// EV_CeilingCrushStop()
|
||||
//
|
||||
// Stops all active ceilings with the right tag
|
||||
//
|
||||
// Passed the linedef stopping the ceilings
|
||||
// Returns true if a ceiling put in stasis
|
||||
//
|
||||
int EV_CeilingCrushStop(line_t* line)
|
||||
{
|
||||
int rtn=0;
|
||||
|
||||
ceilinglist_t *cl;
|
||||
for (cl=activeceilings; cl; cl=cl->next)
|
||||
{
|
||||
ceiling_t *ceiling = cl->ceiling;
|
||||
if (ceiling->direction != 0 && ceiling->tag == line->tag)
|
||||
{
|
||||
ceiling->olddirection = ceiling->direction;
|
||||
ceiling->direction = 0;
|
||||
ceiling->thinker.function = NULL;
|
||||
rtn=1;
|
||||
}
|
||||
}
|
||||
return rtn;
|
||||
}
|
||||
|
||||
//
|
||||
// P_AddActiveCeiling()
|
||||
//
|
||||
// Adds a ceiling to the head of the list of active ceilings
|
||||
//
|
||||
// Passed the ceiling motion structure
|
||||
// Returns nothing
|
||||
//
|
||||
void P_AddActiveCeiling(ceiling_t* ceiling)
|
||||
{
|
||||
ceilinglist_t *list = malloc(sizeof *list);
|
||||
list->ceiling = ceiling;
|
||||
ceiling->list = list;
|
||||
if ((list->next = activeceilings))
|
||||
list->next->prev = &list->next;
|
||||
list->prev = &activeceilings;
|
||||
activeceilings = list;
|
||||
}
|
||||
|
||||
//
|
||||
// P_RemoveActiveCeiling()
|
||||
//
|
||||
// Removes a ceiling from the list of active ceilings
|
||||
//
|
||||
// Passed the ceiling motion structure
|
||||
// Returns nothing
|
||||
//
|
||||
void P_RemoveActiveCeiling(ceiling_t* ceiling)
|
||||
{
|
||||
ceilinglist_t *list = ceiling->list;
|
||||
ceiling->sector->ceilingdata = NULL; //jff 2/22/98
|
||||
P_RemoveThinker(&ceiling->thinker);
|
||||
if ((*list->prev = list->next))
|
||||
list->next->prev = list->prev;
|
||||
free(list);
|
||||
}
|
||||
|
||||
//
|
||||
// P_RemoveAllActiveCeilings()
|
||||
//
|
||||
// Removes all ceilings from the active ceiling list
|
||||
//
|
||||
// Passed nothing, returns nothing
|
||||
//
|
||||
void P_RemoveAllActiveCeilings(void)
|
||||
{
|
||||
while (activeceilings)
|
||||
{
|
||||
ceilinglist_t *next = activeceilings->next;
|
||||
free(activeceilings);
|
||||
activeceilings = next;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue