/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */

		#include <cstdio>

		#include "binding_helpers.h"
		#include "sqstdblob.h"
		#include "filesystem/io_handle.h"
		#include "filesystem/filesystem.h"
		#include "input/input_system.h"
		#include "platform.h"

		using namespace GS;
		using namespace GS::Input;
		using namespace GS::Script;

#include <vector>
#include <string>
#include <iostream>
typedef unsigned char       BYTE;

static const std::string base64_chars =
	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
	"abcdefghijklmnopqrstuvwxyz"
	"0123456789+/";

static inline bool is_base64(BYTE c) {
	return (isalnum(c) || (c == '+') || (c == '/'));
}

std::string base64_encode(BYTE const *buf, unsigned int bufLen) {
	std::string ret;
	int i = 0;
	int j = 0;
	BYTE char_array_3[3];
	BYTE char_array_4[4];

	while (bufLen--) {
		char_array_3[i++] = *(buf++);
		if (i == 3) {
			char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
			char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
			char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
			char_array_4[3] = char_array_3[2] & 0x3f;

			for (i = 0; (i < 4); i++)
				ret += base64_chars[char_array_4[i]];
			i = 0;
		}
	}

	if (i) {
		for (j = i; j < 3; j++)
			char_array_3[j] = '\0';

		char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
		char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
		char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
		char_array_4[3] = char_array_3[2] & 0x3f;

		for (j = 0; (j < i + 1); j++)
			ret += base64_chars[char_array_4[j]];

		while ((i++ < 3))
			ret += '=';
	}

	return ret;
}

std::vector<BYTE> base64_decode(std::string const &encoded_string) {
	int in_len = encoded_string.size();
	int i = 0;
	int j = 0;
	int in_ = 0;
	BYTE char_array_4[4], char_array_3[3];
	std::vector<BYTE> ret;

	while (in_len-- && (encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
		char_array_4[i++] = encoded_string[in_];
		in_++;
		if (i == 4) {
			for (i = 0; i < 4; i++)
				char_array_4[i] = base64_chars.find(char_array_4[i]);

			char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
			char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
			char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

			for (i = 0; (i < 3); i++)
				ret.push_back(char_array_3[i]);
			i = 0;
		}
	}

	if (i) {
		for (j = i; j < 4; j++)
			char_array_4[j] = 0;

		for (j = 0; j < 4; j++)
			char_array_4[j] = base64_chars.find(char_array_4[j]);

		char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
		char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
		char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];

		for (j = 0; (j < i - 1); j++)
			ret.push_back(char_array_3[j]);
	}

	return ret;
}

SQInteger BlobFromStringBase64(HSQUIRRELVM vm) {
	__SQ_GETSTART(1)
	__SQ_GETSTRING(data)
	__SQ_GETEND;

	std::vector<BYTE> str = base64_decode(std::string(data, strlen(data)));
	size_t size = str.size();
	void *p = sqstd_createblob(vm, size); // blob on stack
	if (!p)
		return sq_throwerror(vm, "Failed to create allocate blob memory.");

	memcpy(p, str.data(), size);

	return 1;
}

SQInteger			BlobToStringBase64(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
		SQUserPointer blob;
		sqstd_getblob(vm, __sq_stackpos, &blob); 
		size_t size = sqstd_getblobsize(vm, __sq_stackpos);
		__SQ_GETUPDATESTACK
		__SQ_GETEND;

		__SQ_RETURNSTRING(base64_encode((const unsigned char *)blob, size).c_str())
}

SQInteger			BlobFromString(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	//	sq_getstring(vm, __sq_stackpos, &__VARNAME__); __SQ_GETUPDATESTACK
	__SQ_GETSTRING(data)
	__SQ_GETEND
		size_t size = strlen(data);
	void *p = sqstd_createblob(vm, size);	// blob on stack
	if (!p)
		return sq_throwerror(vm, "Failed to create allocate blob memory.");

	memcpy(p, data, strlen(data));

		return 1;
}

//------------------------------------------------------------------------------
SQInteger			GetMouseDevice(HSQUIRRELVM vm)
{	__SQ_RETURNSAFEPTR(Platform::Get().input_system->GetDevice("mouse"), typetag_InputDevice)	}
SQInteger			GetKeyboardDevice(HSQUIRRELVM vm)
{	__SQ_RETURNSAFEPTR(Platform::Get().input_system->GetDevice("keyboard"), typetag_InputDevice)	}
SQInteger			GetInputDevice(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(name)
	Device *device = Platform::Get().input_system->GetDevice(name);
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(device, typetag_InputDevice)
}
SQInteger			GetInputDeviceFromGuid(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(guid)
	Device *device = Platform::Get().input_system->GetDeviceFromGuid(guid);
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(device, typetag_InputDevice)
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			DeviceIsKeyDown(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(device, Device, typetag_InputDevice)
	__SQ_GETINT(key)
	__SQ_GETEND
	__SQ_RETURNBOOL(device->IsDown((Device::KeyCode)key))
}
SQInteger			DeviceWasKeyDown(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(device, Device, typetag_InputDevice)
	__SQ_GETINT(key)
	__SQ_GETEND
	__SQ_RETURNBOOL(device->WasDown((Device::KeyCode)key))
}
SQInteger			DeviceKeyPressed(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(device, Device, typetag_InputDevice)
	__SQ_GETINT(key)
	__SQ_GETEND
	__SQ_RETURNBOOL(device->IsDown((Device::KeyCode)key) && !device->WasDown((Device::KeyCode)key))
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			DeviceInputSetValue(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(device, Device, typetag_InputDevice)
	__SQ_GETINT(input)
	__SQ_GETFLOAT(value)
	__SQ_GETEND
	__SQ_RETURNBOOL(device->SetValue((Device::InputCode)input, value))
}
SQInteger			DeviceInputValue(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(device, Device, typetag_InputDevice)
	__SQ_GETINT(input)
	__SQ_GETEND
	__SQ_RETURNFLOAT(device->GetValue((Device::InputCode)input))
}
SQInteger			DeviceInputLastValue(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(device, Device, typetag_InputDevice)
	__SQ_GETINT(input)
	__SQ_GETEND
	__SQ_RETURNFLOAT(device->GetLastValue((Device::InputCode)input))
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			GetDeviceList(HSQUIRRELVM vm)
{
	StringList list;
	Platform::Get().input_system->GetDeviceList(list);

	sq_newarray(vm, 0);
	ListForeach(String, name, list)
	{
		sq_pushstring(vm, name.Object().c_str(), name.Object().Len());
		sq_arrayappend(vm, -2);
	}
	return 1;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			GetDeviceGuidList(HSQUIRRELVM vm)
{
	StringList list;
	Platform::Get().input_system->GetDeviceGuidList(list);

	sq_newarray(vm, 0);
	ListForeach(String, name, list)
	{
		sq_pushstring(vm, name.Object().c_str(), name.Object().Len());
		sq_arrayappend(vm, -2);
	}
	return 1;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			DeviceSetEffect(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(device, Device, typetag_InputDevice)
	__SQ_GETINT(effect)
	__SQ_GETFLOAT(v)
	__SQ_GETEND
	device->SetEffect(Device::Effect(effect), v);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			Include(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(path)

	SquirrelVM *sqvm = (SquirrelVM *)sq_getforeignptr(vm);

	Array <char> data;
	if	(!Platform::Get().io->FileLoad(path, data) || !sqvm->Compile(data, data.GetCount(), NULL, path))
		return sq_throwerror(vm, String::Format("Failed to include script '%s'.", path).c_str());

	__SQ_GETEND
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//--------------------------------------------
SQInteger			FileRename(HSQUIRRELVM vm)
//--------------------------------------------
{
	__SQ_GETSTART(2)
	__SQ_GETSTRING(oldname)
	__SQ_GETSTRING(newname)
	bool r = oldname && newname ? !rename(oldname, newname) : false;
	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}

//--------------------------------------------
SQInteger			FileDelete(HSQUIRRELVM vm)
//--------------------------------------------
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(filename)
	bool r =  Platform::Get().io->Delete(filename) ;
	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}

SQInteger			FolderCreate(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(foldername)
	
	bool r =  Platform::Get().io->MkDir(foldername);

	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}

#include <windows.h>
#include <string>
SQInteger			FolderExist(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(foldername)
	
	__SQ_GETEND

	bool r =  false;
	DWORD ftyp = GetFileAttributesA(foldername);
	if (ftyp == INVALID_FILE_ATTRIBUTES)
		__SQ_RETURNBOOL(false);  //something is wrong with your path!

	if (ftyp & FILE_ATTRIBUTE_DIRECTORY)
		__SQ_RETURNBOOL(true);   // this is a directory!
	  
	__SQ_RETURNBOOL(false)
}

SQInteger			FileCopy(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSTRING(src)
	__SQ_GETSTRING(dst)
	
	bool r =  Platform::Get().io->FileCopy(src, dst);

	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}

SQInteger			FileMove(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSTRING(src)
	__SQ_GETSTRING(dst)
	
	bool r =  Platform::Get().io->FileMove(src, dst);

	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}
SQInteger			FileExists(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(uri)
	bool r = Platform::Get().io->Exists(uri);
	__SQ_GETEND
	__SQ_RETURNBOOL(r)
}
SQInteger			FileReadAsBlob(HSQUIRRELVM vm)
{
	__SQ_GETSTART(1)
	__SQ_GETSTRING(name)
	AutoPtr <IO::Handle> h(Platform::Get().io->Open(name));
	if	(h.IsNull())
		return sq_throwerror(vm, String::Format("Failed to open file '%s'.", name));

	size_t size = h->GetSize();
	void *p = sqstd_createblob(vm, size);	// blob on stack
	if	(!p)
		return sq_throwerror(vm, "Failed to create allocate blob memory.");
	h->Read(p, size);

	__SQ_GETEND
	return 1;
}
SQInteger			FileWriteFromBlob(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSTRING(name)
	void *p = NULL;
	sqstd_getblob(vm, __SQ_STACKPOS, &p);
	size_t size = sqstd_getblobsize(vm, __SQ_STACKPOS);
	__SQ_GETUPDATESTACK

	AutoPtr <IO::Handle> h(Platform::Get().io->Open(name, IO::ModeWrite));
	if	(h.IsNull())
		return sq_throwerror(vm, String::Format("Failed to open file '%s'.", name));
	if	(h->Write(p, size) != size)
		return sq_throwerror(vm, String::Format("An error occurred while writing blob to file '%s'.", name));
	__SQ_GETEND
	__SQ_RETURN
}

SQInteger			FileWriteFromString(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSTRING(name)
	__SQ_GETSTRING(text)

	AutoPtr <IO::Handle> h(Platform::Get().io->Open(name, IO::ModeWrite));
	if	(h.IsNull())
		return sq_throwerror(vm, String::Format("Failed to open file '%s'.", name));
	if	(!h->Write(text, String(text).Size()))
		return sq_throwerror(vm, String::Format("An error occurred while writing string to file '%s'.", name));
	__SQ_GETEND
	__SQ_RETURN
}

SQInteger			FileOpen(HSQUIRRELVM vm)
{	
	__SQ_GETSTART(2)
	__SQ_GETSTRING(name)
	__SQ_GETINT(mode)

	AutoPtr <IO::Handle> h(Platform::Get().io->Open(name, (GS::IO::Mode)mode));
	if	(h.IsNull())
		return sq_throwerror(vm, String::Format("Failed to open file '%s'.", name));
	
	__SQ_GETEND
	__SQ_RETURNSAFEPTR(h.Detach(), typetag_FileHandle)
}

SQInteger			FileClose(HSQUIRRELVM vm)
{		
	__SQ_GETSINGLESAFEPTR(h, IO::Handle, typetag_FileHandle)
	h->GetIOSystem()->Close(h);
	delete h;
	__SQ_RETURN
}
	
SQInteger			FileWriteFloat(HSQUIRRELVM vm)
{		
	__SQ_GETSTART(2)	
	__SQ_GETSAFEPTR(h, IO::Handle, typetag_FileHandle)
	__SQ_GETFLOAT(f)
	__SQ_GETEND
	h->Write(f);

	__SQ_RETURN
}
SQInteger			FileReadFloat(HSQUIRRELVM vm)
{		
	__SQ_GETSINGLESAFEPTR(h, IO::Handle, typetag_FileHandle)
	float f = h->Read<float>();

	__SQ_RETURNFLOAT(f)
}
SQInteger			FileWriteInt(HSQUIRRELVM vm)
{		
	__SQ_GETSTART(2)	
	__SQ_GETSAFEPTR(h, IO::Handle, typetag_FileHandle)
	__SQ_GETINT(i)
	__SQ_GETEND
	h->Write(i);

	__SQ_RETURN
}
SQInteger			FileReadInt(HSQUIRRELVM vm)
{		
	__SQ_GETSINGLESAFEPTR(h, IO::Handle, typetag_FileHandle)
	int i = h->Read<int>();
	
	__SQ_RETURNINT(i)
}	
//------------------------------------------------------------------------------

//---------------------------------------------------
void				RegisterIOBinding(HSQUIRRELVM vm)
//---------------------------------------------------
{
	sq_register(vm, Include, "Include", _SC(".s"));
	sq_register(vm, Include, "Import", _SC(".s"));

/*#
	Topic: I/O
	Type: InputDevice
	Desc: Read inputs from devices connected to the host system.
#*/

/*#
	Section: FileManipulation
	Desc: File manipulation functions
#*//*#
		Func: FileRename
		Proto: int:string old,string new
		Desc: Rename a file.
	#*/
	sq_register(vm, FileRename, "FileRename", _SC(".ss"));
	/*#
		Func: FileDelete
		Proto: int:string filename
		Desc: delete a file.
	#*/
	sq_register(vm, FileDelete, "FileDelete", _SC(".s"));
	/*#
		Func: FolderExist
		Proto: bool:string filename
		Desc: check if a folder exist.
	#*/
	sq_register(vm, FolderExist, "FolderExist", _SC(".s"));
	/*#
		Func: FileCopy
		Proto: void:String src,string dst
		Desc: copy the file src in dst.
	#*/
	sq_register(vm, FileCopy, "FileCopy", _SC(".ss"));
	/*#
		Func: FileMove
		Proto: void:String src,string dst
		Desc: move the file src in dst.
	#*/
	sq_register(vm, FileMove, "FileMove", _SC(".ss"));
	/*#
		Func: FolderCreate
		Proto: int:string folder
		Desc: create a folder.
	#*/
	sq_register(vm, FolderCreate, "FolderCreate", _SC(".s"));
	/*#
		Func: FileExists
		Proto: bool:String name
		Desc: Returns true if the file 'name' can be accessed by the platform's file system.
	#*/
	sq_register(vm, FileExists, "FileExists", _SC(".s"));
	/*#
		Func: FileReadAsBlob
		Proto: Blob:String name
		Desc: Load a file as a Squirrel blob.
	#*/
	sq_register(vm, FileReadAsBlob, "FileReadAsBlob", _SC(".s"));
	/*#
		Func: FileWriteFromBlob
		Proto: void:String name,Blob
		Desc: Write a Squirrel blob to a file.
	#*/
	sq_register(vm, FileWriteFromBlob, "FileWriteFromBlob", _SC(".s."));
	/*#
		Func: FileWriteFromString
		Proto: void:String name,string
		Desc: Write a string to a file.
	#*/
	sq_register(vm, FileWriteFromString, "FileWriteFromString", _SC(".ss"));

	/*#
		Func: FileOpen
		Proto: void:String name,int mode
		Desc: open a file.
	#*/
	sq_register(vm, FileOpen, "FileOpen", _SC(".si"));
	/*#
		Func: FileClose
		Proto: void:File
		Desc: Close the  file.
	#*/
	sq_register(vm, FileClose, "FileClose", _SC(".x"));
	/*#
		Func: FileWriteFloat
		Proto: void:File, float
		Desc: write the float to the file.
	#*/
	sq_register(vm, FileWriteFloat, "FileWriteFloat", _SC(".xn"));
	/*#
		Func: FileReadFloat
		Proto: float:File
		Desc: read the float to the file.
	#*/
	sq_register(vm, FileReadFloat, "FileReadFloat", _SC(".x"));
	
	/*#
		Func: FileWriteInt
		Proto: void:File, int
		Desc: write the int to the file.
	#*/
	sq_register(vm, FileWriteInt, "FileWriteInt", _SC(".xi"));
	/*#
		Func: FileReadInt
		Proto: int:File
		Desc: read the int to the file.
	#*/
	sq_register(vm, FileReadInt, "FileReadInt", _SC(".x"));
	
/*#
	Section: InputDeviceQuery
	Desc: Input device query functions
#*/
	/*#
		Func: GetMouseDevice
		Proto: InputDevice:
		Desc: Get platform mouse device.
	#*/
	sq_register(vm, GetMouseDevice, "GetMouseDevice", _SC("."));
	/*#
		Func: GetKeyboardDevice
		Proto: InputDevice:
		Desc: Get platform keyboard device.
	#*/
	sq_register(vm, GetKeyboardDevice, "GetKeyboardDevice", _SC("."));
	/*#
		Func: GetInputDevice
		Proto: InputDevice:String name
		Desc: Get a platform device from its name.
	#*/
	sq_register(vm, GetInputDevice, "GetInputDevice", _SC(".s"));
	/*#
		Func: GetInputDeviceFromGuid
		Proto: InputDevice:String Guid
		Desc: Get a platform device from its Guid.
	#*/
	sq_register(vm, GetInputDeviceFromGuid, "GetInputDeviceFromGuid", _SC(".s"));
	/*#
		Func: GetDeviceList
		Proto: List:void
		Desc: Get a platform devices list.
		Example:
// Get the name of all devices connected to this machine.
local devices = GetDeviceList()

print("Available devices:")
foreach(device_name, i in devices)
	print("Device " + i + ": " + device_name)

// Create the first device from the list.
local device = GetInputDevice(devices[0])
	#*/
	sq_register(vm, GetDeviceList, "GetDeviceList", _SC("."));
	/*#
		Func: GetDeviceGuidList
		Proto: List:void
		Desc: Get a platform devices guid list.
		Example:
// Get the name of all devices connected to this machine.
local devices = GetDeviceGuidList()

print("Available devices:")
foreach(device_guid, i in devices)
	print("Device " + i + ": " + device_guid)

// Create the first device from the list.
local device = GetInputDevice(devices[0])
	#*/
	sq_register(vm, GetDeviceGuidList, "GetDeviceGuidList", _SC("."));
	/*#
		Func: DeviceSetEffect
		Proto: void:InputDevice device,DeviceEffect effect,float value
		Desc: Set device effect.
		Example:
// Retrieve the input device connected to XInput port 1.
local device = GetInputDevice("XInput1")

// Set full vibration on the left motor of the device.
DeviceSetEffect(device, DeviceEffectVibrateLeft, 1.0)
	#*/
	sq_register(vm, DeviceSetEffect, "DeviceSetEffect", _SC(".xin"));

/*#
	Section: InputDeviceState
	Desc: Input device state functions
#*/
	/*#
		Func: DeviceIsKeyDown
		Proto: bool:InputDevice,DeviceKey
		Desc: Returns true if the given device key is currently down, false otherwise.
		Note: The DeviceKey enumeration cannot be used to read analog inputs.<br>
              Only binary on/off inputs from the device are mapped to this enumeration.
		See: DeviceInputLastValue
	#*/
	sq_register(vm, DeviceIsKeyDown, "DeviceIsKeyDown", _SC(".xi"));
	/*#
		Func: DeviceWasKeyDown
		Proto: bool:InputDevice,DeviceKey
		Desc: Returns true if the given device key was down during the last device update, false otherwise.
	#*/
	sq_register(vm, DeviceWasKeyDown, "DeviceWasKeyDown", _SC(".xi"));
	/*#
		Func: DeviceKeyPressed
		Proto: bool:InputDevice,DeviceKey
		Desc: Returns true if the given device key was released during the current update, false otherwise.
	#*/
	sq_register(vm, DeviceKeyPressed, "DeviceKeyPressed", _SC(".xi"));
	/*#
		Func: DeviceInputSetValue
		Proto: bool:InputDevice,DeviceInput,float new_value
		Desc: Returns true if the device could set the value.
		Example:
// Get the mouse device.
local mouse_device = GetMouseDevice()

// Center the mouse cursor on screen.
DeviceInputSetValue(mouse_device, DeviceAxisX, 0.5)
DeviceInputSetValue(mouse_device, DeviceAxisY, 0.5)
	#*/
	sq_register(vm, DeviceInputSetValue, "DeviceInputSetValue", _SC(".xin"));
	/*#
		Func: DeviceInputValue
		Proto: float:InputDevice,DeviceInput
		Desc: Returns the current value of a device input.
	#*/
	sq_register(vm, DeviceInputValue, "DeviceInputValue", _SC(".xi"));
	/*#
		Func: DeviceInputLastValue
		Proto: float:InputDevice,DeviceInput
		Desc: Returns the value of a device input during the last update.
		Note: A DeviceInput can return a range of values and not only a simple on/off state value.<br>
		      In order to access binary on/off inputs please use the DeviceIsKeyDown function.
		See: DeviceIsKeyDown
	#*/
	sq_register(vm, DeviceInputLastValue, "DeviceInputLastValue", _SC(".xi"));

	/*#
	Func: BlobFromString
	Proto: Blob:String data
	Desc: Load data as a Squirrel blob.
	#*/
	sq_register(vm, BlobFromString, "BlobFromString", _SC(".s"));

	/*#
	Func: BlobFromStringBase64
	Proto: Blob:String base64 data
	Desc: Load data as a Squirrel blob.
	#*/
	sq_register(vm, BlobFromStringBase64, "BlobFromStringBase64", _SC(".s"));

	/*#
	Func: BlobToStringBase64
	Proto: String base64 data: Blob
	Desc: Load data as a Squirrel blob.
	#*/
	sq_register(vm, BlobToStringBase64, "BlobToStringBase64", _SC(".x"));

	// Defines.
	sq_pushroottable(vm);

	/*#
		Enum: DeviceType
		Values: DeviceTypeKeyboard,DeviceTypeMouse,DeviceTypeGame
	#*/
	sq_pushstring(vm, "DeviceTypeKeyboard", -1); sq_pushinteger(vm, Device::Type_Keyboard); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceTypeMouse", -1); sq_pushinteger(vm, Device::Type_Mouse); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceTypeGame", -1); sq_pushinteger(vm, Device::Type_Pad); sq_newslot(vm, -3, true);

	/*#
		Enum: DeviceEffect
		Values: DeviceEffectVibrate,DeviceEffectVibrateLeft,DeviceEffectVibrateRight,DeviceEffectConstantForce
	#*/
	sq_pushstring(vm, "DeviceEffectVibrate", -1); sq_pushinteger(vm, Device::Vibrate); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceEffectVibrateLeft", -1); sq_pushinteger(vm, Device::VibrateLeft); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceEffectVibrateRight", -1); sq_pushinteger(vm, Device::VibrateRight); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceEffectConstantForce", -1); sq_pushinteger(vm, Device::ConstantForce); sq_newslot(vm, -3, true);

	/*#
		Enum: DeviceInput
		Values: DeviceAxisX,DeviceAxisY,DeviceAxisZ,DeviceAxisS,DeviceAxisT,DeviceAxisR,DeviceAxisRotX,DeviceAxisRotY,DeviceAxisRotZ,DeviceAxisRotS,DeviceAxisRotT,DeviceAxisRotR,
				DeviceButton0,DeviceButton1,DeviceButton2,DeviceButton3,DeviceButton4,DeviceButton5,DeviceButton6,DeviceButton7,DeviceButton8,
				DeviceButton9,DeviceButton10,DeviceButton11,DeviceButton12,DeviceButton13,DeviceButton14,DeviceButton15
		Desc: Device inputs can take a large range of values, they offer more precision than the simpler on/off device keys.
	#*/
	sq_pushstring(vm, "DeviceAxisX", -1); sq_pushinteger(vm, Device::Input_AxisX); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisY", -1); sq_pushinteger(vm, Device::Input_AxisY); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisZ", -1); sq_pushinteger(vm, Device::Input_AxisZ); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisS", -1); sq_pushinteger(vm, Device::Input_AxisS); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisT", -1); sq_pushinteger(vm, Device::Input_AxisT); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisR", -1); sq_pushinteger(vm, Device::Input_AxisR); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisRotX", -1); sq_pushinteger(vm, Device::Input_RotX); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisRotY", -1); sq_pushinteger(vm, Device::Input_RotY); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisRotZ", -1); sq_pushinteger(vm, Device::Input_RotZ); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisRotS", -1); sq_pushinteger(vm, Device::Input_RotS); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisRotT", -1); sq_pushinteger(vm, Device::Input_RotT); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceAxisRotR", -1); sq_pushinteger(vm, Device::Input_RotR); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "DeviceButton0", -1); sq_pushinteger(vm, Device::Input_Button0); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton1", -1); sq_pushinteger(vm, Device::Input_Button1); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton2", -1); sq_pushinteger(vm, Device::Input_Button2); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton3", -1); sq_pushinteger(vm, Device::Input_Button3); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton4", -1); sq_pushinteger(vm, Device::Input_Button4); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton5", -1); sq_pushinteger(vm, Device::Input_Button5); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton6", -1); sq_pushinteger(vm, Device::Input_Button6); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton7", -1); sq_pushinteger(vm, Device::Input_Button7); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton8", -1); sq_pushinteger(vm, Device::Input_Button8); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton9", -1); sq_pushinteger(vm, Device::Input_Button9); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton10", -1); sq_pushinteger(vm, Device::Input_Button10); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton11", -1); sq_pushinteger(vm, Device::Input_Button11); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton12", -1); sq_pushinteger(vm, Device::Input_Button12); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton13", -1); sq_pushinteger(vm, Device::Input_Button13); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton14", -1); sq_pushinteger(vm, Device::Input_Button14); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "DeviceButton15", -1); sq_pushinteger(vm, Device::Input_Button15); sq_newslot(vm, -3, true);

	/*#
		Enum: DeviceKey
		Values:	KeyLShift,KeyRShift,KeyLCtrl,KeyRCtrl,KeyLAlt,KeyRAlt,KeyLWin,KeyRWin,
				KeyTab,KeyCapsLock,KeySpace,KeyBackspace,KeyReturn,KeyInsert,KeySuppr,KeyHome,KeyEnd,KeyPageUp,KeyPageDown,
				KeyUpArrow,KeyDownArrow,KeyLeftArrow,KeyRightArrow,
				KeyEscape,
				KeyF1,KeyF2,KeyF3,KeyF4,KeyF5,KeyF6,KeyF7,KeyF8,KeyF9,KeyF10,KeyF11,KeyF12,
				KeyPrintScreen,KeyScrollLock,KeyPause,KeyNumLock,KeyReturn,
				KeyNumpad0,KeyNumpad1,KeyNumpad2,KeyNumpad3,KeyNumpad4,KeyNumpad5,KeyNumpad6,KeyNumpad7,KeyNumpad8,KeyNumpad9,
				KeyAdd,KeySub,KeyMul,KeyDiv,KeyEnter,
				KeyA,KeyB,KeyC,KeyD,KeyE,KeyF,KeyG,KeyH,KeyI,KeyJ,KeyK,KeyL,KeyM,KeyN,KeyO,KeyP,KeyQ,KeyR,KeyS,KeyT,KeyU,KeyV,KeyW,KeyX,KeyY,KeyZ,
				KeyButton0,KeyButton1,KeyButton2,KeyButton3,KeyButton4,KeyButton5,KeyButton6,KeyButton7,KeyButton8,KeyButton9,
				KeyButton10,KeyButton11,KeyButton12,KeyButton13,KeyButton14,KeyButton15,KeyButton16,KeyButton17,KeyButton18,KeyButton19,
				KeyButton20,KeyButton21,KeyButton22,KeyButton23,KeyButton24,KeyButton25,KeyButton26,KeyButton27,KeyButton28,KeyButton29,
				KeyButton30,
				KeyCrossUp,KeyCrossDown,KeyCrossLeft,KeyCrossRight,
				KeyBack,KeyStart,KeySelect,KeyL1,KeyL2,KeyL3,KeyR1,KeyR2,KeyR3
		Desc: Device keys are binary values, a device key can only be pressed or released at any given time.
	#*/
	sq_pushstring(vm, "KeyLShift", -1); sq_pushinteger(vm, Device::Key_LShift); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyRShift", -1); sq_pushinteger(vm, Device::Key_RShift); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyLCtrl", -1); sq_pushinteger(vm, Device::Key_LCtrl); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyRCtrl", -1); sq_pushinteger(vm, Device::Key_RCtrl); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyLAlt", -1); sq_pushinteger(vm, Device::Key_LAlt); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyRAlt", -1); sq_pushinteger(vm, Device::Key_RAlt); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyLWin", -1); sq_pushinteger(vm, Device::Key_LWin); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyRWin", -1); sq_pushinteger(vm, Device::Key_RWin); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyTab", -1); sq_pushinteger(vm, Device::Key_Tab); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyCapsLock", -1); sq_pushinteger(vm, Device::Key_CapsLock); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeySpace", -1); sq_pushinteger(vm, Device::Key_Space); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyBackspace", -1); sq_pushinteger(vm, Device::Key_Backspace); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyReturn", -1); sq_pushinteger(vm, Device::Key_Return); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyAdd", -1); sq_pushinteger(vm, Device::Key_Add); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeySub", -1); sq_pushinteger(vm, Device::Key_Sub); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyMul", -1); sq_pushinteger(vm, Device::Key_Mul); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyDiv", -1); sq_pushinteger(vm, Device::Key_Div); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyEnter", -1); sq_pushinteger(vm, Device::Key_Enter); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyInsert", -1); sq_pushinteger(vm, Device::Key_Insert); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeySuppr", -1); sq_pushinteger(vm, Device::Key_Suppr); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyHome", -1); sq_pushinteger(vm, Device::Key_Home); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyEnd", -1); sq_pushinteger(vm, Device::Key_End); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyPageUp", -1); sq_pushinteger(vm, Device::Key_PageUp); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyPageDown", -1); sq_pushinteger(vm, Device::Key_PageDown); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyUpArrow", -1); sq_pushinteger(vm, Device::Key_Up); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyDownArrow", -1); sq_pushinteger(vm, Device::Key_Down); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyLeftArrow", -1); sq_pushinteger(vm, Device::Key_Left); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyRightArrow", -1); sq_pushinteger(vm, Device::Key_Right); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyEscape", -1); sq_pushinteger(vm, Device::Key_Escape); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF1", -1); sq_pushinteger(vm, Device::Key_F1); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF2", -1); sq_pushinteger(vm, Device::Key_F2); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF3", -1); sq_pushinteger(vm, Device::Key_F3); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF4", -1); sq_pushinteger(vm, Device::Key_F4); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF5", -1); sq_pushinteger(vm, Device::Key_F5); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF6", -1); sq_pushinteger(vm, Device::Key_F6); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF7", -1); sq_pushinteger(vm, Device::Key_F7); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF8", -1); sq_pushinteger(vm, Device::Key_F8); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF9", -1); sq_pushinteger(vm, Device::Key_F9); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF10", -1); sq_pushinteger(vm, Device::Key_F10); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF11", -1); sq_pushinteger(vm, Device::Key_F11); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF12", -1); sq_pushinteger(vm, Device::Key_F12); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyPrintScreen", -1); sq_pushinteger(vm, Device::Key_PrintScreen); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyScrollLock", -1); sq_pushinteger(vm, Device::Key_ScrollLock); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyPause", -1); sq_pushinteger(vm, Device::Key_Pause); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyNumLock", -1); sq_pushinteger(vm, Device::Key_NumLock); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyEnter", -1); sq_pushinteger(vm, Device::Key_Enter); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyNumpad0", -1); sq_pushinteger(vm, Device::Key_Numpad0); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad1", -1); sq_pushinteger(vm, Device::Key_Numpad1); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad2", -1); sq_pushinteger(vm, Device::Key_Numpad2); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad3", -1); sq_pushinteger(vm, Device::Key_Numpad3); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad4", -1); sq_pushinteger(vm, Device::Key_Numpad4); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad5", -1); sq_pushinteger(vm, Device::Key_Numpad5); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad6", -1); sq_pushinteger(vm, Device::Key_Numpad6); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad7", -1); sq_pushinteger(vm, Device::Key_Numpad7); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad8", -1); sq_pushinteger(vm, Device::Key_Numpad8); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyNumpad9", -1); sq_pushinteger(vm, Device::Key_Numpad9); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyA", -1); sq_pushinteger(vm, Device::Key_A); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyB", -1); sq_pushinteger(vm, Device::Key_B); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyC", -1); sq_pushinteger(vm, Device::Key_C); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyD", -1); sq_pushinteger(vm, Device::Key_D); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyE", -1); sq_pushinteger(vm, Device::Key_E); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyF", -1); sq_pushinteger(vm, Device::Key_F); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyG", -1); sq_pushinteger(vm, Device::Key_G); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyH", -1); sq_pushinteger(vm, Device::Key_H); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyI", -1); sq_pushinteger(vm, Device::Key_I); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyJ", -1); sq_pushinteger(vm, Device::Key_J); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyK", -1); sq_pushinteger(vm, Device::Key_K); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyL", -1); sq_pushinteger(vm, Device::Key_L); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyM", -1); sq_pushinteger(vm, Device::Key_M); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyN", -1); sq_pushinteger(vm, Device::Key_N); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyO", -1); sq_pushinteger(vm, Device::Key_O); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyP", -1); sq_pushinteger(vm, Device::Key_P); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyQ", -1); sq_pushinteger(vm, Device::Key_Q); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyR", -1); sq_pushinteger(vm, Device::Key_R); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyS", -1); sq_pushinteger(vm, Device::Key_S); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyT", -1); sq_pushinteger(vm, Device::Key_T); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyU", -1); sq_pushinteger(vm, Device::Key_U); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyV", -1); sq_pushinteger(vm, Device::Key_V); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyW", -1); sq_pushinteger(vm, Device::Key_W); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyX", -1); sq_pushinteger(vm, Device::Key_X); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyY", -1); sq_pushinteger(vm, Device::Key_Y); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyZ", -1); sq_pushinteger(vm, Device::Key_Z); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyButton0", -1); sq_pushinteger(vm, Device::Key_Button0); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton1", -1); sq_pushinteger(vm, Device::Key_Button1); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton2", -1); sq_pushinteger(vm, Device::Key_Button2); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton3", -1); sq_pushinteger(vm, Device::Key_Button3); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton4", -1); sq_pushinteger(vm, Device::Key_Button4); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton5", -1); sq_pushinteger(vm, Device::Key_Button5); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton6", -1); sq_pushinteger(vm, Device::Key_Button6); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton7", -1); sq_pushinteger(vm, Device::Key_Button7); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton8", -1); sq_pushinteger(vm, Device::Key_Button8); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton9", -1); sq_pushinteger(vm, Device::Key_Button9); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton10", -1); sq_pushinteger(vm, Device::Key_Button10); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton11", -1); sq_pushinteger(vm, Device::Key_Button11); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton12", -1); sq_pushinteger(vm, Device::Key_Button12); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton13", -1); sq_pushinteger(vm, Device::Key_Button13); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton14", -1); sq_pushinteger(vm, Device::Key_Button14); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton15", -1); sq_pushinteger(vm, Device::Key_Button15); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton16", -1); sq_pushinteger(vm, Device::Key_Button16); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton17", -1); sq_pushinteger(vm, Device::Key_Button17); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton18", -1); sq_pushinteger(vm, Device::Key_Button18); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton19", -1); sq_pushinteger(vm, Device::Key_Button19); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton20", -1); sq_pushinteger(vm, Device::Key_Button20); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton21", -1); sq_pushinteger(vm, Device::Key_Button21); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton22", -1); sq_pushinteger(vm, Device::Key_Button22); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton23", -1); sq_pushinteger(vm, Device::Key_Button23); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton24", -1); sq_pushinteger(vm, Device::Key_Button24); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton25", -1); sq_pushinteger(vm, Device::Key_Button25); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton26", -1); sq_pushinteger(vm, Device::Key_Button26); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton27", -1); sq_pushinteger(vm, Device::Key_Button27); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton28", -1); sq_pushinteger(vm, Device::Key_Button28); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton29", -1); sq_pushinteger(vm, Device::Key_Button29); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton30", -1); sq_pushinteger(vm, Device::Key_Button30); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton31", -1); sq_pushinteger(vm, Device::Key_Button31); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton32", -1); sq_pushinteger(vm, Device::Key_Button32); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton33", -1); sq_pushinteger(vm, Device::Key_Button33); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton34", -1); sq_pushinteger(vm, Device::Key_Button34); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton35", -1); sq_pushinteger(vm, Device::Key_Button35); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton36", -1); sq_pushinteger(vm, Device::Key_Button36); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton37", -1); sq_pushinteger(vm, Device::Key_Button37); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton38", -1); sq_pushinteger(vm, Device::Key_Button38); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton39", -1); sq_pushinteger(vm, Device::Key_Button39); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton40", -1); sq_pushinteger(vm, Device::Key_Button40); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton41", -1); sq_pushinteger(vm, Device::Key_Button41); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton42", -1); sq_pushinteger(vm, Device::Key_Button42); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton43", -1); sq_pushinteger(vm, Device::Key_Button43); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton44", -1); sq_pushinteger(vm, Device::Key_Button44); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton45", -1); sq_pushinteger(vm, Device::Key_Button45); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton46", -1); sq_pushinteger(vm, Device::Key_Button46); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton47", -1); sq_pushinteger(vm, Device::Key_Button47); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton48", -1); sq_pushinteger(vm, Device::Key_Button48); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton49", -1); sq_pushinteger(vm, Device::Key_Button49); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton50", -1); sq_pushinteger(vm, Device::Key_Button50); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton51", -1); sq_pushinteger(vm, Device::Key_Button51); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton52", -1); sq_pushinteger(vm, Device::Key_Button52); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton53", -1); sq_pushinteger(vm, Device::Key_Button53); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton54", -1); sq_pushinteger(vm, Device::Key_Button54); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton55", -1); sq_pushinteger(vm, Device::Key_Button55); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton56", -1); sq_pushinteger(vm, Device::Key_Button56); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton57", -1); sq_pushinteger(vm, Device::Key_Button57); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton58", -1); sq_pushinteger(vm, Device::Key_Button58); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton59", -1); sq_pushinteger(vm, Device::Key_Button59); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton60", -1); sq_pushinteger(vm, Device::Key_Button60); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton61", -1); sq_pushinteger(vm, Device::Key_Button61); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton62", -1); sq_pushinteger(vm, Device::Key_Button62); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton63", -1); sq_pushinteger(vm, Device::Key_Button63); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton64", -1); sq_pushinteger(vm, Device::Key_Button64); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton65", -1); sq_pushinteger(vm, Device::Key_Button65); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton66", -1); sq_pushinteger(vm, Device::Key_Button66); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton67", -1); sq_pushinteger(vm, Device::Key_Button67); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton68", -1); sq_pushinteger(vm, Device::Key_Button68); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton69", -1); sq_pushinteger(vm, Device::Key_Button69); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton70", -1); sq_pushinteger(vm, Device::Key_Button70); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton71", -1); sq_pushinteger(vm, Device::Key_Button71); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton72", -1); sq_pushinteger(vm, Device::Key_Button72); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton73", -1); sq_pushinteger(vm, Device::Key_Button73); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton74", -1); sq_pushinteger(vm, Device::Key_Button74); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton75", -1); sq_pushinteger(vm, Device::Key_Button75); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton76", -1); sq_pushinteger(vm, Device::Key_Button76); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton77", -1); sq_pushinteger(vm, Device::Key_Button77); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton78", -1); sq_pushinteger(vm, Device::Key_Button78); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton79", -1); sq_pushinteger(vm, Device::Key_Button79); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton80", -1); sq_pushinteger(vm, Device::Key_Button80); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton81", -1); sq_pushinteger(vm, Device::Key_Button81); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton82", -1); sq_pushinteger(vm, Device::Key_Button82); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton83", -1); sq_pushinteger(vm, Device::Key_Button83); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton84", -1); sq_pushinteger(vm, Device::Key_Button84); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton85", -1); sq_pushinteger(vm, Device::Key_Button85); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton86", -1); sq_pushinteger(vm, Device::Key_Button86); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton87", -1); sq_pushinteger(vm, Device::Key_Button87); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton88", -1); sq_pushinteger(vm, Device::Key_Button88); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton89", -1); sq_pushinteger(vm, Device::Key_Button89); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton90", -1); sq_pushinteger(vm, Device::Key_Button90); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton91", -1); sq_pushinteger(vm, Device::Key_Button91); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton92", -1); sq_pushinteger(vm, Device::Key_Button92); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton93", -1); sq_pushinteger(vm, Device::Key_Button93); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton94", -1); sq_pushinteger(vm, Device::Key_Button94); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton95", -1); sq_pushinteger(vm, Device::Key_Button95); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton96", -1); sq_pushinteger(vm, Device::Key_Button96); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton97", -1); sq_pushinteger(vm, Device::Key_Button97); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton98", -1); sq_pushinteger(vm, Device::Key_Button98); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton99", -1); sq_pushinteger(vm, Device::Key_Button99); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton100", -1); sq_pushinteger(vm, Device::Key_Button100); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton101", -1); sq_pushinteger(vm, Device::Key_Button101); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton102", -1); sq_pushinteger(vm, Device::Key_Button102); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton103", -1); sq_pushinteger(vm, Device::Key_Button103); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton104", -1); sq_pushinteger(vm, Device::Key_Button104); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton105", -1); sq_pushinteger(vm, Device::Key_Button105); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton106", -1); sq_pushinteger(vm, Device::Key_Button106); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton107", -1); sq_pushinteger(vm, Device::Key_Button107); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton108", -1); sq_pushinteger(vm, Device::Key_Button108); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton109", -1); sq_pushinteger(vm, Device::Key_Button109); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton110", -1); sq_pushinteger(vm, Device::Key_Button110); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton111", -1); sq_pushinteger(vm, Device::Key_Button111); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton112", -1); sq_pushinteger(vm, Device::Key_Button112); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton113", -1); sq_pushinteger(vm, Device::Key_Button113); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton114", -1); sq_pushinteger(vm, Device::Key_Button114); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton115", -1); sq_pushinteger(vm, Device::Key_Button115); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton116", -1); sq_pushinteger(vm, Device::Key_Button116); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton117", -1); sq_pushinteger(vm, Device::Key_Button117); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton118", -1); sq_pushinteger(vm, Device::Key_Button118); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton119", -1); sq_pushinteger(vm, Device::Key_Button119); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton120", -1); sq_pushinteger(vm, Device::Key_Button120); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton121", -1); sq_pushinteger(vm, Device::Key_Button121); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton122", -1); sq_pushinteger(vm, Device::Key_Button122); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton123", -1); sq_pushinteger(vm, Device::Key_Button123); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton124", -1); sq_pushinteger(vm, Device::Key_Button124); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton125", -1); sq_pushinteger(vm, Device::Key_Button125); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton126", -1); sq_pushinteger(vm, Device::Key_Button126); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyButton127", -1); sq_pushinteger(vm, Device::Key_Button127); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyCrossUp", -1);	sq_pushinteger(vm, Device::Key_Cross_Up); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyCrossDown", -1);	sq_pushinteger(vm, Device::Key_Cross_Down); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyCrossLeft", -1);	sq_pushinteger(vm, Device::Key_Cross_Left); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyCrossRight", -1);	sq_pushinteger(vm, Device::Key_Cross_Right); sq_newslot(vm, -3, true);

	sq_pushstring(vm, "KeyBack", -1); sq_pushinteger(vm, Device::Key_Back); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyStart", -1); sq_pushinteger(vm, Device::Key_Start); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeySelect", -1); sq_pushinteger(vm, Device::Key_Select); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyL1", -1); sq_pushinteger(vm, Device::Key_L1); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyL2", -1); sq_pushinteger(vm, Device::Key_L2); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyL3", -1); sq_pushinteger(vm, Device::Key_L3); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyR1", -1); sq_pushinteger(vm, Device::Key_R1); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyR2", -1); sq_pushinteger(vm, Device::Key_R2); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "KeyR3", -1); sq_pushinteger(vm, Device::Key_R3); sq_newslot(vm, -3, true);
	
	sq_pushstring(vm, "ModeRead", -1); sq_pushinteger(vm, GS::IO::ModeRead); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "ModeWrite", -1); sq_pushinteger(vm, GS::IO::ModeWrite); sq_newslot(vm, -3, true);

	sq_pop(vm, 1);
}
