DOOM64-RE

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

r_phase2.c (17133B)


      1 
      2 //Renderer phase 2 - Sky Rendering Routines
      3 
      4 #include "doomdef.h"
      5 #include "r_local.h"
      6 
      7 #define FIRESKY_WIDTH   64
      8 #define FIRESKY_HEIGHT  64
      9 
     10 typedef enum
     11 {
     12     SKF_CLOUD       = 1,
     13     SKF_THUNDER     = 2,
     14     SKF_MOUNTAIN    = 4,
     15 } skyflags_e;
     16 
     17 Vtx SkyCloudVertex[4] = // 8005B1D0
     18 {
     19 	{ -300, 120, -160, 0, (0 << 6), (0 << 6), 0, 0, 0, 0xff },
     20 	{  300, 120, -160, 0, (0 << 6), (0 << 6), 0, 0, 0, 0xff },
     21 	{  300,   0, -300, 0, (0 << 6), (0 << 6), 0, 0, 0, 0xff },
     22 	{ -300,   0, -300, 0, (0 << 6), (0 << 6), 0, 0, 0, 0xff },
     23 };
     24 
     25 Vtx SkyFireVertex[4] = // 8005B210
     26 {
     27 	{ -160, 120, -160, 0, (0 << 6), (0  << 6), 0, 0, 0, 0xff },
     28 	{  160, 120, -160, 0, (0 << 6), (0  << 6), 0, 0, 0, 0xff },
     29 	{  160,   0, -160, 0, (0 << 6), (64 << 6), 0, 0, 0, 0xff },
     30 	{ -160,   0, -160, 0, (0 << 6), (64 << 6), 0, 0, 0, 0xff },
     31 };
     32 
     33 fixed_t     FogNear;            // 800A8120
     34 int         FogColor;           // 800A8124
     35 skyfunc_t   R_RenderSKY;        // 800A8130
     36 byte        *SkyFireData[2];    // 800A8140 // Fire data double buffer
     37 byte        *SkyCloudData;      // 800A8148
     38 int         Skyfadeback;        // 800A814C
     39 int         FireSide;           // 800A8150
     40 int         SkyCloudOffsetX;    // 800A8154
     41 int         SkyCloudOffsetY;    // 800A8158
     42 int         ThunderCounter;     // 800A815C
     43 int         LightningCounter;   // 800A8160
     44 int         SkyPicSpace;        // 800A8164
     45 int         SkyPicMount;        // 800A8168
     46 int         SkyCloudColor;      // 800A816C
     47 int         SkyVoidColor;       // 800A8170
     48 int         SkyFlags;           // 800A8174
     49 
     50 void R_RenderSpaceSky(void);
     51 void R_RederCloudSky(void);
     52 void R_RenderVoidSky(void);
     53 void R_RenderEvilSky(void);
     54 void R_RenderClouds(void);
     55 void R_RenderSkyPic(int lump, int yoffset);
     56 void R_RenderFireSky(void);
     57 void R_CloudThunder(void);
     58 
     59 void R_SetupSky(void) // 80025060
     60 {
     61     byte *data;
     62 
     63     FogNear = 985;
     64     FogColor = PACKRGBA(0,0,0,0);
     65     R_RenderSKY = NULL;
     66     SkyFlags = 0;
     67     SkyCloudOffsetX = 0;
     68     SkyCloudOffsetY = 0;
     69     ThunderCounter = 180;
     70     LightningCounter = 0;
     71     FireSide = 0;
     72     Skyfadeback = 0;
     73     SkyPicSpace = W_GetNumForName("SPACE");
     74 
     75     switch(skytexture)
     76     {
     77         case 1:
     78         case 10:
     79             SkyFlags = (SKF_CLOUD|SKF_THUNDER);
     80             R_RenderSKY = R_RederCloudSky;
     81 
     82             SkyCloudData = (byte *)W_CacheLumpName("CLOUD", PU_STATIC, dec_jag);
     83             SkyCloudColor = PACKRGBA(176,128,255,255); // 0xb080ffff
     84 
     85             if (skytexture == 10)
     86             {
     87                 SkyPicMount = W_GetNumForName("MOUNTC");
     88                 SkyFlags |= SKF_MOUNTAIN;
     89             }
     90 
     91             *(int*)SkyCloudVertex[0].v.cn = PACKRGBA(0,0,0,255); // 0xff;
     92             *(int*)SkyCloudVertex[1].v.cn = PACKRGBA(0,0,0,255); // 0xff;
     93             *(int*)SkyCloudVertex[2].v.cn = PACKRGBA(0,0,21,255); // 0x15ff;
     94             *(int*)SkyCloudVertex[3].v.cn = PACKRGBA(0,0,21,255); // 0x15ff;
     95             break;
     96 
     97         case 2:
     98             SkyFlags = SKF_CLOUD;
     99             R_RenderSKY = R_RederCloudSky;
    100 
    101             SkyCloudData = (byte *)W_CacheLumpName("CLOUD", PU_STATIC, dec_jag);
    102             SkyCloudColor = PACKRGBA(255,48,48,255); // 0xff3030ff;
    103 
    104             *(int*)SkyCloudVertex[0].v.cn = PACKRGBA(16,0,0,255); // 0x100000ff;
    105             *(int*)SkyCloudVertex[1].v.cn = PACKRGBA(16,0,0,255); // 0x100000ff;
    106             *(int*)SkyCloudVertex[2].v.cn = PACKRGBA(16,0,0,255); // 0x100000ff;
    107             *(int*)SkyCloudVertex[3].v.cn = PACKRGBA(16,0,0,255); // 0x100000ff;
    108             break;
    109 
    110         case 3:
    111         case 5:
    112             SkyFlags = SKF_CLOUD;
    113             R_RenderSKY = R_RederCloudSky;
    114 
    115             SkyCloudData = (byte *)W_CacheLumpName("CLOUD", PU_STATIC, dec_jag);
    116             SkyCloudColor = PACKRGBA(208,112,64,255); // 0xd07040ff;
    117 
    118             if (skytexture == 3)
    119             {
    120                 SkyPicMount = W_GetNumForName("MOUNTB");
    121                 SkyFlags |= SKF_MOUNTAIN;
    122             }
    123             else
    124             {
    125                 FogNear = 975;
    126                 FogColor = PACKRGBA(48,16,8,0); // 0x30100800;
    127             }
    128 
    129             *(int*)SkyCloudVertex[0].v.cn = PACKRGBA(0,0,0,255); // 0xff;
    130             *(int*)SkyCloudVertex[1].v.cn = PACKRGBA(0,0,0,255); // 0xff;
    131             *(int*)SkyCloudVertex[2].v.cn = PACKRGBA(64,16,0,255); // 0x401000ff;
    132             *(int*)SkyCloudVertex[3].v.cn = PACKRGBA(64,16,0,255); // 0x401000ff;
    133             break;
    134 
    135         case 4:
    136         case 9:
    137             R_RenderSKY = R_RenderFireSky;
    138 
    139             data = W_CacheLumpName("FIRE", PU_LEVEL, dec_jag);
    140             SkyFireData[0] = (data + 8);
    141             SkyFireData[1] = Z_Malloc((FIRESKY_WIDTH*FIRESKY_HEIGHT), PU_LEVEL, NULL);
    142 
    143             D_memcpy(SkyFireData[1], SkyFireData[0],(FIRESKY_WIDTH*FIRESKY_HEIGHT));
    144 
    145             if (skytexture == 4)
    146             {
    147                 *(int*)SkyFireVertex[0].v.cn = PACKRGBA(255,0,0,255); // 0xff0000ff;
    148                 *(int*)SkyFireVertex[1].v.cn = PACKRGBA(255,0,0,255); // 0xff0000ff;
    149                 *(int*)SkyFireVertex[2].v.cn = PACKRGBA(255,96,0,255); // 0xff6000ff;
    150                 *(int*)SkyFireVertex[3].v.cn = PACKRGBA(255,96,0,255); // 0xff6000ff;
    151             }
    152             else
    153             {
    154                 *(int*)SkyFireVertex[0].v.cn = PACKRGBA(0,255,0,255); // 0xff00ff;
    155                 *(int*)SkyFireVertex[1].v.cn = PACKRGBA(0,255,0,255); // 0xff00ff;
    156                 *(int*)SkyFireVertex[2].v.cn = PACKRGBA(112,112,0,255); // 0x707000ff;
    157                 *(int*)SkyFireVertex[3].v.cn = PACKRGBA(112,112,0,255); // 0x707000ff;
    158             }
    159             break;
    160 
    161         case 6:
    162             R_RenderSKY = R_RenderSpaceSky;
    163             break;
    164 
    165         case 7:
    166             FogNear = 995;
    167             R_RenderSKY = R_RenderEvilSky;
    168             break;
    169 
    170         case 8:
    171             R_RenderSKY = R_RenderVoidSky;
    172             FogNear = 975;
    173             FogColor = PACKRGBA(0,64,64,0); // 0x404000;
    174             SkyVoidColor = PACKRGBA(0,56,56,0); // 0x383800;
    175             break;
    176 
    177         case 11:
    178             R_RenderSKY = R_RenderSpaceSky;
    179             SkyPicMount = W_GetNumForName("MOUNTA");
    180             SkyFlags |= SKF_MOUNTAIN;
    181             break;
    182     }
    183 }
    184 
    185 void R_RenderSpaceSky(void) // 80025440
    186 {
    187 
    188     gDPSetAlphaCompare(GFX1++, G_AC_NONE);
    189     gDPSetCombineMode(GFX1++, G_CC_D64COMB09, G_CC_D64COMB09);
    190     gDPSetRenderMode(GFX1++, G_RM_OPA_SURF, G_RM_OPA_SURF2);
    191     gDPSetPrimColor(GFX1++, 0, (lights[255].rgba >> 8), 0, 0, 0, 255);
    192 
    193     R_RenderSkyPic(SkyPicSpace, 128);
    194 
    195     if (SkyFlags & SKF_MOUNTAIN)
    196     {
    197         gDPPipeSync(GFX1++);
    198         gDPSetAlphaCompare(GFX1++, G_AC_THRESHOLD);
    199         gDPSetCombineMode(GFX1++, G_CC_D64COMB10, G_CC_D64COMB10);
    200         gDPSetRenderMode(GFX1++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
    201 
    202         R_RenderSkyPic(SkyPicMount, 170);
    203     }
    204 }
    205 
    206 void R_RederCloudSky(void) // 800255B8
    207 {
    208     if (SkyFlags & SKF_CLOUD)
    209         R_RenderClouds();
    210 
    211     if (SkyFlags & SKF_THUNDER)
    212         R_CloudThunder();
    213 
    214     if (SkyFlags & SKF_MOUNTAIN)
    215     {
    216         gDPPipeSync(GFX1++);
    217         gDPSetAlphaCompare(GFX1++, G_AC_THRESHOLD);
    218         gDPSetCombineMode(GFX1++, G_CC_D64COMB10, G_CC_D64COMB10);
    219         gDPSetRenderMode(GFX1++, G_RM_TEX_EDGE, G_RM_TEX_EDGE2);
    220 
    221         R_RenderSkyPic(SkyPicMount, 170);
    222     }
    223 }
    224 
    225 void R_RenderVoidSky(void) // 800256B4
    226 {
    227 
    228     gDPSetCycleType(GFX1++, G_CYC_FILL);
    229     gDPSetRenderMode(GFX1++,G_RM_NOOP,G_RM_NOOP2);
    230 
    231     // Fill borders with SkyVoidColor
    232     gDPSetFillColor(GFX1++, SkyVoidColor);
    233     gDPFillRectangle(GFX1++, 0, 0, SCREEN_WD-1, SCREEN_HT-1);
    234 }
    235 
    236 void R_RenderEvilSky(void) // 80025738
    237 {
    238     int color;
    239 
    240     gDPSetPrimColor(GFX1++, 0, ((lights[255].rgba >> 8)  - Skyfadeback), 0, 0, 0, 255);
    241     gDPSetAlphaCompare(GFX1++, G_AC_NONE);
    242     gDPSetCombineMode(GFX1++, G_CC_D64COMB09, G_CC_D64COMB09);
    243     gDPSetRenderMode(GFX1++,G_RM_OPA_SURF,G_RM_OPA_SURF2);
    244 
    245     R_RenderSkyPic(SkyPicSpace, 128);
    246     R_RenderSkyPic(SkyPicSpace, 240);
    247 
    248     if (Skyfadeback)
    249     {
    250         Skyfadeback += 4;
    251 
    252         if (Skyfadeback > 255)
    253             Skyfadeback = 255;
    254 
    255         if (Skyfadeback > 128)
    256             color = 128;
    257         else
    258             color = Skyfadeback;
    259 
    260         M_DrawBackground(63, 25, color, "EVIL");
    261     }
    262 }
    263 
    264 void R_RenderClouds(void) // 80025878
    265 {
    266     int x, y;
    267 
    268     gDPSetCycleType(GFX1++, G_CYC_2CYCLE);
    269     gDPSetTexturePersp(GFX1++, G_TP_PERSP);
    270     gDPSetTextureLUT(GFX1++, G_TT_NONE);
    271     gDPSetCombineMode(GFX1++, G_CC_D64COMB11, G_CC_D64COMB12);
    272     gDPSetRenderMode(GFX1++,G_RM_OPA_SURF,G_RM_OPA_SURF2);
    273 
    274     gDPSetPrimColorD64(GFX1++, 0, (lights[255].rgba >> 8), SkyCloudColor);
    275 
    276     if (!gamepaused)
    277     {
    278         SkyCloudOffsetX = (SkyCloudOffsetX - (viewcos >> 14)) & 16383;
    279         SkyCloudOffsetY = (SkyCloudOffsetY + (viewsin >> 13)) & 16383;
    280     }
    281 
    282     x = SkyCloudOffsetX - (viewangle >> ANGLETOFINESHIFT);
    283     y = SkyCloudOffsetY;
    284 
    285     D_memcpy(VTX1, SkyCloudVertex, sizeof(Vtx)*4);
    286 
    287     VTX1[0].v.tc[0] = x;
    288     VTX1[1].v.tc[0] = x + (64 << 6);
    289     VTX1[2].v.tc[0] = x + (64 << 6);
    290     VTX1[3].v.tc[0] = x;
    291 
    292     VTX1[0].v.tc[1] = y;
    293     VTX1[1].v.tc[1] = y;
    294     VTX1[2].v.tc[1] = y + (128 << 6);
    295     VTX1[3].v.tc[1] = y + (128 << 6);
    296 
    297     gDPSetTextureImage(GFX1++, G_IM_FMT_I, G_IM_SIZ_16b , 1, (SkyCloudData+8));
    298     gDPSetTile(GFX1++, G_IM_FMT_I, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, 0, 6, 0, 0, 6, 0);
    299 
    300     gDPLoadSync(GFX1++);
    301     gDPLoadBlock(GFX1++, G_TX_LOADTILE, 0, 0, (((64 * 64) -1) >> 1), 0);
    302 
    303     gDPPipeSync(GFX1++);
    304     gDPSetTile(GFX1++, G_IM_FMT_I, G_IM_SIZ_8b, 8, 0, G_TX_RENDERTILE, 0, 0, 6, 0, 0, 6, 0);
    305     gDPSetTileSize(GFX1++, G_TX_RENDERTILE, 0, 0, (63 << 2), (63 << 2));
    306     gSPTexture(GFX1++, (768 << 6), (512 << 6), 0, G_TX_RENDERTILE, G_ON);
    307 
    308     gSPVertex(GFX1++, VTX1, 4, 0);
    309     gSP1Triangle(GFX1++, 0, 2, 1, 0);
    310     gSP1Triangle(GFX1++, 0, 3, 2, 0);
    311 
    312     VTX1 += 4;
    313 }
    314 
    315 void R_RenderSkyPic(int lump, int yoffset) // 80025BDC
    316 {
    317     byte *data;
    318     byte *src;
    319     byte *paldata;
    320     int i;
    321 
    322     int tileh;
    323     int yl, yh;
    324     int ang;
    325     int lrs;
    326 
    327     data = W_CacheLumpNum(lump, PU_CACHE, dec_jag);
    328 
    329     ang = (0 - ( viewangle >> 22) & 255);
    330     tileh = ((spriteN64_t*)data)->tileheight;
    331 
    332     src = data + sizeof(spriteN64_t);
    333     paldata = (src + ((spriteN64_t*)data)->cmpsize);
    334 
    335     gDPSetCycleType(GFX1++, G_CYC_1CYCLE);
    336 
    337     gDPSetTexturePersp(GFX1++, G_TP_NONE);
    338     gDPSetTextureLUT(GFX1++, G_TT_RGBA16);
    339     gDPSetBlendColor(GFX1++, 0, 0, 0, 0);
    340 
    341     // Load Palette Data (256 colors)
    342     gDPSetTextureImage(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_16b , 1, paldata);
    343 
    344     gDPTileSync(GFX1++);
    345     gDPSetTile(GFX1++, G_IM_FMT_RGBA, G_IM_SIZ_4b, 0, 256, G_TX_LOADTILE, 0, 0, 0, 0, 0, 0, 0);
    346 
    347     gDPLoadSync(GFX1++);
    348     gDPLoadTLUTCmd(GFX1++, G_TX_LOADTILE, 255);
    349 
    350     gDPPipeSync(GFX1++);
    351 
    352     lrs = (((tileh << 8) + 1) >> 1) - 1;
    353     yl = (yoffset - ((spriteN64_t*)data)->height);
    354 
    355     for(i = 0; i < ((spriteN64_t*)data)->tiles; i++)
    356     {
    357         yh = (tileh + yl);
    358 
    359         gDPSetTextureImage(GFX1++, G_IM_FMT_CI, G_IM_SIZ_16b , 1, src);
    360         gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, 0, 0, 0, 0, 8, 0);
    361 
    362         gDPLoadSync(GFX1++);
    363         gDPLoadBlock(GFX1++, G_TX_LOADTILE, 0, 0, lrs, 0);
    364 
    365         gDPPipeSync(GFX1++);
    366         gDPSetTile(GFX1++, G_IM_FMT_CI, G_IM_SIZ_8b, 32, 0, G_TX_RENDERTILE, 0, 0, 0, 0, 0, 8, 0);
    367         gDPSetTileSize(GFX1++, 0, 0, 0, ((256-1) << 2), ((tileh - 1) << 2));
    368 
    369         gSPTextureRectangle(GFX1++, (0 << 2), (yl << 2),
    370                                     (320 << 2), (yh << 2),
    371                                     G_TX_RENDERTILE,
    372                                     (ang << 5), (0 << 5),
    373                                     (1 << 10), (1 << 10));
    374         src += (tileh << 8);
    375         yl = yh;
    376     }
    377 }
    378 
    379 void R_RenderFireSky(void) // 80025F68
    380 {
    381     byte *buff;
    382     byte *src, *srcoffset, *tmpSrc;
    383     int width, height, rand;
    384     int pixel, randIdx;
    385     int ang, t;
    386 
    387     gDPSetCycleType(GFX1++, G_CYC_2CYCLE);
    388     gDPSetTexturePersp(GFX1++, G_TP_PERSP);
    389     gDPSetTextureLUT(GFX1++, G_TT_NONE);
    390     gDPSetCombineMode(GFX1++, G_CC_D64COMB13, G_CC_D64COMB14);
    391     gDPSetRenderMode(GFX1++,G_RM_OPA_SURF,G_RM_OPA_SURF2);
    392     gDPSetPrimColor(GFX1++, 0, (lights[255].rgba >> 8), 0, 0, 0, 255);
    393 
    394     if (((gamevbls < gametic) && (gametic & 1)) && (!gamepaused))
    395     {
    396         buff = SkyFireData[FireSide];
    397         D_memcpy(buff, SkyFireData[FireSide ^ 1], (FIRESKY_WIDTH*FIRESKY_HEIGHT));
    398 
    399         rand = (M_Random() & 0xff);
    400         width = 0;
    401         src = (buff + FIRESKY_WIDTH);
    402 
    403         do // width
    404         {
    405             height = 2;
    406             srcoffset = (src + width);
    407 
    408             // R_SpreadFire
    409             pixel = *(byte*)srcoffset;
    410             if (pixel != 0)
    411             {
    412                 randIdx = rndtable[rand];
    413                 rand = ((rand + 2) & 0xff);
    414 
    415                 tmpSrc = (src + (((width - (randIdx & 3)) + 1) & (FIRESKY_WIDTH-1)));
    416                 *(byte*)(tmpSrc - FIRESKY_WIDTH) = pixel - ((randIdx & 1) << 4);
    417             }
    418             else
    419             {
    420                 *(byte*)(srcoffset - FIRESKY_WIDTH) = 0;
    421             }
    422 
    423             src += FIRESKY_WIDTH;
    424             srcoffset += FIRESKY_WIDTH;
    425 
    426             do // height
    427             {
    428                 height += 2;
    429 
    430                 // R_SpreadFire
    431                 pixel = *(byte*)srcoffset;
    432                 if (pixel != 0)
    433                 {
    434                     randIdx = rndtable[rand];
    435                     rand = ((rand + 2) & 0xff);
    436 
    437                     tmpSrc = (src + (((width - (randIdx & 3)) + 1) & (FIRESKY_WIDTH-1)));
    438                     *(byte*)(tmpSrc - FIRESKY_WIDTH) = pixel - ((randIdx & 1) << 4);
    439                 }
    440                 else
    441                 {
    442                     *(byte*)(srcoffset - FIRESKY_WIDTH) = 0;
    443                 }
    444 
    445                 src += FIRESKY_WIDTH;
    446                 srcoffset += FIRESKY_WIDTH;
    447 
    448                 // R_SpreadFire
    449                 pixel = *(byte*)srcoffset;
    450                 if (pixel != 0)
    451                 {
    452                     randIdx = rndtable[rand];
    453                     rand = ((rand + 2) & 0xff);
    454 
    455                     tmpSrc = (src + (((width - (randIdx & 3)) + 1) & (FIRESKY_WIDTH-1)));
    456                     *(byte*)(tmpSrc - FIRESKY_WIDTH) = pixel - ((randIdx & 1) << 4);
    457                 }
    458                 else
    459                 {
    460                     *(byte*)(srcoffset - FIRESKY_WIDTH) = 0;
    461                 }
    462 
    463                 src += FIRESKY_WIDTH;
    464                 srcoffset += FIRESKY_WIDTH;
    465 
    466             } while (height != FIRESKY_HEIGHT);
    467 
    468             src -= ((FIRESKY_WIDTH*FIRESKY_HEIGHT) - FIRESKY_WIDTH);
    469             width++;
    470 
    471         } while (width != FIRESKY_WIDTH);
    472 
    473         FireSide ^= 1;
    474     }
    475     else
    476     {
    477         buff = SkyFireData[FireSide ^ 1];
    478     }
    479 
    480     D_memcpy(VTX1, SkyFireVertex, sizeof(Vtx)*4);
    481 
    482     ang = (viewangle >> 22);
    483     t = ((-ang & 255) << 5);
    484 
    485     VTX1[0].v.tc[0] = t;
    486     VTX1[1].v.tc[0] = t + 0x2800;
    487     VTX1[2].v.tc[0] = t + 0x2800;
    488     VTX1[3].v.tc[0] = t;
    489 
    490     gDPSetTextureImage(GFX1++, G_IM_FMT_I, G_IM_SIZ_16b , 1, buff);
    491     gDPSetTile(GFX1++, G_IM_FMT_I, G_IM_SIZ_16b, 0, 0, G_TX_LOADTILE, 0, 0, 0, 0, 0, 6, 0);
    492 
    493     gDPLoadSync(GFX1++);
    494     gDPLoadBlock(GFX1++, G_TX_LOADTILE, 0, 0, (((64 * 64) -1) >> 1), 256);
    495 
    496     gDPPipeSync(GFX1++);
    497     gDPSetTile(GFX1++, G_IM_FMT_I, G_IM_SIZ_8b, 8, 0, G_TX_RENDERTILE, 0, 0, 0, 0, 0, 6, 0);
    498     gDPSetTileSize(GFX1++, G_TX_RENDERTILE, 0, 0, (63 << 2), (63 << 2));
    499     gSPTexture(GFX1++, (1024 << 6)-1, (512 << 6), 0, G_TX_RENDERTILE, G_ON);
    500 
    501     gSPVertex(GFX1++, VTX1, 4, 0);
    502     gSP1Triangle(GFX1++, 0, 2, 1, 0);
    503     gSP1Triangle(GFX1++, 0, 3, 2, 0);
    504 
    505     VTX1 += 4;
    506 }
    507 
    508 void R_CloudThunder(void) // 80026418
    509 {
    510     int rand;
    511     if (!(gamepaused))
    512     {
    513         ThunderCounter -= vblsinframe[0];
    514 
    515         if(ThunderCounter <= 0)
    516         {
    517             if (LightningCounter == 0)
    518             {
    519                 S_StartSound(NULL, sfx_thndrlow + (M_Random() & 1));
    520             }
    521             else if(!(LightningCounter < 6))    // Reset loop after 6 lightning flickers
    522             {
    523                 rand = (M_Random() & 7);
    524                 ThunderCounter = ((rand << 4) - rand << 2) + 60;
    525                 LightningCounter = 0;
    526                 return;
    527             }
    528 
    529             if ((LightningCounter & 1) == 0)
    530             {
    531                 *(int*)SkyCloudVertex[0].v.cn += PACKRGBA(17,17,17,0); // 0x11111100;
    532                 *(int*)SkyCloudVertex[1].v.cn += PACKRGBA(17,17,17,0); // 0x11111100;
    533                 *(int*)SkyCloudVertex[2].v.cn += PACKRGBA(17,17,17,0); // 0x11111100;
    534                 *(int*)SkyCloudVertex[3].v.cn += PACKRGBA(17,17,17,0); // 0x11111100;
    535             }
    536             else
    537             {
    538                 *(int*)SkyCloudVertex[0].v.cn -= PACKRGBA(17,17,17,0); // 0x11111100;
    539                 *(int*)SkyCloudVertex[1].v.cn -= PACKRGBA(17,17,17,0); // 0x11111100;
    540                 *(int*)SkyCloudVertex[2].v.cn -= PACKRGBA(17,17,17,0); // 0x11111100;
    541                 *(int*)SkyCloudVertex[3].v.cn -= PACKRGBA(17,17,17,0); // 0x11111100;
    542             }
    543 
    544             ThunderCounter = (M_Random() & 7) + 1; // Do short delay loops for lightning flickers
    545             LightningCounter += 1;
    546         }
    547     }
    548 }
    549