// Generic control stuff (keyboard+joystick)

#include <stdio.h>		// kbhit, getch
#include "keyboard.h"
#include "joy.h"
#include "control.h"





#define		KEYBOARD_START		1
#define		KEYBOARD_END		255
#define		JOYSTICK_START		256
#define		JOYSTICK_END		265







// Key names
static const char *keynames[128] = {
	"...",
	"Escape",
	"1",
	"2",
	"3",
	"4",
	"5",
	"6",
	"7",
	"8",
	"9",
	"0",
	"-",
	"=",
	"Backspace",
	"Tab",
	"Q",
	"W",
	"E",
	"R",
	"T",
	"Y",
	"U",
	"I",
	"O",
	"P",
	"[",
	"]",
	"Enter",
	"CTRL",
	"A",
	"S",
	"D",
	"F",
	"G",
	"H",
	"J",
	"K",
	"L",
	";",
	"'",
	"~",
	"Left shift",
	"\\",
	"Z",
	"X",
	"C",
	"V",
	"B",
	"N",
	"M",
	",",
	".",
	"/",
	"Right shift",
	"*",
	"ALT",
	"Space",
	"Capslock",
	"F1",
	"F2",
	"F3",
	"F4",
	"F5",
	"F6",
	"F7",
	"F8",
	"F9",
	"F10",
	"Num lock",
	"Scroll lock",
	"Home",
	"Uparrow",
	"PgUp",
	"-",
	"Leftarrow",
	"5",
	"Rightarrow",
	"+",
	"End",
	"Downarrow",
	"PgDn",
	"Ins",
	"Del",
	"<key 84>",
	"<key 85>",
	"<key 86>",
	"F11",
	"F12",
	"<key 89>",
	"<key 90>",
	"Logo left",
	"Logo right",
	"Popup",
	"<key 94>",
	"<key 95>",
	"<key 96>",
	"<key 97>",
	"<key 98>",
	"<key 99>",
	"<key 100>",
	"<key 101>",
	"<key 102>",
	"<key 103>",
	"<key 104>",
	"<key 105>",
	"<key 106>",
	"<key 107>",
	"<key 108>",
	"<key 109>",
	"<key 110>",
	"<key 111>",
	"<key 112>",
	"<key 113>",
	"<key 114>",
	"<key 115>",
	"<key 116>",
	"<key 117>",
	"<key 118>",
	"<key 119>",
	"<key 120>",
	"<key 121>",
	"<key 122>",
	"<key 123>",
	"<key 124>",
	"<key 125>",
	"<key 126>",
	"<key 127>"
};

static const char *joynames[10] = {
	"Joy Fire 1",
	"Joy Fire 2",
	"Joy Fire 3",
	"Joy Fire 4",
	"Joy Up",
	"Joy Down",
	"Joy Left",
	"Joy Right",
	"Joy Fire 5",
	"Joy Fire 6"
};




static int usejoy;





static int flag_to_index(unsigned long flag){
	int index = 0;
	unsigned long bit = 1;

	while(!((bit<<index)&flag) && index<31) ++index;
	return index;
}






#ifdef _XBOX

volatile char keytable[256] ;

#endif ;



void control_exit(){
#ifndef _XBOX
	keyboard_exit();
	joy_exit();
	usejoy = 0;
	while(kbhit()) getch();
#endif
}



void control_init(int joy_enable){
#ifndef _XBOX
	control_exit();
	keyboard_init();
	keyboard_enable_extended(1);
	if(joy_enable) usejoy = joy_init();
#else
	usejoy = 1 ;
	memset( keytable, 0, 256 ) ;
#endif
}



int control_usejoy(int enable){
#ifndef _XBOX
	usejoy = enable;
	if(usejoy) return joy_init();
	joy_exit();
	return 0;
#else
	return 1 ;
#endif
}


int control_getjoyenabled(){
	return usejoy;
}




void control_setkey(s_playercontrols * pcontrols, unsigned int flag, int key){
	if(!pcontrols) return;
	pcontrols->settings[flag_to_index(flag)] = key;
	pcontrols->keyflags = pcontrols->newkeyflags = 0;
}



// Scan input for newly-pressed keys.
// Return value:
// 0  = no key was pressed
// >0 = key code for pressed key
// <0 = error
int control_scankey(){
	static int ready = 0;
	int k=0, b=0;
	int index;

	//k = keyboard_getlastkey();
	if(usejoy) b = joy_getstate();

	if(ready && (k|b)){
		ready = 0;
		if(k) return k;
		if(b & JOY_1) return CONTROL_JOY_1;
		if(b & JOY_2) return CONTROL_JOY_2;
		if(b & JOY_3) return CONTROL_JOY_3;
		if(b & JOY_4) return CONTROL_JOY_4;
		if(b & JOY_5) return CONTROL_JOY_5;
		if(b & JOY_6) return CONTROL_JOY_6;
		if(b & JOY_UP) return CONTROL_JOY_UP;
		if(b & JOY_DOWN) return CONTROL_JOY_DOWN;
		if(b & JOY_LEFT) return CONTROL_JOY_LEFT;
		if(b & JOY_RIGHT) return CONTROL_JOY_RIGHT;
		return -1;
	}
	ready = (!(k|b));
	return 0;
}





char * control_getkeyname(unsigned int keycode){

	if(keycode >= KEYBOARD_START && keycode <= KEYBOARD_END){
		return keynames[keycode % 128];
	}
	if(keycode >= JOYSTICK_START && keycode <= JOYSTICK_END){
		return joynames[(keycode - JOYSTICK_START) % 10];
	}
	return "...";
}





#ifdef _XBOX

unsigned int xbox_check_events();

unsigned long joy_getstate()
{
	return xbox_check_events() ;
}
#endif

void control_update(s_playercontrols ** playercontrols, int numplayers){

	unsigned long k;
	unsigned long jf[2];
	unsigned long i;
	int player;
	int t;
	s_playercontrols * pcontrols;
#ifdef _XBOX
	int kb_break = 0 ;
	jf[0] = joy_getstate();
	jf[1] = (jf[0]>>16)&0xFFFF ;
	jf[0] &= 0xFFFF ;
#else
	int kb_break = keyboard_checkbreak();
	if(usejoy) jf[0] = joy_getstate();
	if(jf[0] == 0xFFFFFFFF) usejoy = 0;
#endif


	for(player=0; player<numplayers; player++){

		pcontrols = playercontrols[player];

		k = 0;

		for(i=0; i<32; i++){
			t = pcontrols->settings[i];
			if(t >= KEYBOARD_START && t <= KEYBOARD_END){
				if(keytable[t]) k |= (1<<i);
			}
		}
		pcontrols->kb_break = kb_break;


		if(usejoy){
			for(i=0; i<32; i++){
				t = pcontrols->settings[i];
				switch(t){
					case CONTROL_JOY_1:
						if(jf[player] & JOY_1) k |= (1<<i);
						break;
					case CONTROL_JOY_2:
						if(jf[player] & JOY_2) k |= (1<<i);
						break;
					case CONTROL_JOY_3:
						if(jf[player] & JOY_3) k |= (1<<i);
						break;
					case CONTROL_JOY_4:
						if(jf[player] & JOY_4) k |= (1<<i);
						break;
					case CONTROL_JOY_UP:
						if(jf[player] & JOY_UP) k |= (1<<i);
						break;
					case CONTROL_JOY_DOWN:
						if(jf[player] & JOY_DOWN) k |= (1<<i);
						break;
					case CONTROL_JOY_LEFT:
						if(jf[player] & JOY_LEFT) k |= (1<<i);
						break;
					case CONTROL_JOY_RIGHT:
						if(jf[player] & JOY_RIGHT) k |= (1<<i);
						break;
					case CONTROL_JOY_5:
						if(jf[player] & JOY_5) k |= (1<<i);
						break;
					case CONTROL_JOY_6:
						if(jf[player] & JOY_6) k |= (1<<i);
						break;
				}
			}
		}

		pcontrols->newkeyflags = k & (~pcontrols->keyflags);
		pcontrols->keyflags = k;
	}
}













