if (rxfunc == NULL)
{
if(rexxdebug) Libprintf("Unknown function%s !!\n",RXARG0);
R->ret=ERR10_015; /* function not found */
R->argstring= NULL;
return;
}
if (argscount != rxfunc->argscount)
{
if(rexxdebug) Libprintf("Function %s need %ld args !!\n",RXARG0,rxfunc->argscount);
R->ret=ERR10_017; /* wrong number of arguments */
R->argstring= NULL;
return;
}
if(rexxdebug==2) OSAlert("Ready?");
R->ret = rxfunc->func(m); /* call the function */
R->argstring = NULL;
if(rexxdebug) Libprintf("Function %s()\n",RXARG0);
if(rxfunc->returntype==' ') /* no return value */
{
if(rexxdebug) Libprintf("return: nothing \n");
Libsprintf(name,"0");
}
if(rxfunc->returntype=='R') /* got a return value */
{
if(rexxdebug) Libprintf("return: int \n");
Libsprintf(name,"%ld",R->ret);
}
Thanks! To sum it up, I can see that you have 5 functions there
stub_RexxSupportPPC
rx_DoObjectFx
rx_AddMotionCapture
findrxfunc
MyRexxSupport
and the supported ARexx functions are in the "rxfuncs" array. You have included two of the functions in the source code: rx_DoObjectFx() (ARexx function name DOOBJECTFX) and rx_AddMotionCapture() (ARexx function name ADDMOTIONCAPTURE).
MyRexxSupport() and findrxfunc() functions seem to be auxilliary functions and stub_RexxSupportPPC() handles all the ARexx function calls, being the ARexx function interface.
If I generate a library template with IDLTool using the following XML file,
how do I know which offset value should be used in the ARexx ADDLIB() function call? How do you calculate it? The offset value is usually -30 and the ADDLIB() call would be something like ADDLIB( "mylibrary.library", 0, -30, 0 ), but is it -30 in this case?
In fact arexx only call as a 68k program
To generate all the stuff for a.library the simpler is to start from an .sfd file thta is used for 68k .library
So put only that in (say) mylib.sfd :
Note it has one more arg than the 68k style dispatcher as the 68k version returns results on a0
You will need to generate the 68k stubs for the library but the one generated for the RLDispatcher function will need editing to pur the pointer resultstring A0 (regarrys[8]) .
@thellier
BYW can you put your code in '[' code ']' blocks, it;s breaking the forum layout!
how do I know which offset value should be used in the ARexx ADDLIB() function call? How do you calculate it? The offset value is usually -30 and the ADDLIB() call would be something like ADDLIB( "mylibrary.library", 0, -30, 0 ), but is it -30 in this case?
If it's the first function after stanadrd inetrfaces ones then the offset will indeed be -30.
Make sure you use the xml I posted above (use the function name you prefer but make sure it's consistant throughout
hello
static LONG stub_RexxSupportPPC(uint32 *regarray)
{
struct Library *Base = (struct Library *) regarray[REG68K_A6/4];
struct ExtendedLibrary *ExtLib = (struct ExtendedLibrary *) ((uint32)Base + Base->lib_PosSize);
struct Microbe3DIFace *Self = (struct Microbe3DIFace *) ExtLib->MainIFace;
struct RexxStuff R;
R.msg=(APTR)regarray[8]; /* arexx msg in a0 */
MyRexxSupport(&R); /* use builtin function */
regarray[8]=regarray[9]=(ULONG)R.argstring; /* arexx argstring in a0 and a1 */
return(R.ret); /* arexx error-code (ret) in d0 */
}
/*=================================================================*/
ULONG rx_DoObjectFx(struct RexxMsg *m)
{
U3D_DoObjectFx((APTR)IA1,(ULONG)IA2);
return(0);
}
/*=================================================================*/
ULONG rx_AddMotionCapture(struct RexxMsg *m)
{
ULONG ret;
ret=(ULONG)U3D_AddMotionCapture((APTR)IA1,(UBYTE*)SA2,(ULONG)IA3,(ULONG)IA4,(float)FA5);
return(ret);
}
/*=================================================================*/
struct arexxfunc rxfuncs[] = {
{"REXXGETFLOAT" ,1,'F',rx_RexxGetFloat},
{"REXXGETNAME" ,1,'S',rx_RexxGetName},
{"REXXSETCOLOR" ,5,'R',rx_RexxSetColor},
{"REXXSETFLOAT" ,2,'R',rx_RexxSetFloat},
{"REXXSETNAME" ,2,'R',rx_RexxSetName},
{"REXXSETVERTEX" ,4,'R',rx_RexxSetVertex},
{"ADDBONE" ,6,'R',rx_AddBone},
{"ADDFACE" ,1,' ',rx_AddFace},
{"ADDGROUP" ,3,'R',rx_AddGroup},
{"ADDINSTANCE" ,3,'R',rx_AddInstance},
{"ADDMAP" ,6,'R',rx_AddMap},
{"ADDMOTIONCAPTURE" ,5,'R',rx_AddMotionCapture},
{"ADDOBJECT" ,4,'R',rx_AddObject},
{"ADDPOINT" ,4,' ',rx_AddPoint},
{"ADDSKIN" ,3,'R',rx_AddSkin},
{"BOX" ,4,' ',rx_Box},
{"DELETE" ,1,' ',rx_Delete},
{"DIMENSIONS" ,4,' ',rx_Dimensions},
{"DOOBJECTFX" ,2,' ',rx_DoObjectFx},
{"DRAWSCENE" ,1,' ',rx_DrawScene},
{"EASYOPENSCENE" ,3,'R',rx_EasyOpenScene},
{"FIND" ,3,'R',rx_Find},
{"GET" ,3,'R',rx_Get},
{"GETTILE" ,4,'R',rx_GetTile},
{"GRIDWELD" ,4,' ',rx_GridWeld},
{"MOTIONCAPTURECUT" ,4,'R',rx_MotionCaptureCut},
{"MOTIONCAPTUREJOIN" ,4,'R',rx_MotionCaptureJoin},
{"MOTIONCAPTUREFX" ,5,'R',rx_MotionCaptureFx},
{"NAME" ,1,'R',rx_Name},
{"NORMALS" ,2,' ',rx_Normals},
{"OPENSCENE" ,7,'R',rx_OpenScene},
{"QUERYVALUE" ,2,'R',rx_QueryValue},
{"READ" ,2,'R',rx_Read},
{"REVERSEWINDING" ,1,' ',rx_ReverseWinding},
{"ROTATE" ,5,' ',rx_Rotate},
{"SCALE" ,5,' ',rx_Scale},
{"SETAMPLITUDE" ,7,' ',rx_SetAmplitude},
{"SETBONEEQUIVALENCE" ,3,' ',rx_SetBoneEquivalence},
{"SETBONEINFLUENCE" ,4,' ',rx_SetBoneInfluence},
{"SETINSTANCE" ,3,' ',rx_SetInstance},
{"SETLIGHT" ,3,' ',rx_SetLight},
{"SETLIGHTPLUS" ,6,' ',rx_SetLightPlus},
{"SETMOTIONCAPTURE" ,3,' ',rx_SetMotionCapture},
{"SETSPECIALMATERIAL" ,4,' ',rx_SetSpecialMaterial},
{"SETTILE" ,5,' ',rx_SetTile},
{"SETTILEDEF" ,3,' ',rx_SetTileDef},
{"SETVALUE" ,3,' ',rx_SetValue},
{"SWAPAXIS" ,2,' ',rx_SwapAxis},
{"TRANSLATE" ,5,' ',rx_Translate},
{"UNITIZE" ,2,' ',rx_Unitize},
{"WELD" ,4,' ',rx_Weld},
{"WRITE" ,2,' ',rx_Write},
};
#define FUNCCOUNT (sizeof(rxfuncs)/sizeof(struct arexxfunc))
/*=================================================================*/
APTR findrxfunc(UBYTE *name)
{
ULONG n;
name=&name[4]; /* skip U3D_ */
NLOOP(FUNCCOUNT)
if(IsKeyword(rxfuncs[n].name,name))
return(&rxfuncs[n]);
return(NULL);
}
/*=================================================================*/
void MyRexxSupport(struct RexxStuff *R)
{
struct RexxMsg *m=R->msg;
struct arexxfunc *rxfunc;
UBYTE argscount;
char name[256];
ULONG n;
float *F;
struct Task *mytask;
ULONG mystack;
REM(RexxSupport)
mytask=FindTask(NULL);
mystack=((ULONG)mytask->tc_SPUpper) - ((ULONG)mytask->tc_SPLower);
if(mystack < MICROBE3DSTACK)
{
errorprintf("Error: Rexx/Stack too low %ld !!\n",mystack);
R->ret=ERR10_003; /* no memory available */
R->argstring= NULL;
((struct RxsLib*)RexxSysBase)->rl_StackSize=MICROBE3DSTACK;
return;
}
if(rexxdebug) Libprintf("RexxSupport=======================\n");
argscount = m->rm_Action & RXARGMASK;
if(rexxdebug) Libprintf("Func: %s\n",m->rm_Args[0]);
rxfunc = findrxfunc(RXARG0);
NLOOP(argscount)
{
if(rexxdebug) Libprintf("Arg%ld: <%s>\n",n+1,m->rm_Args[n+1]);
}
if (rxfunc == NULL)
{
if(rexxdebug) Libprintf("Unknown function%s !!\n",RXARG0);
R->ret=ERR10_015; /* function not found */
R->argstring= NULL;
return;
}
if (argscount != rxfunc->argscount)
{
if(rexxdebug) Libprintf("Function %s need %ld args !!\n",RXARG0,rxfunc->argscount);
R->ret=ERR10_017; /* wrong number of arguments */
R->argstring= NULL;
return;
}
if(rexxdebug==2) OSAlert("Ready?");
R->ret = rxfunc->func(m); /* call the function */
R->argstring = NULL;
if(rexxdebug) Libprintf("Function %s()\n",RXARG0);
if(rxfunc->returntype==' ') /* no return value */
{
if(rexxdebug) Libprintf("return: nothing \n");
Libsprintf(name,"0");
}
if(rxfunc->returntype=='R') /* got a return value */
{
if(rexxdebug) Libprintf("return: int \n");
Libsprintf(name,"%ld",R->ret);
}
if(rxfunc->returntype=='S') /* STRING return value */
{
if(rexxdebug) Libprintf("return: string \n");
Libsprintf(name,"%s",(UBYTE*)R->ret);
}
if(rxfunc->returntype=='F') /* float return value */
{
if(rexxdebug) Libprintf("return: float \n");
F=(float*)&R->ret; /* float encoded as LONG */
spf(name,F[0]);
}
R->ret=RC_OK;
R->argstring=CreateArgstring(name,Libstrlen(name));
if(rexxdebug) Libprintf("ret: %ld argstring: <%s>\n",R->ret,R->argstring);
if(rexxdebug) Libprintf("----------------------------------\n");
if(rexxdebug==2) OSAlert("Done");
}
Alain Thellier - Wazp3D
Thanks! To sum it up, I can see that you have 5 functions there
and the supported ARexx functions are in the "rxfuncs" array. You have included two of the functions in the source code: rx_DoObjectFx() (ARexx function name DOOBJECTFX) and rx_AddMotionCapture() (ARexx function name ADDMOTIONCAPTURE).
MyRexxSupport() and findrxfunc() functions seem to be auxilliary functions and stub_RexxSupportPPC() handles all the ARexx function calls, being the ARexx function interface.
If I generate a library template with IDLTool using the following XML file,
how do I know which offset value should be used in the ARexx ADDLIB() function call? How do you calculate it? The offset value is usually -30 and the ADDLIB() call would be something like ADDLIB( "mylibrary.library", 0, -30, 0 ), but is it -30 in this case?
In fact arexx only call as a 68k program
To generate all the stuff for a.library the simpler is to start from an .sfd file thta is used for 68k .library
So put only that in (say) mylib.sfd :
==id $Id: Microbe3D_lib.sfd,v 1.0 2012/10/12 13:30:00 noname Exp $
==base _Microbe3DBase
==basetype struct Library *
==libname Microbe3D.library
==bias 30
==public
==include
LONG RexxSupport(APTR msg,APTR RexxSupportBase) (a0,a1)
then run
fdtrans mylib.sfd --all
idltool mylib.xml --all
It will generat all the needed files
Also this part will explain how to recover arguments from arexx
/*=================================================================*/
struct arexxfunc {
char *name;
UWORD argscount,returntype;
ULONG (*func)(struct RexxMsg *);
};
/*==========================================================================*/
ULONG myatoi2(UBYTE *param) /* convert string & keywords to numeric*/
{
UBYTE param2[20];
ULONG value;
if(param[0]=='U') /* convert keywords like U3D_VANILLAKEY, U3D_FPS, etc... to numeric*/
if(param[1]=='3')
if(param[2]=='D')
if(param[3]=='_')
{
value=FindKeyWord(param);
if(value==0)
{
errorprintf("Error: Unknown parameter <%s>\n",param);
return(0);
}
if(rexxdebug) Libprintf("REXX:\tKnown parameter %s : %ld\n",param,value);
Libsprintf(param2,"%ld",value); /* new param2 will contain converted keyword as numeric-string */
return(myatoi(param2));
}
return(myatoi(param));
}
/*=================================================================*/
#define RXARG0 m->rm_Args[0]
#define RXARG1 m->rm_Args[1]
#define RXARG2 m->rm_Args[2]
#define RXARG3 m->rm_Args[3]
#define RXARG4 m->rm_Args[4]
#define RXARG5 m->rm_Args[5]
#define RXARG6 m->rm_Args[6]
#define RXARG7 m->rm_Args[7]
#define RXARG8 m->rm_Args[8]
/* arg as int */
#define IA1 myatoi2(RXARG1)
#define IA2 myatoi2(RXARG2)
#define IA3 myatoi2(RXARG3)
#define IA4 myatoi2(RXARG4)
#define IA5 myatoi2(RXARG5)
#define IA6 myatoi2(RXARG6)
#define IA7 myatoi2(RXARG7)
#define IA8 myatoi2(RXARG8)
/* arg as float */
#define FA1 myatof(RXARG1)
#define FA2 myatof(RXARG2)
#define FA3 myatof(RXARG3)
#define FA4 myatof(RXARG4)
#define FA5 myatof(RXARG5)
#define FA6 myatof(RXARG6)
#define FA7 myatof(RXARG7)
#define FA8 myatof(RXARG8)
/* arg as string */
#define SA1 RXARG1
#define SA2 RXARG2
#define SA3 RXARG3
#define SA4 RXARG4
#define SA5 RXARG5
#define SA6 RXARG6
#define SA7 RXARG7
#define SA8 RXARG8
BTW all this code come from my Microbe3D sources
see arexx calling microbe3d here:
http://aminet.net/package/util/libs/Microbe3D
Alain Thellier - Wazp3D
@thellier
You should *NOT* write your library by assuming this!
If you do so and ARexx gets ported to PPC then your library will cease to function.
Taking dataypes library as an example the xml required to define the Rwexx dispatcher is like so:
Note it has one more arg than the 68k style dispatcher as the 68k version returns results on a0
You will need to generate the 68k stubs for the library but the one generated for the RLDispatcher function will need editing to pur the pointer resultstring A0 (regarrys[8]) .
@thellier
BYW can you put your code in '[' code ']' blocks, it;s breaking the forum layout!
If it's the first function after stanadrd inetrfaces ones then the offset will indeed be -30.
Make sure you use the xml I posted above (use the function name you prefer but make sure it's consistant throughout
Possible stub code