/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see .
*/
/** @file squirrel_helper.hpp declarations and parts of the implementation of the class for convert code */
#ifndef SQUIRREL_HELPER_HPP
#define SQUIRREL_HELPER_HPP
#include "squirrel.hpp"
#include "../core/smallvec_type.hpp"
#include "../economy_type.h"
#include "../string_func.h"
#include "squirrel_helper_type.hpp"
template const char *GetClassName();
/**
* The Squirrel convert routines
*/
namespace SQConvert {
/**
* Pointers assigned to this class will be free'd when this instance
* comes out of scope. Useful to make sure you can use stredup(),
* without leaking memory.
*/
struct SQAutoFreePointers : SmallVector {
~SQAutoFreePointers()
{
for (uint i = 0; i < std::vector::size(); i++) free(std::vector::operator[](i));
}
};
template struct YesT {
static const bool Yes = Y;
static const bool No = !Y;
};
/**
* Helper class to recognize if the given type is void. Usage: 'IsVoidT::Yes'
*/
template struct IsVoidT : YesT {};
template <> struct IsVoidT : YesT {};
/**
* Helper class to recognize if the function/method return type is void.
*/
template struct HasVoidReturnT;
/* functions */
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
/* methods */
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
template struct HasVoidReturnT : IsVoidT {};
/**
* Special class to make it possible for the compiler to pick the correct GetParam().
*/
template class ForceType { };
/**
* To return a value to squirrel, we call this function. It converts to the right format.
*/
template static int Return(HSQUIRRELVM vm, T t);
template <> inline int Return (HSQUIRRELVM vm, uint8 res) { sq_pushinteger(vm, (int32)res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, uint16 res) { sq_pushinteger(vm, (int32)res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, uint32 res) { sq_pushinteger(vm, (int32)res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, int8 res) { sq_pushinteger(vm, res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, int16 res) { sq_pushinteger(vm, res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, int32 res) { sq_pushinteger(vm, res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, int64 res) { sq_pushinteger(vm, res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, Money res) { sq_pushinteger(vm, res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, bool res) { sq_pushbool (vm, res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; }
template <> inline int Return(HSQUIRRELVM vm, const char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } return 1; }
template <> inline int Return (HSQUIRRELVM vm, void *res) { sq_pushuserpointer(vm, res); return 1; }
template <> inline int Return (HSQUIRRELVM vm, HSQOBJECT res) { sq_pushobject(vm, res); return 1; }
/**
* To get a param from squirrel, we call this function. It converts to the right format.
*/
template static T GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr);
template <> inline uint8 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline uint16 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline uint32 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline int8 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline int16 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline int32 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline int64 GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline Money GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger (vm, index, &tmp); return tmp; }
template <> inline bool GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQBool tmp; sq_getbool (vm, index, &tmp); return tmp != 0; }
template <> inline void *GetParam(ForceType , HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer tmp; sq_getuserpointer(vm, index, &tmp); return tmp; }
template <> inline const char *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
{
/* Convert what-ever there is as parameter to a string */
sq_tostring(vm, index);
const SQChar *tmp;
sq_getstring(vm, -1, &tmp);
char *tmp_str = stredup(tmp);
sq_poptop(vm);
ptr->push_back((void *)tmp_str);
str_validate(tmp_str, tmp_str + strlen(tmp_str));
return tmp_str;
}
template <> inline Array *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr)
{
/* Sanity check of the size. */
if (sq_getsize(vm, index) > UINT16_MAX) throw sq_throwerror(vm, "an array used as parameter to a function is too large");
SQObject obj;
sq_getstackobj(vm, index, &obj);
sq_pushobject(vm, obj);
sq_pushnull(vm);
SmallVector data;
while (SQ_SUCCEEDED(sq_next(vm, -2))) {
SQInteger tmp;
if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) {
data.push_back((int32)tmp);
} else {
sq_pop(vm, 4);
throw sq_throwerror(vm, "a member of an array used as parameter to a function is not numeric");
}
sq_pop(vm, 2);
}
sq_pop(vm, 2);
Array *arr = (Array*)MallocT(sizeof(Array) + sizeof(int32) * data.size());
arr->size = data.size();
memcpy(arr->array, data.Begin(), sizeof(int32) * data.size());
ptr->push_back(arr);
return arr;
}
/**
* Helper class to recognize the function type (retval type, args) and use the proper specialization
* for SQ callback. The partial specializations for the second arg (Tis_void_retval) are not possible
* on the function. Therefore the class is used instead.
*/
template ::Yes> struct HelperT;
/**
* The real C++ caller for function with return value and 0 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
{
return Return(vm, (*func)());
}
};
/**
* The real C++ caller for function with no return value and 0 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(), HSQUIRRELVM vm)
{
(*func)();
return 0;
}
};
/**
* The real C++ caller for method with return value and 0 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
{
return Return(vm, (instance->*func)());
}
};
/**
* The real C++ caller for method with no return value and 0 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
{
(instance->*func)();
return 0;
}
static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(), HSQUIRRELVM vm)
{
return new Tcls();
}
};
/**
* The real C++ caller for function with return value and 1 param.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (*func)(
GetParam(ForceType(), vm, 2, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for function with no return value and 1 param.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(*func)(
GetParam(ForceType(), vm, 2, &ptr)
);
return 0;
}
};
/**
* The real C++ caller for method with return value and 1 param.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (instance->*func)(
GetParam(ForceType(), vm, 2, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for method with no return value and 1 param.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(instance->*func)(
GetParam(ForceType(), vm, 2, &ptr)
);
return 0;
}
static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tcls *inst = new Tcls(
GetParam(ForceType(), vm, 2, &ptr)
);
return inst;
}
};
/**
* The real C++ caller for function with return value and 2 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for function with no return value and 2 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr)
);
return 0;
}
};
/**
* The real C++ caller for method with return value and 2 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for method with no return value and 2 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr)
);
return 0;
}
static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tcls *inst = new Tcls(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr)
);
return inst;
}
};
/**
* The real C++ caller for function with return value and 3 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for function with no return value and 3 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr)
);
return 0;
}
};
/**
* The real C++ caller for method with return value and 3 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for method with no return value and 3 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr)
);
return 0;
}
static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tcls *inst = new Tcls(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr)
);
return inst;
}
};
/**
* The real C++ caller for function with return value and 4 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for function with no return value and 4 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr)
);
return 0;
}
};
/**
* The real C++ caller for method with return value and 4 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for method with no return value and 4 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr)
);
return 0;
}
static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tcls *inst = new Tcls(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr)
);
return inst;
}
};
/**
* The real C++ caller for function with return value and 5 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for function with no return value and 5 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr)
);
return 0;
}
};
/**
* The real C++ caller for method with return value and 5 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for method with no return value and 5 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr)
);
return 0;
}
static Tcls *SQConstruct(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tcls *inst = new Tcls(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr)
);
return inst;
}
};
/**
* The real C++ caller for function with return value and 10 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr),
GetParam(ForceType(), vm, 7, &ptr),
GetParam(ForceType(), vm, 8, &ptr),
GetParam(ForceType(), vm, 9, &ptr),
GetParam(ForceType(), vm, 10, &ptr),
GetParam(ForceType(), vm, 11, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for function with no return value and 10 params.
*/
template
struct HelperT {
static int SQCall(void *instance, Tretval (*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr),
GetParam(ForceType(), vm, 7, &ptr),
GetParam(ForceType(), vm, 8, &ptr),
GetParam(ForceType(), vm, 9, &ptr),
GetParam(ForceType(), vm, 10, &ptr),
GetParam(ForceType(), vm, 11, &ptr)
);
return 0;
}
};
/**
* The real C++ caller for method with return value and 10 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
Tretval ret = (instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr),
GetParam(ForceType(), vm, 7, &ptr),
GetParam(ForceType(), vm, 8, &ptr),
GetParam(ForceType(), vm, 9, &ptr),
GetParam(ForceType(), vm, 10, &ptr),
GetParam(ForceType(), vm, 11, &ptr)
);
return Return(vm, ret);
}
};
/**
* The real C++ caller for method with no return value and 10 params.
*/
template
struct HelperT {
static int SQCall(Tcls *instance, Tretval (Tcls::*func)(Targ1, Targ2, Targ3, Targ4, Targ5, Targ6, Targ7, Targ8, Targ9, Targ10), HSQUIRRELVM vm)
{
SQAutoFreePointers ptr;
(instance->*func)(
GetParam(ForceType(), vm, 2, &ptr),
GetParam(ForceType(), vm, 3, &ptr),
GetParam(ForceType(), vm, 4, &ptr),
GetParam(ForceType(), vm, 5, &ptr),
GetParam(ForceType(), vm, 6, &ptr),
GetParam(ForceType(), vm, 7, &ptr),
GetParam(ForceType(), vm, 8, &ptr),
GetParam(ForceType(), vm, 9, &ptr),
GetParam(ForceType