/* * Copyright © 2012-2013 RyDeR` * DynamicParams.inc * * This program 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, either version 3 of the License, or * (at your option) any later version. * * This program 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 this program. If not, see . */ #if defined _Included_DynamicParams #endinput #else #define _Included_DynamicParams #endif #if !defined MAX_DYNAMIC_PARAMS #define MAX_DYNAMIC_PARAMS (16) #endif enum e_ParamTypes { e_TYPE_MIXED, e_TYPE_STRING, e_TYPE_BYREF }; stock g_aiStack[MAX_DYNAMIC_PARAMS], g_iIdx ; stock pushParam(const e_ParamTypes: iParamType, { Float, _ }: ...) { if(numargs() == 2) { if(g_iIdx < MAX_DYNAMIC_PARAMS) { new iAddr ; #emit CONST.PRI g_aiStack #emit LOAD.ALT g_iIdx #emit SHL.C.ALT 2 #emit ADD #emit STOR.S.PRI iAddr switch(iParamType) { case e_TYPE_MIXED: { #emit LOAD.S.ALT iAddr #emit LOAD.S.PRI 16 #emit LOAD.I #emit STOR.I } case e_TYPE_STRING, e_TYPE_BYREF: { #emit LOAD.S.ALT iAddr #emit LOAD.S.PRI 16 #emit STOR.I } } g_iIdx++; return (g_iIdx - 1); } } return -1; } stock setParam(const e_ParamTypes: iParamType, const iIdx, { Float, _ }: ...) { if(numargs() == 3) { if(iIdx < MAX_DYNAMIC_PARAMS) { new iAddr ; #emit CONST.PRI g_aiStack #emit LOAD.S.ALT iIdx #emit SHL.C.ALT 2 #emit ADD #emit STOR.S.PRI iAddr switch(iParamType) { case e_TYPE_MIXED: { #emit LOAD.S.ALT iAddr #emit LOAD.S.PRI 20 #emit LOAD.I #emit STOR.I } case e_TYPE_STRING, e_TYPE_BYREF: { #emit LOAD.S.ALT iAddr #emit LOAD.S.PRI 20 #emit STOR.I } } return iIdx; } } return -1; } stock popParam() { if(g_iIdx > 0) { return --g_iIdx; } return 0; } stock clearParams() { g_iIdx = 0; return 1; } stock callFunction(const szName[], const bool: bClear = true) { new iParam, iAddr, iIdx = funcidx(szName) ; // Credits to Slice #emit LCTRL 1 #emit NEG #emit MOVE.ALT #emit ADD.C 32 #emit STOR.S.PRI iParam #emit LREF.S.PRI iParam #emit ADD #emit LOAD.S.ALT iIdx #emit SHL.C.ALT 3 #emit ADD #emit STOR.S.PRI iParam #emit LREF.S.PRI iParam #emit STOR.S.PRI iAddr iIdx = g_iIdx; while (iIdx--) { iParam = g_aiStack[iIdx]; #emit PUSH.S iParam } #emit LOAD.PRI g_iIdx #emit SHL.C.PRI 2 #emit PUSH.PRI if(bClear) { clearParams(); } #emit LCTRL 6 #emit ADD.C 28 #emit PUSH.PRI #emit LOAD.S.PRI iAddr #emit SCTRL 6 #emit STACK 12 #emit RETN return 0; } stock callNative(const iNativeIdx, const bool: bClear = true) { // Credits to ZeeX new iParam, iIdx ; iIdx = g_iIdx; while(iIdx--) { iParam = g_aiStack[iIdx]; #emit PUSH.S iParam } #emit LOAD.PRI g_iIdx #emit SHL.C.PRI 2 #emit PUSH.PRI #emit LCTRL 0 #emit MOVE.ALT #emit LCTRL 6 #emit ADD #emit MOVE.ALT #emit LCTRL 1 #emit SUB.ALT #emit ADD.C 56 #emit STOR.S.PRI iParam #emit LOAD.S.PRI iNativeIdx #emit SREF.S.PRI iParam #emit SYSREQ.C 0xFFFFFFFF #emit STOR.S.PRI iParam #emit LCTRL 4 #emit LOAD.ALT g_iIdx #emit SHL.C.ALT 2 #emit ADD #emit ADD.C 4 #emit SCTRL 4 if(bClear) { clearParams(); } return iParam; }