home *** CD-ROM | disk | FTP | other *** search
/ ST-Computer Leser-CD 2000 January / LCD_01_2000.iso / games / doom / pmdoom / src / f_finale.c < prev    next >
C/C++ Source or Header  |  1999-12-17  |  19KB  |  900 lines

  1. /*  Emacs style mode select   -*- C++ -*-  */
  2. /* ----------------------------------------------------------------------------- */
  3. /*  */
  4. /*  $Id:$ */
  5. /*  */
  6. /*  Copyright (C) 1993-1996 by id Software, Inc. */
  7. /*  */
  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. */
  11. /*  */
  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 */
  15. /*  for more details. */
  16. /*  */
  17. /*  $Log:$ */
  18. /*  */
  19. /*  DESCRIPTION: */
  20. /*     Game completion, final screen animation. */
  21. /*  */
  22. /* ----------------------------------------------------------------------------- */
  23.  
  24.  
  25. static const char
  26. rcsid[] = "$Id: f_finale.c,v 1.5 1997/02/03 21:26:34 b1 Exp $";
  27.  
  28. #include <ctype.h>
  29.  
  30. /*  Functions. */
  31. #include "i_system.h"
  32. #include "m_swap.h"
  33. #include "z_zone.h"
  34. #include "v_video.h"
  35. #include "w_wad.h"
  36. #include "s_sound.h"
  37.  
  38. #include "i_video.h"
  39.  
  40. /*  Data. */
  41. #include "dstrings.h"
  42. #include "sounds.h"
  43.  
  44. #include "doomstat.h"
  45. #include "r_state.h"
  46. #include "i_video.h"
  47.  
  48. /*  ? */
  49. /* #include "doomstat.h" */
  50. /* #include "r_local.h" */
  51. /* #include "f_finale.h" */
  52.  
  53. /*  Stage of animation: */
  54. /*   0 = text, 1 = art screen, 2 = character cast */
  55. int        finalestage;
  56.  
  57. int        finalecount;
  58.  
  59. #define    TEXTSPEED    3
  60. #define    TEXTWAIT    250
  61.  
  62. char*    e1text = E1TEXT;
  63. char*    e2text = E2TEXT;
  64. char*    e3text = E3TEXT;
  65. char*    e4text = E4TEXT;
  66.  
  67. char*    c1text = C1TEXT;
  68. char*    c2text = C2TEXT;
  69. char*    c3text = C3TEXT;
  70. char*    c4text = C4TEXT;
  71. char*    c5text = C5TEXT;
  72. char*    c6text = C6TEXT;
  73.  
  74. char*    p1text = P1TEXT;
  75. char*    p2text = P2TEXT;
  76. char*    p3text = P3TEXT;
  77. char*    p4text = P4TEXT;
  78. char*    p5text = P5TEXT;
  79. char*    p6text = P6TEXT;
  80.  
  81. char*    t1text = T1TEXT;
  82. char*    t2text = T2TEXT;
  83. char*    t3text = T3TEXT;
  84. char*    t4text = T4TEXT;
  85. char*    t5text = T5TEXT;
  86. char*    t6text = T6TEXT;
  87.  
  88. char*    finaletext;
  89. char*    finaleflat;
  90.  
  91. void    F_StartCast (void);
  92. void    F_CastTicker (void);
  93. boolean F_CastResponder (event_t *ev);
  94. void    F_CastDrawer (void);
  95.  
  96. /*  */
  97. /*  F_StartFinale */
  98. /*  */
  99. void F_StartFinale (void)
  100. {
  101.     gameaction = ga_nothing;
  102.     gamestate = GS_FINALE;
  103.     viewactive = false;
  104.     automapactive = false;
  105.  
  106.     /*  Okay - IWAD dependend stuff. */
  107.     /*  This has been changed severly, and */
  108.     /*   some stuff might have changed in the process. */
  109.     switch ( gamemode )
  110.     {
  111.  
  112.       /*  DOOM 1 - E1, E3 or E4, but each nine missions */
  113.       case shareware:
  114.       case registered:
  115.       case retail:
  116.       {
  117.     S_ChangeMusic(mus_victor, true);
  118.     
  119.     switch (gameepisode)
  120.     {
  121.       case 1:
  122.         finaleflat = "FLOOR4_8";
  123.         finaletext = e1text;
  124.         break;
  125.       case 2:
  126.         finaleflat = "SFLR6_1";
  127.         finaletext = e2text;
  128.         break;
  129.       case 3:
  130.         finaleflat = "MFLR8_4";
  131.         finaletext = e3text;
  132.         break;
  133.       case 4:
  134.         finaleflat = "MFLR8_3";
  135.         finaletext = e4text;
  136.         break;
  137.       default:
  138.         /*  Ouch. */
  139.         break;
  140.     }
  141.     break;
  142.       }
  143.       
  144.       /*  DOOM II and missions packs with E1, M34 */
  145.       case commercial:
  146.       {
  147.       S_ChangeMusic(mus_read_m, true);
  148.  
  149.       switch (gamemap)
  150.       {
  151.         case 6:
  152.           finaleflat = "SLIME16";
  153.           finaletext = c1text;
  154.           break;
  155.         case 11:
  156.           finaleflat = "RROCK14";
  157.           finaletext = c2text;
  158.           break;
  159.         case 20:
  160.           finaleflat = "RROCK07";
  161.           finaletext = c3text;
  162.           break;
  163.         case 30:
  164.           finaleflat = "RROCK17";
  165.           finaletext = c4text;
  166.           break;
  167.         case 15:
  168.           finaleflat = "RROCK13";
  169.           finaletext = c5text;
  170.           break;
  171.         case 31:
  172.           finaleflat = "RROCK19";
  173.           finaletext = c6text;
  174.           break;
  175.         default:
  176.           /*  Ouch. */
  177.           break;
  178.       }
  179.       break;
  180.       }    
  181.  
  182.    
  183.       /*  Indeterminate. */
  184.       default:
  185.     S_ChangeMusic(mus_read_m, true);
  186.     finaleflat = "F_SKY1"; /*  Not used anywhere else. */
  187.     finaletext = c1text;  /*  FIXME - other text, music? */
  188.     break;
  189.     }
  190.     
  191.     finalestage = 0;
  192.     finalecount = 0;
  193.     
  194. }
  195.  
  196.  
  197.  
  198. boolean F_Responder (event_t *event)
  199. {
  200.     if (finalestage == 2)
  201.     return F_CastResponder (event);
  202.     
  203.     return false;
  204. }
  205.  
  206.  
  207. /*  */
  208. /*  F_Ticker */
  209. /*  */
  210. void F_Ticker (void)
  211. {
  212.     int        i;
  213.     
  214.     /*  check for skipping */
  215.     if ( (gamemode == commercial)
  216.       && ( finalecount > 50) )
  217.     {
  218.       /*  go on to the next level */
  219.       for (i=0 ; i<MAXPLAYERS ; i++)
  220.     if (players[i].cmd.buttons)
  221.       break;
  222.                 
  223.       if (i < MAXPLAYERS)
  224.       {    
  225.     if (gamemap == 30)
  226.       F_StartCast ();
  227.     else
  228.       gameaction = ga_worlddone;
  229.       }
  230.     }
  231.     
  232.     /*  advance animation */
  233.     finalecount++;
  234.     
  235.     if (finalestage == 2)
  236.     {
  237.     F_CastTicker ();
  238.     return;
  239.     }
  240.     
  241.     if ( gamemode == commercial)
  242.     return;
  243.         
  244.     if (!finalestage && finalecount>strlen (finaletext)*TEXTSPEED + TEXTWAIT)
  245.     {
  246.     finalecount = 0;
  247.     finalestage = 1;
  248.     wipegamestate = -1;        /*  force a wipe */
  249.     if (gameepisode == 3)
  250.         S_StartMusic (mus_bunny);
  251.     }
  252. }
  253.  
  254.  
  255.  
  256. /*  */
  257. /*  F_TextWrite */
  258. /*  */
  259.  
  260. #include "hu_stuff.h"
  261. extern    patch_t *hu_font[HU_FONTSIZE];
  262.  
  263.  
  264. void F_TextWrite (void)
  265. {
  266.     byte    *src,*src1;
  267.     byte*    dest;
  268.     unsigned short    *destsrc;
  269.     unsigned long *destsrc32;
  270.     
  271.     int        x,y,w;
  272.     int        count;
  273.     char*    ch;
  274.     int        c;
  275.     int        cx;
  276.     int        cy;
  277.     
  278.     /*  erase the entire screen to a tiled background */
  279.     src = W_CacheLumpName ( finaleflat , PU_CACHE);
  280.     
  281.     switch (pixel_size)
  282.     {
  283.         case 1:
  284.             dest = screens[0];
  285.             for (y=0 ; y<SCREENHEIGHT ; y++)
  286.             {
  287.                 for (x=0 ; x<SCREENWIDTH/64 ; x++)
  288.                 {
  289.                     memcpy (dest, src+((y&63)<<6), 64);
  290.                     dest += 64;
  291.                 }
  292.                 if (SCREENWIDTH&63)
  293.                 {
  294.                     memcpy (dest, src+((y&63)<<6), SCREENWIDTH&63);
  295.                     dest += (SCREENWIDTH&63);
  296.                 }
  297.             }
  298.             break;
  299.         case 2:
  300.             destsrc = (unsigned short *) screens[0]; 
  301.      
  302.             for (y=0 ; y<SCREENHEIGHT ; y++) 
  303.             { 
  304.                 unsigned short *dest1;
  305.  
  306.                 src1 = src + ((y & 63) << 6);
  307.                 dest1 = destsrc;
  308.  
  309.                 for (x=0; x<SCREENWIDTH ; x++)
  310.                 {
  311.                     *dest1++ = truecolor_palette[ src1[x & 63] ];
  312.                 }
  313.                 destsrc += SCREENWIDTH;
  314.                 } 
  315.             break;
  316.         case 3:
  317.             dest=screens[0];
  318.             for (y=0 ; y<SCREENHEIGHT ; y++) 
  319.             { 
  320.                 byte    *dest1;
  321.  
  322.                 src1 = src + ((y & 63) << 6);
  323.                 dest1 = dest;
  324.  
  325.                 for (x=0; x<SCREENWIDTH ; x++)
  326.                 {
  327.                     unsigned long couleur;
  328.  
  329.                     couleur = truecolor_palette[ src1[x & 63] ];
  330.  
  331.                     *dest1++ = couleur;
  332.                     *dest1++ = couleur >> 8;
  333.                     *dest1++ = couleur >> 16;            
  334.                 }
  335.                 dest += SCREENWIDTH*3;
  336.             } 
  337.             break;
  338.         case 4:
  339.             destsrc32 = (unsigned long *) screens[0]; 
  340.      
  341.             for (y=0 ; y<SCREENHEIGHT ; y++) 
  342.             { 
  343.                 unsigned long *dest1;
  344.  
  345.                 src1 = src + ((y & 63) << 6);
  346.                 dest1 = destsrc32;
  347.  
  348.                 for (x=0; x<SCREENWIDTH ; x++)
  349.                 {
  350.                     *dest1++ = truecolor_palette[ src1[x & 63] ];
  351.                 }
  352.                 destsrc32 += SCREENWIDTH;
  353.                } 
  354.             break;
  355.     }
  356.  
  357.     V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  358.     
  359.     /*  draw some of the text onto the screen */
  360.     cx = 10;
  361.     cy = 10;
  362.     ch = finaletext;
  363.     
  364.     count = (finalecount - 10)/TEXTSPEED;
  365.     if (count < 0)
  366.     count = 0;
  367.     for ( ; count ; count-- )
  368.     {
  369.     c = *ch++;
  370.     if (!c)
  371.         break;
  372.     if (c == '\n')
  373.     {
  374.         cx = 10;
  375.         cy += 11;
  376.         continue;
  377.     }
  378.         
  379.     c = toupper(c) - HU_FONTSTART;
  380.     if (c < 0 || c> HU_FONTSIZE)
  381.     {
  382.         cx += 4;
  383.         continue;
  384.     }
  385.         
  386.     w = SHORT (hu_font[c]->width);
  387.     if (cx+w > SCREENWIDTH)
  388.         break;
  389.     V_DrawPatch(cx, cy, 0, hu_font[c]);
  390.     cx+=w;
  391.     }
  392.     
  393. }
  394.  
  395. /*  */
  396. /*  Final DOOM 2 animation */
  397. /*  Casting by id Software. */
  398. /*    in order of appearance */
  399. /*  */
  400. typedef struct
  401. {
  402.     char        *name;
  403.     mobjtype_t    type;
  404. } castinfo_t;
  405.  
  406. castinfo_t    castorder[] = {
  407.     {CC_ZOMBIE, MT_POSSESSED},
  408.     {CC_SHOTGUN, MT_SHOTGUY},
  409.     {CC_HEAVY, MT_CHAINGUY},
  410.     {CC_IMP, MT_TROOP},
  411.     {CC_DEMON, MT_SERGEANT},
  412.     {CC_LOST, MT_SKULL},
  413.     {CC_CACO, MT_HEAD},
  414.     {CC_HELL, MT_KNIGHT},
  415.     {CC_BARON, MT_BRUISER},
  416.     {CC_ARACH, MT_BABY},
  417.     {CC_PAIN, MT_PAIN},
  418.     {CC_REVEN, MT_UNDEAD},
  419.     {CC_MANCU, MT_FATSO},
  420.     {CC_ARCH, MT_VILE},
  421.     {CC_SPIDER, MT_SPIDER},
  422.     {CC_CYBER, MT_CYBORG},
  423.     {CC_HERO, MT_PLAYER},
  424.  
  425.     {NULL,0}
  426. };
  427.  
  428. int        castnum;
  429. int        casttics;
  430. state_t*    caststate;
  431. boolean        castdeath;
  432. int        castframes;
  433. int        castonmelee;
  434. boolean        castattacking;
  435.  
  436.  
  437. /*  */
  438. /*  F_StartCast */
  439. /*  */
  440. extern    gamestate_t     wipegamestate;
  441.  
  442.  
  443. void F_StartCast (void)
  444. {
  445.     wipegamestate = -1;        /*  force a screen wipe */
  446.     castnum = 0;
  447.     caststate = &states[mobjinfo[castorder[castnum].type].seestate];
  448.     casttics = caststate->tics;
  449.     castdeath = false;
  450.     finalestage = 2;    
  451.     castframes = 0;
  452.     castonmelee = 0;
  453.     castattacking = false;
  454.     S_ChangeMusic(mus_evil, true);
  455. }
  456.  
  457.  
  458. /*  */
  459. /*  F_CastTicker */
  460. /*  */
  461. void F_CastTicker (void)
  462. {
  463.     int        st;
  464.     int        sfx;
  465.     
  466.     if (--casttics > 0)
  467.     return;            /*  not time to change state yet */
  468.         
  469.     if (caststate->tics == -1 || caststate->nextstate == S_NULL)
  470.     {
  471.     /*  switch from deathstate to next monster */
  472.     castnum++;
  473.     castdeath = false;
  474.     if (castorder[castnum].name == NULL)
  475.         castnum = 0;
  476.     if (mobjinfo[castorder[castnum].type].seesound)
  477.         S_StartSound (NULL, mobjinfo[castorder[castnum].type].seesound);
  478.     caststate = &states[mobjinfo[castorder[castnum].type].seestate];
  479.     castframes = 0;
  480.     }
  481.     else
  482.     {
  483.     /*  just advance to next state in animation */
  484.     if (caststate == &states[S_PLAY_ATK1])
  485.         goto stopattack;    /*  Oh, gross hack! */
  486.     st = caststate->nextstate;
  487.     caststate = &states[st];
  488.     castframes++;
  489.     
  490.     /*  sound hacks.... */
  491.     switch (st)
  492.     {
  493.       case S_PLAY_ATK1:    sfx = sfx_dshtgn; break;
  494.       case S_POSS_ATK2:    sfx = sfx_pistol; break;
  495.       case S_SPOS_ATK2:    sfx = sfx_shotgn; break;
  496.       case S_VILE_ATK2:    sfx = sfx_vilatk; break;
  497.       case S_SKEL_FIST2:    sfx = sfx_skeswg; break;
  498.       case S_SKEL_FIST4:    sfx = sfx_skepch; break;
  499.       case S_SKEL_MISS2:    sfx = sfx_skeatk; break;
  500.       case S_FATT_ATK8:
  501.       case S_FATT_ATK5:
  502.       case S_FATT_ATK2:    sfx = sfx_firsht; break;
  503.       case S_CPOS_ATK2:
  504.       case S_CPOS_ATK3:
  505.       case S_CPOS_ATK4:    sfx = sfx_shotgn; break;
  506.       case S_TROO_ATK3:    sfx = sfx_claw; break;
  507.       case S_SARG_ATK2:    sfx = sfx_sgtatk; break;
  508.       case S_BOSS_ATK2:
  509.       case S_BOS2_ATK2:
  510.       case S_HEAD_ATK2:    sfx = sfx_firsht; break;
  511.       case S_SKULL_ATK2:    sfx = sfx_sklatk; break;
  512.       case S_SPID_ATK2:
  513.       case S_SPID_ATK3:    sfx = sfx_shotgn; break;
  514.       case S_BSPI_ATK2:    sfx = sfx_plasma; break;
  515.       case S_CYBER_ATK2:
  516.       case S_CYBER_ATK4:
  517.       case S_CYBER_ATK6:    sfx = sfx_rlaunc; break;
  518.       case S_PAIN_ATK3:    sfx = sfx_sklatk; break;
  519.       default: sfx = 0; break;
  520.     }
  521.         
  522.     if (sfx)
  523.         S_StartSound (NULL, sfx);
  524.     }
  525.     
  526.     if (castframes == 12)
  527.     {
  528.     /*  go into attack frame */
  529.     castattacking = true;
  530.     if (castonmelee)
  531.         caststate=&states[mobjinfo[castorder[castnum].type].meleestate];
  532.     else
  533.         caststate=&states[mobjinfo[castorder[castnum].type].missilestate];
  534.     castonmelee ^= 1;
  535.     if (caststate == &states[S_NULL])
  536.     {
  537.         if (castonmelee)
  538.         caststate=
  539.             &states[mobjinfo[castorder[castnum].type].meleestate];
  540.         else
  541.         caststate=
  542.             &states[mobjinfo[castorder[castnum].type].missilestate];
  543.     }
  544.     }
  545.     
  546.     if (castattacking)
  547.     {
  548.     if (castframes == 24
  549.         ||    caststate == &states[mobjinfo[castorder[castnum].type].seestate] )
  550.     {
  551.       stopattack:
  552.         castattacking = false;
  553.         castframes = 0;
  554.         caststate = &states[mobjinfo[castorder[castnum].type].seestate];
  555.     }
  556.     }
  557.     
  558.     casttics = caststate->tics;
  559.     if (casttics == -1)
  560.     casttics = 15;
  561. }
  562.  
  563.  
  564. /*  */
  565. /*  F_CastResponder */
  566. /*  */
  567.  
  568. boolean F_CastResponder (event_t* ev)
  569. {
  570.     if (ev->type != ev_keydown)
  571.     return false;
  572.         
  573.     if (castdeath)
  574.     return true;            /*  already in dying frames */
  575.         
  576.     /*  go into death frame */
  577.     castdeath = true;
  578.     caststate = &states[mobjinfo[castorder[castnum].type].deathstate];
  579.     casttics = caststate->tics;
  580.     castframes = 0;
  581.     castattacking = false;
  582.     if (mobjinfo[castorder[castnum].type].deathsound)
  583.     S_StartSound (NULL, mobjinfo[castorder[castnum].type].deathsound);
  584.     
  585.     return true;
  586. }
  587.  
  588.  
  589. void F_CastPrint (char* text)
  590. {
  591.     char*    ch;
  592.     int        c;
  593.     int        cx;
  594.     int        w;
  595.     int        width;
  596.     
  597.     /*  find width */
  598.     ch = text;
  599.     width = 0;
  600.     
  601.     while (ch)
  602.     {
  603.     c = *ch++;
  604.     if (!c)
  605.         break;
  606.     c = toupper(c) - HU_FONTSTART;
  607.     if (c < 0 || c> HU_FONTSIZE)
  608.     {
  609.         width += 4;
  610.         continue;
  611.     }
  612.         
  613.     w = SHORT (hu_font[c]->width);
  614.     width += w;
  615.     }
  616.     
  617.     /*  draw it */
  618.     cx = 160-width/2;
  619.     ch = text;
  620.     while (ch)
  621.     {
  622.     c = *ch++;
  623.     if (!c)
  624.         break;
  625.     c = toupper(c) - HU_FONTSTART;
  626.     if (c < 0 || c> HU_FONTSIZE)
  627.     {
  628.         cx += 4;
  629.         continue;
  630.     }
  631.         
  632.     w = SHORT (hu_font[c]->width);
  633.     V_DrawPatch(cx, 180, 0, hu_font[c]);
  634.     cx+=w;
  635.     }
  636.     
  637. }
  638.  
  639.  
  640. /*  */
  641. /*  F_CastDrawer */
  642. /*  */
  643. /* void V_DrawPatchFlipped (int x, int y, int scrn, patch_t *patch); */
  644.  
  645. void F_CastDrawer (void)
  646. {
  647.     spritedef_t*    sprdef;
  648.     spriteframe_t*    sprframe;
  649.     int            lump;
  650.     boolean        flip;
  651.     patch_t*        patch;
  652.     
  653.     /*  erase the entire screen to a background */
  654.     V_DrawPatch (0,0,0, W_CacheLumpName ("BOSSBACK", PU_CACHE));
  655.  
  656.     F_CastPrint (castorder[castnum].name);
  657.     
  658.     /*  draw the current frame in the middle of the screen */
  659.     sprdef = &sprites[caststate->sprite];
  660.     sprframe = &sprdef->spriteframes[ caststate->frame & FF_FRAMEMASK];
  661.     lump = sprframe->lump[0];
  662.     flip = (boolean)sprframe->flip[0];
  663.             
  664.     patch = W_CacheLumpNum (lump+firstspritelump, PU_CACHE);
  665.     if (flip)
  666.     V_DrawPatchFlipped (160,170,0,patch);
  667.     else
  668.     V_DrawPatch (160,170,0,patch);
  669. }
  670.  
  671.  
  672. /*  */
  673. /*  F_DrawPatchCol */
  674. /*  */
  675. void
  676. F_DrawPatchCol8
  677. ( int        x,
  678.   patch_t*    patch,
  679.   int        col )
  680. {
  681.     column_t*    column;
  682.     byte*    source;
  683.     byte*    dest;
  684.     byte*    desttop;
  685.     int        count;
  686.     
  687.     column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
  688.     desttop = screens[0]+x;
  689.  
  690.     /*  step through the posts in a column */
  691.     while (column->topdelta != 0xff )
  692.     {
  693.     source = (byte *)column + 3;
  694.     dest = desttop + column->topdelta*SCREENWIDTH;
  695.     count = column->length;
  696.         
  697.     while (count--)
  698.     {
  699.         *dest = *source++;
  700.         dest += SCREENWIDTH;
  701.     }
  702.     column = (column_t *)(  (byte *)column + column->length + 4 );
  703.     }
  704. }
  705.  
  706. void
  707. F_DrawPatchCol16
  708. ( int        x,
  709.   patch_t*    patch,
  710.   int        col )
  711. {
  712.     column_t*    column;
  713.     byte*    source;
  714.     unsigned short    *desttop,*dest;
  715.     int        count;
  716.     
  717.     column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
  718.     desttop = (unsigned short *) (screens[0])+x;
  719.  
  720.     /*  step through the posts in a column */
  721.     while (column->topdelta != 0xff )
  722.     {
  723.     source = (byte *)column + 3;
  724.     dest = desttop + column->topdelta*SCREENWIDTH;
  725.     count = column->length;
  726.         
  727.     while (count--)
  728.     {
  729.         *dest = truecolor_palette[*source++];
  730.         dest += SCREENWIDTH;
  731.     }
  732.     column = (column_t *)(  (byte *)column + column->length + 4 );
  733.     }
  734. }
  735.  
  736. void
  737. F_DrawPatchCol24
  738. ( int        x,
  739.   patch_t*    patch,
  740.   int        col )
  741. {
  742.     column_t*    column;
  743.     byte*    source;
  744.     byte*    dest;
  745.     byte*    desttop;
  746.     int        count;
  747.  
  748.     unsigned long    couleur;
  749.     
  750.     column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
  751.     desttop = screens[0]+x*3;
  752.  
  753.     /*  step through the posts in a column */
  754.     while (column->topdelta != 0xff )
  755.     {
  756.     source = (byte *)column + 3;
  757.     dest = desttop + column->topdelta*SCREENWIDTH*3;
  758.     count = column->length;
  759.         
  760.     while (count--)
  761.     {
  762.         couleur = truecolor_palette[*source++];
  763.  
  764.         *dest++ = couleur; 
  765.         *dest++ = couleur >> 8; 
  766.         *dest++ = couleur >> 16; 
  767.  
  768.         dest += (SCREENWIDTH*3)-3;
  769.     }
  770.     column = (column_t *)(  (byte *)column + column->length + 4 );
  771.     }
  772. }
  773.  
  774. void
  775. F_DrawPatchCol32
  776. ( int        x,
  777.   patch_t*    patch,
  778.   int        col )
  779. {
  780.     column_t*    column;
  781.     byte*    source;
  782.     unsigned long    *desttop,*dest;
  783.     int        count;
  784.     
  785.     column = (column_t *)((byte *)patch + LONG(patch->columnofs[col]));
  786.     desttop = (unsigned long *) (screens[0])+x;
  787.  
  788.     /*  step through the posts in a column */
  789.     while (column->topdelta != 0xff )
  790.     {
  791.     source = (byte *)column + 3;
  792.     dest = desttop + column->topdelta*SCREENWIDTH;
  793.     count = column->length;
  794.         
  795.     while (count--)
  796.     {
  797.         *dest = truecolor_palette[*source++];
  798.         dest += SCREENWIDTH;
  799.     }
  800.     column = (column_t *)(  (byte *)column + column->length + 4 );
  801.     }
  802. }
  803.  
  804. /*  */
  805. /*  F_BunnyScroll */
  806. /*  */
  807. void F_BunnyScroll (void)
  808. {
  809.     int        scrolled;
  810.     int        x;
  811.     patch_t*    p1;
  812.     patch_t*    p2;
  813.     char    name[10];
  814.     int        stage;
  815.     static int    laststage;
  816.         
  817.     p1 = W_CacheLumpName ("PFUB2", PU_LEVEL);
  818.     p2 = W_CacheLumpName ("PFUB1", PU_LEVEL);
  819.  
  820.     V_MarkRect (0, 0, SCREENWIDTH, SCREENHEIGHT);
  821.     
  822.     scrolled = 320 - (finalecount-230)/2;
  823.     if (scrolled > 320)
  824.     scrolled = 320;
  825.     if (scrolled < 0)
  826.     scrolled = 0;
  827.         
  828.     for ( x=0 ; x<SCREENWIDTH ; x++)
  829.     {
  830.     if (x+scrolled < 320)
  831.         F_DrawPatchCol (x, p1, x+scrolled);
  832.     else
  833.         F_DrawPatchCol (x, p2, x+scrolled - 320);        
  834.     }
  835.     
  836.     if (finalecount < 1130)
  837.     return;
  838.     if (finalecount < 1180)
  839.     {
  840.     V_DrawPatch ((SCREENWIDTH-13*8)/2,
  841.              (SCREENHEIGHT-8*8)/2,0, W_CacheLumpName ("END0",PU_CACHE));
  842.     laststage = 0;
  843.     return;
  844.     }
  845.     
  846.     stage = (finalecount-1180) / 5;
  847.     if (stage > 6)
  848.     stage = 6;
  849.     if (stage > laststage)
  850.     {
  851.     S_StartSound (NULL, sfx_pistol);
  852.     laststage = stage;
  853.     }
  854.     
  855.     sprintf (name,"END%i",stage);
  856.     V_DrawPatch ((SCREENWIDTH-13*8)/2, (SCREENHEIGHT-8*8)/2,0, W_CacheLumpName (name,PU_CACHE));
  857. }
  858.  
  859.  
  860. /*  */
  861. /*  F_Drawer */
  862. /*  */
  863. void F_Drawer (void)
  864. {
  865.     if (finalestage == 2)
  866.     {
  867.     F_CastDrawer ();
  868.     return;
  869.     }
  870.  
  871.     if (!finalestage)
  872.     F_TextWrite ();
  873.     else
  874.     {
  875.     switch (gameepisode)
  876.     {
  877.       case 1:
  878.         if ( gamemode == retail )
  879.           V_DrawPatch (0,0,0,
  880.              W_CacheLumpName("CREDIT",PU_CACHE));
  881.         else
  882.           V_DrawPatch (0,0,0,
  883.              W_CacheLumpName("HELP2",PU_CACHE));
  884.         break;
  885.       case 2:
  886.         V_DrawPatch(0,0,0,
  887.             W_CacheLumpName("VICTORY2",PU_CACHE));
  888.         break;
  889.       case 3:
  890.         F_BunnyScroll ();
  891.         break;
  892.       case 4:
  893.         V_DrawPatch (0,0,0,
  894.              W_CacheLumpName("ENDPIC",PU_CACHE));
  895.         break;
  896.     }
  897.     }
  898.             
  899. }
  900.