osezer patch 001
[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 #ifdef ASSASSIN
173                 /* jim Looks like Dan got this one wrong! 8-) */
174 /*              else if(PlayerClass[consoleplayer] = PCLASS_ASS) */
175                 else if(PlayerClass[consoleplayer] == PCLASS_ASS)
176                 {
177                         V_DrawPatch(60,0, W_CacheLumpNum(W_GetNumForName("chessa"), PU_CACHE));
178                 }
179 #endif
180                 else if(PlayerClass[consoleplayer])
181                 {
182                         V_DrawPatch(60, 0, W_CacheLumpNum(W_GetNumForName("chessc")
183                                 +PlayerClass[consoleplayer]-1, PU_CACHE));
184                 }
185         }
186         // Draw the actual text
187         if(FinaleStage == 5)
188         {
189                 cy = 135;
190         }
191         else
192         {
193                 cy = 5;
194         }
195         cx = 20;
196         ch = FinaleText;
197         count = (FinaleCount-10)/TEXTSPEED;
198         if (count < 0)
199         {
200                 count = 0;
201         }
202         for(; count; count--)
203         {
204                 c = *ch++;
205                 if(!c)
206                 {
207                         break;
208                 }
209                 if(c == '\n')
210                 {
211                         cx = 20;
212                         cy += 9;
213                         continue;
214                 }
215                 if(c < 32)
216                 {
217                         continue;
218                 }
219                 c = toupper(c);
220                 if(c == 32)
221                 {
222                         cx += 5;
223                         continue;
224                 }
225                 w = W_CacheLumpNum(FontABaseLump+c-33, PU_CACHE);
226                 if(cx+w->width > SCREENWIDTH)
227                 {
228                         break;
229                 }
230                 V_DrawPatch(cx, cy, w);
231                 cx += w->width;
232         }
233 }
234
235 //===========================================================================
236 //
237 // InitializeFade
238 //
239 //===========================================================================
240
241 static void InitializeFade(boolean fadeIn)
242 {
243         unsigned i;
244
245         Palette = Z_Malloc(768*sizeof(fixed_t), PU_STATIC, 0);
246         PaletteDelta = Z_Malloc(768*sizeof(fixed_t), PU_STATIC, 0);
247         RealPalette = Z_Malloc(768*sizeof(byte), PU_STATIC, 0);
248
249         if(fadeIn)
250         {
251                 memset(RealPalette, 0, 768*sizeof(byte));
252                 for(i = 0; i < 768; i++)
253                 {
254                         Palette[i] = 0;
255                         PaletteDelta[i] = FixedDiv((*((byte *)W_CacheLumpName("playpal", 
256                                 PU_CACHE)+i))<<FRACBITS, 70*FRACUNIT);
257                 }
258         }
259         else
260         {
261                 for(i = 0; i < 768; i++)
262                 {
263                         RealPalette[i] = *((byte *)W_CacheLumpName("playpal", PU_CACHE)+i);
264                         Palette[i] = RealPalette[i]<<FRACBITS;
265                         PaletteDelta[i] = FixedDiv(Palette[i], -70*FRACUNIT);
266                 }
267         }
268         I_SetPalette(RealPalette);
269 }
270
271 //===========================================================================
272 //
273 // DeInitializeFade
274 //
275 //===========================================================================
276
277 static void DeInitializeFade(void)
278 {
279         Z_Free(Palette);
280         Z_Free(PaletteDelta);
281         Z_Free(RealPalette);
282 }
283
284 //===========================================================================
285 //
286 // FadePic
287 //
288 //===========================================================================
289
290 static void FadePic(void)
291 {
292         unsigned i;
293
294         for(i = 0; i < 768; i++)
295         {
296                 Palette[i] += PaletteDelta[i];
297                 RealPalette[i] = Palette[i]>>FRACBITS;
298         }
299         I_SetPalette(RealPalette);
300 }
301
302 //===========================================================================
303 //
304 // DrawPic
305 //
306 //===========================================================================
307
308 static void DrawPic(void)
309 {
310         memcpy(screen, W_CacheLumpNum(FinaleLumpNum, PU_CACHE), 
311                 SCREENWIDTH*SCREENHEIGHT);
312         if(FinaleStage == 4 || FinaleStage == 5)
313         { // Chess pic, draw the correct character graphic
314                 if(netgame)
315                 {
316                         V_DrawPatch(20, 0, W_CacheLumpName("chessall", PU_CACHE));
317                 }
318                 else if(PlayerClass[consoleplayer])
319                 {
320                         V_DrawPatch(60, 0, W_CacheLumpNum(W_GetNumForName("chessc")
321                                 +PlayerClass[consoleplayer]-1, PU_CACHE));
322                 }
323         }
324 }
325
326 //===========================================================================
327 //
328 // F_Drawer
329 //
330 //===========================================================================
331
332 void F_Drawer(void)
333 {
334         switch(FinaleStage)
335         {
336                 case 0: // Fade in initial finale screen
337                         DrawPic();
338                         break;
339                 case 1:
340                 case 2:
341                         TextWrite();
342                         break;
343                 case 3: // Fade screen out
344                         DrawPic();
345                         break;
346                 case 4: // Fade in chess screen
347                         DrawPic();
348                         break;
349                 case 5:
350                         TextWrite();
351                         break;
352         }
353         UpdateState |= I_FULLSCRN;      
354 }
355
356 //==========================================================================
357 //
358 // GetFinaleText
359 //
360 //==========================================================================
361
362 static char *GetFinaleText(int sequence)
363 {
364         char *msgLumpName;
365         int msgSize;
366         int msgLump;
367         static char *winMsgLumpNames[] =
368         {
369                 "win1msg",
370                 "win2msg",
371                 "win3msg"
372         };
373         msgLumpName = winMsgLumpNames[sequence];
374         msgLump = W_GetNumForName(msgLumpName);
375         msgSize = W_LumpLength(msgLump);
376         if(msgSize >= MAX_INTRMSN_MESSAGE_SIZE)
377         {
378                 I_Error("Finale message too long (%s)", msgLumpName);
379         }
380         W_ReadLump(msgLump, ClusterMessage);
381         ClusterMessage[msgSize] = 0; // Append terminator
382         return ClusterMessage;
383 }
384