]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/f_finale.c
Round 1: $HOME/.hhexen/ for configs and savegames.
[theoddone33/hhexen.git] / base / f_finale.c
1
2 //**************************************************************************
3 //**
4 //** f_finale.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile$
7 //** $Revision$
8 //** $Date$
9 //** $Author$
10 //**
11 //**************************************************************************
12
13 // HEADER FILES ------------------------------------------------------------
14
15 #include "h2def.h"
16 #include "soundst.h"
17 #include "p_local.h"
18 #include <ctype.h>
19
20 // MACROS ------------------------------------------------------------------
21
22 #define TEXTSPEED       3
23 #define TEXTWAIT        250
24
25 // TYPES -------------------------------------------------------------------
26
27 // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
28
29 // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
30
31 // PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
32
33 static void TextWrite(void);
34 static void DrawPic(void);
35 static void InitializeFade(boolean fadeIn);
36 static void DeInitializeFade(void);
37 static void FadePic(void);
38 static char *GetFinaleText(int sequence);
39
40 // EXTERNAL DATA DECLARATIONS ----------------------------------------------
41
42 extern boolean automapactive;
43 extern boolean viewactive;
44
45 // PUBLIC DATA DECLARATIONS ------------------------------------------------
46
47 // PRIVATE DATA DEFINITIONS ------------------------------------------------
48
49 static int FinaleStage;
50 static int FinaleCount;
51 static int FinaleEndCount;
52 static int FinaleLumpNum;
53 static int FontABaseLump;
54 static char *FinaleText;
55
56 static fixed_t *Palette;
57 static fixed_t *PaletteDelta;
58 static byte *RealPalette;
59
60 // CODE --------------------------------------------------------------------
61
62 //===========================================================================
63 //
64 // F_StartFinale
65 //
66 //===========================================================================
67
68 void F_StartFinale (void)
69 {
70         gameaction = ga_nothing;
71         gamestate = GS_FINALE;
72         viewactive = false;
73         automapactive = false;
74         P_ClearMessage(&players[consoleplayer]);
75
76         FinaleStage = 0;
77         FinaleCount = 0;
78         FinaleText = GetFinaleText(0);
79         FinaleEndCount = 70;
80         FinaleLumpNum = W_GetNumForName("FINALE1");
81         FontABaseLump = W_GetNumForName("FONTA_S")+1;
82         InitializeFade(1);
83
84 //      S_ChangeMusic(mus_victor, true);
85         S_StartSongName("hall", false); // don't loop the song
86 }
87
88 //===========================================================================
89 //
90 // F_Responder
91 //
92 //===========================================================================
93
94 boolean F_Responder(event_t *event)
95 {
96         return false;
97 }
98
99 //===========================================================================
100 //
101 // F_Ticker
102 //
103 //===========================================================================
104
105 void F_Ticker (void)
106 {
107         FinaleCount++;
108         if(FinaleStage < 5 && FinaleCount >= FinaleEndCount)
109         {
110                 FinaleCount = 0;
111                 FinaleStage++;
112                 switch(FinaleStage)
113                 {
114                         case 1: // Text 1
115                                 FinaleEndCount = strlen(FinaleText)*TEXTSPEED+TEXTWAIT;
116                                 break;
117                         case 2: // Pic 2, Text 2
118                                 FinaleText = GetFinaleText(1);
119                                 FinaleEndCount = strlen(FinaleText)*TEXTSPEED+TEXTWAIT;
120                                 FinaleLumpNum = W_GetNumForName("FINALE2");
121                                 S_StartSongName("orb", false);
122                                 break;
123                         case 3: // Pic 2 -- Fade out
124                                 FinaleEndCount = 70;
125                                 DeInitializeFade();
126                                 InitializeFade(0);
127                                 break;
128                         case 4: // Pic 3 -- Fade in
129                                 FinaleLumpNum = W_GetNumForName("FINALE3");
130                                 FinaleEndCount = 71;
131                                 DeInitializeFade();
132                                 InitializeFade(1);
133                                 S_StartSongName("chess", true);
134                                 break;
135                         case 5: // Pic 3 , Text 3
136                                 FinaleText = GetFinaleText(2);
137                                 DeInitializeFade();
138                                 break;
139                         default:
140                                  break;
141                 }
142                 return;
143         }
144         if(FinaleStage == 0 || FinaleStage == 3 || FinaleStage == 4)
145         {
146                 FadePic();
147         }
148 }
149
150 //===========================================================================
151 //
152 // TextWrite
153 //
154 //===========================================================================
155
156 static void TextWrite (void)
157 {
158         int             count;
159         char    *ch;
160         int             c;
161         int             cx, cy;
162         patch_t *w;
163
164         memcpy(screen, W_CacheLumpNum(FinaleLumpNum, PU_CACHE), 
165                 SCREENWIDTH*SCREENHEIGHT);
166         if(FinaleStage == 5)
167         { // Chess pic, draw the correct character graphic
168                 if(netgame)
169                 {
170                         V_DrawPatch(20, 0, W_CacheLumpName("chessall", PU_CACHE));
171                 }
172                 /* jim Looks like Dan got this one wrong! 8-) */
173 /*              else if(PlayerClass[consoleplayer] = PCLASS_ASS) */
174                 else if(PlayerClass[consoleplayer] == PCLASS_ASS)
175                 {
176                         V_DrawPatch(60,0, W_CacheLumpNum(W_GetNumForName("chessa"), PU_CACHE));
177                 }
178                 else if(PlayerClass[consoleplayer])
179                 {
180                         V_DrawPatch(60, 0, W_CacheLumpNum(W_GetNumForName("chessc")
181                                 +PlayerClass[consoleplayer]-1, PU_CACHE));
182                 }
183         }
184         // Draw the actual text
185         if(FinaleStage == 5)
186         {
187                 cy = 135;
188         }
189         else
190         {
191                 cy = 5;
192         }
193         cx = 20;
194         ch = FinaleText;
195         count = (FinaleCount-10)/TEXTSPEED;
196         if (count < 0)
197         {
198                 count = 0;
199         }
200         for(; count; count--)
201         {
202                 c = *ch++;
203                 if(!c)
204                 {
205                         break;
206                 }
207                 if(c == '\n')
208                 {
209                         cx = 20;
210                         cy += 9;
211                         continue;
212                 }
213                 if(c < 32)
214                 {
215                         continue;
216                 }
217                 c = toupper(c);
218                 if(c == 32)
219                 {
220                         cx += 5;
221                         continue;
222                 }
223                 w = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
224                 if(cx+w->width > SCREENWIDTH)
225                 {
226                         break;
227                 }
228                 V_DrawPatch(cx, cy, w);
229                 cx += w->width;
230         }
231 }
232
233 //===========================================================================
234 //
235 // InitializeFade
236 //
237 //===========================================================================
238
239 static void InitializeFade(boolean fadeIn)
240 {
241         unsigned i;
242
243         Palette = Z_Malloc(768*sizeof(fixed_t), PU_STATIC, 0);
244         PaletteDelta = Z_Malloc(768*sizeof(fixed_t), PU_STATIC, 0);
245         RealPalette = Z_Malloc(768*sizeof(byte), PU_STATIC, 0);
246
247         if(fadeIn)
248         {
249                 memset(RealPalette, 0, 768*sizeof(byte));
250                 for(i = 0; i < 768; i++)
251                 {
252                         Palette[i] = 0;
253                         PaletteDelta[i] = FixedDiv((*((byte *)W_CacheLumpName("playpal", 
254                                 PU_CACHE)+i))<<FRACBITS, 70*FRACUNIT);
255                 }
256         }
257         else
258         {
259                 for(i = 0; i < 768; i++)
260                 {
261                         RealPalette[i] = *((byte *)W_CacheLumpName("playpal", PU_CACHE)+i);
262                         Palette[i] = RealPalette[i]<<FRACBITS;
263                         PaletteDelta[i] = FixedDiv(Palette[i], -70*FRACUNIT);
264                 }
265         }
266         I_SetPalette(RealPalette);
267 }
268
269 //===========================================================================
270 //
271 // DeInitializeFade
272 //
273 //===========================================================================
274
275 static void DeInitializeFade(void)
276 {
277         Z_Free(Palette);
278         Z_Free(PaletteDelta);
279         Z_Free(RealPalette);
280 }
281
282 //===========================================================================
283 //
284 // FadePic
285 //
286 //===========================================================================
287
288 static void FadePic(void)
289 {
290         unsigned i;
291
292         for(i = 0; i < 768; i++)
293         {
294                 Palette[i] += PaletteDelta[i];
295                 RealPalette[i] = Palette[i]>>FRACBITS;
296         }
297         I_SetPalette(RealPalette);
298 }
299
300 //===========================================================================
301 //
302 // DrawPic
303 //
304 //===========================================================================
305
306 static void DrawPic(void)
307 {
308         memcpy(screen, W_CacheLumpNum(FinaleLumpNum, PU_CACHE), 
309                 SCREENWIDTH*SCREENHEIGHT);
310         if(FinaleStage == 4 || FinaleStage == 5)
311         { // Chess pic, draw the correct character graphic
312                 if(netgame)
313                 {
314                         V_DrawPatch(20, 0, W_CacheLumpName("chessall", PU_CACHE));
315                 }
316                 else if(PlayerClass[consoleplayer])
317                 {
318                         V_DrawPatch(60, 0, W_CacheLumpNum(W_GetNumForName("chessc")
319                                 +PlayerClass[consoleplayer]-1, PU_CACHE));
320                 }
321         }
322 }
323
324 //===========================================================================
325 //
326 // F_Drawer
327 //
328 //===========================================================================
329
330 void F_Drawer(void)
331 {
332         switch(FinaleStage)
333         {
334                 case 0: // Fade in initial finale screen
335                         DrawPic();
336                         break;
337                 case 1:
338                 case 2:
339                         TextWrite();
340                         break;
341                 case 3: // Fade screen out
342                         DrawPic();
343                         break;
344                 case 4: // Fade in chess screen
345                         DrawPic();
346                         break;
347                 case 5:
348                         TextWrite();
349                         break;
350         }
351         UpdateState |= I_FULLSCRN;      
352 }
353
354 //==========================================================================
355 //
356 // GetFinaleText
357 //
358 //==========================================================================
359
360 static char *GetFinaleText(int sequence)
361 {
362         char *msgLumpName;
363         int msgSize;
364         int msgLump;
365         static char *winMsgLumpNames[] =
366         {
367 #ifdef VERSION10_WAD
368                 WIN1MSG,
369                 WIN2MSG,
370                 WIN3MSG
371 #else
372                 "win1msg",
373                 "win2msg",
374                 "win3msg"
375 #endif
376         };
377 #ifdef VERSION10_WAD
378         return winMsgLumpNames[sequence];
379 #else
380         msgLumpName = winMsgLumpNames[sequence];
381         msgLump = W_GetNumForName(msgLumpName);
382         msgSize = W_LumpLength(msgLump);
383         if(msgSize >= MAX_INTRMSN_MESSAGE_SIZE)
384         {
385                 I_Error("Finale message too long (%s)", msgLumpName);
386         }
387         W_ReadLump(msgLump, ClusterMessage);
388         ClusterMessage[msgSize] = 0; // Append terminator
389         return ClusterMessage;
390 #endif
391 }