⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gamecon.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
				axes[0] = axes[1] = 0;				for (j = 0; j < 8; j++) {					if (data[23 - j] & s) axes[0] |= 1 << j;					if (data[31 - j] & s) axes[1] |= 1 << j;				}				input_report_abs(dev + i, ABS_X,  axes[0]);				input_report_abs(dev + i, ABS_Y, -axes[1]);				input_report_abs(dev + i, ABS_HAT0X, !(s & data[6]) - !(s & data[7]));				input_report_abs(dev + i, ABS_HAT0Y, !(s & data[4]) - !(s & data[5]));				for (j = 0; j < 10; j++)					input_report_key(dev + i, gc_n64_btn[j], s & data[gc_n64_bytes[j]]);				input_sync(dev + i);			}		}	}/* * NES and SNES pads */	if (gc->pads[GC_NES] || gc->pads[GC_SNES]) {		gc_nes_read_packet(gc, gc->pads[GC_SNES] ? GC_SNES_LENGTH : GC_NES_LENGTH, data);		for (i = 0; i < 5; i++) {			s = gc_status_bit[i];			if (s & (gc->pads[GC_NES] | gc->pads[GC_SNES])) {				input_report_abs(dev + i, ABS_X, !(s & data[6]) - !(s & data[7]));				input_report_abs(dev + i, ABS_Y, !(s & data[4]) - !(s & data[5]));			}			if (s & gc->pads[GC_NES])				for (j = 0; j < 4; j++)					input_report_key(dev + i, gc_snes_btn[j], s & data[gc_nes_bytes[j]]);			if (s & gc->pads[GC_SNES])				for (j = 0; j < 8; j++)					input_report_key(dev + i, gc_snes_btn[j], s & data[gc_snes_bytes[j]]);			input_sync(dev + i);		}	}/* * Multi and Multi2 joysticks */	if (gc->pads[GC_MULTI] || gc->pads[GC_MULTI2]) {		gc_multi_read_packet(gc, gc->pads[GC_MULTI2] ? GC_MULTI2_LENGTH : GC_MULTI_LENGTH, data);		for (i = 0; i < 5; i++) {			s = gc_status_bit[i];			if (s & (gc->pads[GC_MULTI] | gc->pads[GC_MULTI2])) {				input_report_abs(dev + i, ABS_X,  !(s & data[2]) - !(s & data[3]));				input_report_abs(dev + i, ABS_Y,  !(s & data[0]) - !(s & data[1]));				input_report_key(dev + i, BTN_TRIGGER, s & data[4]);			}			if (s & gc->pads[GC_MULTI2])				input_report_key(dev + i, BTN_THUMB, s & data[5]);			input_sync(dev + i);		}	}/* * PSX controllers */	if (gc->pads[GC_PSX] || gc->pads[GC_DDR]) {		gc_psx_read_packet(gc, data_psx, data);		for (i = 0; i < 5; i++) {	 		switch (data[i]) {				case GC_PSX_RUMBLE:					input_report_key(dev + i, BTN_THUMBL, ~data_psx[i][0] & 0x04);					input_report_key(dev + i, BTN_THUMBR, ~data_psx[i][0] & 0x02);				case GC_PSX_NEGCON:				case GC_PSX_ANALOG:					if(gc->pads[GC_DDR] & gc_status_bit[i]) {						for(j = 0; j < 4; j++)							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));					} else {						for (j = 0; j < 4; j++)							input_report_abs(dev + i, gc_psx_abs[j+2], data_psx[i][j + 2]);						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);					}					for (j = 0; j < 8; j++)						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);					input_sync(dev + i);					break;				case GC_PSX_NORMAL:					if(gc->pads[GC_DDR] & gc_status_bit[i]) {						for(j = 0; j < 4; j++)							input_report_key(dev + i, gc_psx_ddr_btn[j], ~data_psx[i][0] & (0x10 << j));					} else {						input_report_abs(dev + i, ABS_X, 128 + !(data_psx[i][0] & 0x20) * 127 - !(data_psx[i][0] & 0x80) * 128);						input_report_abs(dev + i, ABS_Y, 128 + !(data_psx[i][0] & 0x40) * 127 - !(data_psx[i][0] & 0x10) * 128);						/* for some reason if the extra axes are left unset they drift */						/* for (j = 0; j < 4; j++)							input_report_abs(dev + i, gc_psx_abs[j+2], 128);						 * This needs to be debugged properly,						 * maybe fuzz processing needs to be done in input_sync()						 *				 --vojtech						 */					}					for (j = 0; j < 8; j++)						input_report_key(dev + i, gc_psx_btn[j], ~data_psx[i][1] & (1 << j));					input_report_key(dev + i, BTN_START,  ~data_psx[i][0] & 0x08);					input_report_key(dev + i, BTN_SELECT, ~data_psx[i][0] & 0x01);					input_sync(dev + i);					break;				case 0: /* not a pad, ignore */					break;			}		}	}	mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);}static int gc_open(struct input_dev *dev){	struct gc *gc = dev->private;	if (!gc->used++) {		parport_claim(gc->pd);		parport_write_control(gc->pd->port, 0x04);		mod_timer(&gc->timer, jiffies + GC_REFRESH_TIME);	}	return 0;}static void gc_close(struct input_dev *dev){	struct gc *gc = dev->private;	if (!--gc->used) {		del_timer(&gc->timer);		parport_write_control(gc->pd->port, 0x00);		parport_release(gc->pd);	}}static struct gc __init *gc_probe(int *config, int nargs){	struct gc *gc;	struct parport *pp;	int i, j;	if (config[0] < 0)		return NULL;	if (nargs < 2) {		printk(KERN_ERR "gamecon.c: at least one device must be specified\n");		return NULL;	}	pp = parport_find_number(config[0]);	if (!pp) {		printk(KERN_ERR "gamecon.c: no such parport\n");		return NULL;	}	if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL))) {		parport_put_port(pp);		return NULL;	}	memset(gc, 0, sizeof(struct gc));	gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);	parport_put_port(pp);	if (!gc->pd) {		printk(KERN_ERR "gamecon.c: parport busy already - lp.o loaded?\n");		kfree(gc);		return NULL;	}	parport_claim(gc->pd);	init_timer(&gc->timer);	gc->timer.data = (long) gc;	gc->timer.function = gc_timer;	for (i = 0; i < nargs - 1; i++) {		if (!config[i + 1])			continue;		if (config[i + 1] < 1 || config[i + 1] > GC_MAX) {			printk(KERN_WARNING "gamecon.c: Pad type %d unknown\n", config[i + 1]);			continue;		}                gc->dev[i].private = gc;                gc->dev[i].open = gc_open;                gc->dev[i].close = gc_close;                gc->dev[i].evbit[0] = BIT(EV_KEY) | BIT(EV_ABS);		for (j = 0; j < 2; j++) {			set_bit(ABS_X + j, gc->dev[i].absbit);			gc->dev[i].absmin[ABS_X + j] = -1;			gc->dev[i].absmax[ABS_X + j] =  1;		}		gc->pads[0] |= gc_status_bit[i];		gc->pads[config[i + 1]] |= gc_status_bit[i];		switch(config[i + 1]) {			case GC_N64:				for (j = 0; j < 10; j++)					set_bit(gc_n64_btn[j], gc->dev[i].keybit);				for (j = 0; j < 2; j++) {					set_bit(ABS_X + j, gc->dev[i].absbit);					gc->dev[i].absmin[ABS_X + j] = -127;					gc->dev[i].absmax[ABS_X + j] =  126;					gc->dev[i].absflat[ABS_X + j] = 2;					set_bit(ABS_HAT0X + j, gc->dev[i].absbit);					gc->dev[i].absmin[ABS_HAT0X + j] = -1;					gc->dev[i].absmax[ABS_HAT0X + j] =  1;				}				break;			case GC_SNES:				for (j = 4; j < 8; j++)					set_bit(gc_snes_btn[j], gc->dev[i].keybit);			case GC_NES:				for (j = 0; j < 4; j++)					set_bit(gc_snes_btn[j], gc->dev[i].keybit);				break;			case GC_MULTI2:				set_bit(BTN_THUMB, gc->dev[i].keybit);			case GC_MULTI:				set_bit(BTN_TRIGGER, gc->dev[i].keybit);				break;			case GC_PSX:			case GC_DDR:				if(config[i + 1] == GC_DDR) {					for (j = 0; j < 4; j++)						set_bit(gc_psx_ddr_btn[j], gc->dev[i].keybit);				} else {					for (j = 0; j < 6; j++) {						set_bit(gc_psx_abs[j], gc->dev[i].absbit);						gc->dev[i].absmin[gc_psx_abs[j]] = 4;						gc->dev[i].absmax[gc_psx_abs[j]] = 252;						gc->dev[i].absflat[gc_psx_abs[j]] = 2;					}				}				for (j = 0; j < 12; j++)					set_bit(gc_psx_btn[j], gc->dev[i].keybit);				break;		}		sprintf(gc->phys[i], "%s/input%d", gc->pd->port->name, i);                gc->dev[i].name = gc_names[config[i + 1]];		gc->dev[i].phys = gc->phys[i];                gc->dev[i].id.bustype = BUS_PARPORT;                gc->dev[i].id.vendor = 0x0001;                gc->dev[i].id.product = config[i + 1];                gc->dev[i].id.version = 0x0100;	}	parport_release(gc->pd);	if (!gc->pads[0]) {		parport_unregister_device(gc->pd);		kfree(gc);		return NULL;	}	for (i = 0; i < 5; i++)		if (gc->pads[0] & gc_status_bit[i]) {			input_register_device(gc->dev + i);			printk(KERN_INFO "input: %s on %s\n", gc->dev[i].name, gc->pd->port->name);		}	return gc;}int __init gc_init(void){	gc_base[0] = gc_probe(gc, gc_nargs);	gc_base[1] = gc_probe(gc_2, gc_nargs_2);	gc_base[2] = gc_probe(gc_3, gc_nargs_3);	if (gc_base[0] || gc_base[1] || gc_base[2])		return 0;	return -ENODEV;}void __exit gc_exit(void){	int i, j;	for (i = 0; i < 3; i++)		if (gc_base[i]) {			for (j = 0; j < 5; j++)				if (gc_base[i]->pads[0] & gc_status_bit[j])					input_unregister_device(gc_base[i]->dev + j);			parport_unregister_device(gc_base[i]->pd);		}}module_init(gc_init);module_exit(gc_exit);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -