1 // Emacs style mode select -*- C++ -*-
2 //-----------------------------------------------------------------------------
6 // Copyright (C) 1993-1996 by id Software, Inc.
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
18 // Revision 1.1 2000/02/29 18:21:04 stegerg
19 // Doom port based on ADoomPPC. Read README.AROS!
23 // Game completion, final screen animation.
25 //-----------------------------------------------------------------------------
50 //#include "doomstat.h"
51 //#include "r_local.h"
52 //#include "f_finale.h"
54 // Stage of animation:
55 // 0 = text, 1 = art screen, 2 = character cast
63 char* e1text
= E1TEXT
;
64 char* e2text
= E2TEXT
;
65 char* e3text
= E3TEXT
;
66 char* e4text
= E4TEXT
;
68 char* c1text
= C1TEXT
;
69 char* c2text
= C2TEXT
;
70 char* c3text
= C3TEXT
;
71 char* c4text
= C4TEXT
;
72 char* c5text
= C5TEXT
;
73 char* c6text
= C6TEXT
;
75 char* p1text
= P1TEXT
;
76 char* p2text
= P2TEXT
;
77 char* p3text
= P3TEXT
;
78 char* p4text
= P4TEXT
;
79 char* p5text
= P5TEXT
;
80 char* p6text
= P6TEXT
;
82 char* t1text
= T1TEXT
;
83 char* t2text
= T2TEXT
;
84 char* t3text
= T3TEXT
;
85 char* t4text
= T4TEXT
;
86 char* t5text
= T5TEXT
;
87 char* t6text
= T6TEXT
;
92 void F_StartCast (void);
93 void F_CastTicker (void);
94 boolean
F_CastResponder (event_t
*ev
);
95 void F_CastDrawer (void);
100 void F_StartFinale (void)
102 gameaction
= ga_nothing
;
103 gamestate
= GS_FINALE
;
105 automapactive
= false;
107 // Okay - IWAD dependend stuff.
108 // This has been changed severly, and
109 // some stuff might have changed in the process.
113 // DOOM 1 - E1, E3 or E4, but each nine missions
118 S_ChangeMusic(mus_victor
, true);
123 finaleflat
= "FLOOR4_8";
127 finaleflat
= "SFLR6_1";
131 finaleflat
= "MFLR8_4";
135 finaleflat
= "MFLR8_3";
145 // DOOM II and missions packs with E1, M34
148 S_ChangeMusic(mus_read_m
, true);
153 finaleflat
= "SLIME16";
157 finaleflat
= "RROCK14";
161 finaleflat
= "RROCK07";
165 finaleflat
= "RROCK17";
169 finaleflat
= "RROCK13";
173 finaleflat
= "RROCK19";
186 S_ChangeMusic(mus_read_m
, true);
187 finaleflat
= "F_SKY1"; // Not used anywhere else.
188 finaletext
= c1text
; // FIXME - other text, music?
199 boolean
F_Responder (event_t
*event
)
201 if (finalestage
== 2)
202 return F_CastResponder (event
);
215 // check for skipping
216 if ( (gamemode
== commercial
)
217 && ( finalecount
> 50) )
219 // go on to the next level
220 for (i
=0 ; i
<MAXPLAYERS
; i
++)
221 if (players
[i
].cmd
.buttons
)
229 gameaction
= ga_worlddone
;
236 if (finalestage
== 2)
242 if ( gamemode
== commercial
)
245 if (!finalestage
&& finalecount
>strlen (finaletext
)*TEXTSPEED
+ TEXTWAIT
)
249 wipegamestate
= -1; // force a wipe
250 if (gameepisode
== 3)
251 S_StartMusic (mus_bunny
);
261 #include "hu_stuff.h"
262 extern patch_t
*hu_font
[HU_FONTSIZE
];
265 void F_TextWrite (void)
277 // erase the entire screen to a tiled background
278 src
= W_CacheLumpName ( finaleflat
, PU_CACHE
);
281 for (y
=0 ; y
<SCREENHEIGHT
; y
++)
283 for (x
=0 ; x
<SCREENWIDTH
/64 ; x
++)
285 memcpy (dest
, src
+((y
&63)<<6), 64);
290 memcpy (dest
, src
+((y
&63)<<6), SCREENWIDTH
&63);
291 dest
+= (SCREENWIDTH
&63);
295 // draw some of the text onto the screen
300 count
= (finalecount
- 10)/TEXTSPEED
;
303 for ( ; count
; count
-- )
315 c
= toupper(c
) - HU_FONTSTART
;
316 if (c
< 0 || c
> HU_FONTSIZE
)
322 w
= SWAPSHORT (hu_font
[c
]->width
);
323 if (cx
+w
> SCREENWIDTH
)
325 V_DrawPatchInDirect(cx
, cy
, 0, hu_font
[c
]);
329 I_MarkRect (0, 0, SCREENWIDTH
, SCREENHEIGHT
);
334 // Final DOOM 2 animation
335 // Casting by id Software.
336 // in order of appearance
344 castinfo_t castorder
[] = {
345 {CC_ZOMBIE
, MT_POSSESSED
},
346 {CC_SHOTGUN
, MT_SHOTGUY
},
347 {CC_HEAVY
, MT_CHAINGUY
},
349 {CC_DEMON
, MT_SERGEANT
},
352 {CC_HELL
, MT_KNIGHT
},
353 {CC_BARON
, MT_BRUISER
},
356 {CC_REVEN
, MT_UNDEAD
},
357 {CC_MANCU
, MT_FATSO
},
359 {CC_SPIDER
, MT_SPIDER
},
360 {CC_CYBER
, MT_CYBORG
},
361 {CC_HERO
, MT_PLAYER
},
372 boolean castattacking
;
378 extern gamestate_t wipegamestate
;
381 void F_StartCast (void)
383 wipegamestate
= -1; // force a screen wipe
385 caststate
= &states
[mobjinfo
[castorder
[castnum
].type
].seestate
];
386 casttics
= caststate
->tics
;
391 castattacking
= false;
392 S_ChangeMusic(mus_evil
, true);
399 void F_CastTicker (void)
405 return; // not time to change state yet
407 if (caststate
->tics
== -1 || caststate
->nextstate
== S_NULL
)
409 // switch from deathstate to next monster
412 if (castorder
[castnum
].name
== NULL
)
414 if (mobjinfo
[castorder
[castnum
].type
].seesound
)
415 S_StartSound (NULL
, mobjinfo
[castorder
[castnum
].type
].seesound
);
416 caststate
= &states
[mobjinfo
[castorder
[castnum
].type
].seestate
];
421 // just advance to next state in animation
422 if (caststate
== &states
[S_PLAY_ATK1
])
423 goto stopattack
; // Oh, gross hack!
424 st
= caststate
->nextstate
;
425 caststate
= &states
[st
];
431 case S_PLAY_ATK1
: sfx
= sfx_dshtgn
; break;
432 case S_POSS_ATK2
: sfx
= sfx_pistol
; break;
433 case S_SPOS_ATK2
: sfx
= sfx_shotgn
; break;
434 case S_VILE_ATK2
: sfx
= sfx_vilatk
; break;
435 case S_SKEL_FIST2
: sfx
= sfx_skeswg
; break;
436 case S_SKEL_FIST4
: sfx
= sfx_skepch
; break;
437 case S_SKEL_MISS2
: sfx
= sfx_skeatk
; break;
440 case S_FATT_ATK2
: sfx
= sfx_firsht
; break;
443 case S_CPOS_ATK4
: sfx
= sfx_shotgn
; break;
444 case S_TROO_ATK3
: sfx
= sfx_claw
; break;
445 case S_SARG_ATK2
: sfx
= sfx_sgtatk
; break;
448 case S_HEAD_ATK2
: sfx
= sfx_firsht
; break;
449 case S_SKULL_ATK2
: sfx
= sfx_sklatk
; break;
451 case S_SPID_ATK3
: sfx
= sfx_shotgn
; break;
452 case S_BSPI_ATK2
: sfx
= sfx_plasma
; break;
455 case S_CYBER_ATK6
: sfx
= sfx_rlaunc
; break;
456 case S_PAIN_ATK3
: sfx
= sfx_sklatk
; break;
457 default: sfx
= 0; break;
461 S_StartSound (NULL
, sfx
);
464 if (castframes
== 12)
466 // go into attack frame
467 castattacking
= true;
469 caststate
=&states
[mobjinfo
[castorder
[castnum
].type
].meleestate
];
471 caststate
=&states
[mobjinfo
[castorder
[castnum
].type
].missilestate
];
473 if (caststate
== &states
[S_NULL
])
477 &states
[mobjinfo
[castorder
[castnum
].type
].meleestate
];
480 &states
[mobjinfo
[castorder
[castnum
].type
].missilestate
];
487 || caststate
== &states
[mobjinfo
[castorder
[castnum
].type
].seestate
] )
490 castattacking
= false;
492 caststate
= &states
[mobjinfo
[castorder
[castnum
].type
].seestate
];
496 casttics
= caststate
->tics
;
506 boolean
F_CastResponder (event_t
* ev
)
508 if (ev
->type
!= ev_keydown
)
512 return true; // already in dying frames
514 // go into death frame
516 caststate
= &states
[mobjinfo
[castorder
[castnum
].type
].deathstate
];
517 casttics
= caststate
->tics
;
519 castattacking
= false;
520 if (mobjinfo
[castorder
[castnum
].type
].deathsound
)
521 S_StartSound (NULL
, mobjinfo
[castorder
[castnum
].type
].deathsound
);
527 void F_CastPrint (char* text
)
544 c
= toupper(c
) - HU_FONTSTART
;
545 if (c
< 0 || c
> HU_FONTSIZE
)
551 w
= SWAPSHORT (hu_font
[c
]->width
);
563 c
= toupper(c
) - HU_FONTSTART
;
564 if (c
< 0 || c
> HU_FONTSIZE
)
570 w
= SWAPSHORT (hu_font
[c
]->width
);
571 V_DrawPatchInDirect(cx
, 180, 0, hu_font
[c
]);
581 //void V_DrawPatchFlipped (int x, int y, int scrn, patch_t *patch);
583 void F_CastDrawer (void)
586 spriteframe_t
* sprframe
;
591 // erase the entire screen to a background
592 V_DrawPatchInDirect (0,0,0, W_CacheLumpName ("BOSSBACK", PU_CACHE
));
594 F_CastPrint (castorder
[castnum
].name
);
596 // draw the current frame in the middle of the screen
597 sprdef
= &sprites
[caststate
->sprite
];
598 sprframe
= &sprdef
->spriteframes
[ caststate
->frame
& FF_FRAMEMASK
];
599 lump
= sprframe
->lump
[0];
600 flip
= (boolean
)sprframe
->flip
[0];
602 patch
= W_CacheLumpNum (lump
+firstspritelump
, PU_CACHE
);
604 V_DrawPatchInDirectFlipped (160,170,0,patch
);
606 V_DrawPatchInDirect (160,170,0,patch
);
625 column
= (column_t
*)((byte
*)patch
+ SWAPLONG(patch
->columnofs
[col
]));
626 // desttop = screens[0]+x;
627 desttop
= screens
[0]+x
+(SCREENWIDTH
-320)/2+SCREENWIDTH
*((SCREENHEIGHT
-200)/2);
629 // step through the posts in a column
630 while (column
->topdelta
!= 0xff )
632 source
= (byte
*)column
+ 3;
633 dest
= desttop
+ column
->topdelta
*SCREENWIDTH
;
634 count
= column
->length
;
641 column
= (column_t
*)( (byte
*)column
+ column
->length
+ 4 );
649 void F_BunnyScroll (void)
657 static int laststage
;
659 p1
= W_CacheLumpName ("PFUB2", PU_LEVEL
);
660 p2
= W_CacheLumpName ("PFUB1", PU_LEVEL
);
662 scrolled
= 320 - (finalecount
-230)/2;
668 // for ( x=0 ; x<SCREENWIDTH ; x++)
669 if ((SCREENWIDTH
!=320)||(SCREENHEIGHT
!=200))
670 memset(screens
[0],2,SCREENWIDTH
*SCREENHEIGHT
);
671 for ( x
=0 ; x
<320 ; x
++)
673 if (x
+scrolled
< 320)
674 F_DrawPatchCol (x
, p1
, x
+scrolled
);
676 F_DrawPatchCol (x
, p2
, x
+scrolled
- 320);
679 if (finalecount
< 1130)
681 if (finalecount
< 1180)
683 V_DrawPatchInDirect ((320-13*8)/2,
684 (200-8*8)/2,0, W_CacheLumpName ("END0",PU_CACHE
));
689 stage
= (finalecount
-1180) / 5;
692 if (stage
> laststage
)
694 S_StartSound (NULL
, sfx_pistol
);
698 sprintf (name
,"END%i",stage
);
699 V_DrawPatchInDirect ((320-13*8)/2, (200-8*8)/2,0, W_CacheLumpName (name
,PU_CACHE
));
701 I_MarkRect (0, 0, SCREENWIDTH
, SCREENHEIGHT
);
710 if (finalestage
== 2)
723 if ( gamemode
== retail
)
724 V_DrawPatchInDirect (0,0,0,
725 W_CacheLumpName("CREDIT",PU_CACHE
));
727 V_DrawPatchInDirect (0,0,0,
728 W_CacheLumpName("HELP2",PU_CACHE
));
731 V_DrawPatchInDirect(0,0,0,
732 W_CacheLumpName("VICTORY2",PU_CACHE
));
738 V_DrawPatchInDirect (0,0,0,
739 W_CacheLumpName("ENDPIC",PU_CACHE
));