/ source / blood / src / fire.cpp
fire.cpp
  1  //-------------------------------------------------------------------------
  2  /*
  3  Copyright (C) 2010-2019 EDuke32 developers and contributors
  4  Copyright (C) 2019 Nuke.YKT
  5  
  6  This file is part of NBlood.
  7  
  8  NBlood is free software; you can redistribute it and/or
  9  modify it under the terms of the GNU General Public License version 2
 10  as published by the Free Software Foundation.
 11  
 12  This program is distributed in the hope that it will be useful,
 13  but WITHOUT ANY WARRANTY; without even the implied warranty of
 14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 15  
 16  See the GNU General Public License for more details.
 17  
 18  You should have received a copy of the GNU General Public License
 19  along with this program; if not, write to the Free Software
 20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 21  */
 22  //-------------------------------------------------------------------------
 23  #include <stdio.h>
 24  #include <stdlib.h>
 25  #include <string.h>
 26  #include "build.h"
 27  #include "common_game.h"
 28  #include "blood.h"
 29  #include "fire.h"
 30  #include "globals.h"
 31  #include "misc.h"
 32  #include "tile.h"
 33  
 34  int fireSize = 128;
 35  int gDamping = 6;
 36  
 37  /*extern "C" */char CoolTable[1024];
 38  
 39  void CellularFrame(char *pFrame, int sizeX, int sizeY);
 40  
 41  char FrameBuffer[17280];
 42  char SeedBuffer[16][128];
 43  char *gCLU;
 44  
 45  void InitSeedBuffers(void)
 46  {
 47      for (int i = 0; i < 16; i++)
 48          for (int j = 0; j < fireSize; j += 2)
 49              SeedBuffer[i][j] = SeedBuffer[i][j+1] = wrand();
 50  }
 51  
 52  void BuildCoolTable(void)
 53  {
 54      for (int i = 0; i < 1024; i++)
 55          CoolTable[i] = ClipLow((i-gDamping) / 4, 0);
 56  }
 57  
 58  void DoFireFrame(void)
 59  {
 60      int nRand = qrand()&15;
 61      for (int i = 0; i < 3; i++)
 62      {
 63          memcpy(FrameBuffer+16896+i*128, SeedBuffer[nRand], 128);
 64      }
 65      CellularFrame(FrameBuffer, 128, 132);
 66      char *pData = tileLoadTile(2342);
 67      char *pSource = FrameBuffer;
 68      int x = fireSize;
 69      do
 70      {
 71          int y = fireSize;
 72          char *pDataBak = pData;
 73          do
 74          {
 75              *pData = gCLU[*pSource];
 76              pSource++;
 77              pData += fireSize;
 78          } while (--y);
 79          pData = pDataBak + 1;
 80      } while (--x);
 81  }
 82  
 83  void FireInit(void)
 84  {
 85      memset(FrameBuffer, 0, sizeof(FrameBuffer));
 86      BuildCoolTable();
 87      InitSeedBuffers();
 88      DICTNODE *pNode = gSysRes.Lookup("RFIRE", "CLU");
 89      if (!pNode)
 90          ThrowError("RFIRE.CLU not found");
 91      gCLU = (char*)gSysRes.Lock(pNode);
 92      for (int i = 0; i < 100; i++)
 93          DoFireFrame();
 94  }
 95  
 96  void FireProcess(void)
 97  {
 98      static ClockTicks lastUpdate;
 99      if (totalclock < lastUpdate || lastUpdate + 2 < totalclock)
100      {
101          DoFireFrame();
102          lastUpdate = totalclock;
103          tileInvalidate(2342, -1, -1);
104      }
105  }
106  
107  void CellularFrame(char *pFrame, int sizeX, int sizeY)
108  {
109      int nSquare = sizeX * sizeY;
110      unsigned char *pPtr1 = (unsigned char*)pFrame;
111      while (nSquare--)
112      {
113          unsigned char *pPtr2 = pPtr1+sizeX;
114          int sum = *(pPtr2-1) + *pPtr2 + *(pPtr2+1) + *(pPtr2+sizeX);
115          if (*(pPtr2+sizeX) > 96)
116          {
117              pPtr2 += sizeX;
118              sum += *(pPtr2-1) + *pPtr2 + *(pPtr2+1) + *(pPtr2+sizeX);
119              sum >>= 1;
120          }
121          *pPtr1 = CoolTable[sum];
122          pPtr1++;
123      }
124  }