summaryrefslogtreecommitdiff
path: root/Bob.c
diff options
context:
space:
mode:
Diffstat (limited to 'Bob.c')
-rw-r--r--Bob.c532
1 files changed, 532 insertions, 0 deletions
diff --git a/Bob.c b/Bob.c
new file mode 100644
index 0000000..910d0d7
--- /dev/null
+++ b/Bob.c
@@ -0,0 +1,532 @@
+/*
+** 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 <exec/types.h>
+#include <exec/memory.h>
+#include <graphics/gfx.h>
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <string.h>
+
+#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; i<depth; ++i)
+ bob->Planes[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; i<bm->Depth; ++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<numbobs; ++i)
+ {
+ BobTable[i] = BobTable[i+1];
+ BobTable[i+1] = 0;
+ }
+ numbobs--;
+ }
+ if(numbobs==0) actbobnum=0;
+ RefreshBobNum();
+}
+
+
+/*************************************************************************/
+
+void InsertBob(struct MyBob *bob,WORD num)
+{
+ register int i;
+
+ if(numbobs<MAXNUMBOBS)
+ {
+ numbobs++;
+ for(i=numbobs; 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)||(x1<lastx1)||(y1<lasty1)||(bob->Depth<lastd))
+ {
+clearit:
+ SetAPen(mainrastport,0);
+ RectFill(mainrastport,lastx0-1,lasty0-1,lastx1,lasty1);
+ }
+
+ if(lastcx0>0) /* 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);
+
+ 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(y<yl) val |= 1;
+ if(y>yh) val |= 2;
+ if(x<xl) val |= 4;
+ if(x>xh) 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; i<numbobs; ++i)
+ {
+ sprintf(BobTable[i]->SourceLabel,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; i<numbobs; ++i)
+ {
+ register struct MyBob *bob=BobTable[i];
+ bob->CollX0 = 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;
+ }
+}