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

📄 gamecon.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
		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[7]) - !!(s & data[6]));				input_report_abs(dev + i, ABS_Y, !!(s & data[5]) - !!(s & data[4]));			}			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]]);		}	}/* * 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[3]) - !!(s & data[2]));				input_report_abs(dev + i, ABS_Y, !!(s & data[1]) - !!(s & data[0]));				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]);		}	}/* * PSX controllers */	if (gc->pads[GC_PSX]) {		for (i = 0; i < 5; i++)	       		if (gc->pads[GC_PSX] & gc_status_bit[i])				break; 		switch (gc_psx_read_packet(gc, 6, data)) {			case GC_PSX_ANALOGG:					for (j = 0; j < 4; j++)					input_report_abs(dev + i, gc_psx_abs[j], data[j + 2]);				input_report_abs(dev + i, ABS_HAT0X, !!(data[0]&0x20) - !!(data[0]&0x80));				input_report_abs(dev + i, ABS_HAT0Y, !!(data[0]&0x40) - !!(data[0]&0x10));				for (j = 0; j < 8; j++)					input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << i));				input_report_key(dev + i, BTN_START,  ~data[0] & 0x08);				input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01);				break;			case GC_PSX_ANALOGR:				input_report_key(dev + i, BTN_THUMB,  ~data[0] & 0x04);				input_report_key(dev + i, BTN_THUMB2, ~data[0] & 0x02);			case GC_PSX_NORMAL:			case GC_PSX_NEGCON:				input_report_abs(dev + i, ABS_X, 128 + !!(data[0] & 0x20) * 127 - !!(data[0] & 0x80) * 128);				input_report_abs(dev + i, ABS_Y, 128 + !!(data[0] & 0x40) * 127 - !!(data[0] & 0x10) * 128);				for (j = 0; j < 8; j++)					input_report_key(dev + i, gc_psx_btn[j], ~data[1] & (1 << i));				input_report_key(dev + i, BTN_START,  ~data[0] & 0x08);				input_report_key(dev + i, BTN_SELECT, ~data[0] & 0x01);				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){	struct gc *gc;	struct parport *pp;	int i, j, psx, pbtn;	unsigned char data[2];	if (config[0] < 0)		return NULL;	for (pp = parport_enumerate(); pp && (config[0] > 0); pp = pp->next)		config[0]--;	if (!pp) {		printk(KERN_ERR "gamecon.c: no such parport\n");		return NULL;	}	if (!(gc = kmalloc(sizeof(struct gc), GFP_KERNEL)))		return NULL;	memset(gc, 0, sizeof(struct gc));	gc->pd = parport_register_device(pp, "gamecon", NULL, NULL, NULL, PARPORT_DEV_EXCL, NULL);	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 < 5; 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:								psx = gc_psx_read_packet(gc, 2, data);				switch(psx) {					case GC_PSX_NEGCON:						config[i + 1] += 1;					case GC_PSX_NORMAL:						pbtn = 10;						break;					case GC_PSX_ANALOGG:					case GC_PSX_ANALOGR:						config[i + 1] += 2;						pbtn = 12;						for (j = 0; j < 6; j++) {							psx = gc_psx_abs[j];							set_bit(psx, gc->dev[i].absbit);							gc->dev[i].absmin[psx] = 4;							gc->dev[i].absmax[psx] = 252;							gc->dev[i].absflat[psx] = 2;						}						break;					case -1:						gc->pads[GC_PSX] &= ~gc_status_bit[i];						pbtn = 0;						printk(KERN_ERR "gamecon.c: No PSX controller found.\n");						break;					default:						gc->pads[GC_PSX] &= ~gc_status_bit[i];						pbtn = 0;						printk(KERN_WARNING "gamecon.c: Unsupported PSX controller %#x,"							" please report to <vojtech@suse.cz>.\n", psx);				}				for (j = 0; j < pbtn; j++)					set_bit(gc_psx_btn[j], gc->dev[i].keybit);				break;		}                gc->dev[i].name = gc_names[config[i + 1]];                gc->dev[i].idbus = BUS_PARPORT;                gc->dev[i].idvendor = 0x0001;                gc->dev[i].idproduct = config[i + 1];                gc->dev[i].idversion = 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%d: %s on %s\n", gc->dev[i].number, gc->dev[i].name, gc->pd->port->name);		}	return gc;}#ifndef MODULEint __init gc_setup(char *str){	int i, ints[7];	get_options(str, ARRAY_SIZE(ints), ints);	for (i = 0; i <= ints[0] && i < 6; i++) gc[i] = ints[i + 1];	return 1;}int __init gc_setup_2(char *str){	int i, ints[7];	get_options(str, ARRAY_SIZE(ints), ints);	for (i = 0; i <= ints[0] && i < 6; i++) gc_2[i] = ints[i + 1];	return 1;}int __init gc_setup_3(char *str){	int i, ints[7];	get_options(str, ARRAY_SIZE(ints), ints);	for (i = 0; i <= ints[0] && i < 6; i++) gc_3[i] = ints[i + 1];	return 1;}__setup("gc=", gc_setup);__setup("gc_2=", gc_setup_2);__setup("gc_3=", gc_setup_3);#endifint __init gc_init(void){	gc_base[0] = gc_probe(gc);	gc_base[1] = gc_probe(gc_2);	gc_base[2] = gc_probe(gc_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 + -