Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. #include "version.h"
  2.  
  3. #ifdef USE_CLOUDSKY
  4.  
  5. #include "wl_def.h"
  6. #include "wl_cloudsky.h"
  7.  
  8. // Each colormap defines a number of colors which should be mapped from
  9. // the skytable. The according colormapentry_t array defines how these colors should
  10. // be mapped to the wolfenstein palette. The first int of each entry defines
  11. // how many colors are grouped to this entry and the absolute value of the
  12. // second int sets the starting palette index for this pair. If this value is
  13. // negative the index will be decremented for every color, if it's positive
  14. // it will be incremented.
  15. //
  16. // Example colormap:
  17. //   colormapentry_t colmapents_1[] = { { 6, -10 }, { 2, 40 } };
  18. //   colormap_t colorMaps[] = {
  19. //      { 8, colmapents_1 }
  20. //   };
  21. //
  22. //   The colormap 0 consists of 8 colors. The first color group consists of 6
  23. //   colors and starts descending at palette index 10: 10, 9, 8, 7, 6, 5
  24. //   The second color group consists of 2 colors and starts ascending at
  25. //   index 40: 40, 41
  26. //   There's no other color group because all colors of this colormap are
  27. //   already used (6+2=8)
  28. //
  29. // Warning: Always make sure that the sum of the amount of the colors in all
  30. //          color groups is the number of colors used for your colormap!
  31.  
  32. colormapentry_t colmapents_1[] = { { 16, -31 }, { 16, 136 } };
  33. colormapentry_t colmapents_2[] = { { 16, -31 } };
  34.  
  35. colormap_t colorMaps[] = {
  36.     { 32, colmapents_1 },
  37.     { 16, colmapents_2 }
  38. };
  39.  
  40. const int numColorMaps = lengthof(colorMaps);
  41.  
  42. // The sky definitions which can be selected as defined by GetCloudSkyDefID() in wl_def.h
  43. // You can use <TAB>+Z in debug mode to find out suitable values for seed and colorMapIndex
  44. // Each entry consists of seed, speed, angle and colorMapIndex
  45. cloudsky_t cloudSkys[] = {
  46.     { 626,   800,  20,  0 },
  47.     { 1234,  650,  60,  1 },
  48.     { 0,     700,  120, 0 },
  49.     { 0,     0,    0,   0 },
  50.     { 11243, 750,  310, 0 },
  51.     { 32141, 750,  87,  0 },
  52.     { 12124, 750,  64,  0 },
  53.     { 55543, 500,  240, 0 },
  54.     { 65535, 200,  54,  1 },
  55.     { 4,     1200, 290, 0 },
  56. };
  57.  
  58. byte skyc[65536L];
  59.  
  60. long cloudx = 0, cloudy = 0;
  61. cloudsky_t *curSky = NULL;
  62.  
  63. #ifdef USE_FEATUREFLAGS
  64.  
  65. // The lower left tile of every map determines the used cloud sky definition from cloudSkys.
  66. static int GetCloudSkyDefID()
  67. {
  68.     int skyID = ffDataBottomLeft;
  69.     assert(skyID >= 0 && skyID < lengthof(cloudSkys));
  70.     return skyID;
  71. }
  72.  
  73. #else
  74.  
  75. static int GetCloudSkyDefID()
  76. {
  77.     int skyID;
  78.     switch(gamestate.episode * 10 + mapon)
  79.     {
  80.         case  0: skyID =  0; break;
  81.         case  1: skyID =  1; break;
  82.         case  2: skyID =  2; break;
  83.         case  3: skyID =  3; break;
  84.         case  4: skyID =  4; break;
  85.         case  5: skyID =  5; break;
  86.         case  6: skyID =  6; break;
  87.         case  7: skyID =  7; break;
  88.         case  8: skyID =  8; break;
  89.         case  9: skyID =  9; break;
  90.         default: skyID =  9; break;
  91.     }
  92.     assert(skyID >= 0 && skyID < lengthof(cloudSkys));
  93.     return skyID;
  94. }
  95.  
  96. #endif
  97.  
  98. void SplitS(unsigned size,unsigned x1,unsigned y1,unsigned x2,unsigned y2)
  99. {
  100.    if(size==1) return;
  101.    if(!skyc[((x1+size/2)*256+y1)])
  102.    {
  103.       skyc[((x1+size/2)*256+y1)]=(byte)(((int)skyc[(x1*256+y1)]
  104.             +(int)skyc[((x2&0xff)*256+y1)])/2)+rand()%(size*2)-size;
  105.       if(!skyc[((x1+size/2)*256+y1)]) skyc[((x1+size/2)*256+y1)]=1;
  106.    }
  107.    if(!skyc[((x1+size/2)*256+(y2&0xff))])
  108.    {
  109.       skyc[((x1+size/2)*256+(y2&0xff))]=(byte)(((int)skyc[(x1*256+(y2&0xff))]
  110.             +(int)skyc[((x2&0xff)*256+(y2&0xff))])/2)+rand()%(size*2)-size;
  111.       if(!skyc[((x1+size/2)*256+(y2&0xff))])
  112.          skyc[((x1+size/2)*256+(y2&0xff))]=1;
  113.    }
  114.    if(!skyc[(x1*256+y1+size/2)])
  115.    {
  116.       skyc[(x1*256+y1+size/2)]=(byte)(((int)skyc[(x1*256+y1)]
  117.             +(int)skyc[(x1*256+(y2&0xff))])/2)+rand()%(size*2)-size;
  118.       if(!skyc[(x1*256+y1+size/2)]) skyc[(x1*256+y1+size/2)]=1;
  119.    }
  120.    if(!skyc[((x2&0xff)*256+y1+size/2)])
  121.    {
  122.       skyc[((x2&0xff)*256+y1+size/2)]=(byte)(((int)skyc[((x2&0xff)*256+y1)]
  123.             +(int)skyc[((x2&0xff)*256+(y2&0xff))])/2)+rand()%(size*2)-size;
  124.       if(!skyc[((x2&0xff)*256+y1+size/2)]) skyc[((x2&0xff)*256+y1+size/2)]=1;
  125.    }
  126.  
  127.    skyc[((x1+size/2)*256+y1+size/2)]=(byte)(((int)skyc[(x1*256+y1)]
  128.          +(int)skyc[((x2&0xff)*256+y1)]+(int)skyc[(x1*256+(y2&0xff))]
  129.          +(int)skyc[((x2&0xff)*256+(y2&0xff))])/4)+rand()%(size*2)-size;
  130.  
  131.    SplitS(size/2,x1,y1+size/2,x1+size/2,y2);
  132.    SplitS(size/2,x1+size/2,y1,x2,y1+size/2);
  133.    SplitS(size/2,x1+size/2,y1+size/2,x2,y2);
  134.    SplitS(size/2,x1,y1,x1+size/2,y1+size/2);
  135. }
  136.  
  137. void InitSky()
  138. {
  139.     unsigned cloudskyid = GetCloudSkyDefID();
  140.     if(cloudskyid >= lengthof(cloudSkys))
  141.         Quit("Illegal cloud sky id: %u", cloudskyid);
  142.     curSky = &cloudSkys[cloudskyid];
  143.  
  144.     memset(skyc, 0, sizeof(skyc));
  145.     // funny water texture if used instead of memset ;D
  146.     // for(int i = 0; i < 65536; i++)
  147.     //     skyc[i] = rand() % 32 * 8;
  148.  
  149.     srand(curSky->seed);
  150.     skyc[0] = rand() % 256;
  151.     SplitS(256, 0, 0, 256, 256);
  152.  
  153.     // Smooth the clouds a bit
  154.     for(int k = 0; k < 2; k++)
  155.     {
  156.         for(int i = 0; i < 256; i++)
  157.         {
  158.             for(int j = 0; j < 256; j++)
  159.             {
  160.                 int32_t val = -skyc[j * 256 + i];
  161.                 for(int m = 0; m < 3; m++)
  162.                 {
  163.                     for(int n = 0; n < 3; n++)
  164.                     {
  165.                         val += skyc[((j + n - 1) & 0xff) * 256 + ((i + m - 1) & 0xff)];
  166.                     }
  167.                 }
  168.                 skyc[j * 256 + i] = (byte)(val >> 3);
  169.             }
  170.         }
  171.     }
  172.  
  173.     // the following commented line could be useful, if you're trying to
  174.     // create a new color map. This will display your current color map
  175.     // in one (of course repeating) stripe of the sky
  176.  
  177.     // for(int i = 0; i < 256; i++)
  178.     //     skyc[i] = skyc[i + 256] = skyc[i + 512] = i;
  179.  
  180.     if(curSky->colorMapIndex >= lengthof(colorMaps))
  181.         Quit("Illegal colorMapIndex for cloud sky def %u: %u", cloudskyid, curSky->colorMapIndex);
  182.  
  183.     colormap_t *curMap = &colorMaps[curSky->colorMapIndex];
  184.     int numColors = curMap->numColors;
  185.     byte colormap[256];
  186.     colormapentry_t *curEntry = curMap->entries;
  187.     for(int calcedCols = 0; calcedCols < numColors; curEntry++)
  188.     {
  189.         if(curEntry->startAndDir < 0)
  190.         {
  191.             for(int i = 0, ind = -curEntry->startAndDir; i < curEntry->length; i++, ind--)
  192.                 colormap[calcedCols++] = ind;
  193.         }
  194.         else
  195.         {
  196.             for(int i = 0, ind = curEntry->startAndDir; i < curEntry->length; i++, ind++)
  197.                 colormap[calcedCols++] = ind;
  198.         }
  199.     }
  200.  
  201.     for(int i = 0; i < 256; i++)
  202.     {
  203.         for(int j = 0; j < 256; j++)
  204.         {
  205.             skyc[i * 256 + j] = colormap[skyc[i * 256 + j] * numColors / 256];
  206.         }
  207.     }
  208. }
  209.  
  210. // Based on Textured Floor and Ceiling by DarkOne
  211. void DrawClouds(byte *vbuf, unsigned vbufPitch, int min_wallheight)
  212. {
  213.     // Move clouds
  214.     fixed moveDist = tics * curSky->speed;
  215.     cloudx += FixedMul(moveDist,sintable[curSky->angle]);
  216.     cloudy -= FixedMul(moveDist,costable[curSky->angle]);
  217.  
  218.     // Draw them
  219.     int y0, halfheight;
  220.     unsigned top_offset0;
  221.     fixed dist;                                // distance to row projection
  222.     fixed tex_step;                            // global step per one screen pixel
  223.     fixed gu, gv, du, dv;                      // global texture coordinates
  224.     int u, v;                                  // local texture coordinates
  225.  
  226.     // ------ * prepare * --------
  227.     halfheight = viewheight >> 1;
  228.     y0 = min_wallheight >> 3;                  // starting y value
  229.     if(y0 > halfheight)
  230.         return;                                // view obscured by walls
  231.     if(!y0) y0 = 1;                            // don't let division by zero
  232.     top_offset0 = vbufPitch * (halfheight - y0 - 1);
  233.  
  234.     // draw horizontal lines
  235.     for(int y = y0, top_offset = top_offset0; y < halfheight; y++, top_offset -= vbufPitch)
  236.     {
  237.         dist = (heightnumerator / y) << 8;
  238.         gu =  viewx + FixedMul(dist, viewcos) + cloudx;
  239.         gv = -viewy + FixedMul(dist, viewsin) + cloudy;
  240.         tex_step = (dist << 8) / viewwidth / 175;
  241.         du =  FixedMul(tex_step, viewsin);
  242.         dv = -FixedMul(tex_step, viewcos);
  243.         gu -= (viewwidth >> 1)*du;
  244.         gv -= (viewwidth >> 1)*dv;          // starting point (leftmost)
  245.         for(int x = 0, top_add = top_offset; x < viewwidth; x++, top_add++)
  246.         {
  247.             if(wallheight[x] >> 3 <= y)
  248.             {
  249.                 u = (gu >> 13) & 255;
  250.                 v = (gv >> 13) & 255;
  251.                 vbuf[top_add] = skyc[((255 - u) << 8) + 255 - v];
  252.             }
  253.             gu += du;
  254.             gv += dv;
  255.         }
  256.     }
  257. }
  258.  
  259. #endif
  260.