home *** CD-ROM | disk | FTP | other *** search
/ The Best of Mecomp Multimedia 2 / MECOMP-CD-II.iso / amiga / tools / workbench / copperfade / copperfade10.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-04  |  10.1 KB  |  403 lines

  1. /*
  2. ** CopperFade.c
  3. ** ------------
  4. **
  5. ** First try of an system friendly aga copperlist
  6. **
  7. ** gcc -noixemul -s -O2 -m68020 -o copperfade copperfade.c
  8. **
  9. ** Examples:
  10. ** ---------
  11. ** copperfade c=27 step=2 0 155 56 86 27 0 82 155 56
  12. */
  13.  
  14. #define   __CONSTLIBBASEDECL__  const
  15. #include  <intuition/screens.h>
  16. #include  <graphics/copper.h>
  17. #include  <graphics/view.h>
  18. #include  <graphics/gfxmacros.h>
  19. #include  <graphics/videocontrol.h>
  20. #include  <graphics/GfxBase.h>
  21. #include  <dos/dos.h>
  22. #include  <exec/memory.h>
  23. #include  <hardware/custom.h>
  24.  
  25. #include  <proto/exec.h>
  26. #include  <proto/graphics.h>
  27. #include  <proto/intuition.h>
  28.  
  29. #include  <string.h>
  30. #include  <math.h>
  31.  
  32. /*///"structures and strings "*/
  33. int __nocommandline=1;
  34. char  *VERSION = "$VER: CopperFade 1.0 (" __DATE__ ") by W. Pernath";
  35.  
  36. #define STDCOL     27
  37. #define TEMPLATE  "PS=PUBSCREEN/K,C=COLOR/K/N,STEP/K/N,YSTRT/K/N,YSTOP/K/N,RESET/S,R1/N/A,G1/N/A,B1/N/A,R2/N/A,G2/N/A,B2/N/A,R3/N,G3/N,B3/N"
  38. struct  Arguments
  39. {
  40.     char    *arg_PubName;
  41.     ULONG   *arg_ColorNum;
  42.     ULONG   *arg_Step;
  43.     ULONG   *arg_YStart;
  44.     ULONG   *arg_YStop;
  45.     ULONG   arg_Reset;
  46.     ULONG   *arg_R1,
  47.                     *arg_G1,
  48.                     *arg_B1;
  49.     ULONG   *arg_R2,
  50.                     *arg_G2,
  51.                     *arg_B2;
  52.     ULONG   *arg_R3,
  53.                     *arg_G3,
  54.                     *arg_B3;
  55. };
  56. /*///*/
  57. /*///"global variables "*/
  58. extern  struct Custom custom;
  59.  
  60. struct  Screen      *scr;
  61. struct  ViewPort    *vp;
  62. struct  UCopList    *ucop;
  63. struct  Arguments   args;
  64. BOOL                MiddleSet = 0;
  65. ULONG               YSize = 256;
  66. ULONG               Step  = 1;
  67. ULONG               Color = 0;
  68. ULONG               YStart=0;
  69. ULONG               YStop=0;
  70. BOOL                Reset=0;
  71. ULONG               Red1 = 0,
  72.                                         Green1=0,
  73.                                         Blue1=0,
  74.                                         Red2=0,
  75.                                         Green2=0,
  76.                                         Blue2=0,
  77.                                         Red3=0,
  78.                                         Green3=0,
  79.                                         Blue3=0;
  80. ULONG               ResRGB[]  = { 0, 0, 0 };
  81. /*///*/
  82. /*///"int AGAChipSet( void )"*/
  83. int AGAChipSet( void )
  84. {
  85.     struct GfxBase  *gb = GfxBase;
  86.  
  87.     /* Test if we're running under AGA */
  88.     if( ( gb->ChipRevBits0 & ( GFXF_AA_ALICE | GFXF_AA_LISA ) ) &&
  89.         ( gb->LibNode.lib_Version >= 39 ) )
  90.         return(1);
  91.     else
  92.         return(0);
  93. }
  94. /*///*/
  95. /*///"int NativeScreen( struct Screen * )"*/
  96. int NativeScreen( struct Screen *scr )
  97. {
  98.     struct  BitMap  *bmap;
  99.  
  100.     bmap = scr->RastPort.BitMap;
  101.     if( GetBitMapAttr( bmap, BMA_FLAGS ) & BMF_STANDARD )
  102.         return( 1 );
  103.     else
  104.         return( 0 );
  105. }
  106. /*///*/
  107. /*///"struct UCopList *InitCopper( Long )"*/
  108. struct UCopList *InitCopper( LONG num )
  109. {
  110.     struct  UCopList  *ucop;
  111.     struct  CopList   *cop;
  112.  
  113.     if( ucop = AllocVec( sizeof( struct UCopList ), MEMF_PUBLIC|MEMF_CLEAR ) )
  114.     {
  115.         CINIT( ucop, num+1 );
  116.         return( ucop );
  117.     }
  118.     return( NULL );
  119. }
  120. /*///*/
  121. /*///"void StartCopList( struct ViewPort *, struct UCopList *)"*/
  122. void StartCopList( struct ViewPort *vp, struct UCopList *cop )
  123. {
  124.     struct  TagItem copTags[] =
  125.     {
  126.         {VTAG_USERCLIP_SET, NULL },
  127.         {VTAG_END_CM, NULL }
  128.     };
  129.  
  130.     CEND( cop );
  131.     Forbid();
  132.     vp->UCopIns = cop;
  133.     Permit();
  134.     VideoControl( vp->ColorMap, copTags );
  135.     RethinkDisplay();
  136. }
  137. /*///*/
  138. /*///"void StopCopList( struct ViewPort *, struct UCopList * )"*/
  139. void StopCopList( struct ViewPort *vp, struct UCopList *cop )
  140. {
  141.     vp->UCopIns = NULL;
  142.     RethinkDisplay();
  143.     FreeCopList( cop->FirstCopList );
  144.     FreeVec( cop );
  145. }
  146. /*///*/
  147. /*///"void SetCopperColor( struct ViewPort *, struct UCopList *, UBYTE, UBYTE, UBYTE, UBYTE )"*/
  148. #define LOCTF 1 << 9
  149. /* The BPLCON3 register (0x106):
  150. ** 15-13    choose betw. the color bank num (0-8)
  151. ** 12-10    playfield2 color table offset
  152. ** 9        LOCT bit! When clr msb val of color/set lsb of color
  153. ** 8        unused
  154. ** 7-6      Sprite resolution: 0=ECS def. / 1=LORES(140ns) / 2=HIRES(70ns) / 3=SHIRES(35ns)
  155. ** 5        borderblank
  156. ** 4        borderntrans
  157. ** 3        unused
  158. ** 2        ZDCLKEN
  159. ** 1        bordersprite
  160. ** 0        set when non NTSC/PAL displ mode
  161. */
  162. void SetCopperColor( struct ViewPort *vp, struct UCopList *ucop, UBYTE reg, UBYTE r, UBYTE g, UBYTE b )
  163. {
  164.     struct GfxBase  *gb = GfxBase;
  165.     UWORD lrgb, mrgb;
  166.     int   bnum, rcol;
  167.     UWORD bitset;
  168.     static UWORD  bplcon3bits = 0;
  169.     static struct TagItem  VCTags[]  = {
  170.                                                                 { VTAG_BORDERNOTRANS_GET, NULL },
  171.                                                                 { VTAG_SPRITERESN_GET, NULL },
  172.                                                                 { TAG_DONE, NULL }
  173.                                                             };
  174.  
  175.     static BOOL firsttime = 1;
  176.     int bit;
  177.  
  178.     /* get correct color bank indicator     */
  179.     /* we have 8 banks with each 32 colors  */
  180.     bnum = reg / 32;
  181.     rcol = reg % 32;
  182.  
  183.     /* get the rest of the bpl3con bits by using VideoControl() */
  184.     if( firsttime ){
  185.         firsttime = 0;
  186.         VideoControl( vp->ColorMap, VCTags );
  187.  
  188.         /* set borderblank */
  189.         bit = (gb->BP3Bits & (1<<5));
  190.         bplcon3bits |= bit?1 << 5 : 0;
  191.         /* set Bordersprite */
  192.         bit = (gb->BP3Bits & (1<<1));
  193.         bplcon3bits |= bit?1 << 1 : 0;
  194.  
  195.         /* set border n trans */
  196.         bplcon3bits |= VCTags[ 0 ].ti_Data << 4;
  197.         /* set spriteresn */
  198.         bplcon3bits |= VCTags[ 1 ].ti_Data << 6;
  199.         /*
  200.         ** Set the EXTBLKEN bit to make the BEAM programmable instead of
  201.         ** reflecting internal fixed decodes.
  202.         */
  203.         bplcon3bits |= 1;
  204.     }
  205.     bitset = bplcon3bits | ( bnum << 13 );
  206.  
  207.     /* extract the low and most significant 4bits of the color */
  208.     lrgb =  ( ( r & 0x0f ) << 8 ) | ( ( g & 0x0f ) << 4 ) | ( b & 0x0f );
  209.     mrgb =  ( ( ( r & 0xf0 ) >> 4 ) << 8 ) | ( ( ( g & 0xf0 ) >> 4 ) << 4 ) | ( ( b & 0xf0 ) >> 4 );
  210.  
  211.     /* clr loct bit on bplcon3 to access the lsb */
  212.     CMOVE( ucop, custom.bplcon3, bitset );
  213.  
  214.     /* set low order bits */
  215.     CMOVE( ucop, custom.color[ rcol ], mrgb );
  216.  
  217.     /* set LOCT bit to access the msb rgb triplet */
  218.     CMOVE( ucop, custom.bplcon3, bitset | LOCTF );
  219.     CMOVE( ucop, custom.color[ rcol ], lrgb );
  220. }
  221. /*///*/
  222. /*///"void BuildCopper( struct UCopList * )"*/
  223. void BuildCopper( struct UCopList *ucop )
  224. {
  225.     int y = YStart;
  226.     UBYTE   r1=Red1, g1=Green1, b1=Blue1,
  227.                     r2=Red2, g2=Green2, b2=Blue2,
  228.                     r3=Red3, g3=Green3, b3=Blue3;
  229.     UBYTE   rg, gg, bg;
  230.     float   dr, dg, db;
  231.     float   diff = (YStop - YStart ) / Step;
  232.     int     half;
  233.     int     i;
  234.  
  235.     /* calculate the difference between red1/red2,.... */
  236.     if(!diff )  diff = 1.0;
  237.  
  238.     if( !MiddleSet )
  239.     {
  240.         /* We only have one colorfade until YStop */
  241.         dr = (r2-r1)/diff;
  242.         dg = (g2-g1)/diff;
  243.         db = (b2-b1)/diff;
  244.  
  245.         for( y = YStart, i = YStart; y < YStop; i++, y+=Step )
  246.         {
  247.             CWAIT( ucop, y, 0);
  248.             rg = (UBYTE )(r1+(i-YStart)*dr);
  249.             gg = (UBYTE )(g1+(i-YStart)*dg);
  250.             bg = (UBYTE )(b1+(i-YStart)*db);
  251.             SetCopperColor( vp, ucop, Color, rg, gg, bg );
  252.         }
  253.     }else{
  254.         /* We must fade until the middle of the given range and then
  255.         ** again until the end of given range
  256.         */
  257.         diff = (YStop - YStart ) / 2 / Step;
  258.         dr = (r2-r1)/diff;
  259.         dg = (g2-g1)/diff;
  260.         db = (b2-b1)/diff;
  261.  
  262.         for( y = YStart, i=YStart; y < ( YStop / 2 ) + 1; i++, y+=Step )
  263.         {
  264.             CWAIT( ucop, y, 0 );
  265.             rg = (UBYTE )(r1+(i-YStart)*dr);
  266.             gg = (UBYTE )(g1+(i-YStart)*dg);
  267.             bg = (UBYTE )(b1+(i-YStart)*db);
  268.             SetCopperColor( vp, ucop, Color, rg, gg, bg );
  269.         }
  270.         dr = (r3-r2)/diff;
  271.         dg = (g3-g2)/diff;
  272.         db = (b3-b2)/diff;
  273.  
  274.         half = YStop / 2;
  275.         for( y = ( YStart + half ) + 1, i = YStart; y < YStop; i++, y+=Step )
  276.         {
  277.             CWAIT( ucop, y, 0 );
  278.             rg = (UBYTE )(r2+(i-YStart)*dr);
  279.             gg = (UBYTE )(g2+(i-YStart)*dg);
  280.             bg = (UBYTE )(b2+(i-YStart)*db);
  281.             SetCopperColor( vp, ucop, Color, rg, gg, bg );
  282.         }
  283.     }
  284.  
  285.     if( Reset ){
  286.         /* Should we reset the color after reaching the last scanline ? */
  287.         CWAIT( ucop, YStop, 0 );
  288.         SetCopperColor( vp, ucop, Color, (UBYTE )(ResRGB[ 0 ] & 0xff), (UBYTE )( ResRGB[1] & 0xff ), (UBYTE )(ResRGB[2] & 0xff) );
  289.     }
  290. }
  291. /*///*/
  292. /*///"int main(void )"*/
  293. int main(void )
  294. {
  295.     struct  RDArgs  *rdargs = NULL;
  296.     int             ok = FALSE;
  297.  
  298.     /* Test for AGA chips and OS3.x */
  299.     if( !AGAChipSet() ){
  300.         Printf("CopperFade: Need AGA Chip-Set and OS3.x to run.\n");
  301.         return(20);
  302.     }
  303.  
  304.     /* Set default args */
  305.     args.arg_PubName  = NULL;
  306.     args.arg_ColorNum = NULL;
  307.     args.arg_Step     = NULL;
  308.     args.arg_YStart   = NULL;
  309.     args.arg_YStop    = NULL;
  310.     args.arg_Reset    = 0;
  311.     args.arg_R1       = NULL;
  312.     args.arg_G1       = NULL;
  313.     args.arg_B1       = NULL;
  314.     args.arg_R2       = NULL;
  315.     args.arg_G2       = NULL;
  316.     args.arg_B2       = NULL;
  317.     args.arg_R3       = NULL;
  318.     args.arg_G3       = NULL;
  319.     args.arg_B3       = NULL;
  320.  
  321.     /* Read the arguments */
  322.     if(!( rdargs = ReadArgs( (STRPTR )TEMPLATE, (LONG *)&args, NULL ) ) )
  323.     {
  324.         PrintFault( IoErr(), "CopperFade");
  325.         return(0);
  326.     }
  327.     FreeArgs( rdargs );
  328.  
  329.     if( scr = LockPubScreen( args.arg_PubName ) )
  330.     {
  331.         vp = &scr->ViewPort;
  332.         ok = vp->UCopIns ? 0 : 1;
  333.     }else{
  334.         Printf("CopperFade: Could not lock public screen.\n");
  335.         return(20);
  336.     }
  337.  
  338.     if( !NativeScreen( scr ) ){
  339.         Printf("CopperFade: Copperlist not installable on non-native screens.\n");
  340.         UnlockPubScreen( NULL, scr );
  341.         return(20);
  342.     }
  343.  
  344.     if( !ok ){
  345.         Printf("CopperFade: There is allready a user copper list installed.\n");
  346.         UnlockPubScreen( NULL, scr );
  347.         return(20);
  348.     }
  349.  
  350.     /* setup the argument set */
  351.     Color   = args.arg_ColorNum ? *args.arg_ColorNum : 0;
  352.     Step    = args.arg_Step ? *args.arg_Step : 1;
  353.     if( Step == 0 ) Step = 1;
  354.     YStart  = args.arg_YStart ? *args.arg_YStart : 0;
  355.     YStop   = args.arg_YStop ? *args.arg_YStop : scr->Height;
  356.     if( YStop == 0) YStop = scr->Height;
  357.     Reset   = args.arg_Reset;
  358.     Red1    = *args.arg_R1;
  359.     Green1  = *args.arg_G1;
  360.     Blue1   = *args.arg_B1;
  361.     Red2    = *args.arg_R2;
  362.     Green2  = *args.arg_G2;
  363.     Blue2   = *args.arg_B2;
  364.     /* Test if user wants to have a third color fade */
  365.     if( args.arg_R3 ){
  366.         if((!args.arg_G3 ) && (!args.arg_B3) ){
  367.             PrintFault( ERROR_REQUIRED_ARG_MISSING, "CopperFade" );
  368.             UnlockPubScreen( NULL, scr );
  369.             return(20);
  370.         }
  371.         MiddleSet = 1;
  372.         Red3    = *args.arg_R3;
  373.         Green3  = *args.arg_G3;
  374.         Blue3   = *args.arg_B3;
  375.     }
  376.  
  377.     if( Red1 > 255 )    Red1    = 255;
  378.     if( Red2 > 255 )    Red2    = 255;
  379.     if( Red3 > 255 )    Red3    = 255;
  380.     if( Green1 > 255 )  Green1  = 255;
  381.     if( Green2 > 255 )  Green2  = 255;
  382.     if( Green3 > 255 )  Green3  = 255;
  383.     if( Blue1 > 255 )   Blue1   = 255;
  384.     if( Blue2 > 255 )   Blue2   = 255;
  385.     if( Blue3 > 255 )   Blue3   = 255;
  386.  
  387.     /* Initialize the copper list */
  388.     if( ucop = InitCopper( ( ( ( YStop - YStart ) / Step ) * 5 ) + 10 ) )
  389.     {
  390.         if( Reset ){
  391.             /* Reset colornum after scanline YStop? */
  392.             GetRGB32(vp->ColorMap, Color, 1, (ULONG *)&ResRGB );
  393.         }
  394.  
  395.         BuildCopper(ucop);
  396.         StartCopList( vp, ucop );
  397.         Wait( SIGBREAKF_CTRL_C );
  398.         StopCopList( vp, ucop );
  399.     }
  400.     UnlockPubScreen( NULL, scr );
  401. }
  402. /*///*/
  403.