mirror of
				https://github.com/quelsolaar/MergeSource
				synced 2025-10-31 01:16:12 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			404 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			404 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| 
 | |
| 
 | |
| 
 | |
| #include "forge.h"
 | |
| #include "betray_plugin_api.h"
 | |
| #include <windows.h>
 | |
| #include <stdio.h>
 | |
| 
 | |
| typedef struct{
 | |
| 		float value;
 | |
| 		boolean updated;
 | |
| 		uint betray_axis_id;
 | |
| 		char name[64];
 | |
| }BetrayPluginMidiSlider;
 | |
| 
 | |
| typedef struct{
 | |
| 		boolean events[8];
 | |
| 		uint event_count;
 | |
| 		uint betray_button_id;
 | |
| 		char name[64];
 | |
| }BetrayPluginMidiButton;
 | |
| 
 | |
| typedef struct{
 | |
| 	BetrayPluginMidiSlider sliders[256];
 | |
| 	BetrayPluginMidiButton buttons[256];
 | |
| 	char device_name[64];
 | |
| 	uint user_id;
 | |
| }MidiDevice;
 | |
| 
 | |
| MidiDevice *betray_plugin_midi_devices;
 | |
| uint betray_plugin_midi_device_count;
 | |
| void *betray_plugin_midi_mutex = NULL;
 | |
| 
 | |
| 
 | |
| 
 | |
| void betray_plugin_midi_file_name(char *buffer, MidiDevice *d)
 | |
| {
 | |
| 	char device_name[64];
 | |
| 	uint i;
 | |
| 	for(i = 0; i < 63 && d->device_name[i] != 0; i++)
 | |
| 	{
 | |
| 		if(d->device_name[i] <= ' ')
 | |
| 			device_name[i] = '_';
 | |
| 		else
 | |
| 			device_name[i] = d->device_name[i];
 | |
| 	}
 | |
| 	device_name[i] = 0;
 | |
| 	sprintf(buffer, "betray_midi_%s_settings.txt", device_name);
 | |
| }
 | |
| 
 | |
| void betray_plugin_midi_save()
 | |
| {
 | |
| 	MidiDevice *d;
 | |
| 	char file_name[128];
 | |
| 	FILE *f;
 | |
| 	uint i, j;
 | |
| 	for(i = 0; i < betray_plugin_midi_device_count; i++)
 | |
| 	{
 | |
| 		d = &betray_plugin_midi_devices[i];
 | |
| 		betray_plugin_midi_file_name(file_name, d);
 | |
| 		f = fopen(file_name, "w");
 | |
| 		if(f != NULL)
 | |
| 		{
 | |
| 			for(j = 0; j < 256; j++)
 | |
| 				if(d->buttons[j].betray_button_id != -1)
 | |
| 					fprintf(f, "Button_%u : %s\n", j, d->buttons[j].name);
 | |
| 			for(j = 0; j < 256; j++)
 | |
| 				if(d->sliders[j].betray_axis_id != -1)
 | |
| 					fprintf(f, "Slider_%u : %s\n", j, d->sliders[j].name);
 | |
| 			fclose(f);
 | |
| 		}
 | |
| 	}
 | |
| }
 | |
| 
 | |
| 
 | |
| void betray_plugin_midi_load(MidiDevice *d)
 | |
| {
 | |
| 	char file_name[128], *buffer, *button = "Button_", *slider = "Slider_";
 | |
| 	uint i, j, id;
 | |
| 
 | |
| 	betray_plugin_midi_file_name(file_name, d);
 | |
| 	buffer = f_text_load(file_name, NULL);
 | |
| 	if(buffer == NULL)
 | |
| 		return;
 | |
| 	for(i = 0; buffer[i] != 0; i++)
 | |
| 	{
 | |
| 		if(buffer[i] == 'B')
 | |
| 		{
 | |
| 			for(j = 0; buffer[i + j] == button[j] && buffer[j] != 0; j++);
 | |
| 			if(button[j] == 0)
 | |
| 			{
 | |
| 				id = 0;
 | |
| 				for(i += j; buffer[i] >= '0' && buffer[i] <= '9'; i++)
 | |
| 				{
 | |
| 					id *= 10;
 | |
| 					id += buffer[i] - '0';
 | |
| 				}
 | |
| 				if(id < 256)
 | |
| 				{
 | |
| 					for(;(buffer[i] <= ' ' || buffer[i] == ':') && buffer[i] != '\n' && buffer[i] != 0; i++);
 | |
| 					if(buffer[i] == 0)
 | |
| 					{						
 | |
| 						free(buffer);
 | |
| 						return;
 | |
| 					}
 | |
| 					if(buffer[i] != '\n')
 | |
| 					{
 | |
| 						for(j = 0; j < 63 && buffer[i + j] != '\n' && buffer[i + j] != 0; j++)
 | |
| 							d->buttons[id].name[j] = buffer[i + j];
 | |
| 						d->buttons[id].name[j] = 0;
 | |
| 						i += j - 1;
 | |
| 						d->buttons[id].betray_button_id = betray_plugin_button_allocate(-1, d->buttons[id].name);
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 		if(buffer[i] == 'S')
 | |
| 		{
 | |
| 			for(j = 0; buffer[i + j] == slider[j] && slider[j] != 0; j++);
 | |
| 			if(slider[j] == 0)
 | |
| 			{
 | |
| 				id = 0;
 | |
| 				for(i += j; buffer[i] >= '0' && buffer[i] <= '9'; i++)
 | |
| 				{
 | |
| 					id *= 10;
 | |
| 					id += buffer[i] - '0';
 | |
| 				}
 | |
| 				
 | |
| 				if(id < 256)
 | |
| 				{
 | |
| 					for(;(buffer[i] <= ' ' || buffer[i] == ':') && buffer[i] != '\n' && buffer[i] != 0; i++);
 | |
| 					if(buffer[i] == 0)
 | |
| 					{						
 | |
| 						free(buffer);
 | |
| 						return;
 | |
| 					}
 | |
| 					
 | |
| 					if(buffer[i] != '\n')
 | |
| 					{
 | |
| 						for(j = 0; j < 63 && buffer[i + j] != '\n' && buffer[i + j] != 0; j++)
 | |
| 							d->sliders[id].name[j] = buffer[i + j];
 | |
| 						d->sliders[id].name[j] = 0;
 | |
| 						i += j - 1;
 | |
| 						d->sliders[id].betray_axis_id = betray_plugin_axis_allocate(d->user_id, d->device_id, d->sliders[id].name, B_AXIS_SLIDER, 1);		
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	free(buffer);
 | |
| }
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| void CALLBACK betray_plugin_midi_callback(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, DWORD dwParam1, DWORD dwParam2)
 | |
| {
 | |
| 	MidiDevice *device;
 | |
| 	imagine_mutex_lock(betray_plugin_midi_mutex); 
 | |
| 	device = &betray_plugin_midi_devices[dwInstance];
 | |
| 	switch(wMsg) {
 | |
| 	case MIM_OPEN:
 | |
| 		printf("wMsg=MIM_OPEN\n");
 | |
| 		break;
 | |
| 	case MIM_CLOSE:
 | |
| 		printf("wMsg=MIM_CLOSE\n");
 | |
| 		break;
 | |
| 	case MIM_DATA:
 | |
| 		{
 | |
| 			float value;
 | |
| 			uint id;
 | |
| 			id = (dwParam1 >> 8) & 0xff;
 | |
| 			if((uint32)(dwParam1 & 0xff) == (uint32)0x90)
 | |
| 			{
 | |
| 
 | |
| 				printf("Button down %u\n", (dwParam1 >> 8) & 0xff);
 | |
| 				if(device->buttons[id].event_count < 8)
 | |
| 					device->buttons[id].events[device->buttons[id].event_count++] = TRUE;
 | |
| 			}
 | |
| 			if((uint32)(dwParam1 & 0xff) == (uint32)0x80) // button up
 | |
| 			{
 | |
| 				printf("Button up %u\n", (dwParam1 >> 8) & 0xff);
 | |
| 				if(device->buttons[id].event_count < 8)
 | |
| 					device->buttons[id].events[device->buttons[id].event_count++] = FALSE;
 | |
| 			}
 | |
| 			if((uint32)(dwParam1 & 0xff) == (uint32)0xb0) // axis
 | |
| 			{
 | |
| 				device->sliders[id].updated = TRUE;
 | |
| 				device->sliders[id].value = (float)(dwParam1 & 0x7f0000) / (float)(0x7f0000);
 | |
| 				printf("Axis %u %f\n", (dwParam1 >> 8) & 0xff, device->sliders[id].value);
 | |
| 			}
 | |
| 		}
 | |
| 		break;
 | |
| 	case MIM_LONGDATA:
 | |
| 		printf("wMsg=MIM_LONGDATA\n"); 
 | |
| 		break;
 | |
| 	case MIM_ERROR:
 | |
| 		printf("wMsg=MIM_ERROR\n");
 | |
| 		break;
 | |
| 	case MIM_LONGERROR:
 | |
| 		printf("wMsg=MIM_LONGERROR\n");
 | |
| 		break;
 | |
| 	case MIM_MOREDATA:
 | |
| 		printf("wMsg=MIM_MOREDATA\n");
 | |
| 		break;
 | |
| 	default:
 | |
| 		printf("wMsg = unknown\n");
 | |
| 		break;
 | |
| 	}
 | |
| 	imagine_mutex_unlock(betray_plugin_midi_mutex); 
 | |
| }
 | |
| 
 | |
| void midi_plugin_callback_main(BInputState *input)
 | |
| {
 | |
| 	MidiDevice *device;
 | |
| 	uint i, j, k;	
 | |
| 	imagine_mutex_lock(betray_plugin_midi_mutex); 
 | |
| 	for(i = 0; i < betray_plugin_midi_device_count; i++)
 | |
| 	{
 | |
| 		device = &betray_plugin_midi_devices[i];
 | |
| 		for(j = 0; j < 256; j++)
 | |
| 		{
 | |
| 			if(device->buttons[j].event_count != 0)
 | |
| 			{
 | |
| 				if(device->buttons[j].betray_button_id == -1)
 | |
| 				{
 | |
| 					device->buttons[j].betray_button_id = betray_plugin_button_allocate(-1, device->buttons[j].name);
 | |
| 					betray_plugin_midi_save();
 | |
| 				}
 | |
| 				for(k = 0; k < device->buttons[j].event_count; k++)
 | |
| 					betray_plugin_button_set(device->user_id, device->buttons[j].betray_button_id, device->buttons[j].events[k], -1);
 | |
| 				device->buttons[j].event_count = 0;
 | |
| 			}
 | |
| 			if(device->sliders[j].updated)
 | |
| 			{
 | |
| 				if(device->sliders[j].betray_axis_id == -1)
 | |
| 				{
 | |
| 					device->sliders[j].betray_axis_id = betray_plugin_axis_allocate(device->user_id, device->device_id, device->sliders[j].name, B_AXIS_SLIDER, 1);
 | |
| 					betray_plugin_midi_save();
 | |
| 				}		
 | |
| 				betray_plugin_axis_set(device->sliders[j].betray_axis_id, device->sliders[j].value, 0.0, 0.0);
 | |
| 				device->sliders[j].updated = FALSE;
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	imagine_mutex_unlock(betray_plugin_midi_mutex); 
 | |
| }
 | |
| 
 | |
| void betray_plugin_init(void)
 | |
| {
 | |
| 	MIDIINCAPSW lpMidiInCaps;
 | |
| 	HMIDIIN hMidiDevice = NULL;
 | |
| 	DWORD nMidiPort = 0;
 | |
| 	uint count, i, j, k, l;
 | |
| 	MMRESULT rv;
 | |
| 	char buffer[64];
 | |
| 
 | |
| 	betray_plugin_callback_set_main(midi_plugin_callback_main);
 | |
| 
 | |
| 	betray_plugin_midi_mutex = imagine_mutex_create();
 | |
| 	imagine_mutex_lock(betray_plugin_midi_mutex); 
 | |
| 	count = midiInGetNumDevs();
 | |
| 	betray_plugin_midi_devices = malloc((sizeof *betray_plugin_midi_devices) * count);
 | |
| 	betray_plugin_midi_device_count = 0;
 | |
| 	for(i = 0; i < count; i++)
 | |
| 	{
 | |
| 		midiInGetDevCaps(i, &lpMidiInCaps, sizeof lpMidiInCaps);		
 | |
| 		for(j = 0;  j < 63 && lpMidiInCaps.szPname[j] != 0; j++)
 | |
| 			betray_plugin_midi_devices[betray_plugin_midi_device_count].device_name[j] = lpMidiInCaps.szPname[j];
 | |
| 		betray_plugin_midi_devices[betray_plugin_midi_device_count].device_name[j] = 0;
 | |
| 		betray_plugin_midi_devices[betray_plugin_midi_device_count].user_id = betray_plugin_user_allocate();
 | |
| 		betray_plugin_midi_devices[betray_plugin_midi_device_count].device_id = betray_plugin_input_device_allocate(betray_plugin_midi_devices[betray_plugin_midi_device_count].user_id, lpMidiInCaps.szPname);
 | |
| 
 | |
| 		for(j = 0; j < 256; j++)
 | |
| 		{
 | |
| 			sprintf(buffer, " Button %u", j);
 | |
| 			for(k = 0; betray_plugin_midi_devices[betray_plugin_midi_device_count].device_name[k] != 0; k++)
 | |
| 				betray_plugin_midi_devices[betray_plugin_midi_device_count].buttons[j].name[k] = betray_plugin_midi_devices[betray_plugin_midi_device_count].device_name[k];
 | |
| 			for(l = 0; k + l < 63 && buffer[l] != 0; l++)
 | |
| 				betray_plugin_midi_devices[betray_plugin_midi_device_count].buttons[j].name[k + l] = buffer[l];
 | |
| 			betray_plugin_midi_devices[betray_plugin_midi_device_count].buttons[j].name[k + l] = 0;
 | |
| 			betray_plugin_midi_devices[betray_plugin_midi_device_count].buttons[j].betray_button_id = -1;
 | |
| 			betray_plugin_midi_devices[betray_plugin_midi_device_count].buttons[j].event_count = 0;
 | |
| 
 | |
| 			sprintf(buffer, " Slider %u", j);
 | |
| 			for(k = 0; betray_plugin_midi_devices[betray_plugin_midi_device_count].device_name[k] != 0; k++)
 | |
| 				betray_plugin_midi_devices[betray_plugin_midi_device_count].sliders[j].name[k] = betray_plugin_midi_devices[betray_plugin_midi_device_count].device_name[k];
 | |
| 			for(l = 0; k + l < 63 && buffer[l] != 0; l++)
 | |
| 				betray_plugin_midi_devices[betray_plugin_midi_device_count].sliders[j].name[k + l] = buffer[l];
 | |
| 			betray_plugin_midi_devices[betray_plugin_midi_device_count].sliders[j].name[k + l] = 0;
 | |
| 			betray_plugin_midi_devices[betray_plugin_midi_device_count].sliders[j].betray_axis_id = -1;
 | |
| 			betray_plugin_midi_devices[betray_plugin_midi_device_count].sliders[j].updated = FALSE;
 | |
| 		}
 | |
| 		betray_plugin_midi_load(&betray_plugin_midi_devices[betray_plugin_midi_device_count]);
 | |
| 		rv = midiInOpen(&hMidiDevice, nMidiPort, (DWORD)(void*)betray_plugin_midi_callback, betray_plugin_midi_device_count, CALLBACK_FUNCTION);
 | |
| 		if(rv == MMSYSERR_NOERROR)
 | |
| 		{
 | |
| 			midiInStart(hMidiDevice);
 | |
| 			betray_plugin_midi_device_count++;
 | |
| 		}
 | |
| 	}
 | |
| 	imagine_mutex_unlock(betray_plugin_midi_mutex); 
 | |
| }
 | |
| 
 | |
| /*
 | |
| int  text_usb()
 | |
| {
 | |
|     unsigned int count, i;
 | |
|     MIDIINCAPS inputCapabilities;
 | |
| 
 | |
| 	count = midiInGetNumDevs();
 | |
| 	printf("count %u\n", count);
 | |
|     for(i = 0; i < count; i++)
 | |
| 	{
 | |
|        midiInGetDevCaps(i, &inputCapabilities, sizeof(inputCapabilities));
 | |
|        printf("Hardware: %s\n", inputCapabilities.szPname);
 | |
| 	   inputCapabilities.
 | |
|     }
 | |
| 	i = 0;
 | |
| }
 | |
| /*
 | |
| int text_usb()
 | |
| {
 | |
| 	HDEVINFO                         hDevInfo;
 | |
| 	SP_DEVICE_INTERFACE_DATA         DevIntfData;
 | |
| 	PSP_DEVICE_INTERFACE_DETAIL_DATA DevIntfDetailData;
 | |
| 	SP_DEVINFO_DATA                  DevData;
 | |
| 	HANDLE								handle; 
 | |
| 
 | |
| 	DWORD dwSize, dwType, dwMemberIdx;
 | |
| 	HKEY hKey;
 | |
| 	BYTE lpData[1024];
 | |
| 	// We will try to get device information set for all USB devices that have a
 | |
| 	// device interface and are currently present on the system (plugged in).
 | |
| 	hDevInfo = SetupDiGetClassDevs(&GUID_DEVINTERFACE_USB_DEVICE, NULL, 0, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
 | |
| 	
 | |
| 	if (hDevInfo != INVALID_HANDLE_VALUE)
 | |
| 	{
 | |
| 		int i, j;
 | |
| 		// Prepare to enumerate all device interfaces for the device information
 | |
| 		// set that we retrieved with SetupDiGetClassDevs(..)
 | |
| 		DevIntfData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
 | |
| 		dwMemberIdx = 0;
 | |
| 		
 | |
| 		// Next, we will keep calling this SetupDiEnumDeviceInterfaces(..) until this
 | |
| 		// function causes GetLastError() to return  ERROR_NO_MORE_ITEMS. With each
 | |
| 		// call the dwMemberIdx value needs to be incremented to retrieve the next
 | |
| 		// device interface information.
 | |
| 
 | |
| 		
 | |
| 		
 | |
| 	//	while(GetLastError() != ERROR_NO_MORE_ITEMS)
 | |
| 		for(i = 0; SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, i, &DevIntfData); i++)
 | |
| 		{
 | |
| 			void *h = NULL;
 | |
| 			printf("loop\n");
 | |
| 
 | |
| 			DevData.cbSize = sizeof(DevData);
 | |
| 			SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData, NULL, 0, &dwSize, NULL);
 | |
| 			DevIntfDetailData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwSize);
 | |
| 			DevIntfDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
 | |
| 			if(SetupDiGetDeviceInterfaceDetail(hDevInfo, &DevIntfData, DevIntfDetailData, dwSize, &dwSize, &DevData))
 | |
| 			{
 | |
| 				{
 | |
| 					char buffer[256];
 | |
| 					int i;
 | |
| 					for(i = 0; i < 256 && DevIntfDetailData->DevicePath[i] != 0; i++)
 | |
| 						buffer[i] = DevIntfDetailData->DevicePath[i];
 | |
| 					buffer[i] = 0;
 | |
| 					printf("Device %s\n", buffer);
 | |
| 				}
 | |
| 
 | |
| 
 | |
| 	
 | |
| 				handle = CreateFile(DevIntfDetailData->DevicePath,
 | |
| 								GENERIC_WRITE | GENERIC_READ, 
 | |
| 								FILE_SHARE_WRITE | FILE_SHARE_READ,
 | |
| 								NULL, OPEN_EXISTING, 
 | |
| 								FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, 
 | |
| 								NULL);
 | |
| 				printf("handle %p\n", handle);
 | |
| 				if(handle == NULL)
 | |
| 					return;
 | |
| 				printf("A Error.\n GetLastError=%x\n", GetLastError());
 | |
| 		//		ERROR_INVALID_HANDLE
 | |
| 				if((j = WinUsb_Initialize(handle, &h)))
 | |
| 				{
 | |
| 					printf("WORKING!\n");
 | |
| 
 | |
| 				}
 | |
| 				CloseHandle(handle);
 | |
| 				printf("B Error.\n GetLastError=%x\n", GetLastError());
 | |
| 			}
 | |
| 			HeapFree(GetProcessHeap(), 0, DevIntfDetailData);
 | |
| 
 | |
| 			// Continue looping
 | |
| 		//	SetupDiEnumDeviceInterfaces(hDevInfo, NULL, &GUID_DEVINTERFACE_USB_DEVICE, ++dwMemberIdx, &DevIntfData);
 | |
| 		}
 | |
| 
 | |
| 		SetupDiDestroyDeviceInfoList(hDevInfo);
 | |
| 	}
 | |
| 	exit(0);
 | |
| 	return 0;
 | |
| }*/ |