Thanks again, but now I confirmed my age old suspect, vars are in reverse order so I modified macros accordingly
. Plus lame macros for user vars, that must be manually tweaked if you use mixed types, like one int for applyscale+add and all other doubles
... noes! Using offsets (I always waste at least 2 hours everytime)
#include <math.h>
/*
struct TIteration3Dext {
double something; // -0x88 ; used in sphereheightmap.m3f
double dum0; // -0x80 ; unknown
double x; // -0x78
double y; // -0x70
double z; // -0x68
double dum1[8]; //unknown
double DE2T; // -0x20 ; Output: distance estimate to current object
double dum2[17]; //unknown
double accumulatedScale; // +0x70
double dum3; // +0x78; unknown
double OTforCol; // +0x80
double dum4[16]; //unknown
//void * sphericalMap; // +0x108; pointer to function
} MB3D_PACK;
*/
const int szof1int = 4; // helps to find out offsets
const int szof1dbl = 8; // helps to find out offsets
__CRT_INLINE double __cdecl Hypot(double x,double y) ;
__CRT_INLINE double __cdecl length2(double x,double y,double z);
__CRT_INLINE double __cdecl length(double x,double y,double z);
__CRT_INLINE double __cdecl recip (double _x);
__CRT_INLINE double __cdecl max (double _a, double _b);
__CRT_INLINE double __cdecl min (double _a, double _b);
__CRT_INLINE double __cdecl loadzero (void) // uses constants, assembly required :o)
{
double res;
__asm__ ("fldz": "=t" (res));
return res;
}
__CRT_INLINE double __cdecl load1 (void) // uses constants, assembly required :o)
{
double res;
__asm__ ("fld1": "=t" (res));
return res;
}
__CRT_INLINE double __cdecl loadZ (void)
{
double res;
__asm__ ("fldl -104(%%esi)" // esi-0x068
: "=t" (res)
: // nothing in (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"%esi" // using esi (clobbered));
);
return res;
}
__CRT_INLINE double __cdecl loadY (void)
{
double res;
__asm__ ("fldl -112(%%esi)" // esi-0x070
: "=t" (res)
: // nothing in (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"%esi" // using esi (clobbered));
);
return res;
}
__CRT_INLINE double __cdecl loadX (void)
{
double res;
__asm__ ("fldl -120(%%esi)" // esi-0x078
: "=t" (res)
: // nothing in (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"%esi" // using esi (clobbered));
);
return res;
}
__CRT_INLINE double __cdecl loadNthDoubleVar (int _nVar, int OFFSET) // 0 for the 1st ... use only double vars
// ELSE use offset, idk how I go by attempts normally ;(
{
register int N = -(_nVar*szof1dbl)- 0x010-OFFSET; // EAX
double res;
__asm__ ("fldl (%%edi,%1)" // nothing else seems to work
: "=t" (res)
:"r"(N) // in
:"%edi" // using edi (clobbered));
);
return res;
}
__CRT_INLINE int __cdecl loadNthIntVar (int _nVar, int OFFSET) // 0 for the 1st ... use only int vars
// ELSE use offset, idk how I go by attempts normally ;(
// untested! untested! untested!
{
int N = -(_nVar*szof1int)- 0x0C-OFFSET;
int res;
__asm__ ( "add %%edi,%1
" // omg?!?? nothing else seems to work
"movl %1,%%eax
" // omg?!?? nothing else seems to work
"movl %%eax,%0
"// omg?!?? nothing else seems to work
: "=m" (res)
:"m"(N) // in
:"%edi","%eax" // using edi and eax (clobbered));
);
return res;
}
__CRT_INLINE double __cdecl loadNthDoubleCns (int _nVar, int OFFSET) // 0 for the 1st ... use only double vars
// ELSE use offset, idk how I go by attempts normally ;(
// untested! untested! untested!
{
register int N = +(_nVar*szof1dbl)+ 0x000+OFFSET; // EAX
double res;
__asm__ ("fldl (%%edi,%1)" // nothing else seems to work
: "=t" (res)
:"r"(N) // in
:"%edi" // using edi (clobbered));
);
return res;
}
__CRT_INLINE double __cdecl loadNthIntCns (int _nVar, int OFFSET) // 0 for the 1st ... use only double vars
// ELSE use offset, idk how I go by attempts normally ;(
// untested! untested! untested!
{
register int N = +(_nVar*szof1int)+ 0x000+OFFSET; // EAX
double res;
__asm__ ( "add %%edi,%1
" // omg?!?? nothing else seems to work
"movl %1,%%eax
" // omg?!?? nothing else seems to work
"movl %%eax,%0
"// omg?!?? nothing else seems to work
: "=m" (res)
:"m"(N) // in
:"%edi","%eax" // using edi and eax (clobbered));
);
return res;
}
// WARNING don't do this normally except if you really have changed actual coords,
// AND you scaled them by a value... works even in nonlinear changes like Tglad's sphere inv
// If you changed coords, scaling them you must also change this (at the end of your fmla)
__CRT_INLINE void __cdecl multScaleFactorBy (double _ScaleF)
{
__asm__ ("fldl %0
"
"fmull +112(%%esi)" // esi+0x070
"fstpl +112(%%esi)" // esi+0x070
: // no out (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"m"(_ScaleF) // in
:"%esi" // using esi (clobbered));
);
return;
}
// WARNING don't do this normally except if you really want to change actual coords
__CRT_INLINE void __cdecl saveInZ (double _z)
{
__asm__ ("fldl %0
"
"fstpl -104(%%esi)" // esi-0x068
: // no out (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"m"(_z) // in
:"%esi" // using esi (clobbered));
);
return;
}
// WARNING don't do this normally except if you really want to change actual coords
__CRT_INLINE void __cdecl saveInY (double _y)
{
__asm__ ("fldl %0
"
"fstpl -112(%%esi)" // esi-0x070
: // no out (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"m"(_y) // in
:"%esi" // using esi (clobbered));
);
return;
}
// WARNING don't do this normally except if you really want to change actual coords
__CRT_INLINE void __cdecl saveInX (double _x)
{
__asm__ ("fldl %0
"
"fstpl -120(%%esi)" // esi-0x078
: // no out (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"m"(_x) // in
:"%esi" // using esi (clobbered));
);
return;
}
__CRT_INLINE void __cdecl saveDE (double _DE)
{
__asm__ ("fldl %0
"
"fstpl -32(%%esi)
" // esi-0x020
: // no out (well except the memory located into esi+stuff but we won't say that - it's okayish)
:"m"(_DE) // in
:"%esi" // using esi (clobbered));
);
return;
}
__CRT_INLINE double __cdecl Hypot(double x,double y) { return sqrt(x*x+y*y); }
__CRT_INLINE double __cdecl length2(double x,double y,double z) { return (x*x+y*y+z*z); }
__CRT_INLINE double __cdecl length(double x,double y,double z) { return sqrt(length2(x,y,z)); }
__CRT_INLINE double __cdecl recip (double _x) // uses constants, assembly required :o)
{
double res;
__asm__ ("fld1
"
"fdivp": "=t" (res) : "0" (_x));
return res;
}
__CRT_INLINE double __cdecl max (double _a, double _b)
{
return (_a>_b)?_a:_b;
}
__CRT_INLINE double __cdecl max3 (double _a, double _b, double _c)
{
return max(max(_a,_b),_c);
}
__CRT_INLINE double __cdecl min (double _a, double _b)
{
return (_a<_b)?_a:_b;
}
__CRT_INLINE double __cdecl min3 (double _a, double _b, double _c)
{
return min(min(_a,_b),_c);
}
// ULTRASLIM since Jessie said Mb3D prepares everything for us already
// We just use those lame macros it should be fine I hope? duh
void __attribute__((fastcall)) Formula(void) {
// should we tell the compiler to NOT touch edi nor esi?! I strongly think so...
double x=fabs(loadX()), y=fabs(loadY()), z=fabs(loadZ());
double V0=loadNthDoubleVar(0,0),V1=loadNthDoubleVar(1,0),V2=loadNthDoubleVar(2,0);
saveDE (max3(x-V0,y-V1,z-V2+h));
}
Resulting M3F:
[OPTIONS]
.Version = 6
.DEoption = 20
.Double Size X = 1.
.Double Size Y = 1.
.Double Size Z = 1.
[CONSTANTS]
Double = 1
[CO DE] DELETE the space!
B8F0FFFFFF5756DD4688DD4690DD4698DD0407B0E883EC14DD0407B0E0DD0407
D9CBD9E1DEE3D9CBD9E1DEE3D9CBD9E1DEE3D9CADDE1DFE0F6C4457404DDD8EB
02DDD9DDE1DFE0F6C4457404DDD8EB02DDD9DD5C2408DD442408DD5EE083C414
5E5FC3
[END]
Just a lame test, but prettier :P