home *** CD-ROM | disk | FTP | other *** search
- /*
- * MandelVroom 2.0
- *
- * (c) Copyright 1987,1989 Kevin L. Clague, San Jose, CA
- *
- * All rights reserved.
- *
- * Permission is hereby granted to distribute this program's source
- * executable, and documentation for non-comercial purposes, so long as the
- * copyright notices are not removed from the sources, executable or
- * documentation. This program may not be distributed for a profit without
- * the express written consent of the author Kevin L. Clague.
- *
- * This program is not in the public domain.
- *
- * Fred Fish is expressly granted permission to distribute this program's
- * source and executable as part of the "Fred Fish freely redistributable
- * Amiga software library."
- *
- * Permission is expressly granted for this program and it's source to be
- * distributed as part of the Amicus Amiga software disks, and the
- * First Amiga User Group's Hot Mix disks.
- *
- * contents: this file contains functions to redraw (or repaint) Mandelbrot
- * and Julia projects. There are special high-performance functions to
- * recolor 4 and 5 bit plane pictures (in assembly). There is also a
- * function that can spawn off a child task to redraw the picture (for the
- * other number of bit planes 1,2,3 and 6)
- */
-
- #include "mandp.h"
-
- extern LONG pSigMask;
-
- /*
- * ReColor a picture into a window
- */
- ReColor( Pict )
- register struct Picture *Pict;
- {
- /* This set of variables should not be rearranged or moved.
- There is Assembly language used in this routine, to increase
- performance. The assembly code depends on these variables
- being located on Manx's stack. Obviously it is not too portable
- or maintainable, but it is faster.
- */
- SHORT *CountPtr;
- UBYTE *ColorPtr;
-
- register LONG CountX, CountY;
-
- /* These variables are O.K. to rearrange and add to. */
-
- register struct Window *Window;
- register LONG dx,dy;
-
- LONG i, Depth;
-
- UBYTE *ColorSave;
-
- LONG wx,wy,Sx;
-
- if ( Pict == NULL )
- return;
-
- KillReColor( Pict );
- FreeScrollTemp( Pict );
- PauseChild(Pict);
-
- Window = Pict->Window;
- CountPtr = Pict->Counts;
- CountX = Pict->CountX;
- CountY = Pict->CountY;
-
- Depth = screen->BitMap.Depth;
-
- if (CountPtr == NULL || Pict->Flags & NO_RAM_GENERATE ) {
- DispErrMsg("No counts to recolor",0);
- return;
- }
-
- wx = CountX + Pict->LeftMarg + Pict->RightMarg;
- wy = CountY + Pict->TopMarg + Pict->BotMarg;
-
- dx = screen->Width - wx;
- dy = screen->Height - wy;
-
- if ( dx < 0 || dy < 0 ) {
- DispErrMsg("Picture too big for screen.",0);
- return;
- }
-
- dx -= Window->LeftEdge;
- dy -= Window->TopEdge;
-
- if ( dx < 0 || dy < 0 ) {
- MoveWindow( Window, dx, dy );
- }
-
- dx = wx - Window->Width;
- dy = wy - Window->Height;
-
- if ( dx || dy ) {
-
- SizeWindow(Window, dx, dy );
-
- /* Spin till the window gets resized */
- /* Gross eh? */
-
- i = 0;
-
- while (i++ < 10000 && Window->Width != wx && Window->Height != wy);
-
- if (i == 10000) {
- DispErrMsg("can't resize the window");
- return;
- }
-
- BorderWindow(Window);
- }
-
- if (Pict->CurLine+Pict->TopMarg < Pict->Window->Height-Pict->BotMarg-1) {
-
- SetAPen( Pict->Window->RPort, NORMALPEN );
- RectFill( Pict->Window->RPort, Pict->LeftMarg,
- Pict->CurLine + Pict->TopMarg,
- Pict->Window->Width - Pict->RightMarg - 1,
- Pict->Window->Height - Pict->BotMarg - 1);
- }
-
- Pict->Flags &= ~LENS_DISPLAYED;
-
- MakeColorXlate( Pict );
-
- if ( Depth != 4 && Depth != 5) {
- ReColorSlow( Pict );
- return;
- }
-
- /* try to get enough memory to recolor the picture fast. */
-
- ColorPtr = ColorSave =
- (UBYTE *) safeAllocMem( CountX * CountY + 1, 0L);
-
- if (ColorPtr == (UBYTE *) NULL) {
- ReColorSlow( Pict );
- return;
- }
-
- WindowToFront(Window);
- ClearMenuStrip(Window);
-
- Delay(8);
-
- LockLayers( BackWind->WLayer->LayerInfo );
-
- /* We were able to allocate enough memory to translate the entire
- picture from heights to pens. The array of pens is used to
- quickly recolor the screen using Recolor4 or Recolor5 */
-
- /* If you don't like the assembly, you can use this C instead */
-
- #define SLOW1
- #ifdef SLOW1
- for (Sx = CountX*CountY; Sx-- >= 0; )
- *(ColorPtr++) = *(Pict->ClrXlate + *(CountPtr++));
-
- #else
- #asm
- CountPtr equ -4 ; these define where your variables
- ColorBase equ -8 ; are located on Manx's stack
- move.w d4,d1 ; this is ugly, but CountX is in d4
- muls.w d5,d1 ; and CountY is in d5
- sub.l #1,d1
- move.l CountPtr(a5),a0
- move.l _ColorXlate,a1
- move.l ColorBase(a5),a6
- ColorLoop
- move.w (a0)+,d0
- move.b (a1,d0.w),(a6)+
- sub.l #1,d1
- bge ColorLoop
- #endasm
- #endif
-
- if (Depth == 4) {
- ReColor4( ColorSave, Pict);
- } else
- if (Depth == 5) {
- ReColor5( ColorSave, Pict);
- }
- UnlockLayers( BackWind->WLayer->LayerInfo );
- AwakenChild(Pict);
-
- SetMenuStrip(Window, Menu);
-
- FreeMem(ColorSave,CountX*CountY+1);
- } /* ReColor */
-
- MakeColorXlate( Pict )
- register struct Picture *Pict;
- {
- register LONG i,j;
-
- /* So prepare the color translate table */
- for (i = 0,j = 1023; i < NumContours; i++)
- for (; j >= Pict->Heights[i] && j > 0; )
- *(Pict->ClrXlate + j--) = Pict->Pens[i];
- while (j >= 0) *(Pict->ClrXlate + j--) = 0;
- }
-
- /*
- * Assembly code to recolor 4 bit planes
- */
- ReColor4(ColorSave, Pict)
- UBYTE *ColorSave;
- register struct Picture *Pict;
- {
- /* This set of variables should not be rearranged or moved.
- There is Assembly language used in this routine, to increase
- performance. The assembly code depends on these variables
- being located on Manx's stack. Obviously it is not too portable
- or maintainable, but it is faster.
- */
- SHORT Mask,Width;
- LONG Mod,CMod;
- SHORT LF,LP,RF,RP;
- SHORT i,j,k,l;
- LONG Sx,TL;
- UBYTE *ColorPtr;
-
- struct BitMap *BitMap;
-
- /* This can be messed with */
-
- SHORT CountX, CountY;
-
- register struct Window *Window;
-
- #asm
- SaveReg reg a0-a6/d0-d7
- Plane0 equ 8
- Plane1 equ Plane0+4
- Plane2 equ Plane0+8
- Plane3 equ Plane0+12
- Plane4 equ Plane0+16
- Plane5 equ Plane0+20
-
- CountX equ -50
- CountY equ -48
- BitMap equ -44
- ColorPtr equ -40
- TL equ -36
- Sx equ -32
- l equ -28
- k equ -26
- j equ -24
- i equ -22
- RP equ -20
- RF equ -18
- LP equ -16
- LF equ -14
- CMod equ -12
- Mod equ -8
- Width equ -4
- Mask equ -2
- ColorSave equ 8
- #endasm
-
- Window = Pict->Window;
- BitMap = Window->RPort->BitMap;
- CountX = Pict->CountX;
- CountY = Pict->CurLine;
-
- ColorPtr = ColorSave;
- Sx = (screen->Width + 15) >> 4;
- LP = Window->LeftEdge + Pict->LeftMarg;
- LF = (LP + 15) & 0xfff0;
- CMod = Pict->CountX - (LF-LP);
- Mod = Sx - 1;
- TL = Sx * (Window->TopEdge + Pict->TopMarg) + (LP-1 >> 4);
- Width = LF-LP;
- Mask = 0xffff << Width;
-
- if ( Width > 0 ) {
-
- #asm
- movem.l SaveReg,-(sp) ;Save all the gprs to the stack
- move.l a5,a1 ;We need a5, so put MANX stack in a1
- move.w CountY(a5),i(a1)
- move.l BitMap(a1),a0
- move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
- asl.l #1,d0 ; and make it a 'word' offset
- move.l Plane0(a0),a2 ;Get address of screens first bit plane
- adda.l d0,a2 ; add in window top-left offset.
- move.l Plane1(a0),a3 ;Same for second bit plane.
- adda.l d0,a3
- move.l Plane2(a0),a4 ;Same for third bit plane.
- adda.l d0,a4
- move.l Plane3(a0),a5 ;Same for fourth bit plane.
- adda.l d0,a5
- move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
- move.l #1,d1 ;/* for each row */
- ; for (i = CountY; i; i--) {
- Y0Loop4 ; /* for each pixel in column */
- move.w Width(a1),d7 ; for (k = Width; k; k--) {
- eor.w d2,d2 ; Clear all bits in the bit plane data regs.
- eor.w d3,d3
- eor.w d4,d4
- eor.w d5,d5
- B0Loop4
- move.b (a0)+,d0 ; d0 = *(ColorPtr++);
- asr.b d1,d0 ; get low order bit from d0
- addx.w d2,d2 ; put it in bit plane 0 data
- asr.b d1,d0 ; same for bit plane 1
- addx.w d3,d3
- asr.b d1,d0 ; same for bit plane 2
- addx.w d4,d4
- asr.b d1,d0 ; same for bit plane 3
- addx.w d5,d5
- sub.w d1,d7 ; same for bit plane 5
- bgt B0Loop4 ; } /* did each bit in bit plane word */
- move.w Mask(a1),d0 ; Turn off all the new bits in planes
- and.w d0,(a2)
- and.w d0,(a3)
- and.w d0,(a4)
- and.w d0,(a5)
- or.w d2,(a2)+ ; Set the new bits in the bit planes
- or.w d3,(a3)+
- or.w d4,(a4)+
- or.w d5,(a5)+
- move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
- add.l d0,d0
- add.l d0,a2
- add.l d0,a3
- add.l d0,a4
- add.l d0,a5
- adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
- sub.w d1,i(a1) ;} /* did each row */
- tst.w i(a1)
- bgt Y0Loop4
- movem.l (sp)+,SaveReg ;better restore the registers
- #endasm
- ;
- }
-
- RP = LP + Pict->CountX & 0xfff0;
- RF = RP - 16;
- CMod = Pict->CountX - (RP-LF);
- Mod = Sx - ((RP-LF) >> 4);
- TL++;
- Width = (RP-LF) >> 4;
- ColorPtr = ColorSave + LF - LP;
-
- if (Width > 0 ) {
-
- #asm
- movem.l SaveReg,-(sp) ;Save all the gprs to the stack
- move.l a5,a1 ;We need a5, so put MANX stack in a1
- move.w CountY(a5),i(a1) ;i = CountY;
- move.l BitMap(a1),a0
- move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
- asl.l #1,d0 ; and make it a 'word' offset
- move.l Plane0(a0),a2 ;Get address of screens first bit plane
- adda.l d0,a2 ; add in window top-left offset.
- move.l Plane1(a0),a3 ;Same for second bit plane.
- adda.l d0,a3
- move.l Plane2(a0),a4 ;Same for third bit plane.
- adda.l d0,a4
- move.l Plane3(a0),a5 ;Same for fourth bit plane.
- adda.l d0,a5
- move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
- move.l #1,d1 ;/* for each row */
- ; for (i = CountY; i; i--) {
- YLoop4 ; /* for each column */
- move.w Width(a1),j(a1) ; for (j = Width; j; j--) {
- XLoop4 ; /* pack a word for each bit plane */
- move.w #16,d7 ; for (k = 16; k; k--) {
- BLoop4
- move.b (a0)+,d0 ; d0 = *(ColorPtr++);
- asr.b d1,d0 ; get low order bit from d0
- addx.w d2,d2 ; put it in bit plane 0 data
- asr.b d1,d0 ; same for bit plane 1
- addx.w d3,d3
- asr.b d1,d0 ; same for bit plane 2
- addx.w d4,d4
- asr.b d1,d0 ; same for bit plane 3
- addx.w d5,d5
- sub.w d1,d7 ; same for bit plane 5
- bgt BLoop4 ; } /* did each bit in bit plane word */
- move.w d2,(a2)+ ; Save the packed data in bit planes
- move.w d3,(a3)+
- move.w d4,(a4)+
- move.w d5,(a5)+
- sub.w d1,j(a1) ; } /* did each word in a row */
- tst.w j(a1)
- bgt XLoop4
- move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
- add.l d0,d0
- add.l d0,a2
- add.l d0,a3
- add.l d0,a4
- add.l d0,a5
- adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
- sub.w d1,i(a1) ;} /* did each row */
- tst.w i(a1)
- bgt YLoop4
- movem.l (sp)+,SaveReg ;better restore the registers
- #endasm
- ;
- }
-
- TL += Width;
- Width = LP + Pict->CountX - RP;
- CMod = Pict->CountX - Width;
- Mod = Sx - 1;
- Mask = 0xffff >> Width;
- ColorPtr = ColorSave + RP - LP;
-
- if ( Width > 0 ) {
-
- #asm
- movem.l SaveReg,-(sp) ;Save all the gprs to the stack
- move.l a5,a1 ;We need a5, so put MANX stack in a1
- move.w CountY(a5),i(a1)
- move.l BitMap(a1),a0
- move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
- asl.l #1,d0 ; and make it a 'word' offset
- move.l Plane0(a0),a2 ;Get address of screens first bit plane
- adda.l d0,a2 ; add in window top-left offset.
- move.l Plane1(a0),a3 ;Same for second bit plane.
- adda.l d0,a3
- move.l Plane2(a0),a4 ;Same for third bit plane.
- adda.l d0,a4
- move.l Plane3(a0),a5 ;Same for fourth bit plane.
- adda.l d0,a5
- move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
- move.l #1,d1 ;/* for each row */
- ; ;for (i = CountY; i; i--) {
- Y2Loop4 ; /* for each pixel in column */
- move.w Width(a1),d7 ; for (k = Width; k; k--) {
- eor.w d2,d2 ; Clear all bits in the bit plane data regs.
- eor.w d3,d3
- eor.w d4,d4
- eor.w d5,d5
- B2Loop4
- move.b (a0)+,d0 ; d0 = *(ColorPtr++);
- asr.b d1,d0 ; get low order bit from d0
- addx.w d2,d2 ; put it in bit plane 0 data
- asr.b d1,d0 ; same for bit plane 1
- addx.w d3,d3
- asr.b d1,d0 ; same for bit plane 2
- addx.w d4,d4
- asr.b d1,d0 ; same for bit plane 3
- addx.w d5,d5
- sub.w d1,d7 ; same for bit plane 5
- bgt B2Loop4 ; } /* did each bit in bit plane word */
- move.w Mask(a1),d0 ; Turn off all the new bits in planes
- and.w d0,(a2)
- and.w d0,(a3)
- and.w d0,(a4)
- and.w d0,(a5)
- move.w #16,d0
- sub.w Width(a1),d0
- asl.w d0,d2
- asl.w d0,d3
- asl.w d0,d4
- asl.w d0,d5
- or.w d2,(a2)+ ; Set the new bits in the bit planes
- or.w d3,(a3)+
- or.w d4,(a4)+
- or.w d5,(a5)+
- move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
- add.l d0,d0
- add.l d0,a2
- add.l d0,a3
- add.l d0,a4
- add.l d0,a5
- adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
- sub.w d1,i(a1) ;} /* did each row */
- tst.w i(a1)
- bgt Y2Loop4
- movem.l (sp)+,SaveReg ;better restore the registers
- #endasm
- ;
- }
- } /* ReColor 4 bit planes */
-
-
- /*
- * Assembly code to recolor 5 bit planes
- */
- ReColor5(ColorSave, Pict)
- UBYTE *ColorSave;
- register struct Picture *Pict;
- {
- /* This set of variables should not be rearranged or moved.
- There is Assembly language used in this routine, to increase
- performance. The assembly code depends on these variables
- being located on Manx's stack. Obviously it is not too portable
- or maintainable, but it is faster.
- */
- SHORT Mask,Width;
- LONG Mod,CMod;
- SHORT LF,LP,RF,RP;
- SHORT i,j,k,l;
- LONG Sx,TL;
- UBYTE *ColorPtr;
-
- struct BitMap *BitMap;
-
- /* These can be messed with */
-
- SHORT CountX, CountY;
-
- register struct Window *Window;
-
- Window = Pict->Window;
- BitMap = Window->RPort->BitMap;
-
- CountX = Pict->CountX;
- CountY = Pict->CurLine;
-
- ColorPtr = ColorSave;
- Sx = (screen->Width + 15) >> 4;
- LP = Window->LeftEdge + Pict->LeftMarg;
- LF = (LP + 15) & 0xfff0;
- CMod = CountX - (LF-LP);
- Mod = Sx - 1;
- TL = Sx * (Window->TopEdge + Pict->TopMarg) + (LP-1 >> 4);
- Width = LF-LP;
- Mask = 0xffff << Width;
-
- if ( Width > 0 ) {
-
- #asm
- movem.l SaveReg,-(sp) ;Save all the gprs to the stack
- move.l a5,a1 ;We need a5, so put MANX stack in a1
- move.w CountY(a5),i(a1)
- move.l BitMap(a1),a0
- move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
- asl.l #1,d0 ; and make it a 'word' offset
- move.l Plane0(a0),a2 ;Get address of screens first bit plane
- adda.l d0,a2 ; add in window top-left offset.
- move.l Plane1(a0),a3 ;Same for second bit plane.
- adda.l d0,a3
- move.l Plane2(a0),a4 ;Same for third bit plane.
- adda.l d0,a4
- move.l Plane3(a0),a5 ;Same for fourth bit plane.
- adda.l d0,a5
- move.l Plane4(a0),a6 ;Same for fifth bit plane.
- adda.l d0,a6
- move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
- move.l #1,d1 ;/* for each row */
- ; ;for (i = CountY; i; i--) {
- Y0Loop5 ; /* for each pixel in column */
- move.w Width(a1),d7 ; for (k = Width; k; k--) {
- eor.w d2,d2 ; Clear all bits in the bit plane data regs.
- eor.w d3,d3
- eor.w d4,d4
- eor.w d5,d5
- eor.w d6,d6
- B0Loop5
- move.b (a0)+,d0 ; d0 = *(ColorPtr++);
- asr.b d1,d0 ; get low order bit from d0
- addx.w d2,d2 ; put it in bit plane 0 data
- asr.b d1,d0 ; same for bit plane 1
- addx.w d3,d3
- asr.b d1,d0 ; same for bit plane 2
- addx.w d4,d4
- asr.b d1,d0 ; same for bit plane 3
- addx.w d5,d5
- asr.b d1,d0 ; same for bit plane 4
- addx.w d6,d6
- sub.w d1,d7 ; same for bit plane 5
- bgt B0Loop5 ; } /* did each bit in bit plane word */
- move.w Mask(a1),d0 ; Turn off all the new bits in planes
- and.w d0,(a2)
- and.w d0,(a3)
- and.w d0,(a4)
- and.w d0,(a5)
- and.w d0,(a6)
- or.w d2,(a2)+ ; Set the new bits in the bit planes
- or.w d3,(a3)+
- or.w d4,(a4)+
- or.w d5,(a5)+
- or.w d6,(a6)+
- move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
- add.l d0,d0
- add.l d0,a2
- add.l d0,a3
- add.l d0,a4
- add.l d0,a5
- add.l d0,a6
- adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
- sub.w d1,i(a1) ;} /* did each row */
- tst.w i(a1)
- bgt Y0Loop5
- movem.l (sp)+,SaveReg ;better restore the registers
- #endasm
- ;
- }
-
- RP = LP + CountX & 0xfff0;
- RF = RP - 16;
- CMod = CountX - (RP-LF);
- Mod = Sx - ((RP-LF) >> 4);
- TL++;
- Width = (RP-LF) >> 4;
- ColorPtr = ColorSave + LF - LP;
-
- if ( Width > 0 ) {
-
- #asm
- movem.l SaveReg,-(sp) ;Save all the gprs to the stack
- move.l a5,a1 ;We need a5, so put MANX stack in a1
- move.w CountY(a5),i(a1) ;i = CountY;
- move.l BitMap(a1),a0
- move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
- asl.l #1,d0 ; and make it a 'word' offset
- move.l Plane0(a0),a2 ;Get address of screens first bit plane
- adda.l d0,a2 ; add in window top-left offset.
- move.l Plane1(a0),a3 ;Same for second bit plane.
- adda.l d0,a3
- move.l Plane2(a0),a4 ;Same for third bit plane.
- adda.l d0,a4
- move.l Plane3(a0),a5 ;Same for fourth bit plane.
- adda.l d0,a5
- move.l Plane4(a0),a6 ;Same for fifth bit plane.
- adda.l d0,a6
- move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
- move.l #1,d1 ;/* for each row */
- ; ;for (i = CountY; i; i--) {
- YLoop5 ; /* for each column */
- move.w Width(a1),j(a1) ; for (j = Width; j; j--) {
- XLoop5 ; /* pack a word for each bit plane */
- move.w #16,d7 ; for (k = 16; k; k--) {
- BLoop5
- move.b (a0)+,d0 ; d0 = *(ColorPtr++);
- asr.b d1,d0 ; get low order bit from d0
- addx.w d2,d2 ; put it in bit plane 0 data
- asr.b d1,d0 ; same for bit plane 1
- addx.w d3,d3
- asr.b d1,d0 ; same for bit plane 2
- addx.w d4,d4
- asr.b d1,d0 ; same for bit plane 3
- addx.w d5,d5
- asr.b d1,d0 ; same for bit plane 4
- addx.w d6,d6
- sub.w d1,d7 ; same for bit plane 5
- bgt BLoop5 ; } /* did each bit in bit plane word */
- move.w d2,(a2)+ ; Save the packed data in bit planes
- move.w d3,(a3)+
- move.w d4,(a4)+
- move.w d5,(a5)+
- move.w d6,(a6)+
- sub.w d1,j(a1) ; } /* did each word in a row */
- tst.w j(a1)
- bgt XLoop5
- move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
- add.l d0,d0
- add.l d0,a2
- add.l d0,a3
- add.l d0,a4
- add.l d0,a5
- add.l d0,a6
- adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
- sub.w d1,i(a1) ;} /* did each row */
- tst.w i(a1)
- bgt YLoop5
- movem.l (sp)+,SaveReg ;better restore the registers
- #endasm
- ;
- }
-
- TL += Width;
- Width = LP + CountX - RP;
- CMod = CountX - Width;
- Mod = Sx - 1;
- Mask = 0xffff >> Width;
- ColorPtr = ColorSave + RP - LP;
-
- if ( Width > 0 ) {
- #asm
- movem.l SaveReg,-(sp) ;Save all the gprs to the stack
- move.l a5,a1 ;We need a5, so put MANX stack in a1
- move.w CountY(a5),i(a1)
- move.l BitMap(a1),a0
- move.l TL(a1),d0 ;Load Offset to Top,Left corner of screen
- asl.l #1,d0 ; and make it a 'word' offset
- move.l Plane0(a0),a2 ;Get address of screens first bit plane
- adda.l d0,a2 ; add in window top-left offset.
- move.l Plane1(a0),a3 ;Same for second bit plane.
- adda.l d0,a3
- move.l Plane2(a0),a4 ;Same for third bit plane.
- adda.l d0,a4
- move.l Plane3(a0),a5 ;Same for fourth bit plane.
- adda.l d0,a5
- move.l Plane4(a0),a6 ;Same for fifth bit plane.
- adda.l d0,a6
- move.l ColorPtr(a1),a0 ;Load up pointer to recolored data.
- move.l #1,d1 ;/* for each row */
- ; ;for (i = CountY; i; i--) {
- Y2Loop5 ; ; /* for each pixel in column */
- move.w Width(a1),d7 ; for (k = Width; k; k--) {
- eor.w d2,d2 ; Clear all bits in the bit plane data regs.
- eor.w d3,d3
- eor.w d4,d4
- eor.w d5,d5
- eor.w d6,d6
- B2Loop5
- move.b (a0)+,d0 ; d0 = *(ColorPtr++);
- asr.b d1,d0 ; get low order bit from d0
- addx.w d2,d2 ; put it in bit plane 0 data
- asr.b d1,d0 ; same for bit plane 1
- addx.w d3,d3
- asr.b d1,d0 ; same for bit plane 2
- addx.w d4,d4
- asr.b d1,d0 ; same for bit plane 3
- addx.w d5,d5
- asr.b d1,d0 ; same for bit plane 4
- addx.w d6,d6
- sub.w d1,d7 ; same for bit plane 5
- bgt B2Loop5 ; } /* did each bit in bit plane word */
- move.w Mask(a1),d0 ; Turn off all the new bits in planes
- and.w d0,(a2)
- and.w d0,(a3)
- and.w d0,(a4)
- and.w d0,(a5)
- and.w d0,(a6)
- move.w #16,d0
- sub.w Width(a1),d0
- asl.w d0,d2
- asl.w d0,d3
- asl.w d0,d4
- asl.w d0,d5
- asl.w d0,d6
- or.w d2,(a2)+ ; Set the new bits in the bit planes
- or.w d3,(a3)+
- or.w d4,(a4)+
- or.w d5,(a5)+
- or.w d6,(a6)+
- move.l Mod(a1),d0 ; Adjust plane pointers to start of next line
- add.l d0,d0
- add.l d0,a2
- add.l d0,a3
- add.l d0,a4
- add.l d0,a5
- add.l d0,a6
- adda.l CMod(a1),a0 ; Adjust color pointer to start of next line
- sub.w d1,i(a1) ;} /* did each row */
- tst.w i(a1)
- bgt Y2Loop5
- movem.l (sp)+,SaveReg ;better restore the registers
- #endasm
- ;
- }
-
- } /* ReColor 5 bit planes */
-
- static struct Picture *ReColorPict;
-
- ReColorSlow( Pict )
- register struct Picture *Pict;
- {
- int ReColorTask();
-
- WindowToFront(Pict->Window);
-
- Pict->ColorState = GENERATESTATE;
-
- ReColorPict = Pict;
-
- Pict->cTask = CreateTask( "ReColor", 0, ReColorTask, 1024);
-
- if ( Pict->cTask == NULL ) {
- DispErrMsg("Could not create recolor task",0);
- }
-
- /* Do this so we are sure child is done with ReColorPict */
-
- Wait( pSigMask );
- }
-
- ReColorTask( )
- {
- register struct Picture *Pict;
- register struct RastPort *Rp;
- register UBYTE OldColor, NewColor;
-
- register LONG x, y;
- LONG xl, yl;
-
- SHORT *CountPtr;
-
- struct Window *Window;
-
- geta4();
-
- Pict = ReColorPict;
-
- /* Signal Parent that we have accessed ReColorPict */
-
- Signal( mTask, pSigMask );
-
- Window = Pict->Window;
- Pict->ColorChildState = RECOLORINCOMPLETE;
-
- Rp = Window->RPort;
- CountPtr = Pict->Counts;
-
- OldColor = 0xff;
-
- xl = Pict->CountX + Pict->LeftMarg;
- yl = Pict->CurLine + Pict->TopMarg;
-
- for (y = Pict->TopMarg; y < yl; y++) {
-
- ObtainSemaphore( &Pict->WindowSemi );
-
- OldColor = *(Pict->ClrXlate + *CountPtr);
- Move( Rp, Pict->LeftMarg, y);
-
- for (x = Pict->LeftMarg; x < xl; x++) {
-
- NewColor = *(Pict->ClrXlate + *CountPtr++);
-
- if ( NewColor != OldColor) {
-
- SetAPen( Rp, OldColor );
-
- if ( x < Window->Width - Window->BorderRight) {
- Draw( Rp, x, y);
- }
-
- OldColor = NewColor;
- }
- }
- SetAPen( Rp, NewColor );
- Draw( Rp, x-1, y);
-
- ReleaseSemaphore( &Pict->WindowSemi );
-
- ReColorPause( Pict );
- }
- Pict->ColorChildState = RECOLORCOMPLETE;
-
- /* Indicate that generation has finished for this task */
-
- Signal( mTask, mSigMask ); /* signal parent as to change */
-
- while (Pict->ColorState != PAUSESTATE) ;
-
- ReColorPause(Pict); /* signal back so parent doesn't hang */
- } /* ReColorTask */
-
- KillReColor( Pict )
- register struct Picture *Pict;
- {
- register struct Task *cTask;
-
- if ( cTask = Pict->cTask ) {
-
- PauseReColor( Pict );
- DeleteTask( cTask );
- Pict->cTask = NULL;
- }
- }
-
-