summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian A. Weber <chris@gna.ch>1993-11-02 18:53:33 +0000
committerChristian A. Weber <chris@gna.ch>1993-11-02 18:53:33 +0000
commit62e509e9c90d728c9f65145947276f79112ab48c (patch)
tree4c508e011be0c0bb386a7c4685c7c71c40611a82
downloadbobi-62e509e9c90d728c9f65145947276f79112ab48c.tar.gz
bobi-62e509e9c90d728c9f65145947276f79112ab48c.tar.bz2
bobi-62e509e9c90d728c9f65145947276f79112ab48c.zip
Initial revision
-rw-r--r--ARexx.c483
-rw-r--r--About.c47
-rw-r--r--AboutWindow.h211
-rw-r--r--Anim.c196
-rw-r--r--BMapSupport.c90
-rw-r--r--Bob.c532
-rw-r--r--BobStructure.h112
-rw-r--r--Bobi.c372
-rw-r--r--Bobi.doc122
-rw-r--r--Bobi.h260
-rw-r--r--Bobi.infobin0 -> 1459 bytes
-rw-r--r--Bobi_rev.h8
-rw-r--r--ByteMap.S591
-rw-r--r--ByteMap.h13
-rw-r--r--Color.c999
-rw-r--r--ConvertDate.S130
-rw-r--r--CreateRastPort.S121
-rw-r--r--FileRequest.c77
-rw-r--r--GadgetSupport.S123
-rw-r--r--Generate.c764
-rw-r--r--GenerateWindow.h651
-rw-r--r--Get.c268
-rw-r--r--HunkDefs.h27
-rw-r--r--IFFAnim.c155
-rw-r--r--IFFError.c50
-rw-r--r--ImsgHandler.c263
-rw-r--r--Layer.c289
-rw-r--r--LoadBobs.c425
-rw-r--r--MainWindow.h2166
-rw-r--r--Makefile85
-rw-r--r--Misc.c204
-rw-r--r--Picture.c174
-rw-r--r--PropGadgets.c61
-rw-r--r--Rotate.c208
-rw-r--r--RotateWindow.h202
-rw-r--r--SCOPTIONS24
-rw-r--r--ShowRequest.c293
-rw-r--r--Sleep.c56
-rw-r--r--Snooze.S95
-rw-r--r--Startup.S406
-rw-r--r--Stubs.c93
-rw-r--r--ToolWindow.h402
-rw-r--r--Zoom.c152
-rw-r--r--ZoomWindow.h255
-rw-r--r--pw/AboutWindow.pwbin0 -> 2280 bytes
-rw-r--r--pw/CHW.Brushbin0 -> 1564 bytes
-rw-r--r--pw/GenerateWindow.pwbin0 -> 3631 bytes
-rw-r--r--pw/MainWindow.pwbin0 -> 8927 bytes
-rw-r--r--pw/RotateWindow.pwbin0 -> 1245 bytes
-rw-r--r--pw/ZoomWindow.pwbin0 -> 1488 bytes
50 files changed, 12255 insertions, 0 deletions
diff --git a/ARexx.c b/ARexx.c
new file mode 100644
index 0000000..ebcee2d
--- /dev/null
+++ b/ARexx.c
@@ -0,0 +1,483 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** ARexx.c - ARexx-Port für Bobi (created from TopScan/ARexx.c)
+**
+** 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 <proto/exec.h>
+#include <rexx/rxslib.h>
+#include <rexx/storage.h>
+#include <rexx/errors.h>
+#include <clib/rexxsyslib_protos.h>
+#include <pragmas/rexxsyslib_pragmas.h>
+#include <proto/dos.h>
+#include <proto/intuition.h>
+
+#include <string.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+#define MYREXXPORTNAME "rexx_bobi"
+#define MYREXXSUFFIX "brx"
+
+
+/****************************************************************************
+** Globals
+*/
+
+BYTE arexxflag; /* TRUE wenn ein Kommando von ARexx am laufen ist */
+char arexxfilename[200]; /* Filename z.B. für LoadBobs() */
+BYTE debugflag;
+
+extern struct Screen *mainscreen;
+extern struct MyBob *BobTable[];
+extern WORD numbobs,actbobnum,options,mainx0,mainy0;
+
+
+/****************************************************************************
+** Locals
+*/
+
+static struct Library *RexxSysBase;
+static struct MsgPort *myrexxport; /* TopScan's rexx port */
+static LONG commandcounter; /* Zählt abgeschickte Kommandos */
+static char resultstring[256]; /* Puffer für ARexx-Resultate */
+
+
+/****************************************************************************
+** ASCII String holen, Anführungszeichen interpretieren.
+** Der Char*-Zeiger wird auf den Text nach dem String gesetzt.
+*/
+
+static void GetRexxString(char **strptr,char *dest)
+{
+ char *s=*strptr;
+
+ /*
+ ** Führende Spaces überlesen
+ */
+ while(*s == ' ') s++;
+
+ /*
+ ** Text kopieren
+ */
+ if(*s == '"') /* Anführungszeichen --> plain copy */
+ {
+ s++;
+ while(*s)
+ {
+ if(*s == '\\') /* Escape-Sequenz */
+ {
+ switch(*++s)
+ {
+ case '\0': goto ende;
+ case 'n': *dest++ = '\n'; break;
+ default: *dest++ = *s; break;
+ }
+ s++;
+ }
+ else if(*s == '"') break;
+ else *dest++ = *s++;
+ }
+ende: ;
+ }
+ else /* Keine Anführungszeichen --> bis Space */
+ {
+ while(*s)
+ {
+ if(*s == '\\') /* Escape-Sequenz */
+ {
+ switch(*++s)
+ {
+ case '\0': goto ende2;
+ case 'n': *dest++ = '\n'; break;
+ default: *dest++ = *s; break;
+ }
+ s++;
+ }
+ else if(*s == ' ') break;
+ else *dest++ = *s++;
+ }
+ende2: ;
+ }
+ *dest = '\0';
+
+ /*
+ ** Spaces am Schluss überlesen
+ */
+ while(*s == ' ') s++;
+
+ *strptr = s;
+}
+
+
+/****************************************************************************
+** ASCII nach Integer wandeln, Nachkommastellen werden unterdrückt.
+** Der Char*-Zeiger wird auf den Text nach der Zahl gesetzt.
+*/
+
+static LONG GetRexxInteger(char **strptr)
+{
+ char *s=*strptr;
+ LONG zahl=0,sign=1;
+
+ while(*s == ' ') s++;
+
+ if(*s == '-')
+ {
+ sign=-1;
+ s++;
+ }
+ else if(*s == '+') s++;
+
+ while((*s >= '0') && (*s <= '9'))
+ {
+ zahl = zahl*10+(*s++-'0');
+ }
+
+ while(*s == ' ') s++;
+
+ *strptr = s;
+ return zahl*sign;
+}
+
+
+/****************************************************************************
+** Die Interface-Routinen zu den ARexx-Kommandos
+*/
+
+static LONG RX_BobiToFrontFunc(char *args)
+{
+ ScreenToFront(mainscreen);
+ return RC_OK;
+}
+
+static LONG RX_BobiToBackFunc(char *args)
+{
+ ScreenToBack(mainscreen);
+ return RC_OK;
+}
+
+static LONG RX_ClearAllFunc(char *args)
+{
+ ClearAll();
+ return RC_OK;
+}
+
+static LONG RX_LoadBobsFunc(char *args)
+{
+ GetRexxString(&args,arexxfilename);
+ LoadBobsFunc();
+ return RC_OK;
+}
+
+static LONG RX_InsertBobsFunc(char *args)
+{
+ GetRexxString(&args,arexxfilename);
+ InsertBobsFunc();
+ return RC_OK;
+}
+
+static LONG RX_SaveBobsFunc(char *args)
+{
+ GetRexxString(&args,arexxfilename);
+ SaveBobsFunc();
+ return RC_OK;
+}
+
+static LONG RX_GenerateCodeFunc(char *args)
+{
+ GetRexxString(&args,arexxfilename);
+ GenerateCodeFunc();
+ return RC_OK;
+}
+
+static LONG RX_LoadIFFFunc(char *args)
+{
+ GetRexxString(&args,arexxfilename);
+ LoadPicFunc();
+ return RC_OK;
+}
+
+static LONG RX_ClosePictureFunc(char *args)
+{
+ CloseScreenFunc();
+ return RC_OK;
+}
+
+static LONG RX_GetBobFunc(char *args)
+{
+ int x,y,w,h;
+
+ x = GetRexxInteger(&args); y = GetRexxInteger(&args);
+ w = GetRexxInteger(&args); h = GetRexxInteger(&args);
+
+ if(GetBob(x,y,w,h))
+ {
+ actbobnum++;
+ return RC_OK;
+ }
+ else return RC_ERROR;
+}
+
+static LONG RX_InsertNewFunc(char *args)
+{
+ InsertNewBobFunc();
+ return RC_OK;
+}
+
+static LONG RX_SetOrgFunc(char *args)
+{
+ if((numbobs>0) && (numbobs!=actbobnum))
+ {
+ BobTable[actbobnum]->X0 = GetRexxInteger(&args);
+ BobTable[actbobnum]->Y0 = GetRexxInteger(&args);
+ return RC_OK;
+ }
+ else return RC_ERROR;
+}
+
+#if 0
+static LONG RX_DebugFunc(char *args)
+{
+ debugflag=GetRexxInteger(&args);
+ return RC_OK;
+}
+#endif
+
+
+/****************************************************************************
+** Ein Rexx-Kommando auswerten, geht auch wenn ARexx NICHT läuft
+*/
+
+LONG PerformRexxCommand(char *commandline)
+{
+ static struct MyRexxCmd
+ {
+ char *Name; /* Name des Kommandos */
+ LONG (*Func)(char *); /* Aufzurufende Routine */
+ }
+ rexxcmdtab[] =
+ {
+ "BOBITOFRONT", RX_BobiToFrontFunc,
+ "BOBITOBACK", RX_BobiToBackFunc,
+
+ "CLEARALL", RX_ClearAllFunc,
+ "LOADBOBS", RX_LoadBobsFunc,
+ "INSERTBOBS", RX_InsertBobsFunc,
+ "SAVEBOBS", RX_SaveBobsFunc,
+ "GENERATECODE", RX_GenerateCodeFunc,
+
+ "LOADIFF", RX_LoadIFFFunc,
+ "CLOSEPICTURE", RX_ClosePictureFunc,
+
+ "GETBOB", RX_GetBobFunc,
+ "INSERTNEW", RX_InsertNewFunc,
+ "SETORG", RX_SetOrgFunc,
+
+#if 0
+ "DEFAULTORG", RX_DefaultOrgFunc,
+ "SETCOLLISION", RX_SetCollisionFunc,
+ "FLIPX", RX_FlipXFunc,
+ "FLIPY", RX_FlipYFunc,
+ "ROTATE", RX_RotateFunc,
+ "ZOOM", RX_ZoomFunc,
+ "DELETEBOB", RX_DeleteBobFunc,
+
+ "LOADANIM", RX_LoadAnimFunc,
+ "SAVEANIM", RX_SaveAnimFunc,
+ "ANIMFIRST", RX_AnimFirstFunc,
+ "ANIMLAST", RX_AnimLastFunc,
+ "ANIMMODE", RX_AnimModeFunc,
+ "STARTANIM", RX_StartAnimFunc,
+ "STOPANIM", RX_StopAnimFunc,
+
+ "TOOLWINDOW", RX_ToolWindowFunc,
+ "LAYERMODE", RX_LayerModeFunc,
+ "ORGGRID", RX_OrgGridFunc,
+ "BOBBORDERS", RX_BobBordersFunc,
+ "BOBCOLLISION", RX_BobCollisionFunc,
+ "SETMAINORG", RX_SetMainOrgFunc,
+ "LOADOFFSETS", RX_LoadOffsetsFunc,
+ "SAVEOFFSETS", RX_SaveOffsetsFunc,
+ "REMAKELABELS", RX_RemakeLabelsFunc,
+ "REMAKECOLLISION", RX_RemakeCollisionFunc
+#endif
+ NULL, NULL /* End-Markierung */
+ };
+
+ struct MyRexxCmd *cptr;
+
+ *resultstring = '\0'; /* Resultat löschen */
+
+ for(cptr=rexxcmdtab; cptr->Name; cptr++)
+ {
+ char *s,*d;
+ for(s=commandline,d=cptr->Name; *d; s++,d++)
+ {
+ if(*s != *d) break;
+ }
+
+ if(*s <= ' ') /* Kommandoname fertig <-> das richtige */
+ {
+ LONG result;
+
+ while(*s == ' ') s++; /* Spaces überhüpfen */
+
+ arexxflag = TRUE;
+ result = cptr->Func(s); /* Funktion aufrufen */
+ arexxflag = FALSE;
+
+ return result;
+ }
+ }
+ return RC_ERROR;
+}
+
+
+/****************************************************************************
+** ARexx initialisieren, 1x gerufen bei Programmstart
+** Öffnet rexxsyslib und erstellt rexx_topscan Port
+** Resultat: 0 falls ARexx nicht läuft, sonst Signalmaske von neuem RexxPort
+*/
+
+ULONG InitARexx(void)
+{
+ if(RexxSysBase=OpenLibrary(RXSNAME,0))
+ {
+ if(myrexxport=CreatePort(MYREXXPORTNAME,0))
+ {
+ return 1U<<myrexxport->mp_SigBit;
+ }
+ }
+ CloseARexx();
+ return 0;
+}
+
+
+/****************************************************************************
+** ARexx cleanup, 1x gerufen bei Programmende
+** Zerstört den ARexx-Port und schliesst rexxsyslib, falls kein Kommando
+** am Laufen ist, sonst wird FALSE zurückgegeben
+*/
+
+ULONG CloseARexx(void)
+{
+ if(commandcounter)
+ {
+ ShowMonoReq2("Can't quit yet, there are\nARexx-Commands pending.");
+ return FALSE;
+ }
+
+ if(myrexxport)
+ {
+ DeletePort(myrexxport);
+ myrexxport = NULL;
+ }
+
+ if(RexxSysBase)
+ {
+ CloseLibrary(RexxSysBase);
+ RexxSysBase = NULL;
+ }
+
+ return TRUE;
+}
+
+
+/****************************************************************************
+** RexxMessage holen und Kommando starten falls ARexx läuft
+*/
+
+void RexxMsgHandler(void)
+{
+ struct RexxMsg *msg;
+ if(!myrexxport) return; /* Sofort zurück falls ARexx nicht läuft */
+
+ while (msg = (struct RexxMsg *)GetMsg(myrexxport))
+ {
+ if(msg->rm_Node.mn_Node.ln_Type != NT_REPLYMSG)
+ /*
+ ** Es ist eine gültige Message und keine Antwort.
+ */
+ {
+ if(IsRexxMsg(msg))
+ {
+ /* Sollen wir ein Kommando auführen ? */
+ if((msg->rm_Action & RXCODEMASK) == RXCOMM)
+ {
+ msg->rm_Result1 = 0;
+ msg->rm_Result2 = 0;
+
+ if(msg->rm_Result1 = PerformRexxCommand(msg->rm_Args[0]))
+ {
+ /* Func returned an error */
+ }
+ else if((*resultstring) && (msg->rm_Action & RXFF_RESULT))
+ {
+ msg->rm_Result2 = (LONG)
+ CreateArgstring(resultstring,strlen(resultstring));
+ }
+ }
+// else INTERNAL_ERROR;
+ }
+// else INTERNAL_ERROR;
+ ReplyMsg(msg);
+ }
+ else
+ /*
+ ** Diese Message ist ein reply auf eine Message welche wir
+ ** früher mal geschickt haben
+ */
+ {
+ DeleteArgstring(msg->rm_Args[0]);
+ if(msg->rm_Stdin) Close(msg->rm_Stdin);
+ DeleteRexxMsg(msg);
+ commandcounter--;
+ }
+ }
+}
+
+
+/****************************************************************************
+** Eine RexxMessage schicken (Speicher wird von RexxMsgHandler freigegeben)
+** Parameter: Kommando-String
+*/
+
+void SendRexxCommand(char *command)
+{
+ BPTR window;
+
+ if(window=Open("CON:0/20/600/160/Bobi ARexx Output Window/AUTO/CLOSE",MODE_OLDFILE))
+ {
+ struct MsgPort *masterport;
+
+ Forbid();
+ if(masterport=FindPort(RXSDIR))
+ {
+ struct RexxMsg *msg;
+
+ if(msg=CreateRexxMsg(myrexxport,MYREXXSUFFIX,MYREXXPORTNAME))
+ {
+ if(msg->rm_Args[0] = CreateArgstring(command,strlen(command)))
+ {
+ msg->rm_Action = RXCOMM;
+ msg->rm_Stdin = window;
+ msg->rm_Stdout = window;
+ window = NULL;
+ commandcounter++;
+ PutMsg(masterport,(struct Message *)msg);
+ }
+ }
+ }
+ Permit();
+
+ if(window) Close(window); /* Schliessen falls Error */
+ }
+}
diff --git a/About.c b/About.c
new file mode 100644
index 0000000..ddd9083
--- /dev/null
+++ b/About.c
@@ -0,0 +1,47 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** About.c - About-Requester anzeigen
+**
+** 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 <proto/exec.h>
+#include <proto/intuition.h>
+#include <intuition/intuition.h>
+
+#include "Bobi.h"
+
+char nametext1[] = "Chris Haller, René Straub";
+char nametext2[] = "René Straub, Chris Haller";
+
+#include "AboutWindow.h"
+
+static char *t1 = nametext1, *t2 = nametext2;
+
+void AboutFunc(void)
+{
+ extern struct Screen *mainscreen;
+ extern char idstring[];
+ char *tmp;
+
+ struct Window *w;
+
+ LockWindows();
+ NewWindowStructure1.Screen = mainscreen;
+ IText2.IText = idstring;
+ IText5.IText = t1;
+ if (w = OpenWindow(&NewWindowStructure1))
+ {
+ PrintIText(w->RPort, &IntuiTextList1, 0L, 0L);
+ WaitPort(w->UserPort);
+ CloseWindow(w);
+ }
+ UnLockWindows();
+
+ /* Namen tauschen */
+ tmp = t1; t1 = t2; t2 = tmp;
+}
diff --git a/AboutWindow.h b/AboutWindow.h
new file mode 100644
index 0000000..2e4c94a
--- /dev/null
+++ b/AboutWindow.h
@@ -0,0 +1,211 @@
+
+static USHORT __chip ImageData1[] = {
+ 0x0480,0x1000,0x0200,0x0004,0x0000,0x0000,0x0007,0x9000,
+ 0x0008,0x4100,0x0200,0x0000,0x0000,0x0BC2,0xA800,0x0700,
+ 0x004E,0x0000,0x0000,0x001F,0xF800,0x001C,0xE380,0x1500,
+ 0x0000,0x0000,0x16FD,0x7000,0x0380,0x00A7,0x0000,0x0000,
+ 0x003F,0xF800,0x003D,0x75C0,0x0E00,0x0000,0x0000,0x2F7E,
+ 0x7000,0x0100,0x01C2,0x0000,0x0000,0x007E,0xB800,0x001C,
+ 0xF3C0,0x0E00,0x0000,0x0000,0x5F3C,0x7000,0x0000,0x01C0,
+ 0x0000,0x0000,0x007B,0x7800,0x001C,0x71C0,0x0E00,0x0000,
+ 0x0000,0xE728,0x7108,0xC10F,0x17E2,0x3F42,0x1000,0x0067,
+ 0xB800,0x001C,0x71C6,0x0E20,0xC08C,0x0000,0xE730,0x779D,
+ 0xE39F,0xEBF7,0x5FA7,0x7800,0x0025,0x3800,0x007C,0x71DB,
+ 0x8EF3,0x71DE,0x0000,0xE718,0x7BFE,0xF7FD,0xF1CF,0xA1CF,
+ 0xBC00,0x001A,0x3800,0x00BC,0x71FD,0xCF7F,0xBBEF,0x0000,
+ 0xE70C,0x7DDF,0x2BB8,0xA1C7,0x11C7,0xDE00,0x001C,0x3800,
+ 0x005C,0x71DD,0xEFBB,0xBDF2,0x8000,0xE700,0x71DC,0x139B,
+ 0xC1C7,0x79C7,0x1C00,0x003F,0xF800,0x001C,0x71DE,0xCE3B,
+ 0xD9C1,0x0000,0x6700,0x71DC,0x038F,0xE1C7,0x7DC7,0x1C00,
+ 0x005F,0xF800,0x001C,0x71DD,0x0E3B,0xA1C0,0x0000,0x3702,
+ 0x71DC,0x0387,0xB1C7,0x73C7,0x1C00,0x00A0,0x3800,0x001C,
+ 0x71DE,0x0E3B,0xC1C0,0x0000,0x1E05,0xF1FE,0x078A,0x3BEF,
+ 0x77CF,0x1E00,0x03E1,0x7800,0x003C,0xFABD,0x1E7F,0xA3E0,
+ 0x0000,0x0FFA,0x71DD,0x039F,0x79D7,0x7BE7,0x1D00,0x05FE,
+ 0xB900,0x005F,0x7D1E,0x8FBB,0xD1D0,0x0000,0x07FC,0x398E,
+ 0x01EF,0xF0E3,0xBC53,0x0E00,0x061F,0x1F80,0x00A7,0x9E0D,
+ 0x07C1,0xA0E0,0x0000,0x01F0,0x1084,0x0093,0xE041,0x1021,
+ 0x0400,0x030E,0x09C0,0x00C3,0x0C06,0x0200,0xC040,0x0000,
+ 0x0000,0x0040,0x0000,0x0000,0x0000,0x0000,0x0180,0x0080,
+ 0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0030,0x0000,0x0000,
+ 0x0000,0x0000,0x0480,0x1000,0x0200,0x0004,0x0000,0x0000,
+ 0x0007,0x9000,0x0008,0x4100,0x0200,0x0000,0x0000,0x09C2,
+ 0xA000,0x0700,0x004E,0x0000,0x0000,0x001F,0xF000,0x0018,
+ 0xE380,0x1400,0x0000,0x0000,0x12FC,0x6000,0x0200,0x0084,
+ 0x0000,0x0000,0x0030,0x7000,0x0039,0x6580,0x0C00,0x0000,
+ 0x0000,0x2678,0x6000,0x0000,0x0180,0x0000,0x0000,0x0066,
+ 0xB000,0x0018,0x6180,0x0C00,0x0000,0x0000,0x4E10,0x6000,
+ 0x0000,0x0180,0x0000,0x0000,0x004B,0x3000,0x0018,0x6180,
+ 0x0C00,0x0000,0x0000,0xC620,0x6108,0xC10F,0x17E2,0x3F42,
+ 0x1000,0x0042,0x3000,0x0018,0x6186,0x0C20,0xC08C,0x0000,
+ 0xC620,0x6799,0xE39B,0xE187,0x4386,0x7800,0x0024,0x3000,
+ 0x0078,0x619B,0x8CF3,0x719E,0x0000,0xC618,0x79BE,0x1730,
+ 0x418E,0x218F,0x9C00,0x0018,0x3000,0x00B8,0x61B9,0xCF37,
+ 0x3BE1,0x0000,0xC600,0x6198,0x2330,0x8186,0x1186,0x1800,
+ 0x0010,0x3000,0x0018,0x6199,0x8C33,0x3182,0x0000,0xC600,
+ 0x6198,0x031B,0xC186,0x7986,0x1800,0x003F,0xF000,0x0018,
+ 0x619A,0x0C33,0x4180,0x0000,0x6600,0x6198,0x030F,0x6186,
+ 0x6586,0x1800,0x0040,0x3000,0x0018,0x619C,0x0C33,0x8180,
+ 0x0000,0x3402,0x6198,0x0304,0x3186,0x6386,0x1800,0x0080,
+ 0x3000,0x0010,0x7118,0x0C33,0x0180,0x0000,0x1C04,0xE1BA,
+ 0x0708,0x33AE,0x678E,0x1A00,0x03E1,0x7000,0x003C,0xF239,
+ 0x1C77,0x23A0,0x0000,0x0FF8,0x711C,0x039F,0x61C7,0x78A6,
+ 0x1C00,0x043E,0x3900,0x004F,0x3C1A,0x0F83,0x41C0,0x0000,
+ 0x03E0,0x2108,0x0127,0xC082,0x2042,0x0800,0x041C,0x1380,
+ 0x0086,0x180C,0x0401,0x8080,0x0000,0x0000,0x0080,0x0000,
+ 0x0000,0x0000,0x0000,0x0300,0x0100,0x0080,0x0000,0x0000,
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0000,0x0060,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0200,0x0800,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0800,0x0004,0x0000,0x0100,0x0000,0x0000,0x0401,0x1000,
+ 0x0180,0x0023,0x0000,0x0000,0x000F,0x8800,0x0004,0x1040,
+ 0x0200,0x0000,0x0000,0x0906,0x1000,0x0100,0x0042,0x0000,
+ 0x0000,0x0018,0x0800,0x0004,0x9240,0x0200,0x0000,0x0000,
+ 0x112C,0x1000,0x0000,0x0040,0x0000,0x0000,0x0030,0x4800,
+ 0x0004,0x1040,0x0200,0x0000,0x0000,0x2108,0x1000,0x0000,
+ 0x0000,0x0000,0x0000,0x0025,0x8800,0x0004,0x1040,0x0200,
+ 0x0000,0x0000,0x2110,0x1004,0x0004,0x0A70,0x1C21,0x0000,
+ 0x0001,0x0800,0x0004,0x1040,0x0200,0x0040,0x0000,0x2100,
+ 0x0240,0xE0CD,0xB041,0x8040,0x2000,0x0002,0x0800,0x0004,
+ 0x1044,0x0048,0x800E,0x0000,0x210C,0x1C47,0x0888,0x2041,
+ 0x0041,0xC600,0x000C,0x0800,0x0044,0x1044,0x6388,0x8C70,
+ 0x8000,0x2100,0x1044,0x1080,0x0041,0x0041,0x0400,0x0000,
+ 0x0800,0x0004,0x1044,0xC208,0x9841,0x0000,0x0100,0x1044,
+ 0x0080,0x8041,0x1841,0x0400,0x001F,0xC800,0x0004,0x1041,
+ 0x0208,0x2040,0x0000,0x0300,0x1044,0x0083,0x8041,0x1041,
+ 0x0400,0x0020,0x0800,0x000C,0x00C6,0x0208,0xC040,0x0000,
+ 0x0201,0x1044,0x0082,0x0841,0x1041,0x0400,0x0000,0x0800,
+ 0x0000,0x0884,0x0208,0x8040,0x0000,0x0002,0x00C1,0x0000,
+ 0x1810,0x0341,0x0100,0x01C0,0x8000,0x0010,0x4104,0x8038,
+ 0x9010,0x0000,0x041C,0x1886,0x00C8,0x3061,0x9C11,0x0600,
+ 0x0203,0x0C00,0x0021,0x8601,0x03C0,0x2060,0x0000,0x01F0,
+ 0x1004,0x0093,0xE041,0x1021,0x0400,0x000E,0x08C0,0x0043,
+ 0x0C06,0x0200,0xC040,0x0000,0x0000,0x0040,0x0000,0x0000,
+ 0x0000,0x0000,0x0180,0x0080,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,
+ 0x0000,0x0030,0x0000,0x0000,0x0000,0x0000
+};
+
+static struct Image Image1 = {
+ 0,0,
+ 193,18,
+ 5,
+ ImageData1,
+ 0x0015,0x0000,
+ NULL
+};
+
+static struct Gadget Gadget2 = {
+ NULL,
+ 18,34,
+ 193,18,
+ GADGHBOX+GADGHIMAGE+GADGIMAGE,
+ NULL,
+ BOOLGADGET,
+ (APTR)&Image1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors1[] = {
+ 0,0,
+ 83,0,
+ 83,13,
+ 0,13,
+ 0,0
+};
+static struct Border Border1 = {
+ -1,-1,
+ 31,0,JAM1,
+ 5,
+ BorderVectors1,
+ NULL
+};
+
+static struct IntuiText IText1 = {
+ 28,0,JAM2,
+ 32,2,
+ NULL,
+ "OK",
+ NULL
+};
+
+static struct Gadget OKGadget = {
+ &Gadget2,
+ 73,-19,
+ 82,12,
+ GRELBOTTOM,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border1,
+ NULL,
+ &IText1,
+ NULL,
+ NULL,
+ 101,
+ NULL
+};
+
+#define GadgetList1 OKGadget
+
+static struct TextAttr TOPAZ80 = {
+ (STRPTR)"topaz.font",
+ TOPAZ_EIGHTY,0,0
+};
+static struct IntuiText IText5 = {
+ 10,0,JAM1,
+ 14,76,
+ &TOPAZ80,
+ "René Straub, Chris Haller",
+ NULL
+};
+
+static struct IntuiText IText4 = {
+ 2,0,JAM1,
+ 78,60,
+ &TOPAZ80,
+ "Thanx to:",
+ &IText5
+};
+
+static struct IntuiText IText3 = {
+ 18,0,JAM2,
+ 106,20,
+ &TOPAZ80,
+ "by",
+ &IText4
+};
+
+static struct IntuiText IText2 = {
+ 8,0,JAM2,
+ 19,7,
+ &TOPAZ80,
+ "Bobi 0.00a (Jan 1 1978)",
+ &IText3
+};
+
+#define IntuiTextList1 IText2
+
+static struct NewWindow NewWindowStructure1 = {
+ 46,50,
+ 228,116,
+ 0,12,
+ GADGETDOWN+GADGETUP,
+ SIMPLE_REFRESH+ACTIVATE+RMBTRAP,
+ &OKGadget,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 5,5,
+ 1024,1024,
+ CUSTOMSCREEN
+};
diff --git a/Anim.c b/Anim.c
new file mode 100644
index 0000000..c4aa3c0
--- /dev/null
+++ b/Anim.c
@@ -0,0 +1,196 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** Anim.c - Bobs animieren
+**
+** 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 <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <proto/dos.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+#define MAXANIMDELAY 50
+
+extern struct Gadget AnimSpeedGadget;
+extern struct PropInfo AnimSpeedGadgetSInfo;
+extern struct MyBob *BobTable[];
+extern struct Window *mainwindow,*toolwindow;
+extern WORD numbobs,actbobnum;
+extern WORD firstanimbob,lastanimbob,animflags;
+
+extern struct MenuItem ForwardItem,BackwardItem,PingPongItem;
+
+
+/*************************************************************************/
+
+void SetFirstBobFunc()
+{
+ if(BobTable[actbobnum]) firstanimbob = actbobnum;
+ else ShowMonoReq2("No bob selected!");
+}
+
+
+/*************************************************************************/
+
+void SetLastBobFunc()
+{
+ if(BobTable[actbobnum]) lastanimbob = actbobnum;
+ else ShowMonoReq2("No bob selected!");
+}
+
+
+/*************************************************************************/
+
+void StartAnimFunc()
+{
+ register struct IntuiMessage *msg;
+ register LONG bobnum,dir,delay,i;
+ struct Menu *mainmenus,*toolmenus;
+ STRPTR oldmaintitle,oldtooltitle;
+
+ oldmaintitle=mainwindow->ScreenTitle;
+ SetWindowTitles(mainwindow,(STRPTR)(~0L),"Hit <ESC> or RMB to stop animation");
+ mainmenus = mainwindow->MenuStrip;
+ ClearMenuStrip(mainwindow);
+
+ if(toolwindow)
+ {
+ oldtooltitle=toolwindow->ScreenTitle;
+ SetWindowTitles(toolwindow,(STRPTR)(~0L),"Hit <ESC> or RMB to stop animation");
+ toolmenus = toolwindow->MenuStrip;
+ ClearMenuStrip(toolwindow);
+ }
+
+ if(lastanimbob < firstanimbob)
+ {
+ bobnum = lastanimbob;
+ lastanimbob = firstanimbob;
+ firstanimbob = bobnum;
+ }
+ bobnum = firstanimbob;
+ dir=1; if(animflags & AF_BACKWARD) dir=-1;
+
+ for(;;)
+ {
+ delay = (GetAnimSpeed()*MAXANIMDELAY+0x7fffL)>>16;
+ for(i=0; i<delay; ++i)
+ {
+ WaitTOF();
+ msg=(struct IntuiMessage *)GetMsg(mainwindow->UserPort);
+ if(toolwindow)
+ {
+ if(!msg) msg=(struct IntuiMessage *)GetMsg(toolwindow->UserPort);
+ }
+
+ if(msg)
+ {
+ if((msg->Class==MENUPICK) ||
+ ((msg->Class==RAWKEY) && (msg->Code==0x45)))
+ {
+ ReplyMsg((struct Message *)msg);
+ goto endanim;
+ }
+ ReplyMsg((struct Message *)msg);
+ }
+ }
+ bobnum += dir;
+ if(animflags & AF_BOUNCE)
+ {
+ if((bobnum>lastanimbob) || (bobnum<firstanimbob))
+ {
+ dir = (-dir);
+ bobnum += dir;
+ bobnum += dir;
+ }
+ }
+ else
+ {
+ if(bobnum>lastanimbob) bobnum = firstanimbob;
+ if(bobnum<firstanimbob) bobnum = lastanimbob;
+ }
+ ShowBob(BobTable[bobnum]);
+ }
+endanim:
+ actbobnum = bobnum;
+ SetWindowTitles(mainwindow,(STRPTR)(~0L),oldmaintitle);
+ if(toolwindow) SetWindowTitles(toolwindow,(STRPTR)(~0L),oldtooltitle);
+ ShowFrame(actbobnum);
+ SetMenuStrip(mainwindow,mainmenus);
+ if(toolwindow) SetMenuStrip(toolwindow,toolmenus);
+}
+
+
+/*************************************************************************/
+
+UWORD GetAnimSpeed()
+{
+ return(AnimSpeedGadgetSInfo.VertPot);
+}
+
+
+/*************************************************************************/
+
+void SetAnimSpeed(UWORD speed)
+{
+ AnimSpeedGadgetSInfo.VertBody = 0xffffL/MAXANIMDELAY;
+ AnimSpeedGadgetSInfo.VertPot = speed;
+
+ if(toolwindow)
+ RefreshGList(&AnimSpeedGadget,toolwindow,0,1);
+}
+
+
+/*************************************************************************/
+
+void SetAnimFlags(WORD flags)
+{
+ ForwardItem.MutualExclude = 6;
+ BackwardItem.MutualExclude = 5;
+ PingPongItem.MutualExclude = 3;
+
+ ForwardItem.Flags &= ~CHECKED;
+ BackwardItem.Flags &= ~CHECKED;
+ PingPongItem.Flags &= ~CHECKED;
+
+ if(flags & AF_FORWARD)
+ {
+ ForwardItem.Flags |= CHECKED;
+ }
+ if(flags & AF_BACKWARD)
+ {
+ BackwardItem.Flags |= CHECKED;
+ }
+ if(flags & AF_BOUNCE)
+ {
+ PingPongItem.Flags |= CHECKED;
+ }
+
+ animflags = flags;
+}
+
+
+/*************************************************************************/
+
+void SetAnimModeFunc()
+{
+ if(ForwardItem.Flags & CHECKED)
+ {
+ animflags = AF_FORWARD;
+ }
+ else if(BackwardItem.Flags & CHECKED)
+ {
+ animflags = 0;
+ }
+ else /* if(PingPongItem.Flags & CHECKED) */
+ {
+ animflags = AF_BOUNCE;
+ }
+}
diff --git a/BMapSupport.c b/BMapSupport.c
new file mode 100644
index 0000000..569cdf3
--- /dev/null
+++ b/BMapSupport.c
@@ -0,0 +1,90 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** BMapSupport.c - Erstellen und Vernichten von BitMaps und ByteMaps
+**
+** 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 <proto/exec.h>
+#include <exec/memory.h>
+#include <graphics/gfx.h>
+#include <proto/graphics.h>
+#include "ByteMap.h"
+
+
+struct BitMap *MakeBitMap(WORD width, WORD height, WORD depth)
+{
+ register long i;
+ register struct BitMap *b;
+ register WORD planesize;
+
+ if(b = AllocMem(sizeof(struct BitMap),MEMF_CLEAR))
+ {
+ InitBitMap(b,depth,width,height);
+ planesize=b->BytesPerRow*b->Rows;
+
+ if(b->Planes[0]=AllocMem(planesize*depth,MEMF_CHIP|MEMF_CLEAR))
+ {
+ for(i=1; i<depth; ++i)
+ b->Planes[i] = b->Planes[0]+i*planesize;
+ }
+ else
+ {
+ FreeMem(b,sizeof(*b));
+ b=0;
+ }
+ }
+ return(b);
+}
+
+
+/*************************************************************************/
+
+void MyFreeBitMap(struct BitMap *b)
+{
+ FreeMem(b->Planes[0],b->BytesPerRow*b->Rows*b->Depth);
+ FreeMem(b,sizeof(*b));
+}
+
+
+/*************************************************************************/
+
+struct ByteMap *MakeByteMap(register WORD width,register WORD height)
+{
+ register struct ByteMap *b;
+ register long planesize;
+
+ planesize = width*height;
+
+ if(b = AllocMem(sizeof(struct ByteMap),MEMF_CLEAR))
+ {
+ if(b->Plane = AllocMem(planesize,MEMF_CLEAR))
+ {
+ b->Width = width;
+ b->Height = height;
+ b->PlaneSize = planesize;
+ }
+ else
+ {
+ FreeMem(b,sizeof(*b));
+ b=0;
+ }
+ }
+ return b;
+}
+
+
+/*************************************************************************/
+
+void FreeByteMap(struct ByteMap *b)
+{
+ if(b->Plane)
+ {
+ FreeMem(b->Plane,b->PlaneSize);
+ }
+ FreeMem(b,sizeof(*b));
+}
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;
+ }
+}
diff --git a/BobStructure.h b/BobStructure.h
new file mode 100644
index 0000000..d180fef
--- /dev/null
+++ b/BobStructure.h
@@ -0,0 +1,112 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** BobStructure.h - MyBob, BobFileHeader, BobData
+**
+** 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.
+*/
+
+struct MyBob
+{
+ PLANEPTR Planes[8]; /* Alle Planes sind aneinander!! */
+ PLANEPTR Mask; /* Zeiger auf Masken-Plane */
+ WORD BytesPerRow; /* Aufgerundetes ((Width+15)/8)&~1 */
+ WORD Width;
+ WORD Height;
+ WORD Depth;
+ WORD Flags; /* Siehe BOBF_ Definitionen */
+ WORD PlaneSize; /* BytesPerRow*Height */
+
+ WORD X0; /* Nullpunkt X-Koordinate */
+ WORD Y0; /* Nullpunkt Y-Koordinate */
+ WORD CollX0; /* X0 des Kollisions-Bereiches */
+ WORD CollY0; /* Y0 des Kollisions-Bereiches */
+ WORD CollX1; /* X1 des Kollisions-Bereiches */
+ WORD CollY1; /* Y1 des Kollisions-Bereiches */
+
+ BYTE PlanePick; /* Für welche Planes existieren Daten */
+ BYTE PlaneOnOff; /* wie bei Image Struktur */
+ char SourceLabel[64];
+};
+
+/* Folgende Flags (MyBob.Flags) sind nur für Bobi's Gebrauch */
+
+#define BOBF_AUTOSIZE 1 /* Bob-Größe wird automatisch errechnet */
+#define BOBF_AUTOORG 2 /* Bob bekommt neuen Org beim Manipulieren */
+#define BOB_PRIVATEMASK 0xff /* Diese Flags werden nicht generiert */
+
+/* Folgende Flags (MyBob.Flags) sind für Bobol's Gebrauch und werden generiert */
+
+#define BODF_ANIMKEY 256 /* 1. Bob einer Animation */
+
+
+/*************************************************************************/
+
+struct BobFileHeader
+{
+ LONG Magic; /* Muss BF_MAGIC sein */
+ WORD Version; /* Versionsnummer des File-Formats */
+ WORD NumBobs;
+ WORD ColorTable[32];
+ char OutputName[127];
+ BYTE DefaultOrg; /* 0=OL, 1=OM, 2=OR, 3=ML, 4=M, 5=MR, usw. */
+ WORD OutputFlags; /* Siehe OF_ - Definitionen */
+ char SectionName[64];
+ char DefaultLabel[64];
+ WORD FirstAnimBob;
+ WORD LastAnimBob;
+ UWORD AnimSpeed;
+ WORD AnimFlags; /* Siehe AF_ - Definitionen */
+ WORD GlobalOptions; /* Siehe GO_ - in MyFunctions.h */
+ WORD MainX0,MainY0; /* ORG-Werte, z.B. von SetMainOrgFunc() */
+ BYTE reserved[2];
+};
+
+#define BF_MAGIC 0x42424932 /* 'BBI2' */
+#define BF_VERSION 111 /* Version des File-Formats */
+
+
+/* Bit-Definitionen für das OutputFlags-Feld der BobFileHeader-Struktur: */
+
+#define OF_ASSEMBLER 1
+#define OF_OBJECT 2
+#define OF_RAWDATA 4
+
+#define OF_COLORTABLE 16
+#define OF_BOBDATA 32
+#define OF_BOBMASK 64
+
+#define OF_GENERATEBOBS 256 /* Bobs generieren */
+#define OF_GENERATESPRITES 512 /* Sprites generieren */
+
+
+/* Bit-Definitionen für das AnimFlags-Feld der BobFileHeader-Struktur: */
+
+#define AF_FORWARD 1 /* Animations-Richtung vorwärts */
+#define AF_BACKWARD 2 /* Animations-Richtung rückwärts */
+#define AF_BOUNCE 4 /* Modus: Normal/Bounce */
+
+
+/*************************************************************************/
+
+struct BobData /* Steht im Source vor jedem Bob */
+{
+ WORD Width; /* Breite in Pixel */
+ WORD Height; /* Höhe in Linien */
+ WORD X0; /* X-Offset des Bob-Nullpunkts */
+ WORD Y0; /* Y-Offset des Bob-Nullpunkts */
+ WORD CollX0; /* X0 des Kollisions-Bereiches */
+ WORD CollY0; /* Y0 des Kollisions-Bereiches */
+ WORD CollX1; /* X1 des Kollisions-Bereiches */
+ WORD CollY1; /* Y1 des Kollisions-Bereiches */
+ BYTE PlanePick; /* Für welche Planes sind Daten vorhanden */
+ BYTE PlaneOnOff; /* Was tun mit den restlichen Planes */
+ WORD Flags; /* Verschiedene Flags, siehe BODF_ weiter oben */
+ WORD WordSize; /* Bob-Breite in WORDs +1 */
+ WORD PlaneSize; /* Anzahl Bytes bis zur nächsten Plane */
+ WORD TotalSize; /* Komplette Größe des Bobs/Sprites mit Header */
+};
+
diff --git a/Bobi.c b/Bobi.c
new file mode 100644
index 0000000..a898c45
--- /dev/null
+++ b/Bobi.c
@@ -0,0 +1,372 @@
+/*
+** $Id$
+**
+** Bobi.c - Hautprogramm
+**
+** 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.
+**
+** Modification History
+** --------------------
+**
+** 05-Mar-89 CHW V2.01 Project started
+** 11-Jun-89 CHW V2.15 InsertBobs added
+** 15-Jun-89 CHW V2.16 SaveOffsets() added
+** 25-Jun-89 CHW V2.20 An ch.lib angepasst
+** 04-Jul-89 CHW V2.22 Generate Code Window versch?nert
+** 07-Jul-89 CHW V2.24 AutoResizeBob() implementiert
+** 26-Jul-89 CHW V2.30 Sprites, neues BobData-Format etc.
+** 05-Nov-89 CHW V2.36 bod_Flags implementiert, Lattice 5.04
+** 07-Nov-89 CHW V2.37 CollisionRects gr?sser als Bob m?glich
+** 12-Nov-89 CHW V2.38 Generiert EQU-Headerfile f?r RawData
+** 17-Nov-89 CHW V2.39 Default-Pfade werden aus '.bobi' gelesen
+** 23-Nov-89 CHW V2.40 Aufger?umt, Bobsize nicht mehr begrenzt,
+** SetMainOrg() implementiert, 2 bugs fixed
+** 30-Nov-89 CHW V2.42 About() verbessert, Collision auto on
+** 03-Dec-89 CHW V2.43 Zoom funktioniert jetzt mit Clipping
+** 14-Dec-89 CHW V2.44 LayerMode- & CustomBitmap-Bug fixed
+** 20-Jan-90 CHW V2.99 ToolWindow implemented, LevelEd support added
+** 04-Mar-90 CHW V2.99c DecodeAnim benutzt iff.library
+** 09-Mar-90 CHW V2.99d Save Sprite OK f?r width < 16
+** 03-Apr-90 CHW V2.99e Pfad bleibt erhalten (f?r CHH)
+** 17-Jul-90 CHW V2.99f Default-Font definiert, Screen-Width var.
+** 12-Feb-91 CHW V2.99i Bei Sprites wird auch eine BobData-
+** Struktur definiert
+** 18-Feb-92 CHW V2.99j Ich kann's wieder compilieren :-)
+** 12-Apr-92 CHW V2.99m Picture-Screen scrollt unter 2.0
+** 12-Apr-92 CHW V2.99n BitMap<->ByteMap k?nnen auch <5 Planes,
+** deshalb haben Bobs jetzt nicht immer >=5 Pl.
+** 20-May-92 CHW V2.99o GenerateCode-ARexx-Befehl eingebaut
+** 06-Jun-92 CHW V2.99p Default-Org funktioniert jetzt
+** 11-Jul-92 CHW V2.99q Main-Screen ist jetzt Halfbrite
+** 02-Nov-93 CHW V3.0 Compiliert mit sc6, ASL-Filerequester
+** 13-Jun-20 CHW V3.1 Kann beim Startup Bob-File laden (CLI+WB)
+*/
+#include <proto/exec.h>
+#include <exec/libraries.h>
+#include <proto/graphics.h>
+#include <graphics/gfxbase.h>
+#include <proto/intuition.h>
+#include <intuition/intuitionbase.h>
+#include <proto/dos.h>
+#include <workbench/startup.h>
+
+#include <string.h>
+#include <libraries/iff.h>
+
+#include "Bobi_rev.h"
+#include "Bobi.h"
+#include "BobStructure.h"
+#include "MainWindow.h"
+
+extern void exit(LONG);
+extern void HandleImsg(struct IntuiMessage *, struct Menu *);
+
+#define ns NewScreenStructure
+
+extern struct Process *ProcessBase; /* Zeiger auf unseren Prozess, siehe Startup.o */
+
+struct Library *MathBase, *MathTransBase;
+
+
+/****************************************************************************
+** Globale Variable
+*/
+
+struct Library *AslBase, *IFFBase;
+
+struct Screen *mainscreen;
+struct Window *mainwindow, *toolwindow;
+struct RastPort *mainrastport, *toolrastport;
+
+struct Screen *picturescreen;
+struct Window *picturewindow;
+
+struct MyBob *BobTable[MAXNUMBOBS+3];
+
+char idstring_versiontag[7] = { '\0', '$', 'V', 'E', 'R', ':', ' ' };
+char idstring[] = VERS " (" DATE ")"; /* Wird ?berall verwendet */
+
+
+WORD options; /* Globale Optionen, siehe GO_ Bobi.h */
+BYTE defaultorg; /* 0=OL, 1=OM, 2=OR, 3=ML, 4=M, 5=MR, usw. */
+WORD numbobs; /* Momentane Anzahl benutzte Bobs */
+WORD actbobnum; /* Nummer des aktuellen Bobs */
+
+UWORD mainpalette[64]; /* Palette des Bobi-Screens */
+UWORD picturepalette[64]; /* Palette des geladenen Bildes */
+
+char outputname[80]; /* Name des zu generierenden Files */
+char sectionname[80]; /* Name der Section des zu generierenden Files */
+WORD outputflags; /* Sprache und so */
+
+WORD mainwidth,mainheight; /* Ausmasse des Screens */
+WORD mainx0,mainy0; /* Globaler Nullpunkt der Bobs */
+
+WORD firstanimbob,lastanimbob,animspeed,animflags;
+
+struct TextAttr MyScreenTextAttr =
+{
+ (STRPTR)"topaz.font", TOPAZ_EIGHTY, 0, 0
+};
+
+ULONG rexxsigmask; /* ARexx Signal Bit Maske */
+
+
+/****************************************************************************
+** L?scht alle Bobs
+*/
+
+void ClearAll()
+{
+ register long i;
+
+ for(i=0; i<numbobs; ++i)
+ {
+ FreeBob(BobTable[i]);
+ BobTable[i]=0;
+ }
+ numbobs = 0;
+ actbobnum = 0;
+ SetGlobalOptions(GOF_LAYERMODE|GOF_BOBBORDERS|GOF_COLLISIONRECT,7);
+ outputflags = 0;
+ if(mainwindow) RefreshBobNum();
+
+ firstanimbob=lastanimbob=animspeed=0;
+ SetAnimFlags(AF_FORWARD);
+
+ strcpy(outputname,"RAM:TestBobs.S");
+ strcpy(sectionname,"BobData");
+ strcpy(LabelGadgetSIBuff,"Bob%ld");
+ if(!picturescreen)
+ {
+ CopyMem(Palette,mainpalette,PaletteColorCount*2);
+ if(mainscreen) LoadPalette(mainpalette);
+ }
+}
+
+
+/****************************************************************************
+** Alles freigeben und evtl. Programm verlassen
+*/
+
+void Cleanup(BOOL reallyquit)
+{
+ if(reallyquit)
+ {
+ CloseARexx(); /* Rexx-Stuff freigeben */
+ ClearAll(); /* Alle Bobs freigeben */
+ }
+
+ CloseScreenFunc(); /* Geladenes Bild freigeben */
+
+ if(toolwindow)
+ {
+ ToolNW.TopEdge=toolwindow->TopEdge;
+ ClearMenuStrip(toolwindow);
+ CloseWindow(toolwindow);
+ toolwindow=0; toolrastport=0;
+ }
+
+ if(mainwindow)
+ {
+ ClearMenuStrip(mainwindow);
+ ProcessBase->pr_WindowPtr=0;
+ CloseWindow(mainwindow);
+ mainwindow=0; mainrastport=0;
+ }
+
+ if(mainscreen)
+ {
+ CloseScreen(mainscreen);
+ mainscreen = NULL;
+ }
+
+ if(reallyquit)
+ {
+ if(IFFBase)
+ {
+ CloseLibrary(IFFBase);
+ IFFBase = NULL;
+ }
+
+ if (AslBase)
+ {
+ CloseLibrary(AslBase);
+ AslBase = NULL;
+ }
+
+ if(MathTransBase)
+ {
+ CloseLibrary(MathTransBase);
+ MathTransBase = NULL;
+ }
+
+ if(MathBase)
+ {
+ CloseLibrary(MathBase);
+ MathBase = NULL;
+ }
+
+ if(IntuitionBase)
+ {
+ CloseLibrary((struct Library *)IntuitionBase);
+ IntuitionBase = NULL;
+ }
+
+ if(GfxBase)
+ {
+ CloseLibrary((struct Library *)GfxBase);
+ GfxBase = NULL;
+ }
+ exit(0);
+ }
+}
+
+
+/****************************************************************************
+** Fehlertext ausgeben und Programm verlassen
+*/
+
+void Fail(char *reason)
+{
+ char buf[200];
+ sprintf(buf,"%s:\n%s\nPlease consult your manual.",idstring,reason);
+ ShowRequest(buf,0,"OKAY",0x8000);
+ Cleanup(TRUE);
+}
+
+
+/****************************************************************************
+** Gerufen bei Control-C-Signal
+*/
+
+void __stdargs __saveds _abort(void)
+{
+ if(CloseARexx()) /* D?rfen wir Quit machen ? */
+ {
+ Fail("*** BREAK - Bobi aborted.");
+ }
+}
+
+
+/****************************************************************************
+** Screen und Window ?ffnen
+*/
+
+void OpenMain()
+{
+ ns.Width = GfxBase->NormalDisplayColumns>>1; /* /2 weil Lo-Res */
+ ns.Height = STDSCREENHEIGHT;
+ ns.Font = &MyScreenTextAttr;
+ ns.DefaultTitle = idstring;
+
+ if(!(mainscreen = OpenScreen(&ns)))
+ {
+ Fail("Can't open screen");
+ }
+ LoadPalette(Palette);
+
+ MainNW.Screen = mainscreen;
+ MainNW.Width = mainwidth = mainscreen->Width;
+ MainNW.Height = mainheight = mainscreen->Height;
+ if(!(mainwindow = OpenWindow(&MainNW)))
+ {
+ Fail("Can't open window");
+ }
+ ProcessBase->pr_WindowPtr = (APTR)mainwindow;
+ mainrastport = mainwindow->RPort;
+ DrawRect(mainrastport,mainwidth-26,23,mainwidth-1,mainheight-13,1);
+
+ ToolWindowFunc(); /* ToolWindow ?ffnen falls enabled */
+}
+
+
+/****************************************************************************
+** Hauptprogramm
+*/
+
+LONG Main(LONG arglen, char *argline)
+{
+ struct WBStartup *startup = (struct WBStartup *)argline;
+ char filename[200] = "\0"; /* File beim Start laden? */
+
+ ToolNW.TopEdge=10000; /* ToolWindow ganz unten */
+
+ if(!(GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",0L)))
+ return 0;
+
+ if(!(IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library",0L)))
+ return 0;
+
+ if(!(AslBase = OpenLibrary("asl.library", 0L)))
+ Fail("Can't open asl.library");
+
+ if(!(IFFBase = OpenLibrary(IFFNAME,0L)))
+ Fail("Can't open iff.library");
+
+ if(!(MathBase = OpenLibrary("mathffp.library",0L)))
+ Fail("Can't open mathffp.library");
+
+ if(!(MathTransBase = OpenLibrary("mathtrans.library",0L)))
+ Fail("Can't open mathtrans.library");
+
+ if(IFFBase->lib_Version < IFFVERSION)
+ Fail("Your iff.library is too old");
+
+ rexxsigmask=InitARexx();
+
+ LoadConfigFile(".bobi");
+ ClearAll();
+ mainx0=MAXX/2; mainy0=(MAXY*2)/3;
+
+ OpenMain();
+
+
+ /*
+ ** Tada! Die Hauptschleife
+ */
+ for(;;)
+ {
+ struct IntuiMessage msgcopy,*msg;
+
+ SetMenuStrip(mainwindow,&MenuList1);
+ if(toolwindow) SetMenuStrip(toolwindow,&MenuList1);
+ actbobnum=ReadBobNum();
+ ShowFrame(actbobnum);
+ ModifyIDCMP(mainwindow,mainidcmpflags|MENUVERIFY);
+ if(toolwindow) ModifyIDCMP(toolwindow,toolidcmpflags|MENUVERIFY);
+
+ for(;;)
+ {
+ if(toolwindow && (mainwindow->Flags & WINDOWACTIVE))
+ ActivateWindow(toolwindow);
+ if(msg=(struct IntuiMessage *)GetMsg(mainwindow->UserPort)) break;
+ if(toolwindow)
+ if(msg=(struct IntuiMessage *)GetMsg(toolwindow->UserPort))
+ break;
+
+ if(toolwindow) Wait(SIGMASK(mainwindow)|SIGMASK(toolwindow)|rexxsigmask);
+ else Wait(SIGMASK(mainwindow)|rexxsigmask);
+ RexxMsgHandler();
+ }
+
+ CopyMem(msg,&msgcopy,sizeof(msgcopy));
+ ReplyMsg((struct Message *)msg);
+ if(msgcopy.Class == MENUVERIFY)
+ {
+ LoadPalette(Palette); /* Default-Farben */
+ }
+ else
+ {
+ ModifyIDCMP(mainwindow,mainidcmpflags); /* MENUVERIFY off */
+ if(toolwindow) ModifyIDCMP(toolwindow,toolidcmpflags);
+ GetGlobalOptions(); /* options updaten */
+ HandleImsg(&msgcopy,&MenuList1);
+ }
+ }
+
+ return 0;
+}
diff --git a/Bobi.doc b/Bobi.doc
new file mode 100644
index 0000000..f9b0fa4
--- /dev/null
+++ b/Bobi.doc
@@ -0,0 +1,122 @@
+AREXX Kommandos für Bobi V2.99m (12. April 1992)
+-------------------------------------------------
+
+Port: "rexx_bobi"
+
+
+Allgemeine Steuer-Kommandos
+---------------------------
+
+BobiToFront Bobi-Screen in den Vordergrund
+
+BobiToBack Bobi-Screen in den Hintergrund
+
+
+Project-Menu
+------------
+
+ClearAll Alles löschen
+
+LoadBobs Filename Bobi-File laden
+
+InsertBobs Filename Position Bobi-File einfügen
+
+SaveBobs Filename Bobi-File speichern
+
+GenerateCode Filename [Modus] Code generieren
+ Werte für Modus:
+ ASM = Assembler-Source
+ OBJ = Objekt-Modul
+ RAW = Raw-Data
+
+
+Picture-Menu
+------------
+
+LoadIFF Filename IFF-Bild laden
+
+ClosePicture IFF-Bild-Screen schliessen
+
+
+Bob-Menu
+--------
+
+GetBob X Y Breite Höhe Bob ausschneiden
+
+SetOrg X Y Bob-Nullpunkt setzen
+
+DefaultOrg Position Default-Nullpunkt setzen, die 9 Mög-
+ lichkeiten entsprechen den Zahlen
+ 1-9 auf dem Zehnerblock
+
+SetCollision X Y Breite Höhe Bob-Kollisions-Bereich setzen
+
+FlipX Bob in X-Richtung spiegeln
+
+FlipY Bob in Y-Richtung spiegeln
+
+Rotate Winkel Anzahl Bob um <Winkel> Grad (0-360) rotie-
+ ren und dabei <Anzahl> neue Bobs
+ generieren
+
+Zoom Faktor1 Faktor2 Anzahl Bob von <Faktor1> (Start-Faktor nach
+ <Faktor2> (End-Faktor) zoomen und
+ dabei <Anzahl> neue Bobs generieren.
+ Die Faktoren müssen in Prozent ange-
+ geben werden (0-1000)
+
+InsertNew Neuen Bob an die aktuelle Stelle
+ einfügen
+
+DeleteBob Aktuelles Bob löschen
+
+
+Anim-Menu
+---------
+
+LoadAnim Filename IFF-Animation laden und in Bobs
+ umwandeln
+
+SaveAnim Filename Bobs als IFF-Animation speichern
+ (nicht implementiert :-))
+
+AnimFirst [Nummer] Aktuelles Bob oder Bob <Nummer> als
+ erstes Animations-Bob setzen
+
+AnimLast [Nummer] Aktuelles Bob oder Bob <Nummer> als
+ letztes Animations-Bob setzen
+
+AnimMode Modus Animations-Modus setzen:
+ FORWARD = Vorwärts
+ BACKWARD = Rückwärts
+ PING-PONG = Hin und zurück
+
+StartAnim Animation starten
+
+StopAnim Animation wieder anhalten
+
+
+Global-Menu
+-----------
+
+ToolWindow ON | OFF Werkzeugfenster ein / aus
+
+LayerMode ON | OFF Verschiebemodus ein / aus
+
+OrgGrid ON | OFF Nullpunkts-Fadenkreuz ein / aus
+
+BobBorders ON | OFF Bob-Rahmen ein / aus
+
+BobCollision ON | OFF Kollisions-Rahmen ein / aus
+
+SetMainOrg X Y Globalen Nullpunkt setzen
+
+LoadOffsets Filename Bob-Offset-Tabelle laden
+
+SaveOffsets Filename Bob-Offset-Tabelle speichern
+
+RemakeLabels Alle Labels neu generieren
+
+RemakeCollision Alle Kollisions-Rechtecke auf die
+ Bob-Grösse zurücksetzen
+
diff --git a/Bobi.h b/Bobi.h
new file mode 100644
index 0000000..102573a
--- /dev/null
+++ b/Bobi.h
@@ -0,0 +1,260 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** Bobi.h - Haupt-Include-File
+**
+** 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 <dos/dos.h>
+#include <libraries/iff.h>
+#include <stdio.h>
+#include <string.h>
+
+#define ClearMem(buf,len) memset(buf, 0, len)
+
+
+#define MAXNUMBOBS 500 /* Maximale Anzahl Bobs */
+
+
+/****************************************************************************
+** Definition des für Bobs benützbaren Bereichs des Bobi-Screens
+*/
+
+#define MINX 1
+#define MINY 12
+#define MAXX 292
+#define MAXY 197
+
+/****************************************************************************
+** Bit-Definitionen für die globalen Optionen:
+*/
+
+#define GOF_LAYERMODE 1 /* Layer-Modus ein/aus */
+#define GOF_ORGGRID 2 /* MainOrg-Fadenkreuz sichtbar */
+#define GOF_BOBBORDERS 4 /* Bob-Rähmchen sichtbar */
+#define GOF_COLLISIONRECT 8 /* Kollisions-Grenzen sichtbar */
+
+
+/****************************************************************************
+** Aliases die das Leben leichter machen:
+*/
+
+#define MainNW NewWindowStructure1
+#define ToolNW NewWindowStructure2
+#define SIGMASK(w) (1L<<(w)->UserPort->mp_SigBit)
+
+
+/****************************************************************************
+** MenuItem-Aliases
+*/
+
+#define ForwardItem SubItem1 /* Anim Modes */
+#define BackwardItem SubItem2
+#define PingPongItem SubItem3
+#define FirstDefaultOrgSubItem SubItem4 /* 9 Items insgesamt */
+#define ToolWindowMenuItem MenuItem1
+#define LayerModeMenuItem MenuItem2 /* Layer Mode on/off */
+#define OrgGridMenuItem MenuItem3 /* Main Org Grid */
+#define BobBordersMenuItem MenuItem4 /* Gadget Borders */
+#define CollisionRectMenuItem MenuItem5 /* Show Collision Bounds */
+
+
+/*
+** Macro zum Abfragen der aktuellen Betriebssystem-Version
+*/
+
+#define OSVERSION(ver) (IntuitionBase->LibNode.lib_Version >= (ver))
+
+
+/********************** Menu 1: Project **********************************/
+
+void ClearAllFunc(void); /* Bobi.c */
+void LoadBobsFunc(void); /* LoadBobs.c */
+void InsertBobsFunc(void); /* LoadBobs.c */
+void SaveBobsFunc(void); /* LoadBobs.c */
+void DeleteFileFunc(void); /* LoadBobs.c */
+void GenerateCodeFunc(void); /* Generate.c */
+void AboutFunc(void); /* About.c */
+void SleepFunc(void); /* Sleep.c */
+void QuitFunc(void); /* Stubs.c */
+
+
+/********************** Menu 2: Picture **********************************/
+
+void LoadPicFunc(void); /* Picture.c */
+void GrabDPaintFunc(void); /* Stubs.c */
+void GrabScreenFunc(void); /* Stubs.c */
+void CloseScreenFunc(void); /* Picture.c */
+
+
+/********************** Menu 3: Bob **************************************/
+
+void GetBobFunc(void); /* Menu 3 & Gadget */
+void GetMultiFunc(void); /* Menu 3 & Gadget */
+void SetOrgFunc(void); /* Menu 3 & Gadget */
+void SetCollBoundsFunc(void); /* Menu 3 & Gadget */
+void FlipXFunc(void); /* Menu 3 */
+void FlipYFunc(void); /* Menu 3 */
+void RotateFunc(void); /* Rotate.c */
+void ZoomFunc(void); /* Zoom.c */
+void InsertNewBobFunc(void); /* Menu 3 */
+void DeleteActBobFunc(void); /* Menu 3 */
+
+
+/********************** Menu 4: Anim *************************************/
+
+void LoadIFFAnimFunc(void); /* Menu 4 */
+void SaveIFFAnimFunc(void); /* Menu 4 */
+void SetFirstBobFunc(void); /* Menu 4 */
+void SetLastBobFunc(void); /* Menu 4 */
+void StartAnimFunc(void); /* Menu 4 */
+void SetAnimModeFunc(void); /* Menu 4 */
+
+
+/********************** Menu 5: Global ***********************************/
+
+void ToolWindowFunc(void); /* Stubs.c */
+void SetMainOrgFunc(void); /* Menu 5 */
+void EditPaletteFunc(void); /* Menu 5 */
+void NewCLIFunc(void); /* Menu 5 */
+void LoadOffsetsFunc(void); /* Menu 5 */
+void SaveOffsetsFunc(void); /* Menu 5 */
+void RemakeLabelsFunc(void); /* Menu 5 */
+void RemakeCollisionFunc(void); /* Menu 5 */
+
+
+/********************** Globale Prozeduren *******************************/
+
+/***** Anim.c: *****/
+
+UWORD GetAnimSpeed(void);
+void SetAnimFlags(WORD);
+void SetAnimSpeed(UWORD);
+
+
+/***** ARexx.c: *****/
+
+ULONG InitARexx(void);
+ULONG CloseARexx(void);
+void RexxMsgHandler(void);
+
+
+/***** Bob.c: *****/
+
+struct MyBob *MakeBob(WORD,WORD,WORD);
+void FreeBob(struct MyBob *);
+struct MyBob *BitMapToBob(struct MyBob *,struct BitMap *,WORD);
+struct BitMap *BobToBitMap(struct MyBob *);
+void DeleteBob(WORD);
+void InsertBob(struct MyBob *,WORD);
+void ShowBob(struct MyBob *);
+void ShowFrame(WORD);
+WORD BobHit(struct MyBob *,WORD,WORD);
+struct MyBob *AutoResizeBob(struct MyBob *);
+void SetBobDefaultOrg(struct MyBob *);
+
+
+/***** Bobi.c: *****/
+
+void ClearAll(void);
+void OpenMain(void);
+void Cleanup(BOOL);
+
+
+/***** BMapSupport.c *****/
+
+struct BitMap *MakeBitMap(WORD,WORD,WORD);
+void MyFreeBitMap(struct BitMap *);
+struct ByteMap *MakeByteMap(WORD,WORD);
+void FreeByteMap(struct ByteMap *);
+
+
+/***** ByteMap.a: *****/
+
+void BitMapToByteMap(struct BitMap *,struct ByteMap *);
+void BobToByteMap(struct MyBob *,struct ByteMap *);
+void ByteMapToBitMap(struct ByteMap *,struct BitMap *);
+BOOL AutoResizeByteMap(struct ByteMap *);
+void RotateByteMap(struct ByteMap *,struct ByteMap *,LONG,LONG,LONG,LONG);
+void FlipXByteMap(struct ByteMap *);
+void FlipYByteMap(struct ByteMap *);
+void ZoomByteMap(struct ByteMap *,struct ByteMap *,LONG);
+
+
+/***** Color.c: *****/
+
+WORD *RequestColor(struct Screen *);
+
+
+/***** ConvertDate.S *****/
+
+char __regargs *ConvertDate(struct DateStamp *, char *);
+
+
+/***** CreateRastPort.S ****/
+
+struct RastPort * __regargs CreateRastPort(WORD, WORD, WORD);
+void __regargs DeleteRastPort(struct RastPort *);
+
+
+/***** FileRequest.c: *****/
+
+STRPTR FileRequest(STRPTR wtitle, STRPTR postext, STRPTR drawer, STRPTR file);
+
+
+/***** GadgetSupport.S *****/
+
+BOOL __regargs DeselectGadget(struct Window *,struct Gadget *);
+BOOL __regargs SelectGadget(struct Window *,struct Gadget *);
+
+
+/***** Get.c: *****/
+
+BOOL GetBob(int x,int y,int w,int h);
+
+
+/***** LoadBobs.c: *****/
+
+void LoadBobs(char *);
+void LoadConfigFile(char *);
+
+
+/***** Misc.c: *****/
+
+void ShowMonoReq2(char *);
+BOOL ShowRequest2(char *,char *);
+void ShowFileError(char *);
+BPTR OpenNewFileSafely(char *);
+void DrawRect(struct RastPort *,WORD,WORD,WORD,WORD,WORD);
+void DrawCross(struct Screen *,WORD,WORD);
+void LoadPalette(UWORD *);
+void LockWindows(void);
+void UnLockWindows(void);
+void SetGlobalOptions(WORD opts, BYTE defaultorg);
+void GetGlobalOptions(void);
+
+
+/***** PropGadgets.c: *****/
+
+void MovePosFunc(void);
+void RefreshBobNum(void);
+WORD ReadBobNum(void);
+
+
+/***** Snooze.S *****/
+
+void __regargs Snooze(struct Window *);
+void __regargs UnSnooze(struct Window *);
+
+
+/***** Verschiedenes: *****/
+
+void DragBobFunc(void); /* Layer.c */
+void HandleEvent(APTR); /* MainWindow.h, PW2 */
+void ShowIFFError(char *); /* IFFError.c */
+LONG ShowRequest(char *text, char *postext, char *negtext, ULONG flags); /* ShowRequest.c */
+
diff --git a/Bobi.info b/Bobi.info
new file mode 100644
index 0000000..49da4d0
--- /dev/null
+++ b/Bobi.info
Binary files differ
diff --git a/Bobi_rev.h b/Bobi_rev.h
new file mode 100644
index 0000000..cf15dc2
--- /dev/null
+++ b/Bobi_rev.h
@@ -0,0 +1,8 @@
+/* $VER: 3.0 - File 'Bobi_rev.h' */
+#define VERSION 3
+#define REVISION 0
+#define DATE "2.11.93"
+#define VERS "Bobi 3.0"
+#define VSTRING "Bobi 3.0 (2.11.93)\n\r"
+#define VERSTAG "\0$VER: Bobi 3.0 (2.11.93)"
+/* Bumper 37.116 (12.7.91) was here */
diff --git a/ByteMap.S b/ByteMap.S
new file mode 100644
index 0000000..d2a0c04
--- /dev/null
+++ b/ByteMap.S
@@ -0,0 +1,591 @@
+**
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** ByteMap.S - ByteMaps konvertieren, spiegeln, rotieren, zoomen usw.
+**
+** 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.
+**
+
+
+ IDNT ByteMap
+ SECTION text,CODE
+
+ INCLUDE "exec/types.i"
+ INCLUDE "graphics/gfx.i"
+
+ XDEF @BitMapToByteMap,@BobToByteMap,@ByteMapToBitMap
+ XDEF @AutoResizeByteMap
+ XDEF @FlipXByteMap,@FlipYByteMap
+ XDEF @RotateByteMap,@ZoomByteMap
+
+
+*****************************************************************************
+
+ STRUCTURE MyBob,0
+ STRUCT mb_Planes,8*4 ; Alle Planes sind aneinander!!
+ APTR mb_Mask ; Zeiger auf Masken-Plane
+ WORD mb_BytesPerRow ; Aufgerundetes ((Width+15)/8)&~1
+ WORD mb_Width
+ WORD mb_Height
+ WORD mb_Depth
+ WORD mb_Flags ; Siehe BOBF_ Definitionen
+ WORD mb_PlaneSize ; BytesPerRow*Height
+
+ WORD mb_X0 ; Nullpunkt X-Koordinate
+ WORD mb_Y0 ; Nullpunkt Y-Koordinate
+ WORD mb_CollX0 ; X0 des Kollisions-Bereiches
+ WORD mb_CollY0 ; Y0 des Kollisions-Bereiches
+ WORD mb_CollX1 ; X1 des Kollisions-Bereiches
+ WORD mb_CollY1 ; Y1 des Kollisions-Bereiches
+
+ BYTE mb_PlanePick ; Für welche Planes existieren Daten
+ BYTE mb_PlaneOnOff ; wie bei Image Struktur
+ STRUCT mb_SourceLabel,64
+
+ LABEL mb_SIZEOF
+
+
+*****************************************************************************
+
+ STRUCTURE ByteMap,0
+
+ WORD bym_Width ; Breite der ByteMap in Pixel
+ WORD bym_Height ; Höhe der ByteMap in Pixel
+ LONG bym_PlaneSize ; Grösse für Alloc/FreeMem der Plane
+ APTR bym_Plane ; Zeiger auf die aktuelle Datenplane
+
+ LABEL bym_SIZEOF
+
+
+***************************************************************************
+** **
+** BitMapToByteMap - BitMap in ByteMap umwandeln (1Byte=1Pixel) **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct BitMap (Source) **
+** A1.L : Zeiger auf struct ByteMap (Destination) **
+** **
+** Resultat : nix **
+** **
+***************************************************************************
+
+@BitMapToByteMap:
+ movem.l d0-d7/a0-a6,-(SP)
+ movem.l bm_Planes(a0),a2-a6 ; IMMER 5 Planes
+ bra.b ToByteMap ; --->
+
+
+***************************************************************************
+** **
+** BobToByteMap - struct MyBob in ByteMap umwandeln (1Byte=1Pixel) **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct MyBob (Source) **
+** A1.L : Zeiger auf struct ByteMap (Destination) **
+** **
+** Resultat : nix **
+** **
+***************************************************************************
+
+@BobToByteMap: movem.l d0-d7/a0-a6,-(SP)
+ movem.l mb_Planes(a0),a2-a6 ; IMMER 5 Planes
+ ;; bra.b ToByteMap ; --->
+
+ToByteMap: bsr ValidatePlanePointers ; Falls weniger als 5 Planes
+ move.w bym_Height(a1),-(SP)
+ move.w bym_Width(a1),-(SP)
+ movea.l bym_Plane(a1),a1 ; Destination-Plane
+ movea.w #16,a0 ; 16 Bits pro Word
+
+1$: move.w (SP),d7 ; Breite in Pixel
+2$: move.w (a2)+,d2
+ move.w (a3)+,d3
+ move.w (a4)+,d4
+ move.w (a5)+,d5
+ move.w (a6)+,d6
+ moveq #15,d1
+ cmp.w a0,d7 ; Noch mehr als 16 Bit ?
+ bge.b 3$ ; ja --->
+ move.w d7,d1
+ bra.b 4$ ; für dbf
+3$: ;; moveq #0,d0
+ addx.w d6,d6 ; roxl.w #1,d6
+ addx.w d0,d0
+ addx.w d5,d5
+ addx.w d0,d0
+ addx.w d4,d4
+ addx.w d0,d0
+ addx.w d3,d3
+ addx.w d0,d0
+ addx.w d2,d2
+ addx.w d0,d0
+ move.b d0,(a1)+
+4$: dbf d1,3$
+ sub.w a0,d7 ; D7 -= 16
+ bgt.b 2$
+ subq.w #1,2(SP) ; DEC Rows
+ bgt.b 1$
+ addq.l #4,SP ; Lokalen Datenraum freigeben
+ movem.l (SP)+,d0-d7/a0-a6
+ rts
+
+
+***************************************************************************
+** **
+** ByteMapToBitMap - ByteMap in BitMap umwandeln (1Byte=1Pixel) **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct ByteMap (Source) **
+** A1.L : Zeiger auf struct BitMap (Destination) **
+** **
+** Resultat : nix **
+** **
+***************************************************************************
+
+@ByteMapToBitMap:
+ movem.l d0-d7/a0-a6,-(SP)
+ move.w bym_Height(a0),-(SP)
+ move.w bym_Width(a0),-(SP)
+ movea.l bym_Plane(a0),a0 ; Source-ByteMap-Plane
+ movem.l bm_Planes(a1),a2-a6 ; IMMER 5 Destination-Planes
+ bsr ValidatePlanePointers ; Falls weniger als 5 Planes
+ movea.w #16,a1 ; 16 Bits pro Word
+
+1$: move.w (SP),d7 ; Breite in Pixel
+2$: moveq #15,d1
+3$: move.b (a0)+,d0 ; Color-Wert
+ roxr.w #1,d0
+ roxl.w #1,d2
+ roxr.w #1,d0
+ roxl.w #1,d3
+ roxr.w #1,d0
+ roxl.w #1,d4
+ roxr.w #1,d0
+ roxl.w #1,d5
+ roxr.w #1,d0
+ roxl.w #1,d6
+ dbf d1,3$
+ move.w d2,(a2)+
+ move.w d3,(a3)+
+ move.w d4,(a4)+
+ move.w d5,(a5)+
+ move.w d6,(a6)+
+
+ sub.w a1,d7 ; D7 -= 16
+ bgt.b 2$
+ neg.w d7 ; D7 := #zuvielgenommene Pixel
+ suba.w d7,a0 ; Correct Source
+ add.w d7,d7 ; Index in WORD-Tabelle
+ move.w MaskTab(PC,d7.w),d0
+ and.w d0,-2(a2) ; Rest-Pixel löschen
+ and.w d0,-2(a3)
+ and.w d0,-2(a4)
+ and.w d0,-2(a5)
+ and.w d0,-2(a6)
+ subq.w #1,2(SP) ; DEC Rows
+ bgt.b 1$
+
+ addq.l #4,SP ; Lokalen Datenraum freigeben
+ movem.l (SP)+,d0-d7/a0-a6
+ rts
+
+MaskTab: dc.w %1111111111111111
+ dc.w %1111111111111110
+ dc.w %1111111111111100
+ dc.w %1111111111111000
+ dc.w %1111111111110000
+ dc.w %1111111111100000
+ dc.w %1111111111000000
+ dc.w %1111111110000000
+ dc.w %1111111100000000
+ dc.w %1111111000000000
+ dc.w %1111110000000000
+ dc.w %1111100000000000
+ dc.w %1111000000000000
+ dc.w %1110000000000000
+ dc.w %1100000000000000
+ dc.w %1000000000000000
+
+
+***************************************************************************
+** **
+** AutoResizeByteMap - ByteMap auf kleinstmögliche Grösse reduzieren **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct ByteMap **
+** **
+** Resultat : D0.L : 0 falls ByteMap leer, 1 sonst **
+** **
+***************************************************************************
+
+@AutoResizeByteMap:
+ movem.l d1-d6/a0-a3,-(SP)
+ moveq #0,d0 ; D0 : X0
+ moveq #0,d1 ; D1 : Y0
+ move.w bym_Width(a0),d2 ; D2 : Breite in Pixel
+ move.w bym_Height(a0),d3 ; D3 : Höhe in Pixel
+ move.w d2,d4 ; D4 : Originalbreite const.
+ movea.l bym_Plane(a0),a1 ; A1 : Plane
+
+ *** Neues Y0 finden
+
+FindY0: movea.l a1,a2 ; Plane
+1$: move.w d2,d5 ; Breite
+ bra.b 3$ ; für dbf
+2$: tst.b (a2)+ ; Pixel == 0 ?
+ bne.b 4$ ; nein ---> Y0 gefunden
+3$: dbf d5,2$
+ addq.w #1,d1 ; INC Y0
+ subq.w #1,d3 ; DEC Höhe
+ bgt.b 1$ ; Noch grösse als 0 ---> Loop
+ bra ByteMapEmpty
+4$:
+ *** Neues Y1 finden
+
+FindY1: movea.l a1,a2 ; Plane
+ move.w d2,d5 ; Breite
+ mulu.w bym_Height(a0),d5 ; mal Original-Höhe
+ adda.l d5,a2 ; Plane-Ende
+1$: move.w d2,d5 ; Breite
+ bra.b 3$ ; für dbf
+2$: tst.b -(a2) ; Pixel == 0 ?
+ bne.b 4$ ; nein ---> Y1 gefunden
+3$: dbf d5,2$
+ subq.w #1,d3 ; DEC Höhe
+ bgt.b 1$ ; > 0 ---> Loop
+ bra ByteMapEmpty
+4$:
+ *** Neues X0 finden
+
+FindX0: movea.l a1,a2 ; Plane
+ move.w d1,d5 ; Y0
+ mulu.w d4,d5 ; * Original-Width
+ adda.l d5,a2
+ move.w d4,d5 ; Original-Breite
+1$: movea.l a2,a3 ; Plane
+ move.w d3,d6 ; Höhe
+ bra.b 3$
+2$: tst.b (a3) ; Pixel == 0 ?
+ bne.b 4$ ; nein ---> X0 gefunden
+ adda.w d5,a3 ; Plane += Width
+3$: dbf d6,2$
+ addq.l #1,a2 ; INC Plane
+ addq.w #1,d0 ; INC X0
+ subq.w #1,d2 ; DEC Width
+ bgt.b 1$ ; > 0 ---> Loop
+ bra ByteMapEmpty
+4$:
+ *** Neues X1 finden
+
+FindX1: movea.l a1,a2 ; Plane
+ move.w d1,d5 ; Y0
+ addq.w #1,d5 ; Ganz rechts + 1
+ mulu.w d4,d5 ; * Original-Width
+ adda.l d5,a2
+ move.w d4,d5 ; Original-Breite
+1$: subq.l #1,a2 ; DEC Plane
+ movea.l a2,a3 ; Plane
+ move.w d3,d6 ; Höhe
+ bra.b 3$
+2$: tst.b (a3) ; Pixel == 0 ?
+ bne.b 4$ ; nein ---> X0 gefunden
+ adda.w d5,a3 ; Plane += Width
+3$: dbf d6,2$
+ subq.w #1,d2 ; DEC Width
+ bgt.b 1$ ; > 0 ---> Loop
+ bra ByteMapEmpty
+4$:
+ *** Neue Parameter in ByteMap eintragen
+
+ subq.w #1,d2 ; Nur so stimmt's weiss auch nicht wieso
+ move.w d2,bym_Width(a0)
+ move.w d3,bym_Height(a0)
+
+ *** ByteMap an neues Format anpassen
+
+ResizeBM: movea.l a1,a2 ; Destination
+ adda.w d0,a1 ; A1 += X0
+ mulu.w d4,d1 ; Y0 *= Old Width
+ adda.l d1,a1 ; A1 += Y0
+ move.w d4,d0 ; Original-Width
+ sub.w d2,d0 ; D0 := Width-Modulo
+ move.w d3,d6 ; Height
+ bra.b 4$ ; Für dbf
+1$: move.w d2,d5 ; Neue Breite
+ bra.b 3$ ; Für dbf
+2$: move.b (a1)+,(a2)+ ; Tada!
+3$: dbf d5,2$
+ adda.w d0,a1 ; A1 += Width-Modulo
+4$: dbf d6,1$ ; DEC Höhe, Loop
+
+ moveq.l #1,d0 ; 'Not empty'
+ bra.b AutoResizeEnd ; --->
+
+ByteMapEmpty: moveq.l #0,d0 ; 'Empty'
+
+AutoResizeEnd: movem.l (SP)+,d1-d6/a0-a3
+ rts
+
+
+***************************************************************************
+** **
+** FlipXByteMap - ByteMap in X-Richtung spiegeln **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct ByteMap **
+** **
+** Resultat : nix **
+** **
+***************************************************************************
+
+@FlipXByteMap: movem.l d0-d3/a0-a2,-(SP)
+ move.w bym_Width(a0),d0 ; Breite in Pixel
+ move.w bym_Height(a0),d1 ; Höhe in Pixel
+ movea.l bym_Plane(a0),a0 ; Plane
+ bra.b 4$ ; für dbf
+1$: move.w d0,d2
+ asr.w #1,d2 ; X/2
+ movea.l a0,a1 ; links
+ lea 0(a1,d0.w),a2 ; rechts
+ bra.b 3$ ; für dbf
+
+2$: move.b (a1),d3 ; Pixel swappen
+ move.b -(a2),(a1)+
+ move.b d3,(a2)
+
+3$: dbf d2,2$
+ adda.w d0,a0 ; Nächste Linie
+4$: dbf d1,1$
+ movem.l (SP)+,d0-d3/a0-a2
+ rts
+
+
+***************************************************************************
+** **
+** FlipYByteMap - ByteMap in Y-Richtung spiegeln **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct ByteMap **
+** **
+** Resultat : nix **
+** **
+***************************************************************************
+
+@FlipYByteMap: movem.l d0-d3/a0-a1,-(SP)
+ move.w bym_Width(a0),d0 ; Breite in Pixel
+ move.w bym_Height(a0),d1 ; Höhe in Pixel
+ movea.l bym_Plane(a0),a0 ; Plane
+
+ move.w d1,d2
+ subq.w #1,d2
+ mulu.w d0,d2
+ movea.l a0,a1
+ adda.l d2,a1 ; A1: Letzte Linie
+ lsr.w #1,d1 ; D1: Höhe/2
+ bra.b 4$ ; für dbf
+
+1$: move.w d0,d2 ; Breite
+ bra.b 3$ ; für dbf
+2$: move.b (a0),d3
+ move.b (a1),(a0)+
+ move.b d3,(a1)+
+3$: dbf d2,2$
+ suba.w d0,a1
+ suba.w d0,a1
+4$: dbf d1,1$
+
+ movem.l (SP)+,d0-d3/a0-a1
+ rts
+
+
+***************************************************************************
+** **
+** RotateByteMap - ByteMap um einen bestimmten Punkt/Winkel rotieren **
+** **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct ByteMap (Source) **
+** A1.L : Zeiger auf struct ByteMap (Destination) **
+** D0.L : Rotationsmittelpunkt X **
+** D1.L : Rotationsmittelpunkt Y **
+** D2.L : Sinus des Rotationswinkels <<10 **
+** D3.L : Cosinus des Rotationswinkels <<10 **
+** **
+** Resultat : nix **
+** **
+***************************************************************************
+
+* x2 = (x1-xm)*cos - (y1-ym)*sin +xm
+* y2 = (x1-xm)*sin + (y1-ym)*cos +ym
+
+@RotateByteMap: movem.l d0-d7/a0-a4,-(SP)
+
+ movem.l 13*4+4(SP),d2-d3
+
+ move.w bym_Width(a0),d4 ; D4 : Breite in Pixel
+ move.w bym_Height(a0),d5 ; D5 : Höhe in Pixel
+ movea.l bym_Plane(a0),a0 ; A0 : Source-Plane
+ movea.l bym_Plane(a1),a1 ; A1 : Destination-Plane
+ suba.l a3,a3 ; A3 : Y-Zähler
+1$: suba.l a2,a2 ; A2 : X-Zähler
+
+2$: move.w a2,d6 ; X
+ sub.w d0,d6 ; -Xm
+ muls.w d3,d6 ; *cos
+ move.w a3,d7 ; Y
+ sub.w d1,d7 ; -Ym
+ muls.w d2,d7 ; *sin
+ sub.l d7,d6
+ asr.l #5,d6 ; Fixkomma to int
+ asr.l #5,d6
+ add.l d0,d6 ; +Xm
+ bpl.b 4$
+3$: clr.b (a1)+
+ bra.b 5$
+4$: cmp.w d4,d6
+ bge.b 3$
+ move.l d6,a4 ; X2
+
+ move.w a2,d6 ; X
+ sub.w d0,d6 ; -Xm
+ muls.w d2,d6 ; *sin
+ move.w a3,d7 ; Y
+ sub.w d1,d7 ; -Ym
+ muls.w d3,d7 ; *cos
+ add.l d7,d6
+ asr.l #5,d6 ; Fixkomma to int
+ asr.l #5,d6
+ add.w d1,d6 ; +Ym gibt Y2
+ bmi.b 3$
+ cmp.w d5,d6
+ bge.b 3$
+ muls.w d4,d6 ; * Breite
+ add.l a4,d6 ; + X2 gibt Offset
+
+ move.b 0(a0,d6.l),(a1)+ ; Tada!
+5$:
+ addq.w #1,a2 ; INC X
+ cmp.w d4,a2 ; == width ?
+ blt.b 2$ ; nope --->
+
+ addq.w #1,a3 ; INC Y
+ cmp.w d5,a3 ; == height ?
+ blt.b 1$ ; nope --->
+
+ movem.l (SP)+,d0-d7/a0-a4
+ rts
+
+
+***************************************************************************
+** **
+** ZoomByteMap - ByteMap um einen bestimmten Faktor zoomen **
+** **
+** **
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct ByteMap (Source) **
+** A1.L : Zeiger auf struct ByteMap (Destination) **
+** D0.L : Zoomfaktor in Prozent **
+** **
+** Resultat : nix **
+** **
+***************************************************************************
+
+* x2 = (x1-xm)*f + xm
+* y2 = (y1-ym)*f + ym
+
+@ZoomByteMap: movem.l d0-d7/a0-a2,-(SP)
+ tst.l d0
+ beq .ZoomEnd
+ move.w bym_Width(a1),d4 ; D4 : Breite in Pixel
+ move.w bym_Height(a1),d5 ; D5 : Höhe in Pixel
+ movea.l bym_Plane(a0),a0 ; A0 : Source-Plane
+ movea.l bym_Plane(a1),a1 ; A1 : Destination-Plane
+ move.w d4,d6
+ lsr.w #1,d6 ; D6 : Mittelpunkt X
+ move.w d5,d7
+ lsr.w #1,d7 ; D7 : Mittelpunkt Y
+
+ moveq #0,d2 ; D2 : Y-Zähler
+.YLoop: moveq #0,d3 ; D3 : X-Zähler
+
+.XLoop: move.w d3,d1 ; X1
+ sub.w d6,d1 ; -xm
+ muls.w #100,d1
+ divs.w d0,d1 ; * f
+ add.w d6,d1 ; +xm
+ bmi.b .Next ; X < 0 ---> unsichtbar
+ cmp.w d4,d1
+ bge.b .Next ; X > xmax ---> unsichtbar
+ movea.w d1,a2 ; macht auch ext.l
+
+ move.w d2,d1 ; Y1
+ sub.w d7,d1 ; -ym
+ muls.w #100,d1
+ divs.w d0,d1 ; * f
+ add.w d7,d1 ; +ym
+ bmi.b .Next ; Y < 0 ---> unsichtbar
+ cmp.w d5,d1
+ bge.b .Next ; Y > xmax ---> unsichtbar
+ mulu.w d4,d1 ; mal Breite
+ add.l a2,d1 ; +X
+
+ move.b 0(a0,d1.l),(a1) ; Tada!
+.Next: addq.l #1,a1 ; INC destination
+
+ addq.w #1,d3 ; INC X
+ cmp.w d4,d3 ; X == Width ?
+ blt.b .XLoop ; noch nicht ---> Loop
+
+ addq.w #1,d2 ; INC Y
+ cmp.w d5,d2 ; Y == Height ?
+ blt.b .YLoop ; noch nicht ---> Loop
+
+.ZoomEnd: movem.l (SP)+,d0-d7/a0-a2
+ rts
+
+
+***************************************************************************
+** **
+** ValidatePlanePointers - Letzten gültigen Plane-Pointer in alle **
+** ungültigen Plane-Pointers kopieren **
+** **
+***************************************************************************
+** **
+** Parameter : A2-A6: Zeiger auf Bitplanes oder NULL wenn ungültig **
+** **
+** Resultat : A2-A6: Zeiger auf BitPlanes, nirgends mehr NULL **
+** **
+***************************************************************************
+
+ValidatePlanePointers:
+ move.l a3,d0 ; Plane 1 gültig ?
+ bne.b 1$ ; ja --->
+ movea.l a2,a3 ; Sonst Plane 0 übernehmen
+1$:
+ move.l a4,d0 ; Plane 2 gültig ?
+ bne.b 2$ ; ja --->
+ movea.l a3,a4 ; Sonst Plane 0 übernehmen
+2$:
+ move.l a5,d0 ; Plane 3 gültig ?
+ bne.b 3$ ; ja --->
+ movea.l a4,a5 ; Sonst Plane 0 übernehmen
+3$:
+ move.l a6,d0 ; Plane 4 gültig ?
+ bne.b 4$ ; ja --->
+ movea.l a5,a6 ; Sonst Plane 0 übernehmen
+4$:
+ rts
+
+
+ END
diff --git a/ByteMap.h b/ByteMap.h
new file mode 100644
index 0000000..5f9cd62
--- /dev/null
+++ b/ByteMap.h
@@ -0,0 +1,13 @@
+/*
+** In der 'ByteMap'-Struktur hat jeder Pixel ein Byte mit dem Farbwert.
+** Änderungen müssen auch in ByteMap.S übernommen werden.
+*/
+
+struct ByteMap
+{
+ WORD Width; /* Breite der ByteMap in Pixel */
+ WORD Height; /* Höhe der ByteMap in Pixel */
+ LONG PlaneSize; /* Grösse für Alloc/FreeMem der Plane */
+ APTR Plane; /* Zeiger auf die aktuelle Datenplane */
+};
+
diff --git a/Color.c b/Color.c
new file mode 100644
index 0000000..ddc8ab9
--- /dev/null
+++ b/Color.c
@@ -0,0 +1,999 @@
+/*************************************************************************
+** **
+** R E Q U E S T C O L O R Copyright : -C5- **
+** ----------------------- **
+** **
+** Der geniale Farbrequester **
+** **
+** Created : 04-Mar-89 (-C5-) Last Update: 16-Jul-89 (-C5-) **
+** **
+**************************************************************************
+** **
+** Format : RequestColor(Screen) **
+** **
+*************************************************************************/
+
+
+#include <proto/intuition.h>
+#include <proto/graphics.h>
+#include <graphics/gfx.h>
+#include <proto/exec.h>
+#include <proto/dos.h>
+
+
+static void HandleEvent(APTR);
+static void HandleColor(APTR);
+static void CleanUp(void);
+static void Exchange(APTR);
+static void Spread(APTR);
+static void Default(APTR);
+static void SelectColor(APTR);
+static void EndColor(APTR);
+static void QuitColor(APTR);
+static void Undo(APTR);
+static void CopyColor(APTR);
+static void PrintRGB(UWORD, UWORD, UWORD);
+static void PrintXY(WORD, WORD, UWORD);
+static void DoBorder(UWORD);
+static void MakeBorder(void);
+
+static void DoBox(void);
+static void SetColor(UWORD);
+static void HelpKey(UWORD);
+
+APTR RequestColor(struct Screen *);
+
+#define CopyPtrHeight 20
+#define CopyPtrWidht 16
+#define CopyPtrMem CopyPtrHeight*4+4
+
+static struct Window *MyWindow;
+static struct Screen *MyScreen;
+static struct MsgPort *MyPort;
+static struct IntuiMessage *MyMsg;
+static struct RastPort *MyRapo;
+static struct ViewPort *MyViewPort;
+
+static UWORD *ctable;
+static UWORD actcol=1;
+static UWORD ColorBuf[32];
+static UWORD UndoBuf[32];
+static UWORD BorderX,BorderY;
+
+static UBYTE xstep,ystep;
+static BYTE endflag;
+static BYTE plane,numcols;
+static APTR PtrBase;
+
+static char rgb[] = " ";
+
+
+static SHORT BorderVectors1[] = {
+ 0,0,
+ 55,0,
+ 55,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border1 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors1,
+ NULL
+};
+
+static struct IntuiText IText1 = {
+ 1,0,JAM2,
+ 3,3,
+ NULL,
+ "SPREAD",
+ NULL
+};
+
+static struct Gadget Gadget11 = {
+ NULL,
+ 9,121,
+ 54,13,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border1,
+ NULL,
+ &IText1,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors2[] = {
+ 0,0,
+ 73,0,
+ 73,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border2 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors2,
+ NULL
+};
+
+static struct IntuiText IText2 = {
+ 1,0,JAM2,
+ 5,3,
+ NULL,
+ "EXCHANGE",
+ NULL
+};
+
+static struct Gadget Gadget10 = {
+ &Gadget11,
+ 9,105,
+ 72,13,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border2,
+ NULL,
+ &IText2,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors3[] = {
+ 0,0,
+ 43,0,
+ 43,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border3 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors3,
+ NULL
+};
+
+static struct IntuiText IText3 = {
+ 1,0,JAM2,
+ 5,3,
+ NULL,
+ "COPY",
+ NULL
+};
+
+static struct Gadget Gadget9 = {
+ &Gadget10,
+ 66,121,
+ 42,13,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border3,
+ NULL,
+ &IText3,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors4[] = {
+ 0,0,
+ 42,0,
+ 42,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border4 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors4,
+ NULL
+};
+
+static struct IntuiText IText4 = {
+ 1,0,JAM2,
+ 4,3,
+ NULL,
+ "UNDO",
+ NULL
+};
+
+static struct Gadget Gadget8 = {
+ &Gadget9,
+ 111,121,
+ 41,13,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border4,
+ NULL,
+ &IText4,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors5[] = {
+ 0,0,
+ 69,0,
+ 69,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border5 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors5,
+ NULL
+};
+
+static struct IntuiText IText5 = {
+ 1,0,JAM2,
+ 6,3,
+ NULL,
+ "DEFAULT",
+ NULL
+};
+
+static struct Gadget Gadget7 = {
+ &Gadget8,
+ 84,105,
+ 68,13,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border5,
+ NULL,
+ &IText5,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors6[] = {
+ 0,0,
+ 66,0,
+ 66,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border6 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors6,
+ NULL
+};
+
+static struct IntuiText IText6 = {
+ 1,0,JAM2,
+ 10,3,
+ NULL,
+ "CANCEL",
+ NULL
+};
+
+static struct Gadget Gadget6 = {
+ &Gadget7,
+ 87,137,
+ 65,13,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border6,
+ NULL,
+ &IText6,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors7[] = {
+ 0,0,
+ 47,0,
+ 47,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border7 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors7,
+ NULL
+};
+
+static struct IntuiText IText7 = {
+ 1,0,JAM2,
+ 15,3,
+ NULL,
+ "OK",
+ NULL
+};
+
+static struct Gadget Gadget5 = {
+ &Gadget6,
+ 9,137,
+ 46,13,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border7,
+ NULL,
+ &IText7,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors8[] = {
+ 0,0,
+ 64,0,
+ 64,64,
+ 0,64,
+ 0,1
+};
+static struct Border Border8 = {
+ -1,-1,
+ 0,0,JAM1,
+ 5,
+ BorderVectors8,
+ NULL
+};
+
+static struct Gadget SelGadget = {
+ &Gadget5,
+ 88,24,
+ 64,64,
+ GADGHBOX+GADGHIMAGE,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border8,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static struct PropInfo BlueGadgetSInfo = {
+ AUTOKNOB+FREEVERT,
+ (UWORD)-1,0,
+ (UWORD)-1,4095,
+};
+
+static struct Image Image1 = {
+ 0,0,
+ 8,4,
+ 0,
+ NULL,
+ 0x0000,0x0000,
+ NULL
+};
+
+static struct Gadget BlueGadget = {
+ &SelGadget,
+ 48,24,
+ 16,64,
+ NULL,
+ RELVERIFY+GADGIMMEDIATE,
+ PROPGADGET,
+ (APTR)&Image1,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&BlueGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static struct PropInfo GreenGadgetSInfo = {
+ AUTOKNOB+FREEVERT,
+ (UWORD)-1,0,
+ (UWORD)-1,4095,
+};
+
+static struct Image Image2 = {
+ 0,0,
+ 8,4,
+ 0,
+ NULL,
+ 0x0000,0x0000,
+ NULL
+};
+
+static struct Gadget GreenGadget = {
+ &BlueGadget,
+ 30,24,
+ 16,64,
+ NULL,
+ RELVERIFY+GADGIMMEDIATE,
+ PROPGADGET,
+ (APTR)&Image2,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&GreenGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static struct PropInfo RedGadgetSInfo = {
+ AUTOKNOB+FREEVERT,
+ (UWORD)-1,0,
+ (UWORD)-1,4095,
+};
+
+static struct Image Image3 = {
+ 0,0,
+ 8,4,
+ 0,
+ NULL,
+ 0x0000,0x0000,
+ NULL
+};
+
+static struct Gadget RedGadget = {
+ &GreenGadget,
+ 12,24,
+ 16,64,
+ NULL,
+ RELVERIFY+GADGIMMEDIATE,
+ PROPGADGET,
+ (APTR)&Image3,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&RedGadgetSInfo,
+ NULL,
+ NULL
+};
+
+#define GadgetList1 RedGadget
+
+static struct IntuiText IText10 = {
+ 1,0,JAM2,
+ 52,14,
+ NULL,
+ "B",
+ NULL
+};
+
+static struct IntuiText IText9 = {
+ 1,0,JAM2,
+ 34,14,
+ NULL,
+ "G",
+ &IText10
+};
+
+static struct IntuiText IText8 = {
+ 1,0,JAM2,
+ 16,14,
+ NULL,
+ "R",
+ &IText9
+};
+
+#define IntuiTextList1 IText8
+
+static struct NewWindow NewWindowStructure1 = {
+ 75,30,
+ 161,160,
+ 0,1,
+ REFRESHWINDOW+GADGETDOWN+GADGETUP+CLOSEWINDOW+RAWKEY,
+ WINDOWDRAG+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH,
+ &RedGadget,
+ NULL,
+ "Edit Palette",
+ NULL,
+ NULL,
+ 5,5,
+ (UWORD)-1,(UWORD)-1,
+ CUSTOMSCREEN
+};
+
+
+static void HandleEvent(object)
+APTR object;
+{
+ if (object == (APTR)&SelGadget) { SelectColor(object); return; }
+ if (object == (APTR)&Gadget5) { EndColor(object); return; }
+ if (object == (APTR)&Gadget6) { QuitColor(object); return; }
+ if (object == (APTR)&Gadget7) { Default(object); return; }
+ if (object == (APTR)&Gadget8) { Undo(object); return; }
+ if (object == (APTR)&Gadget9) { CopyColor(object); return; }
+ if (object == (APTR)&Gadget10) { Exchange(object); return; }
+ if (object == (APTR)&Gadget11) { Spread(object); return; }
+}
+
+/* end of PowerWindows source generation */
+
+
+static UWORD CopyPtr[] = {
+ 0x0000,0x0000,
+ 0x0000,0xFC00,
+ 0x7C00,0xFE00,
+ 0x7C00,0x8600,
+ 0x7800,0x8C00,
+ 0x7C00,0x8600,
+ 0x6E00,0x9300,
+ 0x0700,0x6980,
+ 0x0380,0x04C0,
+ 0x01C0,0x0260,
+ 0x0080,0x0140,
+ 0x0000,0x0080,
+ 0x0000,0x0000,
+ 0x3F1C,0xC060,
+ 0x0C36,0x30C8,
+ 0x0C63,0x318C,
+ 0x0C63,0x318C,
+ 0x0C63,0x318C,
+ 0x0C36,0x30C8,
+ 0x0C1C,0x3060,
+ 0x0000,0x0000,
+};
+
+static void HelpKey(UWORD Key)
+{
+ if (Key==223)
+ {
+ LoadRGB4(MyViewPort,ColorBuf,2);
+ SetColor(actcol);
+ }
+}
+
+static void SaveUndo(void)
+{
+ register UWORD i;
+
+ for (i=0;i<numcols;i++)
+ {
+ UndoBuf[i]=ctable[i];
+ }
+}
+
+static void PrintXY(x,y,z)
+WORD x,y;
+UWORD z;
+{
+ if (z>9) {z+=7;}
+ rgb[0]=z+48;
+ Move(MyRapo,x,y);
+ Text(MyRapo,(char *)&rgb,1);
+}
+
+static void PrintRGB(r,g,b)
+UWORD r,g,b;
+{
+ SetAPen(MyRapo,1);
+ PrintXY((WORD)(RedGadget.LeftEdge+5),98,r);
+ PrintXY((WORD)(GreenGadget.LeftEdge+5),98,g);
+ PrintXY((WORD)(BlueGadget.LeftEdge+5),98,b);
+}
+
+static void HandleColor(APTR obj)
+{
+ register UWORD r,g,b;
+
+ SaveUndo();
+ for(;;)
+ {
+ r = 0xF-(RedGadgetSInfo.VertPot>>12);
+ g = 0xF-(GreenGadgetSInfo.VertPot>>12);
+ b = 0xF-(BlueGadgetSInfo.VertPot>>12);
+
+ SetRGB4(MyViewPort,actcol,r,g,b);
+
+ PrintRGB(r,g,b);
+
+ WaitTOF();
+ MyMsg = (struct IntuiMessage *)GetMsg(MyPort);
+ if (MyMsg->Class==GADGETUP)
+ {
+ ReplyMsg((struct IntuiMessage *)MyMsg);
+ break;
+ }
+
+ if (MyMsg)
+ {
+ ReplyMsg((struct IntuiMessage *)MyMsg);
+ }
+ }
+}
+
+static void SelectColor(APTR obj)
+{
+ actcol = ReadPixel(MyRapo,MyWindow->MouseX,MyWindow->MouseY);
+ SetColor(actcol);
+}
+
+static void Undo(APTR nix)
+{
+ register UWORD i,temp;
+
+ for (i=0;i<numcols;i++)
+ {
+ temp=UndoBuf[i];
+ UndoBuf[i]=ctable[i];
+ ctable[i]=temp;
+ }
+ LoadRGB4(MyViewPort,ctable,numcols);
+ SetColor(actcol);
+}
+
+static void CopyColor(APTR nix)
+{
+ register UWORD oldcol;
+
+ SaveUndo();
+ SetPointer(MyWindow,(UWORD *)PtrBase,CopyPtrHeight,CopyPtrWidht,0,0);
+
+ for (;;)
+ {
+ WaitPort(MyPort);
+ MyMsg = (struct IntuiMessage *)GetMsg(MyPort);
+ if (MyMsg->Class==GADGETUP)
+ {
+ if (MyMsg->IAddress==(APTR)&SelGadget)
+ {
+ oldcol=actcol;
+ actcol=ReadPixel(MyRapo,MyWindow->MouseX,MyWindow->MouseY);
+ ctable[actcol]=ctable[oldcol];
+ LoadRGB4(MyViewPort,ctable,numcols);
+ SetColor(actcol);
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ ReplyMsg((struct IntuiMessage *)MyMsg);
+ }
+ ClearPointer(MyWindow);
+}
+
+static void Exchange(APTR nix)
+{
+ register UWORD oldcol,old;
+
+ SaveUndo();
+ SetPointer(MyWindow,(UWORD *)PtrBase,CopyPtrHeight,CopyPtrWidht,0,0);
+
+ for (;;)
+ {
+ WaitPort(MyPort);
+ MyMsg = (struct IntuiMessage *)GetMsg(MyPort);
+ if (MyMsg->Class==GADGETUP)
+ {
+ if (MyMsg->IAddress==(APTR)&SelGadget)
+ {
+ oldcol=actcol;
+ actcol=ReadPixel(MyRapo,MyWindow->MouseX,MyWindow->MouseY);
+
+ old=ctable[actcol];
+ ctable[actcol]=ctable[oldcol];
+ ctable[oldcol]=old;
+
+ LoadRGB4(MyViewPort,ctable,numcols);
+ SetColor(actcol);
+ break;
+ }
+ else
+ {
+ break;
+ }
+ }
+ ReplyMsg((struct IntuiMessage *)MyMsg);
+ }
+ ClearPointer(MyWindow);
+}
+
+static void Spread(APTR nix)
+{
+ register UWORD old,new,newcol,i,temp;
+ register WORD oldr,oldg,oldb,newr,newg,newb,diff,diffr,diffg,diffb;
+
+ SaveUndo();
+ SetPointer(MyWindow,(UWORD *)PtrBase,CopyPtrHeight,CopyPtrWidht,0,0);
+
+ old=ctable[actcol];
+
+ for (;;)
+ {
+ WaitPort(MyPort);
+ MyMsg = (struct IntuiMessage *)GetMsg(MyPort);
+ if (MyMsg->Class==GADGETUP)
+ {
+ if (MyMsg->IAddress==(APTR)&SelGadget)
+ {
+ newcol=ReadPixel(MyRapo,MyWindow->MouseX,MyWindow->MouseY);
+ new=ctable[newcol];
+
+ LoadRGB4(MyViewPort,ctable,numcols);
+ SetColor(newcol);
+ break;
+ }
+ else
+ {
+ newcol=actcol;
+ new=old;
+ break;
+ }
+ }
+ ReplyMsg((struct IntuiMessage *)MyMsg);
+ }
+ ClearPointer(MyWindow);
+
+ if (actcol>newcol)
+ {
+ temp=newcol;
+ newcol=actcol;
+ actcol=temp;
+
+ temp=new;
+ new=old;
+ old=temp;
+ }
+
+ oldr=(UWORD)((old>>8)&0xF)*(UWORD)0x100;
+ oldg=(UWORD)((old>>4)&0xF)*(UWORD)0x100;
+ oldb=(UWORD)(old&0xF)*(UWORD)0x100;
+
+ newr=(UWORD)((new>>8)&0xF)*(UWORD)0x100;
+ newg=(UWORD)((new>>4)&0xF)*(UWORD)0x100;
+ newb=(UWORD)(new&0xF)*(UWORD)0x100;
+
+ diff=(newcol-actcol);
+ if (diff)
+ {
+ diffr=(WORD)(oldr-newr)/(WORD)diff;
+ diffg=(WORD)(oldg-newg)/(WORD)diff;
+ diffb=(WORD)(oldb-newb)/(WORD)diff;
+
+ for (i=actcol+1;i<newcol;i++)
+ {
+ oldr=(oldr-diffr);
+ oldg=(oldg-diffg);
+ oldb=(oldb-diffb);
+
+ if(oldr<0) {oldr=0;}
+ if(oldg<0) {oldg=0;}
+ if(oldb<0) {oldb=0;}
+
+ ctable[i]=(oldr&0xF00)+((oldg/256)<<4)+(oldb/256);
+ }
+ }
+ actcol=newcol;
+ LoadRGB4(MyViewPort,ctable,numcols);
+}
+
+static void MakeBorder(void)
+{
+ Move(MyRapo,BorderX,BorderY);
+ Draw(MyRapo,BorderX+xstep,BorderY);
+ Draw(MyRapo,BorderX+xstep,BorderY+ystep);
+ Draw(MyRapo,BorderX,BorderY+ystep);
+ Draw(MyRapo,BorderX,BorderY);
+}
+
+static void DoBorder(UWORD color)
+{
+ register UWORD y;
+
+ SetAPen(MyRapo,0);
+ MakeBorder();
+
+ y=(ULONG)64/(UWORD)ystep;
+ BorderX=(color/y);
+ BorderY=(color-(BorderX*y));
+ BorderX=(SelGadget.LeftEdge-1)+(UWORD)BorderX*(UWORD)xstep;
+ BorderY=(SelGadget.TopEdge-1)+(UWORD)BorderY*(UWORD)ystep;
+
+ SetAPen(MyRapo,1);
+ MakeBorder();
+}
+
+static void SetColor(UWORD col)
+{
+ register UWORD r,g,b;
+
+ r=g=b=ctable[col];
+ r=(r>>8)&0xF;
+ g=(g>>4)&0xF;
+ b=(b&15);
+
+ PrintRGB(r,g,b);
+ DoBorder(col);
+
+ r=(UWORD)(0xF-r)*(UWORD)0x1111;
+ g=(UWORD)(0xF-g)*(UWORD)0x1111;
+ b=(UWORD)(0xF-b)*(UWORD)0x1111;
+
+ RedGadgetSInfo.VertPot=r;
+ GreenGadgetSInfo.VertPot=g;
+ BlueGadgetSInfo.VertPot=b;
+ RefreshGList(&RedGadget,MyWindow,0L,3L);
+}
+
+static void StoreColors(void)
+{
+ register UWORD i;
+
+ for (i=0;i<numcols;i++)
+ {
+ ColorBuf[i]=ctable[i];
+ }
+}
+
+static void ReStoreColors(void)
+{
+ LoadRGB4(MyViewPort,ColorBuf,numcols);
+}
+
+static void EndColor(APTR nix)
+{
+ CleanUp();
+}
+
+static void QuitColor(APTR nix)
+{
+ ReStoreColors();
+ CleanUp();
+}
+
+static void Default(APTR obj)
+{
+ SaveUndo();
+ ReStoreColors();
+ SetColor(actcol);
+}
+
+static void CleanUp()
+{
+ NewWindowStructure1.LeftEdge = MyWindow->LeftEdge;
+ NewWindowStructure1.TopEdge = MyWindow->TopEdge;
+ CloseWindow(MyWindow);
+ endflag=TRUE;
+}
+
+static void DoBox()
+{
+ UWORD col=0;
+ register UBYTE x,y,xpos,ypos;
+
+ if (plane==1) {xstep=64; ystep=32;}
+ if (plane==2) {xstep=32; ystep=32;}
+ if (plane==3) {xstep=32; ystep=16;}
+ if (plane==4) {xstep=16; ystep=16;}
+ if (plane==5) {xstep=16; ystep=8;}
+
+ xpos=SelGadget.LeftEdge;
+ ypos=SelGadget.TopEdge;
+
+ for (x=0;x<64;x+=xstep)
+ {
+ for (y=0;y<64;y+=ystep)
+ {
+ SetAPen(MyRapo,col);
+ RectFill(MyRapo,x+xpos,y+ypos,x+xpos+xstep-2,y+ypos+ystep-2);
+ col=col+1;
+ }
+ }
+}
+
+APTR RequestColor(struct Screen *scr)
+{
+ if (scr)
+ {
+ register ULONG class;
+ register UWORD code;
+ register APTR address;
+
+ if (PtrBase=AllocMem(CopyPtrMem,2))
+ {
+ CopyMem((char *)&CopyPtr,(char *)PtrBase,CopyPtrMem);
+
+ BorderX=SelGadget.LeftEdge-1;
+ BorderY=SelGadget.TopEdge-1;
+ endflag = 0;
+ NewWindowStructure1.Screen = scr;
+
+ NewWindowStructure1.Type = (scr->Flags)&0x000F;
+
+ if (MyWindow = OpenWindow(&NewWindowStructure1))
+
+ {
+ MyPort = MyWindow->UserPort;
+ MyRapo = MyWindow->RPort;
+ MyViewPort = &(scr->ViewPort);
+ ctable = (UWORD *)MyViewPort->ColorMap->ColorTable;
+ plane = MyRapo->BitMap->Depth; if(plane>5) plane=5;
+ numcols = 1<<plane;
+
+ DoBox();
+ PrintIText(MyRapo,&IntuiTextList1,0L,0L);
+
+ StoreColors();
+ SaveUndo();
+ SetColor(1);
+
+ do
+ {
+ WaitPort(MyPort);
+ MyMsg = (struct IntuiMessage *)GetMsg(MyPort);
+
+ class = MyMsg->Class;
+ code = MyMsg->Code;
+ address = MyMsg->IAddress;
+
+ ReplyMsg((struct IntuiMessage *)MyMsg);
+
+ switch(class)
+ {
+ case RAWKEY:
+ HelpKey(code);
+ break;
+
+ case GADGETDOWN:
+ HandleColor(address);
+ break;
+
+ case GADGETUP:
+ HandleEvent(address);
+ break;
+
+ case CLOSEWINDOW:
+ ReStoreColors();
+ CleanUp();
+
+ default:
+ break;
+ }
+ }
+ while (!endflag);
+ }
+ FreeMem(PtrBase,CopyPtrMem);
+ return((APTR) MyViewPort->ColorMap->ColorTable);
+ }
+ }
+}
+
+/*
+void __stdargs _main(char *argline)
+{
+ register APTR dummy;
+ register WORD depth;
+
+ IntuitionBase = OpenLibrary("intuition.library",0L);
+ GfxBase = OpenLibrary("graphics.library",0L);
+
+ for (depth=1;depth<6;depth++)
+ {
+ NewScreenStructure.Depth=depth;
+ MyScreen = OpenScreen(&NewScreenStructure);
+ dummy=RequestColor(MyScreen);
+ CloseScreen(MyScreen);
+ }
+
+ CloseLibrary(IntuitionBase);
+ CloseLibrary(GfxBase);
+}
+*/
diff --git a/ConvertDate.S b/ConvertDate.S
new file mode 100644
index 0000000..bd0353a
--- /dev/null
+++ b/ConvertDate.S
@@ -0,0 +1,130 @@
+**************************************************************************
+** **
+** ConvertDate - DateStamp in Klartext umwandeln (wie CLI's DATE) **
+** Beispiel: "Wednesday 24-Dec-1986 06:15:42" **
+** **
+** Created: 14-Mar-89 CHW Last update: 25-Jun-89 **
+** **
+**************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf struct DateStamp **
+** A1.L : Zeiger auf Ausgabepuffer (min. 32 Bytes) **
+** Resultat : - **
+** **
+**************************************************************************
+
+ IDNT ConvertDate
+ SECTION text,CODE
+
+ INCLUDE "dos/dos.i"
+
+
+ XREF _sprintf
+
+ XDEF @ConvertDate
+
+
+@ConvertDate: movem.l d1-d4/a0-a2,-(SP)
+
+ ; Tag berechnen
+
+ move.l (a0),d2 ; D2 : Tag
+ move.l d2,d0 ; Tag
+ addq.l #1,d2 ; ist halt so ...
+ moveq.l #0,d3 ; D3 : Monat
+ move.l #1978,d4 ; D4 : Jahr
+
+ divu #7,d0
+ swap d0 ; Tag MOD 7
+ mulu #10,d0 ; Index in Tabelle
+ lea DayName(PC),a2
+ adda.w d0,a2
+1$: move.b (a2)+,(a1)+ ; Wochentag ausgeben
+ bne.b 1$
+ move.b #' ',-1(a1)
+
+2$: lea MonthTab(PC),a2
+3$: moveq.l #0,d1
+ move.b (a2)+,d1 ; Anzahl Tage im nächsten Monat
+ bne.s 4$
+ addq.l #1,d4 ; INC Jahr
+ moveq.l #0,d3 ; Monat resetten
+ bra.s 2$ ; ---> nochmal
+4$:
+ cmpi.b #28,d1 ; Februar ?
+ bne.s 5$ ; nein --->
+ moveq.l #3,d0
+ and.l d4,d0 ; Schaltjahr ?
+ bne.s 5$ ; nein --->
+ addq.l #1,d1 ; sonst INC Monatstage
+5$:
+ cmp.l d1,d2 ; Mehr Tage als dieser Mt ?
+ ble.s 6$ ; nein --->
+ sub.l d1,d2
+ addq.l #1,d3 ; INC Monat
+ bra.s 3$ ; ---> loop
+6$:
+ move.l d2,d0 ; Tag
+ bsr out2 ; %02d ausgeben
+ move.b #'-',(a1)+
+
+ lsl.w #2,d3 ; *4 für Index
+ lea MonthName(PC,d3.w),a2
+7$: move.b (a2)+,(a1)+ ; Monatsname ausgeben
+ bne.b 7$
+ move.b #'-',-1(a1)
+
+ move.l d4,d0 ; Jahr
+ divu #100,d0
+ swap.w d0 ; modulo 100
+ bsr out2 ; %02d ausgeben
+ move.b #' ',(a1)+
+
+ ; Uhrzeit berechnen
+
+ move.l ds_Minute(a0),d0 ; D0 : Stunden
+ divu #60,d0
+ move.l d0,d1
+ swap d1 ; D1 : Minuten
+
+ bsr out2 ; Stunden ausgeben
+ move.b #':',(a1)+
+ move.w d1,d0
+ bsr out2 ; Minuten ausgeben
+ move.b #':',(a1)+
+
+ move.l ds_Tick(a0),d0
+ divu #50,d0
+ bsr out2 ; Sekunden ausgebemn
+ clr.b (a1)+ ; String abschliessen
+
+end: movem.l (SP)+,d1-d4/a0-a2
+ rts
+
+ ; D0 als 2-stellige Zahl ausgeben (00-59)
+
+out2: ext.l d0
+ divu #10,d0
+ add.w #'0',d0
+ move.b d0,(a1)+ ; Zehner
+ swap d0
+ add.w #'0',d0
+ move.b d0,(a1)+ ; Einer
+ rts
+
+
+MonthName: dc.b "Jan",0,"Feb",0,"Mar",0,"Apr",0
+ dc.b "May",0,"Jun",0,"Jul",0,"Aug",0
+ dc.b "Sep",0,"Oct",0,"Nov",0,"Dec",0
+
+DayName: dc.b "Sunday",0,0,0,0
+ dc.b "Monday",0,0,0,0
+ dc.b "Tuesday",0,0,0
+ dc.b "Wednesday",0
+ dc.b "Thursday",0,0
+ dc.b "Friday",0,0,0,0
+ dc.b "Saturday",0,0
+
+MonthTab: dc.b 31,28,31,30,31,30,31,31,30,31,30,31,0
+
+ END
diff --git a/CreateRastPort.S b/CreateRastPort.S
new file mode 100644
index 0000000..32ef457
--- /dev/null
+++ b/CreateRastPort.S
@@ -0,0 +1,121 @@
+**************************************************************************
+** **
+** CreateRastPort - Erstellt & initialisiert RastPort mit BitMaps **
+** **
+*+ Created: 12-Aug-88 CHW/CHH Last update: 25-Nov-89 CHW +*
+*+ +*
+**************************************************************************
+** **
+** Parameter : D0.W : Depth **
+** D1.W : Width in Pixel **
+** D2.W : Height in Pixel **
+** **
+** Resultat : D0.L :  Zeiger auf RastPort oder 0 if failed **
+** **
+**************************************************************************
+
+ IDNT CreateRastPort
+ SECTION text,CODE
+
+ INCLUDE "exec/macros.i"
+ INCLUDE "exec/memory.i"
+ INCLUDE "exec/types.i"
+ INCLUDE "graphics/gfx.i"
+ INCLUDE "graphics/rastport.i"
+
+ XREF _GfxBase
+
+ XDEF @CreateRastPort,@DeleteRastPort
+
+
+@CreateRastPort:
+ movem.l d1-d3/a0-a3/a5-a6,-(SP)
+ movem.l d0-d2,-(SP)
+ moveq.l #(rp_SIZEOF+bm_SIZEOF)/2,d0
+ add.l d0,d0 ; Optimierung...
+ moveq #MEMF_CLEAR>>16,d1
+ swap d1 ; Lattice C lässt grüssen
+ movea.l 4.W,a6
+ JSRLIB AllocMem
+ tst.l d0
+ bne.s 1$
+ lea 12(SP),SP ; Pop D0-D2
+ bra.s EndCreateRP ; No Mem --->
+1$:
+ movea.l d0,a2 ; A2: RastPort
+ lea rp_SIZEOF(a2),a3 ; A3: BitMap
+
+ movea.l a2,a1 ; Rastport
+ movea.l _GfxBase,a6
+ JSRLIB InitRastPort
+ move.l a3,rp_BitMap(a2) ; BitMap in RastPort eintr.
+
+ movem.l (SP)+,d0-d2 ; Depth/Width/Height
+ movea.l a3,a0 ; BitMap
+ JSRLIB InitBitMap
+
+ move.w bm_BytesPerRow(a3),d2 ; Breite in Bytes
+ mulu.w bm_Rows(a3),d2 ; D2 := Länge einer plane
+
+AllocPlanes: lea bm_Planes(a3),a5
+ moveq.l #0,d3
+ move.b bm_Depth(a3),d3 ; Anzahl Planes
+ bra.s 2$ ; für dbf
+1$: move.l d2,d0 ; Amount
+ move.l #MEMF_CHIP+MEMF_CLEAR,d1
+ movea.l 4.W,a6
+ JSRLIB AllocMem
+ move.l d0,(a5)+ ; Plane eintragen
+ bne.s 2$ ; OK --->
+
+ movea.l a2,a0 ; RastPort
+ bsr @DeleteRastPort ; wieder freigeben
+ bra.s EndCreateRP ; und raus (D0 ist noch 0)
+2$:
+ dbf d3,1$ ; ---> loop
+
+ move.l a2,d0 ; The RastPort
+EndCreateRP:
+ movem.l (SP)+,d1-d3/a0-a3/a5-a6
+ rts
+
+
+**************************************************************************
+** **
+** DeleteRastPort - Mit CreateRastPort() erstellten rp freigeben **
+** **
+** Parameter : A0.L : RastPort **
+** **
+**************************************************************************
+
+@DeleteRastPort:
+ movem.l d0-d3/a0-a3/a5-a6,-(SP)
+ move.l a0,d0
+ beq.s EndDeleteRP
+ movea.l a0,a2 ; A2: RastPort
+ lea rp_SIZEOF(a2),a3 ; A3: BitMap
+
+ move.w bm_BytesPerRow(a3),d2 ; Breite in Bytes
+ mulu.w bm_Rows(a3),d2 ; D2 := Länge einer plane
+
+FreePlanes: lea bm_Planes(a3),a5
+ moveq.l #0,d3
+ move.b bm_Depth(a3),d3 ; Anzahl Planes
+ bra.s 2$ ; für dbf
+1$: move.l d2,d0 ; Amount
+ move.l (a5)+,d1 ; Nächste Plane
+ beq.s 2$ ; Null --->
+ movea.l d1,a1
+ movea.l 4.W,a6
+ JSRLIB FreeMem
+2$: dbf d3,1$ ; ---> loop
+
+ movea.l a2,a1 ; RastPort & BitMap
+ moveq.l #(rp_SIZEOF+bm_SIZEOF)/2,d0
+ add.l d0,d0
+ JSRLIB FreeMem
+EndDeleteRP:
+ movem.l (SP)+,d0-d3/a0-a3/a5-a6
+ rts
+
+ END
diff --git a/FileRequest.c b/FileRequest.c
new file mode 100644
index 0000000..b6c82fc
--- /dev/null
+++ b/FileRequest.c
@@ -0,0 +1,77 @@
+/****** FileRequest *********************************************************
+*
+* NAME
+* FileRequest -- Bring up an ASL file requester
+*
+* SYNOPSIS
+* name = FileRequest(title, postext, path, name)
+*
+* STRPTR FileRequest(STRPTR, STRPTR, STRPTR, STRPTR);
+*
+* FUNCTION
+* Shows a file requester.
+*
+* INPUTS
+* title - The window title
+* postext - Text of the left gadget
+* path - Buffer for the path. This will be modifierd.
+* name - Buffer for the name. This will be modifierd.
+*
+* RESULTS
+* pathname - Pathname of the selected file, or NULL if cancel.
+*
+* SEE ALSO
+* asl.library
+*
+****************************************************************************/
+
+#include <exec/execbase.h>
+#include <proto/dos.h>
+#include <dos/dosextens.h>
+#include <proto/asl.h>
+#include <libraries/asl.h>
+
+#include <string.h>
+
+
+extern struct TextAttr MyScreenTextAttr;
+extern struct Screen *mainscreen;
+
+
+STRPTR FileRequest(STRPTR wtitle, STRPTR postext, STRPTR drawer, STRPTR file)
+{
+ if (AslBase)
+ {
+ struct FileRequester *f;
+ char *filename=NULL;
+ static char buf[256];
+
+ if (f = AllocAslRequestTags( ASL_FileRequest,
+ ASLFR_Screen, mainscreen,
+ ASLFR_TextAttr, &MyScreenTextAttr,
+ ASLFR_TitleText, wtitle,
+ ASLFR_InitialFile, file,
+
+ (drawer != NULL) ? ASLFR_InitialDrawer : ASLFR_DrawersOnly,
+ (drawer != NULL) ? drawer : (STRPTR)TRUE,
+ TAG_DONE
+ ))
+ {
+ if (AslRequest(f, NULL))
+ {
+ strcpy(drawer, f->fr_Drawer);
+ strcpy(file, f->fr_File);
+ strcpy(buf, drawer );
+ AddPart(buf, file, sizeof(buf));
+ filename = buf;
+ }
+
+ FreeAslRequest(f);
+ }
+
+ return filename;
+ }
+ else return "";
+}
+
+
diff --git a/GadgetSupport.S b/GadgetSupport.S
new file mode 100644
index 0000000..2d8b02b
--- /dev/null
+++ b/GadgetSupport.S
@@ -0,0 +1,123 @@
+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
+*+ +*
+*+ GadgetSupport - Routinen zum De-/Selektieren v. BoolGadgets +*
+*+ +*
+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
+*+ +*
+*+ Modification History: +*
+*+ -------------------- +*
+*+ +*
+*+ 26-Oct-87 CHW Created this file! +*
+*+ 25-Jun-89 CHW Cleaned up for chlib +*
+*+ 20-Jan-90 CHW Window pointer may be 0 +*
+*+ 10-Sep-90 CHW A6 wird jetzt auch gerettet, macht jetzt brav +*
+*+ RemoveGadget() und wieder AddGadget(), kann jetzt +*
+*+ auch GRELRIGHT und GRELHEIGHT +*
+*+ +*
+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
+
+ IDNT GadgetSupport
+ SECTION text,CODE
+
+ INCLUDE "exec/macros.i"
+ INCLUDE "intuition/intuition.i"
+
+ XREF _GfxBase,_IntuitionBase
+
+ XDEF @SelectGadget,@DeselectGadget
+
+
+GB_RELBOTTOM: EQU 3 ; Bit 3 im WORD
+GB_RELRIGHT: EQU 4 ; Bit 4 im WORD
+GB_SELECTED: EQU 7 ; Bit 7 im WORD
+
+
+
+**************************************************************************
+** **
+** SelectGadget - Boolean-Gadget selektieren & highlighten **
+** **
+** Parameter : A0.L : Adresse der Window-Struktur oder 0 **
+** A1.L : Zeiger auf zu selektierendes Gadget **
+** Resultat : nix **
+** **
+**************************************************************************
+
+@SelectGadget:
+ movem.l d0-d4/a0-a3/a6,-(SP) ; muss so bleiben, siehe unten
+
+ movea.l a0,a2 ; A2 : Window
+ movea.l a1,a3 ; A3 : Gadget
+ bset.b #GB_SELECTED,gg_Flags+1(a3)
+ bne norefresh ; Gleicher wie vorher ---> fertig
+ bra.s commoncont ; --->
+
+
+
+**************************************************************************
+** **
+** DeselectGadget - Boolean-Gadget deselektieren **
+** **
+** Parameter : A0.L : Adresse der Window-Struktur oder 0 **
+** A1.L : Zeiger auf zu deselektierendes Gadget **
+** Resultat : nix **
+** **
+**************************************************************************
+
+@DeselectGadget:
+ movem.l d0-d4/a0-a3/a6,-(SP) ; muss so bleiben
+
+ movea.l a0,a2 ; A2 : Window
+ movea.l a1,a3 ; A3 : Gadget
+ bclr.b #GB_SELECTED,gg_Flags+1(a3)
+ beq.s norefresh ; Gleicher wie vorher ---> fertig
+
+commoncont: move.l a2,d0 ; Window
+ beq.s norefresh ; Null ---> Kein Refresh
+ movea.l _IntuitionBase,a6
+ JSRLIB RemoveGadget
+ move.l d0,d4 ; D4 : Gadget-Position
+
+ moveq.l #0,d0 ; Farbe 0
+ movea.l wd_RPort(a2),a1 ; Window's RastPort
+ movea.l _GfxBase,a6
+ JSRLIB SetAPen ; Farbe setzen
+ moveq.l #RP_JAM2,d0
+ movea.l wd_RPort(a2),a1 ; Window's RastPort
+ JSRLIB SetDrMd ; Modus setzen
+
+ movea.l wd_RPort(a2),a1
+ movem.w gg_LeftEdge(a3),d0-d3 ; Alles auf einmal!
+
+ btst #GB_RELRIGHT,gg_Flags+1(a3)
+ beq.s 1$
+ add.w wd_Width(a2),d0 ; Korrektur von GRELRIGHT
+ subq.w #1,d0
+1$:
+ btst #GB_RELBOTTOM,gg_Flags+1(a3)
+ beq.s 2$
+ add.w wd_Height(a2),d1 ; Korrektur von GRELBOTTOM
+ subq.w #1,d1
+2$:
+ add.w d0,d2 ; Width -> X2
+ add.w d1,d3 ; Height -> Y2
+ subq.w #1,d2
+ subq.w #1,d3
+ JSRLIB RectFill ; Gadget löschen
+
+ move.l d4,d0 ; Gadget-Position
+ movea.l a2,a0 ; Window
+ movea.l a3,a1 ; Gadget
+ movea.l _IntuitionBase,a6
+ JSRLIB AddGadget
+
+ movea.l a3,a0 ; Gadget
+ movea.l a2,a1 ; Window
+ suba.l a2,a2 ; Requester
+ moveq.l #1,d0 ; nur dieses Gadget
+ JSRLIB RefreshGList
+
+norefresh: movem.l (SP)+,d0-d4/a0-a3/a6
+ rts
+
+ END
diff --git a/Generate.c b/Generate.c
new file mode 100644
index 0000000..f1f6711
--- /dev/null
+++ b/Generate.c
@@ -0,0 +1,764 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** Generate.c - Assembler Source, Biärfile oder Objektmodul generieren
+**
+** 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 <proto/exec.h>
+#include <exec/memory.h>
+#include <proto/intuition.h>
+#include <proto/dos.h>
+
+#include <string.h>
+#include <stdarg.h>
+
+#include "HunkDefs.h"
+#include "GenerateWindow.h"
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+extern struct MyBob *BobTable[];
+extern struct Screen *mainscreen;
+extern WORD numbobs;
+extern UWORD mainpalette[];
+extern char idstring[],outputname[],sectionname[],LabelGadgetSIBuff[];
+extern WORD outputflags;
+extern char arexxfilename[];
+extern BYTE arexxflag;
+
+static BPTR file;
+static LONG filesize;
+
+
+/****************************************************************************
+** Daten in File schreiben und filesize erhöhen
+*/
+
+static void MyWrite(void *adr,LONG len)
+{
+ Write(file,adr,len);
+ filesize += len;
+}
+
+
+/****************************************************************************
+** C formatierter String auf ein File ausgeben, filesize erhöhen
+*/
+
+static void fputf(char *text,...)
+{
+ char buf[256];
+ va_list args;
+
+ va_start(args,text);
+ vsprintf(buf,text,args);
+ MyWrite(buf,strlen(buf));
+ va_end(args);
+}
+
+
+/****************************************************************************
+** Langwort in File schreiben
+*/
+
+static void fputl(LONG loy)
+{
+ MyWrite(&loy,4);
+}
+
+
+/****************************************************************************
+** Wort in File schreiben
+*/
+
+static void fputw(UWORD woy)
+{
+ MyWrite(&woy,2);
+}
+
+
+/****************************************************************************
+** Symbolnamen mit Länge und Typ im Objektmodul-Format ausgeben
+*/
+
+static void fputsym(char *string,LONG type)
+{
+ LONG len;
+ char buf[200];
+
+ ClearMem(buf,200);
+ len = (strlen(string)+3)>>2; type |= len;
+ MyWrite(&type,4);
+ strcpy(buf,string);
+ MyWrite(buf,len<<2);
+}
+
+
+/****************************************************************************
+** String mit Länge im Objektmodul-Format ausgeben
+*/
+
+static void fpuths(char *string)
+{
+ fputsym(string,0);
+}
+
+
+/****************************************************************************
+** Bob-Maske berechnen mitels OR-Verknüpfung aller Planes
+*/
+
+static void CalculateMask(struct MyBob *bob)
+{
+ WORD *sptr,*dptr;
+ long i,j;
+
+ if(bob->Mask) FreeMem(bob->Mask,bob->PlaneSize);
+ if(bob->Mask=AllocMem(bob->PlaneSize,MEMF_CLEAR))
+ {
+ for(i=0; i<bob->Depth; i++)
+ {
+ sptr = (WORD *)bob->Planes[i];
+ dptr = (WORD *)bob->Mask;
+ for(j=bob->PlaneSize; j>0; j-=2) *(dptr++) |= *(sptr++);
+ }
+ }
+ else ShowMonoReq2("No memory to create bob mask!");
+}
+
+
+/****************************************************************************
+** PlanePick und PlaneOnOff berechnen
+*/
+
+static void CalculatePlanePick(struct MyBob *bob)
+{
+ WORD *sptr,*dptr;
+ long i,j,x;
+
+ bob->PlanePick = (1<<bob->Depth)-1;
+ bob->PlaneOnOff = 0;
+
+ for(i=0; i<bob->Depth; ++i)
+ {
+ sptr = (WORD *)bob->Planes[i];
+ for(j=bob->PlaneSize,x=0; j>0; j-=2) x |= *sptr++;
+ if(x)
+ {
+ sptr = (WORD *)bob->Planes[i];
+ dptr = (WORD *)bob->Mask;
+ for(j=bob->PlaneSize; j>0; j-=2)
+ {
+ if(*dptr++ != *sptr++) goto notequal;
+ }
+ bob->PlanePick &= ~(1<<i); /* Plane nicht generieren */
+ bob->PlaneOnOff |= (1<<i); /* PlaneOnOffBit = 1 */
+ notequal: ;
+ }
+ else
+ {
+ bob->PlanePick &= ~(1<<i); /* Plane nicht generieren */
+ }
+ }
+}
+
+
+/****************************************************************************
+** Totalen Speicherplatzbedarf eines Bobs berechnen
+*/
+
+static LONG TotBobSize(struct MyBob *bob)
+{
+ LONG x,size;
+
+ size = sizeof(struct BobData);
+ if(outputflags & OF_BOBMASK) size += bob->PlaneSize;
+ x = bob->PlanePick;
+ while(x)
+ {
+ if(x&1) size += bob->PlaneSize;
+ x>>=1;
+ }
+ return size;
+}
+
+
+/****************************************************************************
+** Totalen Speicherplatzbedarf eines Sprites berechnen
+*/
+
+static LONG TotSpriteSize(struct MyBob *bob)
+{
+ LONG x,size;
+
+ size = sizeof(struct BobData);
+ for(x=0; x<bob->Width; x+=16)
+ {
+ size += 4*sizeof(LONG); /* 2x 1 LONG Koords, 1 LONG Endmarkierung */
+ size += bob->Height*2*4; /* 2 Sprites (attached) x 2 WORDs pro Zeile */
+ }
+ return size;
+}
+
+
+/****************************************************************************
+** Ein Bob ins File schreiben
+*/
+
+static void RawDumpBob(struct MyBob *bob)
+{
+ struct BobData bd;
+ long i;
+
+ bd.Width = bob->Width;
+ bd.Height = bob->Height;
+ bd.X0 = bob->X0;
+ bd.Y0 = bob->Y0;
+ bd.CollX0 = bob->CollX0-bob->X0;
+ bd.CollY0 = bob->CollY0-bob->Y0;
+ bd.CollX1 = bob->CollX1-bob->X0;
+ bd.CollY1 = bob->CollY1-bob->Y0;
+ bd.PlanePick = bob->PlanePick;
+ bd.PlaneOnOff = bob->PlaneOnOff;
+ bd.Flags = bob->Flags & (~BOB_PRIVATEMASK);
+ bd.WordSize = bob->BytesPerRow/2+1;
+ bd.PlaneSize = bob->PlaneSize;
+ bd.TotalSize = TotBobSize(bob);
+ MyWrite(&bd,sizeof(bd));
+
+ if(outputflags & OF_BOBMASK)
+ {
+ MyWrite(bob->Mask,bob->PlaneSize);
+ }
+
+ for(i=0; i<bob->Depth; ++i)
+ {
+ if(bob->PlanePick&(1<<i)) MyWrite(bob->Planes[i],bob->PlaneSize);
+ }
+}
+
+
+/****************************************************************************
+** count Bytes ab ptr als Assembler Source ausgeben (DC.L/DC.W)
+*/
+
+static void AsmHexDump(ULONG *ptr, long count)
+{
+ long i,rest;
+
+ rest = count%4; count /= 4;
+
+ for(i=1; count>0; count--,++i)
+ {
+ if(i==1) fputf("\tDC.L\t$%08lx",*ptr++);
+ else fputf(",$%08lx",*ptr++);
+
+ if((i==6) || (count==1))
+ {
+ fputf("\n"); i=0;
+ }
+ }
+ if(rest==2) fputf("\tDC.W\t$%04lx\n",*(UWORD *)ptr);
+ fputf("\n");
+}
+
+
+/****************************************************************************
+** Ein Bob als Assembler-Source ausgeben
+*/
+
+static void AsmDumpBob(struct MyBob *bob,WORD num)
+{
+ long i;
+
+ if(*(bob->SourceLabel))
+ fputf("\n\t*** Bob %ld : Header & Mask\n\n%s:\n",num,bob->SourceLabel);
+ else
+ fputf("\n\t*** Bob %ld : Header & Mask\n\n",num);
+
+ fputf("\tDC.W\t%ld,%ld,%ld,%ld,",bob->Width,bob->Height,bob->X0,bob->Y0);
+ fputf("%ld,%ld,%ld,%ld,",bob->CollX0-bob->X0,bob->CollY0-bob->Y0,
+ bob->CollX1-bob->X0,bob->CollY1-bob->Y0);
+ fputf("$%04lx,$%04lx,%ld,%ld,%ld\n",(bob->PlanePick<<8)+bob->PlaneOnOff,
+ bob->Flags,bob->BytesPerRow/2+1,bob->PlaneSize,TotBobSize(bob));
+ if(outputflags&OF_BOBMASK)
+ {
+ AsmHexDump((ULONG *)bob->Mask,bob->PlaneSize);
+ }
+
+ fputf("\t*** Bob %ld : %ld Planes\n\n",num,bob->Depth);
+ for(i=0; i<bob->Depth; ++i)
+ {
+ if(bob->PlanePick & (1<<i))
+ AsmHexDump((ULONG *)bob->Planes[i],bob->PlaneSize);
+ else
+ if(bob->PlaneOnOff & (1<<i))
+ fputf("\t; Plane %ld not generated (Plane is equal to mask)\n",i);
+ else
+ fputf("\t; Plane %ld not generated (Plane is empty)\n",i);
+ }
+}
+
+
+/****************************************************************************
+** Ein Sprite als Assembler-Source ausgeben
+*/
+
+static void AsmDumpSprite(struct MyBob *bob,WORD num)
+{
+ long x,y;
+ UWORD w1,w2;
+
+ fputf("\n\t*** Sprite %ld : %ld Attached Hardware sprites\n\n%s:\n",
+ num,(bob->Width-1)/16+1,bob->SourceLabel);
+
+ fputf("\tDC.W\t%ld,%ld,%ld,%ld,",bob->Width,bob->Height,bob->X0,bob->Y0);
+ fputf("%ld,%ld,%ld,%ld,",bob->CollX0-bob->X0,bob->CollY0-bob->Y0,
+ bob->CollX1-bob->X0,bob->CollY1-bob->Y0);
+ fputf("$%04lx,$%04lx,%ld,%ld,%ld\n",(bob->PlanePick<<8)+bob->PlaneOnOff,
+ bob->Flags,bob->BytesPerRow/2+1,bob->PlaneSize,TotSpriteSize(bob));
+
+ if(bob->Width>16)
+ fputf("\tDC.L\t%s.1,%s.2,%s.3,%s.4\n\n",bob->SourceLabel,
+ bob->SourceLabel,bob->SourceLabel,bob->SourceLabel);
+ else
+ fputf("\tDC.L\t%s.1,%s.2\n\n",bob->SourceLabel,bob->SourceLabel);
+
+ for(x=0; x < ((bob->Width-1)/16+1); ++x)
+ {
+ fputf("%s.%ld:\n",bob->SourceLabel,2*x+1);
+ fputf("\tDC.W\t$0000,$0000\t; Koordinaten\n");
+ for(y=0; y<bob->Height; ++y)
+ {
+ w1=*(UWORD *)(bob->Planes[0]+y*bob->BytesPerRow+2*x);
+ w2=*(UWORD *)(bob->Planes[1]+y*bob->BytesPerRow+2*x);
+ fputf("\tDC.W\t$%04lx,$%04lx\n",w1,w2);
+ }
+ fputf("\tDC.W\t$0000,$0000\t; End-Markierung\n\n\n");
+
+ fputf("%s.%ld:\n",bob->SourceLabel,2*x+2);
+ fputf("\tDC.W\t$0000,$0000\t; Koordinaten\n");
+ for(y=0; y<bob->Height; ++y)
+ {
+ w1=*(UWORD *)(bob->Planes[2]+y*bob->BytesPerRow+2*x);
+ w2=*(UWORD *)(bob->Planes[3]+y*bob->BytesPerRow+2*x);
+ fputf("\tDC.W\t$%04lx,$%04lx\n",w1,w2);
+ }
+ fputf("\tDC.W\t$0000,$0000\t; End-Markierung\n\n\n");
+ }
+}
+
+
+/****************************************************************************
+** Assembler-Source generieren
+*/
+
+static void GenerateAssemblerSource(void)
+{
+ WORD i;
+ struct DateStamp date;
+ char datebuf[32];
+
+ if(file=Open(outputname,MODE_NEWFILE))
+ {
+ DateStamp(&date);
+ ConvertDate(&date,datebuf);
+ fputf("* Source generated on %s by %s\n\n\tSECTION\t%s,DATA_C\n\n",datebuf,idstring,sectionname);
+
+ if(outputflags & OF_COLORTABLE)
+ {
+ fputf("\tXDEF\tColorPalette\nColorPalette:\n");
+ AsmHexDump((ULONG *)mainpalette,2*32);
+ }
+
+ if(outputflags & OF_BOBDATA)
+ {
+ if(outputflags & OF_GENERATEBOBS)
+ {
+ fputf("* Bob structure: WORD Width, Height, X0, Y0, Collision X0/Y0/X1/Y1\n"
+ "* BYTE PlanePick, PlaneOnOff\n"
+ "* WORD Flags, WORDSize+1, PlaneSize, TotalSize\n\n");
+ }
+
+ for(i=0; i<numbobs; ++i)
+ {
+ if((i%4)==0) fputf("\tXDEF\t%s",BobTable[i]->SourceLabel);
+ else fputf(",%s",BobTable[i]->SourceLabel);
+ if((i%4)==3) fputf("\n");
+ }
+ fputf("\n");
+
+ for(i=0; i<numbobs; ++i)
+ {
+ if(outputflags & OF_GENERATEBOBS)
+ AsmDumpBob(BobTable[i],i);
+ else
+ AsmDumpSprite(BobTable[i],i);
+ }
+ }
+
+ if(outputflags & OF_GENERATEBOBS)
+ {
+ fputf("\n\tDC.L\t-1\t; End of bob list\n\n");
+ }
+
+ fputf("\t; End of %s source generation.\n\n\tEND\n",idstring);
+ Close(file);
+ }
+ else ShowFileError(outputname);
+}
+
+
+/****************************************************************************
+** Raw-Daten generieren
+*/
+
+static void GenerateRawData(void)
+{
+ WORD i;
+
+ if(file=Open(outputname,MODE_NEWFILE))
+ {
+ if(outputflags & OF_COLORTABLE) MyWrite(mainpalette,2*32);
+
+ if(outputflags & OF_BOBDATA)
+ {
+ for(i=0; i<numbobs; ++i) RawDumpBob(BobTable[i]);
+ fputl(-1); /* Ende der Bob-Animation */
+ }
+ Close(file);
+ }
+ else ShowFileError(outputname);
+}
+
+
+/****************************************************************************
+** Objekt-Modul generieren
+*/
+
+static void GenerateObjectModule(void)
+{
+ long datasize,offset=0;
+ WORD i;
+
+ for(i=0,datasize=4; i<numbobs; ++i) datasize += TotBobSize(BobTable[i]);
+ datasize+=3; datasize >>=2;
+
+ if(file=Open(outputname,MODE_NEWFILE))
+ {
+ filesize=0;
+ fputl(HUNK_UNIT); fpuths(idstring);
+
+ if(outputflags & OF_COLORTABLE)
+ {
+ fputl(HUNK_NAME); fpuths(sectionname);
+ fputl(HUNK_DATA); fputl(64>>2);
+ MyWrite(mainpalette,2*32);
+ fputl(HUNK_EXT);
+ fputsym("ColorPalette",EXT_DEF);
+ fputl(0);
+ fputl(0);
+ fputl(HUNK_END);
+ }
+
+ if(outputflags & OF_BOBDATA)
+ {
+ fputl(HUNK_NAME); fpuths(sectionname);
+ fputl(HUNK_DATA|HUNKF_CHIP); fputl(datasize);
+
+ for(i=0; i<numbobs; ++i) RawDumpBob(BobTable[i]);
+ fputl(-1); /* Ende der Bob-Animation */
+ if(filesize&3) fputw(0x9876); /* Pad to longword */
+ fputl(HUNK_EXT);
+ for(i=0; i<numbobs; ++i)
+ {
+ if(*(BobTable[i]->SourceLabel)) /* Nur Symbols mit Länge >0 */
+ {
+ fputsym(BobTable[i]->SourceLabel,EXT_DEF);
+ fputl(offset);
+ }
+ offset += TotBobSize(BobTable[i]);
+ }
+ fputl(0);
+ fputl(HUNK_END);
+ }
+ Close(file);
+ }
+ else ShowFileError(outputname);
+}
+
+
+/****************************************************************************
+** Assembler-Include-File der Bob-Offsets generieren
+*/
+
+static void GenerateHeaderFile(void)
+{
+ char name[256],datebuf[32];
+ struct DateStamp date;
+ LONG len,offset=0;
+
+ if(!strnicmp(outputname,"/DISK/",6))
+ strcpy(name,outputname+6); /* '/DISK/'-Anfang ignorieren */
+ else
+ strcpy(name,outputname);
+
+ len=strlen(name);
+ if(name[len-2]=='.') name[len-1]='i';
+ else
+ {
+ name[len] = '.' ;
+ name[len+1] = 'i' ;
+ name[len+2] = '\0';
+ }
+
+ if(file=Open(name,MODE_NEWFILE))
+ {
+ DateStamp(&date);
+ ConvertDate(&date,datebuf);
+ fputf("* Header file generated on %s by %s\n",datebuf,idstring);
+
+ if(outputflags & OF_COLORTABLE) offset=2*32;
+ if(outputflags & OF_BOBDATA)
+ {
+ LONG i;
+ char sizelabel[100];
+
+ for(i=0; i<numbobs; ++i)
+ {
+ if(*(BobTable[i]->SourceLabel)) /* Nur Symbols mit Länge >0 */
+ {
+ char *sym=BobTable[i]->SourceLabel;
+ if(BobTable[i]->Flags & BODF_ANIMKEY) fputf("\n");
+ fputf("%s:",sym);
+ if(strlen(sym)<7) Write(file,"\t",1);
+ if(strlen(sym)<15) Write(file,"\t",1);
+ else Write(file," ",1);
+ fputf("EQU\t%ld\n",offset);
+ }
+ offset += TotBobSize(BobTable[i]);
+ }
+ strcpy(sizelabel,LabelGadgetSIBuff);
+ if(!strnicmp(sizelabel+strlen(sizelabel)-3,"%ld",3))
+ sizelabel[strlen(sizelabel)-3]='\0';
+ fputf("\n%s_FILESIZE:\tEQU\t%ld\n",sizelabel,offset+4);
+ }
+ Close(file);
+ }
+ else ShowFileError(name);
+}
+
+
+/****************************************************************************
+** outputflags neu berechnen aus den Gadget-Werten
+*/
+
+static void GetOutputFlags(void)
+{
+ outputflags = 0;
+
+ if(GenerateBobsGadget.Flags & SELECTED) outputflags |= OF_GENERATEBOBS;
+ else outputflags |= OF_GENERATESPRITES;
+
+ if(AssemGadget.Flags & SELECTED) outputflags |= OF_ASSEMBLER;
+ else if(ObjectGadget.Flags & SELECTED) outputflags |= OF_OBJECT;
+ else outputflags |= OF_RAWDATA;
+
+ if(ColorGadget.Flags & SELECTED) outputflags |= OF_COLORTABLE;
+ if(BobDataGadget.Flags & SELECTED) outputflags |= OF_BOBDATA;
+ if(MaskGadget.Flags & SELECTED) outputflags |= OF_BOBMASK;
+}
+
+
+/****************************************************************************
+** Gadget-Flags gemäss outputflags setzen
+*/
+
+static void SetOutputFlags(void)
+{
+ if(outputflags & OF_GENERATEBOBS)
+ {
+ GenerateBobsGadget.Flags |= SELECTED;
+ }
+ else
+ {
+ GenerateBobsGadget.Flags &= ~SELECTED;
+ }
+
+ if(outputflags & OF_GENERATESPRITES)
+ {
+ GenerateSpritesGadget.Flags |= SELECTED;
+ MaskGadget.Flags &= ~SELECTED;
+ MaskGadget.Flags |= GADGDISABLED;
+ }
+ else
+ {
+ GenerateSpritesGadget.Flags &= ~SELECTED;
+ MaskGadget.Flags |= SELECTED;
+ MaskGadget.Flags &= ~GADGDISABLED;
+ }
+
+
+ if(outputflags & OF_ASSEMBLER) AssemGadget.Flags |= SELECTED;
+ else AssemGadget.Flags &= ~SELECTED;
+
+ if(outputflags & OF_OBJECT) ObjectGadget.Flags |= SELECTED;
+ else ObjectGadget.Flags &= ~SELECTED;
+
+ if(outputflags & OF_RAWDATA)
+ {
+ RawDataGadget.Flags |= SELECTED;
+ SectionNameGadget.Flags |= GADGDISABLED;
+ }
+ else
+ {
+ RawDataGadget.Flags &= ~SELECTED;
+ SectionNameGadget.Flags &= ~GADGDISABLED;
+ }
+
+ if(outputflags & OF_COLORTABLE) ColorGadget.Flags |= SELECTED;
+ else ColorGadget.Flags &= ~SELECTED;
+
+ if(outputflags & OF_BOBDATA) BobDataGadget.Flags |= SELECTED;
+ else BobDataGadget.Flags &= ~SELECTED;
+
+ if(outputflags & OF_BOBMASK) MaskGadget.Flags |= SELECTED;
+ else MaskGadget.Flags &= ~SELECTED;
+}
+
+
+/****************************************************************************
+** Menuitem oder ARexx-Kommando: Generate code
+*/
+
+void GenerateCodeFunc()
+{
+ int flag;
+
+ LockWindows();
+
+ if(outputflags == 0)
+ outputflags = OF_RAWDATA | OF_OBJECT | OF_BOBDATA | OF_BOBMASK;
+
+ if(arexxflag)
+ {
+ strcpy(outputname,arexxfilename);
+ flag = 1;
+ }
+ else
+ {
+ struct Window *w;
+ struct IntuiMessage *msg;
+
+ NewWindowStructure1.Screen = mainscreen;
+ FileNameGadgetSInfo.Buffer = outputname;
+ SectionNameGadgetSInfo.Buffer = sectionname;
+
+ SetOutputFlags();
+
+ if(w=OpenWindow(&NewWindowStructure1))
+ {
+ PrintIText(w->RPort,&IntuiTextList1,0L,0L);
+ flag=0;
+ do
+ {
+ WaitPort(w->UserPort);
+ msg=(struct IntuiMessage *)GetMsg(w->UserPort);
+ if(msg->Class == CLOSEWINDOW)
+ {
+ flag = -1;
+ }
+ else if(msg->Class == GADGETUP)
+ {
+ if(msg->IAddress == (APTR)&OKGadget)
+ {
+ flag = 1;
+ }
+ else if(msg->IAddress == (APTR)&CancelGadget)
+ {
+ flag = -1;
+ }
+ }
+ else if(msg->Class == GADGETDOWN)
+ {
+ if(msg->IAddress == (APTR)&GenerateBobsGadget)
+ {
+ SelectGadget(w,&GenerateBobsGadget);
+ DeselectGadget(w,&GenerateSpritesGadget);
+ OnGadget(&MaskGadget,w,0);
+ OnGadget(&ObjectGadget,w,0);
+ OnGadget(&RawDataGadget,w,0);
+ SelectGadget(w,&MaskGadget);
+ }
+ else if(msg->IAddress == (APTR)&GenerateSpritesGadget)
+ {
+ SelectGadget(w,&GenerateSpritesGadget);
+ DeselectGadget(w,&GenerateBobsGadget);
+ DeselectGadget(w,&MaskGadget);
+ SelectGadget(w,&AssemGadget);
+ OffGadget(&MaskGadget,w,0);
+ OffGadget(&ObjectGadget,w,0);
+ OffGadget(&RawDataGadget,w,0);
+ }
+ else if(msg->IAddress == (APTR)&AssemGadget)
+ {
+ SelectGadget(w,&AssemGadget);
+ DeselectGadget(w,&ObjectGadget);
+ DeselectGadget(w,&RawDataGadget);
+ OnGadget(&SectionNameGadget,w,0);
+ }
+ else if(msg->IAddress == (APTR)&ObjectGadget)
+ {
+ DeselectGadget(w,&AssemGadget);
+ SelectGadget(w,&ObjectGadget);
+ DeselectGadget(w,&RawDataGadget);
+ OnGadget(&SectionNameGadget,w,0);
+ }
+ else if(msg->IAddress == (APTR)&RawDataGadget)
+ {
+ DeselectGadget(w,&AssemGadget);
+ DeselectGadget(w,&ObjectGadget);
+ SelectGadget(w,&RawDataGadget);
+ OffGadget(&SectionNameGadget,w,0);
+ }
+ }
+ } while(!flag);
+
+ CloseWindow(w);
+ GetOutputFlags();
+ }
+ else
+ {
+ ShowMonoReq2("Can't open window!");
+ goto error;
+ }
+ } /* not ARexx */
+
+ if(flag>0) /* Falls OK-Gadget angeklickt */
+ {
+ int i;
+
+ for(i=0; i<numbobs; ++i)
+ {
+ CalculateMask(BobTable[i]);
+ CalculatePlanePick(BobTable[i]);
+ }
+
+ if(outputflags & OF_ASSEMBLER) GenerateAssemblerSource();
+ else if(outputflags & OF_OBJECT) GenerateObjectModule();
+ else if(outputflags & OF_RAWDATA) GenerateRawData();
+
+ if(outputflags & OF_RAWDATA) GenerateHeaderFile();
+ }
+
+error:
+
+ UnLockWindows();
+}
+
diff --git a/GenerateWindow.h b/GenerateWindow.h
new file mode 100644
index 0000000..80cb9e8
--- /dev/null
+++ b/GenerateWindow.h
@@ -0,0 +1,651 @@
+
+static UBYTE UNDOBUFFER[80];
+
+static SHORT BorderVectors3[] = {
+ 0,0,
+ 67,0,
+ 67,86,
+ 0,86,
+ 0,0
+};
+static struct Border Border3 = {
+ 138,12,
+ 3,0,JAM1,
+ 5,
+ BorderVectors3,
+ NULL
+};
+
+static SHORT BorderVectors2[] = {
+ 0,0,
+ 61,0,
+ 61,86,
+ 0,86,
+ 0,0
+};
+static struct Border Border2 = {
+ 4,12,
+ 3,0,JAM1,
+ 5,
+ BorderVectors2,
+ &Border3
+};
+
+static SHORT BorderVectors1[] = {
+ 0,0,
+ 67,0,
+ 67,86,
+ 0,86,
+ 0,0
+};
+static struct Border Border1 = {
+ 68,12,
+ 3,0,JAM1,
+ 5,
+ BorderVectors1,
+ &Border2
+};
+
+static struct Gadget Gadget13 = {
+ NULL,
+ 0,0,
+ 1,1,
+ GADGHBOX+GADGHIMAGE,
+ NULL,
+ BOOLGADGET,
+ (APTR)&Border1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors4[] = {
+ 0,0,
+ 99,0,
+ 99,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border4 = {
+ -1,-1,
+ 31,0,JAM1,
+ 5,
+ BorderVectors4,
+ NULL
+};
+
+static struct IntuiText IText1 = {
+ 1,0,JAM1,
+ 26,3,
+ NULL,
+ "CANCEL",
+ NULL
+};
+
+static struct Gadget CancelGadget = {
+ &Gadget13,
+ -102,-16,
+ 98,13,
+ GRELBOTTOM+GRELRIGHT,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border4,
+ NULL,
+ &IText1,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors5[] = {
+ 0,0,
+ 99,0,
+ 99,14,
+ 0,14,
+ 0,0
+};
+static struct Border Border5 = {
+ -1,-1,
+ 31,0,JAM1,
+ 5,
+ BorderVectors5,
+ NULL
+};
+
+static struct IntuiText IText2 = {
+ 1,0,JAM1,
+ 26,3,
+ NULL,
+ "Do it!",
+ NULL
+};
+
+static struct Gadget OKGadget = {
+ &CancelGadget,
+ 5,-16,
+ 98,13,
+ GRELBOTTOM,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border5,
+ NULL,
+ &IText2,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static UBYTE FileNameGadgetSIBuff[80] =
+ "RAM:BobTest.o";
+static struct StringInfo FileNameGadgetSInfo = {
+ FileNameGadgetSIBuff,
+ UNDOBUFFER,
+ 0,
+ 80,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ NULL
+};
+
+static SHORT BorderVectors6[] = {
+ 0,0,
+ 201,0,
+ 201,20,
+ 0,20,
+ 0,1
+};
+static struct Border Border6 = {
+ -1,-11,
+ 3,0,JAM1,
+ 5,
+ BorderVectors6,
+ NULL
+};
+
+static struct Gadget FileNameGadget = {
+ &OKGadget,
+ 5,135,
+ 200,9,
+ SELECTED,
+ RELVERIFY,
+ STRGADGET,
+ (APTR)&Border6,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&FileNameGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static UBYTE SectionNameGadgetSIBuff[80] =
+ "BobTestData";
+static struct StringInfo SectionNameGadgetSInfo = {
+ SectionNameGadgetSIBuff,
+ UNDOBUFFER,
+ 0,
+ 80,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ NULL
+};
+
+static SHORT BorderVectors7[] = {
+ 0,0,
+ 201,0,
+ 201,20,
+ 0,20,
+ 0,1
+};
+static struct Border Border7 = {
+ -1,-11,
+ 3,0,JAM1,
+ 5,
+ BorderVectors7,
+ NULL
+};
+
+static struct Gadget SectionNameGadget = {
+ &FileNameGadget,
+ 5,112,
+ 200,9,
+ NULL,
+ RELVERIFY,
+ STRGADGET,
+ (APTR)&Border7,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&SectionNameGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors8[] = {
+ 0,0,
+ 57,0,
+ 57,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border8 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors8,
+ NULL
+};
+
+static struct IntuiText IText4 = {
+ 1,0,JAM1,
+ 12,11,
+ NULL,
+ "Mask",
+ NULL
+};
+
+static struct IntuiText IText3 = {
+ 1,0,JAM1,
+ 16,2,
+ NULL,
+ "Bob",
+ &IText4
+};
+
+static struct Gadget MaskGadget = {
+ &SectionNameGadget,
+ 144,75,
+ 56,20,
+ NULL,
+ TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border8,
+ NULL,
+ &IText3,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors9[] = {
+ 0,0,
+ 57,0,
+ 57,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border9 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors9,
+ NULL
+};
+
+static struct IntuiText IText6 = {
+ 1,0,JAM1,
+ 12,11,
+ NULL,
+ "Data",
+ NULL
+};
+
+static struct IntuiText IText5 = {
+ 1,0,JAM1,
+ 16,2,
+ NULL,
+ "Bob",
+ &IText6
+};
+
+static struct Gadget BobDataGadget = {
+ &MaskGadget,
+ 144,51,
+ 56,20,
+ NULL,
+ TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border9,
+ NULL,
+ &IText5,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors10[] = {
+ 0,0,
+ 57,0,
+ 57,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border10 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors10,
+ NULL
+};
+
+static struct IntuiText IText8 = {
+ 1,0,JAM1,
+ 8,11,
+ NULL,
+ "Table",
+ NULL
+};
+
+static struct IntuiText IText7 = {
+ 1,0,JAM1,
+ 8,2,
+ NULL,
+ "Color",
+ &IText8
+};
+
+static struct Gadget ColorGadget = {
+ &BobDataGadget,
+ 144,27,
+ 56,20,
+ NULL,
+ TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border10,
+ NULL,
+ &IText7,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors11[] = {
+ 0,0,
+ 57,0,
+ 57,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border11 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors11,
+ NULL
+};
+
+static struct IntuiText IText10 = {
+ 1,0,JAM1,
+ 4,11,
+ NULL,
+ "Module",
+ NULL
+};
+
+static struct IntuiText IText9 = {
+ 1,0,JAM1,
+ 4,2,
+ NULL,
+ "Object",
+ &IText10
+};
+
+static struct Gadget ObjectGadget = {
+ &ColorGadget,
+ 74,51,
+ 56,20,
+ NULL,
+ GADGIMMEDIATE,
+ BOOLGADGET,
+ (APTR)&Border11,
+ NULL,
+ &IText9,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors12[] = {
+ 0,0,
+ 57,0,
+ 57,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border12 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors12,
+ NULL
+};
+
+static struct IntuiText IText12 = {
+ 1,0,JAM1,
+ 12,11,
+ NULL,
+ "Data",
+ NULL
+};
+
+static struct IntuiText IText11 = {
+ 1,0,JAM1,
+ 16,2,
+ NULL,
+ "Raw",
+ &IText12
+};
+
+static struct Gadget RawDataGadget = {
+ &ObjectGadget,
+ 74,75,
+ 56,20,
+ NULL,
+ GADGIMMEDIATE,
+ BOOLGADGET,
+ (APTR)&Border12,
+ NULL,
+ &IText11,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors13[] = {
+ 0,0,
+ 57,0,
+ 57,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border13 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors13,
+ NULL
+};
+
+static struct IntuiText IText14 = {
+ 1,0,JAM1,
+ 4,11,
+ NULL,
+ "Source",
+ NULL
+};
+
+static struct IntuiText IText13 = {
+ 1,0,JAM1,
+ 8,2,
+ NULL,
+ "Assem",
+ &IText14
+};
+
+static struct Gadget AssemGadget = {
+ &RawDataGadget,
+ 74,27,
+ 56,20,
+ NULL,
+ GADGIMMEDIATE,
+ BOOLGADGET,
+ (APTR)&Border13,
+ NULL,
+ &IText13,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors14[] = {
+ 0,0,
+ 53,0,
+ 53,33,
+ 0,33,
+ 0,0
+};
+static struct Border Border14 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors14,
+ NULL
+};
+
+static struct IntuiText IText15 = {
+ 1,0,JAM1,
+ 2,12,
+ NULL,
+ "Sprite",
+ NULL
+};
+
+static struct Gadget GenerateSpritesGadget = {
+ &AssemGadget,
+ 9,63,
+ 52,32,
+ NULL,
+ GADGIMMEDIATE,
+ BOOLGADGET,
+ (APTR)&Border14,
+ NULL,
+ &IText15,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors15[] = {
+ 0,0,
+ 53,0,
+ 53,33,
+ 0,33,
+ 0,0
+};
+static struct Border Border15 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors15,
+ NULL
+};
+
+static struct IntuiText IText16 = {
+ 1,0,JAM1,
+ 14,12,
+ NULL,
+ "Bob",
+ NULL
+};
+
+static struct Gadget GenerateBobsGadget = {
+ &GenerateSpritesGadget,
+ 9,27,
+ 52,32,
+ NULL,
+ GADGIMMEDIATE,
+ BOOLGADGET,
+ (APTR)&Border15,
+ NULL,
+ &IText16,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+#define GadgetList1 GenerateBobsGadget
+
+static struct IntuiText IText21 = {
+ 3,0,JAM1,
+ 83,15,
+ NULL,
+ "Mode:",
+ NULL
+};
+
+static struct IntuiText IText20 = {
+ 3,0,JAM1,
+ 53,104,
+ NULL,
+ "Section Name:",
+ &IText21
+};
+
+static struct IntuiText IText19 = {
+ 3,0,JAM1,
+ 141,15,
+ NULL,
+ "Options:",
+ &IText20
+};
+
+static struct IntuiText IText18 = {
+ 3,0,JAM1,
+ 16,15,
+ NULL,
+ "Type:",
+ &IText19
+};
+
+static struct IntuiText IText17 = {
+ 3,0,JAM1,
+ 69,127,
+ NULL,
+ "Filename:",
+ &IText18
+};
+
+#define IntuiTextList1 IText17
+
+static struct NewWindow NewWindowStructure1 = {
+ 50,21,
+ 210,165,
+ 0,1,
+ GADGETDOWN+GADGETUP+CLOSEWINDOW,
+ WINDOWDRAG+WINDOWCLOSE+ACTIVATE+RMBTRAP+NOCAREREFRESH,
+ &GenerateBobsGadget,
+ NULL,
+ " Generate Code ",
+ NULL,
+ NULL,
+ 5,5,
+ (UWORD)-1,(UWORD)-1,
+ CUSTOMSCREEN
+};
diff --git a/Get.c b/Get.c
new file mode 100644
index 0000000..d99ca13
--- /dev/null
+++ b/Get.c
@@ -0,0 +1,268 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** Get.c - Bob aus einem Bild ausschneiden
+**
+** 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 <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <graphics/rastport.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+extern struct MyBob *BobTable[];
+extern struct Screen *mainscreen,*picturescreen;
+extern struct Window *mainwindow,*toolwindow,*picturewindow;
+extern WORD numbobs,actbobnum;
+extern struct Gadget AutoSizeGadget;
+extern char LabelGadgetSIBuff[];
+
+static int x0,x1,y0,y1;
+
+/****************************************************************************
+** Der Benutzer kann auf dem Picture-Screen ein Bob ausschneiden,
+** die Koordinaten werden in x0/y0/x1/y1 gespeichert
+*/
+
+static BOOL CutBob(BOOL multiflag)
+{
+ struct IntuiMessage *msg;
+ BOOL looping=TRUE, okflag=FALSE;
+
+ x0 = -1; /* Startwerte, gegen MultiCutNoMove-Bug */
+ x1 = picturewindow->MouseX;
+ y1 = picturewindow->MouseY;
+ DrawCross(picturescreen,x1,y1);
+
+ ScreenToFront(picturescreen);
+ ActivateWindow(picturewindow);
+ ModifyIDCMP(picturewindow,MOUSEMOVE+MOUSEBUTTONS);
+ do
+ {
+ WaitPort(picturewindow->UserPort);
+ while(msg = (struct IntuiMessage *)GetMsg(picturewindow->UserPort))
+ {
+ if(msg->Class == MOUSEBUTTONS)
+ {
+ switch(msg->Code)
+ {
+ case SELECTDOWN:
+ x0 = x1;
+ y0 = y1;
+ DrawCross(picturescreen,x0,y0);
+ break;
+
+ case SELECTUP:
+ okflag=TRUE; /* hier kein break! */
+
+ default:
+ looping=FALSE;
+ break;
+ }
+ break;
+ }
+ else /* Muss MOUSEMOVE sein */
+ {
+ DrawCross(picturescreen,x1,y1);
+ x1 = msg->MouseX;
+ if(x1>=picturescreen->Width) x1=picturescreen->Width-1;
+ y1 = msg->MouseY;
+ if(x0>=0)
+ {
+ /* if((x1-x0) > MAXBOBWIDTH) x1=x0+MAXBOBWIDTH;
+ if((x0-x1) > MAXBOBWIDTH) x1=x0-MAXBOBWIDTH;
+ if((y1-y0) > MAXBOBHEIGHT) y1=y0+MAXBOBHEIGHT;
+ if((y0-y1) > MAXBOBHEIGHT) y1=y0-MAXBOBHEIGHT;
+ */ }
+ DrawCross(picturescreen,x1,y1);
+ }
+ ReplyMsg((struct Message *)msg);
+ }
+ } while(looping);
+
+ DrawCross(picturescreen,x1,y1);
+ DrawCross(picturescreen,x0,y0);
+ ModifyIDCMP(picturewindow,0);
+
+ if(!multiflag) /* Falls nur 1 Bob zu cutten: mainscreen hervorbringen */
+ {
+ ScreenToFront(mainscreen);
+ ActivateWindow(toolwindow?toolwindow:mainwindow);
+ }
+
+ if(x0>x1) { WORD dummy=x0; x0=x1; x1=dummy; }
+ if(y0>y1) { WORD dummy=y0; y0=y1; y1=dummy; }
+
+ return okflag;
+}
+
+/****************************************************************************
+** Bob an der gewünschten Stelle des Bildes ausschneiden
+*/
+
+BOOL GetBob(int x,int y,int w,int h)
+{
+ BOOL success = FALSE;
+
+ if(picturescreen == NULL) return FALSE; /* Nix auszuschneiden! */
+
+ if(w<0)
+ {
+ x += w; w = -w;
+ }
+
+ if(h<0)
+ {
+ y += h; h = -h;
+ }
+
+ if(AutoSizeGadget.Flags & SELECTED)
+ {
+ int x1 = x+w-1, y1 = y+h-1;
+
+ while((x<x1) && (w>0))
+ {
+ int i;
+
+ for(i=y; i<y1; i++)
+ {
+ if(ReadPixel(&picturescreen->RastPort,x,i))
+ goto xlgot;
+ }
+ x++; w--;
+ }
+ xlgot:
+
+ while((y<y1) && (h>0))
+ {
+ int i;
+
+ for(i=x; i<x1; i++)
+ {
+ if(ReadPixel(&picturescreen->RastPort,i,y))
+ goto ylgot;
+ }
+ y++; h--;
+ }
+ ylgot:
+
+ while(w>0)
+ {
+ int i;
+
+ for(i=y; i<y1; i++)
+ {
+ if(ReadPixel(&picturescreen->RastPort,x1-1,i))
+ goto xhgot;
+ }
+ x1--; w--;
+ }
+ xhgot:
+
+ while(h>0)
+ {
+ int i;
+
+ for(i=x; i<x1; i++)
+ {
+ if(ReadPixel(&picturescreen->RastPort,i,y1-1))
+ goto yhgot;
+ }
+ y1--; h--;
+ }
+ yhgot: ;
+
+ } /* if(autosize) */
+
+ if((w>0) && (h>0))
+ {
+ struct BitMap *tmpmap;
+
+ if(tmpmap=MakeBitMap(w,h,picturescreen->BitMap.Depth))
+ {
+ struct MyBob *bob;
+
+ BltBitMap(&(picturescreen->BitMap),x,y,tmpmap,0,0,w,h,0xc0,0xff,0);
+ if(bob=BitMapToBob(BobTable[actbobnum],tmpmap,w))
+ {
+ if(numbobs<MAXNUMBOBS)
+ {
+ if(BobTable[actbobnum]) /* Falls Bob existiert */
+ {
+ FreeBob(BobTable[actbobnum]);
+ }
+ else /* Neues Bob an Tabellenende anhängen */
+ {
+ numbobs++;
+ sprintf(bob->SourceLabel,LabelGadgetSIBuff,actbobnum);
+ RefreshBobNum(); /* Prop-Gadget anpassen */
+ }
+ BobTable[actbobnum] = bob;
+ ShowBob(bob);
+ success = TRUE;
+ }
+ else ShowMonoReq2("Too many bobs!");
+ }
+ else ShowMonoReq2("Not enough memory for this bob");
+ MyFreeBitMap(tmpmap);
+ }
+ else ShowMonoReq2("Not enough memory for tmp BitMap");
+ }
+
+ return success;
+}
+
+/****************************************************************************
+** Aus Bild ausschneiden und Bob generieren
+*/
+
+static BOOL GetOneBob(BOOL multiflag)
+{
+ if(picturescreen)
+ {
+ if(CutBob(multiflag))
+ {
+ return GetBob(x0,y0,x1-x0+1,y1-y0+1);
+ }
+ else /* CutBob()==0: mit rechter Maustaste abgebrochen */
+ {
+ if(multiflag)
+ {
+ ScreenToFront(mainscreen);
+ ActivateWindow(toolwindow?toolwindow:mainwindow);
+ }
+ else ShowMonoReq2("Operation cancelled");
+ }
+ }
+ else ShowMonoReq2("No picture loaded, use 'Load IFF'");
+
+ return FALSE;
+}
+
+/****************************************************************************
+** Ein Bob ausschneiden
+*/
+
+void GetBobFunc()
+{
+ GetOneBob(FALSE);
+}
+
+/****************************************************************************
+** Mehrere Bobs ausschneiden
+*/
+
+void GetMultiFunc()
+{
+ while(GetOneBob(TRUE)) actbobnum++;
+ if(actbobnum>0) --actbobnum;
+ RefreshBobNum();
+}
+
diff --git a/HunkDefs.h b/HunkDefs.h
new file mode 100644
index 0000000..4fa2197
--- /dev/null
+++ b/HunkDefs.h
@@ -0,0 +1,27 @@
+#define HUNK_UNIT 999
+#define HUNK_NAME 1000
+#define HUNK_CODE 1001
+#define HUNK_DATA 1002
+#define HUNK_BSS 1003
+#define HUNK_RELOC32 1004
+#define HUNK_RELOC16 1005
+#define HUNK_RELOC8 1006
+#define HUNK_EXT 1007
+#define HUNK_SYMBOL 1008
+#define HUNK_DEBUG 1009
+#define HUNK_END 1010
+#define HUNK_HEADER 1011
+#define HUNK_OVERLAY 1013
+#define HUNK_BREAK 1014
+
+#define HUNKF_CHIP 0x40000000
+
+#define EXT_SYMB 0
+#define EXT_DEF 0x01000000
+#define EXT_ABS 0x02000000
+#define EXT_RES 0x03000000
+#define EXT_REF32 0x81000000
+#define EXT_COMMON 0x82000000
+#define EXT_REF16 0x83000000
+#define EXT_REF8 0x84000000
+
diff --git a/IFFAnim.c b/IFFAnim.c
new file mode 100644
index 0000000..8bb5e4d
--- /dev/null
+++ b/IFFAnim.c
@@ -0,0 +1,155 @@
+/*
+** Bobi - The Ultimate Amiga Bob Manipulator
+**
+** IFFAnim.c - Bobs aus einer IFF-Animation ausschneiden
+**
+** 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 <libraries/iff.h>
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/dos.h>
+#include <proto/intuition.h>
+
+#include "Bobi.h"
+#include "ByteMap.h"
+
+extern struct Screen *mainscreen;
+extern WORD actbobnum;
+
+static char AnimPath[128];
+static char AnimName[80];
+
+/****************************************************************************
+** Ein Bob aus einer Animation ausschneiden
+*/
+
+static BOOL GetNextBob(struct BitMap *bim)
+{
+ struct ByteMap *bym;
+ struct MyBob *bob;
+ BOOL success = FALSE;
+ WORD width;
+
+ if(bym=MakeByteMap((WORD)(bim->BytesPerRow*8),bim->Rows))
+ {
+ BitMapToByteMap(bim,bym);
+ if(!AutoResizeByteMap(bym))
+ {
+ bym->Width=1; bym->Height=1;
+ }
+
+ if(bim=MakeBitMap(bym->Width,bym->Height,(WORD)bim->Depth))
+ {
+ ByteMapToBitMap(bym,bim);
+ width = bym->Width;
+ FreeByteMap(bym);
+ if(bob=BitMapToBob(0,bim,width))
+ {
+ InsertBob(bob,(WORD)(actbobnum++));
+ success = TRUE;
+ }
+ else ShowMonoReq2("Not enough memory to insert bob");
+ MyFreeBitMap(bim);
+ }
+ else
+ {
+ ShowMonoReq2("Not enough memory to insert bob");
+ FreeByteMap(bym);
+ }
+ }
+ else ShowMonoReq2("Not enough memory to insert bob");
+
+ return success;
+}
+
+/****************************************************************************
+** IFF-Animation laden und ins Bobi-Format umwandeln
+*/
+
+void LoadIFFAnimFunc()
+{
+ ULONG *ifffile,*formptr;
+ struct IFFL_BMHD *bmhd;
+ LONG count;
+ char *path;
+ struct NewScreen ns;
+ struct Screen *s1, *s2=NULL;
+ UWORD palette[128];
+
+ LockWindows();
+ if (path = FileRequest("Load IFF animation from Disk", "LOAD", AnimPath, AnimName))
+ {
+ if (ifffile = (ULONG *)IFFL_OpenIFF(path, IFFL_MODE_READ))
+ {
+ if(ifffile[2] == ID_ANIM)
+ {
+ formptr = ifffile+3;
+
+ if(bmhd = IFFL_GetBMHD(formptr))
+ {
+ ClearMem(&ns,sizeof(ns));
+ ns.Width = (bmhd->w > 64) ? bmhd->w : 64;
+ ns.Height = (bmhd->h > 64) ? bmhd->h : 64;
+ ns.Depth = (bmhd->nPlanes > 5) ? bmhd->nPlanes : 5;
+ ns.ViewModes = IFFL_GetViewModes(formptr);
+ ns.Type = CUSTOMSCREEN|SCREENQUIET|SCREENBEHIND;
+
+ if((s1 = OpenScreen(&ns)) && (s2 = OpenScreen(&ns)))
+ {
+ count = IFFL_GetColorTab(formptr,(WORD *)palette);
+ if(count>32) count = 32;
+ LoadRGB4(&s1->ViewPort,palette,count);
+ LoadRGB4(&s2->ViewPort,palette,count);
+
+ if(IFFL_DecodePic(formptr,&s1->BitMap))
+ {
+ ClearAll();
+ ScreenToFront(s1);
+ IFFL_DecodePic(formptr,&s2->BitMap);
+ formptr = IFFL_FindChunk(formptr,0L); /* 1st DLTA */
+ if(GetNextBob(&s1->BitMap))
+ {
+ while(*formptr==ID_FORM)
+ {
+ LONG tmp;
+ if(!IFFL_ModifyFrame(formptr,&s2->BitMap))
+ {
+ ShowIFFError("Bad ANIM format");
+ break;
+ }
+ tmp=(LONG)s2; s2=s1; s1=(struct Screen *)tmp;
+ ScreenToFront(s1);
+ if(!GetNextBob(&(s1->BitMap))) break;
+ formptr=IFFL_FindChunk(formptr,0L);
+ }
+ }
+ ScreenToFront(mainscreen);
+ }
+ else ShowIFFError("Error decoding picture");
+ }
+ else ShowMonoReq2("Can't open anim screens");
+ if(s1) CloseScreen(s1);
+ if(s2) CloseScreen(s2);
+ }
+ else ShowIFFError("Mangled IFF ANIM");
+ }
+ else
+ {
+ char buf[150];
+ sprintf(buf,"'%s':\nNot an IFF ANIM file!",path);
+ ShowMonoReq2(buf);
+ }
+ IFFL_CloseIFF(ifffile);
+ }
+ else ShowIFFError(path);
+
+ } /* if(FileRequest()) */
+
+ UnLockWindows();
+}
+
diff --git a/IFFError.c b/IFFError.c
new file mode 100644
index 0000000..e0146c2
--- /dev/null
+++ b/IFFError.c
@@ -0,0 +1,50 @@
+#include <libraries/iff.h>
+#include "Bobi.h"
+
+void ShowIFFError(char *text1)
+{
+ char buf[250];
+ char *text2;
+
+ switch(IFFL_IFFError())
+ {
+ case IFFL_ERROR_OPEN: text2 = "Can't open file";
+ break;
+
+ case IFFL_ERROR_READ: text2 = "Read error";
+ break;
+
+ case IFFL_ERROR_NOMEM: text2 = "Not enough memory";
+ break;
+
+ case IFFL_ERROR_NOTIFF: text2 = "Not an IFF file";
+ break;
+
+ case IFFL_ERROR_WRITE: text2 = "Error writing file";
+ break;
+
+ case IFFL_ERROR_NOILBM: text2 = "Not a picture";
+ break;
+
+ case IFFL_ERROR_NOBMHD: text2 = "No BitMapHeader found";
+ break;
+
+ case IFFL_ERROR_NOBODY: text2 = "No BODY chunk found";
+ break;
+
+ case IFFL_ERROR_BADCOMPRESSION: text2 = "Unknown compression type";
+ break;
+
+ case IFFL_ERROR_NOANHD: text2 = "No ANHD chunk found";
+ break;
+
+ case IFFL_ERROR_NODLTA: text2 = "No DLTA chunk found";
+ break;
+
+ default: text2 = "Unknown IFF error";
+ break;
+ }
+
+ sprintf(buf,"%s:\n%s!",text1,text2); ShowMonoReq2(buf);
+}
+
diff --git a/ImsgHandler.c b/ImsgHandler.c
new file mode 100644
index 0000000..285d344
--- /dev/null
+++ b/ImsgHandler.c
@@ -0,0 +1,263 @@
+#include <proto/exec.h>
+#include <proto/intuition.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+extern struct MenuItem ToolWindowMenuItem,LayerModeMenuItem,
+ OrgGridMenuItem,BobBordersMenuItem,
+ CollisionRectMenuItem;
+extern struct Screen *mainscreen;
+extern struct MyBob *BobTable[];
+extern WORD options,mainx0,mainy0,actbobnum,numbobs;
+extern UWORD mainpalette[];
+extern struct Gadget PosPropGadget,AutoSizeGadget,AutoOrgGadget,AnimKeyGadget;
+
+/************************************************************************/
+
+void HandleImsg(struct IntuiMessage *imsg,struct Menu *menustrip)
+{
+ register struct MyBob *bob;
+ register ULONG class;
+ register UWORD code;
+ register WORD hitflags;
+
+ class = imsg->Class;
+ code = imsg->Code;
+ bob = BobTable[actbobnum];
+
+ switch(class)
+ {
+ case CLOSEWINDOW:
+ ToolWindowMenuItem.Flags &= ~CHECKED;
+ ToolWindowFunc();
+ break;
+
+ case MOUSEBUTTONS:
+ switch(code)
+ {
+ case SELECTDOWN:
+ if((options & GOF_LAYERMODE) && bob)
+ {
+ hitflags=BobHit(bob,imsg->MouseX,imsg->MouseY);
+ if(!hitflags) DragBobFunc();
+ else
+ {
+ if(hitflags&1) bob->Y0++;
+ if(hitflags&2) bob->Y0--;
+ if(hitflags&4) bob->X0++;
+ if(hitflags&8) bob->X0--;
+ }
+ }
+ break;
+
+ case MENUUP:
+ LoadPalette(mainpalette);
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case GADGETDOWN:
+ if(imsg->IAddress == (APTR)&PosPropGadget)
+ {
+ MovePosFunc();
+ }
+ break;
+
+ case GADGETUP:
+ if(bob)
+ {
+ if(AutoSizeGadget.Flags & SELECTED)
+ bob->Flags |= BOBF_AUTOSIZE;
+ else
+ bob->Flags &= ~BOBF_AUTOSIZE;
+
+ if(AutoOrgGadget.Flags & SELECTED)
+ bob->Flags |= BOBF_AUTOORG;
+ else
+ bob->Flags &= ~BOBF_AUTOORG;
+
+ if(AnimKeyGadget.Flags & SELECTED)
+ bob->Flags |= BODF_ANIMKEY;
+ else
+ bob->Flags &= ~BODF_ANIMKEY;
+ }
+
+ HandleEvent((APTR)imsg->IAddress);
+ break;
+
+ case MENUPICK:
+ LoadPalette(mainpalette);
+ if(code != MENUNULL)
+ HandleEvent((APTR)ItemAddress(menustrip,(LONG)code));
+ break;
+
+ case RAWKEY:
+#ifdef DEBUG
+ if(code&0x80)
+ {
+ printf("Rohe Taste losgelassen: $%02lx\n",code&0x7f);
+ }
+ else
+#endif
+ {
+ switch(code)
+ {
+ case 0x5f: /* HELP */
+ AboutFunc();
+ break;
+
+ case 0x50: /* F1 GetBob */
+ GetBobFunc();
+ break;
+
+ case 0x51: /* F2 Get multiple bobs */
+ GetMultiFunc();
+ break;
+
+ case 0x52: /* F3 SetOrg */
+ SetOrgFunc();
+ break;
+
+ case 0x53: /* F4 Set CollisionBounds */
+ SetCollBoundsFunc();
+ break;
+
+ case 0x58: /* F9 Insert New */
+ InsertNewBobFunc();
+ break;
+
+ case 0x59: /* F10 DeleteBob */
+ DeleteActBobFunc();
+ break;
+
+ case 0x4c: /* Cursor rauf: 1. Bob */
+ actbobnum=0;
+ RefreshBobNum();
+ break;
+
+ case 0x4d: /* Cursor runter: letztes Bob */
+ actbobnum=numbobs;
+ RefreshBobNum();
+ break;
+
+ case 0x4e: /* Cursor rechts: 1 Bob vor */
+ if(actbobnum<numbobs) actbobnum++;
+ RefreshBobNum();
+ break;
+
+ case 0x4f: /* Cursor links: 1 Bob zurück */
+ if(actbobnum>0) actbobnum--;
+ RefreshBobNum();
+ break;
+
+ case 0x3e: /* NumPad 8: Bob rauf schieben */
+ if(bob)
+ /* if((mainy0-bob->Y0) > MINY) */
+ bob->Y0++;
+ break;
+
+ case 0x1e: /* NumPad 2: Bob runter */
+ if(bob)
+ /* if((mainy0+bob->Height-bob->Y0) < MAXY) */
+ bob->Y0--;
+ break;
+
+ case 0x2d: /* NumPad 4: Bob links */
+ if(bob)
+ /* if((mainx0-bob->X0) > MINX) */
+ bob->X0++;
+ break;
+
+ case 0x2f: /* NumPad 6: Bob rechts */
+ if(bob)
+ /* if((mainx0+bob->Width-bob->X0) < MAXX) */
+ bob->X0--;
+ break;
+
+ case 0x2e: /* NumPad 5: Bob zentrieren gemäss Modus */
+ if(bob)
+ {
+ SetBobDefaultOrg(bob);
+ }
+ break;
+
+ case 0x40: /* Space-Taste : Redraw screen */
+ Cleanup(FALSE);
+ OpenMain();
+ LoadPalette(mainpalette);
+ break;
+
+ case 0x01: /* Normale '1': SetFirstAnimBob */
+ SetFirstBobFunc();
+ break;
+
+ case 0x02: /* Normale '2': SetLastAnimBob */
+ SetLastBobFunc();
+ break;
+
+ case 0x20: /* 'A': Start Animation */
+ StartAnimFunc();
+ break;
+
+ case 0x11: /* 'W': Tool Window on/off */
+ ToolWindowMenuItem.Flags ^= CHECKED;
+ ToolWindowFunc();
+ break;
+
+ case 0x35: /* 'B': Bob Border on/off */
+ BobBordersMenuItem.Flags ^= CHECKED;
+ break;
+
+ case 0x33: /* 'C': Collision Border on/off */
+ CollisionRectMenuItem.Flags ^= CHECKED;
+ break;
+
+ case 0x28: /* 'L': Layer mode on/off */
+ LayerModeMenuItem.Flags ^= CHECKED;
+ break;
+
+ case 0x18: /* 'O': Org Grid on/off */
+ OrgGridMenuItem.Flags ^= CHECKED;
+ break;
+
+ case 0x19: /* 'P': Edit Palette */
+ EditPaletteFunc();
+ break;
+
+ case 0x13: /* 'R': Rotate */
+ RotateFunc();
+ break;
+
+ case 0x32: /* 'X': Flip X */
+ FlipXFunc();
+ break;
+
+ case 0x15: /* 'Y' (on ASCII keyboards ONLY) */
+ FlipYFunc();
+ break;
+
+ case 0x31: /* 'Z' (on ASCII keyboards ONLY) */
+ ZoomFunc();
+ break;
+
+ default:
+ /* DisplayBeep(mainscreen); */
+ /* printf("Rohe Taste gedrückt: $%02lx\n",code); */
+ break;
+ }
+ }
+ break;
+
+ default:
+ {
+ char buf[100];
+ sprintf(buf,"HandleImsg(): class=$%08lx, code=$%04lx",class,code);
+ ShowMonoReq2(buf);
+ }
+ break;
+ }
+}
diff --git a/Layer.c b/Layer.c
new file mode 100644
index 0000000..0e56e1c
--- /dev/null
+++ b/Layer.c
@@ -0,0 +1,289 @@
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <graphics/rastport.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+extern struct MyBob *BobTable[];
+extern struct Screen *mainscreen;
+extern struct Window *mainwindow,*toolwindow;
+extern struct RastPort *mainrastport;
+extern WORD numbobs,actbobnum,options,mainx0,mainy0;
+extern struct Gadget AutoSizeGadget;
+extern char LabelGadgetSIBuff[];
+extern struct MenuItem CollisionRectMenuItem;
+
+/************************************************************************/
+
+static void DrawBobCross(struct MyBob *bob,WORD x,WORD y)
+{
+ register struct RastPort *rp=mainrastport;
+ register WORD xl,yl;
+
+ xl = mainx0-bob->X0;
+ yl = mainy0-bob->Y0;
+
+ SetDrMd(rp,COMPLEMENT);
+ Move(rp,xl,y);
+ Draw(rp,xl+bob->Width-1,y);
+ Move(rp,x,yl);
+ Draw(rp,x,yl+bob->Height-1);
+}
+
+/************************************************************************/
+
+void SetOrgFunc()
+{
+ register struct MyBob *bob;
+ register struct IntuiMessage *msg;
+ register BOOL looping=TRUE;
+ register ULONG oldidcmp;
+ register WORD x,y;
+
+ if((numbobs>0) && (numbobs!=actbobnum))
+ {
+ bob = BobTable[actbobnum];
+ x = mainx0;
+ y = mainy0;
+ DrawBobCross(bob,x,y);
+ oldidcmp = mainwindow->IDCMPFlags;
+ mainwindow->Flags |= RMBTRAP;
+ ModifyIDCMP(mainwindow,MOUSEBUTTONS);
+ do
+ {
+ WaitTOF();
+ if(msg = (struct IntuiMessage *)GetMsg(mainwindow->UserPort))
+ {
+ switch(msg->Code)
+ {
+ case SELECTDOWN:
+ if(!BobHit(bob,msg->MouseX,msg->MouseY))
+ {
+ bob->X0 = x-mainx0+bob->X0;
+ bob->Y0 = y-mainy0+bob->Y0;
+ }
+ /* hier kein break! */
+ case MENUDOWN:
+ looping=FALSE;
+ break;
+ }
+ }
+ else if(!BobHit(bob,mainwindow->MouseX,mainwindow->MouseY))
+ {
+ DrawBobCross(bob,x,y);
+ x = mainwindow->MouseX;
+ y = mainwindow->MouseY;
+ DrawBobCross(bob,x,y);
+ }
+ } while(looping);
+
+ DrawBobCross(bob,x,y);
+ mainwindow->Flags &= ~RMBTRAP;
+ ModifyIDCMP(mainwindow,oldidcmp);
+ }
+ else ShowMonoReq2("Please select a bob first!");
+}
+
+/************************************************************************/
+
+void SetMainOrgFunc()
+{
+ register ULONG oldidcmp;
+ register WORD x,y;
+
+ x=mainx0; y=mainy0;
+ DrawCross(mainscreen,x,y);
+
+ oldidcmp = mainwindow->IDCMPFlags;
+ mainwindow->Flags |= RMBTRAP;
+ ModifyIDCMP(mainwindow,MOUSEBUTTONS);
+ DrawCross(mainscreen,mainx0,mainy0); /* Am alten Ort zur Orientierung */
+ for(;;)
+ {
+ register struct IntuiMessage *msg;
+
+ WaitTOF();
+ if(msg = (struct IntuiMessage *)GetMsg(mainwindow->UserPort))
+ {
+ DrawCross(mainscreen,mainx0,mainy0);
+ if(msg->Code==SELECTDOWN)
+ {
+ mainx0=x; /* Werte nur übernehmen wenn linke Maustaste */
+ mainy0=y;
+ }
+ DrawCross(mainscreen,x,y);
+ ReplyMsg((struct Message *)msg);
+ break;
+ }
+ else
+ {
+ DrawCross(mainscreen,x,y);
+ x = mainwindow->MouseX;
+ y = mainwindow->MouseY;
+ DrawCross(mainscreen,x,y);
+ }
+ }
+ mainwindow->Flags &= ~RMBTRAP;
+ ModifyIDCMP(mainwindow,oldidcmp);
+}
+
+/************************************************************************/
+
+void DragBobFunc()
+{
+ WORD xold,yold,dx,dy;
+ register struct MyBob *bob;
+ register struct IntuiMessage *msg;
+ register struct BitMap *tmpmap;
+ register WORD x,y,xoff,yoff;
+ BOOL looping=TRUE;
+ LONG oldidcmp;
+
+ if((numbobs>0) && (numbobs!=actbobnum))
+ {
+ bob = BobTable[actbobnum];
+ if(tmpmap=MakeBitMap(bob->Width,bob->Height,bob->Depth))
+ {
+ CopyMem(bob->Planes[0],tmpmap->Planes[0],bob->PlaneSize*bob->Depth);
+
+ xoff = mainwindow->MouseX+bob->X0-mainx0;
+ yoff = mainwindow->MouseY+bob->Y0-mainy0;
+ x = xold = mainwindow->MouseX-xoff;
+ y = yold = mainwindow->MouseY-yoff;
+ oldidcmp = mainwindow->IDCMPFlags;
+ mainwindow->Flags |= RMBTRAP;
+ ModifyIDCMP(mainwindow,MOUSEBUTTONS);
+ DrawRect(mainrastport,(WORD)(x-1),(WORD)(y-1),(WORD)(x+bob->Width),
+ (WORD)(y+bob->Height),0); /* Macht SetAPen,0 */
+ do
+ {
+ WaitTOF();
+ msg=(struct IntuiMessage *)GetMsg(mainwindow->UserPort);
+ if(toolwindow) if(!msg)
+ msg=(struct IntuiMessage *)GetMsg(toolwindow->UserPort);
+ if(msg)
+ {
+ switch(msg->Code)
+ {
+ case SELECTUP:
+ bob->X0 = mainx0-x;
+ bob->Y0 = mainy0-y;
+ looping=FALSE;
+ break;
+
+ case MENUDOWN:
+ RectFill(mainrastport,x-1,y-1,x+bob->Width,
+ y+bob->Height);
+ looping=FALSE;
+ break;
+ }
+ ReplyMsg((struct Message *)msg);
+ }
+ else
+ {
+ xold=x; yold=y;
+ x = mainwindow->MouseX-xoff;
+ y = mainwindow->MouseY-yoff;
+ /* if(x<MINX) x = MINX;
+ if(y<MINY) y = MINY;
+ if(x > MAXX-bob->Width) x = MAXX-bob->Width;
+ if(y > MAXY-bob->Height) y = MAXY-bob->Height;
+ */
+ dx = x-xold; dy = y-yold;
+
+ if(dx>0)
+ RectFill(mainrastport,xold-1,yold-1,x-1,yold+bob->Height);
+ else
+ RectFill(mainrastport,x+bob->Width,yold-1,xold+bob->Width,yold+bob->Height);
+
+ if(dy>0)
+ RectFill(mainrastport,xold-1,yold-1,xold+bob->Width,y);
+ else
+ RectFill(mainrastport,xold-1,y+bob->Height,xold+bob->Width,yold+bob->Height);
+
+ WaitTOF();
+ BltBitMapRastPort(tmpmap,0,0,mainrastport,x,y,
+ bob->Width,bob->Height,0xc0);
+ }
+ } while(looping);
+ mainwindow->Flags &= ~RMBTRAP;
+ ModifyIDCMP(mainwindow,oldidcmp);
+ MyFreeBitMap(tmpmap);
+ }
+ else ShowMonoReq2("Not enough memory to move bob!");
+ }
+ else ShowMonoReq2("Internal Error 193 in Layer.c !");
+}
+
+/************************************************************************/
+
+void SetCollBoundsFunc()
+{
+ register struct MyBob *bob;
+ register struct IntuiMessage *msg;
+ register BOOL looping=TRUE;
+ register ULONG oldidcmp;
+ register WORD x,y;
+
+ if((numbobs>0) && (numbobs!=actbobnum))
+ {
+ CollisionRectMenuItem.Flags |= CHECKED; /* Enable collision */
+ options |= GOF_COLLISIONRECT;
+
+ bob = BobTable[actbobnum];
+ x = mainx0-bob->X0+bob->CollX0;
+ y = mainy0-bob->Y0+bob->CollY0;
+ DrawCross(mainscreen,x,y);
+
+ oldidcmp = mainwindow->IDCMPFlags;
+ mainwindow->Flags |= RMBTRAP;
+ ModifyIDCMP(mainwindow,MOUSEBUTTONS);
+ do
+ {
+ WaitTOF();
+ if(msg = (struct IntuiMessage *)GetMsg(mainwindow->UserPort))
+ {
+ switch(msg->Code)
+ {
+ case SELECTDOWN:
+ /* if(!BobHit(bob,msg->MouseX,msg->MouseY)) */
+ {
+ DrawCross(mainscreen,x,y);
+ bob->CollX0 = x+bob->X0-mainx0;
+ bob->CollY0 = y+bob->Y0-mainy0;
+ ShowBob(bob);
+ x = mainx0-bob->X0+bob->CollX1;
+ y = mainy0-bob->Y0+bob->CollY1;
+ DrawCross(mainscreen,x,y);
+ }
+ break;
+
+ case SELECTUP:
+ /* if(!BobHit(bob,msg->MouseX,msg->MouseY)) */
+ {
+ DrawCross(mainscreen,x,y);
+ bob->CollX1 = x+bob->X0-mainx0;
+ bob->CollY1 = y+bob->Y0-mainy0;
+ }
+ looping=FALSE;
+ break;
+ }
+ ReplyMsg((struct Message *)msg);
+ }
+ else /* if(!BobHit(bob,mainwindow->MouseX,mainwindow->MouseY)) */
+ {
+ DrawCross(mainscreen,x,y);
+ x = mainwindow->MouseX;
+ y = mainwindow->MouseY;
+ DrawCross(mainscreen,x,y);
+ }
+ } while(looping);
+
+ mainwindow->Flags &= ~RMBTRAP;
+ ModifyIDCMP(mainwindow,oldidcmp);
+ }
+ else ShowMonoReq2("Please select a bob first!");
+}
+
diff --git a/LoadBobs.c b/LoadBobs.c
new file mode 100644
index 0000000..84c8848
--- /dev/null
+++ b/LoadBobs.c
@@ -0,0 +1,425 @@
+#include <exec/types.h>
+#include <exec/memory.h>
+#include <proto/exec.h>
+#include <proto/dos.h>
+#include <graphics/gfx.h>
+#include <string.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+extern struct MyBob *BobTable[];
+extern struct Screen *mainscreen;
+
+extern WORD options,numbobs,actbobnum,firstanimbob,lastanimbob,animflags;
+extern BYTE defaultorg;
+extern WORD mainpalette[];
+extern char idstring[],outputname[],sectionname[];
+extern WORD outputflags,mainx0,mainy0;
+extern char LabelGadgetSIBuff[];
+
+extern BYTE arexxflag;
+extern char arexxfilename[];
+
+static char BobPath[128]; /* Load / Save Bobs */
+static char BobName[80];
+static char InsertPath[128]; /* Insert Bobs */
+static char InsertName[80];
+static char OPath[128]; /* Load / Save Offsets */
+static char OName[80];
+
+char PicPath[128]; /* Benötigt von Picture.c */
+char PicName[80];
+
+/****************************************************************************
+** Konfigurations-File laden und auswerten
+*/
+
+void LoadConfigFile(char *name)
+{
+ char buf[500];
+ register BPTR file;
+
+ ClearMem(buf,sizeof(buf));
+
+ if(file=Open(name,MODE_OLDFILE))
+ {
+ register char *sptr,*dptr;
+
+ Read(file,buf,490);
+ Close(file);
+
+ sptr=buf;
+ dptr=BobPath; while((*dptr=*sptr++)>' ') dptr++; *dptr='\0';
+ dptr=PicPath; while((*dptr=*sptr++)>' ') dptr++; *dptr='\0';
+ strcpy(InsertPath,BobPath);
+ }
+}
+
+/****************************************************************************
+** Ein Bob aus file laden
+*/
+
+static struct MyBob *LoadOneBob(register BPTR file,register WORD version)
+{
+ register struct MyBob *bob;
+ register long i;
+
+ if(bob=AllocMem(sizeof(struct MyBob),MEMF_CLEAR))
+ {
+ Read(file,bob,sizeof(*bob));
+ if(version<108)
+ {
+ char buf[66];
+ Seek(file,-8,OFFSET_CURRENT); /* Antiskip Collsion Coords */
+ CopyMem(&bob->CollX0,buf,66);
+ CopyMem(buf,&bob->PlanePick,66);
+ bob->CollX0=bob->CollX1=bob->CollY0=bob->CollY1=0;
+ }
+
+ if(bob->Planes[0] = AllocMem(bob->PlaneSize*bob->Depth,0L))
+ {
+ for(i=1; i<bob->Depth; ++i)
+ bob->Planes[i] = bob->Planes[0]+i*bob->PlaneSize;
+ Read(file,bob->Planes[0],bob->PlaneSize*bob->Depth);
+
+ bob->Mask = 0; /* jaja! */
+ return bob;
+ }
+ else
+ {
+ FreeMem(bob,sizeof(*bob));
+ ShowMonoReq2("Not enough memory for bob planes!");
+ }
+ }
+ else
+ {
+ ShowMonoReq2("Not enough memory for bob structure!");
+ }
+ return 0;
+}
+
+/****************************************************************************
+** Bobs laden
+*/
+
+void LoadBobsFunc()
+{
+ LockWindows();
+ LoadBobs(arexxflag ? arexxfilename
+ : FileRequest("Load Bobs from Disk", "LOAD", BobPath, BobName));
+ UnLockWindows();
+}
+
+
+void LoadBobs(char *name)
+{
+ struct BobFileHeader bfh;
+ register struct MyBob *bob;
+ register BPTR file;
+ register long i;
+ char buf[64];
+
+ LockWindows();
+
+ if(name)
+ {
+ if(file=Open(name,MODE_OLDFILE))
+ {
+ Read(file,&bfh,sizeof(bfh));
+ if(bfh.Magic == BF_MAGIC)
+ {
+ if((bfh.Version>=106) && (bfh.Version<=BF_VERSION))
+ {
+ if(bfh.Version < 110)
+ {
+ ShowMonoReq2("Warning:\nThis is an old Bobi file.\n"
+ "MainOrg is not saved.");
+ }
+
+ if(bfh.Version < 109)
+ {
+ ShowMonoReq2("Warning:\nThis is a very old Bobi file.\n"
+ "AnimKey bobs are not marked.");
+ }
+
+ if(bfh.Version < 108)
+ {
+ ShowMonoReq2("Warning:\nThis is a very very old Bobi file.\n"
+ "Collision info is not set.");
+ }
+
+ if(bfh.Version < 107)
+ {
+ ShowMonoReq2("Warning:\nThis is a very very very old Bobi file!\n"
+ "Bob/Sprite flags and Collision info\n"
+ "may be wrong.");
+ bfh.OutputFlags |= OF_GENERATEBOBS;
+ }
+ ClearAll();
+
+ if(bfh.Version >= 110)
+ {
+ mainx0 = bfh.MainX0;
+ mainy0 = bfh.MainY0;
+ }
+
+ if(bfh.Version >= 111)
+ {
+ defaultorg = bfh.DefaultOrg;
+ }
+
+ CopyMem(bfh.ColorTable,mainpalette,2*32);
+ strcpy(outputname,bfh.OutputName);
+ strcpy(sectionname,bfh.SectionName);
+ SetGlobalOptions(bfh.GlobalOptions,defaultorg);
+ outputflags = bfh.OutputFlags;
+ strcpy(LabelGadgetSIBuff,bfh.DefaultLabel);
+ firstanimbob = bfh.FirstAnimBob;
+ lastanimbob = bfh.LastAnimBob;
+ SetAnimSpeed(bfh.AnimSpeed);
+ SetAnimFlags(bfh.AnimFlags);
+
+ numbobs = bfh.NumBobs;
+ for(i=0; i<bfh.NumBobs; ++i)
+ {
+ if(bob=LoadOneBob(file,bfh.Version)) BobTable[i]=bob;
+ else
+ {
+ numbobs = i;
+ sprintf(buf,"%ld of %ld bobs loaded.",i,bfh.NumBobs);
+ ShowMonoReq2(buf);
+ break;
+ }
+ }
+ RefreshBobNum();
+ }
+ else if(bfh.Version > BF_VERSION)
+ {
+ ShowMonoReq2("You need a newer Bobi version\nto handle this file!");
+ }
+ else ShowMonoReq2("This is a mangled or\ntoo old Bobi file!");
+ }
+ else
+ {
+ sprintf(buf,"This is not a %s file !",idstring);
+ ShowMonoReq2(buf);
+ }
+ Close(file);
+ }
+ else ShowFileError(name);
+ }
+ UnLockWindows();
+}
+
+/****************************************************************************
+** Bobs aus File an aktueller Position einfügen
+*/
+
+void InsertBobsFunc()
+{
+ struct BobFileHeader bfh;
+ register char *name;
+ register struct MyBob *bob;
+ register BPTR file;
+ register long i;
+ char buf[64];
+
+ LockWindows();
+
+ if(arexxflag)
+ name = arexxfilename;
+ else
+ name = FileRequest("Insert Bobs from Disk", "INSERT", InsertPath, InsertName);
+
+ if(name)
+ {
+ if(file=Open(name,MODE_OLDFILE))
+ {
+ Read(file,&bfh,sizeof(bfh));
+ if(bfh.Magic == BF_MAGIC)
+ {
+ if((bfh.Version>=106) && (bfh.Version<=BF_VERSION))
+ {
+ for(i=0; i<bfh.NumBobs; ++i)
+ {
+ if(bob=LoadOneBob(file,bfh.Version))
+ {
+ InsertBob(bob,(WORD)(actbobnum+i));
+ }
+ else
+ {
+ sprintf(buf,"%ld of %ld bobs inserted.",i,bfh.NumBobs);
+ ShowMonoReq2(buf);
+ break;
+ }
+ }
+ RefreshBobNum();
+ }
+ else if(bfh.Version > BF_VERSION)
+ {
+ ShowMonoReq2("You need a newer Bobi version\nto handle this file!");
+ }
+ else ShowMonoReq2("This is a mangled or\ntoo old Bobi file!");
+ }
+ else
+ {
+ sprintf(buf,"This is not a %s file !",idstring);
+ ShowMonoReq2(buf);
+ }
+ Close(file);
+ }
+ else ShowFileError(name);
+ }
+ UnLockWindows();
+}
+
+/****************************************************************************
+** Bobs in eine Datei speichern
+*/
+
+void SaveBobsFunc()
+{
+ struct BobFileHeader bfh;
+ register char *name;
+ register BPTR file;
+ register long i;
+
+ ClearMem(&bfh,sizeof(bfh));
+ LockWindows();
+
+ if(arexxflag)
+ name = arexxfilename;
+ else
+ name = FileRequest("Save Bobs to Disk", "SAVE", BobPath, BobName);
+
+ if(name)
+ {
+ bfh.Magic = BF_MAGIC;
+ bfh.Version = BF_VERSION;
+ bfh.NumBobs = numbobs;
+ bfh.OutputFlags = outputflags;
+ bfh.FirstAnimBob = firstanimbob;
+ bfh.LastAnimBob = lastanimbob;
+ bfh.AnimSpeed = GetAnimSpeed();
+ bfh.AnimFlags = animflags;
+ bfh.DefaultOrg = defaultorg;
+ bfh.GlobalOptions = options;
+ bfh.MainX0 = mainx0;
+ bfh.MainY0 = mainy0;
+
+ CopyMem(mainpalette,bfh.ColorTable,2*32);
+ strcpy(bfh.OutputName,outputname);
+ strcpy(bfh.SectionName,sectionname);
+ strcpy(bfh.DefaultLabel,LabelGadgetSIBuff);
+
+ if(file=OpenNewFileSafely(name))
+ {
+ Write(file,&bfh,sizeof(bfh));
+ for(i=0; i<numbobs; ++i)
+ {
+ Write(file,BobTable[i],sizeof(struct MyBob));
+ Write(file,BobTable[i]->Planes[0],BobTable[i]->PlaneSize*BobTable[i]->Depth);
+ }
+ Close(file);
+ }
+ }
+ UnLockWindows();
+}
+
+/****************************************************************************
+** Eine Datei von der Disk löschen
+*/
+
+void DeleteFileFunc()
+{
+ register char *name;
+ char buf[160];
+
+ LockWindows();
+ if (name = FileRequest("Delete File on Disk", "DELETE", BobPath, BobName))
+ {
+ sprintf(buf,"Do you really want to delete the\nfile '%s' ?",name);
+ if(ShowRequest2(buf,"YEP!"))
+ {
+ if(DeleteFile(name))
+ {
+// sprintf(buf,"%s%s.fd",BobPath,*BobPath?"/":"");
+// DeleteFile(buf);
+ }
+ else ShowFileError(name);
+ }
+ }
+ UnLockWindows();
+}
+
+/****************************************************************************
+** Bob-Offset-Tabelle von Disk laden
+*/
+
+void LoadOffsetsFunc()
+{
+ register char *name;
+ register BPTR file;
+ register long i;
+
+ LockWindows();
+ OPath[0] = OName[0] = '\0';
+
+ if(arexxflag)
+ name = arexxfilename;
+ else
+ name = FileRequest("Load Bob Offsets from Disk", "LOAD", OPath, OName);
+
+ if(name)
+ {
+ if(file=Open(name,MODE_OLDFILE))
+ {
+ for(i=0; i<numbobs; ++i)
+ {
+ Read(file,&BobTable[i]->X0,2);
+ Read(file,&BobTable[i]->Y0,2);
+ }
+ Close(file);
+ }
+ else ShowFileError(name);
+ }
+ UnLockWindows();
+}
+
+/****************************************************************************
+** Bob-Offsets in Datei speichern
+*/
+
+void SaveOffsetsFunc()
+{
+ register char *name;
+ register BPTR file;
+ register long i;
+
+ LockWindows();
+ OPath[0] = OName[0] = '\0';
+
+ if(arexxflag)
+ name = arexxfilename;
+ else
+ name = FileRequest("Save Bob Offsets to Disk", "SAVE", OPath, OName);
+
+ if(name)
+ {
+ if(file=OpenNewFileSafely(name))
+ {
+ for(i=0; i<numbobs; ++i)
+ {
+ Write(file,&BobTable[i]->X0,2);
+ Write(file,&BobTable[i]->Y0,2);
+// sprintf(buf,"\t\tDC.W\t%ld,%ld\t; %s\n",
+// BobTable[i]->X0,BobTable[i]->Y0,BobTable[i]->SourceLabel);
+// Write(file,buf,strlen(buf));
+ }
+ Close(file);
+ }
+ }
+ UnLockWindows();
+}
+
diff --git a/MainWindow.h b/MainWindow.h
new file mode 100644
index 0000000..4b72e64
--- /dev/null
+++ b/MainWindow.h
@@ -0,0 +1,2166 @@
+
+struct TextAttr TOPAZ80 = {
+ (STRPTR)"topaz.font",
+ TOPAZ_EIGHTY,0,0
+};
+struct NewScreen NewScreenStructure = {
+ 0,0,
+ 320,256,
+ 6,
+ 0,1,
+ EXTRA_HALFBRITE,
+ CUSTOMSCREEN,
+ &TOPAZ80,
+ NULL,
+ NULL,
+ NULL
+};
+
+#define NEWSCREENSTRUCTURE NewScreenStructure
+
+USHORT Palette[] = {
+ 0x0000,
+ 0x0ECA,
+ 0x035D,
+ 0x0AAA,
+ 0x0D80,
+ 0x0FE0,
+ 0x08F0,
+ 0x0444,
+ 0x00B6,
+ 0x00DD,
+ 0x00AF,
+ 0x007C,
+ 0x000F,
+ 0x070F,
+ 0x0C0E,
+ 0x0C08,
+ 0x0620,
+ 0x0E52,
+ 0x0A52,
+ 0x0FCA,
+ 0x0333,
+ 0x0444,
+ 0x0555,
+ 0x0666,
+ 0x0777,
+ 0x0888,
+ 0x0999,
+ 0x0AAA,
+ 0x0CCC,
+ 0x014A,
+ 0x0B98,
+ 0x0C00
+#define PaletteColorCount 32
+};
+
+#define PALETTE Palette
+
+UBYTE UNDOBUFFER[64];
+
+SHORT BorderVectors1[] = {
+ 0,0,
+ 25,0,
+ 25,10,
+ 0,10,
+ 0,0
+};
+struct Border Border1 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors1,
+ NULL
+};
+
+struct Gadget Gadget3 = {
+ NULL,
+ -24,12,
+ 24,9,
+ GADGHBOX+GADGHIMAGE+GRELRIGHT,
+ NULL,
+ BOOLGADGET,
+ (APTR)&Border1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+SHORT BorderVectors2[] = {
+ 0,0,
+ 25,0,
+ 25,10,
+ 0,10,
+ 0,0
+};
+struct Border Border2 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors2,
+ NULL
+};
+
+struct Gadget Gadget2 = {
+ &Gadget3,
+ -24,-9,
+ 24,9,
+ GADGHBOX+GADGHIMAGE+GRELBOTTOM+GRELRIGHT,
+ NULL,
+ BOOLGADGET,
+ (APTR)&Border2,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+struct PropInfo PosPropGadgetSInfo = {
+ AUTOKNOB+FREEVERT+PROPBORDERLESS,
+ (UWORD)-1,(UWORD)-1,
+ (UWORD)-1,(UWORD)-1,
+};
+
+struct Image Image1 = {
+ 0,0,
+ 22,161,
+ 0,
+ NULL,
+ 0x0000,0x0000,
+ NULL
+};
+
+struct Gadget PosPropGadget = {
+ &Gadget2,
+ -23,25,
+ 22,-39,
+ GRELRIGHT+GRELHEIGHT,
+ RELVERIFY+GADGIMMEDIATE,
+ PROPGADGET,
+ (APTR)&Image1,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&PosPropGadgetSInfo,
+ NULL,
+ NULL
+};
+
+#define GadgetList1 PosPropGadget
+
+struct IntuiText IText1 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Remake Collision",
+ NULL
+};
+
+struct MenuItem MenuItem15 = {
+ NULL,
+ -50,112,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText1,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText2 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Remake Labels",
+ NULL
+};
+
+struct MenuItem MenuItem14 = {
+ &MenuItem15,
+ -50,104,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText2,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText3 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "-----------------",
+ NULL
+};
+
+struct MenuItem MenuItem13 = {
+ &MenuItem14,
+ -50,96,
+ 136,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText3,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText4 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Save Offsets",
+ NULL
+};
+
+struct MenuItem MenuItem12 = {
+ &MenuItem13,
+ -50,88,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText4,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText5 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Load Offsets",
+ NULL
+};
+
+struct MenuItem MenuItem11 = {
+ &MenuItem12,
+ -50,80,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText5,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText6 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "-----------------",
+ NULL
+};
+
+struct MenuItem MenuItem10 = {
+ &MenuItem11,
+ -50,72,
+ 136,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText6,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText7 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Edit Palette.. P",
+ NULL
+};
+
+struct MenuItem MenuItem9 = {
+ &MenuItem10,
+ -50,64,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText7,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText8 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "-----------------",
+ NULL
+};
+
+struct MenuItem MenuItem8 = {
+ &MenuItem9,
+ -50,56,
+ 136,8,
+ ITEMTEXT+HIGHCOMP,
+ 0,
+ (APTR)&IText8,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText9 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Set Main Org",
+ NULL
+};
+
+struct MenuItem MenuItem7 = {
+ &MenuItem8,
+ -50,48,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText9,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText10 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "-----------------",
+ NULL
+};
+
+struct MenuItem MenuItem6 = {
+ &MenuItem7,
+ -50,40,
+ 136,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText10,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText11 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Collision C",
+ NULL
+};
+
+struct MenuItem MenuItem5 = {
+ &MenuItem6,
+ -50,32,
+ 136,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText11,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText12 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Borders B",
+ NULL
+};
+
+struct MenuItem MenuItem4 = {
+ &MenuItem5,
+ -50,24,
+ 136,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText12,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText13 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Org Grid O",
+ NULL
+};
+
+struct MenuItem MenuItem3 = {
+ &MenuItem4,
+ -50,16,
+ 136,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText13,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText14 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Layer Mode L",
+ NULL
+};
+
+struct MenuItem MenuItem2 = {
+ &MenuItem3,
+ -50,8,
+ 136,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText14,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText15 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Tool Window W",
+ NULL
+};
+
+struct MenuItem MenuItem1 = {
+ &MenuItem2,
+ -50,0,
+ 136,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP+CHECKED,
+ 0,
+ (APTR)&IText15,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct Menu Menu5 = {
+ NULL,
+ 224,0,
+ 55,0,
+ MENUENABLED,
+ "Global",
+ &MenuItem1
+};
+
+struct IntuiText IText16 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Start A",
+ NULL
+};
+
+struct MenuItem MenuItem22 = {
+ NULL,
+ -64,48,
+ 120,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText16,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText17 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Ping-Pong",
+ NULL
+};
+
+struct MenuItem SubItem3 = {
+ NULL,
+ 105,15,
+ 91,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText17,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText18 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Backward",
+ NULL
+};
+
+struct MenuItem SubItem2 = {
+ &SubItem3,
+ 105,7,
+ 91,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText18,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText19 = {
+ 2,1,JAM1,
+ 19,0,
+ &TOPAZ80,
+ "Forward",
+ NULL
+};
+
+struct MenuItem SubItem1 = {
+ &SubItem2,
+ 105,-1,
+ 91,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP+CHECKED,
+ 0,
+ (APTR)&IText19,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText20 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Mode »",
+ NULL
+};
+
+struct MenuItem MenuItem21 = {
+ &MenuItem22,
+ -64,40,
+ 120,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText20,
+ NULL,
+ NULL,
+ &SubItem1,
+ MENUNULL
+};
+
+struct IntuiText IText21 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Last Bob 2",
+ NULL
+};
+
+struct MenuItem MenuItem20 = {
+ &MenuItem21,
+ -64,32,
+ 120,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText21,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText22 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "First Bob 1",
+ NULL
+};
+
+struct MenuItem MenuItem19 = {
+ &MenuItem20,
+ -64,24,
+ 120,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText22,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText23 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "---------------",
+ NULL
+};
+
+struct MenuItem MenuItem18 = {
+ &MenuItem19,
+ -64,16,
+ 120,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText23,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText24 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Save IFF Anim..",
+ NULL
+};
+
+struct MenuItem MenuItem17 = {
+ &MenuItem18,
+ -64,8,
+ 120,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText24,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText25 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Load IFF Anim..",
+ NULL
+};
+
+struct MenuItem MenuItem16 = {
+ &MenuItem17,
+ -64,0,
+ 120,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText25,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct Menu Menu4 = {
+ &Menu5,
+ 178,0,
+ 39,0,
+ MENUENABLED,
+ "Anim",
+ &MenuItem16
+};
+
+struct IntuiText IText26 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Delete F10",
+ NULL
+};
+
+struct MenuItem MenuItem36 = {
+ NULL,
+ 0,104,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText26,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText27 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Insert New F9",
+ NULL
+};
+
+struct MenuItem MenuItem35 = {
+ &MenuItem36,
+ 0,96,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText27,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText28 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "--------------",
+ NULL
+};
+
+struct MenuItem MenuItem34 = {
+ &MenuItem35,
+ 0,88,
+ 112,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText28,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText29 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Zoom Z",
+ NULL
+};
+
+struct MenuItem MenuItem33 = {
+ &MenuItem34,
+ 0,80,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText29,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText30 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Rotate R",
+ NULL
+};
+
+struct MenuItem MenuItem32 = {
+ &MenuItem33,
+ 0,72,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText30,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText31 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Flip Y Y",
+ NULL
+};
+
+struct MenuItem MenuItem31 = {
+ &MenuItem32,
+ 0,64,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText31,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText32 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Flip X X",
+ NULL
+};
+
+struct MenuItem MenuItem30 = {
+ &MenuItem31,
+ 0,56,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText32,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText33 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "--------------",
+ NULL
+};
+
+struct MenuItem MenuItem29 = {
+ &MenuItem30,
+ 0,48,
+ 112,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText33,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText34 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Set Collis. F4",
+ NULL
+};
+
+struct MenuItem MenuItem28 = {
+ &MenuItem29,
+ 0,40,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText34,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText35 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem12 = {
+ NULL,
+ 111,15,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText35,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText36 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem11 = {
+ &SubItem12,
+ 104,15,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP+CHECKED,
+ 0,
+ (APTR)&IText36,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText37 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem10 = {
+ &SubItem11,
+ 97,15,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText37,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText38 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem9 = {
+ &SubItem10,
+ 111,7,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText38,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText39 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem8 = {
+ &SubItem9,
+ 104,7,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText39,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText40 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem7 = {
+ &SubItem8,
+ 97,7,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText40,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText41 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem6 = {
+ &SubItem7,
+ 111,-1,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText41,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText42 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem5 = {
+ &SubItem6,
+ 104,-1,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText42,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText43 = {
+ 3,1,COMPLEMENT,
+ 0,0,
+ NULL,
+ ".",
+ NULL
+};
+
+struct MenuItem SubItem4 = {
+ &SubItem5,
+ 97,-1,
+ 7,8,
+ CHECKIT+ITEMTEXT+MENUTOGGLE+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText43,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText44 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "DefaultOrg »",
+ NULL
+};
+
+struct MenuItem MenuItem27 = {
+ &MenuItem28,
+ 0,32,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText44,
+ NULL,
+ NULL,
+ &SubItem4,
+ MENUNULL
+};
+
+struct IntuiText IText45 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Set Org F3",
+ NULL
+};
+
+struct MenuItem MenuItem26 = {
+ &MenuItem27,
+ 0,24,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText45,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText46 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "--------------",
+ NULL
+};
+
+struct MenuItem MenuItem25 = {
+ &MenuItem26,
+ 0,16,
+ 112,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText46,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText47 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Get multi F2",
+ NULL
+};
+
+struct MenuItem MenuItem24 = {
+ &MenuItem25,
+ 0,8,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText47,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText48 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Get single F1",
+ NULL
+};
+
+struct MenuItem MenuItem23 = {
+ &MenuItem24,
+ 0,0,
+ 112,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText48,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct Menu Menu3 = {
+ &Menu4,
+ 140,0,
+ 31,0,
+ MENUENABLED,
+ "Bob",
+ &MenuItem23
+};
+
+struct IntuiText IText49 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Close Screen",
+ NULL
+};
+
+struct MenuItem MenuItem41 = {
+ NULL,
+ 0,32,
+ 144,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText49,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText50 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "------------------",
+ NULL
+};
+
+struct MenuItem MenuItem40 = {
+ &MenuItem41,
+ 0,24,
+ 144,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText50,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText51 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Grab Screen..",
+ NULL
+};
+
+struct MenuItem MenuItem39 = {
+ &MenuItem40,
+ 0,16,
+ 144,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText51,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText52 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Grab DPaint",
+ NULL
+};
+
+struct MenuItem MenuItem38 = {
+ &MenuItem39,
+ 0,8,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText52,
+ NULL,
+ 'D',
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText53 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Load IFF..",
+ NULL
+};
+
+struct MenuItem MenuItem37 = {
+ &MenuItem38,
+ 0,0,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText53,
+ NULL,
+ 'P',
+ NULL,
+ MENUNULL
+};
+
+struct Menu Menu2 = {
+ &Menu3,
+ 70,0,
+ 63,0,
+ MENUENABLED,
+ "Picture",
+ &MenuItem37
+};
+
+struct IntuiText IText54 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Quit",
+ NULL
+};
+
+struct MenuItem MenuItem56 = {
+ NULL,
+ 0,112,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText54,
+ NULL,
+ 'Q',
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText55 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "------------------",
+ NULL
+};
+
+struct MenuItem MenuItem55 = {
+ &MenuItem56,
+ 0,104,
+ 144,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText55,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText56 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Sleep",
+ NULL
+};
+
+struct MenuItem MenuItem54 = {
+ &MenuItem55,
+ 0,96,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText56,
+ NULL,
+ '`',
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText57 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "------------------",
+ NULL
+};
+
+struct MenuItem MenuItem53 = {
+ &MenuItem54,
+ 0,88,
+ 144,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText57,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText58 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "About..",
+ NULL
+};
+
+struct MenuItem MenuItem52 = {
+ &MenuItem53,
+ 0,80,
+ 144,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText58,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText59 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "------------------",
+ NULL
+};
+
+struct MenuItem MenuItem51 = {
+ &MenuItem52,
+ 0,72,
+ 144,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText59,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText60 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Do Script..",
+ NULL
+};
+
+struct MenuItem SubItem16 = {
+ NULL,
+ 129,23,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText60,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText61 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "-----------------",
+ NULL
+};
+
+struct MenuItem SubItem15 = {
+ &SubItem16,
+ 129,15,
+ 136,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText61,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText62 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Stop Recording",
+ NULL
+};
+
+struct MenuItem SubItem14 = {
+ &SubItem15,
+ 129,7,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText62,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText63 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Start Recording..",
+ NULL
+};
+
+struct MenuItem SubItem13 = {
+ &SubItem14,
+ 129,-1,
+ 136,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText63,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText64 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "ARexx »",
+ NULL
+};
+
+struct MenuItem MenuItem50 = {
+ &MenuItem51,
+ 0,64,
+ 144,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText64,
+ NULL,
+ NULL,
+ &SubItem13,
+ MENUNULL
+};
+
+struct IntuiText IText65 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Generate Code",
+ NULL
+};
+
+struct MenuItem MenuItem49 = {
+ &MenuItem50,
+ 0,56,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText65,
+ NULL,
+ 'G',
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText66 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "------------------",
+ NULL
+};
+
+struct MenuItem MenuItem48 = {
+ &MenuItem49,
+ 0,48,
+ 144,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText66,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText67 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Delete File..",
+ NULL
+};
+
+struct MenuItem MenuItem47 = {
+ &MenuItem48,
+ 0,40,
+ 144,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText67,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText68 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Save Bobs..",
+ NULL
+};
+
+struct MenuItem MenuItem46 = {
+ &MenuItem47,
+ 0,32,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText68,
+ NULL,
+ 'S',
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText69 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Insert Bobs..",
+ NULL
+};
+
+struct MenuItem MenuItem45 = {
+ &MenuItem46,
+ 0,24,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText69,
+ NULL,
+ 'I',
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText70 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Load Bobs",
+ NULL
+};
+
+struct MenuItem MenuItem44 = {
+ &MenuItem45,
+ 0,16,
+ 144,8,
+ ITEMTEXT+COMMSEQ+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText70,
+ NULL,
+ 'O',
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText71 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "------------------",
+ NULL
+};
+
+struct MenuItem MenuItem43 = {
+ &MenuItem44,
+ 0,8,
+ 144,8,
+ ITEMTEXT+HIGHCOMP+HIGHBOX,
+ 0,
+ (APTR)&IText71,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct IntuiText IText72 = {
+ 2,1,JAM1,
+ 0,0,
+ &TOPAZ80,
+ "Clear All..",
+ NULL
+};
+
+struct MenuItem MenuItem42 = {
+ &MenuItem43,
+ 0,0,
+ 144,8,
+ ITEMTEXT+ITEMENABLED+HIGHCOMP,
+ 0,
+ (APTR)&IText72,
+ NULL,
+ NULL,
+ NULL,
+ MENUNULL
+};
+
+struct Menu Menu1 = {
+ &Menu2,
+ 0,0,
+ 63,0,
+ MENUENABLED,
+ "Project",
+ &MenuItem42
+};
+
+#define MenuList1 Menu1
+
+struct NewWindow NewWindowStructure1 = {
+ 0,0,
+ 320,200,
+ 0,1,
+ MOUSEBUTTONS+GADGETDOWN+GADGETUP+MENUPICK+RAWKEY,
+ BACKDROP+REPORTMOUSE+BORDERLESS+ACTIVATE+NOCAREREFRESH,
+ &PosPropGadget,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ 0,0,
+ 0,0,
+ CUSTOMSCREEN
+};
+
+SHORT BorderVectors6[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+struct Border Border6 = {
+ 134,11,
+ 1,0,JAM1,
+ 5,
+ BorderVectors6,
+ NULL
+};
+
+SHORT BorderVectors5[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+struct Border Border5 = {
+ 94,11,
+ 1,0,JAM1,
+ 5,
+ BorderVectors5,
+ &Border6
+};
+
+SHORT BorderVectors4[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+struct Border Border4 = {
+ 174,11,
+ 1,0,JAM1,
+ 5,
+ BorderVectors4,
+ &Border5
+};
+
+SHORT BorderVectors3[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+struct Border Border3 = {
+ 214,11,
+ 1,0,JAM1,
+ 5,
+ BorderVectors3,
+ &Border4
+};
+
+struct Gadget Gadget11 = {
+ NULL,
+ 0,0,
+ 1,1,
+ GADGHBOX+GADGHIMAGE,
+ NULL,
+ BOOLGADGET,
+ (APTR)&Border3,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+UBYTE LabelGadgetSIBuff[64];
+struct StringInfo LabelGadgetSInfo = {
+ LabelGadgetSIBuff,
+ UNDOBUFFER,
+ 0,
+ 64,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ NULL
+};
+
+SHORT BorderVectors7[] = {
+ 0,0,
+ 157,0,
+ 157,11,
+ 0,11,
+ 0,1
+};
+struct Border Border7 = {
+ -2,-2,
+ 1,0,JAM1,
+ 5,
+ BorderVectors7,
+ NULL
+};
+
+struct IntuiText IText73 = {
+ 1,0,JAM1,
+ 28,-11,
+ NULL,
+ "Source Label:",
+ NULL
+};
+
+struct Gadget LabelGadget = {
+ &Gadget11,
+ 96,46,
+ 154,9,
+ NULL,
+ RELVERIFY,
+ STRGADGET,
+ (APTR)&Border7,
+ NULL,
+ &IText73,
+ NULL,
+ (APTR)&LabelGadgetSInfo,
+ NULL,
+ NULL
+};
+
+SHORT BorderVectors8[] = {
+ 0,0,
+ 33,0,
+ 33,21,
+ 0,21,
+ 0,0
+};
+struct Border Border8 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors8,
+ NULL
+};
+
+struct IntuiText IText75 = {
+ 1,0,JAM1,
+ 4,11,
+ NULL,
+ "Org",
+ NULL
+};
+
+struct IntuiText IText74 = {
+ 1,0,JAM1,
+ 4,2,
+ NULL,
+ "Set",
+ &IText75
+};
+
+struct Gadget SetOrgGadget = {
+ &LabelGadget,
+ 255,35,
+ 32,20,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border8,
+ NULL,
+ &IText74,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+SHORT BorderVectors9[] = {
+ 0,0,
+ 33,0,
+ 33,21,
+ 0,21,
+ 0,0
+};
+struct Border Border9 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors9,
+ NULL
+};
+
+struct IntuiText IText77 = {
+ 1,0,JAM1,
+ 4,11,
+ NULL,
+ "Bob",
+ NULL
+};
+
+struct IntuiText IText76 = {
+ 1,0,JAM1,
+ 4,2,
+ NULL,
+ "Get",
+ &IText77
+};
+
+struct Gadget GetBobGadget = {
+ &SetOrgGadget,
+ 255,12,
+ 32,20,
+ NULL,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border9,
+ NULL,
+ &IText76,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+struct PropInfo AnimSpeedGadgetSInfo = {
+ AUTOKNOB+FREEVERT,
+ (UWORD)-1,20755,
+ (UWORD)-1,4095,
+};
+
+struct Image Image2 = {
+ 0,11,
+ 6,4,
+ 0,
+ NULL,
+ 0x0000,0x0000,
+ NULL
+};
+
+struct Gadget AnimSpeedGadget = {
+ &GetBobGadget,
+ 4,11,
+ 14,45,
+ NULL,
+ NULL,
+ PROPGADGET,
+ (APTR)&Image2,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&AnimSpeedGadgetSInfo,
+ NULL,
+ NULL
+};
+
+SHORT BorderVectors10[] = {
+ 0,0,
+ 71,0,
+ 71,11,
+ 0,11,
+ 0,0
+};
+struct Border Border10 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors10,
+ NULL
+};
+
+struct IntuiText IText78 = {
+ 1,0,JAM1,
+ 4,1,
+ NULL,
+ "Anim Key",
+ NULL
+};
+
+struct Gadget AnimKeyGadget = {
+ &AnimSpeedGadget,
+ 21,45,
+ 70,10,
+ SELECTED,
+ RELVERIFY+TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border10,
+ NULL,
+ &IText78,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+SHORT BorderVectors11[] = {
+ 0,0,
+ 71,0,
+ 71,11,
+ 0,11,
+ 0,0
+};
+struct Border Border11 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors11,
+ NULL
+};
+
+struct IntuiText IText79 = {
+ 1,0,JAM1,
+ 4,1,
+ NULL,
+ "Auto Org",
+ NULL
+};
+
+struct Gadget AutoOrgGadget = {
+ &AnimKeyGadget,
+ 21,28,
+ 70,10,
+ SELECTED,
+ RELVERIFY+TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border11,
+ NULL,
+ &IText79,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+SHORT BorderVectors12[] = {
+ 0,0,
+ 71,0,
+ 71,11,
+ 0,11,
+ 0,0
+};
+struct Border Border12 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors12,
+ NULL
+};
+
+struct IntuiText IText80 = {
+ 1,0,JAM1,
+ 4,1,
+ NULL,
+ "AutoSize",
+ NULL
+};
+
+struct Gadget AutoSizeGadget = {
+ &AutoOrgGadget,
+ 21,12,
+ 70,10,
+ SELECTED,
+ RELVERIFY+TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border12,
+ NULL,
+ &IText80,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+#define GadgetList2 AutoSizeGadget
+
+struct NewWindow NewWindowStructure2 = {
+ 0,11,
+ 292,58,
+ 0,1,
+ MOUSEBUTTONS+GADGETDOWN+GADGETUP+MENUPICK+CLOSEWINDOW+RAWKEY,
+ WINDOWDRAG+WINDOWCLOSE+REPORTMOUSE+ACTIVATE+NOCAREREFRESH,
+ &AutoSizeGadget,
+ NULL,
+ "Bobi Tool Window",
+ NULL,
+ NULL,
+ 0,0,
+ 0,0,
+ CUSTOMSCREEN
+};
+
+
+void HandleEvent(object)
+APTR object;
+{
+ if (object == (APTR)&GetBobGadget) { GetBobFunc( ); return; }
+ if (object == (APTR)&SetOrgGadget) { SetOrgFunc( ); return; }
+ if (object == (APTR)&MenuItem42) { ClearAllFunc( ); return; }
+ if (object == (APTR)&MenuItem44) { LoadBobsFunc( ); return; }
+ if (object == (APTR)&MenuItem45) { InsertBobsFunc( ); return; }
+ if (object == (APTR)&MenuItem46) { SaveBobsFunc( ); return; }
+ if (object == (APTR)&MenuItem47) { DeleteFileFunc( ); return; }
+ if (object == (APTR)&MenuItem49) { GenerateCodeFunc( ); return; }
+ if (object == (APTR)&MenuItem52) { AboutFunc( ); return; }
+ if (object == (APTR)&MenuItem54) { SleepFunc( ); return; }
+ if (object == (APTR)&MenuItem56) { QuitFunc( ); return; }
+ if (object == (APTR)&MenuItem37) { LoadPicFunc( ); return; }
+ if (object == (APTR)&MenuItem38) { GrabDPaintFunc( ); return; }
+ if (object == (APTR)&MenuItem39) { GrabScreenFunc( ); return; }
+ if (object == (APTR)&MenuItem41) { CloseScreenFunc( ); return; }
+ if (object == (APTR)&MenuItem23) { GetBobFunc( ); return; }
+ if (object == (APTR)&MenuItem24) { GetMultiFunc( ); return; }
+ if (object == (APTR)&MenuItem26) { SetOrgFunc( ); return; }
+ if (object == (APTR)&MenuItem28) { SetCollBoundsFunc( ); return; }
+ if (object == (APTR)&MenuItem30) { FlipXFunc( ); return; }
+ if (object == (APTR)&MenuItem31) { FlipYFunc( ); return; }
+ if (object == (APTR)&MenuItem32) { RotateFunc( ); return; }
+ if (object == (APTR)&MenuItem33) { ZoomFunc( ); return; }
+ if (object == (APTR)&MenuItem35) { InsertNewBobFunc( ); return; }
+ if (object == (APTR)&MenuItem36) { DeleteActBobFunc( ); return; }
+ if (object == (APTR)&MenuItem16) { LoadIFFAnimFunc( ); return; }
+ if (object == (APTR)&MenuItem17) { SaveIFFAnimFunc( ); return; }
+ if (object == (APTR)&MenuItem19) { SetFirstBobFunc( ); return; }
+ if (object == (APTR)&MenuItem20) { SetLastBobFunc( ); return; }
+ if (object == (APTR)&SubItem1) { SetAnimModeFunc( ); return; }
+ if (object == (APTR)&SubItem2) { SetAnimModeFunc( ); return; }
+ if (object == (APTR)&SubItem3) { SetAnimModeFunc( ); return; }
+ if (object == (APTR)&MenuItem22) { StartAnimFunc( ); return; }
+ if (object == (APTR)&MenuItem1) { ToolWindowFunc( ); return; }
+ if (object == (APTR)&MenuItem7) { SetMainOrgFunc( ); return; }
+ if (object == (APTR)&MenuItem9) { EditPaletteFunc( ); return; }
+ if (object == (APTR)&MenuItem11) { LoadOffsetsFunc( ); return; }
+ if (object == (APTR)&MenuItem12) { SaveOffsetsFunc( ); return; }
+ if (object == (APTR)&MenuItem14) { RemakeLabelsFunc( ); return; }
+ if (object == (APTR)&MenuItem15) { RemakeCollisionFunc( ); return; }
+}
+#define HANDLEEVENT HandleEvent
+
+/* end of PowerWindows source generation */
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..7045ed9
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,85 @@
+##
+## Bobi - The Ultimate Amiga Bob Manipulator
+##
+## COPYRIGHT (C) 1992-1994 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.
+##
+
+
+ALL: Bobi
+
+
+#############################################################################
+## Parameters und Flags
+
+PROJECT = Bobi
+
+ASM = Genam
+AFLAGS = -iINCLUDE: -l
+
+CC = sc
+CFLAGS =
+
+LD = SLINK
+LDDEF = _STACKSIZE=20000 __XCEXIT=@Exit
+LFLAGS = NOICONS ADDSYM MAP RAM:$(PROJECT).map
+
+
+#############################################################################
+## Regeln
+
+.c.o:
+ $(CC) $(CFLAGS) $*.c
+
+.S.o:
+ -@Delete $@
+ $(ASM) $(AFLAGS) $*.S
+
+
+#############################################################################
+## Module für Bobi:
+
+LIBS = LIB:scmffp.lib LIB:sc.lib LIB:small.lib LIB:debug.lib
+
+MODS = Bobi.o About.o Anim.o AREXX.o Bob.o BMapSupport.o ByteMap.o\
+ Color.o FileRequest.o Generate.o Get.o IFFAnim.o IFFError.o\
+ IMSGHandler.o Layer.o LoadBobs.o Misc.o Picture.o PropGadgets.o\
+ Rotate.o Sleep.o Stubs.o Zoom.o\
+ ConvertDate.o CreateRastPort.o GadgetSupport.o ShowRequest.o Snooze.o
+
+
+#############################################################################
+## Abhängigkeiten:
+
+$(MODS): Bobi.h BobStructure.h
+Bobi.o: MainWindow.h
+About.o: AboutWindow.h
+Generate.o: GenerateWindow.h
+Rotate.o: RotateWindow.h
+
+Startup.o: Startup.S
+ -@Delete $@
+ $(ASM) $(AFLAGS) -e DETACH=1 -e TINY=1 $*.S
+
+
+#############################################################################
+## Targets:
+
+Bobi: Startup.o $(MODS) $(LIBS)
+ -@Delete $@
+ $(LD) $(LFLAGS) FROM Startup.o $(MODS) TO $@ LIB $(LIBS) DEFINE $(LDDEF)
+
+
+install: Bobi
+ $(LD) FROM Bobi TO SYS:C-User/Proprietary/Bobi NOICONS NODEBUG
+
+clean:
+ -@Delete *.o Bobi
+
+dist:
+ -@Delete Bobi.LHA
+ -@LHA -x -a a Bobi.LHA c:Bobi Bobi.doc BobiTest.rexx BobiTest.bobs BobiTest.pic
+ -@LHA v Bobi.LHA
+
diff --git a/Misc.c b/Misc.c
new file mode 100644
index 0000000..b4d2fdb
--- /dev/null
+++ b/Misc.c
@@ -0,0 +1,204 @@
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <proto/dos.h>
+
+#include "Bobi.h"
+
+extern struct Screen *mainscreen;
+extern struct Window *mainwindow,*toolwindow;
+extern WORD options;
+extern UWORD mainpalette[],Palette[];
+extern BYTE defaultorg;
+extern struct MenuItem LayerModeMenuItem,OrgGridMenuItem,
+ BobBordersMenuItem,CollisionRectMenuItem,
+ FirstDefaultOrgSubItem;
+extern BYTE arexxflag;
+
+/****************************************************************************
+** Requester mit einem OK-Gadget anzeigen
+*/
+
+void ShowMonoReq2(char *text)
+{
+ LockWindows();
+ ShowRequest(text,0," OK ",0x8000);
+ UnLockWindows();
+}
+
+/****************************************************************************
+** Requester mit PosText und "Cancel" anzeigen
+*/
+
+BOOL ShowRequest2(char *text,char *postext)
+{
+ BOOL val;
+ LockWindows();
+ val = ShowRequest(text,postext,"CANCEL",0x8000);
+ UnLockWindows();
+ return(val);
+}
+
+/****************************************************************************
+** 'Can't open file' plus Text ausgeben
+*/
+
+void ShowFileError(char *name)
+{
+ char buf[200];
+ sprintf(buf,"Can't open file\n'%s' !",name);
+ ShowMonoReq2(buf);
+}
+
+/****************************************************************************
+** File zum Schreiben öffnen und Requester bringen falls es schon existiert
+*/
+
+BPTR OpenNewFileSafely(char *name)
+{
+ register BPTR file;
+ char buf[200];
+
+ if(!arexxflag) /* Wenn das Kommando von ARexx kommt wird nix getestet */
+ {
+ if(file=Lock(name,ACCESS_READ))
+ {
+ UnLock(file);
+ sprintf(buf,"Warning: The file\n'%s'\nexists. Save over top of it?",name);
+ if(!ShowRequest2(buf,"YES")) return 0;
+ }
+ }
+
+ if(!(file=Open(name,MODE_NEWFILE)))
+ {
+ ShowFileError(name);
+ return 0;
+ }
+
+ return file;
+}
+
+/****************************************************************************
+** Rahmen in gewünschter Farbe zeichnen
+*/
+
+void DrawRect(struct RastPort *rp,WORD x0,WORD y0,WORD x1,WORD y1,WORD col)
+{
+ SetDrMd(rp,JAM1);
+ SetAPen(rp,col);
+ Move(rp,x0,y0);
+ Draw(rp,x1,y0);
+ Draw(rp,x1,y1);
+ Draw(rp,x0,y1);
+ Draw(rp,x0,y0);
+}
+
+/****************************************************************************
+** Fadenkreuz zeichnen
+*/
+
+void DrawCross(struct Screen *screen,WORD x,WORD y)
+{
+ if(x>=0)
+ {
+ register struct RastPort *rp = &(screen->RastPort);
+ SetDrMd(rp,COMPLEMENT);
+ Move(rp,0,y);
+ Draw(rp,screen->Width-1,y);
+ Move(rp,x,0);
+ Draw(rp,x,screen->Height-1);
+ }
+}
+
+/****************************************************************************
+** MainScreen-Farbpalette setzen
+*/
+
+void LoadPalette(UWORD *pal)
+{
+ LoadRGB4(&(mainscreen->ViewPort),pal,32);
+}
+
+/****************************************************************************
+** Menus abschalten und Snooze-Pointer setzen
+*/
+
+static WORD LockCntr;
+
+void LockWindows()
+{
+ if(!LockCntr)
+ {
+ LoadPalette(Palette);
+ Snooze(mainwindow);
+ if(toolwindow) Snooze(toolwindow);
+ }
+ LockCntr++;
+}
+
+/****************************************************************************
+** Windows wieder unlocken
+*/
+
+void UnLockWindows()
+{
+ if(LockCntr>0) --LockCntr;
+
+ if(!LockCntr)
+ {
+ if(toolwindow) UnSnooze(toolwindow);
+ UnSnooze(mainwindow);
+ LoadPalette(mainpalette);
+ }
+}
+
+/****************************************************************************
+** Globale Optionen setzen und in den Menuitems updaten
+*/
+
+void SetGlobalOptions(WORD opts, BYTE deforg)
+{
+ struct MenuItem *item;
+ int i;
+
+ options = opts;
+ if(opts & GOF_LAYERMODE) LayerModeMenuItem.Flags |= CHECKED;
+ else LayerModeMenuItem.Flags &= ~CHECKED;
+ if(opts & GOF_ORGGRID) OrgGridMenuItem.Flags |= CHECKED;
+ else OrgGridMenuItem.Flags &= ~CHECKED;
+ if(opts & GOF_BOBBORDERS) BobBordersMenuItem.Flags |= CHECKED;
+ else BobBordersMenuItem.Flags &= ~CHECKED;
+ if(opts & GOF_COLLISIONRECT) CollisionRectMenuItem.Flags |= CHECKED;
+ else CollisionRectMenuItem.Flags &= ~CHECKED;
+
+ defaultorg = deforg;
+
+ for(i=0,item = &FirstDefaultOrgSubItem; item; item=item->NextItem,++i)
+ {
+ if(i == defaultorg) item->Flags |= CHECKED;
+ else item->Flags &= ~CHECKED;
+ }
+}
+
+/****************************************************************************
+** Globale Optionen aus den Menuitems auslesen
+*/
+
+void GetGlobalOptions()
+{
+ struct MenuItem *item;
+
+ options=0;
+ if(LayerModeMenuItem.Flags & CHECKED) options |= GOF_LAYERMODE;
+ if(OrgGridMenuItem.Flags & CHECKED) options |= GOF_ORGGRID;
+ if(BobBordersMenuItem.Flags & CHECKED) options |= GOF_BOBBORDERS;
+ if(CollisionRectMenuItem.Flags & CHECKED) options |= GOF_COLLISIONRECT;
+
+ defaultorg=0;
+ for(item = &FirstDefaultOrgSubItem; item; item=item->NextItem)
+ {
+ if(item->Flags & CHECKED) break;
+ defaultorg++;
+ }
+}
+
diff --git a/Picture.c b/Picture.c
new file mode 100644
index 0000000..19213fe
--- /dev/null
+++ b/Picture.c
@@ -0,0 +1,174 @@
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/dos.h>
+#include <proto/intuition.h>
+#include <intuition/intuitionbase.h>
+#include <libraries/iff.h>
+#include <graphics/gfxbase.h>
+
+#include "Bobi.h"
+#define MAX(a,b) ((a)>(b)?(a):(b))
+
+extern struct Screen *mainscreen;
+extern struct Screen *picturescreen;
+extern struct Window *picturewindow;
+
+extern UWORD mainpalette[],picturepalette[];
+
+extern char PicPath[]; /* Definiert in LoadBobs.c wegen '.bobi' */
+extern char PicName[];
+
+extern BYTE arexxflag;
+extern char arexxfilename[];
+
+static struct RastPort *picturerastport;
+
+
+/****************************************************************************
+** Ein IFF-Bild von Disk laden
+*/
+
+void LoadPicFunc()
+{
+ ULONG *formptr;
+ struct IFFL_BMHD *bmhd;
+ LONG count;
+ IFFL_HANDLE ifffile;
+ char *name;
+
+ LockWindows();
+
+ if(arexxflag)
+ name = arexxfilename;
+ else
+ name=FileRequest("Load Picture from Disk", "LOAD", PicPath, PicName);
+
+ if(name)
+ {
+ if(ifffile = IFFL_OpenIFF(name, IFFL_MODE_READ))
+ {
+ formptr = ifffile;
+ if(formptr[2]==ID_ANIM) formptr+=3;
+
+ if(bmhd = IFFL_GetBMHD(formptr))
+ {
+ CloseScreenFunc();
+ if(picturerastport = CreateRastPort(bmhd->nPlanes,
+ MAX(bmhd->w,GfxBase->NormalDisplayColumns>>1),
+ MAX(bmhd->h,GfxBase->NormalDisplayRows)))
+ {
+ static struct TagItem mytagitems[] =
+ {
+ SA_Overscan,OSCAN_TEXT,
+ SA_AutoScroll,TRUE,
+ };
+ struct ExtNewScreen ns;
+ struct NewWindow nw;
+
+ ClearMem(&ns,sizeof(ns));
+ ClearMem(&nw,sizeof(nw));
+
+ if(OSVERSION(37))
+ {
+ ns.Width = bmhd->w;
+ ns.Height = bmhd->h;
+ }
+ else
+ {
+ ns.Width = GfxBase->NormalDisplayColumns>>1;
+ ns.Height = GfxBase->NormalDisplayRows;
+ }
+ ns.Depth = bmhd->nPlanes;
+ // ns.Depth = (bmhd->nPlanes > 5) ? bmhd->nPlanes:5;
+ ns.ViewModes = IFFL_GetViewModes(formptr);
+ ns.CustomBitMap = picturerastport->BitMap;
+ ns.Type = CUSTOMSCREEN|CUSTOMBITMAP|SCREENQUIET|SCREENBEHIND|NS_EXTENDED;
+ ns.Extension = mytagitems;
+
+ nw.IDCMPFlags = IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_DELTAMOVE;
+ nw.Flags = WFLG_BACKDROP | WFLG_BORDERLESS
+ | WFLG_SIMPLE_REFRESH | WFLG_NOCAREREFRESH
+ | WFLG_REPORTMOUSE | WFLG_RMBTRAP;
+ nw.Type = CUSTOMSCREEN;
+
+ if(picturescreen = OpenScreen(&ns))
+ {
+ nw.Screen = picturescreen;
+ nw.Width = picturescreen->Width;
+ nw.Height = picturescreen->Height;
+ if(picturewindow = OpenWindow(&nw))
+ {
+ ShowTitle(picturescreen,FALSE);
+ count = IFFL_GetColorTab(formptr,(WORD *)picturepalette);
+ if(count>32) count = 32;
+ CopyMem(picturepalette,mainpalette,count*2);
+ LoadRGB4(&picturescreen->ViewPort,picturepalette,count);
+
+ if(IFFL_DecodePic(formptr,&(picturescreen->BitMap)))
+ {
+ if(!arexxflag)
+ {
+ ScreenToFront(picturescreen);
+ MoveScreen(mainscreen,0,-255);
+ MoveScreen(mainscreen,0,255);
+ Delay(15);
+ ScreenToFront(mainscreen);
+ for(count=28; count>0; --count)
+ MoveScreen(mainscreen,0,-10);
+ }
+ }
+ else
+ {
+ CloseScreenFunc();
+ ShowIFFError("Error decoding picture");
+ }
+ }
+ else
+ {
+ CloseScreenFunc();
+ ShowMonoReq2("Can't open window!");
+ }
+ }
+ else
+ {
+ CloseScreenFunc();
+ ShowMonoReq2("Can't open screen!");
+ }
+ }
+ else ShowMonoReq2("No mem for rastport!");
+ }
+ else ShowIFFError("Mangled IFF picture");
+ IFFL_CloseIFF(ifffile);
+ }
+ else ShowIFFError(name);
+
+ } /* if(FileRequest()) */
+ UnLockWindows();
+}
+
+/****************************************************************************
+** Picture-Screen schliessen und Bild freigeben
+*/
+
+void CloseScreenFunc()
+{
+ if(picturewindow)
+ {
+ CloseWindow(picturewindow);
+ picturewindow = 0;
+ }
+
+ if(picturescreen)
+ {
+ CloseScreen(picturescreen);
+ picturescreen = 0;
+ }
+
+ if(picturerastport)
+ {
+ DeleteRastPort(picturerastport);
+ picturerastport = 0;
+ }
+
+}
+
diff --git a/PropGadgets.c b/PropGadgets.c
new file mode 100644
index 0000000..dbbbd8e
--- /dev/null
+++ b/PropGadgets.c
@@ -0,0 +1,61 @@
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <proto/dos.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+
+extern struct MyBob *BobTable[];
+extern struct Window *mainwindow;
+extern struct Gadget PosPropGadget;
+extern struct PropInfo PosPropGadgetSInfo;
+extern WORD numbobs,actbobnum;
+
+/*************************************************************************/
+
+void MovePosFunc()
+{
+ register struct Message *msg;
+ register WORD oldnum=-1;
+
+ for(;;)
+ {
+ WaitTOF();
+ if(msg = GetMsg(mainwindow->UserPort))
+ {
+ ReplyMsg(msg);
+ break;
+ }
+ actbobnum = ReadBobNum();
+ if(actbobnum != oldnum)
+ {
+ ShowFrame(actbobnum);
+ /* ShowBob(BobTable[actbobnum]); */
+ oldnum = actbobnum;
+ }
+ }
+ actbobnum = ReadBobNum();
+ ShowFrame(actbobnum);
+}
+
+/*************************************************************************/
+
+WORD ReadBobNum()
+{
+ return((WORD)((((UWORD)numbobs*PosPropGadgetSInfo.VertPot)+0x7fffL)>>16));
+}
+
+/*************************************************************************/
+
+void RefreshBobNum()
+{
+ PosPropGadgetSInfo.VertBody = 0xffffL/(numbobs+1);
+ if(numbobs>0)
+ {
+ PosPropGadgetSInfo.VertPot = (actbobnum*0xffffL)/numbobs;
+ }
+ else PosPropGadgetSInfo.VertPot = 0;
+
+ RefreshGList(&PosPropGadget,mainwindow,0,1);
+}
diff --git a/Rotate.c b/Rotate.c
new file mode 100644
index 0000000..b79f803
--- /dev/null
+++ b/Rotate.c
@@ -0,0 +1,208 @@
+#include <proto/exec.h>
+#include <proto/graphics.h>
+#include <proto/intuition.h>
+#include <proto/mathffp.h>
+#include <proto/mathtrans.h>
+#include <exec/memory.h>
+#include <graphics/gfx.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+#include "ByteMap.h"
+#include "RotateWindow.h"
+
+#define PI 3.14159265358979323846
+
+extern struct MyBob *BobTable[];
+extern struct Screen *mainscreen;
+extern struct RastPort *mainrastport;
+extern UWORD mainpalette[];
+extern WORD actbobnum,mainx0,mainy0;
+
+/*************************************************************************/
+
+static void RotateBobs(register LONG numframes, register LONG totangle)
+{
+ struct ByteMap *sbym,*dbym;
+ register struct BitMap *sbim,*dbim;
+ register WORD width,height;
+ register struct MyBob *bob,*sbob=BobTable[actbobnum];
+
+
+ if(sbob->Flags & BOBF_AUTOSIZE)
+ {
+ register float wq,hq;
+ wq = SPFlt(sbob->Width); wq = SPMul(wq,wq);
+ hq = SPFlt(sbob->Height); hq = SPMul(hq,hq);
+ width = height = SPFix(SPSqrt(SPAdd(wq,hq)))+1;
+ }
+ else
+ {
+ width = sbob->Width; height = sbob->Height;
+ }
+
+ if(sbym=MakeByteMap(width,height))
+ {
+ if(dbym=MakeByteMap(width,height))
+ {
+ if(sbim=BobToBitMap(sbob))
+ {
+ if(dbim=MakeBitMap(width,height,sbob->Depth))
+ {
+ register LONG i;
+
+ BltBitMap(sbim,0,0,dbim,(width-sbob->Width)/2,
+ (height-sbob->Height)/2,sbob->Width,sbob->Height,0xc0,0xff,0);
+ BitMapToByteMap(dbim,sbym);
+ for(i=numframes; i>0; --i)
+ {
+ register float winkel;
+ register LONG si,co;
+
+ winkel = SPMul((float)(totangle*i)/numframes,PI/180.0);
+ si = SPFix(SPMul(SPSin(winkel),1024.0)); /* 10 Dualstellen */
+ co = SPFix(SPMul(SPCos(winkel),1024.0));
+
+ RotateByteMap(sbym,dbym,width/2,height/2,si,co);
+ ByteMapToBitMap(dbym,dbim);
+
+ if(bob=BitMapToBob(sbob,dbim,width))
+ {
+ ShowBob(bob);
+ InsertBob(bob,(WORD)(actbobnum+1));
+ }
+ else
+ {
+ ShowMonoReq2("No memory for new bobs,\nrotation cancelled.");
+ break;
+ }
+ }
+ MyFreeBitMap(dbim);
+ }
+ else ShowMonoReq2("Not enough memory for rotate!");
+ MyFreeBitMap(sbim);
+ }
+ else ShowMonoReq2("Not enough memory for rotate!");
+ FreeByteMap(dbym);
+ }
+ else ShowMonoReq2("Not enough memory for rotate!");
+ FreeByteMap(sbym);
+ }
+ else ShowMonoReq2("Not enough memory for rotate!");
+}
+
+/*************************************************************************/
+
+void RotateFunc()
+{
+ register struct Window *w;
+
+ if(!BobTable[actbobnum])
+ {
+ ShowMonoReq2("Select a bob to rotate!");
+ return;
+ }
+
+ LockWindows();
+ NewWindowStructure1.Screen = mainscreen;
+ if(w=OpenWindow(&NewWindowStructure1))
+ {
+ register WORD flag = 0;
+
+ do
+ {
+ register struct IntuiMessage *msg;
+
+ WaitPort(w->UserPort);
+ msg=(struct IntuiMessage *)GetMsg(w->UserPort);
+ if(msg->Class == CLOSEWINDOW)
+ {
+ flag = -1;
+ }
+ else if(msg->Class == GADGETUP)
+ {
+ if(msg->IAddress == (APTR)&OKGadget)
+ {
+ flag = 1;
+ }
+ else if(msg->IAddress == (APTR)&CancelGadget)
+ {
+ flag = -1;
+ }
+ }
+ } while(!flag);
+ CloseWindow(w);
+ LoadPalette(mainpalette);
+
+ if(flag>0)
+ {
+ register LONG i;
+ register struct MyBob *bob;
+
+ RotateBobs(FramesGadgetSInfo.LongInt,AngleGadgetSInfo.LongInt);
+
+ for(i=1; i<=FramesGadgetSInfo.LongInt; ++i)
+ {
+ if(bob=AutoResizeBob(BobTable[actbobnum+i]))
+ {
+ FreeBob(BobTable[actbobnum+i]);
+ BobTable[actbobnum+i] = bob;
+ ShowBob(bob);
+ }
+ else ShowMonoReq2("Rotate:noresize");
+ }
+ }
+ }
+ UnLockWindows();
+}
+
+/*************************************************************************/
+
+static void FlipXYBob(BOOL xflag)
+{
+ register struct MyBob *bob;
+ register struct BitMap *bim;
+ struct ByteMap *bym;
+ register struct MyBob *flippedbob;
+
+ if(bob=BobTable[actbobnum])
+ {
+ if(bim=BobToBitMap(bob))
+ {
+ if(bym=MakeByteMap(bob->Width,bim->Rows))
+ {
+ BitMapToByteMap(bim,bym);
+ if(xflag)
+ {
+ FlipXByteMap(bym);
+ bob->X0 = bob->Width-bob->X0;
+ /* if(bob->X0 < 0) bob->X0 = 0;
+ */ }
+ else
+ {
+ FlipYByteMap(bym);
+ bob->Y0 = bob->Height-bob->Y0;
+ /* if(bob->Y0 < 0) bob->Y0 = 0;
+ */ }
+ ByteMapToBitMap(bym,bim);
+ FreeByteMap(bym);
+ if(flippedbob=BitMapToBob(bob,bim,bob->Width))
+ {
+ FreeBob(bob);
+ BobTable[actbobnum]=flippedbob;
+ }
+ else ShowMonoReq2("No memory to flip bob!");
+ }
+ else ShowMonoReq2("No memory to flip bob!");
+ MyFreeBitMap(bim);
+ }
+ else ShowMonoReq2("No memory to flip bob!");
+ }
+ else ShowMonoReq2("Select a bob to flip, you fool!");
+}
+
+/*************************************************************************/
+
+void FlipXFunc(void) { FlipXYBob(TRUE); }
+void FlipYFunc(void) { FlipXYBob(FALSE); }
+
diff --git a/RotateWindow.h b/RotateWindow.h
new file mode 100644
index 0000000..6c0a990
--- /dev/null
+++ b/RotateWindow.h
@@ -0,0 +1,202 @@
+
+static UBYTE FramesGadgetSIBuff[5] =
+ "36";
+static struct StringInfo FramesGadgetSInfo = {
+ FramesGadgetSIBuff,
+ NULL,
+ 0,
+ 5,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 36,
+ NULL
+};
+
+static SHORT BorderVectors1[] = {
+ 0,0,
+ 174,0,
+ 174,12,
+ 0,12,
+ 0,1
+};
+static struct Border Border1 = {
+ -1,-3,
+ 3,0,JAM1,
+ 5,
+ BorderVectors1,
+ NULL
+};
+
+static struct IntuiText IText1 = {
+ 3,0,JAM1,
+ 4,0,
+ NULL,
+ "# of Frames",
+ NULL
+};
+
+static struct Gadget FramesGadget = {
+ NULL,
+ 6,34,
+ 173,11,
+ NULL,
+ RELVERIFY+STRINGRIGHT+LONGINT,
+ STRGADGET,
+ (APTR)&Border1,
+ NULL,
+ &IText1,
+ NULL,
+ (APTR)&FramesGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static UBYTE AngleGadgetSIBuff[5] =
+ "360";
+static struct StringInfo AngleGadgetSInfo = {
+ AngleGadgetSIBuff,
+ NULL,
+ 0,
+ 5,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 360,
+ NULL
+};
+
+static SHORT BorderVectors2[] = {
+ 0,0,
+ 174,0,
+ 174,12,
+ 0,12,
+ 0,1
+};
+static struct Border Border2 = {
+ -1,-3,
+ 3,0,JAM1,
+ 5,
+ BorderVectors2,
+ NULL
+};
+
+static struct IntuiText IText2 = {
+ 3,0,JAM1,
+ 4,0,
+ NULL,
+ "Angle (Total)",
+ NULL
+};
+
+static struct Gadget AngleGadget = {
+ &FramesGadget,
+ 6,17,
+ 173,11,
+ NULL,
+ RELVERIFY+STRINGRIGHT+LONGINT,
+ STRGADGET,
+ (APTR)&Border2,
+ NULL,
+ &IText2,
+ NULL,
+ (APTR)&AngleGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors3[] = {
+ 0,0,
+ 81,0,
+ 81,12,
+ 0,12,
+ 0,0
+};
+static struct Border Border3 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors3,
+ NULL
+};
+
+static struct IntuiText IText3 = {
+ 1,0,JAM1,
+ 16,2,
+ NULL,
+ "ROTATE",
+ NULL
+};
+
+static struct Gadget OKGadget = {
+ &AngleGadget,
+ 6,-15,
+ 80,11,
+ GRELBOTTOM,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border3,
+ NULL,
+ &IText3,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors4[] = {
+ 0,0,
+ 81,0,
+ 81,12,
+ 0,12,
+ 0,0
+};
+static struct Border Border4 = {
+ -1,-1,
+ 31,0,JAM1,
+ 5,
+ BorderVectors4,
+ NULL
+};
+
+static struct IntuiText IText4 = {
+ 31,0,JAM1,
+ 16,2,
+ NULL,
+ "CANCEL",
+ NULL
+};
+
+static struct Gadget CancelGadget = {
+ &OKGadget,
+ -85,-15,
+ 80,11,
+ GRELBOTTOM+GRELRIGHT,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border4,
+ NULL,
+ &IText4,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+#define GadgetList1 CancelGadget
+
+static struct NewWindow NewWindowStructure1 = {
+ 63,39,
+ 185,70,
+ 0,1,
+ GADGETUP+CLOSEWINDOW,
+ WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH,
+ &CancelGadget,
+ NULL,
+ " Rotate Bobs ",
+ NULL,
+ NULL,
+ 5,5,
+ (UWORD)-1,(UWORD)-1,
+ CUSTOMSCREEN
+};
diff --git a/SCOPTIONS b/SCOPTIONS
new file mode 100644
index 0000000..504d97c
--- /dev/null
+++ b/SCOPTIONS
@@ -0,0 +1,24 @@
+MATH=FFP
+PARAMETERS=REGISTERS
+NOSTACKCHECK
+STRINGMERGE
+UNSIGNEDCHARS
+STRUCTUREEQUIVALENCE
+OPTIMIZE
+MAP
+MAPHUNK
+MAPSYMBOLS
+MAPLIB
+MAPXREFERENCE
+MAPOVERLAY
+NOVERSION
+NOICONS
+MEMORYSIZE=HUGE
+INCLUDEDIR=SC:Include
+INCLUDEDIR=INCUSR:
+DEFINE __USE_SYSBASE
+CODENAME=text
+DATANAME=data
+BSSNAME=bss
+MAPFILE=RAM:slink.map
+MAXIMUMWARNINGS=50
diff --git a/ShowRequest.c b/ShowRequest.c
new file mode 100644
index 0000000..a995a41
--- /dev/null
+++ b/ShowRequest.c
@@ -0,0 +1,293 @@
+/**************************************************************************
+** **
+** ShowRequest - Super-Requester unter dem Mauspfeil ausgeben **
+** **
+*+ Original version by René Straub 18-Jul-89 +*
+*+ +*
+*+ Modification History: +*
+*+ -------------------- +*
+*+ +*
+*+ 23-Jul-89 CHW Created this file (99% rewritten :-) +*
+*+ 08-Aug-89 CHW Zulange Textzeilen werden automatisch getrennt +*
+*+ 06-Oct-89 CHW ShowMonoReq() hier hereingenommen +*
+*+ 31-Oct-89 CHW ToUpper-Bug bei VANILLAKEY fixed +*
+*+ 04-Nov-89 CHW ToUpper-Bug bei VANILLAKEY really fixed, Amiga-v/b +*
+*+ 05-Nov-89 CHW No more gurus if word longer than 1 line +*
+*+ 18-Jul-90 CHW itext->Font is now set for IntuiTextLength() +*
+*+ 02-Nov-93 CHW Benutzt jetzt strlen statt StrLen (->Bobi) +*
+*+ +*
+***************************************************************************
+** **
+** Parameter : A0.L : Zeiger auf Text, Linien durch \n getrennt **
+** A1.L : Zeiger auf PosText **
+** A2.L : Zeiger auf NegText **
+** D0.W : Bit 0: 1=Default PosText, 0=Default NegText **
+** Bit 15: 1=Text hat Schatten, 0=normal **
+** **
+** Resultat : D0.L :  0=NegText angewählt, 1=PosText angewählt **
+** **
+**************************************************************************/
+
+/* #define DEBUG */
+
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/graphics.h>
+#include <exec/memory.h>
+#include <intuition/intuition.h>
+#include <intuition/intuitionbase.h>
+#include <libraries/dosextens.h>
+
+#include <string.h>
+
+#include "Bobi.h"
+
+
+extern struct IntuitionBase *IntuitionBase;
+
+#define reg register
+#define MAXTEXTLENGTH 160 /* Maximale Länge einer Textzeile */
+#define REQF_DEFAULT 1 /* Gadget unter dem Mauszeiger */
+#define REQF_SHADOW 0x8000 /* Text hat Schatten */
+
+struct MyIText
+{
+ struct IntuiText ShadowIText;
+ struct IntuiText IText;
+ char Text[MAXTEXTLENGTH];
+};
+
+/*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*/
+
+static BYTE alerttext[] = {
+ 0, 24, 14,
+ 'N','o',' ','m','e','m',' ','f','o','r',' ','r','e','q','u','e','s','t','e','r',
+ 0, 0, 0
+};
+
+/*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*/
+
+static WORD PosBorderVecs[] = { 0,0, -1,0, -1,12, 0,12, 0,1 };
+static WORD NegBorderVecs[] = { 0,0, -1,0, -1,12, 0,12, 0,1 };
+
+static struct Border PosBorder = {
+ -3,-2,1,0,0,5,PosBorderVecs,NULL
+};
+static struct Border NegBorder = {
+ -3,-2,1,0,0,5,NegBorderVecs,NULL
+};
+
+static struct IntuiText PosIText = {
+ 1,0,JAM1,2,1,NULL,NULL,NULL
+};
+static struct IntuiText NegIText = {
+ 1,0,JAM1,2,1,NULL,NULL,NULL
+};
+
+static struct Gadget PosGadget = {
+ NULL,10,-1234,1234,1234,GRELBOTTOM,RELVERIFY,BOOLGADGET,
+ (APTR)&PosBorder,NULL,&PosIText,NULL,NULL,NULL,NULL
+};
+static struct Gadget NegGadget = {
+ &PosGadget,-1234,-1234,1234,1234,GRELBOTTOM|GRELRIGHT,RELVERIFY,BOOLGADGET,
+ (APTR)&NegBorder,NULL,&NegIText,NULL,NULL,NULL,NULL
+};
+
+/*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*/
+
+LONG ShowRequest(char *text, char *postext, char *negtext, ULONG flags)
+{
+ struct NewWindow nw;
+ struct Window *w,*prwindow;
+ struct Screen *s;
+ struct MyIText itext;
+ register struct MyIText *iptr=&itext;
+ UWORD poswidth,negwidth;
+ register LONG endflag=-1;
+
+ /* NewWindow-Struktur initialisieren */
+
+ ClearMem(&nw,sizeof(nw));
+ nw.Width=180;
+ nw.Height=4;
+
+ /* Zeiger auf Screen holen und nw entsprechend anpassen */
+
+ if (prwindow=(struct Window *)(((struct Process *)FindTask(0L))->pr_WindowPtr))
+ {
+ nw.DetailPen = prwindow->DetailPen;
+ nw.BlockPen = prwindow->BlockPen;
+ nw.Screen= s = prwindow->WScreen;
+ nw.Type = CUSTOMSCREEN;
+ ScreenToFront(s);
+ }
+ else
+ {
+ WBenchToFront();
+ nw.DetailPen = 0;
+ nw.BlockPen = 1;
+ nw.Screen = 0;
+ nw.Type = WBENCHSCREEN;
+ s = IntuitionBase->FirstScreen;
+ }
+
+ /* Gadgets und IntuiTexts initialisieren */
+
+ itext.IText.NextText = 0;
+ NegIText.ITextFont = s->Font;
+ PosIText.ITextFont = s->Font;
+ NegIText.IText = negtext;
+ PosIText.IText = postext;
+ NegGadget.Width = negwidth=IntuiTextLength(&NegIText)+4;
+ PosGadget.Width = poswidth=IntuiTextLength(&PosIText)+4;
+ NegBorderVecs[2] = NegBorderVecs[4] = negwidth+5;
+ PosBorderVecs[2] = PosBorderVecs[4] = poswidth+5;
+ NegGadget.Height = s->RastPort.TxHeight+2;
+ PosGadget.Height = s->RastPort.TxHeight+2;
+ NegBorderVecs[5] = NegBorderVecs[7] = NegGadget.Height+3;
+ PosBorderVecs[5] = PosBorderVecs[7] = PosGadget.Height+3;
+ PosBorder.FrontPen = PosIText.FrontPen = flags&REQF_DEFAULT ? 3:1;
+ NegBorder.FrontPen = NegIText.FrontPen = flags&REQF_DEFAULT ? 1:3;
+ NegGadget.LeftEdge = -negwidth-10;
+ NegGadget.TopEdge = PosGadget.TopEdge = -NegGadget.Height-4;
+ NegGadget.NextGadget = postext?&PosGadget:0; /* PosGadget ein/aus */
+
+ if(nw.Width < (negwidth+poswidth+18)) nw.Width=negwidth+poswidth+18;
+
+ do
+ {
+ register char *dptr;
+ register LONG ilen;
+
+ nw.Height += s->RastPort.TxHeight+2;
+ iptr->IText.NextText=AllocMem(sizeof(*iptr),MEMF_CLEAR);
+ if(!(iptr=(struct MyIText *)iptr->IText.NextText)) break;
+ iptr->ShadowIText.NextText = &(iptr->IText);
+ iptr->IText.LeftEdge = 8;
+ iptr->ShadowIText.LeftEdge = 10;
+ iptr->IText.TopEdge = nw.Height;
+ iptr->ShadowIText.TopEdge = nw.Height+1;
+ iptr->IText.FrontPen = 1;
+ iptr->ShadowIText.FrontPen = 2;
+ iptr->IText.IText=iptr->ShadowIText.IText=dptr=iptr->Text;
+
+ for(;;)
+ {
+ register ULONG olddptr=(ULONG)dptr,oldtext=(ULONG)text;
+
+ while((*dptr=*text) > ' ') { text++; dptr++; } *dptr=0;
+ if((ilen=TextLength(&s->RastPort,iptr->Text, strlen(iptr->Text)))
+ > (s->Width-20))
+ {
+ dptr=(char *)olddptr;
+ if(dptr!=iptr->Text) /* Falls nicht 1. Wort d.Zeile (überlang) */
+ {
+ *dptr=0; /* String vor nächstem Wort begrenzen */
+ text=(char *)oldtext-1; /* Source-Ptr zurückstellen */
+ }
+ break;
+ }
+ if(*text != ' ') break;
+ *dptr++=*text++;
+ }
+
+ if(ilen > nw.Width) nw.Width=ilen;
+ if(!(flags & REQF_SHADOW)) iptr->ShadowIText.IText=0;
+ }
+ while(*text++);
+ nw.Height += (s->RastPort.TxHeight<<1)+14;
+
+ nw.Width += 16;
+ nw.LeftEdge = flags&REQF_DEFAULT?s->MouseX-24:s->MouseX-nw.Width+24;
+ nw.TopEdge = s->MouseY-nw.Height+12;
+ nw.IDCMPFlags = GADGETUP|VANILLAKEY;
+ nw.Flags = WINDOWDRAG+WINDOWDEPTH+ACTIVATE+NOCAREREFRESH+RMBTRAP;
+ nw.FirstGadget = &NegGadget;
+ nw.Title = "Click to continue";
+ nw.Screen = s;
+
+ if(nw.Width > s->Width) nw.Width =s->Width;
+ if(nw.Height > s->Height) nw.Height=s->Height;
+
+
+ /* Randbegrenzungen abfragen */
+ {
+ register WORD maxx0=s->Width-nw.Width,maxy0=s->Height-nw.Height;
+
+ if(nw.LeftEdge<0) nw.LeftEdge = 0;
+ if(nw.TopEdge<0) nw.TopEdge = 0;
+ if(nw.LeftEdge>maxx0) nw.LeftEdge = maxx0;
+ if(nw.TopEdge>maxy0) nw.TopEdge = maxy0;
+ }
+
+ if(w=OpenWindow(&nw))
+ {
+ register struct IntuiMessage *msg;
+ register LONG code;
+
+ /* Pos/NegText raufsetzen, damit Taste geht wenn's Spaces davor hat */
+
+ if(postext) while(*postext <= ' ') postext++;
+ while(*negtext <= ' ') negtext++;
+
+ PrintIText(w->RPort,itext.IText.NextText,0,0);
+ do
+ {
+ WaitPort(w->UserPort);
+ msg = (struct IntuiMessage *)GetMsg(w->UserPort);
+ code = msg->Code;
+
+ switch(msg->Class)
+ {
+ case VANILLAKEY:
+ code &= 0xDF; /* ToUpper */
+ if(msg->Qualifier & AMIGALEFT)
+ {
+ if(code=='V') endflag=TRUE;
+ if(code=='B') endflag=FALSE;
+ break;
+ }
+ if(!postext) { endflag=FALSE; break; }
+ if(code==13) { endflag=flags&REQF_DEFAULT; }
+ if(code==(*postext&0xDF)) endflag=TRUE;
+ if(code==(*negtext&0xDF)) endflag=FALSE;
+ break;
+
+ default: /* case GADGETUP: */
+ endflag = (msg->IAddress==(APTR)&PosGadget);
+ break;
+ }
+ ReplyMsg((struct Message *)msg);
+ }
+ while(endflag<0);
+ CloseWindow(w);
+ }
+ else
+ {
+#ifdef DEBUG
+ for(iptr=(struct MyIText *)itext.IText.NextText; iptr; iptr=(struct MyIText *)iptr->IText.NextText)
+ {
+ printf("'%s'\n",iptr->IText.IText);
+ }
+ printf("\nWindow: %ld/%ld %ld/%ld\n",nw.LeftEdge,nw.TopEdge,nw.Width,nw.Height);
+#endif
+ DisplayAlert(0,alerttext,24);
+ endflag=FALSE;
+ }
+
+ for(iptr=(struct MyIText *)itext.IText.NextText; iptr;)
+ {
+ register struct MyIText *temp=iptr;
+ iptr = (struct MyIText *)iptr->IText.NextText;
+ FreeMem(temp,sizeof(*temp));
+ }
+
+ return endflag;
+}
+
+/*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*/
+
+void __regargs ShowMonoReq(char *text)
+{
+ ShowRequest(text,0," OK ",REQF_SHADOW);
+}
diff --git a/Sleep.c b/Sleep.c
new file mode 100644
index 0000000..550f932
--- /dev/null
+++ b/Sleep.c
@@ -0,0 +1,56 @@
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <graphics/gfxbase.h>
+#include <string.h>
+
+#include "Bobi.h"
+
+extern struct GfxBase *GfxBase;
+extern struct Screen *mainscreen;
+extern char idstring[];
+extern UWORD mainpalette[];
+extern ULONG rexxsigmask;
+
+/****************************************************************************
+** Screen und so schliessen und schlafen gehn
+*/
+
+void SleepFunc(void)
+{
+ struct Screen *wb;
+
+ static struct NewWindow NewW =
+ {
+ -1,-1,-1,-1,0,1,CLOSEWINDOW,
+ WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+NOCAREREFRESH,
+ NULL,NULL,idstring,NULL,NULL,0,0,(UWORD)-1,(UWORD)-1,WBENCHSCREEN
+ };
+
+ if(wb=(void *)OpenWorkBench())
+ {
+ struct Window *w;
+
+ if(NewW.LeftEdge<0)
+ {
+ NewW.Width = 85+8*strlen(idstring);
+ NewW.Height = wb->RastPort.TxHeight+3;
+ NewW.LeftEdge = wb->Width-NewW.Width;
+ NewW.TopEdge = wb->Height-NewW.Height;
+ }
+
+ if(w=OpenWindow(&NewW))
+ {
+ Cleanup(FALSE);
+ Wait(SIGMASK(w)|rexxsigmask);
+ NewW.LeftEdge = w->LeftEdge;
+ NewW.TopEdge = w->TopEdge;
+ CloseWindow(w);
+ OpenMain();
+ LoadPalette(mainpalette);
+ RexxMsgHandler();
+ }
+ else ShowMonoReq2("Can't open sleep window!");
+ }
+ else ShowMonoReq2("Can't open the Workbench screen!");
+}
+
diff --git a/Snooze.S b/Snooze.S
new file mode 100644
index 0000000..44e9737
--- /dev/null
+++ b/Snooze.S
@@ -0,0 +1,95 @@
+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
+*+ +*
+*+ Snooze - ZZ-Mauszeiger setzen/löschen +*
+*+ +*
+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
+*+ +*
+*+ Modification History: +*
+*+ -------------------- +*
+*+ +*
+*+ 17-Dec-87 CHW Created this file! +*
+*+ 20-Jan-90 CHW Uses w->UserData instead of static var -> reentrant +*
+*+ +*
+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*+*
+
+ IDNT Snooze
+ SECTION text,CODE
+
+ INCLUDE "exec/macros.i"
+ INCLUDE "intuition/intuition.i"
+
+
+ XREF _IntuitionBase
+ XDEF @Snooze,@UnSnooze
+
+
+**************************************************************************
+** **
+** Snooze - Mauszeiger für bestimmtes Window auf zz setzen **
+** und Menus abschalten **
+** **
+** WARNUNG: Benutzt wd_UserData als Zwischenspeicher für MenuStrip **
+** **
+** Parameter : A0.L : Adresse der Window-Struktur **
+** Resultat : ALLE REGISTER BLEIBEN ERHALTEN **
+** **
+**************************************************************************
+
+@Snooze: movem.l d0-d3/a0-a2/a6,-(SP)
+ movea.l a0,a2 ; A2 : WindowPtr
+
+ *+* Snooze-Pointer anzeigen
+
+ movea.l a2,a0 ; Window
+ lea SnoozeDaten,a1 ; Snooze-Pointer
+ moveq #24,d0 ; Height
+ moveq #16,d1 ; Width
+ moveq #-8,d2 ; Xoffset
+ moveq #-3,d3 ; Yoffset
+ movea.l _IntuitionBase,a6
+ JSRLIB SetPointer
+
+98$: movea.l a2,a0 ; Window
+ move.l wd_MenuStrip(a0),wd_UserData(a0)
+ JSRLIB ClearMenuStrip ; Menus disable
+
+99$: movem.l (SP)+,d0-d3/a0-a2/a6
+ rts
+
+
+**************************************************************************
+** **
+** UnSnooze - Mauszeiger für bestimmtes Window wieder zurücksetzen **
+** und Menus wieder anschalten **
+** **
+** Parameter : A0.L : Adresse der Window-Struktur **
+** Resultat : ALLE REGISTER BLEIBEN ERHALTEN **
+** **
+**************************************************************************
+
+@UnSnooze: movem.l d0-d1/a0-a2/a6,-(SP)
+ movea.l a0,a2
+ movea.l _IntuitionBase,a6
+ JSRLIB ClearPointer
+ movea.l a2,a0 ; Window
+ movea.l wd_UserData(a2),a1 ; Geretteter MenuStrip
+ JSRLIB SetMenuStrip
+
+ movem.l (SP)+,d0-d1/a0-a2/a6
+ rts
+
+
+ SECTION datachip,DATA_C
+
+SnoozeDaten: dc.w $0000,$0000
+ dc.w $0600,$0000,$0F40,$0600,$3FE0,$0F40
+ dc.w $7FF0,$3FE0,$FFF0,$7FE0,$E1F8,$7FF0
+ dc.w $FBFC,$7FF8,$F7FC,$FFF8,$E1FE,$7FFC
+ dc.w $FF0E,$7FFC,$7FDE,$3FFE,$FFBE,$7FFC
+ dc.w $7F0E,$3FFC,$3FFC,$1FF8,$1FF8,$07F0
+ dc.w $07F0,$01C0,$0FC0,$0700,$1FE0,$0FC0
+ dc.w $0FC0,$0680,$07C0,$0000,$03E0,$01C0
+ dc.w $07F0,$03E0,$03E0,$00C0,$00C0,$0000
+ dc.w $0000,$0000
+
+ END
diff --git a/Startup.S b/Startup.S
new file mode 100644
index 0000000..503bc3f
--- /dev/null
+++ b/Startup.S
@@ -0,0 +1,406 @@
+*****************************************************************************
+** **
+** S T A R T U P - Universeller Startup-Code für Workbench und CLI **
+** **
+** by Christian A. Weber, Zürich/Switzwerland **
+** **
+*****************************************************************************
+** **
+** Universeller Startup-Code für CLI und WorkBench, öffnet die dos- **
+** library (DOSBase), schreibt Adresse unseres Tasks nach 'Process- **
+** Base'. Falls wir von der WorkBench gestartet wurden, wird die **
+** WorkBenchStartupMessage abgeholt und auf unser Directory ein Cur- **
+** rentDir() gemacht. Alle Register bleiben erhalten (BCPL...), **
+** z.B. steht bei Start vom CLI in D0 die Länge der Argument-Zeile, **
+** und in A0 steht ein Zeiger darauf. Bei Start von der WorkBench **
+** steht in D0 eine 0 und in A0 ein Zeiger auf die WBStartupMessage. **
+** **
+** Das Programm kann durch RTS beendet werden (ReturnCode D0) oder **
+** mittels der Routinen '@Exit' oder '@exit' (auch ReturnCode D0). **
+** **
+*****************************************************************************
+** **
+** Es existieren zur Zeit 3 verschiedene Versionen: **
+** **
+** Startup.o - Standard Startup-Code **
+** **
+** DetachStartup.o - Hängt sich vom CLI ab **
+** Die Stacksize des Prozesses kann beim Linken **
+** mit DEFINE _STACKSIZE=12345 angegeben werden. **
+** **
+** TinyStartup.o - Öffnet keine Windows, kein StdIn/Out/Err **
+** **
+*****************************************************************************
+** **
+** Modification History **
+** -------------------- **
+** **
+** 07-Sep-87 V1.0 Project started **
+** **
+** 01-Feb-88 V1.5 Versteht nun Strings in Gänsefüßchen (tnx JMH) **
+** 17-Jun-88 V1.6 'dos.library' moved from data to code segment **
+** 12-Jul-88 V2.0 _CliParse extracted to separate file, no stack **
+** 16-Nov-88 V2.1 Gründlich aufgeräumt, ist jetzt nur in chw.lib **
+** 21-Nov-88 V2.2 Default-StdWindowName added **
+** 02-Jan-88 V2.3 Default-StdWindowName wieder rausgeworfen **
+** 06-Feb-89 V2.4 An neues Library-Konzept angepasst (Labelnamen) **
+** 10-Feb-89 V2.5 Läuft nun auch mit Lattice asm und C **
+** 12-Feb-89 V2.6 Läuft nun auch mit SmallCode Aztec C **
+** 18-Mar-89 V3.0 Detach added (tnx CHH!) **
+** 02-Apr-89 V3.1 Lattice exit() has now registerized parameters **
+** 25-Jun-89 V3.2 An Genim2 angepasst und gekürzt, Detach besser **
+** 16-Jul-89 V3.3 Prozessname bei Detach stimmt wieder **
+** 12-Aug-89 V3.4 stderr implementiert **
+** 25-Sep-89 V3.5 ARP version implementiert **
+** 03-Nov-89 V3.6 Tiny-Version (ohne stdin/out/err/window) impl. **
+** 12-Jan-90 V3.7 ARP-Version von Exit rettet D2 (für result2) **
+** 15-Jan-90 V3.8 ARP-Version in separaten Source verlegt **
+** 21-Jul-90 V3.9 NewOS-Flag added (nicht im TinyStartup) **
+** 22-Jul-90 V4.0 Öffnet GfxBase und IntuitionBase **
+** 05-May-91 V4.1 NewOS erst ab V37 (früher V36) **
+** 30-May-91 V4.2 _STACKSIZE von ARPStartup auch hier eingebaut **
+** 21-Jul-91 V4.3 BSS-Bereich wird gelöscht -> kürzere Programme **
+** 02-Apr-92 V4.4 Genam statt asm -> Detach läuft wieder **
+** **
+*****************************************************************************
+
+ IDNT Startup
+ SECTION text,CODE
+
+ INCLUDE "exec/types.i"
+ INCLUDE "exec/macros.i"
+ INCLUDE "exec/execbase.i"
+ INCLUDE "dos/dosextens.i"
+ INCLUDE "workbench/startup.i"
+
+*****************************************************************************
+** Referenzen
+
+ XREF @Main ; Hauptprogramm, das aufgerufen wird
+
+ XREF _LinkerDB ; Start des Datenbereichs
+ XREF __BSSBAS ; Start des __MERGED BSS-Bereichs
+ XREF __BSSLEN ; Länge in LONGS des __MERGED BSS-Bereichs
+
+ IFD DETACH
+ XREF _STACKSIZE ; Grösse des Stapels
+ ENDC
+
+ IFND TINY
+ XREF _StdWindowName ; Workbench-Window-Name, z.B. 'NIL:'
+ ENDC
+
+*****************************************************************************
+** Definitionen
+
+ XDEF _geta4 ; A4 holen für Small Data
+ XDEF @exit,@Exit ; Fehler-Ausgang
+ XDEF _SysBase
+ XDEF _DOSBase
+ XDEF _ProcessBase ; Zeiger auf unseren Prozess
+ IFND TINY
+ XDEF StdErr,_StdErr ; Immer CLI-Window oder WB-Window
+ XDEF NewOS,_NewOS ; Flag ob Kick 2.x
+ ENDC
+
+*****************************************************************************
+** Einsprung
+
+FirstByte:
+ bra.b _WbStartup
+ ;; dc.w $4AFC ; ARP Magic
+ ;; dc.l _STACKSIZE ; ARP StackSize
+ ;; dc.l 0 ; ARP data size if resident
+
+ dc.b "CHW",0 ; Für mein Ego :-)
+ dc.b "4.4",0 ; Startup-Version
+
+DOSName: dc.b "dos.library",0
+
+ *** A4 holen, Testen ob 2. Durchgang von Detach
+
+_WbStartup: bsr _geta4
+
+ IFD DETACH
+ tst.b FirstTime(a4) ; 1. Mal hier ?
+ bne SecondTime ; nein --->
+ ENDC
+
+ *** BSS-Bereich löschen
+
+ lea __BSSBAS(a4),a3 ; get base of BSS
+ move.l #__BSSLEN,d3 ; get length of BSS in longwords
+ bra.b .ClearDBF ; and clear for length given
+.ClearLoop: clr.l (a3)+
+.ClearDBF: dbf d3,.ClearLoop
+
+ IFD DETACH
+ st.b FirstTime(a4) ; Flag setzen (jaja erst hier :-( )
+ ENDC
+
+ *** D0/A0/SP retten, ExecBase und ThisTask holen
+
+ movem.l d0/a0/a7,InitRegs(a4)
+ movea.l (4).W,a6
+ move.l a6,_SysBase(a4)
+ movea.l ThisTask(a6),a3 ; A3 : Task/Process pointer
+
+ *** DOS öffnen, Verzweigung WorkBench/CLI
+
+ lea DOSName(PC),a1
+ JSRLIB OldOpenLibrary ; DOS-Bibliothek öffnen
+ movea.l d0,a6 ; A6 : DOSBase
+ move.l a6,_DOSBase(a4)
+ IFND TINY
+ cmpi.w #36,LIB_VERSION(a6)
+ scc.b NewOS(a4) ; Flag setzen falls Kick 2.x
+ ENDC
+ move.l pr_CLI(a3),d0 ; Vom CLI aufgerufen ?
+ beq FromWorkBench ; nein --->
+
+***************** *****************************************************
+** Start vom CLI
+
+ *** Falls erwünscht detachen
+
+ IFD DETACH
+ lsl.l #2,d0 ; BPTR to APTR
+ movea.l d0,a2 ; A2 : struct CLI
+ move.l cli_Module(a2),CliSegList(a4) ; SegList retten
+ clr.l cli_Module(a2) ; für CLI löschen
+
+ move.l pr_CurrentDir(a3),d1 ; Unser CurrentDir
+ JSRLIB DupLock ; duplizieren
+ move.l d0,ActDir(a4) ; und merken
+
+ *** Kommandozeile in unseren Buffer kopieren
+
+CopyCmdLine: movea.l InitialA0(a4),a0 ; Original-ArgLine
+ lea CommandLine,a1 ; Unsere ArgLine
+ move.l a1,InitialA0(a4) ; reinpatchen
+1$: move.b (a0),(a1)+ ; char kopieren
+ beq.s 2$ ; ---> fertig
+ cmpi.b #10,(a0)+ ; Endmarkierung ?
+ bne.b 1$ ; nein ---> Loop
+2$: clr.b (a1)+ ; Endmarkierung
+
+ *** Command-Name als Prozess-Name von BCPL nach CSTR konvertieren
+ *** a1 zeigt auf freien Platz für Tasknamen
+
+GetProcName: move.l a1,d1 ; D1: Name für CreateProc()
+ move.l cli_CommandName(a2),d0 ; PrgName holen
+ beq.b 3$ ; kein Name --->
+ lsl.l #2,d0 ; BPTR to APTR
+ movea.l d0,a0
+ moveq.l #0,d0
+ move.b (a0)+,d0 ; Länge des Strings holen
+ bra.b 2$ ; für dbf
+1$: move.b (a0)+,(a1)+ ; kopieren
+2$: dbf d0,1$
+ clr.b (a1) ; mit NULL abschliessen
+3$:
+ *** Prozess kreieren und zurück zum CLI
+
+ moveq #0,d2
+ move.b LN_PRI(a3),d2 ; D2: Priority
+ move.l CliSegList(a4),d3 ; D3: SegList, ist schon BPTR
+ ;; move.l pr_StackSize(a3),d4 ; D4: StackSize
+ ;; lsl.l #2,d4 ; Stimmt das ??
+ move.l #_STACKSIZE,d4
+ JSRLIB CreateProc ; Neuen prozess starten
+ moveq #0,d0 ; Zum CLI zurück
+EndDet: rts
+
+ *** Einsprung des neuen Prozesses, hat schon _geta4 gemacht
+
+SecondTime: move.l SP,InitialSP(a4)
+ movea.l _SysBase(a4),a6
+ movea.l ThisTask(a6),a3 ; Neue ProcessBase holen
+ movea.l _DOSBase(a4),a6
+ move.l ActDir(a4),d1 ; Unser CurrentDir
+ JSRLIB CurrentDir ; setzen
+
+ bra.b Windy ; --->
+ ELSE
+
+ IFND TINY
+ lea StdErrName(PC),a0
+ move.l a0,d1
+ move.l #MODE_OLDFILE,d2
+ JSRLIB Open
+ move.l d0,_StdErr(a4)
+ ENDC
+ bra.b StartMain ; --->
+ ENDC
+
+*****************************************************************************
+** Register A4 holen für small data
+
+_geta4: lea _LinkerDB,a4
+ rts
+
+*****************************************************************************
+** Start von der Werkbank
+
+FromWorkBench: movea.l _SysBase(a4),a6
+ lea pr_MsgPort(a3),a0
+ JSRLIB WaitPort
+ lea pr_MsgPort(a3),a0
+ JSRLIB GetMsg
+ move.l d0,WBenchMsg(a4)
+
+ clr.l InitialD0(a4) ; D0 : Null
+ move.l d0,InitialA0(a4) ; A0 : WBStartup-Message
+ movea.l d0,a0 ; Workbench Startup Message
+ movea.l sm_ArgList(a0),a0 ; erstes Argument: wir selbst!
+ move.l wa_Lock(a0),d1 ; Lock unseres Directories
+ movea.l _DOSBase(a4),a6
+ JSRLIB CurrentDir ; als Current Dir setzen
+
+Windy:
+ IFND TINY
+ move.l #_StdWindowName,d1 ; Zu öffnendes Dos-Fenster
+ move.l #MODE_OLDFILE,d2
+ JSRLIB Open ; Window öffnen
+ move.l d0,OurWindow(a4) ; für Exit()
+ IFND DETACH
+ move.l d0,_StdErr(a4)
+ ENDC
+ move.l d0,pr_CIS(a3) ; für Input()
+ move.l d0,pr_COS(a3) ; für Output()
+ lsl.l #2,d0 ; BPTR to APTR
+ movea.l d0,a0
+ move.l fh_Type(a0),pr_ConsoleTask(a3) ; für Open("*",mode);
+ ENDC
+
+**************** *****************************************************
+** Hauptprogramm starten
+
+StartMain: move.l a3,ProcessBase(a4) ; für die Aussenwelt
+ movem.l InitRegs(a4),d0/a0
+ jsr @Main(PC) ; PROGRAMM AUSFÜHREN!
+
+ *** Programm-Termination durch Exit(val) oder return(val)
+
+@exit:
+@Exit: bsr.b _geta4
+ IFND DETACH
+ move.l d0,d7 ; return-code retten
+ ENDC
+ movea.l InitialSP(a4),SP ; Stackpointer restaurieren
+
+ IFND TINY
+ movea.l _DOSBase(a4),a6
+ move.l OurWindow(a4),d1 ; Fenster oder 0
+ beq.b 1$
+ JSRLIB Close ; Fenster schliessen
+1$:
+ ENDC
+ move.l WBenchMsg(a4),d2 ; gibt's was zu beantworten?
+ beq.b 2$ ; nein, CLI --->
+ movea.l _SysBase(a4),a6
+ JSRLIB Forbid ; sonst werden wir 'entladen' !
+ movea.l d2,a1
+ JSRLIB ReplyMsg
+ IFND TINY
+ bra.b QuitnDie ; ---> raus!
+ ENDC
+2$:
+ IFND DETACH
+ IFND TINY
+ move.l _StdErr(a4),d1 ; StdErr schliessen if CLI
+ movea.l _DOSBase(a4),a6
+ JSRLIB Close
+ ENDC
+ ENDC
+
+**************** *****************************************************
+
+ *** Uns selber und unseren Lock freigeben falls degetacht (CLI)
+
+ IFD DETACH
+ ;; movea.l ProcessBase(a4),a3
+ ;; clr.l pr_CIS(a3) ; Input handle ungültig
+ ;; clr.l pr_COS(a3) ; Output handle ungültig
+ movea.l _DOSBase(a4),a6
+ move.l ActDir(a4),d1
+ JSRLIB UnLock ; Altes CD freigeben
+
+ move.l CliSegList(a4),d1 ; Uns selbst
+ JMPLIB UnLoadSeg ; freigeben
+ * NOT REACHED
+ ENDC
+
+*****************************************************************************
+** Returncode von D7 holen und Programm beenden
+
+QuitnDie: move.l d7,d0 ; return-code
+ rts ; ZURÜCK ZUM DOS!
+
+*****************************************************************************
+
+ IFND DETACH
+ IFND TINY
+StdErrName: dc.b "*",0
+ ENDC
+ ENDC
+
+*****************************************************************************
+
+ SECTION __MERGED,DATA
+
+; Anscheinend darf die Data-Size im __MERGED-Segment nicht 0 sein, sonst
+; erzeugt der Linker einen BSS-Hunk mit Länge 0 im Hunk und Länge 20 im
+; Header (?!)
+
+_DOSBase:
+DOSBase: ds.l 1 ; wird hier geöffnet & geschlossen
+
+
+ SECTION __MERGED,BSS
+
+_SysBase: ds.l 1
+
+_ProcessBase:
+ProcessBase: ds.l 1 ; Address of this process
+
+WBenchMsg: ds.l 1 ; Startup-Message oder NULL
+
+
+ IFND TINY
+_StdErr: ; MUSS vor OurWindow stehen, weil if ..
+StdErr: ; .. detach, StdErr=OurWindow
+ IFND DETACH
+ ds.l 1 ; Standard Error FileHandle
+ ENDC
+
+OurWindow: ds.l 1 ; Zeiger auf unser Window oder NULL
+
+_NewOS:
+NewOS: ds.l 1 ; Flag ob Kick 2.x
+ ENDC
+
+
+InitRegs: ; Die 3 geretteten Register D0/A0/SP:
+InitialD0: ds.l 1
+InitialA0: ds.l 1
+InitialSP: ds.l 1
+
+ IFD DETACH
+
+CliSegList: ds.l 1 ; Unsere Segmentliste
+ActDir: ds.l 1 ; Lock auf unser Current Directory
+FirstTime: ds.l 1 ; Flag ob 1. Mal durch
+
+ ENDC
+
+
+ IFD DETACH
+
+ SECTION bss,BSS
+
+CommandLine: ds.b 2100 ; Kommandozeile und Task-Name
+
+ ENDC
+
+ END
diff --git a/Stubs.c b/Stubs.c
new file mode 100644
index 0000000..fab0209
--- /dev/null
+++ b/Stubs.c
@@ -0,0 +1,93 @@
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/dos.h>
+
+#include "Bobi.h"
+
+extern struct NewWindow ToolNW;
+extern struct Screen *mainscreen;
+extern struct Window *mainwindow,*toolwindow;
+extern struct RastPort *toolrastport;
+extern WORD mainpalette[];
+extern struct MenuItem ToolWindowMenuItem;
+
+/*************************************************************************/
+
+void ClearAllFunc()
+{
+ if(ShowRequest2("Do you really want to\ndelete all bobs?","OF COURSE!"))
+ ClearAll();
+}
+
+/*************************************************************************/
+
+void QuitFunc()
+{
+ if(ShowRequest2("Do you really want to quit ?","JAJA!"))
+ Cleanup(TRUE);
+ else ShowMonoReq2("Da hast du nochmals Glück gehabt!");
+}
+
+/*************************************************************************/
+
+void GrabDPaintFunc()
+{
+ ShowMonoReq2("Can't find the DPaint screen :-)");
+}
+
+/*************************************************************************/
+
+void GrabScreenFunc()
+{
+ ShowMonoReq2("Sorry, this function will\nnever be implemented!");
+}
+
+/*************************************************************************/
+
+void SaveIFFAnimFunc()
+{
+ ShowMonoReq2("Sorry, this function is not\nyet implemented!");
+}
+
+/*************************************************************************/
+
+void EditPaletteFunc()
+{
+ Snooze(mainwindow); /* nicht LockWindows() wegen Farbpalette! */
+ if(toolwindow) Snooze(toolwindow);
+ CopyMem(RequestColor(mainscreen),mainpalette,2*32);
+ if(toolwindow) UnSnooze(toolwindow);
+ UnSnooze(mainwindow);
+}
+
+/*************************************************************************/
+
+void ToolWindowFunc()
+{
+ if(ToolWindowMenuItem.Flags & CHECKED)
+ {
+ if(!toolwindow)
+ {
+ ToolNW.Screen = mainscreen;
+ if(ToolNW.TopEdge>mainscreen->Height-ToolNW.Height)
+ ToolNW.TopEdge=mainscreen->Height-ToolNW.Height;
+ if(!(toolwindow = OpenWindow(&ToolNW)))
+ {
+ ShowMonoReq2("Can't open tool window!\n");
+ }
+ toolrastport = toolwindow->RPort;
+ }
+ }
+ else
+ {
+ if(toolwindow)
+ {
+ ToolNW.TopEdge=toolwindow->TopEdge;
+ ClearMenuStrip(toolwindow);
+ CloseWindow(toolwindow);
+ toolwindow=0; toolrastport=0;
+ ActivateWindow(mainwindow);
+ }
+ }
+}
+
diff --git a/ToolWindow.h b/ToolWindow.h
new file mode 100644
index 0000000..dbfed27
--- /dev/null
+++ b/ToolWindow.h
@@ -0,0 +1,402 @@
+
+static UBYTE UNDOBUFFER[64];
+
+static SHORT BorderVectors4[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+static struct Border Border4 = {
+ 135,-23280,
+ 1,0,JAM1,
+ 5,
+ BorderVectors4,
+ NULL
+};
+
+static SHORT BorderVectors3[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+static struct Border Border3 = {
+ 95,-17624,
+ 1,0,JAM1,
+ 5,
+ BorderVectors3,
+ &Border4
+};
+
+static SHORT BorderVectors2[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+static struct Border Border2 = {
+ 175,-3208,
+ 1,0,JAM1,
+ 5,
+ BorderVectors2,
+ &Border3
+};
+
+static SHORT BorderVectors1[] = {
+ 0,0,
+ 37,0,
+ 37,10,
+ 0,10,
+ 0,0
+};
+static struct Border Border1 = {
+ 215,-3072,
+ 1,0,JAM1,
+ 5,
+ BorderVectors1,
+ &Border2
+};
+
+static struct Gadget Gadget8 = {
+ NULL,
+ 0,0,
+ 1,1,
+ GADGHBOX+GADGHIMAGE,
+ NULL,
+ BOOLGADGET,
+ (APTR)&Border1,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static UBYTE LabelGadgetSIBuff[64] =
+ "abcdefghhhhhhhhhhhk";
+static struct StringInfo LabelGadgetSInfo = {
+ LabelGadgetSIBuff,
+ UNDOBUFFER,
+ 0,
+ 64,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ NULL
+};
+
+static SHORT BorderVectors5[] = {
+ 0,0,
+ 155,0,
+ 155,10,
+ 0,10,
+ 0,1
+};
+static struct Border Border5 = {
+ -1,-2,
+ 3,0,JAM1,
+ 5,
+ BorderVectors5,
+ NULL
+};
+
+static struct IntuiText IText1 = {
+ 3,0,JAM2,
+ 28,-11,
+ NULL,
+ "Source Label:",
+ NULL
+};
+
+static struct Gadget LabelGadget = {
+ &Gadget8,
+ 96,-13,
+ 154,9,
+ GRELBOTTOM,
+ RELVERIFY,
+ STRGADGET,
+ (APTR)&Border5,
+ NULL,
+ &IText1,
+ NULL,
+ (APTR)&LabelGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors6[] = {
+ 0,0,
+ 33,0,
+ 33,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border6 = {
+ -1,-1,
+ 3,0,JAM1,
+ 5,
+ BorderVectors6,
+ NULL
+};
+
+static struct IntuiText IText3 = {
+ 1,0,JAM1,
+ 4,11,
+ NULL,
+ "Org",
+ NULL
+};
+
+static struct IntuiText IText2 = {
+ 1,0,JAM1,
+ 4,2,
+ NULL,
+ "Set",
+ &IText3
+};
+
+static struct Gadget Gadget6 = {
+ &LabelGadget,
+ 257,-25,
+ 32,20,
+ GRELBOTTOM,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border6,
+ NULL,
+ &IText2,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors7[] = {
+ 0,0,
+ 33,0,
+ 33,21,
+ 0,21,
+ 0,0
+};
+static struct Border Border7 = {
+ -1,-1,
+ 3,0,JAM1,
+ 5,
+ BorderVectors7,
+ NULL
+};
+
+static struct IntuiText IText5 = {
+ 1,0,JAM1,
+ 4,11,
+ NULL,
+ "Bob",
+ NULL
+};
+
+static struct IntuiText IText4 = {
+ 1,0,JAM1,
+ 4,2,
+ NULL,
+ "Get",
+ &IText5
+};
+
+static struct Gadget Gadget5 = {
+ &Gadget6,
+ 257,-50,
+ 32,20,
+ GRELBOTTOM,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border7,
+ NULL,
+ &IText4,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static struct PropInfo AnimSpeedGadgetSInfo = {
+ AUTOKNOB+FREEVERT,
+ -1,20755,
+ -1,4095,
+};
+
+static struct Image Image1 = {
+ 0,12,
+ 6,4,
+ 0,
+ NULL,
+ 0x0000,0x0000,
+ NULL
+};
+
+static struct Gadget AnimSpeedGadget = {
+ &Gadget5,
+ 4,-51,
+ 14,47,
+ GRELBOTTOM,
+ NULL,
+ PROPGADGET,
+ (APTR)&Image1,
+ NULL,
+ NULL,
+ NULL,
+ (APTR)&AnimSpeedGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors8[] = {
+ 0,0,
+ 71,0,
+ 71,11,
+ 0,11,
+ 0,0
+};
+static struct Border Border8 = {
+ -1,-1,
+ 3,0,JAM1,
+ 5,
+ BorderVectors8,
+ NULL
+};
+
+static struct IntuiText IText6 = {
+ 1,0,JAM1,
+ 4,1,
+ NULL,
+ "Anim Key",
+ NULL
+};
+
+static struct Gadget AnimKeyGadget = {
+ &AnimSpeedGadget,
+ 21,-15,
+ 70,10,
+ GRELBOTTOM+SELECTED,
+ RELVERIFY+TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border8,
+ NULL,
+ &IText6,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors9[] = {
+ 0,0,
+ 71,0,
+ 71,11,
+ 0,11,
+ 0,0
+};
+static struct Border Border9 = {
+ -1,-1,
+ 3,0,JAM1,
+ 5,
+ BorderVectors9,
+ NULL
+};
+
+static struct IntuiText IText7 = {
+ 1,0,JAM1,
+ 4,1,
+ NULL,
+ "Auto Org",
+ NULL
+};
+
+static struct Gadget AutoOrgGadget = {
+ &AnimKeyGadget,
+ 21,-33,
+ 70,10,
+ GRELBOTTOM+SELECTED,
+ RELVERIFY+TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border9,
+ NULL,
+ &IText7,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors10[] = {
+ 0,0,
+ 71,0,
+ 71,11,
+ 0,11,
+ 0,0
+};
+static struct Border Border10 = {
+ -1,-1,
+ 3,0,JAM1,
+ 5,
+ BorderVectors10,
+ NULL
+};
+
+static struct IntuiText IText8 = {
+ 1,0,JAM1,
+ 4,1,
+ NULL,
+ "AutoSize",
+ NULL
+};
+
+static struct Gadget AutoSizeGadget = {
+ &AutoOrgGadget,
+ 21,-50,
+ 70,10,
+ GRELBOTTOM+SELECTED,
+ RELVERIFY+TOGGLESELECT,
+ BOOLGADGET,
+ (APTR)&Border10,
+ NULL,
+ &IText8,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+#define GadgetList1 AutoSizeGadget
+
+static struct NewWindow NewWindowStructure1 = {
+ 0,61,
+ 295,65,
+ 0,1,
+ MOUSEBUTTONS+GADGETDOWN+GADGETUP+MENUPICK+RAWKEY,
+ WINDOWDRAG+WINDOWCLOSE+REPORTMOUSE+ACTIVATE+NOCAREREFRESH,
+ &AutoSizeGadget,
+ NULL,
+ "Bobi Tool Window",
+ NULL,
+ NULL,
+ 0,0,
+ 0,0,
+ CUSTOMSCREEN
+};
+
+
+void HandleEvent(object)
+APTR object;
+{
+ if (object == (APTR)&Gadget5) { GetBobFunc( ); return; }
+ if (object == (APTR)&Gadget6) { SetOrgFunc( ); return; }
+}
+#define HANDLEEVENT HandleEvent
+
+/* end of PowerWindows source generation */
diff --git a/Zoom.c b/Zoom.c
new file mode 100644
index 0000000..eb0d9fc
--- /dev/null
+++ b/Zoom.c
@@ -0,0 +1,152 @@
+#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 <proto/mathffp.h>
+#include <proto/mathtrans.h>
+
+#include "Bobi.h"
+#include "BobStructure.h"
+#include "ByteMap.h"
+#include "ZoomWindow.h"
+
+extern struct MyBob *BobTable[];
+extern struct Screen *mainscreen;
+extern struct RastPort *mainrastport;
+extern UWORD mainpalette[];
+extern WORD actbobnum,mainx0,mainy0;
+
+/*************************************************************************/
+
+static void ZoomBitMap(struct BitMap *bim, LONG faktor)
+{
+ register struct ByteMap *sbym,*dbym; /* Source & Destination */
+
+ if(sbym=MakeByteMap((WORD)(bim->BytesPerRow*8),bim->Rows))
+ {
+ if(dbym=MakeByteMap((WORD)(bim->BytesPerRow*8),bim->Rows))
+ {
+ BitMapToByteMap(bim,sbym);
+ ZoomByteMap(sbym,dbym,faktor);
+ ByteMapToBitMap(dbym,bim);
+ FreeByteMap(dbym);
+ }
+ else ShowMonoReq2("No memory for zoom");
+ FreeByteMap(sbym);
+ }
+ else ShowMonoReq2("No memory for zoom");
+}
+
+/*************************************************************************/
+
+static struct MyBob *ZoomBob(struct MyBob *bob,register LONG faktor)
+{
+ register struct BitMap *sbim,*dbim;
+ register WORD width,height;
+
+ if((bob->Flags & BOBF_AUTOSIZE) && (faktor>100))
+ {
+ width = (bob->Width*faktor)/100+1;
+ height = (bob->Height*faktor)/100+1;
+ }
+ else
+ {
+ width = bob->Width; height = bob->Height;
+ }
+
+ if(sbim=BobToBitMap(bob))
+ {
+ if(dbim=MakeBitMap(width,height,bob->Depth))
+ {
+ BltBitMap(sbim,0,0,dbim,(width-bob->Width)/2,
+ (height-bob->Height)/2,bob->Width,bob->Height,0xc0,0xff,0);
+ ZoomBitMap(dbim,faktor);
+ bob=BitMapToBob(bob,dbim,width);
+ MyFreeBitMap(dbim);
+ }
+ else bob = 0;
+ MyFreeBitMap(sbim);
+ }
+ else bob = 0;
+ return(bob);
+}
+
+/*************************************************************************/
+
+void ZoomFunc()
+{
+ register struct Window *w;
+ register WORD flag = 0;
+ register LONG i,increment;
+
+ if(BobTable[actbobnum])
+ {
+ LockWindows();
+ NewWindowStructure1.Screen = mainscreen;
+ if(w=OpenWindow(&NewWindowStructure1))
+ {
+ do
+ {
+ register struct IntuiMessage *msg;
+
+ WaitPort(w->UserPort);
+ msg=(struct IntuiMessage *)GetMsg(w->UserPort);
+ if(msg->Class == CLOSEWINDOW)
+ {
+ flag = -1;
+ }
+ else if(msg->Class == GADGETUP)
+ {
+ if(msg->IAddress == (APTR)&OKGadget)
+ {
+ flag = 1;
+ }
+ else if(msg->IAddress == (APTR)&CancelGadget)
+ {
+ flag = -1;
+ }
+ }
+ } while(!flag);
+ CloseWindow(w);
+ LoadPalette(mainpalette);
+
+ if(flag>0)
+ {
+ register struct MyBob *bob;
+
+ increment=LastGadgetSInfo.LongInt-FirstGadgetSInfo.LongInt;
+ increment/=FramesGadgetSInfo.LongInt;
+
+ for(i=0; i<FramesGadgetSInfo.LongInt; ++i)
+ {
+ if(bob=ZoomBob(BobTable[actbobnum],i*increment))
+ {
+ ShowBob(bob);
+ InsertBob(bob,(WORD)(actbobnum+i+1));
+ }
+ else
+ {
+ ShowMonoReq2("No memory for new bobs, Zoom aborted.");
+ break;
+ }
+ }
+
+ for(i=1; i<=FramesGadgetSInfo.LongInt; ++i)
+ {
+ if(bob=AutoResizeBob(BobTable[actbobnum+i]))
+ {
+ FreeBob(BobTable[actbobnum+i]);
+ BobTable[actbobnum+i] = bob;
+ ShowBob(bob);
+ }
+ else ShowMonoReq2("Zoom:noresize");
+ }
+ }
+ }
+ UnLockWindows();
+ }
+ else ShowMonoReq2("Select a bob to zoom!");
+}
+
diff --git a/ZoomWindow.h b/ZoomWindow.h
new file mode 100644
index 0000000..8fb6c1a
--- /dev/null
+++ b/ZoomWindow.h
@@ -0,0 +1,255 @@
+
+static UBYTE LastGadgetSIBuff[5] =
+ "200";
+static struct StringInfo LastGadgetSInfo = {
+ LastGadgetSIBuff,
+ NULL,
+ 0,
+ 5,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 200,
+ NULL
+};
+
+static SHORT BorderVectors1[] = {
+ 0,0,
+ 174,0,
+ 174,12,
+ 0,12,
+ 0,1
+};
+static struct Border Border1 = {
+ -1,-3,
+ 3,0,JAM1,
+ 5,
+ BorderVectors1,
+ NULL
+};
+
+static struct IntuiText IText1 = {
+ 3,0,JAM1,
+ 4,0,
+ NULL,
+ "Last (0-1000%)",
+ NULL
+};
+
+static struct Gadget LastGadget = {
+ NULL,
+ 6,33,
+ 173,11,
+ NULL,
+ RELVERIFY+STRINGRIGHT+LONGINT,
+ STRGADGET,
+ (APTR)&Border1,
+ NULL,
+ &IText1,
+ NULL,
+ (APTR)&LastGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static UBYTE FramesGadgetSIBuff[5] =
+ "20";
+static struct StringInfo FramesGadgetSInfo = {
+ FramesGadgetSIBuff,
+ NULL,
+ 0,
+ 5,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 20,
+ NULL
+};
+
+static SHORT BorderVectors2[] = {
+ 0,0,
+ 174,0,
+ 174,12,
+ 0,12,
+ 0,1
+};
+static struct Border Border2 = {
+ -1,-3,
+ 3,0,JAM1,
+ 5,
+ BorderVectors2,
+ NULL
+};
+
+static struct IntuiText IText2 = {
+ 3,0,JAM1,
+ 4,0,
+ NULL,
+ "# of Frames",
+ NULL
+};
+
+static struct Gadget FramesGadget = {
+ &LastGadget,
+ 6,49,
+ 173,11,
+ NULL,
+ RELVERIFY+STRINGRIGHT+LONGINT,
+ STRGADGET,
+ (APTR)&Border2,
+ NULL,
+ &IText2,
+ NULL,
+ (APTR)&FramesGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static UBYTE FirstGadgetSIBuff[5] =
+ "0";
+static struct StringInfo FirstGadgetSInfo = {
+ FirstGadgetSIBuff,
+ NULL,
+ 0,
+ 5,
+ 0,
+ 0,0,0,0,0,
+ 0,
+ 0,
+ NULL
+};
+
+static SHORT BorderVectors3[] = {
+ 0,0,
+ 174,0,
+ 174,12,
+ 0,12,
+ 0,1
+};
+static struct Border Border3 = {
+ -1,-3,
+ 3,0,JAM1,
+ 5,
+ BorderVectors3,
+ NULL
+};
+
+static struct IntuiText IText3 = {
+ 3,0,JAM1,
+ 4,0,
+ NULL,
+ "First (0-1000%)",
+ NULL
+};
+
+static struct Gadget FirstGadget = {
+ &FramesGadget,
+ 6,17,
+ 173,11,
+ NULL,
+ RELVERIFY+STRINGRIGHT+LONGINT,
+ STRGADGET,
+ (APTR)&Border3,
+ NULL,
+ &IText3,
+ NULL,
+ (APTR)&FirstGadgetSInfo,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors4[] = {
+ 0,0,
+ 81,0,
+ 81,12,
+ 0,12,
+ 0,0
+};
+static struct Border Border4 = {
+ -1,-1,
+ 1,0,JAM1,
+ 5,
+ BorderVectors4,
+ NULL
+};
+
+static struct IntuiText IText4 = {
+ 1,0,JAM1,
+ 24,2,
+ NULL,
+ "ZOOM",
+ NULL
+};
+
+static struct Gadget OKGadget = {
+ &FirstGadget,
+ 6,-15,
+ 80,11,
+ GRELBOTTOM,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border4,
+ NULL,
+ &IText4,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static SHORT BorderVectors5[] = {
+ 0,0,
+ 81,0,
+ 81,12,
+ 0,12,
+ 0,0
+};
+static struct Border Border5 = {
+ -1,-1,
+ 31,0,JAM1,
+ 5,
+ BorderVectors5,
+ NULL
+};
+
+static struct IntuiText IText5 = {
+ 31,0,JAM1,
+ 16,2,
+ NULL,
+ "CANCEL",
+ NULL
+};
+
+static struct Gadget CancelGadget = {
+ &OKGadget,
+ -85,-15,
+ 80,11,
+ GRELBOTTOM+GRELRIGHT,
+ RELVERIFY,
+ BOOLGADGET,
+ (APTR)&Border5,
+ NULL,
+ &IText5,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+#define GadgetList1 CancelGadget
+
+static struct NewWindow NewWindowStructure1 = {
+ 63,39,
+ 185,82,
+ 0,1,
+ GADGETUP+CLOSEWINDOW,
+ WINDOWDRAG+WINDOWDEPTH+WINDOWCLOSE+ACTIVATE+NOCAREREFRESH,
+ &CancelGadget,
+ NULL,
+ " Zoom Bobs ",
+ NULL,
+ NULL,
+ 5,5,
+ (UWORD)-1,(UWORD)-1,
+ CUSTOMSCREEN
+};
diff --git a/pw/AboutWindow.pw b/pw/AboutWindow.pw
new file mode 100644
index 0000000..23ad3e2
--- /dev/null
+++ b/pw/AboutWindow.pw
Binary files differ
diff --git a/pw/CHW.Brush b/pw/CHW.Brush
new file mode 100644
index 0000000..d17b82d
--- /dev/null
+++ b/pw/CHW.Brush
Binary files differ
diff --git a/pw/GenerateWindow.pw b/pw/GenerateWindow.pw
new file mode 100644
index 0000000..bbabf46
--- /dev/null
+++ b/pw/GenerateWindow.pw
Binary files differ
diff --git a/pw/MainWindow.pw b/pw/MainWindow.pw
new file mode 100644
index 0000000..55afd92
--- /dev/null
+++ b/pw/MainWindow.pw
Binary files differ
diff --git a/pw/RotateWindow.pw b/pw/RotateWindow.pw
new file mode 100644
index 0000000..c6ef09b
--- /dev/null
+++ b/pw/RotateWindow.pw
Binary files differ
diff --git a/pw/ZoomWindow.pw b/pw/ZoomWindow.pw
new file mode 100644
index 0000000..b02c485
--- /dev/null
+++ b/pw/ZoomWindow.pw
Binary files differ