home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d3xx
/
d326
/
snap.lha
/
Snap
/
source
/
snapgfx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-03-05
|
8KB
|
260 lines
/* Auto: make
*/
IMPORT struct SnapRsrc *SnapRsrc;
IMPORT struct Image DiskImage;
IMPORT struct Gadget DiskGad;
IMPORT struct Gadget VProp, HProp;
IMPORT struct PropInfo VInfo, HInfo;
IMPORT struct Image VImage, HImage;
IMPORT struct NewWindow Nw;
IMPORT UBYTE *WindowTitle;
#define MINWIDTH (24 + SnapRsrc->GadOffset + 16)
#define MINHEIGHT 15
LONG xl; /* leftmost x position */
LONG xr; /* rightmost x position */
LONG yt; /* topmost y position */
LONG yb; /* bottommost y position */
LONG mx, my; /* Mouse position in pixels */
#define GfxFrame 4L
IMPORT Point OldFrame[];
IMPORT Point NewFrame[];
IMPORT LONG OFType; /* Old frame type: ShortFrame/LongFrame */
IMPORT UWORD Ptrn;
IMPORT WORD Pattern[];
IMPORT struct RastPort MyRP;
IMPORT struct BitMap MyBM;
IMPORT struct Screen *theScreen;
struct Layer_Info *LockedLayerInfo;
IMPORT struct RastPort rp;
IMPORT LONGBITS cancelsignal, donesignal, movesignal, clicksignal, timersignal;
IMPORT WORD action;
LONG TitleBarHeight;
LONG ContentsFontHeight;
VOID FixHeights()
{
struct Screen WBScreen;
if (GetScreenData((char *)&WBScreen, (LONG)sizeof(struct Screen), WBENCHSCREEN, NULL)) {
/* Now this is a good practice */
TitleBarHeight = WBScreen.RastPort.TxHeight+2;
ContentsFontHeight = WBScreen.Font->ta_YSize;
} else {
/* Sorry, but I don't realise how this could fail.
Well, if we're snapping on another screen and
WB is closed and it can't be opened by GetScreenData()...
Anyway, IF this should happen -- Use Topaz 8 */
TitleBarHeight = 10;
ContentsFontHeight = 8;
}
}
/* SnapGfx is the actual graphics snapper.
** It steals the bitmap data from the given rastport
** and puts it in a separate bitmap.
** It also prepares the NewWindow structure according
** to the snapped bitmap.
** The coordinates are assumed to be valid.
*/
struct GfxSnap *SnapGfx(rp)
struct RastPort *rp;
{
struct GfxSnap *GS;
LONG i;
GS = Create(GfxSnap);
if (!GS) {
return NULL;
}
GS->x = xl;
GS->y = yt;
GS->width = xr - xl + 1;
GS->height = yb - yt + 1;
GS->depth = rp->BitMap->Depth;
GS->viewmode = theScreen->ViewPort.Modes;
GS->pagew = theScreen->Width;
GS->pageh = theScreen->Height;
i = (GS->viewmode & HAM ? 16 : 1L << GS->depth);
/* Copy the color map in case we should need it later */
while (i--) {
ULONG col = GetRGB4(theScreen->ViewPort.ColorMap, i);
GS->rgb[i][0] = ((col >> 8) & 0x0f) << 4;
GS->rgb[i][1] = ((col >> 4) & 0x0f) << 4;
GS->rgb[i][2] = ((col >> 0) & 0x0f) << 4;
}
/* Set up a nice bitmap */
InitBitMap(&GS->BM, GS->depth, GS->width, GS->height);
/* Get a handle on the bitmap */
InitRastPort(&MyRP);
MyRP.BitMap = &GS->BM;
if (!AllocPlanes(&GS->BM, GS->width, GS->height)) {
FreePlanes(&GS->BM, GS->width, GS->height);
Kill(GS);
return NULL;
}
/* Copy the selected part of the screen */
ClipBlit(rp, xl, yt, &MyRP, 0L, 0L, GS->width, GS->height, 0xC0L);
Nw.LeftEdge = xl;
Nw.TopEdge = yt;
Nw.Width = GS->width + 18; /* Two pixels on each side */
Nw.Height = GS->height + TitleBarHeight + 9; /* Bar & scroll bar */
Nw.Title = WindowTitle;
Nw.MaxWidth = Nw.Width;
Nw.MaxHeight = Nw.Height;
CopyMem((char *)&DiskGad, (char *)&GS->DiskGad,
(LONG)sizeof(DiskGad) + sizeof(VProp) + sizeof(HProp) +
sizeof(VInfo) + sizeof(HInfo) + sizeof(VImage) + sizeof(HImage));
GS->DiskGad.NextGadget = &GS->VProp;
GS->DiskGad.LeftEdge = -(SnapRsrc->GadOffset+16);
GS->DiskGad.Height = TitleBarHeight - 2;
DiskImage.Height = TitleBarHeight;
GS->VProp.NextGadget = &GS->HProp;
GS->VProp.TopEdge = TitleBarHeight;
GS->VProp.Height = -8 - TitleBarHeight;
GS->VProp.GadgetRender = (APTR)&GS->VImage;
GS->VProp.SpecialInfo = (APTR)&GS->VInfo;
GS->HProp.NextGadget = NULL;
GS->HProp.GadgetRender = (APTR)&GS->HImage;
GS->HProp.SpecialInfo = (APTR)&GS->HInfo;
return GS;
}
VOID ExtendGfx()
{
/* Fix which row we're talking about */
if (my-yt < yb-my) { /* Find closest row */
yt = my; /* change top row */
} else {
yb = my; /* change bottom row */
}
if (mx-xl < xr-mx) {
xl = mx;
} else {
xr = mx;
}
}
VOID gfx_frame()
{
NewFrame[0].x = xl; NewFrame[0].y = yt;
NewFrame[1].x = xr; NewFrame[1].y = yt;
NewFrame[2].x = xr; NewFrame[2].y = yb;
NewFrame[3].x = xl; NewFrame[3].y = yb;
NewFrame[4].x = xl; NewFrame[4].y = yt;
draw_frame(GfxFrame);
}
WORD HandleGfx()
{
theScreen = WhichScreen(); /* Find out where we are */
if (!theScreen) { /* Don't know? Forget it. */
action = noaction;
return 0;
}
/* Lock everything - find out what happens */
LockedLayerInfo = &theScreen->LayerInfo;
LockLayers(LockedLayerInfo);
/* Get a copy. Don't mess with somebody else's RP. */
CopyMem((char *)&theScreen->RastPort, (char *)&rp, (long)sizeof(struct RastPort));
SetDrMd(&rp, COMPLEMENT);
xl = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
if (xl < 0) {
xl = 0;
}
if (xl >= theScreen->Width) { /* Check those corners. Check those corners. */
xl = theScreen->Width - 1;
}
yt = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
if (yt < 0) {
yt = 0;
}
if (yt >= theScreen->Height) {
yt = theScreen->Height - 1;
}
xr = xl;
yb = yt;
Ptrn = (SnapRsrc->CrawlPtrn ? SnapRsrc->CrawlPtrn : Pattern[UNIT_FRAME]);
OFType = 0L;
gfx_frame();
FOREVER {
REGISTER LONGBITS sig =
Wait(movesignal|clicksignal|cancelsignal|donesignal|timersignal);
if ((sig & timersignal) && (SnapRsrc->CrawlPtrn != 0xffff)) {
crawl_frame(1L);
}
if (sig & movesignal || sig & clicksignal) {
mx = theScreen->MouseX + theScreen->ViewPort.RasInfo->RxOffset;
if (mx < 0) {
mx = 0;
}
if (mx>=theScreen->Width) {
mx = theScreen->Width - 1;
}
my = theScreen->MouseY + theScreen->ViewPort.RasInfo->RyOffset;
if (my < 0) {
my = 0;
}
if (my>=theScreen->Height) {
my = theScreen->Height - 1;
}
ExtendGfx();
gfx_frame();
}
if (sig & cancelsignal) { /* Cancelled? */
erase_frame();
UnlockLayers(LockedLayerInfo);
return 0;
}
if (sig & donesignal) { /* Finished. Copy gfx. */
struct GfxSnap *GS;
erase_frame();
if (xr < xl + MINWIDTH) { /* Can't have too small windows */
xr = xl + MINWIDTH;
}
if (xr >= theScreen->Width) {
xl -= xr - theScreen->Width - 1;
xr = theScreen->Width - 1;
}
if (yb < yt + MINHEIGHT) {
yb = yt + MINHEIGHT;
}
if (yb >= theScreen->Height) {
yt -= yb - theScreen->Height - 1;
yb = theScreen->Height - 1;
}
FixHeights();
GS = SnapGfx(&rp); /* Snap! */
UnlockLayers(LockedLayerInfo);
if (GS) {
if (GS->window = opensharedwindow(&Nw)) {
GS->window->UserData = (BYTE *)GS;
/* Put gfx in our new window */
(VOID)AddGList(GS->window, &GS->DiskGad, 0L, 3L, NULL);
RefreshGList(&GS->DiskGad, GS->window, NULL, 3L);
AdjustSize(GS);
} else {
FreePlanes(&GS->BM, GS->width, GS->height);
Kill(GS);
}
} else { /* Good question */
}
action = noaction;
return 0;
}
}
}