diff --git a/plugins/Dfusion/dfusion.cpp b/plugins/Dfusion/dfusion.cpp index 6f14fb66c..e1792ba5f 100644 --- a/plugins/Dfusion/dfusion.cpp +++ b/plugins/Dfusion/dfusion.cpp @@ -2,14 +2,13 @@ #include #include #include -#include +#include #include #include -#include - #include "luamain.h" #include "lua_Console.h" +#include "functioncall.h" using std::vector; using std::string; @@ -20,8 +19,8 @@ static SDL::Mutex* mymutex=0; DFhackCExport command_result dfusion (Core * c, vector & parameters); DFhackCExport command_result lua_run (Core * c, vector & parameters); -typedef -int __stdcall (*dfprint)(const char*, char, char,void *ptr) ; + typedef + int (__thiscall *dfprint)(const char*, char, char,void *) ; DFhackCExport const char * plugin_name ( void ) { @@ -81,15 +80,20 @@ DFhackCExport command_result plugin_onupdate ( Core * c ) DFhackCExport command_result lua_run (Core * c, vector & parameters) { + //testing part{ c->Suspend(); - std::stringstream ss; - ss<>i; - dfprint mprint=(dfprint)(0x27F030+i); - mprint("Hello world",1,4,0); + FunctionCaller caller(c->p->getBase()); + std::vector args; + args.push_back((size_t)"Hello world"); + args.push_back(4); + args.push_back(4); + args.push_back(0); + dfprint mprint=(dfprint)(0x27F030+c->p->getBase()); + mprint("Hello world",4,4,0); + caller.CallFunction((0x27F030),FunctionCaller::THIS_CALL,args); c->Resume(); return CR_OK; + //}end testing Console &con=c->con; SDL_mutexP(mymutex); lua::state s=lua::glua::Get(); @@ -116,7 +120,7 @@ DFhackCExport command_result dfusion (Core * c, vector & parameters) { Console &con=c->con; - con.print("%x\n",c->vinfo->getBase()); + con.print("%x\n",c->p->getBase()); SDL_mutexP(mymutex); lua::state s=lua::glua::Get(); diff --git a/plugins/Dfusion/include/functioncall.h b/plugins/Dfusion/include/functioncall.h new file mode 100644 index 000000000..b0cb07038 --- /dev/null +++ b/plugins/Dfusion/include/functioncall.h @@ -0,0 +1,23 @@ +#ifndef FUNCTIONCALL__H +#define FUNCTIONCALL__H +#include +using std::vector; +class FunctionCaller +{ +public: + enum callconv + { + STD_CALL, //__stdcall - all in stack + FAST_CALL, //__fastcall - as much in registers as fits + THIS_CALL, //__thiscall - eax ptr to this, rest in stack + CDECL_CALL //__cdecl - same as stdcall but no stack realign + }; + + FunctionCaller(size_t base):base_(base){}; + + int CallFunction(size_t func_ptr,callconv conv,const vector &arguments); +private: + size_t base_; +}; + +#endif //FUNCTIONCALL__H \ No newline at end of file diff --git a/plugins/Dfusion/src/functioncall.cpp b/plugins/Dfusion/src/functioncall.cpp new file mode 100644 index 000000000..085a2e7d2 --- /dev/null +++ b/plugins/Dfusion/src/functioncall.cpp @@ -0,0 +1,81 @@ +#include "functioncall.h" +#define __F_TDEF(CONV,CONV_,tag) typedef int(CONV_ *F_TYPE##CONV##tag) +#define __F_T(CONV,tag) F_TYPE##CONV##tag +#define __F_TYPEDEFS(CONV,CONV_) __F_TDEF(CONV,CONV_,1)(int);\ + __F_TDEF(CONV,CONV_,2)(int,int);\ + __F_TDEF(CONV,CONV_,3)(int,int,int);\ + __F_TDEF(CONV,CONV_,4)(int,int,int,int);\ + __F_TDEF(CONV,CONV_,5)(int,int,int,int,int);\ + __F_TDEF(CONV,CONV_,6)(int,int,int,int,int,int);\ + __F_TDEF(CONV,CONV_,7)(int,int,int,int,int,int,int) + + +#define __FCALL(CONV,CONV_) if(conv==CONV)\ + { \ + if(count==1)\ + ret= (reinterpret_cast<__F_T(CONV,1)>(f))\ + (arguments[0]);\ + else if(count==2)\ + ret= (reinterpret_cast<__F_T(CONV,2)>(f))\ + (arguments[0],arguments[1]);\ + else if(count==3)\ + ret= (reinterpret_cast<__F_T(CONV,3)>(f))\ + (arguments[0],arguments[1],arguments[2]);\ + else if(count==4)\ + ret= (reinterpret_cast<__F_T(CONV,4)>(f))\ + (arguments[0],arguments[1],arguments[2],arguments[3]);\ + else if(count==5)\ + ret= (reinterpret_cast<__F_T(CONV,5)>(f))\ + (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);\ + else if(count==6)\ + ret= (reinterpret_cast<__F_T(CONV,6)>(f))\ + (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);\ + else if(count==7)\ + ret= (reinterpret_cast<__F_T(CONV,7)>(f))\ + (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);\ + } + +#define __FCALLEX(CONV,CONV_) if(conv==CONV)\ + { if(count==1) {__F_T(CONV,1) tmp_F=reinterpret_cast<__F_T(CONV,1)>(f); return tmp_F(arguments[0]);}\ + else if(count==2){__F_T(CONV,2) tmp_F=reinterpret_cast<__F_T(CONV,2)>(f); return tmp_F(arguments[0],arguments[1]);}\ + else if(count==3){__F_T(CONV,3) tmp_F=reinterpret_cast<__F_T(CONV,3)>(f); return tmp_F(arguments[0],arguments[1],arguments[2]);}\ + else if(count==4){__F_T(CONV,4) tmp_F=reinterpret_cast<__F_T(CONV,4)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3]);}\ + else if(count==5){__F_T(CONV,5) tmp_F=reinterpret_cast<__F_T(CONV,5)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);}\ + else if(count==6){__F_T(CONV,6) tmp_F=reinterpret_cast<__F_T(CONV,6)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);}\ + else if(count==7){__F_T(CONV,7) tmp_F=reinterpret_cast<__F_T(CONV,7)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);}\ + } + /*else if(count==8)\ + ret= (reinterpret_cast<__F_T(CONV,8)>(f))\ + (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7]);\ + else if(count==9)\ + ret= (reinterpret_cast(f))\ + (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8]);\ + else if(count==10)\ + ret= (reinterpret_cast(f))\ + (arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8],arguments[9]);}*/ + + +int FunctionCaller::CallFunction(size_t func_ptr,callconv conv,const vector &arguments) +{ + //nasty nasty code... + int ret=0; + + void* f= reinterpret_cast(func_ptr+base_); + size_t count=arguments.size(); + if(count==0) + return (reinterpret_cast(f))(); //does not matter how we call it... + __F_TYPEDEFS(STD_CALL,__stdcall); + __F_TYPEDEFS(FAST_CALL,__fastcall); + __F_TYPEDEFS(THIS_CALL,__thiscall); + __F_TYPEDEFS(CDECL_CALL,__cdecl); + + __FCALLEX(STD_CALL,__stdcall); + __FCALLEX(FAST_CALL,__fastcall); + __FCALLEX(THIS_CALL,__thiscall); + __FCALLEX(CDECL_CALL,__cdecl); + return ret; +} +#undef __FCALL +#undef __FCALLEX \ No newline at end of file