/* ** Bobi - The Ultimate Amiga Bob Manipulator ** ** Bob.c - Verschiedene Bob-Manipulations- und Anzeigeroutinen ** ** COPYRIGHT (C) 1989-1993 BY CHRISTIAN A. WEBER, ZUERICH, SWITZERLAND. ** ALL RIGHTS RESERVED. NO PART OF THIS SOFTWARE MAY BE COPIED, REPRODUCED, ** OR TRANSMITTED IN ANY FORM OR BY ANY MEANS, WITHOUT THE PRIOR WRITTEN ** PERMISSION OF THE AUTHOR. NO WARRANTY. USE AT YOUR OWN RISK. */ #include #include #include #include #include #include #include #include "Bobi.h" #include "BobStructure.h" #include "ByteMap.h" extern struct Window *mainwindow,*toolwindow; extern struct RastPort *mainrastport,*toolrastport; extern struct Gadget LabelGadget; extern struct Gadget AutoSizeGadget,AutoOrgGadget,AnimKeyGadget; extern struct StringInfo LabelGadgetSInfo; extern char LabelGadgetSIBuff[]; extern struct MyBob *BobTable[]; extern WORD numbobs,actbobnum,mainwidth,mainheight,mainx0,mainy0; extern WORD options; extern BYTE defaultorg; /*************************************************************************/ struct MyBob *MakeBob(WORD width, WORD height, WORD depth) { register struct MyBob *bob; register long i; if(bob=AllocMem(sizeof(struct MyBob),MEMF_CLEAR)) { bob->Width = width; bob->Height = height; bob->Depth = depth; bob->BytesPerRow = ((width+15)>>3)&(~1); bob->PlaneSize = bob->BytesPerRow*bob->Height; bob->CollX0 = 0; bob->CollY0 = 0; bob->CollX1 = width-1; bob->CollY1 = height-1; SetBobDefaultOrg(bob); if(AutoSizeGadget.Flags & SELECTED) bob->Flags |= BOBF_AUTOSIZE; if(AutoOrgGadget.Flags & SELECTED) bob->Flags |= BOBF_AUTOORG; if(AnimKeyGadget.Flags & SELECTED) bob->Flags |= BODF_ANIMKEY; sprintf(bob->SourceLabel,LabelGadgetSIBuff,actbobnum); if(bob->Planes[0] = AllocMem(bob->PlaneSize*depth,MEMF_CLEAR)) { for(i=1; iPlanes[i] = bob->Planes[0]+i*bob->PlaneSize; } else { FreeBob(bob); bob=0; ShowMonoReq2("No memory for bob planes!"); } } else ShowMonoReq2("No memory for bob node!"); return bob; } /*************************************************************************/ void FreeBob(struct MyBob *bob) { if(bob->Planes[0]) FreeMem(bob->Planes[0],bob->PlaneSize*bob->Depth); if(bob->Mask) FreeMem(bob->Mask,bob->PlaneSize); FreeMem(bob,sizeof(*bob)); } /*************************************************************************/ struct MyBob *BitMapToBob(struct MyBob *oldbob,struct BitMap *bm, WORD width) { register struct MyBob *bob; register long i; if(bob=MakeBob(width,bm->Rows,bm->Depth)) { for(i=0; iDepth; ++i) CopyMem(bm->Planes[i],bob->Planes[i],bob->PlaneSize); if(oldbob) { bob->Flags = oldbob->Flags; bob->X0 = oldbob->X0; /* Nur für Flip etc. erwünscht! */ bob->Y0 = oldbob->Y0; strcpy(bob->SourceLabel,oldbob->SourceLabel); } return(bob); } else return 0; } /*************************************************************************/ struct BitMap *BobToBitMap(struct MyBob *bob) { register struct BitMap *bm; if(bm=MakeBitMap(bob->Width,bob->Height,bob->Depth)) { CopyMem(bob->Planes[0],bm->Planes[0],bob->PlaneSize*bob->Depth); return(bm); } else return 0; } /*************************************************************************/ void DeleteBob(WORD num) { register int i; if(BobTable[num]) { FreeBob(BobTable[num]); for(i=num; i=num; --i) BobTable[i+1] = BobTable[i]; BobTable[num] = bob; RefreshBobNum(); } else ShowMonoReq2("Too many bobs!"); } /*************************************************************************/ void DeleteActBobFunc() { DeleteBob(actbobnum); } /*************************************************************************/ void InsertNewBobFunc() { register struct MyBob *bob; register struct RastPort *rp; if(rp=CreateRastPort(5,34,26)) { SetFont(rp,mainwindow->RPort->Font); SetAPen(rp,1); Move(rp,1,7); Text(rp,"Your",4); Move(rp,5,15); Text(rp,"new",3); Move(rp,5,23); Text(rp,"Bob",3); if(bob=BitMapToBob(0,rp->BitMap,34)) InsertBob(bob,actbobnum); DeleteRastPort(rp); } } /*************************************************************************/ void ShowBob(struct MyBob *bob) { static WORD lastx0=50,lasty0=50,lastx1=52,lasty1=52,lastd=0; static WORD lastcx0=-1,lastcy0,lastcx1,lastcy1; register struct BitMap *tmpmap; register WORD x0,y0,x1,y1; if(!bob) goto clearit; x0 = mainx0-bob->X0; y0 = mainy0-bob->Y0; x1 = x0+bob->Width; y1 = y0+bob->Height; if((x0>lastx0)||(y0>lasty0)||(x1Depth0) /* Falls altes CollisionRect gültig: löschen*/ { if(bob == NULL) goto clearrect; if((lastcx0!=(x0+bob->CollX0)) || (lastcy0!=(y0+bob->CollY0)) || (lastcx1!=(x0+bob->CollX1)) || (lastcy1!=(y0+bob->CollY1)) || (!(options & GOF_COLLISIONRECT))) { clearrect: DrawRect(mainrastport,lastcx0,lastcy0,lastcx1,lastcy1,0); } lastcx0=-1; /* LastCollisionRect als ungültig markieren */ } if(bob && bob->Planes[0]) { lastx0 = x0; lasty0 = y0; lastx1 = x1; lasty1 = y1; lastd = bob->Depth; DrawRect(mainrastport,(WORD)(x0-1),(WORD)(y0-1),x1,y1, (WORD)((options & GOF_BOBBORDERS) ? 1 : 0)); if(tmpmap=BobToBitMap(bob)) { BltBitMapRastPort(tmpmap,0,0,mainrastport,x0,y0,bob->Width,bob->Height,0xc0); WaitBlit(); MyFreeBitMap(tmpmap); } else ShowMonoReq2("Not enough memory to show bob!"); if(options & GOF_COLLISIONRECT) { lastcx0=x0+bob->CollX0; /* Dieses CollisionRect merken */ lastcy0=y0+bob->CollY0; lastcx1=x0+bob->CollX1; lastcy1=y0+bob->CollY1; mainrastport->LinePtrn = 0xAAAA; DrawRect(mainrastport,lastcx0,lastcy0,lastcx1,lastcy1,1); mainrastport->LinePtrn = 0xFFFF; } } } /*************************************************************************/ void ShowFrame(WORD nr) { register struct MyBob *bob; char buf[16]; bob = BobTable[nr]; ShowBob(bob); SetAPen(mainrastport,1); SetBPen(mainrastport,0); SetDrMd(mainrastport,JAM2); if(toolrastport) { SetAPen(toolrastport,1); SetBPen(toolrastport,0); SetDrMd(toolrastport,JAM2); } if(bob) sprintf(buf,"%3ld",(long)nr); else strcpy(buf,"new"); Move(mainrastport,mainwidth-25,19); Text(mainrastport,buf,3); sprintf(buf,"%3ld",(long)numbobs); Move(mainrastport,mainwidth-25,mainheight-3); Text(mainrastport,buf,3); if(toolwindow) { if(bob) sprintf(buf,"W%3ld",bob->Width); else sprintf(buf,"W "); Move(toolrastport,98,19); Text(toolrastport,buf,4); if(bob) sprintf(buf,"H%3ld",bob->Height); else sprintf(buf,"H "); Move(toolrastport,138,19); Text(toolrastport,buf,4); if(bob) sprintf(buf,"X%3ld",bob->X0); else sprintf(buf,"X "); Move(toolrastport,178,19); Text(toolrastport,buf,4); if(bob) sprintf(buf,"Y%3ld",bob->Y0); else sprintf(buf,"Y "); Move(toolrastport,218,19); Text(toolrastport,buf,4); } if(bob) LabelGadgetSInfo.Buffer = bob->SourceLabel; else LabelGadgetSInfo.Buffer = LabelGadgetSIBuff; if(toolwindow) RefreshGList(&LabelGadget,toolwindow,0,1); if(bob) { if(bob->Flags & BOBF_AUTOSIZE) { SelectGadget(toolwindow,&AutoSizeGadget); } else { DeselectGadget(toolwindow,&AutoSizeGadget); } if(bob->Flags & BOBF_AUTOORG) SelectGadget(toolwindow,&AutoOrgGadget); else DeselectGadget(toolwindow,&AutoOrgGadget); if(bob->Flags & BODF_ANIMKEY) SelectGadget(toolwindow,&AnimKeyGadget); else DeselectGadget(toolwindow,&AnimKeyGadget); } } /*************************************************************************/ /* BobHit() liefert 'Position' des Punkts X/Y relativ zum Bob zurück: Bit 0: Punkt zuweit oben Bit 1: Punkt zuweit unten Bit 2: Punkt zuweit links Bit 3: Punkt zuweit rechts */ WORD BobHit(struct MyBob *bob,WORD x,WORD y) { register WORD xl,yl,xh,yh,val; xl = mainx0-bob->X0; /* inklusive xl/yl */ yl = mainy0-bob->Y0; xh = xl+bob->Width; /* exklusive xh/yh */ yh = yl+bob->Height; val = 0; if(yyh) val |= 2; if(xxh) val |= 8; return(val); } /*************************************************************************/ struct MyBob *AutoResizeBob(bob) register struct MyBob *bob; { struct BitMap *bim; register struct ByteMap *bym; struct MyBob *newbob=0; if(AutoSizeGadget.Flags & SELECTED) { if(bim=BobToBitMap(bob)) { if(bym=MakeByteMap((WORD)(bim->BytesPerRow*8),bim->Rows)) { BitMapToByteMap(bim,bym); MyFreeBitMap(bim); if(!AutoResizeByteMap(bym)) { bym->Width=1; bym->Height=1; } bob->X0 -= (bob->Width-bym->Width)/2; /* Bob-Org anpassen */ bob->Y0 -= (bob->Height-bym->Height)/2; if(bim=MakeBitMap(bym->Width,bym->Height,bob->Depth)) { ByteMapToBitMap(bym,bim); if(newbob=BitMapToBob(bob,bim,bym->Width)) { ; } MyFreeBitMap(bim); bim=0; } else ShowMonoReq2("Not enough memory to resize bob"); FreeByteMap(bym); } else ShowMonoReq2("Not enough memory to resize bob"); if(bim) MyFreeBitMap(bim); } else ShowMonoReq2("Not enough memory to resize bob"); } /* if AutoSizeGadget.Flags & SELECTED */ return newbob; } /*************************************************************************/ void RemakeLabelsFunc() { char buf[200]; register LONG i; sprintf(buf,"Do you really want to overwrite\n" "all your labels with the new\nlabel '%s' ?",LabelGadgetSIBuff); if(ShowRequest2(buf,"Dänk scho!")) for(i=0; iSourceLabel,LabelGadgetSIBuff,i); } } /**************************************************************************** ** Alle Collision-Rectangles auf Bob-Grösse setzen */ void RemakeCollisionFunc() { if(ShowRequest2("Do you really want to change all\n" "collision rects to the bob size ?","Yes, please!")) { register LONG i; for(i=0; iCollX0 = 0; bob->CollY0 = 0; bob->CollX1 = bob->Width-1; bob->CollY1 = bob->Height-1; } } } /**************************************************************************** ** Den Nullpunkt eines Bobs auf Default-Wert setzen */ void SetBobDefaultOrg(struct MyBob *bob) { switch(defaultorg) { case 0: // Oben links bob->X0 = 0; bob->Y0 = 0; break; case 1: // Oben Mitte bob->X0 = bob->Width/2; bob->Y0 = 0; break; case 2: // Oben rechts bob->X0 = bob->Width-1; bob->Y0 = 0; break; case 3: // Mitte links bob->X0 = 0; bob->Y0 = bob->Height/2; break; case 4: // Mitte Mitte bob->X0 = bob->Width/2; bob->Y0 = bob->Height/2; break; case 5: // Mitte rechts bob->X0 = bob->Width-1; bob->Y0 = bob->Height/2; break; case 6: // Unten links bob->X0 = 0; bob->Y0 = bob->Height-1; break; case 7: // Unten Mitte bob->X0 = bob->Width/2; bob->Y0 = bob->Height-1; break; case 8: // Unten rechts bob->X0 = bob->Width-1; bob->Y0 = bob->Height-1; break; } }