//
// WIImote CONTROL 
// Bastien BOURINEAU
//


#include <scol.h>
#include <wiimote.h>
#include <wiimote_state.h>
#include <stdio.h>


cbmachine	ww;
mmachine	mm;

HWND HScol = NULL;

//#define _SCOL_DEBUG_


// OBJWII Scol
int OBJWIISCOL;

// CALLBACK
int SCOL_WIIMOTE_IR_CB = 0;
int SCOL_WIIMOTE_BUTTON_CB = 1;
int SCOL_WIIMOTE_ACCEL_CB = 2;
int SCOL_WIIMOTE_CONNECTION_LOST_CB = 3;

int SCOL_NUNCHUK_BUTTON_CB = 4;
int SCOL_NUNCHUK_ACCEL_CB = 5;
int SCOL_NUNCHUK_JOY_CB = 6;

int SCOL_BALANCE_BOARD_CB = 7;

//TODO send flag of extension type
int SCOL_EXTENSION_DISCONNECTED_CB = 8;
int SCOL_EXTENSION_CONNECTED_CB = 9;  

//TODO motion plus

int WIIMOTE_IR_CB;
int WIIMOTE_BUTTON_CB;
int WIIMOTE_ACCEL_CB;
int WIIMOTE_CONNECTION_LOST_CB;

int NUNCHUK_BUTTON_CB;
int NUNCHUK_ACCEL_CB;
int NUNCHUK_JOY_CB;

int BALANCE_BOARD_CB;

int EXTENSION_DISCONNECTED_CB;
int EXTENSION_CONNECTED_CB;

//TODO last extension type for type in disconnected
//TODO classic controler in callbacks
//TODO motion plus

int extensionTypeToSimpleType(wiimote *remote)
{
	if (remote->ExtensionType == 0)
		return 0;
	
	if (remote->ExtensionType == wiimote::extension_type::NUNCHUK)
		return 1;

	if (remote->ExtensionType == wiimote::extension_type::CLASSIC)
		return 2;

	if (remote->ExtensionType == wiimote::extension_type::MOTION_PLUS)
		return 3;

	if (remote->ExtensionType == wiimote::extension_type::BALANCE_BOARD)
		return 4;

	if (remote->ExtensionType == wiimote::extension_type::GH3_GHWT_GUITAR)
		return 5;

	if (remote->ExtensionType == wiimote::extension_type::GHWT_DRUMS)
		return 6;

	if (remote->ExtensionType == wiimote::extension_type::PARTIALLY_INSERTED)
		return -1;

	return -1;
}


//TODO see all flags in wiimote_state.h
void on_state_change (wiimote &remote, state_change_flags  changed, const wiimote_state &new_state)
	{
   	//$BB need to refresh since v1.15b_RC3
		remote.RefreshState();

		if(changed & CONNECTED)
		{
			// ask the wiimote to report everything (using the 'non-continous updates'
			//  default mode - updates will be frequent anyway due to the acceleration/IR
			//  values changing):

			// note1: you don't need to set a report type for Balance Boards - the
			//		   library does it automatically.
			
			// note2: for wiimotes, the report mode that includes the extension data
			//		   unfortunately only reports the 'BASIC' IR info (ie. no dot sizes),
			//		   so let's choose the best mode based on the extension status:
			if(new_state.ExtensionType != wiimote::BALANCE_BOARD)
				{
				if(new_state.bExtension)
					remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR_EXT); // no IR dots
				else
					remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR);		//    IR dots
				}
		}

		// a MotionPlus was detected
		if(changed & MOTIONPLUS_DETECTED)
		{
			// enable it if there isn't a normal extension plugged into it
			// (MotionPlus devices don't report like normal extensions until
			//  enabled - and then, other extensions attached to it will no longer be
			//  reported (so disable it when you want to access to those again).
			if(remote.ExtensionType == wiimote_state::NONE) {
				bool res = remote.EnableMotionPlus();
				_ASSERT(res);
				}
			MMechostr(0,"Wiimote Extension connected > Motion plus\n");
		}
		if(changed & MOTIONPLUS_EXTENSION_CONNECTED)
		{
			// an extension is connected to the MotionPlus.  We can't read it if the
			//  MotionPlus is currently enabled, so disable it:
			if(remote.MotionPlusEnabled())
				remote.DisableMotionPlus();
			MMechostr(0,"Wiimote Motion plus Extension connected\n");
		}
		if(changed & MOTIONPLUS_EXTENSION_DISCONNECTED)
		{
			// the extension plugged into the MotionPlus was removed, so enable
			//  the MotionPlus data again:
			if(remote.MotionPlusConnected())
				remote.EnableMotionPlus();
			MMechostr(0,"Wiimote Motion plus Extension disconnected\n");
		}
		// extension was just connected:
		if(changed & EXTENSION_CONNECTED)
		{
			// switch to a report mode that includes the extension data (we will
			//  loose the IR dot sizes)
			// note: there is no need to set report types for a Balance Board.
				if(!remote.IsBalanceBoard()){
					remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR_EXT);
					PostMessage( HScol, EXTENSION_CONNECTED_CB, (int)&remote,(LPARAM)NULL);
				}
		}
		// extension was just disconnected:
		if(changed & EXTENSION_DISCONNECTED)
		{
			// use a non-extension report mode (this gives us back the IR dot sizes)
			remote.SetReportType(wiimote::IN_BUTTONS_ACCEL_IR);
			PostMessage( HScol, EXTENSION_DISCONNECTED_CB, (int)&remote,(LPARAM)NULL);
		}
		// wiimote connection lost
		if(changed & CONNECTION_LOST)
		{
			PostMessage( HScol, WIIMOTE_CONNECTION_LOST_CB, (int)&remote,(LPARAM)NULL);
		}

		// ir data change
		if(changed & IR_CHANGED)
		{
			PostMessage( HScol, WIIMOTE_IR_CB, (int)&remote,(LPARAM)NULL);
		}
		// wiimote button change 
		if(changed & BUTTONS_CHANGED)
		{
			PostMessage( HScol, WIIMOTE_BUTTON_CB, (int)&remote,(LPARAM)NULL);
		}
		// wiimote accel change 
		if(changed & ACCEL_CHANGED || changed & ORIENTATION_CHANGED)
		{
			PostMessage( HScol, WIIMOTE_ACCEL_CB, (int)&remote,(LPARAM)NULL);
		}
		// nunchuck button
		if(changed & NUNCHUK_BUTTONS_CHANGED)
		{
			PostMessage( HScol, NUNCHUK_BUTTON_CB, (int)&remote,(LPARAM)NULL);
		}
		// nunchuck accel
		if(changed & NUNCHUK_ACCEL_CHANGED || changed & NUNCHUK_ORIENTATION_CHANGED)
		{
			PostMessage( HScol, NUNCHUK_ACCEL_CB, (int)&remote,(LPARAM)NULL);
		}
		// nunchuck joy
		if(changed & NUNCHUK_JOYSTICK_CHANGED)
		{
			PostMessage( HScol, NUNCHUK_JOY_CB, (int)&remote,(LPARAM)NULL);
		}
		// board data change
		if(changed & BALANCE_WEIGHT_CHANGED)
		{
			PostMessage( HScol, BALANCE_BOARD_CB, (int)&remote,(LPARAM)NULL);	
		}
	}

int destroyWiiObj(mmachine m,int handsys,int wii)
{
	wiimote* WiiMoteOBJ = (wiimote*) MMfetch(m, MTOP(wii), 0);
	if( !WiiMoteOBJ ) { MMset(m,0,NIL); return 0; }

	WiiMoteOBJ->SetRumble(false);
	WiiMoteOBJ->SetLEDs(false,false,false,false);

	SAFE_DELETE( WiiMoteOBJ );
	MMstore( m, MTOP(wii), 0, (int)NULL );
	MMechostr(MSKDEBUG,"WiiObj destroyed.\n");

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		_OpenWiiDevice
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[Chn I] WiiObj
int _ZOpenWIIdevice(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_OpenWiiDevice\n");
#endif
	
	int remoteId;

    /* test le channel */
    if (MMget(m,1)==NIL)
    {
        MMechostr(MSKDEBUG,"_OpenWiiDevice : channel NIL\n");
        m->pp+=1;
        return 0;
    }

	if ((remoteId = MTOI(MMpull(m))) == NIL)
		remoteId = wiimote::FIRST_AVAILABLE;
	
	MMechostr(MSKDEBUG,"_OpenWiiDevice new wiimote\n");
	wiimote* WiiMoteOBJ = new wiimote();
	
	// simple callback example (we use polling for almost everything here):
	//  notify us when something related to the extension changes
	MMechostr(MSKDEBUG,"_OpenWiiDevice set callback\n");
	WiiMoteOBJ->ChangedCallback = on_state_change;

	//  avoid unwanted callback overhead by requesting only extension-related data
	MMechostr(MSKDEBUG,"_OpenWiiDevice set cb flags\n");
	WiiMoteOBJ->CallbackTriggerFlags = (state_change_flags)( CHANGED_ALL );

	// connect wiimote
	MMechostr(MSKDEBUG,"_OpenWiiDevice trying to connect\n");
	if (!WiiMoteOBJ->Connect(remoteId))
	{
		MMechostr(MSKDEBUG,"_OpenWiiDevice connexion failed\n");
		SAFE_DELETE( WiiMoteOBJ ); 
		MMechostr(MSKDEBUG,"_OpenWiiDevice connexion failed obj deleted\n");
		MMpull(m); /* depile le channel */
        return MMpush(m,NIL);
	}

	// if (!(WiiMoteOBJ->ExtensionType & wiimote_state::BALANCE_BOARD))
	if(!WiiMoteOBJ->IsBalanceBoard())
	{
		WiiMoteOBJ->Nunchuk.Joystick.DeadZone.X = 0.05f;
		WiiMoteOBJ->Nunchuk.Joystick.DeadZone.Y = 0.05f;
	
		WiiMoteOBJ->ClassicController.JoystickL.DeadZone.X = 0.05f;
		WiiMoteOBJ->ClassicController.JoystickL.DeadZone.Y = 0.05f;
		WiiMoteOBJ->ClassicController.JoystickR.DeadZone.X = 0.05f;
		WiiMoteOBJ->ClassicController.JoystickR.DeadZone.Y = 0.05f;	
		
	
		if(WiiMoteOBJ->bExtension)
			WiiMoteOBJ->SetReportType(wiimote::IN_BUTTONS_ACCEL_IR_EXT); // no IR dots
		else
			WiiMoteOBJ->SetReportType(wiimote::IN_BUTTONS_ACCEL_IR);	 //    IR dots
	}
	else
		WiiMoteOBJ->CalibrateAtRest();
	
	int wii = MMmalloc(m,1,TYPETAB);
	if ( wii == NIL ) {
		MMechostr(MSKDEBUG,"_OpenWiiDevice MMmalloc failed\n");
		SAFE_DELETE( WiiMoteOBJ ); 
		MMechostr(MSKDEBUG,"_OpenWiiDevice MMmalloc obj deleted\n");
		MMpull(m); /* depile le channel */
        return MMpush(m,NIL);
	}
	
	MMechostr(MSKDEBUG,"_OpenWiiDevice MMstore tab\n");
	MMstore( m, wii, 0, (int)WiiMoteOBJ );
	
	MMechostr(MSKDEBUG,"_OpenWiiDevice MMpush obj ptr\n");
	MMpush(m, PTOM( wii ));
	

#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif
	return OBJcreate(m, OBJWIISCOL, (int)WiiMoteOBJ, -1, -1);

}

//fun to get motion plus data


//////////////////////////////////////////////////////////////////////////////////////////////
///		_CloseWiiDevice
//////////////////////////////////////////////////////////////////////////////////////////////

// fun[WiiObj] I
int _ZCloseWIIdevice(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_CloseWiiDevice\n");
#endif
	
	int wii = MTOP( MMget(m,0) );
	if ( wii == NIL ) { MMset(m,0,NIL); return 0; }
	
	OBJdelTM( m, OBJWIISCOL, PTOM(wii) );
	MMset(m,0,0);	

#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif

	return 0;
}




//////////////////////////////////////////////////////////////////////////////////////////////
///		_GetWiiExtensionType
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[WiiObj I] I
int _ZGetWiiExtensionType(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_GetWiiExtensionType\n");
#endif

	int wii = MTOP( MMget(m,0) );
	if ( wii == NIL ) { MMset(m,0,NIL); return 0; }

	wiimote* WiiMoteOBJ = (wiimote*)MMfetch(m, wii, 0);
	if( !WiiMoteOBJ ) { MMset(m,0,NIL); return 0; }

	MMset(m,0,ITOM(extensionTypeToSimpleType(WiiMoteOBJ)));

#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		_SetWiiLeds
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[WiiObj I I I I] I
int _ZSetWIIleds(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_SetWiiLeds\n");
#endif

	bool led1, led2, led3, led4;
	int  scled1, scled2, scled3, scled4;

	scled1 = MTOI (MMpull(m));
	scled2 = MTOI (MMpull(m));
	scled3 = MTOI (MMpull(m));
	scled4 = MTOI (MMpull(m));

	int wii = MTOP( MMget(m,0) );
	if ( wii == NIL ) { MMset(m,0,NIL); return 0; }

	wiimote* WiiMoteOBJ = (wiimote*)MMfetch(m, wii, 0);
	if( !WiiMoteOBJ ) { MMset(m,0,NIL); return 0; }

	if (scled1 == 1){
		led1 = true;
	}
	else{
		led1 = false;
	}

	if (scled2 == 1){
		led2 = true;
	}
	else{
		led2 = false;
	}

	if (scled3 == 1){
		led3 = true;
	}
	else{
		led3 = false;
	}

	if (scled4 == 1){
		led4 = true;
	}
	else{
		led4 = false;
	}
	
	WiiMoteOBJ->SetLEDs(led1, led2, led3, led4);

	MMset(m,0,0);
	

#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		_SetWiiVibrate
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[WiiObj I] I
int _ZSetWIIvibrate(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_SetWiiVibrate\n");
#endif

	bool vibrate;
	int scVibrate;

	
	scVibrate = MTOI (MMpull(m));

	int wii = MTOP( MMget(m,0) );
	if ( wii == NIL ) { MMset(m,0,NIL); return 0; }

	wiimote* WiiMoteOBJ = (wiimote*)MMfetch(m, wii, 0);
	if( !WiiMoteOBJ ) { MMset(m,0,NIL); return 0; }

	
	if (scVibrate == 1)
	{
		vibrate = true;
	}
	else
	{
		vibrate = false;
	}

	WiiMoteOBJ->SetRumble(vibrate);

	MMset(m,0,0);
	

#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///		_GetWiiClassicInfos
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[WiiObj] [[F F F] [F F F] [I I] [F F] I]
int _ZGetWIIClassicInfos(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_GetWiiClassicInfos\n");
#endif

	float tL,tR;
	float rX,rY;
	float lX,lY;
	
	tL = tR = rX = rY = lX = lY =0.f;

	int wii = MTOP( MMget(m,0) );
	if ( wii == NIL ) { MMset(m,0,NIL); return 0; }

	wiimote* WiiMoteOBJ = (wiimote*)MMfetch(m, wii, 0);
	if( !WiiMoteOBJ ) { MMset(m,0,NIL); return 0; }

	if (!(WiiMoteOBJ->ExtensionType & wiimote_state::CLASSIC))
	{
		MMechostr(MSKDEBUG,"_ZGetWIIClassicInfos Classic controller is not connected\n");
		MMset(m,0,NIL); return 0;
	}
	
	lX = WiiMoteOBJ->ClassicController.JoystickL.X;
	lY = WiiMoteOBJ->ClassicController.JoystickL.Y;
	
	rX = WiiMoteOBJ->ClassicController.JoystickR.X;
	rY = WiiMoteOBJ->ClassicController.JoystickR.Y;
	
	tL = WiiMoteOBJ->ClassicController.TriggerL;
	tR = WiiMoteOBJ->ClassicController.TriggerR;

	int lbuts = 0;
	
	int cmA = 4;
	int cmB = 8;
	int cmP = 16;
	int cmM = 32;
	int cmU = 64;
	int cmD = 128;
	int cmL = 256;
	int cmR = 512;
	int cmH = 1024;
	int cmX = 2048;
	int cmY = 4096;
	int cmTL = 8192;
	int cmTR = 16384;
	int cmZL = 1;
	int cmZR = 2;

	if (WiiMoteOBJ->ClassicController.Button.A())
		lbuts = lbuts|cmA;
	if (WiiMoteOBJ->ClassicController.Button.B())
		lbuts = lbuts|cmB;
	if (WiiMoteOBJ->ClassicController.Button.X())
		lbuts = lbuts|cmX;
	if (WiiMoteOBJ->ClassicController.Button.Y())
		lbuts = lbuts|cmY;
	if (WiiMoteOBJ->ClassicController.Button.Plus())
		lbuts = lbuts|cmP;
	if (WiiMoteOBJ->ClassicController.Button.Minus())
		lbuts = lbuts|cmM;
	if (WiiMoteOBJ->ClassicController.Button.Home())
		lbuts = lbuts|cmH;
	if (WiiMoteOBJ->ClassicController.Button.Up())
		lbuts = lbuts|cmU;
	if (WiiMoteOBJ->ClassicController.Button.Down())
		lbuts = lbuts|cmD;
	if (WiiMoteOBJ->ClassicController.Button.Left())
		lbuts = lbuts|cmL;
	if (WiiMoteOBJ->ClassicController.Button.Right())
		lbuts = lbuts|cmR;
	if (WiiMoteOBJ->ClassicController.Button.TriggerL())
		lbuts = lbuts|cmTL;
	if (WiiMoteOBJ->ClassicController.Button.TriggerR())
		lbuts = lbuts|cmTR;
	if (WiiMoteOBJ->ClassicController.Button.ZL())
		lbuts = lbuts|cmZL;
	if (WiiMoteOBJ->ClassicController.Button.ZR())
		lbuts = lbuts|cmZR;

	int tuple = MMmalloc(m, 2, TYPETAB);
	if(tuple==NIL)					{	MMset(m,0,NIL);		return MERRMEM;	}
	MMstore(m, tuple, 0, FTOM(lX));
	MMstore(m, tuple, 1, FTOM(lY));

    MMpush(m,PTOM(tuple));	
	
	int tuple2 = MMmalloc(m, 2, TYPETAB);
	if(tuple2==NIL)					{	MMset(m,0,NIL);		return MERRMEM;	}
	MMstore(m, tuple2, 0, FTOM(rX));
	MMstore(m, tuple2, 1, FTOM(rY));

    MMpush(m,PTOM(tuple2));	
	
	// buttons
	if (MMpush(m,ITOM(lbuts))) return MERRMEM;
	if (MMpush(m,FTOM(tL))) return MERRMEM;
	if (MMpush(m,FTOM(tR))) return MERRMEM;

	int finaltuple = MMmalloc(m, 5, TYPETAB);
	if(finaltuple==NIL)					{	MMset(m,0,NIL);		return MERRMEM;	}
	MMstore(m, finaltuple, 4, MMpull(m) );
	MMstore(m, finaltuple, 3, MMpull(m) );
	MMstore(m, finaltuple, 2, MMpull(m) );
	MMstore(m, finaltuple, 1, MMpull(m) );
	MMstore(m, finaltuple, 0, MMpull(m) );

    MMset(m,0,PTOM(finaltuple));	
    

#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif

	return 0;
}


// TODO use thread ?
//////////////////////////////////////////////////////////////////////////////////////////////
///		_PlayWiiSound
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[WiiObj P] I
int _ZPlayWIIsound(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_PlayWiiSound\n");
#endif

	int filename = MMpull(m);

	// Get the path of the file to open
	char* strFileName = (char*)MMstartstr(m,MTOP(filename));
	
	//MMechostr(MSKDEBUG,"_PlayWiiSound %s\n ", strFileName);

	int wii = MTOP( MMget(m,0) );
	if ( wii == NIL ){ MMset(m,0,NIL); return 0; }

	wiimote* WiiMoteOBJ = (wiimote*)MMfetch(m, wii, 0);
	if( !WiiMoteOBJ ) { MMset(m,0,NIL); return 0; }

	if ( filename == NIL ){ WiiMoteOBJ->EnableSpeaker(false); MMset(m,0,NIL); return 0; }


	if (WiiMoteOBJ->IsPlayingSample())
	{
		WiiMoteOBJ->EnableSpeaker(false);
	};

	wiimote_sample sample;

	if (!wiimote::Load16bitMonoSampleWAV(_T(strFileName), sample))
	{
		//WiiMoteOBJ->PlaySquareWave(FREQ_3130HZ, 0x20);
		MMset(m,0,0); return 0;
	};

  WiiMoteOBJ->PlaySample (sample, 0x40, FREQ_3130HZ);
	MMset(m,0,1);


#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif

	return 0;
}



//////////////////////////////////////////////////////////////////////////////////////////////
///		_EmulateMouseClick [I button I state]
//////////////////////////////////////////////////////////////////////////////////////////////
// fun[I I] I
int _ZEmulateMouseClick(mmachine m)
{
#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"_EmulateMouseClick\n");
#endif

	int button;
	int state;

	
	state = MTOI ( MMpull(m) );

	button = MTOI( MMget(m,0) );
	
	if ( (button == NIL) || (button == 0) ) { button = 1; }

	if ( (state == NIL) || (state == 0) )
	{
		if ( button == 2 ) 
			state = MOUSEEVENTF_RIGHTUP;
		else if ( button == 3 ) 
			state = MOUSEEVENTF_MIDDLEUP;
		else
			state = MOUSEEVENTF_LEFTUP;
	}
	else
	{
		if ( button == 2 ) 
			state = MOUSEEVENTF_RIGHTDOWN;
		else if ( button == 3 ) 
			state = MOUSEEVENTF_MIDDLEDOWN;
		else
			state = MOUSEEVENTF_LEFTDOWN;
	}

	mouse_event(state, 0, 0, 0, 0);

	MMset(m,0,0);
	

#ifdef	_SCOL_DEBUG_
	MMechostr(MSKDEBUG,"ok\n");
#endif

	return 0;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBwiimoteIr
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBwiimoteIr ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_WIIMOTE_IR_CB);
}

int getWiimoteIrCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_WIIMOTE_IR_CB))
		return 0;

	float wX,wY,sX,sY = 0.f;
	
	wX = WiiMoteOBJ->IR.Dot[0].X;
	wY = WiiMoteOBJ->IR.Dot[0].Y;
    
	sX = WiiMoteOBJ->IR.Dot[1].X;
	sY = WiiMoteOBJ->IR.Dot[1].Y;

	if (!WiiMoteOBJ->IR.Dot[0].bVisible)
	{
		if (MMpush(m,NIL)) return MERRMEM;
		if (MMpush(m,NIL)) return MERRMEM;
	}
	else
	{
		if (MMpush(m,FTOM(wX))) return MERRMEM;
		if (MMpush(m,FTOM(wY))) return MERRMEM;
	}

	if (!WiiMoteOBJ->IR.Dot[1].bVisible)
	{
		if (MMpush(m,NIL)) return MERRMEM;
		if (MMpush(m,NIL)) return MERRMEM;
	}
	else
	{
		if (MMpush(m,FTOM(sX))) return MERRMEM;
		if (MMpush(m,FTOM(sY))) return MERRMEM;
	}
	
	int finaltuple = MMmalloc(m, 4, TYPETAB);
	if(finaltuple==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, finaltuple, 3, MMpull(m) );
	MMstore(m, finaltuple, 2, MMpull(m) );
	MMstore(m, finaltuple, 1, MMpull(m) );
	MMstore(m, finaltuple, 0, MMpull(m) );

    MMpush(m,PTOM(finaltuple));	

	if ((k=OBJcallreflex(m, 1))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBwiimoteButton
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBwiimoteButton ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_WIIMOTE_BUTTON_CB);
}

int getWiimoteButtonCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;
	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_WIIMOTE_BUTTON_CB))
		return 0;

	int lbuts = 0;

	int cm1 = 1;
	int cm2 = 2;
	int cmA = 4;
	int cmB = 8;
	int cmP = 16;
	int cmM = 32;
	int cmU = 64;
	int cmD = 128;
	int cmL = 256;
	int cmR = 512;
	int cmH = 1024;

	if (WiiMoteOBJ->Button.One())
		lbuts = lbuts|cm1;
	if (WiiMoteOBJ->Button.Two())
		lbuts = lbuts|cm2;
	if (WiiMoteOBJ->Button.A())
		lbuts = lbuts|cmA;
	if (WiiMoteOBJ->Button.B())
		lbuts = lbuts|cmB;
	if (WiiMoteOBJ->Button.Plus())
		lbuts = lbuts|cmP;
	if (WiiMoteOBJ->Button.Minus())
		lbuts = lbuts|cmM;
	if (WiiMoteOBJ->Button.Up())
		lbuts = lbuts|cmU;
	if (WiiMoteOBJ->Button.Down())
		lbuts = lbuts|cmD;
	if (WiiMoteOBJ->Button.Left())
		lbuts = lbuts|cmL;
	if (WiiMoteOBJ->Button.Right())
		lbuts = lbuts|cmR;
	if (WiiMoteOBJ->Button.Home())
		lbuts = lbuts|cmH;

    MMpush(m,ITOM(lbuts));

	if ((k=OBJcallreflex(m, 1))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBwiimoteAccel
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBwiimoteAccel ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_WIIMOTE_ACCEL_CB);
}

int getWiimoteAccelCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_WIIMOTE_ACCEL_CB))
		return 0;

	float wX,wY,wZ,oX,oY,oZ = 0.f;
	int Roll,Pitch = 0;

	wX = WiiMoteOBJ->Acceleration.X;
	wY = WiiMoteOBJ->Acceleration.Y;
	wZ = WiiMoteOBJ->Acceleration.Z;
	
	oX = WiiMoteOBJ->Acceleration.Orientation.X;
	oY = WiiMoteOBJ->Acceleration.Orientation.Y;
	oZ = WiiMoteOBJ->Acceleration.Orientation.Z;
	
	Roll = (int)WiiMoteOBJ->Acceleration.Orientation.Roll;
	Pitch = (int)WiiMoteOBJ->Acceleration.Orientation.Pitch;
	
	WiiMoteOBJ->Acceleration.Orientation.UpdateAge;

	int tuple = MMmalloc(m, 3, TYPETAB);
	if(tuple==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, tuple, 0, FTOM(wX));
	MMstore(m, tuple, 1, FTOM(wY));
	MMstore(m, tuple, 2, FTOM(wZ));

    MMpush(m,PTOM(tuple));	


	int tuple2 = MMmalloc(m, 3, TYPETAB);
	if(tuple2==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, tuple2, 0, FTOM(oX));
	MMstore(m, tuple2, 1, FTOM(oY));
	MMstore(m, tuple2, 2, FTOM(oZ));

    MMpush(m,PTOM(tuple2));	


	int tuple3 = MMmalloc(m, 2, TYPETAB);
	if(tuple3==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, tuple3, 0, ITOM(Pitch));
	MMstore(m, tuple3, 1, ITOM(Roll));

    MMpush(m,PTOM(tuple3));

	if ((k=OBJcallreflex(m, 3))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBwiimoteConnectionLost
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBwiimoteConnectionLost ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_WIIMOTE_CONNECTION_LOST_CB);
}

int getWiimoteConnectionLostCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_WIIMOTE_CONNECTION_LOST_CB))
		return 0;

	if ((k=OBJcallreflex(m, 0))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBnunchukButton
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBnunchukButton ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_NUNCHUK_BUTTON_CB);
}

int getNunchukButtonCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (!WiiMoteOBJ->NunchukConnected())
		return 0;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_NUNCHUK_BUTTON_CB))
		return 0;

	int lbuts = 0;

	if (WiiMoteOBJ->Nunchuk.C)
		lbuts = lbuts|1;
	if (WiiMoteOBJ->Nunchuk.Z)
		lbuts = lbuts|2;
	
	MMpush(m,ITOM(lbuts));

	if ((k=OBJcallreflex(m, 1))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBnunchukAccel
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBnunchukAccel ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_NUNCHUK_ACCEL_CB);
}

int getNunchukAccelCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (!WiiMoteOBJ->NunchukConnected())
		return 0;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_NUNCHUK_ACCEL_CB))
		return 0;

	int Roll,Pitch = 0;
	float wX,wY,wZ,oX,oY,oZ = 0.f;
	
	wX = WiiMoteOBJ->Nunchuk.Acceleration.X;
	wY = WiiMoteOBJ->Nunchuk.Acceleration.Y;
	wZ = WiiMoteOBJ->Nunchuk.Acceleration.Z;

	oX = WiiMoteOBJ->Nunchuk.Acceleration.Orientation.X;
	oY = WiiMoteOBJ->Nunchuk.Acceleration.Orientation.Y;
	oZ = WiiMoteOBJ->Nunchuk.Acceleration.Orientation.Z;

	Roll = (int)WiiMoteOBJ->Nunchuk.Acceleration.Orientation.Roll;
	Pitch = (int)WiiMoteOBJ->Nunchuk.Acceleration.Orientation.Pitch;
	
	WiiMoteOBJ->Nunchuk.Acceleration.Orientation.UpdateAge;
	
	int tuple = MMmalloc(m, 3, TYPETAB);
	if(tuple==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, tuple, 0, FTOM(wX));
	MMstore(m, tuple, 1, FTOM(wY));
	MMstore(m, tuple, 2, FTOM(wZ));

    MMpush(m,PTOM(tuple));	
	
	int tuple2 = MMmalloc(m, 3, TYPETAB);
	if(tuple2==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, tuple2, 0, FTOM(oX));
	MMstore(m, tuple2, 1, FTOM(oY));
	MMstore(m, tuple2, 2, FTOM(oZ));

    MMpush(m,PTOM(tuple2));	
	
	int tuple3 = MMmalloc(m, 2, TYPETAB);
	if(tuple3==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, tuple3, 0, ITOM(Pitch));
	MMstore(m, tuple3, 1, ITOM(Roll));

    MMpush(m,PTOM(tuple3));

	if ((k=OBJcallreflex(m, 3))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBnunchukJoy
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBnunchukJoy ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_NUNCHUK_JOY_CB);
}

int getNunchukJoyCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (!WiiMoteOBJ->NunchukConnected())
		return 0;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_NUNCHUK_JOY_CB))
		return 0;
	
	float sX = WiiMoteOBJ->Nunchuk.Joystick.X;
    float sY = WiiMoteOBJ->Nunchuk.Joystick.Y;

	int tuple4 = MMmalloc(m, 2, TYPETAB);
	if(tuple4==NIL)					{	MMpush(m,NIL);	return MERRMEM;	}
	MMstore(m, tuple4, 0, FTOM(sX));
	MMstore(m, tuple4, 1, FTOM(sY));

    MMpush(m,PTOM(tuple4));

	if ((k=OBJcallreflex(m, 1))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_CBwiiBalanceBoard
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBwiiBalanceBoard ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_BALANCE_BOARD_CB);
}

int getWiimoteBoardCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (!WiiMoteOBJ->IsBalanceBoard())
		return 0;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_BALANCE_BOARD_CB))
		return 0;
	
	float tl,tr,bl,br,total = 0.f;
	
	tl = WiiMoteOBJ->BalanceBoard.Kg.TopL;
	tr = WiiMoteOBJ->BalanceBoard.Kg.TopR;
	bl = WiiMoteOBJ->BalanceBoard.Kg.BottomL;
	br = WiiMoteOBJ->BalanceBoard.Kg.BottomR;
	total = WiiMoteOBJ->BalanceBoard.Kg.Total;

	if (MMpush(m,FTOM(tl))) return MERRMEM;
	if (MMpush(m,FTOM(tr))) return MERRMEM;
	if (MMpush(m,FTOM(bl))) return MERRMEM;
	if (MMpush(m,FTOM(br))) return MERRMEM;
	if (MMpush(m,FTOM(total))) return MERRMEM;
	
	int finaltuple = MMmalloc(m, 5, TYPETAB);
	if(finaltuple==NIL)					{	MMpush(m,NIL);		return MERRMEM;	}
	MMstore(m, finaltuple, 4, MMpull(m) );
	MMstore(m, finaltuple, 3, MMpull(m) );
	MMstore(m, finaltuple, 2, MMpull(m) );
	MMstore(m, finaltuple, 1, MMpull(m) );
	MMstore(m, finaltuple, 0, MMpull(m) );

    MMpush(m,PTOM(finaltuple));	
	
	if ((k=OBJcallreflex(m, 1))) return k;
	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBextensionDisconnected
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBextensionDisconnected ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_EXTENSION_DISCONNECTED_CB);
}

int getExtensionDisconnectedCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_EXTENSION_DISCONNECTED_CB))
		return 0;

    MMpush(m,ITOM(extensionTypeToSimpleType(WiiMoteOBJ)));

	if ((k=OBJcallreflex(m, 1))) return k;

	return k;
}


//////////////////////////////////////////////////////////////////////////////////////////////
///	_ZCBextensionConnected
//////////////////////////////////////////////////////////////////////////////////////////////

int _ZCBextensionConnected ( mmachine m )
{
	return OBJaddreflex(m, OBJWIISCOL, SCOL_EXTENSION_CONNECTED_CB);
}

int getExtensionConnectedCb(mmachine m,HWND h,unsigned msg,UINT id,LONG param,int *ret)
{
	int k = 0;
	wiimote* WiiMoteOBJ = (wiimote*) id;

	if (OBJbeginreflex(m, OBJWIISCOL, (int)WiiMoteOBJ, SCOL_EXTENSION_CONNECTED_CB))
		return 0;

    MMpush(m,ITOM(extensionTypeToSimpleType(WiiMoteOBJ)));

	if ((k=OBJcallreflex(m, 1))) return k;

	return k;
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////																											   ////
///										DECLARATION DES FONCTIONS POUR SCOL											///
////																											   ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



#define NbWiiPKG	19


//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des noms de fonction SCOL
//////////////////////////////////////////////////////////////////////////////////////////////
char	*WiiName[NbWiiPKG] =
{
	"WiiObj",
	"_OpenWiiDevice",
	"_CloseWiiDevice",
	"_SetWiiLeds",
	"_SetWiiVibrate",
	"_GetWiiClassicInfos",
	"_PlayWiiSound",
	"_EmulateMouseClick",
	"_CBwiimoteIr",
	"_CBwiimoteButton",
	"_CBwiimoteAccel",
	"_CBwiimoteConnectionLost",
	"_CBwiiBalanceBoard",
	"_CBnunchukButton",
	"_CBnunchukAccel",
	"_CBnunchukJoy",
	"_CBextensionDisconnected",
	"_CBextensionConnected",
	"_GetWiiExtensionType"
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des pointeurs sur fonctions
//////////////////////////////////////////////////////////////////////////////////////////////
int (*WiiFunc[NbWiiPKG])(mmachine m)=
{
	NULL,
	_ZOpenWIIdevice,										// _OpenWiiDevice
	_ZCloseWIIdevice,										// _CloseWiiDevice
	_ZSetWIIleds,											// _SetWiiLeds
	_ZSetWIIvibrate,										// _SetWiiVibrate
	_ZGetWIIClassicInfos,                                   // _GetWiiClassicInfos
	_ZPlayWIIsound,											// _PlayWiiSound
	_ZEmulateMouseClick,									// _EmulateMouseClick
	_ZCBwiimoteIr,											// _CBwiimoteIr
	_ZCBwiimoteButton,										// _CBwiimoteButton
	_ZCBwiimoteAccel,										// _CBwiimoteAccel
	_ZCBwiimoteConnectionLost,								// _CBwiimoteConnectionLost
	_ZCBwiiBalanceBoard,									// _CBwiiBalanceBoard
	_ZCBnunchukButton,										// _CBnunchukButton
	_ZCBnunchukAccel,										// _CBnunchukAccel
	_ZCBnunchukJoy,											// _CBnunchukJoy
	_ZCBextensionDisconnected,								// _CBextensionDisconnected
	_ZCBextensionConnected,									// _CBextensionConnected
	_ZGetWiiExtensionType									// _GetWiiExtensionType
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition du nombre de paramètres
//////////////////////////////////////////////////////////////////////////////////////////////
int WiiNArg[NbWiiPKG]=
{
	TYPTYPE,
	2,														// _OpenWiiDevice
	1,														// _CloseWiiDevice
	5,														// _SetWiiLeds
	2,														// _SetWiiVibrate
	1,														// _GetWiiClassicInfos
	2,														// _PlayWiiSound
	2,														// _EmulateMouseClick
	3,														// _CBwiimoteIr
	3,														// _CBwiimoteButton
	3,														// _CBwiimoteAccel
	3,														// _CBwiimoteConnectionLost
	3,														// _CBwiiBalanceBoard
	3,														// _CBnunchukButton
	3,														// _CBnunchukAccel
	3,														// _CBnunchukJoy
	3,														// _CBextensionDisconnected
	3,														// _CBextensionConnected
	1														// _GetWiiExtensionType
};



//////////////////////////////////////////////////////////////////////////////////////////////
///		Definition des grammaires fontionnelles
//////////////////////////////////////////////////////////////////////////////////////////////
char* WiiType[NbWiiPKG]=
{
	NULL,
	"fun [Chn I] WiiObj",														// _OpenWiiDevice
	"fun [WiiObj] I",															// _CloseWiiDevice
	"fun [WiiObj I I I I] I",													// _SetWiiLeds
	"fun [WiiObj I] I",															// _SetWiiVibrate
	"fun [WiiObj] [[F F] [F F] I F F]",											// _GetWiiClassicInfos
	"fun [WiiObj P] I",															// _PlayWiiSound 
	"fun [I I] I",																// _EmulateMouseClick 
	"fun [WiiObj fun [WiiObj u0 [F F F F]] u1 u0] WiiObj",						// _CBwiimoteIr
	"fun [WiiObj fun [WiiObj u0 I] u1 u0] WiiObj",								// _CBwiimoteButton
	"fun [WiiObj fun [WiiObj u0 [F F F] [F F F] [I I]] u1 u0] WiiObj",			// _CBwiimoteAccel
	"fun [WiiObj fun [WiiObj u0] u1 u0] WiiObj",								// _CBwiimoteConnectionLost
	"fun [WiiObj fun [WiiObj u0 [F F F F F]] u1 u0] WiiObj",					// _CBwiiBalanceBoard
	"fun [WiiObj fun [WiiObj u0 I] u1 u0] WiiObj",								// _CBnunchukButton
	"fun [WiiObj fun [WiiObj u0 [F F F] [F F F] [I I]] u1 u0] WiiObj",			// _CBnunchukAccel
	"fun [WiiObj fun [WiiObj u0 [F F]] u1 u0] WiiObj",							// _CBnunchukJoy
	"fun [WiiObj fun [WiiObj u0 I] u1 u0] WiiObj",								// _CBextensionDisconnected
	"fun [WiiObj fun [WiiObj u0 I] u1 u0] WiiObj",								// _CBextensionConnected
	"fun [WiiObj] I"															// _GetWiiExtensionType
};



///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////																											   ////
///											FONCTIONS D'APPEL DE LA DLL												///
////																											   ////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



int LoadWii(mmachine m)
{
	int			k;

	//MMechostr(0,"\n" );
	//MMechostr(0,"************************    WII  Support   *************************\n" );

	// Declaration des types de donnée
	OBJWIISCOL = OBJregister( 10, 0, destroyWiiObj, "OBJWIISCOL" );
	
	WIIMOTE_IR_CB = OBJgetUserEvent();
	OBJdefEvent( WIIMOTE_IR_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getWiimoteIrCb );

	WIIMOTE_BUTTON_CB = OBJgetUserEvent();
	OBJdefEvent( WIIMOTE_BUTTON_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getWiimoteButtonCb );

	WIIMOTE_ACCEL_CB = OBJgetUserEvent();
	OBJdefEvent( WIIMOTE_ACCEL_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getWiimoteAccelCb );

	WIIMOTE_CONNECTION_LOST_CB = OBJgetUserEvent();
	OBJdefEvent( WIIMOTE_CONNECTION_LOST_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getWiimoteConnectionLostCb );


	NUNCHUK_BUTTON_CB = OBJgetUserEvent();
	OBJdefEvent( NUNCHUK_BUTTON_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getNunchukButtonCb );

	NUNCHUK_ACCEL_CB = OBJgetUserEvent();
	OBJdefEvent( NUNCHUK_ACCEL_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getNunchukAccelCb );

	NUNCHUK_JOY_CB = OBJgetUserEvent();
	OBJdefEvent( NUNCHUK_JOY_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getNunchukJoyCb );
	
	
	BALANCE_BOARD_CB = OBJgetUserEvent();
	OBJdefEvent( BALANCE_BOARD_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getWiimoteBoardCb );
	
	
	EXTENSION_DISCONNECTED_CB = OBJgetUserEvent();
	OBJdefEvent( EXTENSION_DISCONNECTED_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getExtensionDisconnectedCb );
	
	EXTENSION_CONNECTED_CB = OBJgetUserEvent();
	OBJdefEvent( EXTENSION_CONNECTED_CB, (int (__cdecl *)(struct Mmachine *,int,unsigned int,int,int,int *))getExtensionConnectedCb );
	
	
	k = PKhardpak(m, "WiiEngine", NbWiiPKG, WiiName, WiiFunc, WiiNArg, WiiType);

	//MMechostr(0,"**********************  Successfully Loaded  **********************\n" );
	//MMechostr(0,"\n" );

	return k;
}

///////////////////////////////////////////////////////////////
///		Starting point of the DLL							///
///////////////////////////////////////////////////////////////
extern "C" __declspec (dllexport) int ScolLoadPlugin(mmachine m, cbmachine w)
{
	int	k = 0;
	ww = w;
	mm = m;

	HScol=(HWND)SCgetExtra("hscol");;
	k = LoadWii(m);
	return k;
}

///////////////////////////////////////////////////////////////
///		Ending point of the DLL								///
///////////////////////////////////////////////////////////////
extern "C" __declspec (dllexport) int ScolUnloadPlugin()
{
    return 0;
}