wi_stuff.c (23496B)
1 #include <stdio.h> 2 3 #include "m_swap.h" 4 #include "z_zone.h" 5 #include "m_random.h" 6 #include "i_system.h" 7 #include "w_wad.h" 8 #include "g_game.h" 9 #include "r_local.h" 10 #include "s_sound.h" 11 #include "doomstat.h" 12 #include "sounds.h" 13 #include "v_video.h" 14 #include "wi_stuff.h" 15 16 #define NUMEPISODES 4 17 #define NUMMAPS 9 18 #define WI_TITLEY 2 19 #define WI_SPACINGY 33 20 #define SP_STATSX 50 21 #define SP_STATSY 50 22 #define SP_TIMEX 16 23 #define SP_TIMEY (SCREENHEIGHT-32) 24 #define NG_STATSY 50 25 #define NG_STATSX (32 + SHORT(star->width)/2 + 32*!dofrags) 26 #define NG_SPACINGX 64 27 #define DM_MATRIXX 42 28 #define DM_MATRIXY 68 29 #define DM_SPACINGX 40 30 #define DM_TOTALSX 269 31 #define DM_KILLERSX 10 32 #define DM_KILLERSY 100 33 #define DM_VICTIMSX 5 34 #define DM_VICTIMSY 50 35 #define FB 0 36 #define SP_KILLS 0 37 #define SP_ITEMS 2 38 #define SP_SECRET 4 39 #define SP_FRAGS 6 40 #define SP_TIME 8 41 #define SP_PAR ST_TIME 42 #define SP_PAUSE 1 43 #define SHOWNEXTLOCDELAY 4 44 45 46 typedef enum { 47 ANIM_ALWAYS, 48 ANIM_RANDOM, 49 ANIM_LEVEL 50 } animenum_t; 51 52 typedef struct { 53 int x; 54 int y; 55 } point_t; 56 57 typedef struct { 58 animenum_t type; 59 int period; 60 int nanims; 61 point_t loc; 62 int data1; 63 int data2; 64 patch_t* p[3]; 65 int nexttic; 66 int lastdrawn; 67 int ctr; 68 int state; 69 } anim_t; 70 71 static point_t lnodes[NUMEPISODES][NUMMAPS] = { 72 { 73 { 185, 164 }, 74 { 148, 143 }, 75 { 69, 122 }, 76 { 209, 102 }, 77 { 116, 89 }, 78 { 166, 55 }, 79 { 71, 56 }, 80 { 135, 29 }, 81 { 71, 24 } 82 }, 83 { 84 { 254, 25 }, 85 { 97, 50 }, 86 { 188, 64 }, 87 { 128, 78 }, 88 { 214, 92 }, 89 { 133, 130 }, 90 { 208, 136 }, 91 { 148, 140 }, 92 { 235, 158 } 93 }, 94 { 95 { 156, 168 }, 96 { 48, 154 }, 97 { 174, 95 }, 98 { 265, 75 }, 99 { 130, 48 }, 100 { 279, 23 }, 101 { 198, 48 }, 102 { 140, 25 }, 103 { 281, 136 } 104 } 105 }; 106 107 static anim_t epsd0animinfo[] = { 108 { ANIM_ALWAYS, TICRATE/3, 3, { 224, 104 } }, 109 { ANIM_ALWAYS, TICRATE/3, 3, { 184, 160 } }, 110 { ANIM_ALWAYS, TICRATE/3, 3, { 112, 136 } }, 111 { ANIM_ALWAYS, TICRATE/3, 3, { 72, 112 } }, 112 { ANIM_ALWAYS, TICRATE/3, 3, { 88, 96 } }, 113 { ANIM_ALWAYS, TICRATE/3, 3, { 64, 48 } }, 114 { ANIM_ALWAYS, TICRATE/3, 3, { 192, 40 } }, 115 { ANIM_ALWAYS, TICRATE/3, 3, { 136, 16 } }, 116 { ANIM_ALWAYS, TICRATE/3, 3, { 80, 16 } }, 117 { ANIM_ALWAYS, TICRATE/3, 3, { 64, 24 } } 118 }; 119 120 static anim_t epsd1animinfo[] = { 121 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 1 }, 122 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 2 }, 123 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 3 }, 124 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 4 }, 125 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 5 }, 126 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 6 }, 127 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 7 }, 128 { ANIM_LEVEL, TICRATE/3, 3, { 192, 144 }, 8 }, 129 { ANIM_LEVEL, TICRATE/3, 1, { 128, 136 }, 8 } 130 }; 131 132 static anim_t epsd2animinfo[] = { 133 { ANIM_ALWAYS, TICRATE/3, 3, { 104, 168 } }, 134 { ANIM_ALWAYS, TICRATE/3, 3, { 40, 136 } }, 135 { ANIM_ALWAYS, TICRATE/3, 3, { 160, 96 } }, 136 { ANIM_ALWAYS, TICRATE/3, 3, { 104, 80 } }, 137 { ANIM_ALWAYS, TICRATE/3, 3, { 120, 32 } }, 138 { ANIM_ALWAYS, TICRATE/4, 3, { 40, 0 } } 139 }; 140 141 static int NUMANIMS[NUMEPISODES] = { 142 sizeof(epsd0animinfo)/sizeof(anim_t), 143 sizeof(epsd1animinfo)/sizeof(anim_t), 144 sizeof(epsd2animinfo)/sizeof(anim_t) 145 }; 146 147 static anim_t *anims[NUMEPISODES] = { 148 epsd0animinfo, 149 epsd1animinfo, 150 epsd2animinfo 151 }; 152 153 static int acceleratestage; 154 static int me; 155 static stateenum_t state; 156 static wbstartstruct_t* wbs; 157 static wbplayerstruct_t* plrs; 158 static int cnt; 159 static int bcnt; 160 static int firstrefresh; 161 static int cnt_kills[MAXPLAYERS]; 162 static int cnt_items[MAXPLAYERS]; 163 static int cnt_secret[MAXPLAYERS]; 164 static int cnt_time; 165 static int cnt_par; 166 static int cnt_pause; 167 static patch_t* bg; 168 static patch_t* yah[2]; 169 static patch_t* splat; 170 static patch_t* percent; 171 static patch_t* colon; 172 static patch_t* num[10]; 173 static patch_t* wiminus; 174 static patch_t* finished; 175 static patch_t* entering; 176 static patch_t* sp_secret; 177 static patch_t* kills; 178 static patch_t* secret; 179 static patch_t* items; 180 static patch_t* frags; 181 static patch_t* time; 182 static patch_t* par; 183 static patch_t* sucks; 184 static patch_t* killers; 185 static patch_t* victims; 186 static patch_t* total; 187 static patch_t* star; 188 static patch_t* bstar; 189 static patch_t* p[MAXPLAYERS]; 190 static patch_t* bp[MAXPLAYERS]; 191 static patch_t** lnames; 192 static boolean snl_pointeron = false; 193 static int dm_state; 194 static int dm_frags[MAXPLAYERS][MAXPLAYERS]; 195 static int dm_totals[MAXPLAYERS]; 196 static int cnt_frags[MAXPLAYERS]; 197 static int dofrags; 198 static int ng_state; 199 static int sp_state; 200 201 void 202 WI_slamBackground() 203 { 204 memcpy(screens[0], screens[1], SCREENWIDTH * SCREENHEIGHT); 205 V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT); 206 } 207 208 boolean 209 WI_Responder(event_t* ev) 210 { 211 return false; 212 } 213 214 void 215 WI_drawLF() 216 { 217 int y; 218 219 y = WI_TITLEY; 220 V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->last]->width))/2, y, FB, lnames[wbs->last]); 221 y += (5*SHORT(lnames[wbs->last]->height))/4; 222 V_DrawPatch((SCREENWIDTH - SHORT(finished->width))/2, y, FB, finished); 223 } 224 225 void 226 WI_drawEL() 227 { 228 int y; 229 230 y = WI_TITLEY; 231 V_DrawPatch((SCREENWIDTH - SHORT(entering->width))/2, y, FB, entering); 232 y += (5*SHORT(lnames[wbs->next]->height))/4; 233 V_DrawPatch((SCREENWIDTH - SHORT(lnames[wbs->next]->width))/2, y, FB, lnames[wbs->next]); 234 } 235 236 void 237 WI_drawOnLnode(int n, patch_t* c[]) 238 { 239 int i, left, top, right, bottom; 240 boolean fits; 241 242 fits = false; 243 i = 0; 244 do { 245 left = lnodes[wbs->epsd][n].x - SHORT(c[i]->leftoffset); 246 top = lnodes[wbs->epsd][n].y - SHORT(c[i]->topoffset); 247 right = left + SHORT(c[i]->width); 248 bottom = top + SHORT(c[i]->height); 249 if (left >= 0 && right < SCREENWIDTH && top >= 0 && bottom < SCREENHEIGHT) 250 fits = true; 251 else 252 ++i; 253 } while (!fits && i!=2); 254 if (fits && i<2) 255 V_DrawPatch(lnodes[wbs->epsd][n].x, lnodes[wbs->epsd][n].y, FB, c[i]); 256 else 257 printf("Could not place patch on level %d", n+1); 258 } 259 260 void 261 WI_initAnimatedBack() 262 { 263 anim_t* a; 264 int i; 265 266 if (wbs->epsd > 2) return; 267 for (i = 0; i < NUMANIMS[wbs->epsd]; ++i) { 268 a = &anims[wbs->epsd][i]; 269 a->ctr = -1; 270 if (a->type == ANIM_ALWAYS) a->nexttic = bcnt + 1 + (M_Random()%a->period); 271 if (a->type == ANIM_RANDOM) a->nexttic = bcnt + 1 + a->data2+(M_Random()%a->data1); 272 if (a->type == ANIM_LEVEL) a->nexttic = bcnt + 1; 273 } 274 } 275 276 void 277 WI_updateAnimatedBack() 278 { 279 anim_t* a; 280 int i; 281 282 if (wbs->epsd > 2) 283 return; 284 for (i = 0; i < NUMANIMS[wbs->epsd]; ++i) { 285 a = &anims[wbs->epsd][i]; 286 if (bcnt == a->nexttic) { 287 switch (a->type) { 288 case ANIM_ALWAYS: 289 if (++a->ctr >= a->nanims) 290 a->ctr = 0; 291 a->nexttic = bcnt + a->period; 292 break; 293 case ANIM_RANDOM: 294 a->ctr++; 295 if (a->ctr == a->nanims) { 296 a->ctr = -1; 297 a->nexttic = bcnt+a->data2+(M_Random()%a->data1); 298 } else a->nexttic = bcnt + a->period; 299 break; 300 case ANIM_LEVEL: 301 if (!(state == StatCount && i == 7) && wbs->next == a->data1) { 302 if (++a->ctr == a->nanims) 303 a->ctr--; 304 a->nexttic = bcnt + a->period; 305 } 306 } 307 } 308 } 309 } 310 311 void 312 WI_drawAnimatedBack() 313 { 314 anim_t* a; 315 int i; 316 317 if (wbs->epsd > 2) return; 318 for (i = 0; i < NUMANIMS[wbs->epsd]; ++i) { 319 a = &anims[wbs->epsd][i]; 320 if (a->ctr >= 0) 321 V_DrawPatch(a->loc.x, a->loc.y, FB, a->p[a->ctr]); 322 } 323 } 324 325 int 326 WI_drawNum(int x, int y, int n, int digits) 327 { 328 int fontwidth, neg, temp; 329 330 fontwidth = SHORT(num[0]->width); 331 if (digits < 0) { 332 if (!n) 333 digits = 1; 334 else { 335 digits = 0; 336 for (temp = n; temp; temp /= 10) ++digits; 337 } 338 } 339 neg = n < 0; 340 if (neg) 341 n = -n; 342 if (n == 1994) 343 return 0; 344 while (digits--) { 345 x -= fontwidth; 346 V_DrawPatch(x, y, FB, num[ n % 10 ]); 347 n /= 10; 348 } 349 if (neg) 350 V_DrawPatch(x-=8, y, FB, wiminus); 351 return x; 352 } 353 354 void 355 WI_drawPercent(int x, int y, int p) 356 { 357 if (p < 0) 358 return; 359 V_DrawPatch(x, y, FB, percent); 360 WI_drawNum(x, y, p, -1); 361 } 362 363 void 364 WI_drawTime(int x, int y, int t) 365 { 366 int div, n; 367 368 if (t < 0) 369 return; 370 if (t <= 61*59) { 371 div = 1; 372 do { 373 n = (t / div) % 60; 374 x = WI_drawNum(x, y, n, 2) - SHORT(colon->width); 375 div *= 60; 376 if (div==60 || t / div) 377 V_DrawPatch(x, y, FB, colon); 378 379 } while (t / div); 380 } else V_DrawPatch(x - SHORT(sucks->width), y, FB, sucks); 381 } 382 383 void 384 WI_initShowNextLoc() 385 { 386 state = ShowNextLoc; 387 acceleratestage = 0; 388 cnt = SHOWNEXTLOCDELAY * TICRATE; 389 WI_initAnimatedBack(); 390 } 391 392 void 393 WI_drawShowNextLoc() 394 { 395 int i, last; 396 397 WI_slamBackground(); 398 WI_drawAnimatedBack(); 399 if (wbs->epsd > 2) { 400 WI_drawEL(); 401 return; 402 } 403 last = (wbs->last == 8) ? wbs->next - 1 : wbs->last; 404 for (i = 0; i <= last; ++i) 405 WI_drawOnLnode(i, &splat); 406 if (wbs->didsecret) WI_drawOnLnode(8, &splat); 407 if (snl_pointeron) WI_drawOnLnode(wbs->next, yah); 408 if (wbs->next != 30) WI_drawEL(); 409 } 410 411 void 412 WI_drawNoState() 413 { 414 snl_pointeron = true; 415 WI_drawShowNextLoc(); 416 } 417 418 int 419 WI_fragSum(int playernum) 420 { 421 int i, frags; 422 423 frags = 0; 424 for (i = 0; i < MAXPLAYERS; ++i) 425 if (playeringame[i] && i!=playernum) 426 frags += plrs[playernum].frags[i]; 427 frags -= plrs[playernum].frags[playernum]; 428 return frags; 429 } 430 431 void 432 WI_initDeathmatchStats() 433 { 434 int i, j; 435 436 state = StatCount; 437 acceleratestage = 0; 438 dm_state = 1; 439 cnt_pause = TICRATE; 440 for (i = 0; i < MAXPLAYERS; ++i) { 441 if (playeringame[i]) { 442 for (j = 0; j < MAXPLAYERS; ++j) 443 if (playeringame[j]) 444 dm_frags[i][j] = 0; 445 dm_totals[i] = 0; 446 } 447 } 448 WI_initAnimatedBack(); 449 } 450 451 void 452 WI_updateDeathmatchStats() 453 { 454 boolean stillticking; 455 int i, j; 456 457 WI_updateAnimatedBack(); 458 if (acceleratestage && dm_state != 4) { 459 acceleratestage = 0; 460 for (i = 0; i < MAXPLAYERS; ++i) { 461 if (playeringame[i]) { 462 for (j = 0; j < MAXPLAYERS; ++j) 463 if (playeringame[j]) 464 dm_frags[i][j] = plrs[i].frags[j]; 465 dm_totals[i] = WI_fragSum(i); 466 } 467 } 468 S_StartSound(0, sfx_barexp); 469 dm_state = 4; 470 } 471 if (dm_state == 2) { 472 if (!(bcnt&3)) 473 S_StartSound(0, sfx_pistol); 474 stillticking = false; 475 for (i = 0; i < MAXPLAYERS; ++i) { 476 if (playeringame[i]) { 477 for (j = 0; j < MAXPLAYERS; ++j) { 478 if (playeringame[j] && dm_frags[i][j] != plrs[i].frags[j]) { 479 if (plrs[i].frags[j] < 0) dm_frags[i][j]--; 480 else dm_frags[i][j]++; 481 if (dm_frags[i][j] > 99) dm_frags[i][j] = 99; 482 if (dm_frags[i][j] < -99) dm_frags[i][j] = -99; 483 stillticking = true; 484 } 485 } 486 dm_totals[i] = WI_fragSum(i); 487 if (dm_totals[i] > 99) dm_totals[i] = 99; 488 if (dm_totals[i] < -99) dm_totals[i] = -99; 489 } 490 } 491 if (!stillticking) { 492 S_StartSound(0, sfx_barexp); 493 dm_state++; 494 } 495 } 496 if (dm_state == 4) { 497 if (acceleratestage) { 498 S_StartSound(0, sfx_slop); 499 WI_initShowNextLoc(); 500 } 501 } 502 if (dm_state & 1) { 503 if (!--cnt_pause) { 504 dm_state++; 505 cnt_pause = TICRATE; 506 } 507 } 508 } 509 510 void 511 WI_drawDeathmatchStats() 512 { 513 514 int i, j, x, y, w; 515 516 WI_slamBackground(); 517 WI_drawAnimatedBack(); 518 WI_drawLF(); 519 V_DrawPatch(DM_TOTALSX-SHORT(total->width)/2, DM_MATRIXY-WI_SPACINGY+10, FB, total); 520 V_DrawPatch(DM_KILLERSX, DM_KILLERSY, FB, killers); 521 V_DrawPatch(DM_VICTIMSX, DM_VICTIMSY, FB, victims); 522 x = DM_MATRIXX + DM_SPACINGX; 523 y = DM_MATRIXY; 524 for (i = 0; i < MAXPLAYERS; ++i) { 525 if (playeringame[i]) { 526 V_DrawPatch(x-SHORT(p[i]->width)/2, DM_MATRIXY - WI_SPACINGY, FB, p[i]); 527 V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2, y, FB, p[i]); 528 if (i == me) { 529 V_DrawPatch(x-SHORT(p[i]->width)/2, DM_MATRIXY - WI_SPACINGY, FB, bstar); 530 V_DrawPatch(DM_MATRIXX-SHORT(p[i]->width)/2, y, FB, star); 531 } 532 } 533 x += DM_SPACINGX; 534 y += WI_SPACINGY; 535 } 536 y = DM_MATRIXY+10; 537 w = SHORT(num[0]->width); 538 for (i = 0; i < MAXPLAYERS; ++i) { 539 x = DM_MATRIXX + DM_SPACINGX; 540 if (playeringame[i]) { 541 for (j = 0; j < MAXPLAYERS; ++j) { 542 if (playeringame[j]) 543 WI_drawNum(x+w, y, dm_frags[i][j], 2); 544 x += DM_SPACINGX; 545 } 546 WI_drawNum(DM_TOTALSX+w, y, dm_totals[i], 2); 547 } 548 y += WI_SPACINGY; 549 } 550 } 551 552 void 553 WI_initNetgameStats() 554 { 555 int i; 556 557 state = StatCount; 558 acceleratestage = 0; 559 ng_state = 1; 560 cnt_pause = TICRATE; 561 for (i = 0; i < MAXPLAYERS; ++i) { 562 if (!playeringame[i]) 563 continue; 564 cnt_kills[i] = cnt_items[i] = cnt_secret[i] = cnt_frags[i] = 0; 565 dofrags += WI_fragSum(i); 566 } 567 dofrags = !!dofrags; 568 WI_initAnimatedBack(); 569 } 570 571 void 572 WI_updateNetgameStats() 573 { 574 int i, fsum; 575 boolean stillticking; 576 577 WI_updateAnimatedBack(); 578 if (acceleratestage && ng_state != 10) { 579 acceleratestage = 0; 580 for (i = 0; i < MAXPLAYERS; ++i) { 581 if (!playeringame[i]) 582 continue; 583 cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills; 584 cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems; 585 cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret; 586 if (dofrags) 587 cnt_frags[i] = WI_fragSum(i); 588 } 589 S_StartSound(0, sfx_barexp); 590 ng_state = 10; 591 } 592 switch (ng_state) { 593 case 2: 594 if (!(bcnt&3)) 595 S_StartSound(0, sfx_pistol); 596 stillticking = false; 597 for (i = 0; i < MAXPLAYERS; ++i) { 598 if (!playeringame[i]) 599 continue; 600 cnt_kills[i] += 2; 601 if (cnt_kills[i] >= (plrs[i].skills * 100) / wbs->maxkills) 602 cnt_kills[i] = (plrs[i].skills * 100) / wbs->maxkills; 603 else stillticking = true; 604 } 605 if (!stillticking) { 606 S_StartSound(0, sfx_barexp); 607 ++ng_state; 608 } 609 break; 610 case 4: 611 if (!(bcnt&3)) 612 S_StartSound(0, sfx_pistol); 613 stillticking = false; 614 for (i = 0; i < MAXPLAYERS; ++i) { 615 if (!playeringame[i]) 616 continue; 617 cnt_items[i] += 2; 618 if (cnt_items[i] >= (plrs[i].sitems * 100) / wbs->maxitems) 619 cnt_items[i] = (plrs[i].sitems * 100) / wbs->maxitems; 620 else stillticking = true; 621 } 622 if (!stillticking) { 623 S_StartSound(0, sfx_barexp); 624 ++ng_state; 625 } 626 break; 627 case 6: 628 if (!(bcnt&3)) 629 S_StartSound(0, sfx_pistol); 630 stillticking = false; 631 for (i = 0; i < MAXPLAYERS; ++i) { 632 if (!playeringame[i]) 633 continue; 634 cnt_secret[i] += 2; 635 if (cnt_secret[i] >= (plrs[i].ssecret * 100) / wbs->maxsecret) 636 cnt_secret[i] = (plrs[i].ssecret * 100) / wbs->maxsecret; 637 else stillticking = true; 638 } 639 if (!stillticking) { 640 S_StartSound(0, sfx_barexp); 641 ng_state += 1 + 2*!dofrags; 642 } 643 break; 644 case 8: 645 if (!(bcnt&3)) 646 S_StartSound(0, sfx_pistol); 647 stillticking = false; 648 for (i = 0; i < MAXPLAYERS; ++i) { 649 if (!playeringame[i]) 650 continue; 651 cnt_frags[i] += 1; 652 if (cnt_frags[i] >= (fsum = WI_fragSum(i))) 653 cnt_frags[i] = fsum; 654 else stillticking = true; 655 } 656 if (!stillticking) { 657 S_StartSound(0, sfx_pldeth); 658 ++ng_state; 659 } 660 break; 661 case 10: 662 if (acceleratestage) { 663 S_StartSound(0, sfx_sgcock); 664 WI_initShowNextLoc(); 665 } 666 } 667 if (ng_state & 1) { 668 if (!--cnt_pause) { 669 ++ng_state; 670 cnt_pause = TICRATE; 671 } 672 } 673 } 674 675 void 676 WI_drawNetgameStats() 677 { 678 int i, x, y, pwidth; 679 680 pwidth = SHORT(percent->width); 681 WI_slamBackground(); 682 WI_drawAnimatedBack(); 683 WI_drawLF(); 684 V_DrawPatch(NG_STATSX+NG_SPACINGX-SHORT(kills->width), NG_STATSY, FB, kills); 685 V_DrawPatch(NG_STATSX+2*NG_SPACINGX-SHORT(items->width), NG_STATSY, FB, items); 686 V_DrawPatch(NG_STATSX+3*NG_SPACINGX-SHORT(secret->width), NG_STATSY, FB, secret); 687 if (dofrags) 688 V_DrawPatch(NG_STATSX+4*NG_SPACINGX-SHORT(frags->width), NG_STATSY, FB, frags); 689 y = NG_STATSY + SHORT(kills->height); 690 for (i = 0; i < MAXPLAYERS; ++i) { 691 if (!playeringame[i]) 692 continue; 693 x = NG_STATSX; 694 V_DrawPatch(x-SHORT(p[i]->width), y, FB, p[i]); 695 if (i == me) 696 V_DrawPatch(x-SHORT(p[i]->width), y, FB, star); 697 x += NG_SPACINGX; 698 WI_drawPercent(x-pwidth, y+10, cnt_kills[i]); x += NG_SPACINGX; 699 WI_drawPercent(x-pwidth, y+10, cnt_items[i]); x += NG_SPACINGX; 700 WI_drawPercent(x-pwidth, y+10, cnt_secret[i]); x += NG_SPACINGX; 701 if (dofrags) 702 WI_drawNum(x, y+10, cnt_frags[i], -1); 703 y += WI_SPACINGY; 704 } 705 } 706 707 void 708 WI_initStats() 709 { 710 state = StatCount; 711 acceleratestage = 0; 712 sp_state = 1; 713 cnt_kills[0] = cnt_items[0] = cnt_secret[0] = -1; 714 cnt_time = cnt_par = -1; 715 cnt_pause = TICRATE; 716 WI_initAnimatedBack(); 717 } 718 719 void 720 WI_updateStats() 721 { 722 WI_updateAnimatedBack(); 723 if (acceleratestage && sp_state != 10) { 724 acceleratestage = 0; 725 cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills; 726 cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems; 727 cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret; 728 cnt_time = plrs[me].stime / TICRATE; 729 cnt_par = wbs->partime / TICRATE; 730 S_StartSound(0, sfx_barexp); 731 sp_state = 10; 732 } 733 switch (sp_state) { 734 case 2: 735 cnt_kills[0] += 2; 736 if (!(bcnt&3)) 737 S_StartSound(0, sfx_pistol); 738 if (cnt_kills[0] >= (plrs[me].skills * 100) / wbs->maxkills) { 739 cnt_kills[0] = (plrs[me].skills * 100) / wbs->maxkills; 740 S_StartSound(0, sfx_barexp); 741 ++sp_state; 742 } 743 break; 744 case 4: 745 cnt_items[0] += 2; 746 if (!(bcnt&3)) 747 S_StartSound(0, sfx_pistol); 748 if (cnt_items[0] >= (plrs[me].sitems * 100) / wbs->maxitems) { 749 cnt_items[0] = (plrs[me].sitems * 100) / wbs->maxitems; 750 S_StartSound(0, sfx_barexp); 751 ++sp_state; 752 } 753 break; 754 case 6: 755 cnt_secret[0] += 2; 756 if (!(bcnt&3)) 757 S_StartSound(0, sfx_pistol); 758 if (cnt_secret[0] >= (plrs[me].ssecret * 100) / wbs->maxsecret) { 759 cnt_secret[0] = (plrs[me].ssecret * 100) / wbs->maxsecret; 760 S_StartSound(0, sfx_barexp); 761 ++sp_state; 762 } 763 break; 764 case 8: 765 if (!(bcnt&3)) 766 S_StartSound(0, sfx_pistol); 767 cnt_time += 3; 768 if (cnt_time >= plrs[me].stime / TICRATE) 769 cnt_time = plrs[me].stime / TICRATE; 770 cnt_par += 3; 771 if (cnt_par >= wbs->partime / TICRATE) { 772 cnt_par = wbs->partime / TICRATE; 773 if (cnt_time >= plrs[me].stime / TICRATE) { 774 S_StartSound(0, sfx_barexp); 775 ++sp_state; 776 } 777 } 778 break; 779 case 10: 780 if (acceleratestage) { 781 S_StartSound(0, sfx_sgcock); 782 WI_initShowNextLoc(); 783 } 784 } 785 if (sp_state & 1) { 786 if (!--cnt_pause) { 787 ++sp_state; 788 cnt_pause = TICRATE; 789 } 790 } 791 } 792 793 void 794 WI_drawStats() 795 { 796 int lh; 797 798 lh = (3*SHORT(num[0]->height))/2; 799 WI_slamBackground(); 800 WI_drawAnimatedBack(); 801 WI_drawLF(); 802 V_DrawPatch(SP_STATSX, SP_STATSY, FB, kills); 803 WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY, cnt_kills[0]); 804 V_DrawPatch(SP_STATSX, SP_STATSY+lh, FB, items); 805 WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+lh, cnt_items[0]); 806 V_DrawPatch(SP_STATSX, SP_STATSY+2*lh, FB, sp_secret); 807 WI_drawPercent(SCREENWIDTH - SP_STATSX, SP_STATSY+2*lh, cnt_secret[0]); 808 V_DrawPatch(SP_TIMEX, SP_TIMEY, FB, time); 809 WI_drawTime(SCREENWIDTH/2 - SP_TIMEX, SP_TIMEY, cnt_time); 810 if (wbs->epsd < 3) { 811 V_DrawPatch(SCREENWIDTH/2 + SP_TIMEX, SP_TIMEY, FB, par); 812 WI_drawTime(SCREENWIDTH - SP_TIMEX, SP_TIMEY, cnt_par); 813 } 814 } 815 816 void 817 WI_checkForAccelerate() 818 { 819 player_t* player; 820 int i; 821 822 for (i = 0, player = players; i < MAXPLAYERS; ++i, ++player) { 823 if (playeringame[i]) { 824 if (player->cmd.buttons & BT_ATTACK) { 825 if (!player->attackdown) 826 acceleratestage = 1; 827 player->attackdown = true; 828 } else player->attackdown = false; 829 if (player->cmd.buttons & BT_USE) { 830 if (!player->usedown) 831 acceleratestage = 1; 832 player->usedown = true; 833 } else player->usedown = false; 834 } 835 } 836 } 837 838 void 839 WI_initNoState() 840 { 841 state = NoState; 842 acceleratestage = 0; 843 cnt = 10; 844 } 845 846 void 847 WI_updateShowNextLoc() 848 { 849 WI_updateAnimatedBack(); 850 if (!--cnt || acceleratestage) 851 WI_initNoState(); 852 else 853 snl_pointeron = (cnt & 31) < 20; 854 } 855 856 857 void 858 WI_updateNoState() 859 { 860 WI_updateAnimatedBack(); 861 if (!--cnt) 862 G_WorldDone(); 863 } 864 865 void 866 WI_Ticker() 867 { 868 bcnt++; 869 870 if (bcnt == 1) 871 S_ChangeMusic(mus_inter, true); 872 WI_checkForAccelerate(); 873 switch (state) { 874 case StatCount: 875 if (deathmatch) WI_updateDeathmatchStats(); 876 else if (netgame) WI_updateNetgameStats(); 877 else WI_updateStats(); 878 break; 879 case ShowNextLoc: 880 WI_updateShowNextLoc(); 881 break; 882 case NoState: 883 WI_updateNoState(); 884 } 885 } 886 887 void 888 WI_loadData() 889 { 890 char name[10]; 891 anim_t* a; 892 int i, j; 893 894 sprintf(name, "WIMAP%d", wbs->epsd); 895 bg = W_CacheLumpName(name, PU_CACHE); 896 V_DrawPatch(0, 0, 1, bg); 897 lnames = (patch_t **) Z_Malloc(sizeof(patch_t*) * NUMMAPS, PU_STATIC, 0); 898 for (i = 0; i < NUMMAPS; ++i) { 899 sprintf(name, "WILV%d%d", wbs->epsd, i); 900 lnames[i] = W_CacheLumpName(name, PU_STATIC); 901 } 902 yah[0] = W_CacheLumpName("WIURH0", PU_STATIC); 903 yah[1] = W_CacheLumpName("WIURH1", PU_STATIC); 904 splat = W_CacheLumpName("WISPLAT", PU_STATIC); 905 if (wbs->epsd < 3) { 906 for (j = 0; j < NUMANIMS[wbs->epsd]; ++j) { 907 a = &anims[wbs->epsd][j]; 908 for (i = 0; i < a->nanims; ++i) { 909 if (wbs->epsd != 1 || j != 8) { 910 sprintf(name, "WIA%d%02d%02d", wbs->epsd % 10, j % 100, i % 100); 911 a->p[i] = W_CacheLumpName(name, PU_STATIC); 912 } else a->p[i] = anims[1][4].p[i]; 913 } 914 } 915 } 916 wiminus = W_CacheLumpName("WIMINUS", PU_STATIC); 917 for (i = 0; i < 10; ++i) { 918 sprintf(name, "WINUM%d", i); 919 num[i] = W_CacheLumpName(name, PU_STATIC); 920 } 921 percent = W_CacheLumpName("WIPCNT", PU_STATIC); 922 finished = W_CacheLumpName("WIF", PU_STATIC); 923 entering = W_CacheLumpName("WIENTER", PU_STATIC); 924 kills = W_CacheLumpName("WIOSTK", PU_STATIC); 925 secret = W_CacheLumpName("WIOSTS", PU_STATIC); 926 sp_secret = W_CacheLumpName("WISCRT2", PU_STATIC); 927 items = W_CacheLumpName("WIOSTI", PU_STATIC); 928 frags = W_CacheLumpName("WIFRGS", PU_STATIC); 929 colon = W_CacheLumpName("WICOLON", PU_STATIC); 930 time = W_CacheLumpName("WITIME", PU_STATIC); 931 sucks = W_CacheLumpName("WISUCKS", PU_STATIC); 932 par = W_CacheLumpName("WIPAR", PU_STATIC); 933 killers = W_CacheLumpName("WIKILRS", PU_STATIC); 934 victims = W_CacheLumpName("WIVCTMS", PU_STATIC); 935 total = W_CacheLumpName("WIMSTT", PU_STATIC); 936 star = W_CacheLumpName("STFST01", PU_STATIC); 937 bstar = W_CacheLumpName("STFDEAD0", PU_STATIC); 938 for (i = 0; i < MAXPLAYERS; ++i) { 939 sprintf(name, "STPB%d", i); 940 p[i] = W_CacheLumpName(name, PU_STATIC); 941 sprintf(name, "WIBP%d", i+1); 942 bp[i] = W_CacheLumpName(name, PU_STATIC); 943 } 944 } 945 946 void 947 WI_unloadData() 948 { 949 int i, j; 950 951 Z_ChangeTag(wiminus, PU_CACHE); 952 for (i = 0; i < 10; ++i) 953 Z_ChangeTag(num[i], PU_CACHE); 954 Z_ChangeTag(yah[0], PU_CACHE); 955 Z_ChangeTag(yah[1], PU_CACHE); 956 Z_ChangeTag(splat, PU_CACHE); 957 for (i = 0; i < NUMMAPS; ++i) 958 Z_ChangeTag(lnames[i], PU_CACHE); 959 if (wbs->epsd < 3) { 960 for (j = 0; j < NUMANIMS[wbs->epsd]; ++j) { 961 if (wbs->epsd != 1 || j != 8) 962 for (i = 0; i < anims[wbs->epsd][j].nanims; ++i) 963 Z_ChangeTag(anims[wbs->epsd][j].p[i], PU_CACHE); 964 } 965 } 966 Z_Free(lnames); 967 Z_ChangeTag(percent, PU_CACHE); 968 Z_ChangeTag(colon, PU_CACHE); 969 Z_ChangeTag(finished, PU_CACHE); 970 Z_ChangeTag(entering, PU_CACHE); 971 Z_ChangeTag(kills, PU_CACHE); 972 Z_ChangeTag(secret, PU_CACHE); 973 Z_ChangeTag(sp_secret, PU_CACHE); 974 Z_ChangeTag(items, PU_CACHE); 975 Z_ChangeTag(frags, PU_CACHE); 976 Z_ChangeTag(time, PU_CACHE); 977 Z_ChangeTag(sucks, PU_CACHE); 978 Z_ChangeTag(par, PU_CACHE); 979 Z_ChangeTag(victims, PU_CACHE); 980 Z_ChangeTag(killers, PU_CACHE); 981 Z_ChangeTag(total, PU_CACHE); 982 for (i = 0; i < MAXPLAYERS; ++i) 983 Z_ChangeTag(p[i], PU_CACHE); 984 for (i = 0; i < MAXPLAYERS; ++i) 985 Z_ChangeTag(bp[i], PU_CACHE); 986 } 987 988 void 989 WI_End() 990 { 991 WI_unloadData(); 992 } 993 994 void 995 WI_Drawer() 996 { 997 switch (state) { 998 case StatCount: 999 if (deathmatch) WI_drawDeathmatchStats(); 1000 else if (netgame) WI_drawNetgameStats(); 1001 else WI_drawStats(); 1002 break; 1003 case ShowNextLoc: 1004 WI_drawShowNextLoc(); 1005 break; 1006 case NoState: 1007 WI_drawNoState(); 1008 } 1009 } 1010 1011 void 1012 WI_initVariables(wbstartstruct_t* wbstartstruct) 1013 { 1014 wbs = wbstartstruct; 1015 acceleratestage = cnt = bcnt = 0; 1016 firstrefresh = 1; 1017 me = wbs->pnum; 1018 plrs = wbs->plyr; 1019 if (!wbs->maxkills) wbs->maxkills = 1; 1020 if (!wbs->maxitems) wbs->maxitems = 1; 1021 if (!wbs->maxsecret) wbs->maxsecret = 1; 1022 if (wbs->epsd > 2) wbs->epsd -= 3; 1023 } 1024 1025 void 1026 WI_Start(wbstartstruct_t* wbstartstruct) 1027 { 1028 1029 WI_initVariables(wbstartstruct); 1030 WI_loadData(); 1031 if (deathmatch) WI_initDeathmatchStats(); 1032 else if (netgame) WI_initNetgameStats(); 1033 else WI_initStats(); 1034 }