diff --git a/apps/openmw-mp/CMakeLists.txt b/apps/openmw-mp/CMakeLists.txt index bdf426a71..a9ae8c05d 100644 --- a/apps/openmw-mp/CMakeLists.txt +++ b/apps/openmw-mp/CMakeLists.txt @@ -1,5 +1,10 @@ project(tes3mp-server) +if(UNIX) #temporarly disabled for non-unix +find_package(CallFF REQUIRED) +include_directories(${CallFF_INCLUDES}) +endif(UNIX) + option(BUILD_WITH_PAWN "Enable Pawn language" OFF) option(ENABLE_BREAKPAD "Enable Google Breakpad for Crash reporting" OFF) @@ -99,6 +104,7 @@ set(SERVER_HEADER ${PawnScript_Headers} ${LuaScript_Headers} ${NativeScript_Headers} + ${CallFF_INCLUDES} ) source_group(tes3mp-server FILES ${SERVER} ${SERVER_HEADER}) @@ -168,6 +174,7 @@ target_link_libraries(tes3mp-server ${LUA_LIBRARIES} ${Pawn_LIBRARY} ${Breakpad_Library} + ${CallFF_LIBRARY} ) if (UNIX) diff --git a/apps/openmw-mp/Script/ScriptFunction.cpp b/apps/openmw-mp/Script/ScriptFunction.cpp index edfc788ec..b0925ce22 100644 --- a/apps/openmw-mp/Script/ScriptFunction.cpp +++ b/apps/openmw-mp/Script/ScriptFunction.cpp @@ -6,6 +6,10 @@ #include #include "ScriptFunction.hpp" +#ifndef _WIN32 // temporally disabled +#include +#endif + #if defined (ENABLE_LUA) #include "LangLua/LangLua.hpp" #endif @@ -120,105 +124,42 @@ boost::any ScriptFunction::Call(const vector &args) #endif else { - throw runtime_error("Native Call: native calls does not supported yet"); -#if 0 -#ifdef ARCH_X86 - // cdecl convention string::iterator it; vector::const_iterator it2; - vector data; + vector data; + CallArgs callArgs; for (it = def.begin(), it2 = args.begin(); it != def.end(); ++it, ++it2) { switch (*it) { case 'i': - { - unsigned int value = boost::any_cast(*it2); - data.push_back(value); + callArgs.push_integer(boost::any_cast(*it2)); break; - } - case 'q': - { - unsigned int value = boost::any_cast(*it2); - data.push_back(value); - break; - } - - case 'l': - { - unsigned long long value = boost::any_cast(*it2); - data.push_back(*reinterpret_cast(&value)); - data.push_back(*reinterpret_cast((unsigned) &value + 4)); - break; - } - - case 'w': - { - signed long long value = boost::any_cast(*it2); - data.push_back(*reinterpret_cast(&value)); - data.push_back(*reinterpret_cast((unsigned) &value + 4)); + callArgs.push_integer(boost::any_cast(*it2)); break; - } - case 'f': - { - double value = boost::any_cast(*it2); - data.push_back(*reinterpret_cast(&value)); - data.push_back(*reinterpret_cast((unsigned) &value + 4)); + callArgs.push_double(boost::any_cast(*it2)); break; - } - - case 'p': - { - void *value = boost::any_cast(*it2); - data.push_back(reinterpret_cast(value)); + case 'd': + callArgs.push_double(boost::any_cast(*it2)); break; - } - case 's': - { - const string *value = boost::any_cast(&*it2); - data.push_back(reinterpret_cast(value->c_str())); + callArgs.push_stringPtr(boost::any_cast(*it2)); + break; + case 'v': + result = boost::any(); break; - } - default: throw runtime_error("C++ call: Unknown argument identifier " + *it); } } - - unsigned int result_low; - unsigned int result_high; - unsigned int *source = &data[0]; - unsigned int size = data.size() * 4; - - asm( - "MOV EDI,ESP\n" - "SUB EDI,%3\n" // allocate memory in stack. - "MOV ESI,%4\n" // move ptr of source to ESI. - "MOV ECX,%3\n" // length of data. - "PUSH DS\n" // move DS - "POP ES\n" // to ES. - "CLD\n" // clear direction flag. - "REP MOVSB\n" // Move bytes at address DS:ESI to address ES:EDI (move to stack). - "MOV ESI,ESP\n" // stack pointer. - "SUB ESP,%3\n" - "CALL %2\n" - "MOV ESP,ESI\n" - "MOV %0,EAX\n" // move low result from eax - "MOV %1,EDX\n" // move high result from edx - : "=m"(result_low), "=m"(result_high) - : "m"(fCpp) //2, "m"(size) //3, "m"(source) //4 - : "eax", "edx", "ecx", "esi", "edi", "cc" - ); - - *reinterpret_cast(&result) = result_low; - *reinterpret_cast(((unsigned) &result) + 4) = result_high; +#ifndef _WIN32 // temporally disabled + Func f = reinterpret_cast(fCpp); + result = ::Call(f, callArgs); #else - throw runtime_error("x64 Not supported yet (builtin timers and [Call/Make]Public"); -#endif + throw runtime_error("C++ call: Windows not supported yet.") #endif } diff --git a/cmake/FindCallFF.cmake b/cmake/FindCallFF.cmake new file mode 100644 index 000000000..73e0ee7f0 --- /dev/null +++ b/cmake/FindCallFF.cmake @@ -0,0 +1,28 @@ +FIND_PATH(CallFF_INCLUDES call.hpp + ENV CPATH + PATH_SUFFIXES include/CallFF include + /usr/include + /usr/local/include + /opt/local/include + $ENV{CallFF_ROOT}/include + ) + +FIND_LIBRARY(CallFF_LIBRARY NAMES callff + PATHS + ENV LD_LIBRARY_PATH + ENV LIBRARY_PATH + /usr/lib64 + /usr/lib + /usr/local/lib64 + /usr/local/lib + /opt/local/lib + $ENV{CallFF_ROOT}/lib/* + ) + +if(CallFF_LIBRARY) + set(CallFF_LIBRARIES "${CallFF_LIBRARY}" CACHE STRING "CallFF Libraries") +endif() + +if(CallFF_INCLUDES AND CallFF_LIBRARY) + set(CallFF_FOUND TRUE) +endif(CallFF_INCLUDES AND CallFF_LIBRARY)