home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
AmigActive 6
/
AACD06.ISO
/
AACD
/
Programming
/
ImageManager
/
Examples
/
AlphaBlend.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-01-27
|
7KB
|
257 lines
#include <math.h>
#include <stdio.h>
#include <proto/exec.h>
#include <proto/cybergraphics.h>
#include <proto/graphics.h>
#include <proto/imagemanager.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include <exec/memory.h>
#include <libraries/cybergraphics.h>
#ifndef REG
#define REG(x) register __ ## x
#endif
struct Library *ImageManagerBase, *CyberGfxBase;
VOID _INIT_7_CGX () { CyberGfxBase = OpenLibrary("cybergraphics.library", 0); }
VOID _EXIT_7_CGX () { CloseLibrary(CyberGfxBase); }
struct ColourEntry
{
UBYTE R, G, B, A;
VOID Init (ULONG *table)
{
R = *table++ >> 24; G = *table++ >> 24; B = *table >> 24;
}
VOID Mix (UWORD blend, struct ColourEntry &other)
{
UWORD i_blend = (1<<16)-1 - blend;
R = (R * i_blend + other.R * blend) >> 16;
G = (G * i_blend + other.G * blend) >> 16;
B = (B * i_blend + other.B * blend) >> 16;
}
};
struct InstanceData
{
ULONG Height;
struct Window **Win;
struct ColourEntry *RGBBuffer, Palette[256], *Dst;
UBYTE *Sinus;
struct RastPort TmpRP;
BOOL LowColour;
};
#define IMA_MyClass_WindowPnt (TAG_USER+0x100000)
ULONG Dispatcher (REG(a0) struct IClass *cl, REG(a2) Object *obj, REG(a1) Msg msg)
{
ULONG result = FALSE;
struct InstanceData *data = (InstanceData *)INST_DATA(cl, obj);
switch(msg->MethodID)
{
case OM_NEW:
{
if(obj = (Object *)(result = DoSuperMethodA(cl, obj, msg)))
{
data = (InstanceData *)INST_DATA(cl, obj);
data->Win = (Window **)GetTagData(IMA_MyClass_WindowPnt, NULL, ((opSet *)msg)->ops_AttrList);
}
}
break;
case IMM_NewFrame:
{
struct IMP_NewFrame *nmsg = (IMP_NewFrame *)msg;
ULONG width = nmsg->Width;
data->Height = nmsg->Height;
result = DoSuperMethodA(cl, obj, msg);
if(data->Sinus = new UBYTE [width])
{
for(ULONG x = 0; x < width; x++)
data->Sinus[x] = 255 * sin(((DOUBLE)x) * PI / ((DOUBLE)width));
data->RGBBuffer = new ColourEntry [width];
if(!CyberGfxBase || GetBitMapAttr((*data->Win)->RPort->BitMap, BMA_DEPTH) <= 8)
{
data->LowColour = TRUE;
data->TmpRP = *(*data->Win)->RPort;
data->TmpRP.Layer = NULL;
data->TmpRP.BitMap = AllocBitMap((width+15) & ~15, 1, 8, 0L, NULL);
struct ColorMap *cmap = (*data->Win)->WScreen->ViewPort.ColorMap;
for(ULONG col = 0; col < 256; col++)
{
ULONG table[3];
GetRGB32(cmap, col, 1, table);
data->Palette[col].Init(table);
}
}
// if(data->RGBBuffer && (!data->LowColour || data->TmpRP.BitMap))
}
}
break;
case IMM_Abort:
case IMM_EndFrame:
{
delete data->Sinus;
delete data->RGBBuffer;
FreeBitMap(data->TmpRP.BitMap);
result = DoSuperMethodA(cl, obj, msg);
}
break;
case IMM_ReceiveData:
{
struct IMP_ReceiveData *rmsg = (IMP_ReceiveData *)msg;
if(rmsg->Pixels.Flags & IMF_ReceiveData_Draft)
{
result = TRUE;
}
else
{
ULONG width = rmsg->Pixels.Width, y = rmsg->Pixels.Y;
rmsg->Pixels.Height = 1;
struct Window *win = *data->Win;
if(data->LowColour)
{
UBYTE *store = ((UBYTE *)data->RGBBuffer)+3*width;
ReadPixelLine8(win->RPort, win->BorderLeft, win->BorderTop+y, width, store, &data->TmpRP);
ULONG *rgb = (ULONG *)data->RGBBuffer, *palette = (ULONG *)data->Palette;
for(ULONG x = 0; x < width; x++)
*rgb++ = palette[store[x]];
}
else
{
ReadPixelArray(data->RGBBuffer, 0, 0, 0, win->RPort, win->BorderLeft, win->BorderTop+y, width, 1, RECTFMT_RGBA);
}
struct ColourEntry *buf = (ColourEntry *)rmsg->Pixels.RGBA;
UWORD y_blend = 255 * sin(((DOUBLE)y) * PI / ((DOUBLE)data->Height));
for(ULONG x = 0; x < width; x++)
data->RGBBuffer[x].Mix(y_blend * data->Sinus[x], buf[x]);
rmsg->Pixels.RGBA = (ULONG *)data->RGBBuffer;
result = DoSuperMethodA(cl, obj, msg);
}
}
break;
default:
result = DoSuperMethodA(cl, obj, msg);
break;
}
return result;
}
ULONG MyHookCode (REG(a0) struct Hook *hook, REG(a1) struct IMP_NewFrame *msg, REG(a2) Object *obj)
{
ULONG result = FALSE;
switch(msg->MethodID)
{
case IMM_NewFrame:
{
struct Window *win;
struct Screen *scr = (Screen *)hook->h_Data;
if(hook->h_Data = win = OpenWindowTags(NULL, WA_Title, hook->h_SubEntry, WA_PubScreen, scr, WA_Activate, TRUE, WA_IDCMP, IDCMP_CLOSEWINDOW, WA_CloseGadget, TRUE, WA_DragBar, TRUE, WA_DepthGadget, TRUE, WA_InnerWidth, msg->Width, WA_InnerHeight, msg->Height, WA_BackFill, LAYERS_NOBACKFILL, TAG_DONE))
{
Object *raster;
if(GetAttr(IMA_Next, obj, (ULONG *)&raster), raster)
SetAttrs(raster, IMA_Raster_RastPort, win->RPort, IMA_Raster_Left, win->BorderLeft, IMA_Raster_Top, win->BorderTop, TAG_DONE);
result = TRUE;
}
UnlockPubScreen(NULL, scr);
}
break;
case IMM_ReceiveData:
{
struct Window *win = (Window *)hook->h_Data;
result = !(SetSignal(0L, 0L) & (1 << win->UserPort->mp_SigBit));
}
break;
}
return result;
}
int main (int argc, char **argv)
{
if(ImageManagerBase = OpenLibrary("ImageManager.library", 1))
{
STRPTR filename = argc == 2 ? argv[1] : "Download:/«99.03.02»/001_ScrollBarGrab.PNG";
struct IClass *myclass, *superclass = IM_GetClass("Link");
if(superclass && (myclass = MakeClass(NULL, NULL, superclass, sizeof(InstanceData), 0L)))
{
myclass->cl_Dispatcher.h_Entry = (HOOKFUNC)Dispatcher;
struct Screen *scr = LockPubScreen(NULL);
struct Hook MyHook = { { NULL, NULL }, (HOOKFUNC)MyHookCode, (HOOKFUNC)FilePart(filename), scr };
Object **objects = IM_CreateChain(0L,
IMC_NewObject, "File",
TAG_DONE,
IMC_NewObject, "Decoder",
TAG_DONE,
IMC_NewObject, "ScaleX",
IMA_ScaleX_Width, 800,
TAG_DONE,
IMC_NewObject, "ScaleY",
IMA_ScaleY_Height, 600,
TAG_DONE,
IMC_CustomObject, myclass,
IMA_MyClass_WindowPnt, &MyHook.h_Data,
TAG_DONE,
IMC_NewObject, "Container",
IMA_Container_Screen, scr,
TAG_DONE,
IMC_NewObject, "Probe",
IMA_Probe_NewFrameHook, &MyHook,
IMA_Probe_ReceiveDataHook, &MyHook,
TAG_DONE,
IMC_NewObject, "Raster",
TAG_DONE,
IMC_EndChain);
if(objects)
{
DoMethod(objects[0], IMM_File_Load, filename);
struct Window *win = (Window *)MyHook.h_Data;
if(win && ((APTR)win != (APTR)scr))
{
WaitPort(win->UserPort);
CloseWindow(win);
}
else
{
UnlockPubScreen(NULL, scr);
}
IM_DeleteChain(objects);
}
FreeClass(myclass);
}
IM_FreeClass(superclass);
CloseLibrary(ImageManagerBase);
}
return 0;
}
void wbmain (struct WBStartup *) { ; }