home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format 105 / af105sub.adf / Beyondthedark.LZX / BeyondTheDark / Developer / Source / Qix / Qix.c < prev   
C/C++ Source or Header  |  1999-05-02  |  10KB  |  368 lines

  1. /* Qix Library */
  2.  
  3. #include <exec/memory.h>
  4. #include <exec/execbase.h>
  5. #include <libraries/iffparse.h>
  6. #include <dos/dosextens.h>
  7. #include <utility/tagitem.h>
  8. #include <graphics/gfxbase.h>
  9. #include <intuition/intuitionbase.h>
  10.  
  11. #include <clib/macros.h>
  12.  
  13. #define __USE_SYSBASE 42
  14.  
  15. #include <proto/dos.h>
  16. #include <proto/exec.h>
  17. #include <proto/graphics.h>
  18. #include <proto/intuition.h>
  19. #include <proto/utility.h>
  20.  
  21. #include <math.h>
  22.  
  23. #include <BTD.h>
  24.  
  25. struct IntuitionBase *IntuitionBase;
  26. struct GfxBase *GfxBase;
  27. struct Library *UtilityBase;
  28.  
  29. /* #define DEBUG YES */
  30.  
  31. #ifdef DEBUG 
  32.  
  33. void KPrintF(char *,...);
  34.  
  35. #define DEBUG_PRINTF(a,b)  KPrintF(a,b);
  36. #define DEBUG_PRINT(a)     KPrintF(a)
  37. #else
  38. #define DEBUG_PRINTF(a,b)
  39. #define DEBUG_PRINT(a)
  40. #endif
  41.  
  42.  
  43. #define QTAG(o) (BTD_Client+(o))
  44.  
  45. #define QP_Seconds QTAG(0)
  46. #define QP_Lines   QTAG(1)
  47. #define QP_Colors  QTAG(2)
  48.  
  49. #define MAX_SECONDS 360L /* seconds until a new graphic is plotted */
  50. #define MAX_LINES 255L
  51.  
  52. #define DEF_SECONDS 60L
  53. #define DEF_LINES 10L
  54.  
  55. #define DEF_COLORS 8L
  56. #define MAX_COLORS 256L
  57.  
  58. #define BORDER 5L
  59.  
  60. struct BTDInteger QixIntParams[] =
  61.  {
  62.   QP_Seconds,"Patternchange",BTDPT_INTEGER,DEF_SECONDS,1L,MAX_SECONDS,TRUE,
  63.   QP_Lines,"Lines",BTDPT_INTEGER,DEF_LINES,4L,MAX_LINES,TRUE,
  64.   QP_Colors,"Colors",BTDPT_INTEGER,DEF_COLORS,4L,MAX_COLORS,TRUE
  65.  };
  66.  
  67. struct BTDNode *QixParams[] = 
  68.  {
  69.   &QixIntParams[0].BI_Node,
  70.   &QixIntParams[1].BI_Node,
  71.   &QixIntParams[2].BI_Node,NULL
  72.  };
  73.  
  74. struct BTDInfo QixInfo =
  75.  {
  76.   BTDI_Revision,MAKE_ID('Q','I','X',' '),
  77.   "Qix Line Blanker","One of those lonely standard modules","Markus Illenseer 1994",
  78.   QixParams
  79.  };
  80.  
  81. char MyBlankerName[] = "qix.btd";
  82. char MyBlankerID[]   = "Qix Line Blanker V" VERSION "." REVISION " for BTD";
  83.  
  84.  
  85. LONG MyBlankerLibInit(void)
  86.  
  87. {
  88.  if (GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",37L))
  89.   {
  90.    if (IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",37L))
  91.     {
  92.      if (UtilityBase=OpenLibrary("utility.library",37L)) return TRUE;
  93.  
  94.      CloseLibrary (&IntuitionBase->LibNode);
  95.     }
  96.    CloseLibrary (&GfxBase->LibNode);
  97.   }
  98.  return FALSE;
  99. }
  100.  
  101. void MyBlankerLibFree(void)
  102.  
  103. {
  104.  CloseLibrary (UtilityBase);
  105.  CloseLibrary (&IntuitionBase->LibNode);
  106.  CloseLibrary (&GfxBase->LibNode);
  107. }
  108.  
  109.  
  110. #define check_bounds(qp, val, del, min, max)                \
  111. {                                                            \
  112.     if ((val) <= min) {                                       \
  113.   *(del) = (Random((qp),(qp)->qp_delta)) +1 + (qp)->qp_offset; \
  114.     } else if ((val) >= (max)) {                                \
  115.   *(del) = -(Random((qp),(qp)->qp_delta))+1 - (qp)->qp_offset;   \
  116.     }                                                             \
  117. }                                                                  \
  118.  
  119. typedef struct {
  120.   LONG  x,y;
  121. } point;
  122.  
  123. struct QixStruct
  124.  {
  125.   struct BTDDrawInfo *BTDDrawInfo;
  126.   LONG   qp_Seconds;
  127.   LONG   qp_Time;
  128.   LONG   qp_Left;    /* Left Offset of our Rect */
  129.   LONG   qp_Top;     /* Top Offset of our Rect */
  130.   LONG   qp_Width;   /* Width of our Rect */
  131.   LONG   qp_Height;  /* Height of our Rect */
  132.   LONG   qp_pix;
  133.   LONG   qp_first;
  134.   LONG   qp_last;
  135.   LONG   qp_dx1;
  136.   LONG   qp_dy1;
  137.   LONG   qp_dx2;
  138.   LONG   qp_dy2;
  139.   LONG   qp_x1;
  140.   LONG   qp_y1;
  141.   LONG   qp_x2;
  142.   LONG   qp_y2;
  143.   LONG   qp_offset;
  144.   LONG   qp_delta;
  145.   LONG   qp_nlines;
  146.   LONG   qp_ncolors;
  147.   point  *qp_lineq;
  148.   LONG   hs_RandN,hs_RandF,hs_RandI;
  149.  };
  150.  
  151.  
  152. struct BTDInfo *QueryMyBlanker(void)
  153.  
  154. {
  155.  return &QixInfo;
  156. }
  157.  
  158.  
  159. void __regargs InitRandom(struct QixStruct *QP,ULONG Instance)
  160.  
  161. {
  162.  ULONG Time[2];
  163.  
  164.  CurrentTime (&Time[0],&Time[1]);
  165.  QP->hs_RandN=(LONG)Time[0];
  166.  if (Time[1]<1024L) Time[1]|=1;
  167.  else Time[1]>>=10;
  168.  Time[1]^=Instance;
  169.  
  170.  QP->hs_RandF=4*Time[1]+1;
  171.  QP->hs_RandI=2*Time[1]+1;
  172. }
  173.  
  174. WORD __regargs Random(struct QixStruct *QP,WORD Max)
  175.  
  176. {
  177.  QP->hs_RandN=QP->hs_RandF*QP->hs_RandN+QP->hs_RandI;
  178.  if (QP->hs_RandN<0L) QP->hs_RandN=-QP->hs_RandN;
  179.  
  180.  return (WORD)(QP->hs_RandN%Max);
  181. }
  182.  
  183.  
  184. #define FindTagData(l,t,d) GetTagData((t),(d),(l))
  185. /* rainbow colors */
  186.  
  187. #define NUM_RAINBOW_COLORS 6
  188.  
  189. UBYTE RBRed[NUM_RAINBOW_COLORS+1]   = {0xFF,0xFF,0x00,0x00,0x00,0xFF,0xFF};
  190. UBYTE RBGreen[NUM_RAINBOW_COLORS+1] = {0x00,0xFF,0xFF,0xFF,0x00,0x00,0x00};
  191. UBYTE RBBlue[NUM_RAINBOW_COLORS+1]  = {0x00,0x00,0x00,0xFF,0xFF,0xFF,0x00};
  192.  
  193. struct QixStruct *InitMyBlanker(struct TagItem *TagList)
  194. {
  195.  LONG Seconds,Lines,Colors;
  196.  struct QixStruct *QP;
  197.  struct BTDDrawInfo *BTDDrawInfo;
  198.  ULONG *Error,Dummy,Index,Instance;
  199.  
  200.  if ((BTDDrawInfo=(struct BTDDrawInfo *)
  201.                    FindTagData(TagList,BTD_DrawInfo,NULL))==NULL) return NULL;
  202.  Error=(LONG *)FindTagData(TagList,BTD_Error,(ULONG)&Dummy);
  203.  if ((QP=AllocVec(sizeof(struct QixStruct),MEMF_PUBLIC|MEMF_CLEAR))==NULL)
  204.   {
  205.    *Error=BTDERR_Memory;
  206.    return NULL;
  207.   }
  208.  
  209.  Lines=FindTagData(TagList,QP_Lines,DEF_LINES);
  210.  Seconds=FindTagData(TagList,QP_Seconds,DEF_SECONDS);
  211.  Colors=FindTagData(TagList,QP_Colors,DEF_COLORS);
  212.  Instance=FindTagData(TagList,BTD_Instance,0L);
  213.  
  214.  if (!QP->qp_lineq)
  215.   {
  216.    if ((QP->qp_lineq=(point *)AllocVec((Lines%2==0?Lines:Lines+1)*sizeof(point),MEMF_PUBLIC|MEMF_CLEAR))==NULL) 
  217.     {
  218.      *Error=BTDERR_Memory;
  219.      return NULL;
  220.     }
  221.   }
  222.  
  223.  
  224.  InitRandom(QP,Instance);
  225.  
  226.  QP->BTDDrawInfo=BTDDrawInfo;
  227.  QP->qp_Left=QP->BTDDrawInfo->BDI_Left;
  228.  QP->qp_Top=QP->BTDDrawInfo->BDI_Top;
  229.  QP->qp_Width=QP->BTDDrawInfo->BDI_Width;
  230.  QP->qp_Height=QP->BTDDrawInfo->BDI_Height;
  231.  
  232.  QP->qp_nlines=(Lines%2==0?Lines:Lines+1);
  233.  QP->qp_ncolors=Colors;
  234.  QP->qp_Seconds= Seconds;
  235.  QP->qp_delta=16;
  236.  QP->qp_offset = (LONG)(QP->qp_delta / 3);
  237.  QP->qp_last = 0;
  238.  QP->qp_pix = Random(QP,Colors);
  239.  QP->qp_x1 = Random(QP,QP->qp_Width)+1;
  240.  QP->qp_y1 = Random(QP,QP->qp_Height)+1;
  241.  QP->qp_x2 = Random(QP,QP->qp_Width)+1;
  242.  QP->qp_y2 = Random(QP,QP->qp_Height)+1;
  243.  
  244.  QP->qp_dx1 = Random(QP,QP->qp_delta) + QP->qp_offset;
  245.  QP->qp_dy1 = Random(QP,QP->qp_delta) + QP->qp_offset;
  246.  QP->qp_dx2 = Random(QP,QP->qp_delta) + QP->qp_offset;
  247.  QP->qp_dy2 = Random(QP,QP->qp_delta) + QP->qp_offset;
  248.  
  249.  if (QP->qp_ncolors>NUM_RAINBOW_COLORS)
  250.   {
  251.    LONG ColNum,Col,RBCol;
  252.    UBYTE *Red,*Green,*Blue,*Changed;
  253.  
  254.    Red=BTDDrawInfo->BDI_Red;
  255.    Green=BTDDrawInfo->BDI_Green;
  256.    Blue=BTDDrawInfo->BDI_Blue;
  257.    Changed=BTDDrawInfo->BDI_Changed;
  258.    ColNum=QP->qp_ncolors/NUM_RAINBOW_COLORS+1L;
  259.    Index=0L;
  260.    for (RBCol=0L; RBCol<NUM_RAINBOW_COLORS; RBCol++)
  261.     {
  262.      if (RBCol==(QP->qp_ncolors%NUM_RAINBOW_COLORS)) ColNum--;
  263.  
  264.      for (Col=0L; Col<ColNum; Col++)
  265.       {
  266.        Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[RBCol]+((RBRed[RBCol+1]-RBRed[RBCol])*Col)/ColNum;
  267.        Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[RBCol]+((RBGreen[RBCol+1]-RBGreen[RBCol])*Col)/ColNum;
  268.        Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[RBCol]+((RBBlue[RBCol+1]-RBBlue[RBCol])*Col)/ColNum;
  269.        Changed[BTDDrawInfo->BDI_Pens[Index++]]=TRUE;
  270.       }
  271.     }
  272.   }
  273.  else
  274.   for (Index=0L; Index<QP->qp_ncolors; Index++)
  275.    {
  276.     BTDDrawInfo->BDI_Red[BTDDrawInfo->BDI_Pens[Index]]=RBRed[Index];
  277.     BTDDrawInfo->BDI_Green[BTDDrawInfo->BDI_Pens[Index]]=RBGreen[Index];
  278.     BTDDrawInfo->BDI_Blue[BTDDrawInfo->BDI_Pens[Index]]=RBBlue[Index];
  279.     BTDDrawInfo->BDI_Changed[BTDDrawInfo->BDI_Pens[Index]]=TRUE;
  280.    }
  281.  
  282. DEBUG_PRINT("Qix: Init ready\n");
  283.  
  284.  return QP;
  285. }
  286.  
  287. void EndMyBlanker(struct QixStruct *QP)
  288.  
  289. {
  290. DEBUG_PRINT("Qix: FreeMem\n");
  291.  FreeVec (QP->qp_lineq);
  292.  FreeVec (QP);
  293. }
  294.  
  295. void AnimMyBlanker(struct QixStruct *QP)
  296.  
  297. {
  298.  
  299.   ULONG Seconds,Micros;
  300.   struct BTDDrawInfo *BTDDrawInfo;
  301.  
  302.   CurrentTime (&Seconds,&Micros);
  303.   if (Seconds>=QP->qp_Time)
  304.   {
  305.    QP->qp_Time=Seconds+QP->qp_Seconds;
  306.  
  307.    QP->qp_dx1 = Random(QP,QP->qp_delta) + QP->qp_offset;
  308.    QP->qp_dy1 = Random(QP,QP->qp_delta) + QP->qp_offset;
  309.    QP->qp_dx2 = Random(QP,QP->qp_delta) + QP->qp_offset;
  310.    QP->qp_dy2 = Random(QP,QP->qp_delta) + QP->qp_offset;
  311.   }
  312.  
  313.   QP->qp_first = (QP->qp_last + 2) % QP->qp_nlines;
  314.  
  315.   if(QP->qp_first<0) QP->qp_first=0;
  316.   if(QP->qp_first>QP->qp_nlines) QP->qp_first=QP->qp_nlines;
  317.  
  318.   QP->qp_x1 += QP->qp_dx1;
  319.   QP->qp_y1 += QP->qp_dy1;
  320.   QP->qp_x2 += QP->qp_dx2;
  321.   QP->qp_y2 += QP->qp_dy2;
  322.  
  323.   check_bounds(QP, QP->qp_x1, &QP->qp_dx1, QP->qp_Left, QP->qp_Width+QP->qp_Left);
  324.   check_bounds(QP, QP->qp_y1, &QP->qp_dy1, QP->qp_Top, QP->qp_Height+QP->qp_Top);
  325.   check_bounds(QP, QP->qp_x2, &QP->qp_dx2, QP->qp_Left, QP->qp_Width+QP->qp_Left);
  326.   check_bounds(QP, QP->qp_y2, &QP->qp_dy2, QP->qp_Top, QP->qp_Height+QP->qp_Top);
  327.  
  328.   if(QP->qp_x1>=QP->qp_Width+QP->qp_Left) QP->qp_x1=QP->qp_Width+QP->qp_Left-QP->qp_delta*2;
  329.   if(QP->qp_x1<=QP->qp_Left) QP->qp_x1=QP->qp_Left+QP->qp_delta*2;
  330.   if(QP->qp_x2>=QP->qp_Width+QP->qp_Left) QP->qp_x2=QP->qp_Width+QP->qp_Left-QP->qp_delta*2;
  331.   if(QP->qp_x2<=QP->qp_Left) QP->qp_x2=QP->qp_Left+QP->qp_delta*2;
  332.  
  333.   if(QP->qp_y1>=QP->qp_Height+QP->qp_Top) QP->qp_y1=QP->qp_Height+QP->qp_Top-QP->qp_delta*2;
  334.   if(QP->qp_y1<=QP->qp_Top) QP->qp_y1=QP->qp_Top+QP->qp_delta*2;
  335.   if(QP->qp_y2>=QP->qp_Height+QP->qp_Top) QP->qp_y2=QP->qp_Height+QP->qp_Top-QP->qp_delta*2;
  336.   if(QP->qp_y2<=QP->qp_Top) QP->qp_y2=QP->qp_Top+QP->qp_delta*2;
  337.  
  338.   BTDDrawInfo= QP->BTDDrawInfo;
  339.  
  340.   SetAPen(BTDDrawInfo->BDI_RPort,BTD_BgPen);
  341.   Move(BTDDrawInfo->BDI_RPort,QP->qp_lineq[QP->qp_first].x, QP->qp_lineq[QP->qp_first].y);
  342.   Draw(BTDDrawInfo->BDI_RPort,QP->qp_lineq[QP->qp_first + 1].x, QP->qp_lineq[QP->qp_first + 1].y);
  343.  
  344.   SetAPen(BTDDrawInfo->BDI_RPort,BTDDrawInfo->BDI_Pens[QP->qp_pix]);
  345.   if (QP->qp_pix++ > QP->qp_ncolors) QP->qp_pix = 0;
  346.  
  347.   Move(BTDDrawInfo->BDI_RPort,QP->qp_x1,QP->qp_y1);
  348.   Draw(BTDDrawInfo->BDI_RPort,QP->qp_x2,QP->qp_y2);
  349.  
  350.   QP->qp_lineq[QP->qp_last].x = QP->qp_x1;
  351.   QP->qp_lineq[QP->qp_last].y = QP->qp_y1;
  352.   QP->qp_last++;
  353.   if (QP->qp_last >= QP->qp_nlines) QP->qp_last = 0;
  354.  
  355.   QP->qp_lineq[QP->qp_last].x = QP->qp_x2;
  356.   QP->qp_lineq[QP->qp_last].y = QP->qp_y2;
  357.   QP->qp_last++;
  358.   if (QP->qp_last >= QP->qp_nlines)    QP->qp_last = 0;
  359. }
  360.  
  361. ULONG PenCountMyBlanker(struct TagItem *TagList)
  362.  
  363. {
  364.  ULONG colors;
  365.  colors=FindTagData(TagList,QP_Colors,DEF_COLORS);
  366.  return colors;
  367. }
  368.