DOOM64-RE

DOOM 64 Reverse Engineering
Log | Files | Refs | README | LICENSE

f_main.c (25522B)


      1 /* f_main.c -- finale */
      2 
      3 #include "doomdef.h"
      4 #include "p_local.h"
      5 #include "st_main.h"
      6 #include "r_local.h"
      7 
      8 #define T_NULL	        ""
      9 
     10 #define C_END1_TXT01	"you cackle as the"
     11 #define C_END1_TXT02	"familiarity of the"
     12 #define C_END1_TXT03	"situation occurs to you."
     13 #define C_END1_TXT04	"The gateway to the Demons"
     14 #define C_END1_TXT05	"domain was too accessible."
     15 #define C_END1_TXT06	"You realize the demons mock"
     16 #define C_END1_TXT07	"you with their invitation."
     17 #define C_END1_TXT08	"It does not matter..."
     18 #define C_END1_TXT09	"The demons spawn like rats"
     19 #define C_END1_TXT10	"and you have the grade AAA"
     20 #define C_END1_TXT11	"U.A.C. poison they crave."
     21 #define C_END1_TXT12	"Your bloodthirsty scream"
     22 #define C_END1_TXT13	"shatters the teleport haze."
     23 #define C_END1_TXT14	"Once again you find yourself"
     24 #define C_END1_TXT15	"amidst..."
     25 
     26 #define C_END2_TXT01	"The vast silence reminds"
     27 #define C_END2_TXT02	"you of the military morgue."
     28 #define C_END2_TXT03	" "
     29 #define C_END2_TXT04	"You knew the installation"
     30 #define C_END2_TXT05	"had a classified level."
     31 #define C_END2_TXT06	" "
     32 #define C_END2_TXT07	"The U.A.C. had some good"
     33 #define C_END2_TXT08	"reason to hide this place."
     34 #define C_END2_TXT09	" "
     35 #define C_END2_TXT10	"You wonder what it"
     36 #define C_END2_TXT11	"could be..."
     37 
     38 #define C_END3_TXT01	"You smile."
     39 #define C_END3_TXT02	" "
     40 #define C_END3_TXT03	"What strange place have"
     41 #define C_END3_TXT04	"you stumbled upon?"
     42 #define C_END3_TXT05	" "
     43 #define C_END3_TXT06	"The Demons did not expect"
     44 #define C_END3_TXT07	"you to survive this far."
     45 #define C_END3_TXT08	"You feel their demonic"
     46 #define C_END3_TXT09	"presence waiting for you..."
     47 #define C_END3_TXT10	" "
     48 #define C_END3_TXT11	"Let them taste their guts!"
     49 
     50 #define C_END4_TXT01	"You wretch as a strange"
     51 #define C_END4_TXT02	"acrid odor assaults you."
     52 #define C_END4_TXT03	" "
     53 #define C_END4_TXT04	"Death and Demon carcass!"
     54 #define C_END4_TXT05	" "
     55 #define C_END4_TXT06	"No nightmare could have"
     56 #define C_END4_TXT07	"prepared you for this."
     57 #define C_END4_TXT08	" "
     58 #define C_END4_TXT09	"You realize that this"
     59 #define C_END4_TXT10	"place was not meant for"
     60 #define C_END4_TXT11	"living humans."
     61 
     62 #define C_END5_TXT01	"Congratulations!"
     63 #define C_END5_TXT02	"You found..."
     64 #define C_END5_TXT03	" "
     65 #define C_END5_TXT04	"HECTIC"
     66 #define C_END5_TXT05	" "
     67 #define C_END5_TXT06	"Only the best will reap"
     68 #define C_END5_TXT07	"its rewards."
     69 
     70 #define C_END6_TXT01	"Finally..."
     71 #define C_END6_TXT02	"The mother of all demons"
     72 #define C_END6_TXT03	"is dead!"
     73 #define C_END6_TXT04	" "
     74 #define C_END6_TXT05	"The blood pours from"
     75 #define C_END6_TXT06	"your eyes as you stand"
     76 #define C_END6_TXT07	"in defiance."
     77 #define C_END6_TXT08	" "
     78 #define C_END6_TXT09	"As the only marine to"
     79 #define C_END6_TXT10	"endure the slaughter-"
     80 #define C_END6_TXT11	"you decide to remain"
     81 #define C_END6_TXT12	"in Hell and ensure no"
     82 #define C_END6_TXT13	"demon ever rises again."
     83 #define C_END6_TXT14	" "
     84 #define C_END6_TXT15	"The End."
     85 
     86 char *endcluster1[] =   // 8005A2C0
     87 {
     88     C_END1_TXT01,
     89 	C_END1_TXT02,
     90 	C_END1_TXT03,
     91 	C_END1_TXT04,
     92 	C_END1_TXT05,
     93 	C_END1_TXT06,
     94 	C_END1_TXT07,
     95 	C_END1_TXT08,
     96 	C_END1_TXT09,
     97 	C_END1_TXT10,
     98 	C_END1_TXT11,
     99 	C_END1_TXT12,
    100 	C_END1_TXT13,
    101 	C_END1_TXT14,
    102 	C_END1_TXT15,
    103 	T_NULL
    104 };
    105 
    106 char *endcluster2[] =   // 8005A300
    107 {
    108     C_END2_TXT01,
    109 	C_END2_TXT02,
    110 	C_END2_TXT03,
    111 	C_END2_TXT04,
    112 	C_END2_TXT05,
    113 	C_END2_TXT06,
    114 	C_END2_TXT07,
    115 	C_END2_TXT08,
    116 	C_END2_TXT09,
    117 	C_END2_TXT10,
    118 	C_END2_TXT11,
    119 	T_NULL
    120 };
    121 
    122 char *endcluster3[] =   // 8005A330
    123 {
    124     C_END3_TXT01,
    125 	C_END3_TXT02,
    126 	C_END3_TXT03,
    127 	C_END3_TXT04,
    128 	C_END3_TXT05,
    129 	C_END3_TXT06,
    130 	C_END3_TXT07,
    131 	C_END3_TXT08,
    132 	C_END3_TXT09,
    133 	C_END3_TXT10,
    134 	C_END3_TXT11,
    135 	T_NULL
    136 };
    137 
    138 char *endcluster4[] =   // 8005A360
    139 {
    140     C_END4_TXT01,
    141 	C_END4_TXT02,
    142 	C_END4_TXT03,
    143 	C_END4_TXT04,
    144 	C_END4_TXT05,
    145 	C_END4_TXT06,
    146 	C_END4_TXT07,
    147 	C_END4_TXT08,
    148 	C_END4_TXT09,
    149 	C_END4_TXT10,
    150 	C_END4_TXT11,
    151 	T_NULL
    152 };
    153 
    154 char *endcluster5[] =   // 8005A390
    155 {
    156     C_END5_TXT01,
    157 	C_END5_TXT02,
    158 	C_END5_TXT03,
    159 	C_END5_TXT04,
    160 	C_END5_TXT05,
    161 	C_END5_TXT06,
    162 	C_END5_TXT07,
    163 	T_NULL
    164 };
    165 
    166 char *endcluster6[] =   // 8005A3B0
    167 {
    168     C_END6_TXT01,
    169 	C_END6_TXT02,
    170 	C_END6_TXT03,
    171 	C_END6_TXT04,
    172 	C_END6_TXT05,
    173 	C_END6_TXT06,
    174 	C_END6_TXT07,
    175 	C_END6_TXT08,
    176 	C_END6_TXT09,
    177 	C_END6_TXT10,
    178 	C_END6_TXT11,
    179 	C_END6_TXT12,
    180 	C_END6_TXT13,
    181 	C_END6_TXT14,
    182 	C_END6_TXT15,
    183 	T_NULL
    184 };
    185 
    186 //
    187 // Character cast strings F_FINALE.C
    188 //
    189 #define CC_ZOMBIE	"Zombieman"
    190 #define CC_SHOTGUN	"Shotgun Guy"
    191 //#define CC_HEAVY	"Heavy Weapon Dude" // Enemy Removed
    192 #define CC_IMP		"Imp"
    193 #define CC_NIMP		"Nightmare Imp" // New Enemy on Doom64
    194 #define CC_DEMON	"Demon"
    195 #define CC_SPECT	"Spectre"   // New Enemy on Doom64
    196 #define CC_LOST		"Lost Soul"
    197 #define CC_CACO		"Cacodemon"
    198 #define CC_HELL		"Hell Knight"
    199 #define CC_BARON	"Baron Of Hell"
    200 #define CC_ARACH	"Arachnotron"
    201 #define CC_PAIN		"Pain Elemental"
    202 //#define CC_REVEN	"Revenant"  // Enemy Removed
    203 #define CC_MANCU	"Mancubus"
    204 //#define CC_ARCH	"Arch-Vile" // Enemy Removed
    205 //#define CC_SPIDER	"The Spider Mastermind" // Enemy Removed
    206 #define CC_CYBER	"The Cyberdemon"
    207 #define CC_HERO		"Our Hero"
    208 
    209 //
    210 // Final DOOM 2 animation
    211 // Casting by id Software.
    212 // in order of appearance
    213 //
    214 typedef struct
    215 {
    216 	char		*name;
    217 	mobjtype_t	type;
    218 } castinfo_t;
    219 
    220 static castinfo_t	castorder[] = // 8005A3F0
    221 {
    222 	{ CC_ZOMBIE, MT_POSSESSED1 },// MT_POSSESSED
    223 	{ CC_SHOTGUN, MT_POSSESSED2 },// MT_SHOTGUY
    224 	//{ CC_HEAVY, MT_CHAINGUY },
    225 	{ CC_IMP, MT_IMP1 },// MT_TROOP
    226 	{ CC_NIMP, MT_IMP2 },// MT_TROOP2
    227 	{ CC_DEMON, MT_DEMON1 },// MT_SERGEANT
    228 	{ CC_SPECT, MT_DEMON2 },// MT_SERGEANT2
    229 	{ CC_LOST, MT_SKULL },// MT_SKULL
    230 	{ CC_CACO, MT_CACODEMON },// MT_HEAD
    231 	{ CC_HELL, MT_BRUISER2 },// MT_KNIGHT
    232 	{ CC_BARON, MT_BRUISER1 },// MT_BRUISER
    233 	{ CC_ARACH, MT_BABY },// MT_BABY
    234 	{ CC_PAIN, MT_PAIN },// MT_PAIN
    235 	//{ CC_REVEN, MT_UNDEAD },
    236 	{ CC_MANCU, MT_MANCUBUS },// MT_FATSO
    237 	//{ CC_ARCH, MT_VILE },
    238 	//{ CC_SPIDER, MT_SPIDER },
    239 	{ CC_CYBER, MT_CYBORG },// MT_CYBORG
    240 	{ CC_HERO, MT_PLAYER },// MT_PLAYER
    241 	{ NULL, 0 }
    242 };
    243 
    244 typedef enum
    245 {
    246     F_STAGE_FADEIN_BACKGROUD,
    247     F_STAGE_DRAWTEXT,
    248     F_STAGE_SCROLLTEXT,
    249     F_STAGE_FADEOUT_BACKGROUD,
    250     F_STAGE_CAST
    251 } finalestage_t;
    252 
    253 static int textypos;			// 800631F0
    254 static int textline;			// 800631F4
    255 static char **text;			    // 800631F8
    256 static int textalpha;			// 800631FC
    257 
    258 /*
    259 =================
    260 =
    261 = F_StartIntermission
    262 =
    263 =================
    264 */
    265 
    266 void F_StartIntermission(void) // 80002CD0
    267 {
    268     if ((gamemap == 8) && (nextmap == 9))
    269     {
    270         text = endcluster1;
    271         textypos = 15;
    272     }
    273     else if ((gamemap == 4) && (nextmap == 29))
    274     {
    275         text = endcluster2;
    276         textypos = 43;
    277     }
    278     else if ((gamemap == 12) && (nextmap == 30))
    279     {
    280         text = endcluster3;
    281         textypos = 43;
    282     }
    283     else if ((gamemap == 18) && (nextmap == 31))
    284     {
    285         text = endcluster4;
    286         textypos = 43;
    287     }
    288     else if ((gamemap == 1) && (nextmap == 32))
    289     {
    290         text = endcluster5;
    291         textypos = 71;
    292     }
    293 
    294     DrawerStatus = 2;
    295     textline = 0;
    296     textalpha = 0;
    297 }
    298 
    299 /*
    300 =================
    301 =
    302 = F_StopIntermission
    303 =
    304 =================
    305 */
    306 
    307 void F_StopIntermission(void) // 80002E14
    308 {
    309     gamepaused = false;
    310     DrawerStatus = 0;
    311     I_WIPE_FadeOutScreen();
    312 }
    313 
    314 /*
    315 =================
    316 =
    317 = F_TickerIntermission
    318 =
    319 =================
    320 */
    321 
    322 int F_TickerIntermission(void) // 80002E44
    323 {
    324 	unsigned int buttons, oldbuttons, exit;
    325 
    326 	gameaction = ga_nothing;
    327 	P_CheckCheats();
    328 
    329 	exit = gameaction;
    330 	if (!gamepaused)
    331 	{
    332 	    buttons = ticbuttons[0] & 0xffff0000;
    333         oldbuttons = oldticbuttons[0] & 0xffff0000;
    334 
    335 	    exit = ga_nothing;
    336 
    337         if(*text[textline])
    338         {
    339             textalpha += 8;
    340             if (textalpha > 255)
    341             {
    342                 textalpha = 0;
    343                 textline++;
    344             }
    345         }
    346         else if ((buttons != oldbuttons) && (buttons & (ALL_CBUTTONS|ALL_TRIG|PAD_A|PAD_B)))
    347         {
    348             exit = ga_exit;
    349         }
    350 	}
    351 
    352 	return exit;
    353 }
    354 
    355 /*
    356 =================
    357 =
    358 = F_DrawerIntermission
    359 =
    360 =================
    361 */
    362 
    363 void F_DrawerIntermission(void) // 80002F14
    364 {
    365     int i, ypos;
    366     I_ClearFrame();
    367 
    368     gDPPipeSync(GFX1++);
    369     gDPSetCycleType(GFX1++, G_CYC_FILL);
    370     gDPSetRenderMode(GFX1++,G_RM_NOOP,G_RM_NOOP2);
    371     gDPSetColorImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD, OS_K0_TO_PHYSICAL(cfb[vid_side]));
    372     // Fill borders with black
    373     gDPSetFillColor(GFX1++, GPACK_RGBA5551(0,0,0,0) << 16 | GPACK_RGBA5551(0,0,0,0)) ;
    374     gDPFillRectangle(GFX1++, 0, 0, SCREEN_WD-1, SCREEN_HT-1);
    375 
    376     M_DrawBackground(63, 25, 128, "EVIL");
    377 
    378     ypos = textypos;
    379     for(i = 0; i < textline; i++)
    380     {
    381         ST_DrawString(-1, ypos, text[i], 0xc0c0c0ff);
    382         ypos += 14;
    383     }
    384 
    385     ST_DrawString(-1, ypos, text[i], textalpha | 0xc0c0c000);
    386 
    387     if (MenuCall)
    388     {
    389         M_DrawOverlay(0, 0, 320, 240, 96);
    390         MenuCall();
    391     }
    392 
    393     I_DrawFrame();
    394 }
    395 
    396 static finalestage_t	finalestage;	// 80063200
    397 static int				castnum;		// 80063204
    398 static int				casttics;		// 80063208
    399 static state_t         *caststate;		// 8006320C
    400 static boolean			castdeath;		// 80063210
    401 static int				castframes;		// 80063214
    402 static int				castonmelee;	// 80063218
    403 static int              castrotation;   // 8006321C
    404 static int              castfadein;     // 80063220
    405 static int              fadeinout;      // 80063224
    406 
    407 /*
    408 =================
    409 =
    410 = F_Start/Cast_Start
    411 =
    412 =================
    413 */
    414 
    415 void F_Start(void) // 8000313C
    416 {
    417 	DrawerStatus = 3;
    418 	finalestage = F_STAGE_FADEIN_BACKGROUD;
    419 	fadeinout = 0;
    420 	textypos = 15;
    421 	textline = 0;
    422 	textalpha = 0;
    423 	castnum = 0;
    424 	caststate = &states[mobjinfo[castorder[castnum].type].seestate];
    425 	casttics = states[mobjinfo[castorder[castnum].type].seestate].tics;
    426 	castdeath = false;
    427 	castframes = 0;
    428 	castonmelee = 0;
    429 	castrotation = 0;
    430 	castfadein = 0;
    431 
    432 	S_StartMusic(113);
    433 }
    434 
    435 /*
    436 =================
    437 =
    438 = F_Stop/Cast_Stop
    439 =
    440 =================
    441 */
    442 
    443 void F_Stop(void) // 80003220
    444 {
    445     gamepaused = false;
    446     DrawerStatus = 0;
    447     S_StopMusic();
    448     I_WIPE_FadeOutScreen();
    449 }
    450 
    451 /*
    452 =================
    453 =
    454 = F_Ticker/Cast_Ticker
    455 =
    456 =================
    457 */
    458 
    459 int F_Ticker(void) // 80003258
    460 {
    461     unsigned int buttons, oldbuttons;
    462 	int	st, sfx;
    463 
    464 	buttons = ticbuttons[0] = M_ButtonResponder(ticbuttons[0]);
    465 	oldbuttons = oldticbuttons[0] & 0xffff0000;
    466 
    467 	gameaction = ga_nothing;
    468 	P_CheckCheats();
    469 
    470 	if (gamepaused != 0)
    471 	{
    472 		return gameaction;
    473 	}
    474 
    475     switch(finalestage)
    476     {
    477         case F_STAGE_FADEIN_BACKGROUD:
    478             fadeinout += 6;
    479             if (fadeinout > 160)
    480             {
    481                 fadeinout = 160;
    482                 finalestage = F_STAGE_DRAWTEXT;
    483             }
    484             break;
    485 
    486         case F_STAGE_DRAWTEXT:
    487             if (*endcluster6[textline])
    488             {
    489                 textalpha += 8;
    490                 if (textalpha > 255)
    491                 {
    492                     textalpha = 0;
    493                     textline++;
    494                 }
    495             }
    496             else
    497             {
    498                 finalestage = F_STAGE_SCROLLTEXT;
    499             }
    500             break;
    501 
    502         case F_STAGE_SCROLLTEXT:
    503             textypos -= 1;
    504             if (textypos < -200)
    505             {
    506                 finalestage = F_STAGE_FADEOUT_BACKGROUD;
    507             }
    508             break;
    509 
    510         case F_STAGE_FADEOUT_BACKGROUD:
    511             fadeinout -= 6;
    512             if (fadeinout < 0)
    513             {
    514                 fadeinout = 0;
    515                 finalestage = F_STAGE_CAST;
    516             }
    517             break;
    518 
    519         case F_STAGE_CAST:
    520             fadeinout += 6;
    521             if (fadeinout > 128)
    522             {
    523                 fadeinout = 128;
    524             }
    525 
    526             if (castdeath == false)
    527 			{
    528 			    if (buttons != oldbuttons)
    529 			    {
    530 			        if (buttons & PAD_LEFT)
    531                     {
    532                         castrotation += 1;
    533                         if (castrotation > 7) {
    534                             castrotation = 0;
    535                         }
    536                     }
    537                     else if (buttons & PAD_RIGHT)
    538                     {
    539                         castrotation -= 1;
    540                         if (castrotation < 0) {
    541                             castrotation = 7;
    542                         }
    543                     }
    544                     else if (buttons & (ALL_CBUTTONS|ALL_TRIG|PAD_A|PAD_B))
    545                     {
    546                         S_StartSound(NULL, sfx_shotgun); // sfx_shotgn
    547 
    548                         /* go into death frame */
    549                         if (mobjinfo[castorder[castnum].type].deathsound)
    550                             S_StartSound(NULL, mobjinfo[castorder[castnum].type].deathsound);
    551 
    552                         caststate = &states[mobjinfo[castorder[castnum].type].deathstate];
    553                         castframes = 0;
    554                         castdeath = true;
    555 
    556                         if(castorder[castnum].type == MT_CYBORG) {
    557                             casttics = 10;
    558                         }
    559                         else {
    560                             casttics = caststate->tics;
    561                         }
    562 
    563                     }
    564 			    }
    565 			}
    566 
    567 			if (gametic > gamevbls)
    568 			{
    569                 if (castfadein < 192) {
    570                     castfadein += 2;
    571                 }
    572 
    573                 /* advance state*/
    574                 if (--casttics > 0)
    575                     return ga_nothing;  /* not time to change state yet */
    576 
    577 				if (castdeath && caststate->nextstate == S_000) // S_NULL
    578 				{
    579 					/* switch from deathstate to next monster */
    580 					castrotation = 0;
    581 					castnum++;
    582 					castfadein = 0;
    583 					castdeath = false;
    584 
    585 					if (castorder[castnum].name == NULL)
    586 						castnum = 0;
    587 
    588 					if (mobjinfo[castorder[castnum].type].seesound)
    589 						S_StartSound(NULL, mobjinfo[castorder[castnum].type].seesound);
    590 
    591 					caststate = &states[mobjinfo[castorder[castnum].type].seestate];
    592 					castframes = 0;
    593 				}
    594 
    595 				st = caststate->nextstate;
    596 				caststate = &states[st];
    597 
    598 				if (castdeath == false)
    599                 {
    600                     castframes++;
    601 
    602                     if (castframes == 12)
    603                     {   /* go into attack frame */
    604                         if (castonmelee)
    605                             caststate = &states[mobjinfo[castorder[castnum].type].meleestate];
    606                         else
    607                             caststate = &states[mobjinfo[castorder[castnum].type].missilestate];
    608 
    609                         castonmelee ^= 1;
    610 
    611                         if (caststate == &states[S_000]) // S_NULL
    612                         {
    613                             if (castonmelee)
    614                                 caststate = &states[mobjinfo[castorder[castnum].type].meleestate];
    615                             else
    616                                 caststate = &states[mobjinfo[castorder[castnum].type].missilestate];
    617                         }
    618                     }
    619 
    620                     if (((castframes == 20) && (castorder[castnum].type == MT_MANCUBUS)) ||
    621                           castframes == 24 || caststate == &states[S_001])//S_PLAY
    622                     {
    623                         caststate = &states[mobjinfo[castorder[castnum].type].seestate];
    624                         castframes = 0;
    625                     }
    626                 }
    627 
    628 				casttics = caststate->tics;
    629 				if (casttics == -1)
    630 					casttics = TICRATE;
    631 
    632                 /* sound hacks.... */
    633                 st = ((int)caststate - (int)states) / sizeof(state_t);
    634                 switch (st)
    635                 {
    636                     case S_007: // S_PLAY_ATK2
    637                         sfx = sfx_sht2fire; // sfx_dshtgn
    638                         break;
    639 
    640                     case S_055: // S_SARG_ATK2
    641                         sfx = sfx_sargatk; // sfx_sgtatk
    642                         break;
    643 
    644                     case S_084: // S_FATT_ATK8
    645                     case S_086: // S_FATT_ATK5
    646                     case S_088: // S_FATT_ATK2
    647                         sfx = sfx_bdmissile; // sfx_firsht
    648                         break;
    649 
    650                     case S_109: // S_POSS_ATK2
    651                         sfx = sfx_pistol;
    652                         break;
    653 
    654                     case S_138: // S_SPOS_ATK2
    655                         sfx = sfx_shotgun; // sfx_shotgn
    656                         break;
    657 
    658                     case S_166:   // S_TROO_ATK3
    659                         sfx = sfx_scratch; // sfx_claw
    660                         break;
    661 
    662                     case S_169: // S_TROO_ATK
    663                     case S_199: // S_HEAD_ATK2
    664                     case S_222: // S_BOSS_ATK2
    665                     case S_243: // S_BOS2_ATK2
    666                         sfx = sfx_bdmissile; // sfx_firsht
    667                         break;
    668 
    669                     case S_261: // S_SKULL_ATK2
    670                         sfx = sfx_skullatk; // sfx_sklatk
    671                         break;
    672 
    673                     case S_288: // S_BSPI_ATK2
    674                         sfx = sfx_plasma; // sfx_plasma
    675                         break;
    676 
    677                     case S_307: // S_CYBER_ATK2
    678                     case S_309: // S_CYBER_ATK4
    679                     case S_311: // S_CYBER_ATK6
    680                         sfx = sfx_missile; // sfx_rlaunc
    681                         break;
    682 
    683                     case S_328: // S_PAIN_ATK3
    684                         sfx = sfx_skullatk; // sfx_sklatk
    685                         break;
    686 
    687                     //case S_VILE_ATK2:
    688                         //sfx = sfx_vilatk;
    689                         //break;
    690 
    691                     //case S_SKEL_FIST2:
    692                         //sfx = sfx_skeswg;
    693                         //break;
    694 
    695                     //case S_SKEL_FIST4:
    696                         //sfx = sfx_skepch;
    697                         //break;
    698 
    699                     //case S_SKEL_MISS2:
    700                         //sfx = sfx_skeatk;
    701                         //break;
    702 
    703                     //case S_CPOS_ATK2:
    704                     //case S_CPOS_ATK3:
    705                     //case S_CPOS_ATK4:
    706                         //sfx = sfx_pistol;
    707                         //break;
    708 
    709                     //case S_SPID_ATK2:
    710                     //case S_SPID_ATK3:
    711                         //sfx = sfx_pistol;
    712                         //break;
    713 
    714                     default:
    715                         sfx = 0;
    716                         break;
    717                 }
    718 
    719                 if (sfx)
    720                     S_StartSound(NULL, sfx);
    721 			}
    722 
    723             break;
    724 
    725         default:
    726             break;
    727     }
    728 
    729 	return ga_nothing;
    730 }
    731 
    732 /*
    733 =================
    734 =
    735 = F_Drawer/Cast_Drawer
    736 =
    737 =================
    738 */
    739 void F_Drawer(void) // 800039DC
    740 {
    741 	int i, type, alpha, ypos;
    742 	char buff[64];
    743 
    744 	I_ClearFrame();
    745 
    746     gDPPipeSync(GFX1++);
    747     gDPSetCycleType(GFX1++, G_CYC_FILL);
    748     gDPSetRenderMode(GFX1++,G_RM_NOOP,G_RM_NOOP2);
    749     gDPSetColorImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_32b, SCREEN_WD, OS_K0_TO_PHYSICAL(cfb[vid_side]));
    750     // Fill borders with black
    751     gDPSetFillColor(GFX1++, GPACK_RGBA5551(0,0,0,0) << 16 | GPACK_RGBA5551(0,0,0,0)) ;
    752     gDPFillRectangle(GFX1++, 0, 0, SCREEN_WD-1, SCREEN_HT-1);
    753 
    754     switch(finalestage)
    755     {
    756         case F_STAGE_FADEIN_BACKGROUD:
    757         case F_STAGE_FADEOUT_BACKGROUD:
    758             M_DrawBackground(0, 0, fadeinout, "FINAL");
    759             break;
    760 
    761         case F_STAGE_DRAWTEXT:
    762         case F_STAGE_SCROLLTEXT:
    763             M_DrawBackground(0, 0, fadeinout, "FINAL");
    764 
    765             ypos = textypos;
    766             for(i = 0; i < textline; i++)
    767             {
    768                 ST_DrawString(-1, ypos, endcluster6[i], 0xc0c0c0ff);
    769                 ypos += 14;
    770             }
    771 
    772             ST_DrawString(-1, ypos, endcluster6[i], textalpha | 0xc0c0c000);
    773             break;
    774 
    775         case F_STAGE_CAST:
    776             M_DrawBackground(63, 25, fadeinout, "EVIL");
    777 
    778             type = castorder[castnum].type;
    779 
    780             if (type == MT_DEMON2){
    781                 alpha = 48;
    782             }
    783             else {
    784                 alpha = mobjinfo[type].alpha;
    785             }
    786 
    787             BufferedDrawSprite(type, caststate, castrotation,
    788                                PACKRGBA(castfadein, castfadein, castfadein, alpha), 160, 190);
    789 
    790             ST_DrawString(-1, 208, castorder[castnum].name, 0xC00000ff);
    791             break;
    792 
    793         default:
    794             break;
    795     }
    796 
    797 	if (MenuCall)
    798     {
    799         M_DrawOverlay(0, 0, 320, 240, 96);
    800         MenuCall();
    801     }
    802 
    803     I_DrawFrame();
    804 }
    805 
    806 void BufferedDrawSprite(int type, state_t *state, int rotframe, int color, int xpos, int ypos) // 80003D1C
    807 {
    808     spritedef_t     *sprdef;
    809 	spriteframe_t   *sprframe;
    810 	int			    lump;
    811 	boolean		    flip;
    812 
    813 	byte *data;
    814 	byte *paldata;
    815 	byte *src;
    816 
    817 	int compressed;
    818     int tileh;
    819     int tilew;
    820     int height;
    821     int width;
    822     int width2;
    823     int tiles;
    824     int xoffs;
    825     int yoffs;
    826 
    827     int tilecnt;
    828     int dsdx;
    829     int spos;
    830     int tpos;
    831     int x1;
    832     int y1;
    833     int xh;
    834     int yh;
    835 
    836     // draw the current frame in the middle of the screen
    837     sprdef = &sprites[state->sprite];
    838     sprframe = &sprdef->spriteframes[state->frame & FF_FRAMEMASK];
    839     lump = sprframe->lump[rotframe];
    840     flip = (boolean)sprframe->flip[rotframe];
    841 
    842 	gDPPipeSync(GFX1++);
    843 	gDPSetCycleType(GFX1++, G_CYC_1CYCLE);
    844 	gDPSetTexturePersp(GFX1++, G_TP_NONE);
    845 	gDPSetTextureLUT(GFX1++, G_TT_RGBA16);
    846 	gDPSetAlphaCompare(GFX1++, G_AC_THRESHOLD);
    847 	gDPSetBlendColor(GFX1++, 0, 0, 0, 0);
    848 	gDPSetCombineMode(GFX1++, G_CC_D64COMB04, G_CC_D64COMB04);
    849 
    850 	gDPSetPrimColorD64(GFX1++, 0, 0, color);
    851 
    852     if ((color & 255) < 255) {
    853         gDPSetRenderMode(GFX1++, G_RM_XLU_SURF_CLAMP, G_RM_XLU_SURF2_CLAMP);
    854     }
    855     else {
    856         gDPSetRenderMode(GFX1++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
    857     }
    858 
    859 
    860     data = W_CacheLumpNum(lump, PU_CACHE, dec_jag);
    861 
    862     compressed = ((spriteN64_t*)data)->compressed;
    863     tileh = ((spriteN64_t*)data)->tileheight;
    864     width = ((spriteN64_t*)data)->width;
    865     height = ((spriteN64_t*)data)->height;
    866     tiles = ((spriteN64_t*)data)->tiles;
    867     xoffs = ((spriteN64_t*)data)->xoffs;
    868     yoffs = ((spriteN64_t*)data)->yoffs;
    869 
    870     src = data + sizeof(spriteN64_t);
    871 
    872     if (compressed < 0)
    873     {
    874         width2 = width + 7 & ~7;
    875         tilew = tileh * width2;
    876 
    877         if (((spriteN64_t*)data)->cmpsize & 1)
    878         {
    879             paldata = W_CacheLumpNum(((mobjinfo[type].palette + lump) -
    880                                     (((spriteN64_t*)data)->cmpsize >> 1)), PU_CACHE, dec_jag) + 8;
    881         }
    882         else
    883         {
    884             paldata = (src + ((spriteN64_t*)data)->cmpsize);
    885         }
    886 
    887         /* Load Palette Data (256 colors) */
    888         gDPSetTextureImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_16b , 1, paldata);
    889 
    890         gDPTileSync(GFX1++);
    891         gDPSetTile(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_4b, 0, 256, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0);
    892 
    893         gDPLoadSync(GFX1++);
    894         gDPLoadTLUTCmd(GFX1++, G_TX_LOADTILE, 255);
    895 
    896         gDPPipeSync(GFX1++);
    897     }
    898     else
    899     {
    900         width2 = width + 15 & ~15;
    901         tilew = tileh * width2;
    902 
    903         if (tilew < 0) {
    904             tilew = tilew + 1;
    905         }
    906 
    907         tilew >>= 1;
    908 
    909         /* Load Palette Data (16 colors) */
    910         gDPSetTextureImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_16b , 1, (src + ((spriteN64_t*)data)->cmpsize));
    911 
    912         gDPTileSync(GFX1++);
    913         gDPSetTile(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_4b, 0, 256, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0);
    914 
    915         gDPLoadSync(GFX1++);
    916         gDPLoadTLUTCmd(GFX1++, G_TX_LOADTILE, 15);
    917 
    918         gDPPipeSync(GFX1++);
    919     }
    920 
    921     if (!flip)
    922     {
    923         x1 = (xpos - xoffs) << 2;
    924         xh = (x1 + (width << 2));
    925         spos = 0;
    926         dsdx = 1;
    927     }
    928     else
    929     {
    930         xh = (xpos + xoffs) << 2;
    931         x1 = (xh - (width << 2));
    932         spos = (width - 1);
    933         dsdx = 63;
    934     }
    935 
    936     y1 = (ypos - yoffs) << 2;
    937 
    938     if (tiles > 0)
    939     {
    940         do
    941         {
    942             if (tileh < height)
    943                 tpos = tileh;
    944             else
    945                 tpos = height;
    946 
    947             if (compressed < 0)
    948             {
    949                 /* Load Image Data (8bit) */
    950                 gDPSetTextureImage(GFX1++, G_IM_FMT_CI, G_IM_SIZ_16b , 1, src);
    951                 gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0);
    952 
    953                 gDPLoadSync(GFX1++);
    954                 gDPLoadBlock(GFX1++, G_TX_LOADTILE, 0, 0, ((width2 * tpos + 1) >> 1) - 1, 0);
    955 
    956                 gDPPipeSync(GFX1++);
    957                 gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_8b, ((width2 + 7) >> 3), 0,
    958                                G_TX_RENDERTILE , 0, 0, 0, 0, 0, 0, 0);
    959 
    960                 gDPSetTileSize(GFX1++, G_TX_RENDERTILE, 0, 0, ((width2 - 1) << 2), (tpos - 1) << 2);
    961             }
    962             else
    963             {
    964                 /* Load Image Data (4bit) */
    965                 gDPSetTextureImage(GFX1++, G_IM_FMT_CI, G_IM_SIZ_16b , 1, src);
    966                 gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0);
    967 
    968                 gDPLoadSync(GFX1++);
    969                 gDPLoadBlock(GFX1++, G_TX_LOADTILE, 0, 0, ((width2 * tpos + 3) >> 2) - 1, 0);
    970 
    971                 gDPPipeSync(GFX1++);
    972                 gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_4b, (((width2>>1) + 7) >> 3), 0,
    973                            G_TX_RENDERTILE , 0, 0, 0, 0, 0, 0, 0);
    974 
    975                 gDPSetTileSize(GFX1++, G_TX_RENDERTILE, 0, 0, ((width2 - 1) << 2), (tpos - 1) << 2);
    976             }
    977 
    978             yh = (y1 + (tpos << 2));
    979 
    980             gSPTextureRectangle(GFX1++,
    981                                 x1, y1,
    982                                 xh, yh,
    983                                 G_TX_RENDERTILE,
    984                                 (spos << 5), (0 << 5),
    985                                 (dsdx << 10), (1 << 10));
    986 
    987             height -= tpos;
    988 
    989             src += tilew;
    990             y1 = yh;
    991             tilecnt += 1;
    992         } while (tilecnt != tiles);
    993     }
    994 
    995     globallump = -1;
    996 }