home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 105 / af105sub.adf / Beyondthedark.LZX / BeyondTheDark / Developer / Source / Flame / Flame.c next >
C/C++ Source or Header  |  1994-05-14  |  9KB  |  354 lines

  1. /* Flame Library */
  2.  
  3. #include <exec/memory.h>
  4. #include <exec/execbase.h>
  5. #include <graphics/gfxbase.h>
  6. #include <intuition/intuitionbase.h>
  7. #include <libraries/iffparse.h>
  8. #include <utility/tagitem.h>
  9.  
  10. #include <clib/macros.h>
  11.  
  12. #define __USE_SYSBASE 42
  13.  
  14. #include <proto/exec.h>
  15. #include <proto/graphics.h>
  16. #include <proto/intuition.h>
  17. #include <proto/utility.h>
  18.  
  19. #include <math.h>
  20.  
  21. #include <btd.h>
  22.  
  23. // #define DEBUG YES 
  24.  
  25. #ifdef DEBUG 
  26.  
  27. void KPrintF(char *,...);
  28.  
  29. #define DEBUG_PRINTF(a,b)  KPrintF(a,b);
  30. #define DEBUG_PRINT(a)     KPrintF(a)
  31. #else
  32. #define DEBUG_PRINTF(a,b)
  33. #define DEBUG_PRINT(a)
  34. #endif
  35.  
  36.  
  37. struct IntuitionBase *IntuitionBase;
  38. struct GfxBase *GfxBase;
  39. struct Library *UtilityBase,*MathIeeeDoubBasBase,*MathIeeeDoubTransBase;
  40.  
  41. #define FlameTAG(o) (BTD_Client+(o))
  42.  
  43. #define Flame_Colors FlameTAG(0)
  44. #define Flame_Level FlameTAG(1)
  45.  
  46. #define MAX_COLORS 255L /* seconds until a new graphic is plotted */
  47. #define DEF_COLORS 20L
  48.  
  49. #define MAX_LEVEL 10L
  50. #define DEF_LEVEL 4L
  51.  
  52. struct BTDInteger FlameIntParams[] =
  53.  {
  54.   Flame_Colors,"Colors",BTDPT_INTEGER,DEF_COLORS,1L,MAX_COLORS,TRUE,
  55.   Flame_Level,"Patternchange",BTDPT_INTEGER,DEF_LEVEL,1L,MAX_LEVEL,TRUE
  56.  };
  57.  
  58. struct BTDNode *FlameParams[] = {
  59.  &FlameIntParams[0].BI_Node,
  60.  &FlameIntParams[1].BI_Node,
  61.  NULL
  62. };
  63.  
  64. struct BTDInfo FlameInfo =
  65.  {
  66.   BTDI_Revision,MAKE_ID('F','L','A','M'),
  67.   "Flame","based on Flame\nScientific American","Markus Illenseer",
  68.   FlameParams
  69.  };
  70.  
  71. #define MAXTOTAL    10000
  72. #define MAXBATCH    10
  73. #define MAXLEV        4
  74.  
  75. struct XPoint
  76.  {
  77.   int x,y;
  78.  };
  79.  
  80. struct FlameStruct
  81.  {
  82.   struct BTDDrawInfo *BTDDrawInfo;
  83.   LONG   hs_RandN,hs_RandF,hs_RandI;
  84.   double      f[2][3][MAXLEV];/* three non-homogeneous transforms */
  85.   int         max_levels;
  86.   int         cur_level;
  87.   int         snum;
  88.   int         anum;
  89.   int         width, height;
  90.   int         num_points;
  91.   int         total_points;
  92.   int         pixcol;
  93.   int         numcol;
  94.   int         alt;
  95.   struct XPoint      pts[MAXBATCH];
  96.  };
  97.  
  98. /* library stuff */
  99.  
  100. char MyBlankerName[] = "flame.btd";
  101. char MyBlankerID[]   = "Flame Blanker V" VERSION "." REVISION " for BTD";
  102.  
  103. LONG MyBlankerLibInit(void)
  104.  
  105. {
  106.  if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
  107.   {
  108.    if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
  109.     {
  110.      if (UtilityBase=OpenLibrary("utility.library",37L))
  111.       {
  112.        if (MathIeeeDoubBasBase=OpenLibrary("mathieeedoubbas.library",37L))
  113.         {
  114.          if (MathIeeeDoubTransBase=OpenLibrary("mathieeedoubtrans.library",37L)) return TRUE;
  115.  
  116.          CloseLibrary (MathIeeeDoubBasBase);
  117.         }
  118.        CloseLibrary (UtilityBase);
  119.       }
  120.      CloseLibrary (&IntuitionBase->LibNode);
  121.     }
  122.    CloseLibrary (&GfxBase->LibNode);
  123.   }
  124.  return FALSE;
  125. }
  126.  
  127. void MyBlankerLibFree(void)
  128.  
  129. {
  130.  CloseLibrary (MathIeeeDoubTransBase);
  131.  CloseLibrary (MathIeeeDoubBasBase);
  132.  CloseLibrary (UtilityBase);
  133.  CloseLibrary (&IntuitionBase->LibNode);
  134.  CloseLibrary (&GfxBase->LibNode);
  135. }
  136.  
  137. /* random generator */
  138.  
  139. void __regargs InitRandom(struct FlameStruct *FlameStruct,ULONG Instance)
  140.  
  141. {
  142.  ULONG Time[2];
  143.  
  144.  CurrentTime (&Time[0],&Time[1]);
  145.  FlameStruct->hs_RandN=(LONG)Time[0];
  146.  
  147.  if (Time[1]<1024L) Time[1]|=1;
  148.  else Time[1]>>=10;
  149.  Time[1]^=Instance;
  150.  
  151.  FlameStruct->hs_RandF=4*Time[1]+1;
  152.  FlameStruct->hs_RandI=2*Time[1]+1;
  153. }
  154.  
  155. WORD __regargs Random(struct FlameStruct *FlameStruct,WORD Max)
  156.  
  157. {
  158.  FlameStruct->hs_RandN=FlameStruct->hs_RandF*FlameStruct->hs_RandN+FlameStruct->hs_RandI;
  159.  if (FlameStruct->hs_RandN<0L) FlameStruct->hs_RandN=-FlameStruct->hs_RandN;
  160.  
  161.  return (WORD)(FlameStruct->hs_RandN%Max);
  162. }
  163.  
  164. /* implementation of library functions */
  165.  
  166. struct BTDInfo *QueryMyBlanker(void)
  167.  
  168. {
  169.  return &FlameInfo;
  170. }
  171.  
  172.  
  173. #define NUM_RAINBOW_COLORS 6
  174.  
  175. UBYTE RBRed[NUM_RAINBOW_COLORS+1]   = {0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF};
  176. UBYTE RBGreen[NUM_RAINBOW_COLORS+1] = {0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00};
  177. UBYTE RBBlue[NUM_RAINBOW_COLORS+1]  = {0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00};
  178.  
  179.  
  180. struct FlameStruct *InitMyBlanker(struct TagItem *TagList)
  181.  
  182. {
  183.  struct BTDDrawInfo *BTDDrawInfo;
  184.  struct FlameStruct *FlameStruct;
  185.  ULONG *Error,Dummy,Instance;
  186.  int Index;
  187.  
  188.  if ((BTDDrawInfo=(struct BTDDrawInfo *)
  189.                    GetTagData(BTD_DrawInfo,NULL,TagList))==NULL) return NULL;
  190.  Error=(ULONG *)GetTagData(BTD_Error,(ULONG)&Dummy,TagList);
  191.  if ((FlameStruct=AllocVec(2*sizeof(struct FlameStruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  192.   {
  193.    *Error=BTDERR_Memory;
  194.    return NULL;
  195.   }
  196.  Instance=GetTagData(BTD_Instance,0L,TagList);
  197.  
  198.  FlameStruct->BTDDrawInfo=BTDDrawInfo;
  199.  FlameStruct->numcol=GetTagData(Flame_Colors,DEF_COLORS,TagList);
  200.  FlameStruct->max_levels=GetTagData(Flame_Level,DEF_LEVEL,TagList);
  201.  InitRandom (FlameStruct,Instance);
  202.  
  203.  FlameStruct->width = BTDDrawInfo->BDI_Width-1;
  204.  FlameStruct->height = BTDDrawInfo->BDI_Height-1;
  205.  
  206.  FlameStruct->cur_level = 0; 
  207.  FlameStruct->alt = 0; 
  208.  FlameStruct->anum = 0;
  209.  FlameStruct->snum = 0;
  210.  
  211.  if (FlameStruct->numcol>NUM_RAINBOW_COLORS)
  212.   {
  213.    LONG ColNum,Col,RBCol;
  214.    UBYTE *Red,*Green,*Blue,*Changed;
  215.  
  216.    Red=BTDDrawInfo->BDI_Red;
  217.    Green=BTDDrawInfo->BDI_Green;
  218.    Blue=BTDDrawInfo->BDI_Blue;
  219.    Changed=BTDDrawInfo->BDI_Changed;
  220.    ColNum=FlameStruct->numcol/NUM_RAINBOW_COLORS+1L;
  221.    Index=0L;
  222.    for (RBCol=0L; RBCol<NUM_RAINBOW_COLORS; RBCol++)
  223.     {
  224.      if (RBCol==(FlameStruct->numcol%NUM_RAINBOW_COLORS)) ColNum--;
  225.  
  226.      for (Col=0L; Col<ColNum; Col++)
  227.       {
  228.        Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[RBCol]+((RBRed[RBCol+1]-RBRed[RBCol])*Col)/ColNum;
  229.        Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[RBCol]+((RBGreen[RBCol+1]-RBGreen[RBCol])*Col)/ColNum;
  230.        Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[RBCol]+((RBBlue[RBCol+1]-RBBlue[RBCol])*Col)/ColNum;
  231.        Changed[BTDDrawInfo->BDI_Pens[Index++]]=TRUE;
  232.       }
  233.     }
  234.   }
  235.  else
  236.   for (Index=0L; Index<FlameStruct->numcol; Index++)
  237.    {
  238.     BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[Index];
  239.     BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[Index];
  240.     BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[Index];
  241.     BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  242.    }
  243.  
  244.  FlameStruct->pixcol=1;
  245.  SetAPen(FlameStruct->BTDDrawInfo->BDI_RPort,BTDDrawInfo->BDI_Pens[FlameStruct->pixcol]);
  246.  
  247.  return FlameStruct;
  248. }
  249.  
  250. void XDrawPoints(struct FlameStruct *fs)
  251. {
  252.  
  253.  LONG Index;
  254.  int x,y;
  255.  
  256.  DEBUG_PRINT("Flame: Drawing Points\n");
  257.  
  258.  for(Index=0; Index<fs->num_points; Index++)
  259.   {
  260.    x=fs->pts[Index].x;
  261.    y=fs->pts[Index].y;
  262.  
  263.    if(x<fs->width && x>0 && y<fs->height && y>0)
  264.     WritePixel(fs->BTDDrawInfo->BDI_RPort, x, y); 
  265.   }
  266. }
  267.  
  268. static BOOL recurse(struct FlameStruct *fs, double x, double y, int l)
  269. {
  270.     int         /*xp, yp,*/ i;
  271.     double      nx, ny;
  272.  
  273.     if (l == fs->max_levels) {
  274.     fs->total_points++;
  275.     if (fs->total_points > MAXTOTAL)    /* how long each fractal runs */
  276.         return FALSE;
  277.  
  278.     if (x > -1.0 && x < 1.0 && y > -1.0 && y < 1.0) {
  279.         /* xp = */ fs->pts[fs->num_points].x = (int) ((fs->width / 2)
  280.                             * (x + 1.0));
  281.         /* yp = */ fs->pts[fs->num_points].y = (int) ((fs->height / 2)
  282.                             * (y + 1.0));
  283.         fs->num_points++;
  284.         if (fs->num_points > MAXBATCH) {    /* point buffer size */
  285.         XDrawPoints(fs);
  286.         fs->num_points = 0;
  287.         }
  288.     }
  289.     } else {
  290.     for (i = 0; i < fs->snum; i++) {
  291.         nx = fs->f[0][0][i] * x + fs->f[0][1][i] * y + fs->f[0][2][i];
  292.         ny = fs->f[1][0][i] * x + fs->f[1][1][i] * y + fs->f[1][2][i];
  293.         if (i < fs->anum) {
  294.         nx = sin(nx);
  295.         ny = sin(ny);
  296.         }
  297.         if (!recurse(fs, nx, ny, l + 1))
  298.         return FALSE;
  299.     }
  300.     }
  301.     return TRUE;
  302. }
  303.  
  304. void EndMyBlanker(struct FlameStruct *FlameStruct)
  305.  
  306. {
  307.  DEBUG_PRINT("Flame: End\n");
  308.  
  309.  FreeVec (FlameStruct);
  310. }
  311.  
  312. void AnimMyBlanker(struct FlameStruct *fs)
  313.  
  314. {
  315.     int         i, j, k;
  316.  
  317.  DEBUG_PRINT("Flame: Anim\n");
  318.  
  319.     if (!(fs->cur_level++ % fs->max_levels)) {
  320.     SetRast(fs->BTDDrawInfo->BDI_RPort,0);
  321.     fs->alt = !fs->alt;
  322.     } else {
  323.         SetAPen(fs->BTDDrawInfo->BDI_RPort, fs->BTDDrawInfo->BDI_Pens[fs->pixcol]);
  324.         if (--fs->pixcol < 1)
  325.         fs->pixcol = fs->numcol;
  326.     }
  327.     
  328.     /* number of functions */
  329.     fs->snum = 2 + (fs->cur_level % (MAXLEV - 1));
  330.  
  331.     /* how many of them are of alternate form */
  332.     if (fs->alt)
  333.     fs->anum = 0;
  334.     else
  335.     fs->anum = Random(fs,fs->snum) + 2;
  336.  
  337.     /* 6 coefs per function */
  338.     for (k = 0; k < fs->snum; k++) {
  339.     for (i = 0; i < 2; i++)
  340.         for (j = 0; j < 3; j++)
  341.         fs->f[i][j][k] = ((double) Random(fs,fs->width) / (fs->width/2.0) - 1.0);
  342.     }
  343.     fs->num_points = 0;
  344.     fs->total_points = 0;
  345.     (void) recurse(fs, 0.0, 0.0, 0);
  346.     XDrawPoints(fs);
  347. }
  348.  
  349. ULONG PenCountMyBlanker(struct TagItem *TagList)
  350.  
  351. {
  352.  return  GetTagData(Flame_Colors,DEF_COLORS,TagList);
  353. }
  354.