home *** CD-ROM | disk | FTP | other *** search
- /*
- ** CopperFade.c
- ** ------------
- **
- ** First try of an system friendly aga copperlist
- **
- ** gcc -noixemul -s -O2 -m68020 -o copperfade copperfade.c
- **
- ** Examples:
- ** ---------
- ** copperfade c=27 step=2 0 155 56 86 27 0 82 155 56
- */
-
- #define __CONSTLIBBASEDECL__ const
- #include <intuition/screens.h>
- #include <graphics/copper.h>
- #include <graphics/view.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/videocontrol.h>
- #include <graphics/GfxBase.h>
- #include <dos/dos.h>
- #include <exec/memory.h>
- #include <hardware/custom.h>
-
- #include <proto/exec.h>
- #include <proto/graphics.h>
- #include <proto/intuition.h>
-
- #include <string.h>
- #include <math.h>
-
- /*///"structures and strings "*/
- int __nocommandline=1;
- char *VERSION = "$VER: CopperFade 1.0 (" __DATE__ ") by W. Pernath";
-
- #define STDCOL 27
- #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"
- struct Arguments
- {
- char *arg_PubName;
- ULONG *arg_ColorNum;
- ULONG *arg_Step;
- ULONG *arg_YStart;
- ULONG *arg_YStop;
- ULONG arg_Reset;
- ULONG *arg_R1,
- *arg_G1,
- *arg_B1;
- ULONG *arg_R2,
- *arg_G2,
- *arg_B2;
- ULONG *arg_R3,
- *arg_G3,
- *arg_B3;
- };
- /*///*/
- /*///"global variables "*/
- extern struct Custom custom;
-
- struct Screen *scr;
- struct ViewPort *vp;
- struct UCopList *ucop;
- struct Arguments args;
- BOOL MiddleSet = 0;
- ULONG YSize = 256;
- ULONG Step = 1;
- ULONG Color = 0;
- ULONG YStart=0;
- ULONG YStop=0;
- BOOL Reset=0;
- ULONG Red1 = 0,
- Green1=0,
- Blue1=0,
- Red2=0,
- Green2=0,
- Blue2=0,
- Red3=0,
- Green3=0,
- Blue3=0;
- ULONG ResRGB[] = { 0, 0, 0 };
- /*///*/
- /*///"int AGAChipSet( void )"*/
- int AGAChipSet( void )
- {
- struct GfxBase *gb = GfxBase;
-
- /* Test if we're running under AGA */
- if( ( gb->ChipRevBits0 & ( GFXF_AA_ALICE | GFXF_AA_LISA ) ) &&
- ( gb->LibNode.lib_Version >= 39 ) )
- return(1);
- else
- return(0);
- }
- /*///*/
- /*///"int NativeScreen( struct Screen * )"*/
- int NativeScreen( struct Screen *scr )
- {
- struct BitMap *bmap;
-
- bmap = scr->RastPort.BitMap;
- if( GetBitMapAttr( bmap, BMA_FLAGS ) & BMF_STANDARD )
- return( 1 );
- else
- return( 0 );
- }
- /*///*/
- /*///"struct UCopList *InitCopper( Long )"*/
- struct UCopList *InitCopper( LONG num )
- {
- struct UCopList *ucop;
- struct CopList *cop;
-
- if( ucop = AllocVec( sizeof( struct UCopList ), MEMF_PUBLIC|MEMF_CLEAR ) )
- {
- CINIT( ucop, num+1 );
- return( ucop );
- }
- return( NULL );
- }
- /*///*/
- /*///"void StartCopList( struct ViewPort *, struct UCopList *)"*/
- void StartCopList( struct ViewPort *vp, struct UCopList *cop )
- {
- struct TagItem copTags[] =
- {
- {VTAG_USERCLIP_SET, NULL },
- {VTAG_END_CM, NULL }
- };
-
- CEND( cop );
- Forbid();
- vp->UCopIns = cop;
- Permit();
- VideoControl( vp->ColorMap, copTags );
- RethinkDisplay();
- }
- /*///*/
- /*///"void StopCopList( struct ViewPort *, struct UCopList * )"*/
- void StopCopList( struct ViewPort *vp, struct UCopList *cop )
- {
- vp->UCopIns = NULL;
- RethinkDisplay();
- FreeCopList( cop->FirstCopList );
- FreeVec( cop );
- }
- /*///*/
- /*///"void SetCopperColor( struct ViewPort *, struct UCopList *, UBYTE, UBYTE, UBYTE, UBYTE )"*/
- #define LOCTF 1 << 9
- /* The BPLCON3 register (0x106):
- ** 15-13 choose betw. the color bank num (0-8)
- ** 12-10 playfield2 color table offset
- ** 9 LOCT bit! When clr msb val of color/set lsb of color
- ** 8 unused
- ** 7-6 Sprite resolution: 0=ECS def. / 1=LORES(140ns) / 2=HIRES(70ns) / 3=SHIRES(35ns)
- ** 5 borderblank
- ** 4 borderntrans
- ** 3 unused
- ** 2 ZDCLKEN
- ** 1 bordersprite
- ** 0 set when non NTSC/PAL displ mode
- */
- void SetCopperColor( struct ViewPort *vp, struct UCopList *ucop, UBYTE reg, UBYTE r, UBYTE g, UBYTE b )
- {
- struct GfxBase *gb = GfxBase;
- UWORD lrgb, mrgb;
- int bnum, rcol;
- UWORD bitset;
- static UWORD bplcon3bits = 0;
- static struct TagItem VCTags[] = {
- { VTAG_BORDERNOTRANS_GET, NULL },
- { VTAG_SPRITERESN_GET, NULL },
- { TAG_DONE, NULL }
- };
-
- static BOOL firsttime = 1;
- int bit;
-
- /* get correct color bank indicator */
- /* we have 8 banks with each 32 colors */
- bnum = reg / 32;
- rcol = reg % 32;
-
- /* get the rest of the bpl3con bits by using VideoControl() */
- if( firsttime ){
- firsttime = 0;
- VideoControl( vp->ColorMap, VCTags );
-
- /* set borderblank */
- bit = (gb->BP3Bits & (1<<5));
- bplcon3bits |= bit?1 << 5 : 0;
- /* set Bordersprite */
- bit = (gb->BP3Bits & (1<<1));
- bplcon3bits |= bit?1 << 1 : 0;
-
- /* set border n trans */
- bplcon3bits |= VCTags[ 0 ].ti_Data << 4;
- /* set spriteresn */
- bplcon3bits |= VCTags[ 1 ].ti_Data << 6;
- /*
- ** Set the EXTBLKEN bit to make the BEAM programmable instead of
- ** reflecting internal fixed decodes.
- */
- bplcon3bits |= 1;
- }
- bitset = bplcon3bits | ( bnum << 13 );
-
- /* extract the low and most significant 4bits of the color */
- lrgb = ( ( r & 0x0f ) << 8 ) | ( ( g & 0x0f ) << 4 ) | ( b & 0x0f );
- mrgb = ( ( ( r & 0xf0 ) >> 4 ) << 8 ) | ( ( ( g & 0xf0 ) >> 4 ) << 4 ) | ( ( b & 0xf0 ) >> 4 );
-
- /* clr loct bit on bplcon3 to access the lsb */
- CMOVE( ucop, custom.bplcon3, bitset );
-
- /* set low order bits */
- CMOVE( ucop, custom.color[ rcol ], mrgb );
-
- /* set LOCT bit to access the msb rgb triplet */
- CMOVE( ucop, custom.bplcon3, bitset | LOCTF );
- CMOVE( ucop, custom.color[ rcol ], lrgb );
- }
- /*///*/
- /*///"void BuildCopper( struct UCopList * )"*/
- void BuildCopper( struct UCopList *ucop )
- {
- int y = YStart;
- UBYTE r1=Red1, g1=Green1, b1=Blue1,
- r2=Red2, g2=Green2, b2=Blue2,
- r3=Red3, g3=Green3, b3=Blue3;
- UBYTE rg, gg, bg;
- float dr, dg, db;
- float diff = (YStop - YStart ) / Step;
- int half;
- int i;
-
- /* calculate the difference between red1/red2,.... */
- if(!diff ) diff = 1.0;
-
- if( !MiddleSet )
- {
- /* We only have one colorfade until YStop */
- dr = (r2-r1)/diff;
- dg = (g2-g1)/diff;
- db = (b2-b1)/diff;
-
- for( y = YStart, i = YStart; y < YStop; i++, y+=Step )
- {
- CWAIT( ucop, y, 0);
- rg = (UBYTE )(r1+(i-YStart)*dr);
- gg = (UBYTE )(g1+(i-YStart)*dg);
- bg = (UBYTE )(b1+(i-YStart)*db);
- SetCopperColor( vp, ucop, Color, rg, gg, bg );
- }
- }else{
- /* We must fade until the middle of the given range and then
- ** again until the end of given range
- */
- diff = (YStop - YStart ) / 2 / Step;
- dr = (r2-r1)/diff;
- dg = (g2-g1)/diff;
- db = (b2-b1)/diff;
-
- for( y = YStart, i=YStart; y < ( YStop / 2 ) + 1; i++, y+=Step )
- {
- CWAIT( ucop, y, 0 );
- rg = (UBYTE )(r1+(i-YStart)*dr);
- gg = (UBYTE )(g1+(i-YStart)*dg);
- bg = (UBYTE )(b1+(i-YStart)*db);
- SetCopperColor( vp, ucop, Color, rg, gg, bg );
- }
- dr = (r3-r2)/diff;
- dg = (g3-g2)/diff;
- db = (b3-b2)/diff;
-
- half = YStop / 2;
- for( y = ( YStart + half ) + 1, i = YStart; y < YStop; i++, y+=Step )
- {
- CWAIT( ucop, y, 0 );
- rg = (UBYTE )(r2+(i-YStart)*dr);
- gg = (UBYTE )(g2+(i-YStart)*dg);
- bg = (UBYTE )(b2+(i-YStart)*db);
- SetCopperColor( vp, ucop, Color, rg, gg, bg );
- }
- }
-
- if( Reset ){
- /* Should we reset the color after reaching the last scanline ? */
- CWAIT( ucop, YStop, 0 );
- SetCopperColor( vp, ucop, Color, (UBYTE )(ResRGB[ 0 ] & 0xff), (UBYTE )( ResRGB[1] & 0xff ), (UBYTE )(ResRGB[2] & 0xff) );
- }
- }
- /*///*/
- /*///"int main(void )"*/
- int main(void )
- {
- struct RDArgs *rdargs = NULL;
- int ok = FALSE;
-
- /* Test for AGA chips and OS3.x */
- if( !AGAChipSet() ){
- Printf("CopperFade: Need AGA Chip-Set and OS3.x to run.\n");
- return(20);
- }
-
- /* Set default args */
- args.arg_PubName = NULL;
- args.arg_ColorNum = NULL;
- args.arg_Step = NULL;
- args.arg_YStart = NULL;
- args.arg_YStop = NULL;
- args.arg_Reset = 0;
- args.arg_R1 = NULL;
- args.arg_G1 = NULL;
- args.arg_B1 = NULL;
- args.arg_R2 = NULL;
- args.arg_G2 = NULL;
- args.arg_B2 = NULL;
- args.arg_R3 = NULL;
- args.arg_G3 = NULL;
- args.arg_B3 = NULL;
-
- /* Read the arguments */
- if(!( rdargs = ReadArgs( (STRPTR )TEMPLATE, (LONG *)&args, NULL ) ) )
- {
- PrintFault( IoErr(), "CopperFade");
- return(0);
- }
- FreeArgs( rdargs );
-
- if( scr = LockPubScreen( args.arg_PubName ) )
- {
- vp = &scr->ViewPort;
- ok = vp->UCopIns ? 0 : 1;
- }else{
- Printf("CopperFade: Could not lock public screen.\n");
- return(20);
- }
-
- if( !NativeScreen( scr ) ){
- Printf("CopperFade: Copperlist not installable on non-native screens.\n");
- UnlockPubScreen( NULL, scr );
- return(20);
- }
-
- if( !ok ){
- Printf("CopperFade: There is allready a user copper list installed.\n");
- UnlockPubScreen( NULL, scr );
- return(20);
- }
-
- /* setup the argument set */
- Color = args.arg_ColorNum ? *args.arg_ColorNum : 0;
- Step = args.arg_Step ? *args.arg_Step : 1;
- if( Step == 0 ) Step = 1;
- YStart = args.arg_YStart ? *args.arg_YStart : 0;
- YStop = args.arg_YStop ? *args.arg_YStop : scr->Height;
- if( YStop == 0) YStop = scr->Height;
- Reset = args.arg_Reset;
- Red1 = *args.arg_R1;
- Green1 = *args.arg_G1;
- Blue1 = *args.arg_B1;
- Red2 = *args.arg_R2;
- Green2 = *args.arg_G2;
- Blue2 = *args.arg_B2;
- /* Test if user wants to have a third color fade */
- if( args.arg_R3 ){
- if((!args.arg_G3 ) && (!args.arg_B3) ){
- PrintFault( ERROR_REQUIRED_ARG_MISSING, "CopperFade" );
- UnlockPubScreen( NULL, scr );
- return(20);
- }
- MiddleSet = 1;
- Red3 = *args.arg_R3;
- Green3 = *args.arg_G3;
- Blue3 = *args.arg_B3;
- }
-
- if( Red1 > 255 ) Red1 = 255;
- if( Red2 > 255 ) Red2 = 255;
- if( Red3 > 255 ) Red3 = 255;
- if( Green1 > 255 ) Green1 = 255;
- if( Green2 > 255 ) Green2 = 255;
- if( Green3 > 255 ) Green3 = 255;
- if( Blue1 > 255 ) Blue1 = 255;
- if( Blue2 > 255 ) Blue2 = 255;
- if( Blue3 > 255 ) Blue3 = 255;
-
- /* Initialize the copper list */
- if( ucop = InitCopper( ( ( ( YStop - YStart ) / Step ) * 5 ) + 10 ) )
- {
- if( Reset ){
- /* Reset colornum after scanline YStop? */
- GetRGB32(vp->ColorMap, Color, 1, (ULONG *)&ResRGB );
- }
-
- BuildCopper(ucop);
- StartCopList( vp, ucop );
- Wait( SIGBREAKF_CTRL_C );
- StopCopList( vp, ucop );
- }
- UnlockPubScreen( NULL, scr );
- }
- /*///*/
-