p_misc.c (19669B)
1 /* p_misc.c */ 2 3 #include "doomdef.h" 4 #include "p_local.h" 5 #include "r_local.h" 6 7 /* 8 ============================================================================== 9 10 AIM CAMERA 11 12 ============================================================================== 13 */ 14 15 #define CAMAIMANGLE ANG5 16 17 void T_AimCamera(aimcamera_t *camera) // 8000DE60 18 { 19 angle_t delta; 20 angle_t newangle; 21 angle_t angle; 22 23 if((cameratarget != camera->viewmobj) || (cameratarget == players[0].mo)) 24 { 25 P_RemoveThinker(&camera->thinker); 26 return; 27 } 28 29 /* adjust angle */ 30 newangle = R_PointToAngle2(cameratarget->x, cameratarget->y, players[0].mo->x, players[0].mo->y); 31 angle = cameratarget->angle; 32 delta = (newangle - angle); 33 34 if ((delta < CAMAIMANGLE) || (delta > -CAMAIMANGLE)) { 35 cameratarget->angle = newangle; 36 } 37 else if (delta < ANG180) { 38 cameratarget->angle = angle + CAMAIMANGLE; 39 } 40 else { 41 cameratarget->angle = angle - CAMAIMANGLE; 42 } 43 } 44 45 int P_SetAimCamera(line_t *line, boolean aim) // 8000DF20 46 { 47 aimcamera_t *camera; 48 mobj_t *mo; 49 50 if (demorecording == false) 51 { 52 for (mo = mobjhead.next; mo != &mobjhead; mo = mo->next) 53 { 54 if((line->tag != mo->tid)) 55 continue; /* not matching the tid */ 56 57 if(line->tag == cameratarget->tid) 58 continue; /* skip if cameratarget matches tag */ 59 60 cameratarget = mo; 61 if ((cameratarget != players[0].mo) && (aim)) 62 { 63 mo->angle = R_PointToAngle2(mo->x, mo->y, players[0].mo->x, players[0].mo->y); 64 65 camera = Z_Malloc(sizeof(*camera), PU_LEVSPEC, NULL); 66 P_AddThinker(&camera->thinker); 67 camera->thinker.function = T_AimCamera; 68 camera->viewmobj = mo; 69 } 70 71 return 1; 72 } 73 } 74 75 return 0; 76 } 77 78 /* 79 ============================================================================== 80 81 EV_SpawnTrapMissile 82 83 ============================================================================== 84 */ 85 86 int EV_SpawnTrapMissile(line_t *line, mobj_t *target, mobjtype_t type) // 8000E02C 87 { 88 mobj_t* mo; 89 mobj_t* th; 90 int ok; 91 92 ok = 0; 93 for(mo = mobjhead.next; mo != &mobjhead; mo = mo->next) 94 { 95 if(mo->type != MT_DEST_PROJECTILE) 96 continue; /* not a dart projector */ 97 98 if((line->tag != mo->tid)) 99 continue; /* not matching the tid */ 100 101 ok = 1; 102 103 if(type == MT_PROJ_TRACER) 104 { 105 th = P_SpawnMissile(mo, target, 0, 0, (32*FRACUNIT), MT_PROJ_TRACER); 106 th->x = (th->x + th->momx); 107 th->y = (th->y + th->momy); 108 th->tracer = target; 109 } 110 else if(type == MT_PROJ_DART) 111 { 112 th = P_SpawnMissile(mo, NULL, 0, 0, 0, MT_PROJ_DART); 113 } 114 } 115 116 return ok; 117 } 118 119 /* 120 ============================================================================== 121 122 EXIT DELAY 123 124 ============================================================================== 125 */ 126 127 /* 128 ================================================================================ 129 = 130 = P_SpawnDelayTimer 131 = 132 = Exclusive Psx Doom / Doom 64 133 = 134 =============================================================================== 135 */ 136 137 void P_SpawnDelayTimer(int tics, void(*action)()) // 8000E160 138 { 139 delay_t *timer; 140 141 timer = Z_Malloc(sizeof(*timer), PU_LEVSPEC, NULL); 142 P_AddThinker(&timer->thinker); 143 timer->thinker.function = T_CountdownTimer; 144 timer->tics = tics; 145 timer->finishfunc = action; 146 } 147 148 /* 149 ================================================================================ 150 = 151 = T_CountdownTimer 152 = 153 = Exclusive Psx Doom / Doom 64 154 = 155 =============================================================================== 156 */ 157 158 void T_CountdownTimer(delay_t *timer) // 8000E1CC 159 { 160 if((--timer->tics) <= 0) 161 { 162 if (timer->finishfunc) 163 timer->finishfunc(); 164 165 P_RemoveThinker(&timer->thinker); 166 } 167 } 168 169 /* 170 ================================================================================ 171 = 172 = P_ExitLevel 173 = 174 = Exclusive Psx Doom / Doom 64 175 = 176 =============================================================================== 177 */ 178 179 void P_ExitLevel(void) // 8000E220 180 { 181 nextmap = gamemap + 1; 182 P_SpawnDelayTimer(15, G_CompleteLevel); 183 } 184 185 /* 186 ================================================================================ 187 = 188 = P_SecretExitLevel 189 = 190 = Exclusive Psx Doom / Doom 64 191 = 192 =============================================================================== 193 */ 194 195 void P_SecretExitLevel(int map) // 8000E25C 196 { 197 int delaytics; 198 199 if (map < LASTLEVEL) 200 delaytics = 15; 201 else 202 delaytics = 120; 203 204 nextmap = map; 205 P_SpawnDelayTimer(delaytics, G_CompleteLevel); 206 } 207 208 /* 209 ==================================================================== 210 211 TELEPORTATION 212 The teleportation functions for some reason, were in the middle of 213 the other functions in this file, I move them in the corresponding 214 file p_telept.c 215 216 ==================================================================== 217 */ 218 219 //void P_Telefrag (mobj_t *thing, fixed_t x, fixed_t y) // 8000E29C 220 //int EV_Teleport( line_t *line, mobj_t *thing ) // 8000E3A0 221 //int EV_SilentTeleport( line_t *line, mobj_t *thing ) // 8000E5C0 222 223 /* --------------------------------------------------------------------------------- */ 224 225 int P_ModifyLineFlags(line_t *line, int tag) // 8000E6BC 226 { 227 line_t *line1, *line2; 228 int i; 229 230 line2 = lines; 231 for (i = 0; i < numlines; i++, line2++) 232 { 233 if (line2->tag == tag) break; 234 } 235 236 if (i < numlines) 237 { 238 line1 = lines; 239 for (i = 0; i < numlines; i++, line1++) 240 { 241 if (line->tag == line1->tag) 242 { 243 if (line1->flags & ML_TWOSIDED) 244 { 245 line1->flags = (line2->flags | ML_TWOSIDED); 246 } 247 else 248 { 249 line1->flags = line2->flags; 250 line1->flags &= ~ML_TWOSIDED; 251 } 252 } 253 } 254 255 return 1; 256 } 257 258 return 0; 259 } 260 261 int P_ModifyLineData(line_t *line, int tag) // 8000E780 262 { 263 line_t *line1, *line2; 264 int i; 265 266 line2 = lines; 267 for (i = 0; i < numlines; i++, line2++) 268 { 269 if (line2->tag == tag) break; 270 } 271 272 if (i < numlines) 273 { 274 line1 = lines; 275 for (i = 0; i < numlines; i++, line1++) 276 { 277 if (line->tag == line1->tag) 278 { 279 line1->special = line2->special; 280 } 281 } 282 283 return 1; 284 } 285 286 return 0; 287 } 288 289 int P_ModifyLineTexture(line_t *line, int tag) // 8000E82C 290 { 291 line_t *line1, *line2; 292 int i; 293 294 line2 = lines; 295 for (i = 0; i < numlines; i++, line2++) 296 { 297 if (line2->tag == tag) break; 298 } 299 300 if (i < numlines) 301 { 302 line1 = lines; 303 for (i = 0; i < numlines; i++, line1++) 304 { 305 if (line->tag == line1->tag) 306 { 307 sides[line1->sidenum[0]].toptexture = sides[line2->sidenum[0]].toptexture; 308 sides[line1->sidenum[0]].bottomtexture = sides[line2->sidenum[0]].bottomtexture; 309 sides[line1->sidenum[0]].midtexture = sides[line2->sidenum[0]].midtexture; 310 } 311 } 312 313 return 1; 314 } 315 316 return 0; 317 } 318 319 int P_ModifySector(line_t *line, int tag, int type) // 8000E928 320 { 321 sector_t *sec1, *sec2; 322 int secnum; 323 int rtn; 324 325 secnum = P_FindSectorFromLineTag(tag, 0); 326 327 if(secnum == -1) 328 return 0; 329 330 sec2 = §ors[secnum]; 331 332 secnum = -1; 333 rtn = 0; 334 335 while((secnum = P_FindSectorFromLineTag(line->tag, secnum)) >= 0) 336 { 337 sec1 = §ors[secnum]; 338 rtn = 1; 339 340 switch(type) 341 { 342 case mods_flags: 343 sec1->flags = sec2->flags; 344 break; 345 case mods_special: 346 if (sec1->special != sec2->special) 347 { 348 sec1->special = sec2->special; 349 P_AddSectorSpecial(sec1); 350 } 351 break; 352 case mods_flats: 353 sec1->ceilingpic = sec2->ceilingpic; 354 sec1->floorpic = sec2->floorpic; 355 break; 356 case mods_lights: 357 sec1->colors[0] = sec2->colors[0]; 358 sec1->colors[1] = sec2->colors[1]; 359 sec1->colors[2] = sec2->colors[2]; 360 sec1->colors[3] = sec2->colors[3]; 361 sec1->colors[4] = sec2->colors[4]; 362 break; 363 default: 364 break; 365 } 366 } 367 368 return rtn; 369 } 370 371 void T_FadeThinker(fade_t *fade) // 8000EACC 372 { 373 mobj_t *mo; 374 375 mo = fade->mobj; 376 mo->alpha += fade->amount; 377 378 if (fade->amount > 0) 379 { 380 if (mo->alpha < fade->destAlpha) 381 return; 382 383 mo->alpha = fade->destAlpha; 384 mo->flags |= fade->flagReserve; 385 P_RemoveThinker(&fade->thinker); 386 } 387 else if ((fade->destAlpha < mo->alpha) == 0) 388 { 389 mo->alpha = fade->destAlpha; 390 P_RemoveThinker(&fade->thinker); 391 392 if (fade->destAlpha == 0) 393 P_RemoveMobj(mo); 394 } 395 396 /*if (fade->amount <= 0) 397 { 398 if (mo->alpha <= fade->destAlpha) 399 { 400 mo->alpha = fade->destAlpha; 401 P_RemoveThinker(&fade->thinker); 402 403 if (fade->destAlpha == 0) 404 P_RemoveMobj(mo); 405 } 406 } 407 else if (mo->alpha >= fade->destAlpha) 408 { 409 mo->alpha = fade->destAlpha; 410 mo->flags |= fade->flagReserve; 411 P_RemoveThinker(&fade->thinker); 412 }*/ 413 } 414 415 extern mobj_t *P_SpawnMapThing (mapthing_t *mthing); 416 extern mapthing_t *spawnlist; // 800A5D74 417 extern int spawncount; // 800A5D78 418 419 int EV_SpawnMobjTemplate(int tag) // 8000EB8C 420 { 421 mobj_t *mobj; 422 fade_t *fade; 423 mapthing_t *mthing; 424 int i; 425 int rtn; 426 427 rtn = 0; 428 mthing = spawnlist; 429 for (i = 0; i < spawncount; i++, mthing++) 430 { 431 if(mthing->tid != tag) 432 continue; /* find matching tid */ 433 434 if(!(mobj = P_SpawnMapThing(mthing))) 435 continue; /* setup spawning */ 436 437 rtn = 1; 438 if (mobj->type == MT_DEMON2) 439 { 440 mobj->alpha = 48; 441 mobj->flags |= MF_SHADOW; 442 } 443 else 444 { 445 fade = Z_Malloc (sizeof(*fade), PU_LEVSPEC, NULL); 446 P_AddThinker (&fade->thinker); 447 fade->thinker.function = T_FadeThinker; 448 fade->mobj = mobj; 449 fade->amount = 8; 450 fade->destAlpha = mobj->alpha; 451 fade->flagReserve = mobj->flags & (MF_SPECIAL|MF_SOLID|MF_SHOOTABLE); 452 453 if (mobj->flags & MF_SHOOTABLE) 454 { 455 mobj->flags &= ~MF_SHOOTABLE; 456 } 457 else 458 { 459 mobj->flags &= ~(MF_SPECIAL|MF_SOLID|MF_SHOOTABLE); 460 } 461 mobj->alpha = 0; 462 } 463 464 S_StartSound(mobj, sfx_spawn); 465 } 466 467 return rtn; 468 } 469 470 int EV_FadeOutMobj(int tag) // 8000ED08 471 { 472 fade_t *fade; 473 mobj_t *mo; 474 mobj_t *pmVar1; 475 int rtn; 476 477 rtn = 0; 478 479 for (mo=mobjhead.next ; mo != &mobjhead ; mo=mo->next) 480 { 481 if(tag != mo->tid) 482 continue; /* not matching the tid */ 483 484 rtn = 1; 485 mo->flags &= ~(MF_SPECIAL|MF_SOLID|MF_SHOOTABLE); 486 487 fade = Z_Malloc (sizeof(*fade), PU_LEVSPEC, 0); 488 P_AddThinker (&fade->thinker); 489 fade->thinker.function = T_FadeThinker; 490 fade->mobj = mo; 491 fade->amount = -8; 492 fade->destAlpha = 0; 493 } 494 495 return rtn; 496 } 497 498 void T_Quake(quake_t *quake) // 8000EDE8 499 { 500 if((--quake->tics) == 0) 501 { 502 S_StopSound(NULL, sfx_quake); 503 quakeviewy = 0; 504 quakeviewx = 0; 505 P_RemoveThinker(&quake->thinker); 506 return; 507 } 508 509 quakeviewy = (((P_Random() & 1) << 18) - (2*FRACUNIT)); 510 quakeviewx = (((P_Random() & 1) << 24) - (128*FRACUNIT)); 511 } 512 513 void P_SpawnQuake(int tics) // 8000EE7C 514 { 515 quake_t *quake; 516 517 quake = Z_Malloc (sizeof(*quake), PU_LEVSPEC, 0); 518 P_AddThinker (&quake->thinker); 519 quake->thinker.function = T_Quake; 520 quake->tics = tics; 521 522 S_StopSound(NULL, sfx_quake); 523 } 524 525 int P_RandomLineTrigger(line_t *line,mobj_t *thing) // 8000EEE0 526 { 527 line_t *li; 528 int line_idx[16]; 529 int i, count; 530 531 if (activemacro) 532 return 0; 533 534 count = 0; 535 536 li = lines; 537 for(i = 0; ((i < numlines)&&(count < 16)); i++, li++) 538 { 539 /* special 240 -> Execute random line trigger */ 540 if(((line->tag == li->tag) && (li != line)) && (SPECIALMASK(li->special) != 240)) 541 { 542 line_idx[count] = i; 543 count++; 544 } 545 } 546 547 if(!count) 548 return 0; 549 550 return P_UseSpecialLine(&lines[line_idx[P_Random()%count]], thing); 551 } 552 553 #define CAMMOVESPEED 164 554 #define CAMTRACEANGLE ANG1 555 556 void T_MoveCamera(movecamera_t *camera) // 8000F014 557 { 558 angle_t delta; 559 angle_t newangle; 560 angle_t angle; 561 int dist; 562 mobj_t *mo; 563 564 int iVar1; 565 566 /* adjust angle */ 567 newangle = R_PointToAngle2(cameratarget->x, cameratarget->y, camera->x, camera->y); 568 angle = cameratarget->angle; 569 delta = newangle - angle; 570 if ((delta < CAMTRACEANGLE) || (delta > -CAMTRACEANGLE)) { 571 cameratarget->angle = newangle; 572 } 573 else if (delta < ANG180) { 574 cameratarget->angle = angle + CAMTRACEANGLE; 575 } 576 else { 577 cameratarget->angle = angle - CAMTRACEANGLE; 578 } 579 580 /* adjust pitch */ 581 dist = P_AproxDistance(cameratarget->x - camera->x, cameratarget->y - camera->y); 582 if(dist >= (48*FRACUNIT)) 583 { 584 newangle = R_PointToAngle2(0, cameratarget->z, dist, camera->z); 585 angle = camviewpitch; 586 delta = newangle - angle; 587 if ((delta < CAMTRACEANGLE) || (delta > -CAMTRACEANGLE)) { 588 camviewpitch = newangle; 589 } 590 else if (delta < ANG180) { 591 camviewpitch = angle + CAMTRACEANGLE; 592 } 593 else { 594 camviewpitch = angle - CAMTRACEANGLE; 595 } 596 } 597 598 /* adjust camera position */ 599 600 camera->tic++; 601 if (camera->tic < CAMMOVESPEED) 602 { 603 cameratarget->x = cameratarget->x + camera->slopex; 604 cameratarget->y = cameratarget->y + camera->slopey; 605 cameratarget->z = cameratarget->z + camera->slopez; 606 return; 607 } 608 609 /* jump to next camera spot */ 610 for(mo = mobjhead.next; mo != &mobjhead; mo = mo->next) 611 { 612 if(camera->current != mo->tid) 613 continue; /* must match tid */ 614 615 if(mo->type != MT_CAMERA) 616 continue; /* not a camera */ 617 618 camera->slopex = (mo->x - cameratarget->x) / CAMMOVESPEED; 619 camera->slopey = (mo->y - cameratarget->y) / CAMMOVESPEED; 620 camera->slopez = (mo->z - cameratarget->z) / CAMMOVESPEED; 621 622 camera->tic = 0; 623 camera->current++; 624 return; 625 } 626 } 627 628 void P_SetMovingCamera(line_t *line) // 8000F2F8 629 { 630 movecamera_t *camera; 631 mobj_t *mo; 632 633 camera = Z_Malloc (sizeof(*camera), PU_LEVSPEC, 0); 634 P_AddThinker (&camera->thinker); 635 camera->thinker.function = T_MoveCamera; 636 637 for(mo = mobjhead.next; mo != &mobjhead; mo = mo->next) 638 { 639 if(mo->tid != line->tag) 640 continue; /* not matching the tid */ 641 642 if(mo->type != MT_CAMERA) 643 continue; /* not a camera */ 644 645 /* setup moving camera */ 646 camera->x = mo->x; 647 camera->y = mo->y; 648 camera->z = mo->z; 649 camera->tic = CAMMOVESPEED; 650 camera->current = mo->tid + 1; 651 652 /* set camera target */ 653 mo->angle = cameratarget->angle; 654 mo->x = cameratarget->x; 655 mo->y = cameratarget->y; 656 cameratarget = mo; 657 return; 658 } 659 } 660 661 void P_RefreshBrightness(void) // 8000f410 662 { 663 int factor; 664 665 factor = brightness + 100; 666 if (factor < infraredFactor) { 667 factor = infraredFactor; 668 } 669 670 P_SetLightFactor(factor); 671 } 672 673 extern maplights_t *maplights; // 800A5EA4 674 675 void P_SetLightFactor(int lightfactor) // 8000F458 676 { 677 register u32 fpstat, fpstatset; 678 679 float l_flt; 680 light_t *light; 681 maplights_t *maplight; 682 int base_r, base_g, base_b; 683 int r, g, b; 684 int h, s, v; 685 int factor; 686 int i; 687 688 maplight = maplights; 689 light = lights; 690 for(i = 0; i < numlights; i++) 691 { 692 if (i > 255) 693 { 694 LightGetHSV(maplight->r, maplight->g, maplight->b, &h, &s, &v); 695 maplight++; 696 factor = v; 697 } 698 else 699 { 700 factor = i; 701 } 702 703 // fetch the current floating-point control/status register 704 fpstat = __osGetFpcCsr(); 705 // enable round to negative infinity for floating point 706 fpstatset = (fpstat | FPCSR_RM_RM) ^ 2; 707 // _Disable_ unimplemented operation exception for floating point. 708 __osSetFpcCsr(fpstatset); 709 710 l_flt = (float)factor * ((float)lightfactor / 100.0); 711 712 v = (int)l_flt; 713 if (v > 255) { 714 v = 255; 715 } 716 717 if (i > 255) 718 { 719 LightGetRGB(h, s, v, &r, &g, &b); 720 base_r = r; 721 base_g = g; 722 base_b = b; 723 /*base_r = maplight->r; 724 base_g = maplight->g; 725 base_b = maplight->b; 726 maplight++;*/ 727 } 728 else 729 { 730 base_r = v; 731 base_g = v; 732 base_b = v; 733 734 /* base_r = i; 735 base_g = i; 736 base_b = i;*/ 737 } 738 739 // [GEC] New Cheat Codes 740 if (players[0].cheats & CF_FULLBRIGHT) 741 { 742 base_r = 255; 743 base_g = 255; 744 base_b = 255; 745 } 746 else if (players[0].cheats & CF_NOCOLORS) 747 { 748 base_r = v & 255; 749 base_g = v & 255; 750 base_b = v & 255; 751 } 752 753 light->rgba = PACKRGBA(base_r, base_g, base_b, 255); 754 light++; 755 } 756 } 757 758 void T_FadeInBrightness(fadebright_t *fb) // 8000f610 759 { 760 fb->factor += 2; 761 if (fb->factor >= (brightness + 100)) 762 { 763 fb->factor = (brightness + 100); 764 P_RemoveThinker(&fb->thinker); 765 } 766 767 P_SetLightFactor(fb->factor); 768 } 769 770 int P_ModifyMobjFlags(int tid, int flags) // 8000F674 771 { 772 mobj_t *mo; 773 int ok; 774 775 ok = 0; 776 for(mo = mobjhead.next; mo != &mobjhead; mo = mo->next) 777 { 778 if(mo->tid != tid) 779 continue; /* not matching the tid */ 780 781 ok = 1; 782 mo->flags &= ~flags; 783 } 784 785 return ok; 786 } 787 788 int P_AlertTaggedMobj(int tid, mobj_t *activator) // 8000F6C4 789 { 790 mobj_t *mo; 791 state_t *st; 792 int ok; 793 794 ok = 0; 795 for(mo = mobjhead.next; mo != &mobjhead; mo = mo->next) 796 { 797 if(mo->tid != tid) 798 continue; /* not matching the tid */ 799 800 if(mo->info->seestate == S_000) 801 continue; 802 803 mo->threshold = 0; 804 mo->target = activator; 805 ok = 1; 806 807 st = &states[mo->info->seestate]; 808 809 mo->state = st; 810 mo->tics = st->tics; 811 mo->sprite = st->sprite; 812 mo->frame = st->frame; 813 } 814 815 return ok; 816 } 817 818 void T_MobjExplode(mobjexp_t *exp) // 8000F76C 819 { 820 fixed_t x; 821 fixed_t y; 822 fixed_t z; 823 mobj_t *mo; 824 825 if((--exp->delay) <= 0) 826 { 827 exp->delay = exp->delaydefault; 828 829 x = (((P_Random() - P_Random()) << 14) + exp->mobj->x); 830 y = (((P_Random() - P_Random()) << 14) + exp->mobj->y); 831 z = (((P_Random() - P_Random()) << 14) + exp->mobj->z); 832 833 mo = P_SpawnMobj(x, y, z + (exp->mobj->info->height >> 1), MT_EXPLOSION2); 834 835 if((exp->lifetime & 1)) 836 S_StartSound(mo, sfx_explode); 837 838 if((--exp->lifetime) == 0) 839 { 840 P_RemoveThinker(&exp->thinker); 841 } 842 } 843 }