Exemplo n.º 1
0
static cell AMX_NATIVE_CALL amx_fpga_load(AMX *amx, const cell *params)
{
    set_port_directions(0); // All as inputs
    
    char *fname;
    amx_StrParam(amx, params[1], fname);
    
    uint8_t *buffer;
    if (amx_Allot(amx, 1024/sizeof(cell), (cell**)&buffer) != 0)
        return false;
    
    bool status = false;
    if (!fname[0])
    {
        have_custom_image = false;
        status = fpga_configure(NULL, buffer);
        set_port_directions(default_pins);
    }
    else
    {
        have_custom_image = true;
        
        FIL file;
        if (f_open(&file, fname, FA_READ) != FR_OK)
            return false;

        status = fpga_configure(&file, buffer);
        
        f_close(&file);
    }
    
    amx_Release(amx, (cell*)buffer);
    return status;
}
        int call(std::vector<int> const& v) {
            if (amx && fn) {
                int rezult;
                std::vector<cell> cells(v.size() + 1);

                //precall
                cells[0] = v.size() * sizeof(cell);
                for (std::size_t param_id = 0, len = v.size(); param_id < len; ++param_id) {
                    cell* phys_addr;
                    amx_Allot(amx, 1, &cells[param_id + 1], &phys_addr);
                    *phys_addr = v[param_id];
                }
                //call
                rezult = fn(amx, &cells[0]);

                //postcall
                for (std::size_t param_id = 0, len = v.size(); param_id < len; ++param_id) {
                    amx_Release(amx, cells[param_id + 1]);
                }

                return rezult;
            }
            else {
                assert(false && "error call null amx");
                return -1;
            }
        }
Exemplo n.º 3
0
int amxinit_fpga(AMX *amx)
{
    static const AMX_NATIVE_INFO funcs[] = {
        {"fpga_load", amx_fpga_load},
        {"fpga_config_outputs", amx_fpga_config_outputs},
        {"fpga_read_pins", amx_fpga_read_pins},
        {"fpga_write_pins", amx_fpga_write_pins},
        {"fpga_read", amx_fpga_read},
        {"fpga_write", amx_fpga_write},
        {0, 0}
    };
    
    if (have_custom_image)
    {
        uint8_t *buffer;
        if (amx_Allot(amx, 1024/sizeof(cell), (cell**)&buffer) != 0)
            return false;
    
        have_custom_image = false;
        fpga_configure(NULL, buffer); // Restore original FPGA image
    
        amx_Release(amx, (cell*)buffer);
    }
    
    set_port_directions(default_pins);
    
    return amx_Register(amx, funcs, -1);
}
Exemplo n.º 4
0
int main(int argc,char *argv[])
{
  extern int amx_ConsoleInit(AMX *amx);
  extern int amx_ConsoleCleanup(AMX *amx);
  extern int amx_CoreInit(AMX *amx);
  extern int amx_CoredCleanp(AMX *amx);

  size_t memsize;
  void *program;
  AMX amx;
  int index, err;
  cell amx_addr, *phys_addr;
  char output[128];

  if (argc != 4)
    PrintUsage(argv[0]);
  if ((memsize = aux_ProgramSize(argv[1])) == 0)
    PrintUsage(argv[0]);

  program = malloc(memsize);
  if (program == NULL)
    ErrorExit(NULL, AMX_ERR_MEMORY);

  err = aux_LoadProgram(&amx, argv[1], program);
  if (err)
    ErrorExit(&amx, err);

  amx_ConsoleInit(amx);
  err = amx_CoreInit(amx);
  if (err)
    ErrorExit(&amx, err);

  err = amx_FindPublic(&amx, argv[2], &index);
  if (err)
    ErrorExit(&amx, err);

  err = amx_Allot(&amx, strlen(argv[3]) + 1, &amx_addr, &phys_addr);
  if (err)
    ErrorExit(&amx, err);
  amx_SetString(phys_addr, argv[3], 0);

  err = amx_Exec(&amx, NULL, index, 1, amx_addr);
  if (err)
    ErrorExit(&amx, err);

  amx_GetString(output, phys_addr);
  amx_Release(&amx, amx_addr);
  printf("%s returns %s\n", argv[1], output);

  amx_ConsoleCleanup(&amx);
  amx_CoreCleanup(&amx);
  amx_Cleanup(&amx);
  free(program);
  return 0;
}
Exemplo n.º 5
0
uint32_t CScriptTimers::NewEx(char* _scriptName, uint32_t _interval, uint32_t _repeat, cell* _params, AMX* pAMX)
{
	timerCount++;

	timerData* _timer = new timerData;

	strncpy(_timer->funcName, _scriptName, 255);
	_timer->totalTime = _interval;
	_timer->remainingTime = _interval;
	_timer->timerRepeat = _repeat;
	_timer->timerKilled = 0;
	_timer->timerAMX = pAMX;
	
	cell amx_addr[256];
	
	char* szParamList;
	amx_StrParam(pAMX, _params[4], szParamList);
	int j, numstr, iOff = 5;
	if (szParamList == NULL) j = 0;
	else j = strlen(szParamList);
	numstr = 0;
	while (j)
	{
		j--;
		cell *paddr = NULL;
		if (*(szParamList + j) == 'a')
		{
			int numcells = *get_amxaddr(pAMX, _params[j + iOff + 1]);
			if (amx_Allot(pAMX, numcells, &amx_addr[numstr], &paddr) == AMX_ERR_NONE)
			{
				memcpy(paddr, get_amxaddr(pAMX, _params[j + iOff]), numcells * sizeof (cell));
				numstr++;
			}
		}
		else if (*(szParamList + j) == 's')
		{
			char* szParamText;
			amx_StrParam(pAMX, _params[j + iOff], szParamText);
			if (szParamText != NULL && strlen(szParamText) > 0)
			{
				int numcells = strlen(szParamText) + 1;
				if (amx_Allot(pAMX, numcells, &amx_addr[numstr], &paddr) == AMX_ERR_NONE)
				{
					amx_SetString(paddr, szParamText, 0, 0, UNLIMITED);
					numstr++;
				}
			}
			else
			{
				*szParamText = 1;
				*(szParamText + 1) = 0;
				if (amx_Allot(pAMX, 1, &amx_addr[numstr], &paddr) == AMX_ERR_NONE)
				{
					amx_SetString(paddr, szParamText, 0, 0, UNLIMITED);
					numstr++;
				}
			}
		}
		else
		{
			amx_addr[numstr] = *get_amxaddr(pAMX, _params[j + iOff]);
			numstr++;
		}
	}
	void* mem = NULL;
	if (numstr)
	{
		mem = malloc(numstr * sizeof (cell));
		memcpy(mem, &amx_addr, numstr * sizeof (cell));
		_timer->timerParams = mem;
	}
	else
	{
		_timer->timerParams = NULL;
	}
	_timer->paramCount = numstr;
	
	timersMap.insert(std::pair<uint32_t, timerData*>(timerCount, _timer));
	return timerCount;
}
Exemplo n.º 6
0
// native ArraySortEx(Array:array, const comparefunc[], data[]="", data_size=0);
static cell AMX_NATIVE_CALL ArraySortEx(AMX* amx, cell* params)
{
	CellArray* vec = ArrayHandles.lookup(params[1]);

	if (!vec)
	{
		LogError(amx, AMX_ERR_NATIVE, "Invalid array handle provided (%d)", params[1]);
		return 0;
	}

	int len;
	char* funcName = get_amxstring(amx, params[2], 0, len);

	int func = registerSPForwardByName(amx, funcName, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_DONE);

	if (!func)
	{
		LogError(amx, AMX_ERR_NATIVE, "The public function \"%s\" was not found.", funcName);
		return 0;
	}

	size_t arraysize = vec->size();
	size_t blocksize = vec->blocksize();
	cell *array = vec->base();
	cell amx_addr1 = 0, amx_addr2 = 0, *phys_addr = NULL;

	if (blocksize > 1)
	{
		int err;
		if ((err = amx_Allot(amx, blocksize, &amx_addr1, &phys_addr)) != AMX_ERR_NONE
		|| ( err = amx_Allot(amx, blocksize, &amx_addr2, &phys_addr)) != AMX_ERR_NONE)
		{
			LogError(amx, err, "Ran out of memory");
			return 0;
		}
	}

	ArraySort_s oldinfo = SortInfo;

	SortInfo.func        = func;
	SortInfo.array_base  = array;
	SortInfo.array_bsize = static_cast<cell>(blocksize);
	SortInfo.array_hndl  = params[1];
	SortInfo.data        = params[3];
	SortInfo.size        = params[4];
	SortInfo.amx         = amx;
	SortInfo.addr1       = amx_addr1;
	SortInfo.addr2       = amx_addr2;

	qsort(array, arraysize, blocksize * sizeof(cell), blocksize > 1 ? SortArrayListExArray : SortArrayListExCell);

	SortInfo = oldinfo;

	if (blocksize > 1)
	{
		amx_Release(amx, amx_addr1);
		amx_Release(amx, amx_addr2);
	}

	unregisterSPForward(func);

	return 1;
}
Exemplo n.º 7
0
int Invoke::callNative(const PAWN::Native * native, ...)
{
	if (amx_list.empty() || amx_map.find(native->name) == amx_map.end())
	{
		return 0;
	}

	unsigned int amx_addr = amx_map[native->name], count = strlen(native->data), variables = 0;
	cell * params = new cell[count + 1], * physAddr[6];
	params[0] = count * sizeof(cell);
	va_list input;
	va_start(input, native);
	for (unsigned int i = 0; i < count; ++i)
	{
		switch (native->data[i])
		{
			case 'd':
			case 'i':
			{
				params[i + 1] = va_arg(input, int);
			}
			break;
			case 'f':
			{
				float value = (float)va_arg(input, double);
				params[i + 1] = amx_ftoc(value);
			}
			break;
			case 's':
			{
				char * string = va_arg(input, char *);
				amx_Allot(amx_list.front(), strlen(string) + 1, &params[i + 1], &physAddr[variables++]);
				amx_SetString(physAddr[variables - 1], string, 0, 0, strlen(string) + 1);
			}
			break;
			case 'v':
			{
				va_arg(input, void *);
				amx_Allot(amx_list.front(), 1, &params[i + 1], &physAddr[variables++]);
			}
			break;
			case 'p':
			{
				va_arg(input, void *);
				int size = va_arg(input, int);
				amx_Allot(amx_list.front(), size, &params[++i], &physAddr[variables++]);
				params[i + 1] = size;
			}
			break;
		}
	}
	va_end(input);
	amx_Function_t amx_Function = (amx_Function_t)amx_addr;
	int value = amx_Function(amx_list.front(), params);
	if (variables)
	{
		variables = 0;
		va_start(input, native);
		for (unsigned int i = 0; i < count; ++i)
		{
			switch (native->data[i])
			{
				case 's':
				{
					amx_Release(amx_list.front(), params[i + 1]);
				}
				break;
				case 'v':
				{
					unsigned int * value = va_arg(input, unsigned int *), * returnValue = (unsigned int *)physAddr[variables++];
					* value = * returnValue;
					amx_Release(amx_list.front(), params[i + 1]);
				}
				break;
				case 'p':
				{
					char * text = va_arg(input, char *);
					int size = va_arg(input, int);
					amx_GetString(text, physAddr[variables++], 0, size);
					amx_Release(amx_list.front(), params[++i]);
				}
				break;
				default:
				{
					va_arg(input, void *);
				}
				break;
			}
		}
		va_end(input);
	}
	delete [] params;
	return value;
}
Exemplo n.º 8
0
cell CForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{
	cell realParams[FORWARD_MAX_PARAMS];
	cell *physAddrs[FORWARD_MAX_PARAMS];

	const int STRINGEX_MAXLENGTH = 128;

	cell globRetVal = 0;

	AMXForwardList::iterator iter;

	for (iter = m_Funcs.begin(); iter != m_Funcs.end(); iter++)
	{
		if (iter->pPlugin->isExecutable(iter->func))
		{
			// Get debug info
			AMX *amx = (*iter).pPlugin->getAMX();
			Debugger *pDebugger = (Debugger *)amx->userdata[UD_DEBUGGER];
			
			if (pDebugger)
				pDebugger->BeginExec();
			
			// handle strings & arrays
			int i;
			
			for (i = 0; i < m_NumParams; ++i)
			{
				if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
				{
					const char *str = reinterpret_cast<const char*>(params[i]);
					cell *tmp;
					if (!str)
						str = "";
					amx_Allot(iter->pPlugin->getAMX(), (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
					amx_SetStringOld(tmp, str, 0, 0);
					physAddrs[i] = tmp;
				}
				else if (m_ParamTypes[i] == FP_ARRAY)
				{
					cell *tmp;
					amx_Allot(amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
					physAddrs[i] = tmp;
					
					if (preparedArrays[params[i]].type == Type_Cell)
					{
						memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
					} else {
						char *data = (char*)preparedArrays[params[i]].ptr;
						
						for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
							*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
					}
				} else {
					realParams[i] = params[i];
				}
			}
			
			//Push the parameters in reverse order. Weird, unfriendly part of Small 3.0!
			for (i = m_NumParams-1; i >= 0; i--)
			{
				amx_Push(amx, realParams[i]);
			}
			
			// exec
			cell retVal = 0;
#if defined BINLOG_ENABLED
			g_BinLog.WriteOp(BinLog_CallPubFunc, (*iter).pPlugin->getId(), iter->func);
#endif
			int err = amx_Exec(amx, &retVal, iter->func);
			
			// log runtime error, if any
			if (err != AMX_ERR_NONE)
			{
				//Did something else set an error?
				if (pDebugger && pDebugger->ErrorExists())
				{
					//we don't care, something else logged the error.
				}
				else if (err != -1)
				{
					//nothing logged the error so spit it out anyway
					LogError(amx, err, NULL);
				}
			}
			
			amx->error = AMX_ERR_NONE;
			
			if (pDebugger)
				pDebugger->EndExec();

			// cleanup strings & arrays
			for (i = 0; i < m_NumParams; ++i)
			{
				if (m_ParamTypes[i] == FP_STRING)
				{
					amx_Release(iter->pPlugin->getAMX(), realParams[i]);
				}
				else if (m_ParamTypes[i] == FP_STRINGEX)
				{
					// copy back
					amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
					amx_Release(iter->pPlugin->getAMX(), realParams[i]);
				}
				else if (m_ParamTypes[i] == FP_ARRAY)
				{
					// copy back
					if (preparedArrays[params[i]].copyBack)
					{
						cell *tmp = physAddrs[i];
						if (preparedArrays[params[i]].type == Type_Cell)
						{
							memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
						} else {
							char *data = (char*)preparedArrays[params[i]].ptr;
							
							for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
								*data++ = static_cast<char>(*tmp++ & 0xFF);
						}
					}
					amx_Release(iter->pPlugin->getAMX(), realParams[i]);
				}
			}

			// decide what to do (based on exectype and retval)
			switch (m_ExecType)
			{
				case ET_IGNORE:
					break;
				case ET_STOP:
					if (retVal > 0)
						return retVal;
				case ET_STOP2:
					if (retVal == 1)
						return 1;
					else if (retVal > globRetVal)
						globRetVal = retVal;
					break;
				case ET_CONTINUE:
					if (retVal > globRetVal)
						globRetVal = retVal;
					break;
			}
		}
	}
	
	return globRetVal;
}
Exemplo n.º 9
0
cell CSPForward::execute(cell *params, ForwardPreparedArray *preparedArrays)
{
	if (isFree)
		return 0;
	
	const int STRINGEX_MAXLENGTH = 128;

	cell realParams[FORWARD_MAX_PARAMS];
	cell *physAddrs[FORWARD_MAX_PARAMS];

	if (!m_HasFunc || m_ToDelete)
		return 0;

	CPluginMngr::CPlugin *pPlugin = g_plugins.findPluginFast(m_Amx);
	if (!pPlugin->isExecutable(m_Func))
		return 0;

	m_InExec = true;

	Debugger *pDebugger = (Debugger *)m_Amx->userdata[UD_DEBUGGER];
	if (pDebugger)
		pDebugger->BeginExec();

	// handle strings & arrays
	int i;
	
	for (i = 0; i < m_NumParams; ++i)
	{
		if (m_ParamTypes[i] == FP_STRING || m_ParamTypes[i] == FP_STRINGEX)
		{
			const char *str = reinterpret_cast<const char*>(params[i]);
			if (!str)
				str = "";
			cell *tmp;
			amx_Allot(m_Amx, (m_ParamTypes[i] == FP_STRING) ? strlen(str) + 1 : STRINGEX_MAXLENGTH, &realParams[i], &tmp);
			amx_SetStringOld(tmp, str, 0, 0);
			physAddrs[i] = tmp;
		}
		else if (m_ParamTypes[i] == FP_ARRAY)
		{
			cell *tmp;
			amx_Allot(m_Amx, preparedArrays[params[i]].size, &realParams[i], &tmp);
			physAddrs[i] = tmp;
			
			if (preparedArrays[params[i]].type == Type_Cell)
			{
				memcpy(tmp, preparedArrays[params[i]].ptr, preparedArrays[params[i]].size * sizeof(cell));
			} else {
				char *data = (char*)preparedArrays[params[i]].ptr;
				
				for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
					*tmp++ = (static_cast<cell>(*data++)) & 0xFF;
			}
		} else {
			realParams[i] = params[i];
		}
	}
	
	for (i = m_NumParams - 1; i >= 0; i--)
		amx_Push(m_Amx, realParams[i]);
	
	// exec
	cell retVal;
#if defined BINLOG_ENABLED
	g_BinLog.WriteOp(BinLog_CallPubFunc, pPlugin->getId(), m_Func);
#endif
	int err = amx_Exec(m_Amx, &retVal, m_Func);
	
	if (err != AMX_ERR_NONE)
	{
		//Did something else set an error?
		if (pDebugger && pDebugger->ErrorExists())
		{
			//we don't care, something else logged the error.
		}
		else if (err != -1)
		{
			//nothing logged the error so spit it out anyway
			LogError(m_Amx, err, NULL);
		}
	}
	
	if (pDebugger)
		pDebugger->EndExec();
	
	m_Amx->error = AMX_ERR_NONE;

	// cleanup strings & arrays
	for (i = 0; i < m_NumParams; ++i)
	{
		if (m_ParamTypes[i] == FP_STRING)
		{
			amx_Release(m_Amx, realParams[i]);
		}
		else if (m_ParamTypes[i] == FP_STRINGEX)
		{
			// copy back
			amx_GetStringOld(reinterpret_cast<char*>(params[i]), physAddrs[i], 0);
			amx_Release(m_Amx, realParams[i]);
		}
		else if (m_ParamTypes[i] == FP_ARRAY)
		{
			// copy back
			if (preparedArrays[params[i]].copyBack)
			{
				cell *tmp = physAddrs[i];
				if (preparedArrays[params[i]].type == Type_Cell)
				{
					memcpy(preparedArrays[params[i]].ptr, tmp, preparedArrays[params[i]].size * sizeof(cell));
				} else {
					char *data = (char*)preparedArrays[params[i]].ptr;
					
					for (unsigned int j = 0; j < preparedArrays[params[i]].size; ++j)
						*data++ = static_cast<char>(*tmp++ & 0xFF);
				}
			}
			amx_Release(m_Amx, realParams[i]);
		}
	}

	m_InExec = false;

	return retVal;
}