summaryrefslogtreecommitdiff
path: root/ARexx.c
diff options
context:
space:
mode:
Diffstat (limited to 'ARexx.c')
-rw-r--r--ARexx.c483
1 files changed, 483 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 */
+ }
+}