示例#1
0
// Handle incoming data from USB 
void FfbOnUsbData(uint8_t* data, uint16_t len)
{

	uint8_t effectId = data[1]; // effectBlockIndex is always the second byte.

	switch (data[0])    // reportID
	{
	case 1:
		FfbHandle_SetEffect((USB_FFBReport_SetEffect_Output_Data_t*)data);
		break;
	case 2:
		SetEnvelope((USB_FFBReport_SetEnvelope_Output_Data_t*)data, &gEffectStates[effectId]);
		break;
	case 3:
		SetCondition((USB_FFBReport_SetCondition_Output_Data_t*)data, &gEffectStates[effectId]);
		break;
	case 4:
		SetPeriodic((USB_FFBReport_SetPeriodic_Output_Data_t*)data, &gEffectStates[effectId]);
		break;
	case 5:
		SetConstantForce((USB_FFBReport_SetConstantForce_Output_Data_t*)data, &gEffectStates[effectId]);
		break;
	case 6:
		SetRampForce((USB_FFBReport_SetRampForce_Output_Data_t*)data, &gEffectStates[effectId]);
		break;
	case 7:
		FfbHandle_SetCustomForceData((USB_FFBReport_SetCustomForceData_Output_Data_t*)data);
		break;
	case 8:
		FfbHandle_SetDownloadForceSample((USB_FFBReport_SetDownloadForceSample_Output_Data_t*)data);
		break;
	case 9:
		break;
	case 10:
		FfbHandle_EffectOperation((USB_FFBReport_EffectOperation_Output_Data_t*)data);
		break;
	case 11:
		FfbHandle_BlockFree((USB_FFBReport_BlockFree_Output_Data_t*)data);
		break;
	case 12:
		FfbHandle_DeviceControl((USB_FFBReport_DeviceControl_Output_Data_t*)data);
		break;
	case 13:
		FfbHandle_DeviceGain((USB_FFBReport_DeviceGain_Output_Data_t*)data);
		break;
	case 14:
		FfbHandle_SetCustomForce((USB_FFBReport_SetCustomForce_Output_Data_t*)data);
		break;
	default:
		break;
	};

}
static int token_out(PADState *ps, uint8_t *data, int len)
{
	LinuxPADState *s = (LinuxPADState*)ps;
	uint8_t idx = 1 - s->padState.port;
	if(idx>1) return 0;

	memcpy(&ffdata,data, sizeof(ffdata));
	//if(idx!=0)return 0;
	Dbg("FFB 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x0%4X\n", ffdata.reportid, ffdata.index, ffdata.data1, ffdata.data2, *(int*)((char*)&ffdata + 4) );

	switch(ffdata.reportid)
	{
		case 0xF8:
			//TODO needed?
			if(ffdata.index == 5)
				sendCrap = true;
			//TODO guess-work
			//if(ffdata.index == 3)
			//	SetAutoCenter(s, 100);
		break;
		case 9:
			{
				//not handled
			}
			break;
		case 0x13:
			//some games issue this command on pause
			//if(ffdata.reportid == 19 && ffdata.data2 == 0)break;
			if(ffdata.index == 0x8)
				SetConstantForce(s, 127); //data1 looks like previous force sent with reportid 0x11
			//TODO unset spring
			else if(ffdata.index == 3)
				SetSpringForce(s, 127);

			//Dbg("FFB 0x%X, 0x%X, 0x%X\n", ffdata.reportid, ffdata.index, ffdata.data1);
			break;
		case 0x11://constant force
			{
				//handle calibration commands
				//if(!calibrating)
				{
					SetConstantForce(s, ffdata.data1);
				}
			}
			break;
		case 0x21:
			if(ffdata.index == 0xB)
			{
				//if(!calibrating)
				{
					//TODO guess-work
					SetAutoCenter(s, 100);
					//SetSpringForce(s, ffdata.data1); //spring is broken?
				}
				break;
			}
			//drop through
		case 0xFE://autocenter?
		case 0xFF://autocenter?
		case 0xF4://autocenter?
			//{
			//	SetAutoCenter(s, 0);
			//}
			//break;
		case 0xF5://autocenter?
			{
				SetAutoCenter(s, 0);
				//just release force
				SetConstantForce(s, 127);
			}
			break;
		case 0xF1:
			//DF/GTF and GT3
			//if(!calibrating)
			{
				SetConstantForce(s, ffdata.pad1);
			}
			break;
		case 0xF3://initialize
			{
				//SetAutoCenter(s, 0xFFFFUL);
			}
			break;
	}

	return len;
}