# Wrote by Holguer A Becerra # Semillero ADT-UPB # Pontificia Bolivariana University # PSX to serial converter, Keyboard Emulador # Platform: DE0-NANO # https://sites.google.com/site/semilleroadt/de0-nano-psx import threading import serial, math,time import time,win32api,win32con #keyboard virtual and scan codes KEYBOARD_HOLD = 0x1 KEYBOARD_UP_EVEN = 0x2 VK_LBUTTON = 0x1 VK_RBUTTON = 0x2 VK_CTRLBREAK = 0x3 VK_MBUTTON = 0x4 VK_BACKSPACE = 0x8 VK_TAB = 0x9 VK_ENTER = 0xD VK_SHIFT = 0x10 VK_CONTROL = 0x11 VK_ALT = 0x12 VK_PAUSE = 0x13 VK_CAPSLOCK = 0x14 VK_ESCAPE = 0x1B VK_SPACE = 0x20 VK_PAGEUP = 0x21 VK_PAGEDOWN = 0x22 VK_END = 0x23 VK_HOME = 0x24 VK_LEFT = 0x25 VK_UP = 0x26 VK_RIGHT = 0x27 VK_DOWN = 0x28 VK_PRINTSCREEN = 0x2C VK_INSERT = 0x2D VK_DELETE = 0x2E VK_0 = 0x30 VK_1 = 0x31 VK_2 = 0x32 VK_3 = 0x33 VK_4 = 0x34 VK_5 = 0x35 VK_6 = 0x36 VK_7 = 0x37 VK_8 = 0x38 VK_9 = 0x39 VK_A = 0x41 VK_B = 0x42 VK_C = 0x43 VK_D = 0x44 VK_E = 0x45 VK_F = 0x46 VK_G = 0x47 VK_H = 0x48 VK_I = 0x49 VK_J = 0x4A VK_K = 0x4B VK_L = 0x4C VK_M = 0x4D VK_N = 0x4E VK_O = 0x4F VK_P = 0x50 VK_Q = 0x51 VK_R = 0x52 VK_S = 0x53 VK_T = 0x54 VK_U = 0x55 VK_V = 0x56 VK_W = 0x57 VK_X = 0x58 VK_Y = 0x59 VK_Z = 0x5A VK_LWINDOWS = 0x5B VK_RWINDOWS = 0x5C VK_APPSPOPUP = 0x5D VK_NUMPAD_0 = 0x60 VK_NUMPAD_1 = 0x61 VK_NUMPAD_2 = 0x62 VK_NUMPAD_3 = 0x63 VK_NUMPAD_4 = 0x64 VK_NUMPAD_5 = 0x65 VK_NUMPAD_6 = 0x66 VK_NUMPAD_7 = 0x67 VK_NUMPAD_8 = 0x68 VK_NUMPAD_9 = 0x69 VK_NUMPAD_MULTIPLY = 0x6A VK_NUMPAD_ADD = 0x6B VK_NUMPAD_PLUS = 0x6B VK_NUMPAD_SUBTRACT = 0x6D VK_NUMPAD_MINUS = 0x6D VK_NUMPAD_MOINS = 0x6D VK_NUMPAD_DECIMAL = 0x6E VK_NUMPAD_POINT = 0x6E VK_NUMPAD_DIVIDE = 0x6F VK_F1 = 0x70 VK_F2 = 0x71 VK_F3 = 0x72 VK_F4 = 0x73 VK_F5 = 0x74 VK_F6 = 0x75 VK_F7 = 0x76 VK_F8 = 0x77 VK_F9 = 0x78 VK_F10 = 0x79 VK_F11 = 0x7A VK_F12 = 0x7B VK_NUMLOCK = 0x90 VK_SCROLL = 0x91 VK_LSHIFT = 0xA0 VK_RSHIFT = 0xA1 VK_LCONTROL = 0xA2 VK_RCONTROL = 0xA3 VK_LALT = 0xA4 VK_RALT = 0xA5 VK_POINTVIRGULE = 0xBA VK_ADD = 0xBB VK_PLUS = 0xBB VK_EQUAL = 0xBB VK_VIRGULE = 0xBC VK_SUBTRACT = 0xBD VK_MINUS = 0xBD VK_MOINS = 0xBD VK_UNDERLINE = 0xBD VK_POINT = 0xBE VK_SLASH = 0xBF VK_TILDE = 0xC0 VK_LEFTBRACKET = 0xDB VK_BACKSLASH = 0xDC VK_RIGHTBRACKET = 0xDD VK_QUOTE = 0xDE VK_APOSTROPHE = 0xDE VS_Q = 16 VS_W = 17 VS_E = 18 VS_R = 19 VS_T = 20 VS_Y = 21 VS_U = 22 VS_I = 23 VS_0 = 24 VS_P = 25 VS_A = 30 VS_S = 31 VS_D = 32 VS_F = 33 VS_G = 34 VS_H = 35 VS_J = 36 VS_K = 37 VS_L = 38 VS_Z = 44 VS_X = 45 VS_C = 46 VS_V = 47 VS_B = 48 VS_N = 49 VS_M = 50 VS_UP = 200 VS_DOWN = 208 VS_LEFT = 203 VS_RIGHT = 205 VS_PAUSE = 197 VS_SPACE = 57 VS_ENTER = 28 VS_ESCAPE = 1 VS_00 = 11 VS_1 = 2 VS_2 = 3 VS_3 = 4 VS_4 = 5 VS_5 = 6 VS_6 = 7 VS_7 = 8 VS_8 = 9 VS_9 = 10 #mouse events CLICK_LEFTDOWN = 0x2 CLICK_LEFTUP = 0x4 CLICK_MIDDLEDOWN = 0x20 CLICK_MIDDLEUP = 0x40 CLICK_RIGHTDOWN = 0x8 CLICK_RIGHTUP = 0x10 MOUSEEVENTF_MOVE = 0x1 # buttons code BUTTON_X=128 BUTTON_O=64 BUTTON_TRIANGLE=32 BUTTON_SQUARE=16 BUTTON_L1=8 BUTTON_L2=4 BUTTON_R1=2 BUTTON_R2=1 BUTTON_UP=128 | 512 BUTTON_DOWN=64 | 512 BUTTON_RIGHT=32 | 512 BUTTON_LEFT=16 | 512 BUTTON_L3=8 | 512 BUTTON_R3=4 | 512 BUTTON_SELECT=2 | 512 BUTTON_START=1 | 512 AN_L_UD= 1 | 512 AN_L_LR= 2 | 512 AN_R_UD= 3 | 512 AN_R_LR= 4 | 512 #buttons received analog_axis_l_lr_med=0#analogic axis left, left right movement analog_axis_l_ud_med=0#analogic axis left, up down movement analog_axis_r_lr_med=0#analogic axis right, left right movement analog_axis_r_ud_med=0#analogic axis right, up down movement analog_axis_l_lr=0#analogic axis left, left right movement analog_axis_l_ud=0#analogic axis left, up down movement analog_axis_r_lr=0#analogic axis right, left right movement analog_axis_r_ud=0#analogic axis right, up down movement x_c_tri_sq_l1_l2_r1_r2=0 #buttons[X,O,/\,[],L1,L2,R1,R2] u_d_r_l_l3_r3_sel_st=0#buttons[UP,DOWN,RIGHT,LEFT,L3,R3,SELECT,START] #vars packet1=[0,0,0,0] packet2=[0,0,0,0,0,0] contador=0 key=0; checksum1=0 checksum1_to_compare=0 checksum2=0 checksum2_to_compare=0 #Class for emule key class emule_key(threading.Thread): def __init__(self,vk,vs,key_p,delay): self.last = 0 self.vk = vk self.vs = vs self.key_p=key_p self.delay=delay threading.Thread.__init__(self) def stop(self): self._Thread__stop() def run(self): while True: if(self.key_p & 512): if(u_d_r_l_l3_r3_sel_st & ((self.key_p & 255))): win32api.keybd_event(self.vk, self.vs, 0, 0) self.last = 1 #time.sleep(self.delay) if((u_d_r_l_l3_r3_sel_st & ((self.key_p & 255)))==0): if(self.last ==1): win32api.keybd_event(self.vk, self.vs, 0x2, 0) self.last = 0 else: if(x_c_tri_sq_l1_l2_r1_r2 & ((self.key_p & 255))): win32api.keybd_event(self.vk, self.vs, 0, 0) self.last=1 #time.sleep(self.delay) if((x_c_tri_sq_l1_l2_r1_r2 & ((self.key_p & 255)))==0): if(self.last ==1): win32api.keybd_event(self.vk, self.vs, 0x2, 0) self.last = 0 time.sleep(self.delay) class emule_mouse(threading.Thread): def __init__(self,vk,key_p,sens,delay): self.last = 0 self.vk = vk self.key_p=key_p self.delay=delay self.sens=sens threading.Thread.__init__(self) def stop(self): self._Thread__stop() def run(self): while True: if(self.vk==MOUSEEVENTF_MOVE): if(self.key_p==AN_L_UD): win32api.mouse_event(self.vk, 0, analog_axis_l_ud/self.sens-analog_axis_l_ud_med/self.sens, 0, 0) elif(self.key_p==AN_R_UD): win32api.mouse_event(self.vk, 0, analog_axis_r_ud/self.sens-analog_axis_r_ud_med/self.sens, 0, 0) elif(self.key_p==AN_L_LR): win32api.mouse_event(self.vk, analog_axis_l_lr/self.sens-analog_axis_l_lr_med/self.sens, 0, 0, 0) elif(self.key_p==AN_R_LR): win32api.mouse_event(self.vk, analog_axis_r_lr/self.sens-analog_axis_r_lr_med/self.sens, 0, 0, 0) elif(self.key_p & 512): if(u_d_r_l_l3_r3_sel_st & ((self.key_p & 255))): win32api.mouse_event(self.vk, 0, 0, 0, 0) self.last = 1 #time.sleep(self.delay) if((u_d_r_l_l3_r3_sel_st & ((self.key_p & 255)))==0): if(self.last == 1): win32api.mouse_event(self.vk*2, 0, 0, 0,0) self.last = 0 else: if(x_c_tri_sq_l1_l2_r1_r2 & ((self.key_p & 255))): win32api.mouse_event(self.vk, 0, 0, 0,0) self.last = 1 #time.sleep(self.delay) if((x_c_tri_sq_l1_l2_r1_r2 & ((self.key_p & 255)))==0): if(self.last == 1): win32api.mouse_event(self.vk*2, 0, 0, 0,0) self.last = 0 time.sleep(self.delay) ser = serial.Serial('COM9', 9600) #ser.parity=serial.PARITY_EVEN #PADDLE key1_1 = emule_key(VK_W,VS_W,BUTTON_UP,0.08) key1_2 = emule_key(VK_D,VS_D,BUTTON_RIGHT,0.08) key1_3 = emule_key(VK_S,VS_S,BUTTON_DOWN,0.08) key1_4 = emule_key(VK_A,VS_A,BUTTON_LEFT,0.08) #BUTTONS key2_1 = emule_key(VK_J,VS_J,BUTTON_O,0.08) #key2_2 = emule_key(VK_K,VS_K,BUTTON_X,0.08) key2_2 = emule_mouse(CLICK_LEFTDOWN,BUTTON_X,0,0.05) key2_3 = emule_key(VK_L,VS_L,BUTTON_SQUARE,0.08) key2_4 = emule_key(VK_I,VS_I,BUTTON_TRIANGLE,0.08) #TOP BUTTONS key3_1 = emule_key(VK_R,VS_R,BUTTON_L1,0.08) key3_2 = emule_key(VK_T,VS_T,BUTTON_L2,0.08) key3_3 = emule_key(VK_Y,VS_Y,BUTTON_R1,0.08) key3_4 = emule_key(VK_U,VS_U,BUTTON_R2,0.08) #MIDDLE BUTTONS key4_1 = emule_key(VK_M,VS_M,BUTTON_L3,0.1) key4_2 = emule_key(VK_C,VS_C,BUTTON_R3,0.1) key4_3 = emule_key(VK_B,VS_B,BUTTON_SELECT,0.1) key4_4 = emule_key(VK_N,VS_N,BUTTON_START,0.1) #emule mouse mouse1_x_axis= emule_mouse(MOUSEEVENTF_MOVE,AN_R_LR,10,0.01) mouse1_y_axis= emule_mouse(MOUSEEVENTF_MOVE,AN_R_UD,10,0.01) #AJUSTAR AXIS DE LOS ANALOGICOS print "Ajustando Axis porfavor no mueva ningun analogico" calibre=7 while(calibre>0): key=ord(ser.readline(1)) if(key==27): packet2[0]=ord(ser.readline(1)) packet2[1]=ord(ser.readline(1)) packet2[2]=ord(ser.readline(1)) packet2[3]=ord(ser.readline(1)) packet2[4]=ord(ser.readline(1)) packet2[5]=ord(ser.readline(1)) checksum2=(key+packet2[0]+packet2[1]+packet2[2]+packet2[3]+packet2[4]) & 255 checksum2_to_compare=(packet2[5]&127)+((packet2[0] & 1)<<7) if(checksum2==checksum2_to_compare): analog_axis_l_ud_med= (packet2[1] & 127) | (((packet2[0]>>1)&1)<<7) analog_axis_l_lr_med= (packet2[2] & 127) | (((packet2[0]>>2)&1)<<7) analog_axis_r_ud_med= (packet2[3] & 127) | (((packet2[0]>>3)&1)<<7) analog_axis_r_lr_med= (packet2[4] & 127) | (((packet2[0]>>4)&1)<<7) calibre=calibre-1 ser.flushInput() print analog_axis_r_lr_med print analog_axis_l_lr_med print analog_axis_l_ud_med print analog_axis_r_ud_med print "Termino Ajuste de Axis, Empezando en 5 seg.. emulacion" time.sleep(5) #START THREADS key1_1.start() key1_2.start() key1_3.start() key1_4.start() key2_1.start() key2_2.start() key2_3.start() key2_4.start() key3_1.start() key3_2.start() key3_3.start() key3_4.start() key4_1.start() key4_2.start() key4_3.start() key4_4.start() mouse1_x_axis.start() mouse1_y_axis.start() #FREE ser.flushInput() while (key1_1.isAlive()):# & begin2.isAlive()): try: key=ord(ser.readline(1)) if(key==17): packet1[0]=ord(ser.readline(1)) packet1[1]=ord(ser.readline(1)) packet1[2]=ord(ser.readline(1)) packet1[3]=ord(ser.readline(1)) checksum1=(key+packet1[0]+packet1[1]+packet1[2]) & 255 checksum1_to_compare=(packet1[3]&127)+((packet1[0] & 1)<<7) #print str(checksum1)+ ", " +str(checksum1_to_compare) if(checksum1==checksum1_to_compare): x_c_tri_sq_l1_l2_r1_r2=((packet1[1]>>3)& 15) | ((packet1[1] & 1)<<7) | ((packet1[2] & 7)<<4) u_d_r_l_l3_r3_sel_st=(((packet1[2]>>3)&15)<<4) | (((packet1[0]>>3)&3)<<2) | ((packet1[1]>>1)&3) #if(x_c_tri_sq_l1_l2_r1_r2 & 128): #print "Se esta oprimiendo: x" #if(x_c_tri_sq_l1_l2_r1_r2 & 64): #print "Se esta oprimiendo: circle" #if(x_c_tri_sq_l1_l2_r1_r2 & 32): #print "Se esta oprimiendo: triangle" #if(x_c_tri_sq_l1_l2_r1_r2 & 16): #print "Se esta oprimiendo: square" #if(x_c_tri_sq_l1_l2_r1_r2 & 8): #print "Se esta oprimiendo: L1" #if(x_c_tri_sq_l1_l2_r1_r2 & 4): #print "Se esta oprimiendo: L2" #if(x_c_tri_sq_l1_l2_r1_r2 & 2): #print "Se esta oprimiendo: R1" #if(x_c_tri_sq_l1_l2_r1_r2 & 1): #print "Se esta oprimiendo: R2" #if(u_d_r_l_l3_r3_sel_st & 128): #print "Se esta oprimiendo: UP" #if(u_d_r_l_l3_r3_sel_st & 64): #print "Se esta oprimiendo: DOWN" #if(u_d_r_l_l3_r3_sel_st & 32): #print "Se esta oprimiendo: RIGHT" #if(u_d_r_l_l3_r3_sel_st & 16): #print "Se esta oprimiendo: LEFT" #if(u_d_r_l_l3_r3_sel_st & 8): #print "Se esta oprimiendo: L3" #if(u_d_r_l_l3_r3_sel_st & 4): #print "Se esta oprimiendo: R3" #if(u_d_r_l_l3_r3_sel_st & 2): #print "Se esta oprimiendo: SELECT" #if(u_d_r_l_l3_r3_sel_st & 1): #print "Se esta oprimiendo: START" #print "buen dato 1\n" #print("eating..." + str(contador) + " " + str(key)) #print(packet2[3]) elif(key==27): packet2[0]=ord(ser.readline(1)) packet2[1]=ord(ser.readline(1)) packet2[2]=ord(ser.readline(1)) packet2[3]=ord(ser.readline(1)) packet2[4]=ord(ser.readline(1)) packet2[5]=ord(ser.readline(1)) checksum2=(key+packet2[0]+packet2[1]+packet2[2]+packet2[3]+packet2[4]) & 255 checksum2_to_compare=(packet2[5]&127)+((packet2[0] & 1)<<7) if(checksum2==checksum2_to_compare): analog_axis_l_ud= (packet2[1] & 127) | (((packet2[0]>>1)&1)<<7) analog_axis_l_lr= (packet2[2] & 127) | (((packet2[0]>>2)&1)<<7) analog_axis_r_ud= (packet2[3] & 127) | (((packet2[0]>>3)&1)<<7) analog_axis_r_lr= (packet2[4] & 127) | (((packet2[0]>>4)&1)<<7) #if(u_d_r_l_l3_r3_sel_st & 16):# if left print the value of analog left up down #print "anal_l_ud:"+bin(analog_axis_l_ud) #if(u_d_r_l_l3_r3_sel_st & 32):# if right print the value of analog left right left #print "anal_l_ud:"+bin(analog_axis_l_lr) #if(u_d_r_l_l3_r3_sel_st & 128):# if up print the value of analog right up down #print "anal_l_ud:"+bin(analog_axis_r_ud) #if(u_d_r_l_l3_r3_sel_st & 64):# if down print the value of analog right right left #print "anal_l_ud:"+bin(analog_axis_r_lr) #print "buen dato 2\n" #print((packet2[5])) #descarto N paquetes en un tiempo. if(contador==100): ser.flushInput() contador=0 ##print("eating..." + str(contador) + " " + str(key)) contador+=1 except KeyboardInterrupt: print "Ctrl-c received! kill threads..." key1_1.stop() key1_2.stop() key1_3.stop() key1_4.stop() key2_1.stop() key2_2.stop() key2_3.stop() key2_4.stop() key3_1.stop() key3_2.stop() key3_3.stop() key3_4.stop() key4_1.stop() key4_2.stop() key4_3.stop() key4_4.stop() mouse1_x_axis.stop() mouse1_y_axis.stop() pass if ser.isOpen(): ser.close()