/*
===========================================================================
Copyright (C) 1999-2005 Id Software, Inc.
Copyright (C) 2006 Robert Beckebans <trebor_7@users.sourceforge.net>

This file is part of XreaL source code.

XreaL source code 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 2 of the License,
or (at your option) any later version.

XreaL source code 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 XreaL source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
===========================================================================
*/

// vm.h
#ifndef VM_H
#define VM_H

//Ignore __attribute__ on non-gcc platforms
#ifndef __GNUC__
#ifndef __attribute__
#define __attribute__(x)
#endif
#endif

/*
==============================================================

VIRTUAL MACHINE

==============================================================
*/

typedef struct vm_s vm_t;

typedef enum
{
	VMI_NATIVE,
	VMI_BYTECODE
} vmInterpret_t;

typedef enum
{
	TRAP_MEMSET = 100,
	TRAP_MEMCPY,
	TRAP_STRNCPY,
	TRAP_SIN,
	TRAP_COS,
	TRAP_ATAN2,
	TRAP_SQRT,
	TRAP_MATRIXMULTIPLY,
	TRAP_ANGLEVECTORS,
	TRAP_PERPENDICULARVECTOR,
	TRAP_FLOOR,
	TRAP_CEIL,

	TRAP_TESTPRINTINT,
	TRAP_TESTPRINTFLOAT
} sharedTraps_t;

void            VM_Init(void);
vm_t           *VM_Create(const char *module, intptr_t(*systemCalls) (intptr_t *), vmInterpret_t interpret);

// module should be bare: "cgame", not "cgame.dll" or "vm/cgame.qvm"

void            VM_Free(vm_t * vm);
void            VM_Clear(void);
vm_t           *VM_Restart(vm_t * vm);

intptr_t QDECL  VM_Call(vm_t * vm, int callNum, ...);

void            VM_Debug(int level);

void           *VM_ArgPtr(intptr_t intValue);
void           *VM_ExplicitArgPtr(vm_t * vm, intptr_t intValue);

#define VMA(x) VM_ArgPtr(args[x])
static ID_INLINE float _vmf(intptr_t x)
{
	union
	{
		intptr_t        l;
		float			f;
	} t;

	t.l = x;
	return t.f;
}
#define VMF(x)  _vmf(args[x])

#endif // VM_H