Just popping in
Joined: 2018/3/1 21:08 Last Login
: 11/21 15:56
From italy
Group:
Registered Users
|
For now I have resolved with this Fade (to black) C function, it's perfect on 8bit screens, and good for 24bit screens in low/med resolutions. In hires it's a bit slow. Maybe in future I can look for compositing use to get a butter effect even on 24bit/hires screens. Anyway some hardware acceleration can be inside ReadPixelArray and WritePixelArray OS4 API Calls, but fading effect is all cpu brute force, writing in system memory.
Here is complete C function, it works ok when I use "Win->Width * 4" inside Read/WritePixelArray api calls, but fails if I use Win->RPort->Bitmap->BytesPerRow value.
extern uint8 *ARGBMEM;
int16 Fade (struct Window *Win, uint32 *PaletteSrc, uint32 MaxStep, uint32 MyTimeDelay, int16 ToBlack) { // DisplayInfoHandle DHandle; // struct DimensionInfo DimInfo; static uint32 __attribute__ ((aligned (16))) PaletteTmp [3L * 252L + 2L]; // uint8 *ARGB = NULL; uint8 R, G, B; int16 Success = FALSE; uint32 Var, Step, Rows, Cols, Modulo; uint32 DstWinWidth, DstWinHeight, Depth, Color, Range, ModeID; /* ModeID = GetVPModeID (ViewPortAddress (Win)); DHandle = FindDisplayInfo (ModeID);
if (!((DHandle) && GetDisplayInfoData (DHandle, (uint8 *) &DimInfo, sizeof (struct DimensionInfo), DTAG_DIMS, ModeID))) goto ExitFade; */ DstWinWidth = ((Win->Flags & WFLG_GIMMEZEROZERO) ? Win->GZZWidth : Win->Width); DstWinHeight = ((Win->Flags & WFLG_GIMMEZEROZERO) ? Win->GZZHeight : Win->Height); Depth = GetBitMapAttr (Win->RPort->BitMap, BMA_DEPTH); if (Depth == MIN_DEPTH) // 8 bit screens { if (ToBlack) { Range = (1L << Depth) - 4L; PaletteTmp [0L] = (Range << 16L) + 4L; GetRGB32 (((struct ViewPort *) ViewPortAddress (Win))->ColorMap, 4L, Range, &PaletteTmp [1L]); PaletteTmp [3L * Range + 1L] = NULL; PaletteSrc += (3 * RESERVED_PENS); /* exclude reserved pens for GUI */ for (Step = 0L; Step <= MaxStep; Step++) { for (Var = 1; Var <= 3L * Range; Var+=3) /* unroll loop 3 times */ { if (PaletteTmp [Var + 0]) { Color = (uint32) (((PaletteSrc [Var + 0] >> 24L) * (MaxStep - Step)) / MaxStep); PaletteTmp [Var + 0] = (Color << 24L); }
if (PaletteTmp [Var + 1]) { Color = (uint32) (((PaletteSrc [Var + 1] >> 24L) * (MaxStep - Step)) / MaxStep); PaletteTmp [Var + 1] = (Color << 24L); }
if (PaletteTmp [Var + 2]) { Color = (uint32) (((PaletteSrc [Var + 2] >> 24L) * (MaxStep - Step)) / MaxStep); PaletteTmp [Var + 2] = (Color << 24L); } }
WaitTOF (); LoadRGB32 (ViewPortAddress (Win), &PaletteTmp); Delay (MyTimeDelay); } }
else { for (Var = 0; Var < ((DstWinWidth * DstWinHeight) / 4); Var++) WritePixelColor (Win->RPort, rand() % (DstWinWidth - 1), rand() % (DstWinHeight - 1), 0xff000000); }
Success = TRUE; goto ExitFade; } else if (Depth == MAX_DEPTH) // 24bit screens { if (ToBlack) { Modulo = DstWinWidth; ReadPixelArray (Win->RPort, 0, 0, ARGBMEM, Win->LeftEdge, Win->TopEdge, Modulo * 4, PIXF_A8R8G8B8, DstWinWidth, DstWinHeight);
for (Step = 0L; Step <= MaxStep; Step++) { for (Cols = Win->TopEdge; Cols < (DstWinHeight * 4); Cols += 4) { for (Rows = Win->LeftEdge; Rows < (DstWinWidth * 4); Rows += 8) // unroll loop twice { if ((R = *(ARGBMEM + (Cols * Modulo + (Rows + 1))))) *(ARGBMEM + (Cols * Modulo + (Rows + 1))) = (uint8) ((R * (MaxStep - Step)) / MaxStep); if ((G = *(ARGBMEM + (Cols * Modulo + (Rows + 2))))) *(ARGBMEM + (Cols * Modulo + (Rows + 2))) = (uint8) ((G * (MaxStep - Step)) / MaxStep);
if ((B = *(ARGBMEM + (Cols * Modulo + (Rows + 3))))) *(ARGBMEM + (Cols * Modulo + (Rows + 3))) = (uint8) ((B * (MaxStep - Step)) / MaxStep);
if ((R = *(ARGBMEM + (Cols * Modulo + (Rows + 5))))) *(ARGBMEM + (Cols * Modulo + (Rows + 5))) = (uint8) ((R * (MaxStep - Step)) / MaxStep); if ((G = *(ARGBMEM + (Cols * Modulo + (Rows + 6))))) *(ARGBMEM + (Cols * Modulo + (Rows + 6))) = (uint8) ((G * (MaxStep - Step)) / MaxStep);
if ((B = *(ARGBMEM + (Cols * Modulo + (Rows + 7))))) *(ARGBMEM + (Cols * Modulo + (Rows + 7))) = (uint8) ((B * (MaxStep - Step)) / MaxStep); } } WaitTOF (); WritePixelArray (ARGBMEM, 0, 0, Modulo * 4, PIXF_A8R8G8B8, Win->RPort, Win->LeftEdge, Win->TopEdge, DstWinWidth, DstWinHeight); Delay (MyTimeDelay); } } else { for (Cols = Win->TopEdge; Cols < DstWinHeight; Cols += 2) { for (Rows = Win->LeftEdge; Rows < DstWinWidth; Rows += 4) // unroll loop twice { WritePixelColor (Win->RPort, Rows, Cols, 0xff000000); WritePixelColor (Win->RPort, Rows + 2, Cols, 0xff000000); } Delay (MyTimeDelay / 2); } } Success = TRUE; }
ExitFade: return (Success); }
|