mirror of
				https://github.com/Ed94/HandmadeHero.git
				synced 2025-10-31 06:50:54 -07:00 
			
		
		
		
	Day 6 Bonus: Dualsense Edge support!
I had to temporarily make my own binaries for the JoyShockLibrary but it works!
This commit is contained in:
		
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -19,3 +19,5 @@ bld/ | |||||||
| vc140.pdb | vc140.pdb | ||||||
|  |  | ||||||
| build | build | ||||||
|  |  | ||||||
|  | **/*.dll | ||||||
|   | |||||||
							
								
								
									
										548
									
								
								project/dependencies/JoyShockLibrary/InputHelpers.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										548
									
								
								project/dependencies/JoyShockLibrary/InputHelpers.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,548 @@ | |||||||
|  | #include "JoyShockLibrary.h" | ||||||
|  | #include "JoyShock.cpp" | ||||||
|  |  | ||||||
|  | #include <cmath> | ||||||
|  |  | ||||||
|  | bool handle_input(JoyShock *jc, uint8_t *packet, int len, bool &hasIMU) { | ||||||
|  | 	hasIMU = true; | ||||||
|  | 	if (packet[0] == 0) return false; // ignore non-responses | ||||||
|  | 									  // remember last input | ||||||
|  |  | ||||||
|  | 	//printf("%d: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||||||
|  | 	//	jc->left_right, | ||||||
|  | 	//	packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9], | ||||||
|  | 	//	packet[10], packet[11], packet[12], packet[13], packet[14], packet[15], packet[16], packet[17], packet[18], packet[19], packet[20]); | ||||||
|  |  | ||||||
|  | 	jc->last_simple_state = jc->simple_state; | ||||||
|  | 	jc->simple_state.buttons = 0; | ||||||
|  | 	jc->last_imu_state = jc->imu_state; | ||||||
|  | 	IMU_STATE imu_state; | ||||||
|  | 	// delta time | ||||||
|  | 	auto time_now = std::chrono::steady_clock::now(); | ||||||
|  | 	jc->delta_time = (float)(std::chrono::duration_cast<std::chrono::microseconds>(time_now - jc->last_polled).count() / 1000000.0); | ||||||
|  | 	jc->last_polled = time_now; | ||||||
|  | 	if (jc->cue_motion_reset) | ||||||
|  | 	{ | ||||||
|  | 		//printf("RESET motion\n"); | ||||||
|  | 		jc->cue_motion_reset = false; | ||||||
|  | 		jc->motion.Reset(); | ||||||
|  | 	} | ||||||
|  | 	if (jc->motion.GetCalibrationMode() == GamepadMotionHelpers::CalibrationMode::Manual) | ||||||
|  | 	{ | ||||||
|  | 		if (jc->use_continuous_calibration) | ||||||
|  | 		{ | ||||||
|  | 			jc->motion.StartContinuousCalibration(); | ||||||
|  | 		} | ||||||
|  | 		else | ||||||
|  | 		{ | ||||||
|  | 			jc->motion.PauseContinuousCalibration(); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	// ds4 | ||||||
|  | 	if (jc->controller_type == ControllerType::s_ds4) { | ||||||
|  | 		int indexOffset = 0; | ||||||
|  | 		bool isValid = true; | ||||||
|  | 		if (!jc->is_usb) { | ||||||
|  | 			isValid = packet[0] == 0x11; | ||||||
|  | 			indexOffset = 2; | ||||||
|  | 		} | ||||||
|  | 		else { | ||||||
|  | 			isValid = packet[0] == 0x01; | ||||||
|  | 			if (isValid && (packet[31] & 0x04) == 0x04) | ||||||
|  | 				return false; // ignore packets from Dongle with no connected controller | ||||||
|  | 		} | ||||||
|  | 		if (isValid) { | ||||||
|  | 			// Gyroscope: | ||||||
|  | 			// Gyroscope data is relative (degrees/s) | ||||||
|  | 			int16_t gyroSampleX = uint16_to_int16(packet[indexOffset+13] | (packet[indexOffset+14] << 8) & 0xFF00); | ||||||
|  | 			int16_t gyroSampleY = uint16_to_int16(packet[indexOffset+15] | (packet[indexOffset+16] << 8) & 0xFF00); | ||||||
|  | 			int16_t gyroSampleZ = uint16_to_int16(packet[indexOffset+17] | (packet[indexOffset+18] << 8) & 0xFF00); | ||||||
|  | 			int16_t accelSampleX = uint16_to_int16(packet[indexOffset+19] | (packet[indexOffset+20] << 8) & 0xFF00); | ||||||
|  | 			int16_t accelSampleY = uint16_to_int16(packet[indexOffset+21] | (packet[indexOffset+22] << 8) & 0xFF00); | ||||||
|  | 			int16_t accelSampleZ = uint16_to_int16(packet[indexOffset+23] | (packet[indexOffset+24] << 8) & 0xFF00); | ||||||
|  |  | ||||||
|  | 			if ((gyroSampleX | gyroSampleY | gyroSampleZ | accelSampleX | accelSampleY | accelSampleZ) == 0) | ||||||
|  | 			{ | ||||||
|  | 				// all zero? | ||||||
|  | 				hasIMU = false; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			// convert to real units | ||||||
|  | 			imu_state.gyroX = (float)(gyroSampleX) * (2000.0f / 32767.0f); | ||||||
|  | 			imu_state.gyroY = (float)(gyroSampleY) * (2000.0f / 32767.0f); | ||||||
|  | 			imu_state.gyroZ = (float)(gyroSampleZ) * (2000.0f / 32767.0f); | ||||||
|  |  | ||||||
|  | 			imu_state.accelX = (float)(accelSampleX) / 8192.0f; | ||||||
|  | 			imu_state.accelY = (float)(accelSampleY) / 8192.0f; | ||||||
|  | 			imu_state.accelZ = (float)(accelSampleZ) / 8192.0f; | ||||||
|  |  | ||||||
|  | 			//printf("DS4 accel: %.4f, %.4f, %.4f\n", imu_state.accelX, imu_state.accelY, imu_state.accelZ); | ||||||
|  |  | ||||||
|  | 			//printf("%.4f,%.4f,%.4f,%.4f,%.4f,%.4f,%d\n", | ||||||
|  | 			//	jc->gyro.yaw, jc->gyro.pitch, jc->gyro.roll, jc->accel.x, jc->accel.y, jc->accel.z, universal_counter++); | ||||||
|  |  | ||||||
|  | 			// Touchpad: | ||||||
|  | 			jc->last_touch_state = jc->touch_state; | ||||||
|  |  | ||||||
|  | 			jc->touch_state.t0Id = (int)(packet[indexOffset+35] & 0x7F); | ||||||
|  | 			jc->touch_state.t1Id = (int)(packet[indexOffset+39] & 0x7F); | ||||||
|  | 			jc->touch_state.t0Down = (packet[indexOffset+35] & 0x80) == 0; | ||||||
|  | 			jc->touch_state.t1Down = (packet[indexOffset+39] & 0x80) == 0; | ||||||
|  |  | ||||||
|  | 			jc->touch_state.t0X = (packet[indexOffset+36] | (packet[indexOffset+37] & 0x0F) << 8) / 1920.0f; | ||||||
|  | 			jc->touch_state.t0Y = ((packet[indexOffset+37] & 0xF0) >> 4 | packet[indexOffset+38] << 4) / 943.0f; | ||||||
|  | 			jc->touch_state.t1X = (packet[indexOffset+40] | (packet[indexOffset+41] & 0x0F) << 8) / 1920.0f; | ||||||
|  | 			jc->touch_state.t1Y = ((packet[indexOffset+41] & 0xF0) >> 4 | packet[indexOffset+42] << 4) / 943.0f; | ||||||
|  |  | ||||||
|  | 			//printf("DS4 touch: %d, %d, %d, %d, %.4f, %.4f, %.4f, %.4f\n", | ||||||
|  | 			//	jc->touch_state.t0Id, jc->touch_state.t1Id, jc->touch_state.t0Down, jc->touch_state.t1Down, | ||||||
|  | 			//	jc->touch_state.t0X, jc->touch_state.t0Y, jc->touch_state.t1X, jc->touch_state.t1Y); | ||||||
|  |  | ||||||
|  | 			// DS4 dpad is a hat...  0x08 is released, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW | ||||||
|  | 			// http://eleccelerator.com/wiki/index.php?title=DualShock_4 | ||||||
|  | 			uint8_t hat = packet[indexOffset+5] & 0x0f; | ||||||
|  |  | ||||||
|  | 			if ((hat > 2) & (hat < 6)) jc->simple_state.buttons |= JSMASK_DOWN; // down = SE | S | SW | ||||||
|  | 			if ((hat == 7) | (hat < 2)) jc->simple_state.buttons |= JSMASK_UP; // up = N | NE | NW | ||||||
|  | 			if ((hat > 0) & (hat < 4)) jc->simple_state.buttons |= JSMASK_RIGHT; // right = NE | E | SE | ||||||
|  | 			if ((hat > 4) & (hat < 8)) jc->simple_state.buttons |= JSMASK_LEFT; // left = SW | W | NW | ||||||
|  |  | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+5] >> 4) << JSOFFSET_W) & JSMASK_W; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+5] >> 7) << JSOFFSET_N) & JSMASK_N; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+5] >> 5) << JSOFFSET_S) & JSMASK_S; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+5] >> 6) << JSOFFSET_E) & JSMASK_E; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+6] >> 6) << JSOFFSET_LCLICK) & JSMASK_LCLICK; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+6] >> 7) << JSOFFSET_RCLICK) & JSMASK_RCLICK; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+6] >> 5) << JSOFFSET_OPTIONS) & JSMASK_OPTIONS; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+6] >> 4) << JSOFFSET_SHARE) & JSMASK_SHARE; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+6] >> 1) << JSOFFSET_R) & JSMASK_R; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+6]) << JSOFFSET_L) & JSMASK_L; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+7]) << JSOFFSET_PS) & JSMASK_PS; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(packet[indexOffset+7] >> 1) << JSOFFSET_TOUCHPAD_CLICK) & JSMASK_TOUCHPAD_CLICK; | ||||||
|  | 			//jc->btns.zr = (packet[indexOffset+6] >> 3) & 1; | ||||||
|  | 			//jc->btns.zl = (packet[indexOffset+6] >> 2) & 1; | ||||||
|  | 			jc->simple_state.rTrigger = packet[indexOffset+9] / 255.0f; | ||||||
|  | 			jc->simple_state.lTrigger = packet[indexOffset+8] / 255.0f; | ||||||
|  |  | ||||||
|  | 			if (jc->simple_state.rTrigger > 0.0) jc->simple_state.buttons |= JSMASK_ZR; | ||||||
|  | 			if (jc->simple_state.lTrigger > 0.0) jc->simple_state.buttons |= JSMASK_ZL; | ||||||
|  |  | ||||||
|  | 			uint16_t stick_x = packet[indexOffset+1]; | ||||||
|  | 			uint16_t stick_y = packet[indexOffset+2]; | ||||||
|  | 			stick_y = 255 - stick_y; | ||||||
|  |  | ||||||
|  | 			uint16_t stick2_x = packet[indexOffset+3]; | ||||||
|  | 			uint16_t stick2_y = packet[indexOffset+4]; | ||||||
|  | 			stick2_y = 255 - stick2_y; | ||||||
|  |  | ||||||
|  | 			jc->simple_state.stickLX = (std::fmin)(1.0f, (stick_x - 127.0f) / 127.0f); | ||||||
|  | 			jc->simple_state.stickLY = (std::fmin)(1.0f, (stick_y - 127.0f) / 127.0f); | ||||||
|  | 			jc->simple_state.stickRX = (std::fmin)(1.0f, (stick2_x - 127.0f) / 127.0f); | ||||||
|  | 			jc->simple_state.stickRY = (std::fmin)(1.0f, (stick2_y - 127.0f) / 127.0f); | ||||||
|  |  | ||||||
|  | 			jc->modifying_lock.lock(); | ||||||
|  | 			jc->push_sensor_samples(imu_state.gyroX, imu_state.gyroY, imu_state.gyroZ, | ||||||
|  | 					imu_state.accelX, imu_state.accelY, imu_state.accelZ, jc->delta_time); | ||||||
|  |  | ||||||
|  | 			jc->get_calibrated_gyro(imu_state.gyroX, imu_state.gyroY, imu_state.gyroZ); | ||||||
|  | 			jc->modifying_lock.unlock(); | ||||||
|  |  | ||||||
|  | 			jc->imu_state = imu_state; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		//printf("Buttons: %d LX: %.5f LY: %.5f RX: %.5f RY: %.5f GX: %.4f GY: %.4f GZ: %.4f\n", \ | ||||||
|  | 				//	jc->simple_state.buttons, (jc->simple_state.stickLX + 1), (jc->simple_state.stickLY + 1), (jc->simple_state.stickRX + 1), (jc->simple_state.stickRY + 1), jc->imu_state.gyroX, jc->imu_state.gyroY, jc->imu_state.gyroZ); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	if (jc->controller_type == ControllerType::s_ds) { | ||||||
|  |         //printf("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", | ||||||
|  |         //	packet[0], packet[1], packet[2], packet[3], packet[4], packet[5], packet[6], packet[7], packet[8], packet[9], | ||||||
|  |         //	packet[10], packet[11], packet[12], packet[13], packet[14], packet[15], packet[16], packet[17], packet[18], packet[19], packet[20], | ||||||
|  |         //	packet[21], packet[22], packet[23], packet[24], packet[25], packet[26], packet[27], packet[28], packet[29], packet[30], | ||||||
|  |         //	packet[31], packet[32], packet[33], packet[34], packet[35], packet[36], packet[37], packet[38], packet[39], packet[40], | ||||||
|  |         //	packet[41], packet[42], packet[43], packet[44], packet[45], packet[46], packet[47], packet[48], packet[49], packet[50]); | ||||||
|  |         int indexOffset = 1; | ||||||
|  |         if(!jc->is_usb) { | ||||||
|  |             indexOffset = 2; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Gyroscope: | ||||||
|  |         // Gyroscope data is relative (degrees/s) | ||||||
|  |         int16_t gyroSampleX = uint16_to_int16(packet[indexOffset + 15] | (packet[indexOffset + 16] << 8) & 0xFF00); | ||||||
|  |         int16_t gyroSampleY = uint16_to_int16(packet[indexOffset + 17] | (packet[indexOffset + 18] << 8) & 0xFF00); | ||||||
|  |         int16_t gyroSampleZ = uint16_to_int16(packet[indexOffset + 19] | (packet[indexOffset + 20] << 8) & 0xFF00); | ||||||
|  |         int16_t accelSampleX = uint16_to_int16(packet[indexOffset + 21] | (packet[indexOffset + 22] << 8) & 0xFF00); | ||||||
|  |         int16_t accelSampleY = uint16_to_int16(packet[indexOffset + 23] | (packet[indexOffset + 24] << 8) & 0xFF00); | ||||||
|  |         int16_t accelSampleZ = uint16_to_int16(packet[indexOffset + 25] | (packet[indexOffset + 26] << 8) & 0xFF00); | ||||||
|  |  | ||||||
|  |         if ((gyroSampleX | gyroSampleY | gyroSampleZ | accelSampleX | accelSampleY | accelSampleZ) == 0) { | ||||||
|  |             // all zero? | ||||||
|  |             hasIMU = false; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // convert to real units | ||||||
|  |         imu_state.gyroX = (float) (gyroSampleX) * (2000.0f / 32767.0f); | ||||||
|  |         imu_state.gyroY = (float) (gyroSampleY) * (2000.0f / 32767.0f); | ||||||
|  |         imu_state.gyroZ = (float) (gyroSampleZ) * (2000.0f / 32767.0f); | ||||||
|  |  | ||||||
|  |         imu_state.accelX = (float) (accelSampleX) / 8192.0f; | ||||||
|  |         imu_state.accelY = (float) (accelSampleY) / 8192.0f; | ||||||
|  |         imu_state.accelZ = (float) (accelSampleZ) / 8192.0f; | ||||||
|  |  | ||||||
|  |         //printf("DS accel: %.4f, %.4f, %.4f\n", imu_state.accelX, imu_state.accelY, imu_state.accelZ); | ||||||
|  |  | ||||||
|  |         //printf("%.4f,%.4f,%.4f,%.4f,%.4f,%.4f,%d\n", | ||||||
|  |         //	jc->gyro.yaw, jc->gyro.pitch, jc->gyro.roll, jc->accel.x, jc->accel.y, jc->accel.z, universal_counter++); | ||||||
|  |  | ||||||
|  |         // Touchpad: | ||||||
|  |         jc->last_touch_state = jc->touch_state; | ||||||
|  |  | ||||||
|  |         jc->touch_state.t0Id = (int) (packet[indexOffset + 32] & 0x7F); | ||||||
|  |         jc->touch_state.t1Id = (int) (packet[indexOffset + 36] & 0x7F); | ||||||
|  |         jc->touch_state.t0Down = (packet[indexOffset + 32] & 0x80) == 0; | ||||||
|  |         jc->touch_state.t1Down = (packet[indexOffset + 36] & 0x80) == 0; | ||||||
|  |  | ||||||
|  |         jc->touch_state.t0X = (packet[indexOffset + 33] | (packet[indexOffset + 34] & 0x0F) << 8) / 1920.0f; | ||||||
|  |         jc->touch_state.t0Y = ((packet[indexOffset + 34] & 0xF0) >> 4 | packet[indexOffset + 35] << 4) / 943.0f; | ||||||
|  |         jc->touch_state.t1X = (packet[indexOffset + 37] | (packet[indexOffset + 38] & 0x0F) << 8) / 1920.0f; | ||||||
|  |         jc->touch_state.t1Y = ((packet[indexOffset + 38] & 0xF0) >> 4 | packet[indexOffset + 39] << 4) / 943.0f; | ||||||
|  |  | ||||||
|  |         //printf("DS touch: %d, %d, %d, %d, %.4f, %.4f, %.4f, %.4f\n", | ||||||
|  |         //	jc->touch_state.t0Id, jc->touch_state.t1Id, jc->touch_state.t0Down, jc->touch_state.t1Down, | ||||||
|  |         //	jc->touch_state.t0X, jc->touch_state.t0Y, jc->touch_state.t1X, jc->touch_state.t1Y); | ||||||
|  |  | ||||||
|  |         // DS dpad is a hat...  0x08 is released, 0=N, 1=NE, 2=E, 3=SE, 4=S, 5=SW, 6=W, 7=NW | ||||||
|  |         // http://eleccelerator.com/wiki/index.php?title=DualShock_4 | ||||||
|  |         uint8_t hat = packet[indexOffset + 7] & 0x0f; | ||||||
|  |  | ||||||
|  |         if ((hat > 2) & (hat < 6)) jc->simple_state.buttons |= JSMASK_DOWN; // down = SE | S | SW | ||||||
|  |         if ((hat == 7) | (hat < 2)) jc->simple_state.buttons |= JSMASK_UP; // up = N | NE | NW | ||||||
|  |         if ((hat > 0) & (hat < 4)) jc->simple_state.buttons |= JSMASK_RIGHT; // right = NE | E | SE | ||||||
|  |         if ((hat > 4) & (hat < 8)) jc->simple_state.buttons |= JSMASK_LEFT; // left = SW | W | NW | ||||||
|  |  | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 7] >> 4) << JSOFFSET_W) & JSMASK_W; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 7] >> 7) << JSOFFSET_N) & JSMASK_N; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 7] >> 5) << JSOFFSET_S) & JSMASK_S; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 7] >> 6) << JSOFFSET_E) & JSMASK_E; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 8] >> 6) << JSOFFSET_LCLICK) & JSMASK_LCLICK; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 8] >> 7) << JSOFFSET_RCLICK) & JSMASK_RCLICK; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 8] >> 5) << JSOFFSET_OPTIONS) & JSMASK_OPTIONS; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 8] >> 4) << JSOFFSET_SHARE) & JSMASK_SHARE; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 8] >> 1) << JSOFFSET_R) & JSMASK_R; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 8]) << JSOFFSET_L) & JSMASK_L; | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 9]) << JSOFFSET_PS) & JSMASK_PS; | ||||||
|  |         // The DS5 has a mute button that is normally ignored on PC. We can use this. | ||||||
|  |         jc->simple_state.buttons |= ((int) (packet[indexOffset + 9] >> 2) << JSOFFSET_MIC) & JSMASK_MIC; | ||||||
|  |         jc->simple_state.buttons |= | ||||||
|  |                 ((int) (packet[indexOffset + 9] >> 1) << JSOFFSET_TOUCHPAD_CLICK) & JSMASK_TOUCHPAD_CLICK; | ||||||
|  |         //jc->btns.zr = (packet[indexOffset+6] >> 3) & 1; | ||||||
|  |         //jc->btns.zl = (packet[indexOffset+6] >> 2) & 1; | ||||||
|  |         jc->simple_state.rTrigger = packet[indexOffset + 5] / 255.0f; | ||||||
|  |         jc->simple_state.lTrigger = packet[indexOffset + 4] / 255.0f; | ||||||
|  |  | ||||||
|  |         if (jc->simple_state.rTrigger > 0.0) jc->simple_state.buttons |= JSMASK_ZR; | ||||||
|  |         if (jc->simple_state.lTrigger > 0.0) jc->simple_state.buttons |= JSMASK_ZL; | ||||||
|  |  | ||||||
|  |             uint16_t stick_x = packet[indexOffset + 0]; | ||||||
|  |             uint16_t stick_y = packet[indexOffset + 1]; | ||||||
|  |  | ||||||
|  | 		stick_y = 255 - stick_y; | ||||||
|  |  | ||||||
|  | 		uint16_t stick2_x = packet[indexOffset + 2]; | ||||||
|  | 		uint16_t stick2_y = packet[indexOffset + 3]; | ||||||
|  | 		stick2_y = 255 - stick2_y; | ||||||
|  |  | ||||||
|  | 		jc->simple_state.stickLX = (std::fmin)(1.0f, (stick_x - 127.0f) / 127.0f); | ||||||
|  | 		jc->simple_state.stickLY = (std::fmin)(1.0f, (stick_y - 127.0f) / 127.0f); | ||||||
|  | 		jc->simple_state.stickRX = (std::fmin)(1.0f, (stick2_x - 127.0f) / 127.0f); | ||||||
|  | 		jc->simple_state.stickRY = (std::fmin)(1.0f, (stick2_y - 127.0f) / 127.0f); | ||||||
|  |  | ||||||
|  | 		jc->modifying_lock.lock(); | ||||||
|  | 		jc->push_sensor_samples(imu_state.gyroX, imu_state.gyroY, imu_state.gyroZ, | ||||||
|  | 				imu_state.accelX, imu_state.accelY, imu_state.accelZ, jc->delta_time); | ||||||
|  |  | ||||||
|  | 		jc->get_calibrated_gyro(imu_state.gyroX, imu_state.gyroY, imu_state.gyroZ); | ||||||
|  | 		jc->modifying_lock.unlock(); | ||||||
|  |  | ||||||
|  | 		jc->imu_state = imu_state; | ||||||
|  |  | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// most of this JoyCon and Pro Controller stuff is adapted from MFosse's Joycon driver. | ||||||
|  |  | ||||||
|  | 	// bluetooth button pressed packet: | ||||||
|  | 	if (packet[0] == 0x3F) { | ||||||
|  |  | ||||||
|  | 		//uint16_t old_buttons = jc->buttons; | ||||||
|  | 		//int8_t old_dstick = jc->dstick; | ||||||
|  |  | ||||||
|  | 		jc->dstick = packet[3]; | ||||||
|  | 		// todo: get button states here aswell: | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	int buttons_pressed = 0; | ||||||
|  |  | ||||||
|  | 	// input update packet: | ||||||
|  | 	// 0x21 is just buttons, 0x30 includes gyro, 0x31 includes NFC (large packet size) | ||||||
|  | 	if (packet[0] == 0x21 || packet[0] == 0x30 || packet[0] == 0x31) { | ||||||
|  |  | ||||||
|  | 		// offset for usb or bluetooth data: | ||||||
|  | 		/*int offset = settings.usingBluetooth ? 0 : 10;*/ | ||||||
|  | 		int offset = 0; | ||||||
|  | 		//int offset = !jc->is_usb ? 0 : 10; | ||||||
|  |  | ||||||
|  | 		uint8_t *btn_data = packet + offset + 3; | ||||||
|  |  | ||||||
|  | 		// get button states: | ||||||
|  | 		{ | ||||||
|  | 			uint16_t states = 0; | ||||||
|  | 			uint16_t states2 = 0; | ||||||
|  |  | ||||||
|  | 			// Left JoyCon: | ||||||
|  | 			if (jc->left_right == 1) { | ||||||
|  | 				states = (btn_data[1] << 8) | (btn_data[2] & 0xFF); | ||||||
|  | 				// Right JoyCon: | ||||||
|  | 			} | ||||||
|  | 			else if (jc->left_right == 2) { | ||||||
|  | 				states = (btn_data[1] << 8) | (btn_data[0] & 0xFF); | ||||||
|  | 				// Pro Controller: | ||||||
|  | 			} | ||||||
|  | 			else if (jc->left_right == 3) { | ||||||
|  | 				states = (btn_data[1] << 8) | (btn_data[2] & 0xFF); | ||||||
|  | 				states2 = (btn_data[1] << 8) | (btn_data[0] & 0xFF); | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			buttons_pressed = states; | ||||||
|  | 			// Pro Controller: | ||||||
|  | 			if (jc->left_right == 3) { | ||||||
|  | 				buttons_pressed |= states2 << 16; | ||||||
|  |  | ||||||
|  | 				// fix some non-sense the Pro Controller does | ||||||
|  | 				// clear nth bit | ||||||
|  | 				//num &= ~(1UL << n); | ||||||
|  | 				buttons_pressed &= ~(1L << 9); | ||||||
|  | 				buttons_pressed &= ~(1L << 12); | ||||||
|  | 				buttons_pressed &= ~(1L << 14); | ||||||
|  |  | ||||||
|  | 				buttons_pressed &= ~(1UL << (8 + 16)); | ||||||
|  | 				buttons_pressed &= ~(1UL << (11 + 16)); | ||||||
|  | 				buttons_pressed &= ~(1UL << (13 + 16)); | ||||||
|  | 			} | ||||||
|  | 			else if (jc->left_right == 2) { | ||||||
|  | 				buttons_pressed = buttons_pressed << 16; | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// get stick data: | ||||||
|  | 		uint8_t *stick_data = packet + offset; | ||||||
|  | 		if (jc->left_right == 1) { | ||||||
|  | 			stick_data += 6; | ||||||
|  | 		} | ||||||
|  | 		else if (jc->left_right == 2) { | ||||||
|  | 			stick_data += 9; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		uint16_t stick_x = stick_data[0] | ((stick_data[1] & 0xF) << 8); | ||||||
|  | 		uint16_t stick_y = (stick_data[1] >> 4) | (stick_data[2] << 4); | ||||||
|  |  | ||||||
|  | 		// use calibration data: | ||||||
|  | 		if (jc->left_right == 1) { | ||||||
|  | 			jc->CalcAnalogStick2(jc->simple_state.stickLX, jc->simple_state.stickLY, | ||||||
|  | 				stick_x, | ||||||
|  | 				stick_y, | ||||||
|  | 				jc->stick_cal_x_l, | ||||||
|  | 				jc->stick_cal_y_l); | ||||||
|  | 		} | ||||||
|  | 		else if (jc->left_right == 2) { | ||||||
|  | 			jc->CalcAnalogStick2(jc->simple_state.stickRX, jc->simple_state.stickRY, | ||||||
|  | 				stick_x, | ||||||
|  | 				stick_y, | ||||||
|  | 				jc->stick_cal_x_r, | ||||||
|  | 				jc->stick_cal_y_r); | ||||||
|  | 		} | ||||||
|  | 		else if (jc->left_right == 3) { | ||||||
|  | 			// pro controller | ||||||
|  | 			stick_data += 6; | ||||||
|  | 			//printf("%d, %d\n", | ||||||
|  | 			//	jc->stick_cal_x_l, | ||||||
|  | 			//	jc->stick_cal_y_l); | ||||||
|  | 			uint16_t stick_x = stick_data[0] | ((stick_data[1] & 0xF) << 8); | ||||||
|  | 			uint16_t stick_y = (stick_data[1] >> 4) | (stick_data[2] << 4); | ||||||
|  | 			jc->CalcAnalogStick2(jc->simple_state.stickLX, jc->simple_state.stickLY, | ||||||
|  | 				stick_x, | ||||||
|  | 				stick_y, | ||||||
|  | 				jc->stick_cal_x_l, | ||||||
|  | 				jc->stick_cal_y_l); | ||||||
|  | 			stick_data += 3; | ||||||
|  | 			uint16_t stick_x2 = stick_data[0] | ((stick_data[1] & 0xF) << 8); | ||||||
|  | 			uint16_t stick_y2 = (stick_data[1] >> 4) | (stick_data[2] << 4); | ||||||
|  | 			jc->CalcAnalogStick2(jc->simple_state.stickRX, jc->simple_state.stickRY, | ||||||
|  | 				stick_x2, | ||||||
|  | 				stick_y2, | ||||||
|  | 				jc->stick_cal_x_r, | ||||||
|  | 				jc->stick_cal_y_r); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		jc->battery = (stick_data[1] & 0xF0) >> 4; | ||||||
|  | 		//printf("JoyCon battery: %d\n", jc->battery); | ||||||
|  |  | ||||||
|  | 		// Accelerometer: | ||||||
|  | 		// Accelerometer data is absolute | ||||||
|  | 		{ | ||||||
|  | 			// get accelerometer X: | ||||||
|  | 			float accelSampleZ = (float)uint16_to_int16(packet[13] | (packet[14] << 8) & 0xFF00) * jc->acc_cal_coeff[0]; | ||||||
|  | 			float accelSampleX = (float)uint16_to_int16(packet[15] | (packet[16] << 8) & 0xFF00) * jc->acc_cal_coeff[1]; | ||||||
|  | 			float accelSampleY = (float)uint16_to_int16(packet[17] | (packet[18] << 8) & 0xFF00) * jc->acc_cal_coeff[2]; | ||||||
|  | 			float gyroSampleX = (float)uint16_to_int16(packet[19] | (packet[20] << 8) & 0xFF00) * jc->gyro_cal_coeff[0]; | ||||||
|  | 			float gyroSampleY = (float)uint16_to_int16(packet[21] | (packet[22] << 8) & 0xFF00) * jc->gyro_cal_coeff[1]; | ||||||
|  | 			float gyroSampleZ = (float)uint16_to_int16(packet[23] | (packet[24] << 8) & 0xFF00) * jc->gyro_cal_coeff[2]; | ||||||
|  |  | ||||||
|  | 			if (gyroSampleX == 0.f && gyroSampleY == 0.f && gyroSampleZ == 0.f && accelSampleX == 0.f && accelSampleY == 0.f && accelSampleZ == 0.f) | ||||||
|  | 			{ | ||||||
|  | 				// all zero? | ||||||
|  | 				hasIMU = false; | ||||||
|  | 			} | ||||||
|  |  | ||||||
|  | 			//jc->push_sensor_samples(accelSampleX, accelSampleY, accelSampleZ, gyroSampleX, gyroSampleY, gyroSampleZ); | ||||||
|  | 			float accelX = accelSampleX; | ||||||
|  | 			float accelY = accelSampleY; | ||||||
|  | 			float accelZ = accelSampleZ; | ||||||
|  | 			float totalGyroX = gyroSampleX - jc->sensor_cal[1][0]; | ||||||
|  | 			float totalGyroY = gyroSampleY - jc->sensor_cal[1][1]; | ||||||
|  | 			float totalGyroZ = gyroSampleZ - jc->sensor_cal[1][2]; | ||||||
|  | 			// each packet actually has 3 samples worth of data, so collect sample 2 | ||||||
|  | 			accelSampleZ = (float)uint16_to_int16(packet[25] | (packet[26] << 8) & 0xFF00) * jc->acc_cal_coeff[0]; | ||||||
|  | 			accelSampleX = (float)uint16_to_int16(packet[27] | (packet[28] << 8) & 0xFF00) * jc->acc_cal_coeff[1]; | ||||||
|  | 			accelSampleY = (float)uint16_to_int16(packet[29] | (packet[30] << 8) & 0xFF00) * jc->acc_cal_coeff[2]; | ||||||
|  | 			gyroSampleX = (float)uint16_to_int16(packet[31] | (packet[32] << 8) & 0xFF00) * jc->gyro_cal_coeff[0]; | ||||||
|  | 			gyroSampleY = (float)uint16_to_int16(packet[33] | (packet[34] << 8) & 0xFF00) * jc->gyro_cal_coeff[1]; | ||||||
|  | 			gyroSampleZ = (float)uint16_to_int16(packet[35] | (packet[36] << 8) & 0xFF00) * jc->gyro_cal_coeff[2]; | ||||||
|  | 			//jc->push_sensor_samples(accelSampleX, accelSampleY, accelSampleZ, gyroSampleX, gyroSampleY, gyroSampleZ); | ||||||
|  | 			accelX += accelSampleX; | ||||||
|  | 			accelY += accelSampleY; | ||||||
|  | 			accelZ += accelSampleZ; | ||||||
|  | 			totalGyroX += gyroSampleX - jc->sensor_cal[1][0]; | ||||||
|  | 			totalGyroY += gyroSampleY - jc->sensor_cal[1][1]; | ||||||
|  | 			totalGyroZ += gyroSampleZ - jc->sensor_cal[1][2]; | ||||||
|  | 			// ... and sample 3 | ||||||
|  | 			accelSampleZ = (float)uint16_to_int16(packet[37] | (packet[38] << 8) & 0xFF00) * jc->acc_cal_coeff[0]; | ||||||
|  | 			accelSampleX = (float)uint16_to_int16(packet[39] | (packet[40] << 8) & 0xFF00) * jc->acc_cal_coeff[1]; | ||||||
|  | 			accelSampleY = (float)uint16_to_int16(packet[41] | (packet[42] << 8) & 0xFF00) * jc->acc_cal_coeff[2]; | ||||||
|  | 			gyroSampleX = (float)uint16_to_int16(packet[43] | (packet[44] << 8) & 0xFF00) * jc->gyro_cal_coeff[0]; | ||||||
|  | 			gyroSampleY = (float)uint16_to_int16(packet[45] | (packet[46] << 8) & 0xFF00) * jc->gyro_cal_coeff[1]; | ||||||
|  | 			gyroSampleZ = (float)uint16_to_int16(packet[47] | (packet[48] << 8) & 0xFF00) * jc->gyro_cal_coeff[2]; | ||||||
|  | 			//jc->push_sensor_samples(accelSampleX, accelSampleY, accelSampleZ, gyroSampleX, gyroSampleY, gyroSampleZ); | ||||||
|  | 			accelX += accelSampleX; | ||||||
|  | 			accelY += accelSampleY; | ||||||
|  | 			accelZ += accelSampleZ; | ||||||
|  | 			totalGyroX += gyroSampleX - jc->sensor_cal[1][0]; | ||||||
|  | 			totalGyroY += gyroSampleY - jc->sensor_cal[1][1]; | ||||||
|  | 			totalGyroZ += gyroSampleZ - jc->sensor_cal[1][2]; | ||||||
|  | 			// average the 3 samples | ||||||
|  | 			accelX /= 3; | ||||||
|  | 			accelY /= 3; | ||||||
|  | 			accelZ /= 3; | ||||||
|  | 			totalGyroX /= 3; | ||||||
|  | 			totalGyroY /= 3; | ||||||
|  | 			totalGyroZ /= 3; | ||||||
|  | 			imu_state.accelX = -accelX; | ||||||
|  | 			imu_state.accelY = accelY; | ||||||
|  | 			imu_state.accelZ = -accelZ; | ||||||
|  | 			imu_state.gyroX = -totalGyroY; | ||||||
|  | 			imu_state.gyroY = totalGyroZ; | ||||||
|  | 			imu_state.gyroZ = totalGyroX; | ||||||
|  |  | ||||||
|  | 			//printf("Switch accel: %.4f, %.4f, %.4f\n", imu_state.accelX, imu_state.accelY, imu_state.accelZ); | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	// handle buttons | ||||||
|  | 	{ | ||||||
|  | 		// left: | ||||||
|  | 		if (jc->left_right == 1) { | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 1) << JSOFFSET_UP) & JSMASK_UP; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed) << JSOFFSET_DOWN) & JSMASK_DOWN; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 3) << JSOFFSET_LEFT) & JSMASK_LEFT; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 2) << JSOFFSET_RIGHT) & JSMASK_RIGHT; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 11) << JSOFFSET_LCLICK) & JSMASK_LCLICK; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 8) << JSOFFSET_MINUS) & JSMASK_MINUS; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 6) << JSOFFSET_L) & JSMASK_L; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 13) << JSOFFSET_CAPTURE) & JSMASK_CAPTURE; | ||||||
|  | 			jc->simple_state.lTrigger = (float)((buttons_pressed >> 7) & 1); | ||||||
|  | 			jc->simple_state.buttons |= ((int)(jc->simple_state.lTrigger) << JSOFFSET_ZL) & JSMASK_ZL; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 5) << JSOFFSET_SL) & JSMASK_SL; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 4) << JSOFFSET_SR) & JSMASK_SR; | ||||||
|  |  | ||||||
|  | 			// just need to negate gyroZ | ||||||
|  | 			imu_state.gyroZ = -imu_state.gyroZ; | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// right: | ||||||
|  | 		if (jc->left_right == 2) { | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 16) << JSOFFSET_W) & JSMASK_W; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 17) << JSOFFSET_N) & JSMASK_N; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 18) << JSOFFSET_S) & JSMASK_S; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 19) << JSOFFSET_E) & JSMASK_E; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 26) << JSOFFSET_RCLICK) & JSMASK_RCLICK; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 25) << JSOFFSET_PLUS) & JSMASK_PLUS; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 22) << JSOFFSET_R) & JSMASK_R; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 28) << JSOFFSET_HOME) & JSMASK_HOME; | ||||||
|  | 			jc->simple_state.rTrigger = (float)((buttons_pressed >> 23) & 1); | ||||||
|  | 			jc->simple_state.buttons |= ((int)(jc->simple_state.rTrigger) << JSOFFSET_ZR) & JSMASK_ZR; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 21) << JSOFFSET_SL) & JSMASK_SL; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 20) << JSOFFSET_SR) & JSMASK_SR; | ||||||
|  |  | ||||||
|  | 			// for some reason we need to negate x and y, and z on the right joycon | ||||||
|  | 			imu_state.gyroX = -imu_state.gyroX; | ||||||
|  | 			imu_state.gyroY = -imu_state.gyroY; | ||||||
|  | 			imu_state.gyroZ = -imu_state.gyroZ; | ||||||
|  |  | ||||||
|  | 			imu_state.accelX = -imu_state.accelX; | ||||||
|  | 			imu_state.accelY = -imu_state.accelY; | ||||||
|  |  | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// pro controller: | ||||||
|  | 		if (jc->left_right == 3) { | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 1) << JSOFFSET_UP) & JSMASK_UP; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed) << JSOFFSET_DOWN) & JSMASK_DOWN; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 3) << JSOFFSET_LEFT) & JSMASK_LEFT; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 2) << JSOFFSET_RIGHT) & JSMASK_RIGHT; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 16) << JSOFFSET_W) & JSMASK_W; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 17) << JSOFFSET_N) & JSMASK_N; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 18) << JSOFFSET_S) & JSMASK_S; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 19) << JSOFFSET_E) & JSMASK_E; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 11) << JSOFFSET_LCLICK) & JSMASK_LCLICK; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 26) << JSOFFSET_RCLICK) & JSMASK_RCLICK; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 25) << JSOFFSET_PLUS) & JSMASK_PLUS; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 8) << JSOFFSET_MINUS) & JSMASK_MINUS; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 22) << JSOFFSET_R) & JSMASK_R; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 6) << JSOFFSET_L) & JSMASK_L; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 28) << JSOFFSET_HOME) & JSMASK_HOME; | ||||||
|  | 			jc->simple_state.buttons |= ((buttons_pressed >> 13) << JSOFFSET_CAPTURE) & JSMASK_CAPTURE; | ||||||
|  | 			jc->simple_state.rTrigger = (float)((buttons_pressed >> 23) & 1); | ||||||
|  | 			jc->simple_state.lTrigger = (float)((buttons_pressed >> 7) & 1); | ||||||
|  | 			jc->simple_state.buttons |= ((int)(jc->simple_state.lTrigger) << JSOFFSET_ZL) & JSMASK_ZL; | ||||||
|  | 			jc->simple_state.buttons |= ((int)(jc->simple_state.rTrigger) << JSOFFSET_ZR) & JSMASK_ZR; | ||||||
|  |  | ||||||
|  | 			// just need to negate gyroZ | ||||||
|  | 			imu_state.gyroZ = -imu_state.gyroZ; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	jc->modifying_lock.lock(); | ||||||
|  | 	jc->push_sensor_samples(imu_state.gyroX, imu_state.gyroY, imu_state.gyroZ, | ||||||
|  | 		imu_state.accelX, imu_state.accelY, imu_state.accelZ, jc->delta_time); | ||||||
|  |  | ||||||
|  | 	jc->get_calibrated_gyro(imu_state.gyroX, imu_state.gyroY, imu_state.gyroZ); | ||||||
|  | 	jc->modifying_lock.unlock(); | ||||||
|  |  | ||||||
|  | 	jc->imu_state = imu_state; | ||||||
|  |  | ||||||
|  | 	return true; | ||||||
|  | } | ||||||
							
								
								
									
										1564
									
								
								project/dependencies/JoyShockLibrary/JoyShock.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1564
									
								
								project/dependencies/JoyShockLibrary/JoyShock.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										1164
									
								
								project/dependencies/JoyShockLibrary/JoyShockLibrary.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1164
									
								
								project/dependencies/JoyShockLibrary/JoyShockLibrary.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										248
									
								
								project/dependencies/JoyShockLibrary/JoyShockLibrary.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										248
									
								
								project/dependencies/JoyShockLibrary/JoyShockLibrary.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,248 @@ | |||||||
|  | // JoyShockLibrary.h - Contains declarations of functions | ||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #if _MSC_VER // this is defined when compiling with Visual Studio | ||||||
|  | #define JOY_SHOCK_API __declspec(dllexport) // Visual Studio needs annotating exported functions with this | ||||||
|  | #else | ||||||
|  | #define JOY_SHOCK_API // XCode does not need annotating exported functions, so define is empty | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #define JS_TYPE_JOYCON_LEFT 1 | ||||||
|  | #define JS_TYPE_JOYCON_RIGHT 2 | ||||||
|  | #define JS_TYPE_PRO_CONTROLLER 3 | ||||||
|  | #define JS_TYPE_DS4 4 | ||||||
|  | #define JS_TYPE_DS 5 | ||||||
|  |  | ||||||
|  | #define JS_SPLIT_TYPE_LEFT 1 | ||||||
|  | #define JS_SPLIT_TYPE_RIGHT 2 | ||||||
|  | #define JS_SPLIT_TYPE_FULL 3 | ||||||
|  |  | ||||||
|  | #define JSMASK_UP 0x00001 | ||||||
|  | #define JSMASK_DOWN 0x00002 | ||||||
|  | #define JSMASK_LEFT 0x00004 | ||||||
|  | #define JSMASK_RIGHT 0x00008 | ||||||
|  | #define JSMASK_PLUS 0x00010 | ||||||
|  | #define JSMASK_OPTIONS 0x00010 | ||||||
|  | #define JSMASK_MINUS 0x00020 | ||||||
|  | #define JSMASK_SHARE 0x00020 | ||||||
|  | #define JSMASK_LCLICK 0x00040 | ||||||
|  | #define JSMASK_RCLICK 0x00080 | ||||||
|  | #define JSMASK_L 0x00100 | ||||||
|  | #define JSMASK_R 0x00200 | ||||||
|  | #define JSMASK_ZL 0x00400 | ||||||
|  | #define JSMASK_ZR 0x00800 | ||||||
|  | #define JSMASK_S 0x01000 | ||||||
|  | #define JSMASK_E 0x02000 | ||||||
|  | #define JSMASK_W 0x04000 | ||||||
|  | #define JSMASK_N 0x08000 | ||||||
|  | #define JSMASK_HOME 0x10000 | ||||||
|  | #define JSMASK_PS 0x10000 | ||||||
|  | #define JSMASK_CAPTURE 0x20000 | ||||||
|  | #define JSMASK_TOUCHPAD_CLICK 0x20000 | ||||||
|  | #define JSMASK_MIC 0x40000 | ||||||
|  | #define JSMASK_SL 0x40000 | ||||||
|  | #define JSMASK_SR 0x80000 | ||||||
|  |  | ||||||
|  | #define JSOFFSET_UP 0 | ||||||
|  | #define JSOFFSET_DOWN 1 | ||||||
|  | #define JSOFFSET_LEFT 2 | ||||||
|  | #define JSOFFSET_RIGHT 3 | ||||||
|  | #define JSOFFSET_PLUS 4 | ||||||
|  | #define JSOFFSET_OPTIONS 4 | ||||||
|  | #define JSOFFSET_MINUS 5 | ||||||
|  | #define JSOFFSET_SHARE 5 | ||||||
|  | #define JSOFFSET_LCLICK 6 | ||||||
|  | #define JSOFFSET_RCLICK 7 | ||||||
|  | #define JSOFFSET_L 8 | ||||||
|  | #define JSOFFSET_R 9 | ||||||
|  | #define JSOFFSET_ZL 10 | ||||||
|  | #define JSOFFSET_ZR 11 | ||||||
|  | #define JSOFFSET_S 12 | ||||||
|  | #define JSOFFSET_E 13 | ||||||
|  | #define JSOFFSET_W 14 | ||||||
|  | #define JSOFFSET_N 15 | ||||||
|  | #define JSOFFSET_HOME 16 | ||||||
|  | #define JSOFFSET_PS 16 | ||||||
|  | #define JSOFFSET_CAPTURE 17 | ||||||
|  | #define JSOFFSET_TOUCHPAD_CLICK 17 | ||||||
|  | #define JSOFFSET_MIC 18 | ||||||
|  | #define JSOFFSET_SL 18 | ||||||
|  | #define JSOFFSET_SR 19 | ||||||
|  |  | ||||||
|  | // PS5 Player maps for the DS Player Lightbar | ||||||
|  | #define DS5_PLAYER_1 4 | ||||||
|  | #define DS5_PLAYER_2 10 | ||||||
|  | #define DS5_PLAYER_3 21 | ||||||
|  | #define DS5_PLAYER_4 27 | ||||||
|  | #define DS5_PLAYER_5 31 | ||||||
|  |  | ||||||
|  | typedef struct JOY_SHOCK_STATE { | ||||||
|  | 	int buttons = 0; | ||||||
|  | 	float lTrigger = 0.f; | ||||||
|  | 	float rTrigger = 0.f; | ||||||
|  | 	float stickLX = 0.f; | ||||||
|  | 	float stickLY = 0.f; | ||||||
|  | 	float stickRX = 0.f; | ||||||
|  | 	float stickRY = 0.f; | ||||||
|  | } JOY_SHOCK_STATE; | ||||||
|  |  | ||||||
|  | typedef struct IMU_STATE { | ||||||
|  | 	float accelX = 0.f; | ||||||
|  | 	float accelY = 0.f; | ||||||
|  | 	float accelZ = 0.f; | ||||||
|  | 	float gyroX = 0.f; | ||||||
|  | 	float gyroY = 0.f; | ||||||
|  | 	float gyroZ = 0.f; | ||||||
|  | } IMU_STATE; | ||||||
|  |  | ||||||
|  | typedef struct MOTION_STATE { | ||||||
|  | 	float quatW = 0.f; | ||||||
|  | 	float quatX = 0.f; | ||||||
|  | 	float quatY = 0.f; | ||||||
|  | 	float quatZ = 0.f; | ||||||
|  | 	float accelX = 0.f; | ||||||
|  | 	float accelY = 0.f; | ||||||
|  | 	float accelZ = 0.f; | ||||||
|  | 	float gravX = 0.f; | ||||||
|  | 	float gravY = 0.f; | ||||||
|  | 	float gravZ = 0.f; | ||||||
|  | } MOTION_STATE; | ||||||
|  |  | ||||||
|  | typedef struct TOUCH_STATE { | ||||||
|  | 	int t0Id = 0; | ||||||
|  | 	int t1Id = 0; | ||||||
|  | 	bool t0Down = false; | ||||||
|  | 	bool t1Down = false; | ||||||
|  | 	float t0X = 0.f; | ||||||
|  | 	float t0Y = 0.f; | ||||||
|  | 	float t1X = 0.f; | ||||||
|  | 	float t1Y = 0.f; | ||||||
|  | } TOUCH_STATE; | ||||||
|  |  | ||||||
|  | typedef struct JSL_AUTO_CALIBRATION { | ||||||
|  | 	float confidence = 0.f; | ||||||
|  | 	bool autoCalibrationEnabled = false; | ||||||
|  | 	bool isSteady = false; | ||||||
|  | } JSL_AUTO_CALIBRATION; | ||||||
|  |  | ||||||
|  | typedef struct JSL_SETTINGS { | ||||||
|  | 	int gyroSpace = 0; | ||||||
|  | 	int colour = 0; | ||||||
|  | 	int playerNumber = 0; | ||||||
|  | 	int controllerType = 0; | ||||||
|  | 	int splitType = 0; | ||||||
|  | 	bool isCalibrating = false; | ||||||
|  | 	bool autoCalibrationEnabled = false; | ||||||
|  | 	bool isConnected = false; | ||||||
|  | } JSL_SETTINGS; | ||||||
|  |  | ||||||
|  | extern "C" JOY_SHOCK_API int JslConnectDevices(); | ||||||
|  | extern "C" JOY_SHOCK_API int JslGetConnectedDeviceHandles(int* deviceHandleArray, int size); | ||||||
|  | extern "C" JOY_SHOCK_API void JslDisconnectAndDisposeAll(); | ||||||
|  | extern "C" JOY_SHOCK_API bool JslStillConnected(int deviceId); | ||||||
|  |  | ||||||
|  | // get buttons as bits in the following order, using North South East West to name face buttons to avoid ambiguity between Xbox and Nintendo layouts: | ||||||
|  | // 0x00001: up | ||||||
|  | // 0x00002: down | ||||||
|  | // 0x00004: left | ||||||
|  | // 0x00008: right | ||||||
|  | // 0x00010: plus | ||||||
|  | // 0x00020: minus | ||||||
|  | // 0x00040: left stick click | ||||||
|  | // 0x00080: right stick click | ||||||
|  | // 0x00100: L | ||||||
|  | // 0x00200: R | ||||||
|  | // ZL and ZR are reported as analogue inputs (GetLeftTrigger, GetRightTrigger), because DS4 and XBox controllers use analogue triggers, but we also have them as raw buttons | ||||||
|  | // 0x00400: ZL | ||||||
|  | // 0x00800: ZR | ||||||
|  | // 0x01000: S | ||||||
|  | // 0x02000: E | ||||||
|  | // 0x04000: W | ||||||
|  | // 0x08000: N | ||||||
|  | // 0x10000: home / PS | ||||||
|  | // 0x20000: capture / touchpad-click | ||||||
|  | // 0x40000: SL | ||||||
|  | // 0x80000: SR | ||||||
|  | // These are the best way to get all the buttons/triggers/sticks, gyro/accelerometer (IMU), orientation/acceleration/gravity (Motion), or touchpad | ||||||
|  | extern "C" JOY_SHOCK_API JOY_SHOCK_STATE JslGetSimpleState(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API IMU_STATE JslGetIMUState(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API MOTION_STATE JslGetMotionState(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API TOUCH_STATE JslGetTouchState(int deviceId, bool previous = false); | ||||||
|  | extern "C" JOY_SHOCK_API bool JslGetTouchpadDimension(int deviceId, int &sizeX, int &sizeY); | ||||||
|  |  | ||||||
|  | extern "C" JOY_SHOCK_API int JslGetButtons(int deviceId); | ||||||
|  |  | ||||||
|  | // get thumbsticks | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetLeftX(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetLeftY(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetRightX(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetRightY(int deviceId); | ||||||
|  |  | ||||||
|  | // get triggers. Switch controllers don't have analogue triggers, but will report 0.0 or 1.0 so they can be used in the same way as others | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetLeftTrigger(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetRightTrigger(int deviceId); | ||||||
|  |  | ||||||
|  | // get gyro | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetGyroX(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetGyroY(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetGyroZ(int deviceId); | ||||||
|  |  | ||||||
|  | // get accumulated average gyro since this function was last called or last flushed values | ||||||
|  | extern "C" JOY_SHOCK_API void JslGetAndFlushAccumulatedGyro(int deviceId, float& gyroX, float& gyroY, float& gyroZ); | ||||||
|  |  | ||||||
|  | // set gyro space. JslGetGyro*, JslGetAndFlushAccumulatedGyro, JslGetIMUState, and the IMU_STATEs reported in the callback functions will use one of 3 transformations: | ||||||
|  | // 0 = local space -> no transformation is done on gyro input | ||||||
|  | // 1 = world space -> gyro input is transformed based on the calculated gravity direction to account for the player's preferred controller orientation | ||||||
|  | // 2 = player space -> a simple combination of local and world space that is as adaptive as world space but is as robust as local space | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetGyroSpace(int deviceId, int gyroSpace); | ||||||
|  |  | ||||||
|  | // get accelerometor | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetAccelX(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetAccelY(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetAccelZ(int deviceId); | ||||||
|  |  | ||||||
|  | // get touchpad | ||||||
|  | extern "C" JOY_SHOCK_API int JslGetTouchId(int deviceId, bool secondTouch = false); | ||||||
|  | extern "C" JOY_SHOCK_API bool JslGetTouchDown(int deviceId, bool secondTouch = false); | ||||||
|  |  | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetTouchX(int deviceId, bool secondTouch = false); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetTouchY(int deviceId, bool secondTouch = false); | ||||||
|  |  | ||||||
|  | // analog parameters have different resolutions depending on device | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetStickStep(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetTriggerStep(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetPollRate(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API float JslGetTimeSinceLastUpdate(int deviceId); | ||||||
|  |  | ||||||
|  | // calibration | ||||||
|  | extern "C" JOY_SHOCK_API void JslResetContinuousCalibration(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API void JslStartContinuousCalibration(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API void JslPauseContinuousCalibration(int deviceId); | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetAutomaticCalibration(int deviceId, bool enabled); | ||||||
|  | extern "C" JOY_SHOCK_API void JslGetCalibrationOffset(int deviceId, float& xOffset, float& yOffset, float& zOffset); | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetCalibrationOffset(int deviceId, float xOffset, float yOffset, float zOffset); | ||||||
|  | extern "C" JOY_SHOCK_API JSL_AUTO_CALIBRATION JslGetAutoCalibrationStatus(int deviceId); | ||||||
|  |  | ||||||
|  | // this function will get called for each input event from each controller | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetCallback(void(*callback)(int, JOY_SHOCK_STATE, JOY_SHOCK_STATE, IMU_STATE, IMU_STATE, float)); | ||||||
|  | // this function will get called for each input event, even if touch data didn't update | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetTouchCallback(void(*callback)(int, TOUCH_STATE, TOUCH_STATE, float)); | ||||||
|  | // this function will get called for each device when it is newly connected | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetConnectCallback(void(*callback)(int)); | ||||||
|  | // this function will get called for each device when it is disconnected | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetDisconnectCallback(void(*callback)(int, bool)); | ||||||
|  |  | ||||||
|  | // super-getter for reading a whole lot of state at once | ||||||
|  | extern "C" JOY_SHOCK_API JSL_SETTINGS JslGetControllerInfoAndSettings(int deviceId); | ||||||
|  | // what kind of controller is this? | ||||||
|  | extern "C" JOY_SHOCK_API int JslGetControllerType(int deviceId); | ||||||
|  | // is this a left, right, or full controller? | ||||||
|  | extern "C" JOY_SHOCK_API int JslGetControllerSplitType(int deviceId); | ||||||
|  | // what colour is the controller (not all controllers support this; those that don't will report white) | ||||||
|  | extern "C" JOY_SHOCK_API int JslGetControllerColour(int deviceId); | ||||||
|  | // set controller light colour (not all controllers have a light whose colour can be set, but that just means nothing will be done when this is called -- no harm) | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetLightColour(int deviceId, int colour); | ||||||
|  | // set controller rumble | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetRumble(int deviceId, int smallRumble, int bigRumble); | ||||||
|  | // set controller player number indicator (not all controllers have a number indicator which can be set, but that just means nothing will be done when this is called -- no harm) | ||||||
|  | extern "C" JOY_SHOCK_API void JslSetPlayerNumber(int deviceId, int number); | ||||||
							
								
								
									
										391
									
								
								project/dependencies/JoyShockLibrary/hidapi/hidapi.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										391
									
								
								project/dependencies/JoyShockLibrary/hidapi/hidapi.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,391 @@ | |||||||
|  | /******************************************************* | ||||||
|  |  HIDAPI - Multi-Platform library for | ||||||
|  |  communication with HID devices. | ||||||
|  |  | ||||||
|  |  Alan Ott | ||||||
|  |  Signal 11 Software | ||||||
|  |  | ||||||
|  |  8/22/2009 | ||||||
|  |  | ||||||
|  |  Copyright 2009, All Rights Reserved. | ||||||
|  |  | ||||||
|  |  At the discretion of the user of this library, | ||||||
|  |  this software may be licensed under the terms of the | ||||||
|  |  GNU General Public License v3, a BSD-Style license, or the | ||||||
|  |  original HIDAPI license as outlined in the LICENSE.txt, | ||||||
|  |  LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt | ||||||
|  |  files located at the root of the source distribution. | ||||||
|  |  These files may also be found in the public source | ||||||
|  |  code repository located at: | ||||||
|  |         http://github.com/signal11/hidapi . | ||||||
|  | ********************************************************/ | ||||||
|  |  | ||||||
|  | /** @file | ||||||
|  |  * @defgroup API hidapi API | ||||||
|  |  */ | ||||||
|  |  | ||||||
|  | #ifndef HIDAPI_H__ | ||||||
|  | #define HIDAPI_H__ | ||||||
|  |  | ||||||
|  | #include <wchar.h> | ||||||
|  |  | ||||||
|  | #ifdef _WIN32 | ||||||
|  |       #define HID_API_EXPORT __declspec(dllexport) | ||||||
|  |       #define HID_API_CALL | ||||||
|  | #else | ||||||
|  |       #define HID_API_EXPORT /**< API export macro */ | ||||||
|  |       #define HID_API_CALL /**< API call macro */ | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #define HID_API_EXPORT_CALL HID_API_EXPORT HID_API_CALL /**< API export and call macro*/ | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | extern "C" { | ||||||
|  | #endif | ||||||
|  | 		struct hid_device_; | ||||||
|  | 		typedef struct hid_device_ hid_device; /**< opaque hidapi structure */ | ||||||
|  |  | ||||||
|  | 		/** hidapi info structure */ | ||||||
|  | 		struct hid_device_info { | ||||||
|  | 			/** Platform-specific device path */ | ||||||
|  | 			char *path; | ||||||
|  | 			/** Device Vendor ID */ | ||||||
|  | 			unsigned short vendor_id; | ||||||
|  | 			/** Device Product ID */ | ||||||
|  | 			unsigned short product_id; | ||||||
|  | 			/** Serial Number */ | ||||||
|  | 			wchar_t *serial_number; | ||||||
|  | 			/** Device Release Number in binary-coded decimal, | ||||||
|  | 			    also known as Device Version Number */ | ||||||
|  | 			unsigned short release_number; | ||||||
|  | 			/** Manufacturer String */ | ||||||
|  | 			wchar_t *manufacturer_string; | ||||||
|  | 			/** Product string */ | ||||||
|  | 			wchar_t *product_string; | ||||||
|  | 			/** Usage Page for this Device/Interface | ||||||
|  | 			    (Windows/Mac only). */ | ||||||
|  | 			unsigned short usage_page; | ||||||
|  | 			/** Usage for this Device/Interface | ||||||
|  | 			    (Windows/Mac only).*/ | ||||||
|  | 			unsigned short usage; | ||||||
|  | 			/** The USB interface which this logical device | ||||||
|  | 			    represents. Valid on both Linux implementations | ||||||
|  | 			    in all cases, and valid on the Windows implementation | ||||||
|  | 			    only if the device contains more than one interface. */ | ||||||
|  | 			int interface_number; | ||||||
|  |  | ||||||
|  | 			/** Pointer to the next device */ | ||||||
|  | 			struct hid_device_info *next; | ||||||
|  | 		}; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | 		/** @brief Initialize the HIDAPI library. | ||||||
|  |  | ||||||
|  | 			This function initializes the HIDAPI library. Calling it is not | ||||||
|  | 			strictly necessary, as it will be called automatically by | ||||||
|  | 			hid_enumerate() and any of the hid_open_*() functions if it is | ||||||
|  | 			needed.  This function should be called at the beginning of | ||||||
|  | 			execution however, if there is a chance of HIDAPI handles | ||||||
|  | 			being opened by different threads simultaneously. | ||||||
|  | 			 | ||||||
|  | 			@ingroup API | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns 0 on success and -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT HID_API_CALL hid_init(void); | ||||||
|  |  | ||||||
|  | 		/** @brief Finalize the HIDAPI library. | ||||||
|  |  | ||||||
|  | 			This function frees all of the static data associated with | ||||||
|  | 			HIDAPI. It should be called at the end of execution to avoid | ||||||
|  | 			memory leaks. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  |  | ||||||
|  | 		    @returns | ||||||
|  | 				This function returns 0 on success and -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT HID_API_CALL hid_exit(void); | ||||||
|  |  | ||||||
|  | 		/** @brief Enumerate the HID Devices. | ||||||
|  |  | ||||||
|  | 			This function returns a linked list of all the HID devices | ||||||
|  | 			attached to the system which match vendor_id and product_id. | ||||||
|  | 			If @p vendor_id is set to 0 then any vendor matches. | ||||||
|  | 			If @p product_id is set to 0 then any product matches. | ||||||
|  | 			If @p vendor_id and @p product_id are both set to 0, then | ||||||
|  | 			all HID devices will be returned. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param vendor_id The Vendor ID (VID) of the types of device | ||||||
|  | 				to open. | ||||||
|  | 			@param product_id The Product ID (PID) of the types of | ||||||
|  | 				device to open. | ||||||
|  |  | ||||||
|  | 		    @returns | ||||||
|  | 		    	This function returns a pointer to a linked list of type | ||||||
|  | 		    	struct #hid_device, containing information about the HID devices | ||||||
|  | 		    	attached to the system, or NULL in the case of failure. Free | ||||||
|  | 		    	this linked list by calling hid_free_enumeration(). | ||||||
|  | 		*/ | ||||||
|  | 		struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id); | ||||||
|  |  | ||||||
|  | 		/** @brief Free an enumeration Linked List | ||||||
|  |  | ||||||
|  | 		    This function frees a linked list created by hid_enumerate(). | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 		    @param devs Pointer to a list of struct_device returned from | ||||||
|  | 		    	      hid_enumerate(). | ||||||
|  | 		*/ | ||||||
|  | 		void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs); | ||||||
|  |  | ||||||
|  | 		/** @brief Open a HID device using a Vendor ID (VID), Product ID | ||||||
|  | 			(PID) and optionally a serial number. | ||||||
|  |  | ||||||
|  | 			If @p serial_number is NULL, the first device with the | ||||||
|  | 			specified VID and PID is opened. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param vendor_id The Vendor ID (VID) of the device to open. | ||||||
|  | 			@param product_id The Product ID (PID) of the device to open. | ||||||
|  | 			@param serial_number The Serial Number of the device to open | ||||||
|  | 				               (Optionally NULL). | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns a pointer to a #hid_device object on | ||||||
|  | 				success or NULL on failure. | ||||||
|  | 		*/ | ||||||
|  | 		HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number); | ||||||
|  |  | ||||||
|  | 		/** @brief Open a HID device by its path name. | ||||||
|  |  | ||||||
|  | 			The path name be determined by calling hid_enumerate(), or a | ||||||
|  | 			platform-specific path name can be used (eg: /dev/hidraw0 on | ||||||
|  | 			Linux). | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 		    @param path The path name of the device to open | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns a pointer to a #hid_device object on | ||||||
|  | 				success or NULL on failure. | ||||||
|  | 		*/ | ||||||
|  | 		HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path); | ||||||
|  |  | ||||||
|  | 		/** @brief Write an Output report to a HID device. | ||||||
|  |  | ||||||
|  | 			The first byte of @p data[] must contain the Report ID. For | ||||||
|  | 			devices which only support a single report, this must be set | ||||||
|  | 			to 0x0. The remaining bytes contain the report data. Since | ||||||
|  | 			the Report ID is mandatory, calls to hid_write() will always | ||||||
|  | 			contain one more byte than the report contains. For example, | ||||||
|  | 			if a hid report is 16 bytes long, 17 bytes must be passed to | ||||||
|  | 			hid_write(), the Report ID (or 0x0, for devices with a | ||||||
|  | 			single report), followed by the report data (16 bytes). In | ||||||
|  | 			this example, the length passed in would be 17. | ||||||
|  |  | ||||||
|  | 			hid_write() will send the data on the first OUT endpoint, if | ||||||
|  | 			one exists. If it does not, it will send the data through | ||||||
|  | 			the Control Endpoint (Endpoint 0). | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param data The data to send, including the report number as | ||||||
|  | 				the first byte. | ||||||
|  | 			@param length The length in bytes of the data to send. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns the actual number of bytes written and | ||||||
|  | 				-1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int  HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length); | ||||||
|  |  | ||||||
|  | 		/** @brief Read an Input report from a HID device with timeout. | ||||||
|  |  | ||||||
|  | 			Input reports are returned | ||||||
|  | 			to the host through the INTERRUPT IN endpoint. The first byte will | ||||||
|  | 			contain the Report number if the device uses numbered reports. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param data A buffer to put the read data into. | ||||||
|  | 			@param length The number of bytes to read. For devices with | ||||||
|  | 				multiple reports, make sure to read an extra byte for | ||||||
|  | 				the report number. | ||||||
|  | 			@param milliseconds timeout in milliseconds or -1 for blocking wait. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns the actual number of bytes read and | ||||||
|  | 				-1 on error. If no packet was available to be read within | ||||||
|  | 				the timeout period, this function returns 0. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds); | ||||||
|  |  | ||||||
|  | 		/** @brief Read an Input report from a HID device. | ||||||
|  |  | ||||||
|  | 			Input reports are returned | ||||||
|  | 		    to the host through the INTERRUPT IN endpoint. The first byte will | ||||||
|  | 			contain the Report number if the device uses numbered reports. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param data A buffer to put the read data into. | ||||||
|  | 			@param length The number of bytes to read. For devices with | ||||||
|  | 				multiple reports, make sure to read an extra byte for | ||||||
|  | 				the report number. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns the actual number of bytes read and | ||||||
|  | 				-1 on error. If no packet was available to be read and | ||||||
|  | 				the handle is in non-blocking mode, this function returns 0. | ||||||
|  | 		*/ | ||||||
|  | 		int  HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length); | ||||||
|  |  | ||||||
|  | 		/** @brief Set the device handle to be non-blocking. | ||||||
|  |  | ||||||
|  | 			In non-blocking mode calls to hid_read() will return | ||||||
|  | 			immediately with a value of 0 if there is no data to be | ||||||
|  | 			read. In blocking mode, hid_read() will wait (block) until | ||||||
|  | 			there is data to read before returning. | ||||||
|  |  | ||||||
|  | 			Nonblocking can be turned on and off at any time. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param nonblock enable or not the nonblocking reads | ||||||
|  | 			 - 1 to enable nonblocking | ||||||
|  | 			 - 0 to disable nonblocking. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns 0 on success and -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int  HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock); | ||||||
|  |  | ||||||
|  | 		/** @brief Send a Feature report to the device. | ||||||
|  |  | ||||||
|  | 			Feature reports are sent over the Control endpoint as a | ||||||
|  | 			Set_Report transfer.  The first byte of @p data[] must | ||||||
|  | 			contain the Report ID. For devices which only support a | ||||||
|  | 			single report, this must be set to 0x0. The remaining bytes | ||||||
|  | 			contain the report data. Since the Report ID is mandatory, | ||||||
|  | 			calls to hid_send_feature_report() will always contain one | ||||||
|  | 			more byte than the report contains. For example, if a hid | ||||||
|  | 			report is 16 bytes long, 17 bytes must be passed to | ||||||
|  | 			hid_send_feature_report(): the Report ID (or 0x0, for | ||||||
|  | 			devices which do not use numbered reports), followed by the | ||||||
|  | 			report data (16 bytes). In this example, the length passed | ||||||
|  | 			in would be 17. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param data The data to send, including the report number as | ||||||
|  | 				the first byte. | ||||||
|  | 			@param length The length in bytes of the data to send, including | ||||||
|  | 				the report number. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns the actual number of bytes written and | ||||||
|  | 				-1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length); | ||||||
|  |  | ||||||
|  | 		/** @brief Get a feature report from a HID device. | ||||||
|  |  | ||||||
|  | 			Set the first byte of @p data[] to the Report ID of the | ||||||
|  | 			report to be read.  Make sure to allow space for this | ||||||
|  | 			extra byte in @p data[]. Upon return, the first byte will | ||||||
|  | 			still contain the Report ID, and the report data will | ||||||
|  | 			start in data[1]. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param data A buffer to put the read data into, including | ||||||
|  | 				the Report ID. Set the first byte of @p data[] to the | ||||||
|  | 				Report ID of the report to be read, or set it to zero | ||||||
|  | 				if your device does not use numbered reports. | ||||||
|  | 			@param length The number of bytes to read, including an | ||||||
|  | 				extra byte for the report ID. The buffer can be longer | ||||||
|  | 				than the actual report. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns the number of bytes read plus | ||||||
|  | 				one for the report ID (which is still in the first | ||||||
|  | 				byte), or -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length); | ||||||
|  |  | ||||||
|  | 		/** @brief Close a HID device. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 		*/ | ||||||
|  | 		void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device); | ||||||
|  |  | ||||||
|  | 		/** @brief Get The Manufacturer String from a HID device. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param string A wide string buffer to put the data into. | ||||||
|  | 			@param maxlen The length of the buffer in multiples of wchar_t. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns 0 on success and -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen); | ||||||
|  |  | ||||||
|  | 		/** @brief Get The Product String from a HID device. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param string A wide string buffer to put the data into. | ||||||
|  | 			@param maxlen The length of the buffer in multiples of wchar_t. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns 0 on success and -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen); | ||||||
|  |  | ||||||
|  | 		/** @brief Get The Serial Number String from a HID device. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param string A wide string buffer to put the data into. | ||||||
|  | 			@param maxlen The length of the buffer in multiples of wchar_t. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns 0 on success and -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen); | ||||||
|  |  | ||||||
|  | 		/** @brief Get a string from a HID device, based on its string index. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  | 			@param string_index The index of the string to get. | ||||||
|  | 			@param string A wide string buffer to put the data into. | ||||||
|  | 			@param maxlen The length of the buffer in multiples of wchar_t. | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns 0 on success and -1 on error. | ||||||
|  | 		*/ | ||||||
|  | 		int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen); | ||||||
|  |  | ||||||
|  | 		/** @brief Get a string describing the last error which occurred. | ||||||
|  |  | ||||||
|  | 			@ingroup API | ||||||
|  | 			@param device A device handle returned from hid_open(). | ||||||
|  |  | ||||||
|  | 			@returns | ||||||
|  | 				This function returns a string containing the last error | ||||||
|  | 				which occurred or NULL if none has occurred. | ||||||
|  | 		*/ | ||||||
|  | 		HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device); | ||||||
|  |  | ||||||
|  | #ifdef __cplusplus | ||||||
|  | } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | #endif | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								project/dependencies/JoyShockLibrary/stdafx.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								project/dependencies/JoyShockLibrary/stdafx.cpp
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								project/dependencies/JoyShockLibrary/stdafx.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								project/dependencies/JoyShockLibrary/stdafx.h
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								project/dependencies/JoyShockLibrary/targetver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								project/dependencies/JoyShockLibrary/targetver.h
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										109
									
								
								project/dependencies/JoyShockLibrary/tools.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										109
									
								
								project/dependencies/JoyShockLibrary/tools.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,109 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
|  | #include <chrono> | ||||||
|  | #include <thread> | ||||||
|  | #include <map> | ||||||
|  | #include <string> | ||||||
|  | #include <iostream> | ||||||
|  | #include <fstream> | ||||||
|  | #include <sstream> | ||||||
|  | #include <cstring> | ||||||
|  |  | ||||||
|  | //#include <curl/curl.h> | ||||||
|  |  | ||||||
|  | #pragma warning(disable: 4996) | ||||||
|  |  | ||||||
|  | typedef uint8_t u8; | ||||||
|  | typedef uint16_t u16; | ||||||
|  | typedef uint32_t u32; | ||||||
|  | typedef uint64_t u64; | ||||||
|  | typedef int8_t s8; | ||||||
|  | typedef int16_t s16; | ||||||
|  | typedef int32_t s32; | ||||||
|  | typedef int64_t s64; | ||||||
|  |  | ||||||
|  | int16_t unsignedToSigned16(uint16_t n) { | ||||||
|  | 	uint16_t A = n; | ||||||
|  | 	uint16_t B = 0xFFFF - A; | ||||||
|  | 	if (A < B) { | ||||||
|  | 		return (int16_t)A; | ||||||
|  | 	} else { | ||||||
|  | 		return (int16_t)(-1 * B); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int16_t uint16_to_int16(uint16_t a) { | ||||||
|  | 	int16_t b; | ||||||
|  | 	char* aPointer = (char*)&a, *bPointer = (char*)&b; | ||||||
|  | 	memcpy(bPointer, aPointer, sizeof(a)); | ||||||
|  | 	return b; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint16_t combine_uint8_t(uint8_t a, uint8_t b) { | ||||||
|  | 	uint16_t c = ((uint16_t)a << 8) | b; | ||||||
|  | 	return c; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | int16_t combine_gyro_data(uint8_t a, uint8_t b) { | ||||||
|  | 	uint16_t c = combine_uint8_t(a, b); | ||||||
|  | 	int16_t d = uint16_to_int16(c); | ||||||
|  | 	return d; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | float clamp(float a, float min, float max) { | ||||||
|  | 	if (a < min) { | ||||||
|  | 		return min; | ||||||
|  | 	} else if (a > max) { | ||||||
|  | 		return max; | ||||||
|  | 	} else { | ||||||
|  | 		return a; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | uint16_t clamp(uint16_t a, uint16_t min, uint16_t max) { | ||||||
|  | 	if (a < min) { | ||||||
|  | 		return min; | ||||||
|  | 	} | ||||||
|  | 	else if (a > max) { | ||||||
|  | 		return max; | ||||||
|  | 	} | ||||||
|  | 	else { | ||||||
|  | 		return a; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | unsigned createMask(unsigned a, unsigned b) { | ||||||
|  | 	unsigned r = 0; | ||||||
|  | 	for (unsigned i = a; i <= b; i++) | ||||||
|  | 		r |= 1 << i; | ||||||
|  |  | ||||||
|  | 	return r; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hex_dump(unsigned char *buf, int len) { | ||||||
|  | 	for (int i = 0; i < len; i++) { | ||||||
|  | 		printf("%02x ", buf[i]); | ||||||
|  | 	} | ||||||
|  | 	printf("\n"); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hex_dump2(unsigned char *buf, int len) { | ||||||
|  | 	for (int i = 0; i < len; i++) { | ||||||
|  | 		printf("%02x ", buf[i]); | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void hex_dump_0(unsigned char *buf, int len) { | ||||||
|  | 	for (int i = 0; i < len; i++) { | ||||||
|  | 		if (buf[i] != 0) { | ||||||
|  | 			printf("%02x ", buf[i]); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void int_dump(unsigned char *buf, int len) { | ||||||
|  | 	for (int i = 0; i < len; i++) { | ||||||
|  | 		printf("%i ", buf[i]); | ||||||
|  | 	} | ||||||
|  | 	printf("\n"); | ||||||
|  | } | ||||||
| @@ -16,6 +16,10 @@ | |||||||
|  |  | ||||||
| #include "win32.h" | #include "win32.h" | ||||||
|  |  | ||||||
|  | // Using this to get dualsense controllers | ||||||
|  | #include "JoyShockLibrary/JoyShockLibrary.h" | ||||||
|  |  | ||||||
|  |  | ||||||
| NS_WIN32_BEGIN | NS_WIN32_BEGIN | ||||||
|  |  | ||||||
| // TODO(Ed) : This is a global for now. | // TODO(Ed) : This is a global for now. | ||||||
| @@ -301,7 +305,17 @@ WinMain( | |||||||
| ) | ) | ||||||
| { | { | ||||||
| 	using namespace win32; | 	using namespace win32; | ||||||
| 	xinput_load_library_bindings(); | 	// xinput_load_library_bindings(); | ||||||
|  |  | ||||||
|  | 	using JSL_DeviceHandle = int; | ||||||
|  | 	u32 jsl_num_devices = JslConnectDevices(); | ||||||
|  |  | ||||||
|  | 	JSL_DeviceHandle device_handles[4] {}; | ||||||
|  | 	u32 jsl_getconnected_found = JslGetConnectedDeviceHandles( device_handles, jsl_num_devices ); | ||||||
|  | 	if ( jsl_getconnected_found != jsl_num_devices ) | ||||||
|  | 	{ | ||||||
|  | 		OutputDebugStringA( "Error: JSLGetConnectedDeviceHandles didn't find as many as were stated with JslConnectDevices\n"); | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	// MessageBox( 0, L"First message!", L"Handmade Hero", MB_Ok_Btn | MB_Icon_Information ); | 	// MessageBox( 0, L"First message!", L"Handmade Hero", MB_Ok_Btn | MB_Icon_Information ); | ||||||
|  |  | ||||||
| @@ -374,6 +388,7 @@ WinMain( | |||||||
| 					DispatchMessage( & msg_info ); | 					DispatchMessage( & msg_info ); | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				// XInput Polling | ||||||
| 				// TODO(Ed) : Should we poll this more frequently? | 				// TODO(Ed) : Should we poll this more frequently? | ||||||
| 				for ( DWORD controller_index = 0; controller_index < XUSER_MAX_COUNT; ++ controller_index ) | 				for ( DWORD controller_index = 0; controller_index < XUSER_MAX_COUNT; ++ controller_index ) | ||||||
| 				{ | 				{ | ||||||
| @@ -406,6 +421,30 @@ WinMain( | |||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
|  |  | ||||||
|  | 				// JSL Input Polling | ||||||
|  | 				for ( u32 jsl_device_index = 0; jsl_device_index < jsl_num_devices; ++ jsl_device_index ) | ||||||
|  | 				{ | ||||||
|  | 					if ( ! JslStillConnected( device_handles[ jsl_device_index ] ) ) | ||||||
|  | 					{ | ||||||
|  | 						OutputDebugStringA( "Error: JSLStillConnected returned false\n" ); | ||||||
|  | 						continue; | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  | 					JOY_SHOCK_STATE state = JslGetSimpleState( device_handles[ jsl_device_index ] ); | ||||||
|  | 					dpad_up        = state.buttons & JSMASK_UP; | ||||||
|  | 					dpad_down      = state.buttons & JSMASK_DOWN; | ||||||
|  | 					dpad_left      = state.buttons & JSMASK_LEFT; | ||||||
|  | 					dpad_right     = state.buttons & JSMASK_RIGHT; | ||||||
|  | 					start          = state.buttons & JSMASK_PLUS; | ||||||
|  | 					back           = state.buttons & JSMASK_MINUS; | ||||||
|  | 					left_shoulder  = state.buttons & JSMASK_L; | ||||||
|  | 					right_shoulder = state.buttons & JSMASK_R; | ||||||
|  | 					btn_a_button   = state.buttons & JSMASK_S; | ||||||
|  | 					btn_b_button   = state.buttons & JSMASK_E; | ||||||
|  | 					btn_x_button   = state.buttons & JSMASK_W; | ||||||
|  | 					btn_y_button   = state.buttons & JSMASK_N; | ||||||
|  | 				} | ||||||
|  |  | ||||||
| 				x_offset += dpad_right; | 				x_offset += dpad_right; | ||||||
| 				x_offset -= dpad_left; | 				x_offset -= dpad_left; | ||||||
| 				y_offset += dpad_up; | 				y_offset += dpad_up; | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
| #pragma region Platform Detection | #pragma region Platform Detection | ||||||
|  |  | ||||||
| /* Platform architecture */ | /* Platform architecture */ | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
| // Keywords | // Keywords | ||||||
|  |  | ||||||
| #define global        static    // Global variables | #define global        static    // Global variables | ||||||
|   | |||||||
| @@ -1,3 +1,5 @@ | |||||||
|  | #pragma once | ||||||
|  |  | ||||||
| #pragma region Basic Types | #pragma region Basic Types | ||||||
|  |  | ||||||
| #define U8_MIN 0u | #define U8_MIN 0u | ||||||
|   | |||||||
| @@ -338,10 +338,15 @@ $includes = @( | |||||||
| 	$path_deps, | 	$path_deps, | ||||||
| 	$path_platform | 	$path_platform | ||||||
| ) | ) | ||||||
|  |  | ||||||
|  | # Microsoft | ||||||
| $lib_gdi32  = 'Gdi32.lib' | $lib_gdi32  = 'Gdi32.lib' | ||||||
| $lib_xinput = 'Xinput.lib' | $lib_xinput = 'Xinput.lib' | ||||||
| $lib_user32 = 'User32.lib' | $lib_user32 = 'User32.lib' | ||||||
|  |  | ||||||
|  | # Github | ||||||
|  | $lib_jsl = Join-Path $path_deps 'JoyShockLibrary/x64/JoyShockLibrary.lib' | ||||||
|  |  | ||||||
| $unit       = Join-Path $path_project 'handmade_win32.cpp' | $unit       = Join-Path $path_project 'handmade_win32.cpp' | ||||||
| $executable = Join-Path $path_build   'handmade_win32.exe' | $executable = Join-Path $path_build   'handmade_win32.exe' | ||||||
|  |  | ||||||
| @@ -351,6 +356,9 @@ $linker_args = @( | |||||||
| 	$lib_gdi32, | 	$lib_gdi32, | ||||||
| 	# $lib_xinput, | 	# $lib_xinput, | ||||||
| 	$lib_user32, | 	$lib_user32, | ||||||
|  |  | ||||||
|  | 	$lib_jsl, | ||||||
|  |  | ||||||
| 	$flag_link_win_subsystem_windows | 	$flag_link_win_subsystem_windows | ||||||
| ) | ) | ||||||
|  |  | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| @@ -1,28 +1,65 @@ | |||||||
| clear-host | clear-host | ||||||
| $path_root = & git rev-parse --show-toplevel | $path_root = & git rev-parse --show-toplevel | ||||||
|  |  | ||||||
|  | $path_data         = Join-Path $path_root         "data" | ||||||
| $path_project      = Join-Path $path_root         "project" | $path_project      = Join-Path $path_root         "project" | ||||||
| $path_deps         = Join-Path $path_project      "dependencies" | $path_deps         = Join-Path $path_project      "dependencies" | ||||||
| $path_deps_windows = Join-Path $path_deps         "windows" | $path_deps_windows = Join-Path $path_deps         "windows" | ||||||
| $path_temp         = Join-Path $path_deps         "temp" | $path_temp         = Join-Path $path_deps         "temp" | ||||||
| $path_platform     = Join-Path $path_project      "platform" | $path_platform     = Join-Path $path_project      "platform" | ||||||
|  |  | ||||||
| # Define the URL of the zip file and the destination directory | # Clear out the current content first | ||||||
| $url            = "https://github.com/Ed94/gencpp/releases/download/latest/gencpp_singleheader.zip" | if (Test-Path $path_deps) { | ||||||
| $destinationZip = Join-Path $path_temp "gencpp_singleheader.zip" | 	Remove-Item $path_deps -Recurse -Force | ||||||
|  |  | ||||||
| # Create directories if they don't exist |  | ||||||
| if (-not (Test-Path $path_deps)) { |  | ||||||
| 	New-Item -ItemType Directory -Path $path_deps | 	New-Item -ItemType Directory -Path $path_deps | ||||||
| } | } | ||||||
| if (-not (Test-Path $path_temp)) { | New-Item -ItemType Directory -Path $path_temp | ||||||
| 	New-Item -ItemType Directory -Path $path_temp |  | ||||||
| } | $url_gencpp      = "https://github.com/Ed94/gencpp/releases/download/latest/gencpp_singleheader.zip" | ||||||
|  | $path_gencpp_zip = Join-Path $path_temp "gencpp_singleheader.zip" | ||||||
|  |  | ||||||
| #region gencpp | #region gencpp | ||||||
| Invoke-WebRequest -Uri $url -OutFile $destinationZip | Invoke-WebRequest -Uri  $url_gencpp                      -OutFile         $path_gencpp_zip | ||||||
| Expand-Archive    -Path $destinationZip                  -DestinationPath $path_temp | Expand-Archive    -Path $path_gencpp_zip                 -DestinationPath $path_temp | ||||||
| Move-Item         -Path (Join-Path $path_temp "gen.hpp") -Destination     $path_deps -Force | Move-Item         -Path (Join-Path $path_temp "gen.hpp") -Destination     $path_deps -Force | ||||||
| #endregion gencpp | #endregion gencpp | ||||||
|  |  | ||||||
|  | #region JoyShockLibrary | ||||||
|  | $url_jsl_repo       = "https://github.com/JibbSmart/JoyShockLibrary.git" | ||||||
|  | # $url_jsl_zip        = "https://github.com/JibbSmart/JoyShockLibrary/releases/download/v3.0/JSL_3_0.zip" | ||||||
|  | $url_jsl_zip        = "https://github.com/Ed94/JoyShockLibrary/releases/download/not_for_public_use/JSL.zip" | ||||||
|  | $path_jsl_repo      = Join-Path $path_temp    "JoyShockLibraryRepo" | ||||||
|  | $path_jsl_repo_code = Join-Path $path_jsl_repo "JoyShockLibrary" | ||||||
|  | $path_jsl_lib_zip   = Join-Path $path_temp    "JSL_3_0.zip" | ||||||
|  | $path_jsl           = Join-Path $path_deps    "JoyShockLibrary" | ||||||
|  | $path_jsl_hidapi    = Join-Path $path_jsl     "hidapi" | ||||||
|  | $path_jsl_lib	    = Join-Path $path_jsl     "x64" | ||||||
|  |  | ||||||
|  | # Grab code from repo | ||||||
|  | & git clone $url_jsl_repo $path_jsl_repo | ||||||
|  | Move-Item -Path $path_jsl_repo_code -Destination $path_deps -Force | ||||||
|  |  | ||||||
|  | # Clean up the junk | ||||||
|  | @( $path_jsl, $path_jsl_hidapi ) | ForEach-Object { | ||||||
|  | 	Get-ChildItem -Path $path_jsl -Recurse -File | Where-Object { | ||||||
|  | 		($_.Extension -ne ".h" -and $_.Extension -ne ".cpp") | ||||||
|  | 	} | Remove-Item -Force | ||||||
|  | } | ||||||
|  | Remove-Item (join-path $path_jsl_hidapi 'objs') -Recurse -Force | ||||||
|  |  | ||||||
|  | # Get precompiled binaries | ||||||
|  | Invoke-WebRequest -Uri  $url_jsl_zip      -OutFile         $path_jsl_lib_zip | ||||||
|  | Expand-Archive    -Path $path_jsl_lib_zip -DestinationPath $path_temp | ||||||
|  |  | ||||||
|  | if (-not (Test-Path $path_jsl_lib)) { | ||||||
|  |     New-Item -ItemType Directory -Path $path_jsl_lib | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $jsl_lib_files = (Get-ChildItem (Join-Path $path_temp "JSL\x64") -Recurse -Include *.dll, *.lib) | ||||||
|  | Move-Item $jsl_lib_files -Destination $path_jsl_lib -Force | ||||||
|  |  | ||||||
|  | $path_jsl_dll  = Join-Path $path_jsl_lib "JoyShockLibrary.dll" | ||||||
|  | Move-Item  $path_jsl_dll $path_data -Force | ||||||
|  | #endregion JoyShockLibrary | ||||||
|  |  | ||||||
| Remove-Item $path_temp -Recurse -Force | Remove-Item $path_temp -Recurse -Force | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user