DOOM64-RE

DOOM 64 Reverse Engineering
Log | Files | Refs | README | LICENSE

p_user.c (19124B)


      1 /* P_user.c */
      2 
      3 #include "doomdef.h"
      4 #include "p_local.h"
      5 #include "st_main.h"
      6 
      7 #define MAXMOCKTIME     1800
      8 int deathmocktics; // 800A56A0
      9 
     10 #define MK_TXT01	"HAHAHAHA!"
     11 #define MK_TXT02	"YOU SHOULDN'T HAVE DONE THAT."
     12 #define MK_TXT03	"TRY AN EASIER LEVEL..."
     13 #define MK_TXT04	"WOW! LOOK AT THOSE DEMON FEET."
     14 #define MK_TXT05	"I PLAY DOOM AND I CAN'T GET UP."
     15 #define MK_TXT06	"OUCH! THAT HAD TO HURT."
     16 #define MK_TXT07	"LOOK AT ME! I'M FLAT!"
     17 #define MK_TXT08	"THANKS FOR PLAYING!"
     18 #define MK_TXT09	"YOU LAZY @&$#!"
     19 #define MK_TXT10	"HAVE YOU HAD ENOUGH?"
     20 #define MK_TXT11	"THE DEMONS GAVE YOU THE BOOT!"
     21 #define MK_TXT12	"THE LEAD DEMON VANQUISHED YOU!"
     22 
     23 char *mockstrings[] =   // 8005A290
     24 {
     25     MK_TXT01, MK_TXT02, MK_TXT03, MK_TXT04,
     26 	MK_TXT05, MK_TXT06, MK_TXT07, MK_TXT08,
     27 	MK_TXT09, MK_TXT10, MK_TXT11, MK_TXT12,
     28 };
     29 
     30 fixed_t 		forwardmove[2] = {0xE000, 0x16000}; // 8005B060
     31 fixed_t 		sidemove[2] = {0xE000, 0x16000};    // 8005B068
     32 
     33 #define SLOWTURNTICS    10
     34 fixed_t			angleturn[] =       // 8005B070
     35 	{50,50,83,83,100,116,133,150,150,166,
     36 	133,133,150,166,166,200,200,216,216,233}; // fastangleturn
     37 
     38 /*============================================================================= */
     39 
     40 mobj_t          *slidething;    //80077D04, pmGp000008f4
     41 extern	fixed_t	slidex, slidey; //80077dbc || 80077dc0
     42 extern	line_t	*specialline;   //80077dc8
     43 
     44 void P_SlideMove (mobj_t *mo);
     45 
     46 #if 0
     47 void P_PlayerMove (mobj_t *mo)//L80029CB8()
     48 {
     49 	fixed_t		momx, momy;
     50 	line_t		*latchedline;
     51 	fixed_t		latchedx, latchedy;
     52 
     53 	//momx = vblsinframe[playernum] * (mo->momx>>2);
     54 	//momy = vblsinframe[playernum] * (mo->momy>>2);
     55 
     56 	// Change on Final Doom
     57 	momx = mo->momx;
     58 	momy = mo->momy;
     59 
     60 	slidething = mo;
     61 
     62 	P_SlideMove ();
     63 
     64 	latchedline = (line_t *)specialline;
     65 	latchedx = slidex;
     66 	latchedy = slidey;
     67 
     68 	if ((latchedx == mo->x) && (latchedy == mo->y))
     69 		goto stairstep;
     70 
     71 	if (P_TryMove (mo, latchedx, latchedy))
     72 		goto dospecial;
     73 
     74 stairstep:
     75 
     76 	if (momx > MAXMOVE)
     77 		momx = MAXMOVE;
     78 	else if (momx < -MAXMOVE)
     79 		momx = -MAXMOVE;
     80 
     81 	if (momy > MAXMOVE)
     82 		momy = MAXMOVE;
     83 	else if (momy < -MAXMOVE)
     84 		momy = -MAXMOVE;
     85 
     86 	/* something fucked up in slidemove, so stairstep */
     87 
     88 	if (P_TryMove (mo, mo->x, mo->y + momy))
     89 	{
     90 		mo->momx = 0;
     91 		mo->momy = momy;
     92 		goto dospecial;
     93 	}
     94 
     95 	if (P_TryMove (mo, mo->x + momx, mo->y))
     96 	{
     97 		mo->momx = momx;
     98 		mo->momy = 0;
     99 		goto dospecial;
    100 	}
    101 
    102 	mo->momx = mo->momy = 0;
    103 
    104 dospecial:
    105 	if (latchedline)
    106 		P_CrossSpecialLine (latchedline, mo);
    107 }
    108 #endif // 0
    109 
    110 /*
    111 ===================
    112 =
    113 = P_PlayerXYMovement
    114 =
    115 ===================
    116 */
    117 
    118 #define	STOPSPEED		0x1000
    119 #define	FRICTION		0xd200  //Jag 0xd240
    120 
    121 void P_PlayerXYMovement (mobj_t *mo) // 80021E20
    122 {
    123     /* */
    124 	/* try to slide along a blocked move */
    125 	/* */
    126     if (!P_TryMove(mo, mo->x + mo->momx, mo->y + mo->momy))
    127         P_SlideMove(mo);
    128 
    129 	/* */
    130 	/* slow down */
    131 	/* */
    132 	if (mo->z > mo->floorz)
    133 		return;		/* no friction when airborne */
    134 
    135 	if (mo->flags & MF_CORPSE)
    136 		if (mo->floorz != mo->subsector->sector->floorheight)
    137 			return;			/* don't stop halfway off a step */
    138 
    139 	if (mo->momx > -STOPSPEED && mo->momx < STOPSPEED &&
    140         mo->momy > -STOPSPEED && mo->momy < STOPSPEED)
    141 	{
    142 		mo->momx = 0;
    143 		mo->momy = 0;
    144 	}
    145 	else
    146 	{
    147 		mo->momx = (mo->momx>>8)*(FRICTION>>8);
    148 		mo->momy = (mo->momy>>8)*(FRICTION>>8);
    149 	}
    150 }
    151 
    152 
    153 /*
    154 ===============
    155 =
    156 = P_PlayerZMovement
    157 =
    158 ===============
    159 */
    160 
    161 void P_PlayerZMovement (mobj_t *mo) // 80021f38
    162 {
    163 	/* */
    164 	/* check for smooth step up */
    165 	/* */
    166 	if (mo->z < mo->floorz)
    167 	{
    168 		mo->player->viewheight -= (mo->floorz - mo->z);
    169 		mo->player->deltaviewheight = (VIEWHEIGHT - mo->player->viewheight) >> 2;
    170 	}
    171 
    172 	/* */
    173 	/* adjust height */
    174 	/* */
    175 	mo->z += mo->momz;
    176 
    177 	/* */
    178 	/* clip movement */
    179 	/* */
    180 	if (mo->z <= mo->floorz)
    181 	{	/* hit the floor */
    182 		if (mo->momz < 0)
    183 		{
    184 			if (mo->momz < -(GRAVITY*2))	/* squat down */
    185 			{
    186 				mo->player->deltaviewheight = mo->momz>>3;
    187 				S_StartSound (mo, sfx_oof);
    188 			}
    189 			mo->momz = 0;
    190 		}
    191 		mo->z = mo->floorz;
    192 	}
    193 	else
    194 	{
    195 		if (mo->momz == 0)
    196 			mo->momz = -(GRAVITY/2);
    197 		else
    198 			mo->momz -= (GRAVITY/4);
    199 	}
    200 
    201 	if (mo->z + mo->height > mo->ceilingz)
    202 	{	/* hit the ceiling */
    203 		if (mo->momz > 0)
    204 			mo->momz = 0;
    205 		mo->z = mo->ceilingz - mo->height;
    206 	}
    207 }
    208 
    209 
    210 /*
    211 ================
    212 =
    213 = P_PlayerMobjThink
    214 =
    215 ================
    216 */
    217 
    218 void P_PlayerMobjThink (mobj_t *mobj) // 80022060
    219 {
    220 	state_t	*st;
    221 	int		state;
    222 
    223 	/* */
    224 	/* momentum movement */
    225 	/* */
    226 	if (mobj->momx || mobj->momy)
    227 		P_PlayerXYMovement (mobj);
    228 
    229     mobj->player->onground = (mobj->z <= mobj->floorz);
    230 
    231 	if ( (mobj->z != mobj->floorz) || mobj->momz)
    232 		P_PlayerZMovement (mobj);
    233 
    234 	/* */
    235 	/* cycle through states, calling action functions at transitions */
    236 	/* */
    237 	if (mobj->tics == -1)
    238 		return;				/* never cycle */
    239 
    240 	mobj->tics--;
    241 
    242 	if (mobj->tics > 0)
    243 		return;				/* not time to cycle yet */
    244 
    245 	state = mobj->state->nextstate;
    246 	st = &states[state];
    247 
    248 	mobj->state = st;
    249 	mobj->tics = st->tics;
    250 	mobj->sprite = st->sprite;
    251 	mobj->frame = st->frame;
    252 }
    253 
    254 /*============================================================================= */
    255 
    256 
    257 /*
    258 ====================
    259 =
    260 = P_BuildMove
    261 =
    262 ====================
    263 */
    264 
    265 #define MAXSENSIVITY    10
    266 
    267 void P_BuildMove (player_t *player) // 80022154
    268 {
    269 	int         speed, sensitivity;
    270 	int			buttons, oldbuttons;
    271 	mobj_t		*mo;
    272 	buttons_t	*cbutton;
    273 
    274 	cbutton = BT_DATA[0];
    275 	buttons = ticbuttons[0];
    276 	oldbuttons = oldticbuttons[0];
    277 
    278     player->forwardmove = player->sidemove = player->angleturn = 0;
    279 
    280 	speed = (buttons & cbutton->BT_SPEED) > 0;
    281 	sensitivity = 0;
    282 
    283 	/*  */
    284 	/* forward and backward movement  */
    285 	/*  */
    286 	if (cbutton->BT_FORWARD & buttons)
    287     {
    288         player->forwardmove = forwardmove[speed];
    289     }
    290     else if (cbutton->BT_BACK & buttons)
    291     {
    292         player->forwardmove = -forwardmove[speed];
    293     }
    294     else
    295     {
    296         /* Analyze analog stick movement (up / down) */
    297         sensitivity = (int)((buttons) << 24) >> 24;
    298 
    299         if(sensitivity >= MAXSENSIVITY || sensitivity <= -MAXSENSIVITY)
    300         {
    301             player->forwardmove += (forwardmove[1] * sensitivity) / 80;
    302         }
    303     }
    304 
    305 	/*  */
    306 	/* use two stage accelerative turning on the joypad  */
    307 	/*  */
    308 	if (((buttons & cbutton->BT_LEFT) && (oldbuttons & cbutton->BT_LEFT)))
    309 		player->turnheld++;
    310     else if (((buttons & cbutton->BT_RIGHT) && (oldbuttons & cbutton->BT_RIGHT)))
    311 		player->turnheld++;
    312 	else
    313 		player->turnheld = 0;
    314 
    315 	if (player->turnheld >= SLOWTURNTICS)
    316 		player->turnheld = SLOWTURNTICS-1;
    317 
    318     /*  */
    319 	/* strafe movement  */
    320 	/*  */
    321 	if (buttons & cbutton->BT_STRAFELEFT)
    322 	{
    323 	    player->sidemove -= sidemove[speed];
    324 	}
    325 	if (buttons & cbutton->BT_STRAFERIGHT)
    326 	{
    327 		player->sidemove += sidemove[speed];
    328 	}
    329 
    330     if (buttons & cbutton->BT_STRAFE)
    331 	{
    332 		if (buttons & cbutton->BT_LEFT)
    333 		{
    334             player->sidemove = -sidemove[speed];
    335 		}
    336 		else if (buttons & cbutton->BT_RIGHT)
    337 		{
    338             player->sidemove = sidemove[speed];
    339 		}
    340 		else
    341         {
    342             /* Analyze analog stick movement (left / right) */
    343             sensitivity = (int)(((buttons & 0xff00) >> 8) << 24) >> 24;
    344 
    345             if(sensitivity >= MAXSENSIVITY || sensitivity <= -MAXSENSIVITY)
    346             {
    347                 player->sidemove += (sidemove[1] * sensitivity) / 80;
    348             }
    349         }
    350 	}
    351 	else
    352 	{
    353         if (sensitivity == 0)
    354             speed = 0;
    355 
    356         if (cbutton->BT_LEFT & buttons)
    357         {
    358             player->angleturn =  angleturn[player->turnheld + (speed * SLOWTURNTICS)] << 17;
    359         }
    360         else if (cbutton->BT_RIGHT & buttons)
    361         {
    362             player->angleturn = -angleturn[player->turnheld + (speed * SLOWTURNTICS)] << 17;
    363         }
    364         else
    365         {
    366             /* Analyze analog stick movement (left / right) */
    367             sensitivity = (int)(((buttons & 0xff00) >> 8) << 24) >> 24;
    368             sensitivity = -sensitivity;
    369 
    370             if(sensitivity >= MAXSENSIVITY || sensitivity <= -MAXSENSIVITY)
    371             {
    372                 sensitivity = (((M_SENSITIVITY * 800) / 100) + 233) * sensitivity;
    373                 player->angleturn += (sensitivity / 80) << 17;
    374             }
    375         }
    376 	}
    377 
    378 	/* */
    379 	/* if slowed down to a stop, change to a standing frame */
    380 	/* */
    381 	mo = player->mo;
    382 
    383 	if (!mo->momx && !mo->momy && player->forwardmove == 0 && player->sidemove == 0 )
    384 	{	/* if in a walking frame, stop moving */
    385 		if (mo->state == &states[S_002] //S_PLAY_RUN1
    386 		|| mo->state == &states[S_003]  //S_PLAY_RUN2
    387 		|| mo->state == &states[S_004]  //S_PLAY_RUN3
    388 		|| mo->state == &states[S_005]) //S_PLAY_RUN4
    389 			P_SetMobjState (mo, S_001); //S_PLAY
    390 	}
    391 }
    392 
    393 /*
    394 ===============================================================================
    395 
    396 						movement
    397 
    398 ===============================================================================
    399 */
    400 
    401 #define MAXBOB			0x100000		/* 16 pixels of bob */
    402 
    403 /*
    404 ==================
    405 =
    406 = P_Thrust
    407 =
    408 = moves the given origin along a given angle
    409 =
    410 ==================
    411 */
    412 
    413 void P_Thrust (player_t *player, angle_t angle, fixed_t move) // 800225BC
    414 {
    415     angle >>= ANGLETOFINESHIFT;
    416 	player->mo->momx += FixedMul(vblsinframe[0] * move, finecosine[angle]);
    417 	player->mo->momy += FixedMul(vblsinframe[0] * move, finesine[angle]);
    418 }
    419 
    420 
    421 
    422 /*
    423 ==================
    424 =
    425 = P_CalcHeight
    426 =
    427 = Calculate the walking / running height adjustment
    428 =
    429 ==================
    430 */
    431 
    432 void P_CalcHeight (player_t *player) // 80022670
    433 {
    434 	int			angle;
    435 	fixed_t		bob;
    436 	fixed_t		val;
    437 
    438 	/* */
    439 	/* regular movement bobbing (needs to be calculated for gun swing even */
    440 	/* if not on ground) */
    441 	/* OPTIMIZE: tablify angle  */
    442 	/* */
    443 	val = player->mo->momx;
    444 	player->bob = FixedMul(val, val);
    445 	val = player->mo->momy;
    446 	player->bob += FixedMul(val, val);
    447 
    448 	player->bob >>= 2;
    449 	if (player->bob > MAXBOB)
    450 	{
    451 		player->bob = MAXBOB;
    452 	}
    453 
    454 	if (!player->onground)
    455 	{
    456 		player->viewz = player->mo->z + VIEWHEIGHT;
    457 		if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
    458 			player->viewz = player->mo->ceilingz-4*FRACUNIT;
    459 		return;
    460 	}
    461 
    462 	angle = (FINEANGLES/40*ticon)&(FINEANGLES-1);
    463 	bob = FixedMul((player->bob / 2), finesine[angle]);
    464 
    465 	//ST_DebugPrint("bob %x",FixedMul((player->bob / 2), finesine[angle]));
    466 	//ST_DebugPrint("bob2 %x",FixedMul2((player->bob / 2), finesine[angle]));
    467 
    468 	//ST_DebugPrint("bobdiv %x",FixedDiv2(0x49003, 0x2));
    469 	//ST_DebugPrint("bobdiv2 %x",FixedMul3(0x49003, 0x2));
    470 
    471 	/* */
    472 	/* move viewheight */
    473 	/* */
    474 	if (player->playerstate == PST_LIVE)
    475 	{
    476 		player->viewheight += player->deltaviewheight;
    477 		if (player->viewheight > VIEWHEIGHT)
    478 		{
    479 			player->viewheight = VIEWHEIGHT;
    480 			player->deltaviewheight = 0;
    481 		}
    482 		if (player->viewheight < VIEWHEIGHT/2)
    483 		{
    484 			player->viewheight = VIEWHEIGHT/2;
    485 			if (player->deltaviewheight <= 0)
    486 				player->deltaviewheight = 1;
    487 		}
    488 
    489 		if (player->deltaviewheight)
    490 		{
    491 			player->deltaviewheight += FRACUNIT/2;
    492 			if (!player->deltaviewheight)
    493 				player->deltaviewheight = 1;
    494 		}
    495 	}
    496 	player->viewz = player->mo->z + player->viewheight + bob;
    497 	if (player->viewz > player->mo->ceilingz-4*FRACUNIT)
    498 		player->viewz = player->mo->ceilingz-4*FRACUNIT;
    499 }
    500 
    501 /*
    502 =================
    503 =
    504 = P_MovePlayer
    505 =
    506 =================
    507 */
    508 
    509 void P_MovePlayer (player_t *player) // 8002282C
    510 {
    511 	player->mo->angle += vblsinframe[0] * player->angleturn;
    512 
    513 	if(player->onground)
    514     {
    515         if (player->forwardmove)
    516             P_Thrust (player, player->mo->angle, player->forwardmove);
    517         if (player->sidemove)
    518             P_Thrust (player, player->mo->angle-ANG90, player->sidemove);
    519     }
    520 
    521 	if ((player->forwardmove || player->sidemove) && player->mo->state == &states[S_001])//S_PLAY
    522 		P_SetMobjState (player->mo, S_002);//S_PLAY_RUN1
    523 }
    524 
    525 
    526 /*
    527 =================
    528 =
    529 = P_DeathThink
    530 =
    531 =================
    532 */
    533 
    534 void P_DeathThink (player_t *player) // 80022914
    535 {
    536 	angle_t		angle, delta;
    537 
    538 	P_MovePsprites (player);
    539 
    540 	/* fall to the ground */
    541 	if (player->viewheight > 8*FRACUNIT)
    542 		player->viewheight -= FRACUNIT;
    543 
    544 	player->onground = (player->mo->z <= player->mo->floorz);
    545 
    546 	P_CalcHeight (player);
    547 
    548 	if (player->attacker && player->attacker != player->mo)
    549 	{
    550 		angle = R_PointToAngle2 (player->mo->x, player->mo->y, player->attacker->x, player->attacker->y);
    551 		delta = angle - player->mo->angle;
    552 		if (delta < ANG5 || delta > (unsigned)-ANG5)
    553 		{	/* looking at killer, so fade damage flash down */
    554 			player->mo->angle = angle;
    555 			if (player->damagecount)
    556 				player->damagecount--;
    557 		}
    558 		else if (delta < ANG180)
    559 			player->mo->angle += ANG5;
    560 		else
    561 			player->mo->angle -= ANG5;
    562 	}
    563 	else if (player->damagecount)
    564 		player->damagecount--;
    565 
    566 	/* mocking text */
    567     if ((ticon - deathmocktics) > MAXMOCKTIME)
    568     {
    569         player->messagetic = MSGTICS;
    570         player->message = mockstrings[P_Random() % 12];
    571         deathmocktics = ticon;
    572     }
    573 
    574 	if (((ticbuttons[0] & (PAD_A|PAD_B|ALL_TRIG|ALL_CBUTTONS)) != 0) &&
    575         (player->viewheight <= 8*FRACUNIT))
    576     {
    577 		player->playerstate = PST_REBORN;
    578     }
    579 
    580     if (player->bonuscount)
    581         player->bonuscount -= 1;
    582 
    583     // [d64] - recoil pitch from weapons
    584     if (player->recoilpitch)
    585         player->recoilpitch = (((player->recoilpitch << 2) - player->recoilpitch) >> 2);
    586 
    587     if(player->bfgcount)
    588     {
    589         player->bfgcount -= 6;
    590 
    591         if(player->bfgcount < 0)
    592             player->bfgcount = 0;
    593     }
    594 }
    595 
    596 /*
    597 ===============================================================================
    598 =
    599 = P_PlayerInSpecialSector
    600 =
    601 = Called every tic frame that the player origin is in a special sector
    602 =
    603 ===============================================================================
    604 */
    605 
    606 void P_PlayerInSpecialSector (player_t *player, sector_t *sec) // 80022B1C
    607 {
    608     fixed_t speed;
    609 
    610 	if (player->mo->z != sec->floorheight)
    611 		return;		/* not all the way down yet */
    612 
    613     if(sec->flags & MS_SECRET)
    614     {
    615         player->secretcount++;
    616         player->message = "You found a secret area!";
    617         player->messagetic = MSGTICS;
    618         sec->flags &= ~MS_SECRET;
    619     }
    620 
    621     if(sec->flags & MS_DAMAGEX5)    /* NUKAGE DAMAGE */
    622     {
    623         if(!player->powers[pw_ironfeet])
    624         {
    625             if ((gamevbls < (int)gametic) && !(gametic & 31))
    626                   P_DamageMobj(player->mo, NULL, NULL, 5);
    627         }
    628     }
    629 
    630     if(sec->flags & MS_DAMAGEX10)    /* HELLSLIME DAMAGE */
    631     {
    632         if(!player->powers[pw_ironfeet])
    633         {
    634             if ((gamevbls < (int)gametic) && !(gametic & 31))
    635                   P_DamageMobj(player->mo, NULL, NULL, 10);
    636         }
    637     }
    638 
    639     if(sec->flags & MS_DAMAGEX20)    /* SUPER HELLSLIME DAMAGE */
    640     {
    641         if(!player->powers[pw_ironfeet] || (P_Random() < 5))
    642         {
    643             if ((gamevbls < (int)gametic) && !(gametic & 31))
    644                   P_DamageMobj(player->mo, NULL, NULL, 20);
    645         }
    646     }
    647 
    648     if(sec->flags & MS_SCROLLFLOOR)
    649     {
    650         if(sec->flags & MS_SCROLLFAST)
    651             speed = 0x3000;
    652         else
    653             speed = 0x1000;
    654 
    655         if(sec->flags & MS_SCROLLLEFT)
    656         {
    657             P_Thrust(player, ANG180, speed);
    658         }
    659         else if(sec->flags & MS_SCROLLRIGHT)
    660         {
    661             P_Thrust(player, 0, speed);
    662         }
    663 
    664         if(sec->flags & MS_SCROLLUP)
    665         {
    666             P_Thrust(player, ANG90, speed);
    667         }
    668         else if(sec->flags & MS_SCROLLDOWN)
    669         {
    670             P_Thrust(player, ANG270, speed);
    671         }
    672     }
    673 }
    674 
    675 /*
    676 =================
    677 =
    678 = P_PlayerThink
    679 =
    680 =================
    681 */
    682 
    683 void P_PlayerThink (player_t *player) // 80022D60
    684 {
    685 	int		     buttons, oldbuttons;
    686 	buttons_t    *cbutton;
    687 	weapontype_t weapon;
    688 	sector_t     *sec;
    689 
    690 	buttons = ticbuttons[0];
    691 	oldbuttons = oldticbuttons[0];
    692 	cbutton = BT_DATA[0];
    693 
    694 	/* */
    695 	/* check for weapon change */
    696 	/* */
    697 	if (player->playerstate == PST_LIVE)
    698 	{
    699 		weapon = player->pendingweapon;
    700 		if (weapon == wp_nochange)
    701 			weapon = player->readyweapon;
    702 
    703 		if ((buttons & cbutton->BT_WEAPONBACKWARD) && !(oldbuttons & cbutton->BT_WEAPONBACKWARD))
    704 		{
    705             if (weapon == wp_chainsaw)
    706             {
    707                 player->pendingweapon = wp_fist;
    708             }
    709             else
    710             {
    711                 if((int)(weapon-1) >= wp_chainsaw)
    712                 {
    713                     while(--weapon >= wp_chainsaw && !player->weaponowned[weapon]);
    714                 }
    715 
    716                 if((int)weapon >= wp_chainsaw)
    717                     player->pendingweapon = weapon;
    718             }
    719 		}
    720 		else if ((buttons & cbutton->BT_WEAPONFORWARD) && !(oldbuttons & cbutton->BT_WEAPONFORWARD))
    721 		{
    722 		    if((int)(weapon+1) < NUMWEAPONS)
    723             {
    724                 while(++weapon < NUMWEAPONS && !player->weaponowned[weapon]);
    725             }
    726 
    727             if((int)weapon < NUMWEAPONS)
    728                 player->pendingweapon = weapon;
    729 		}
    730 	}
    731 
    732 	if (!gamepaused)
    733 	{
    734 		P_PlayerMobjThink(player->mo);
    735 		P_BuildMove(player);
    736 
    737         sec = player->mo->subsector->sector;
    738         if (sec->flags & (MS_SECRET | MS_DAMAGEX5 | MS_DAMAGEX10 | MS_DAMAGEX20 | MS_SCROLLFLOOR))
    739             P_PlayerInSpecialSector(player, sec);
    740 
    741 		if (player->playerstate == PST_DEAD)
    742 		{
    743 			P_DeathThink(player);
    744 			return;
    745 		}
    746 
    747 		/* */
    748 		/* chain saw run forward */
    749 		/* */
    750 		if (player->mo->flags & MF_JUSTATTACKED)
    751 		{
    752 			player->angleturn = 0;
    753 			player->forwardmove = 0xc800;
    754 			player->sidemove = 0;
    755 			player->mo->flags &= ~MF_JUSTATTACKED;
    756 		}
    757 
    758 		/* */
    759 		/* move around */
    760 		/* reactiontime is used to prevent movement for a bit after a teleport */
    761 		/* */
    762 
    763 		if (player->mo->reactiontime)
    764 			player->mo->reactiontime--;
    765 		else
    766 			P_MovePlayer(player);
    767 
    768 		P_CalcHeight(player);
    769 
    770 		/* */
    771 		/* check for use */
    772 		/* */
    773 
    774 		if ((buttons & cbutton->BT_USE))
    775 		{
    776 			if (player->usedown == false)
    777 			{
    778 				P_UseLines(player);
    779 				player->usedown = true;
    780 			}
    781 		}
    782 		else
    783         {
    784 			player->usedown = false;
    785         }
    786 
    787 		if (buttons & cbutton->BT_ATTACK)
    788 		{
    789 			P_SetMobjState(player->mo, S_006);//S_PLAY_ATK1
    790 			player->attackdown++;
    791 		}
    792 		else
    793         {
    794 			player->attackdown = 0;
    795         }
    796 
    797 		/* */
    798 		/* cycle psprites */
    799 		/* */
    800 
    801 		P_MovePsprites(player);
    802 
    803 		/* */
    804 		/* counters */
    805 		/* */
    806 
    807 		if (gamevbls < gametic)
    808 		{
    809 			if (player->powers[pw_strength] > 1)
    810 				player->powers[pw_strength]--;	/* strength counts down to diminish fade */
    811 
    812 			if (player->powers[pw_invulnerability])
    813 				player->powers[pw_invulnerability]--;
    814 
    815 			if (player->powers[pw_invisibility])
    816 			{
    817 				player->powers[pw_invisibility]--;
    818 				if (!player->powers[pw_invisibility])
    819 				{
    820 					player->mo->flags &= ~MF_SHADOW;
    821 				}
    822 				else if ((player->powers[pw_invisibility] < 61) && !(player->powers[pw_invisibility] & 7))
    823                 {
    824                     player->mo->flags ^= MF_SHADOW;
    825                 }
    826 			}
    827 
    828             if (player->powers[pw_infrared])
    829                 player->powers[pw_infrared]--;
    830 
    831             if (player->powers[pw_ironfeet])
    832                 player->powers[pw_ironfeet]--;
    833 
    834             if (player->damagecount)
    835                 player->damagecount--;
    836 
    837             if (player->bonuscount)
    838                 player->bonuscount--;
    839 
    840             // [d64] - recoil pitch from weapons
    841             if (player->recoilpitch)
    842                 player->recoilpitch = (((player->recoilpitch << 2) - player->recoilpitch) >> 2);
    843 
    844             if(player->bfgcount)
    845             {
    846                 player->bfgcount -= 6;
    847 
    848                 if(player->bfgcount < 0)
    849                     player->bfgcount = 0;
    850             }
    851 		}
    852 	}
    853 }