From eb28d884d099894e91ca3321de0c9b1ea3e3458f Mon Sep 17 00:00:00 2001 From: kaqu Date: Fri, 20 Nov 2020 18:38:54 +0100 Subject: [PATCH] 1st game loop for pong --- evalgamepad.py | 235 ++++++++++++++++++++++++++++++++++--------------- 1 file changed, 162 insertions(+), 73 deletions(-) diff --git a/evalgamepad.py b/evalgamepad.py index a58b5fe..549703c 100644 --- a/evalgamepad.py +++ b/evalgamepad.py @@ -2,7 +2,7 @@ # # evalgamepad.py -# Reading two USB gamepads & making sense of it ... +# Reading two USB gamepads & making sense of it (try pong)... # #----------------------------------------------------------------------- # 'lsusb' ouput: Bus 002 Device 003: ID 0079:0011 DragonRise Inc. Gamepad @@ -12,7 +12,7 @@ # /dev/input/event7 # -import sys, os, fcntl +import sys, os, fcntl, time import libevdev # Buttons in 'state' @@ -25,6 +25,42 @@ BTN_PINKIE = 32 # [Frontal right] BTN_BASE3 = 64 # [Centre left] BTN_BASE4 = 128 # [Centre right] +GAMEAREA_MIN_X = 0 # Game area definition +GAMEAREA_MAX_X = 1920 # Assume FHD resolution +GAMEAREA_MIN_Y = 0 +GAMEAREA_MAX_Y = 1080 + +def init_player(path): + # Gamepad init. + fd = open(path, "rb") + fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) + dev = libevdev.Device(fd) + + return { + "fd" : fd, # File descriptor to close (later ...) + "dev" : dev, # Actual gamepad of this player + "state" : 0, # Button mask (as above) + "delta_x" : 0, # Current delta setting + "delta_y" : 0, + "x" : GAMEAREA_MAX_X/2, # Current actual position + "y" : GAMEAREA_MAX_Y/2, # Start at center + "w" : 10, + "h" : 100 + } + +def exit_player(player): + player["fd"].close() + +def init_object(x, y, w, h, delta_x, delta_y): + return { + "delta_x" : delta_x, # Current movement + "delta_y" : delta_y, + "x" : x, # Current position + "y" : y, + "w" : w, # Size of object + "h" : h, + } + def print_event(e): print("Event: time {}.{:06d}, ".format(e.sec, e.usec), end='') if e.matches(libevdev.EV_SYN): @@ -37,11 +73,11 @@ def print_event(e): else: print("type {:02x} {} code {:03x} {:20s} value {:4d}".format(e.type.value, e.type.name, e.code.value, e.code.name, e.value)) -def evalgamepad(dev, state, x, y): + +def eval_gamepad(player): bChanged = False - try: - for e in dev.events(): - bChanged = True + try: + for e in player["dev"].events(): #print_event(e) # Event type 1 (EV_KEY) @@ -58,105 +94,158 @@ def evalgamepad(dev, state, x, y): if e.type.value == 1: # Non-Cross events if e.value == 1: # Simple buttons may act as toggles if e.code.value == 288: # BTN_TRIGGER - state = state ^ BTN_TRIGGER + player["state"] = player["state"] ^ BTN_TRIGGER elif e.code.value == 289: # BTN_THUMB - state = state ^ BTN_THUMB + player["state"] = player["state"] ^ BTN_THUMB elif e.code.value == 290: # BTN_THUMB2 - state = state ^ BTN_THUMB2 + player["state"] = player["state"] ^ BTN_THUMB2 elif e.code.value == 291: # BTN_TOP - state = state ^ BTN_TOP + player["state"] = player["state"] ^ BTN_TOP elif e.code.value == 292: # BTN_TOP2 - state = state ^ BTN_TOP2 + player["state"] = player["state"] ^ BTN_TOP2 elif e.code.value == 293: # BTN_PINKIE - state = state ^ BTN_PINKIE + player["state"] = player["state"] ^ BTN_PINKIE elif e.code.value == 296: # BTN_BASE3 - state = state ^ BTN_BASE3 + player["state"] = player["state"] ^ BTN_BASE3 elif e.code.value == 297: # BTN_BASE4 - state = state ^ BTN_BASE4 - + player["state"] = player["state"] ^ BTN_BASE4 + bChanged = True + # Event type 3 (EV_ABS) # Event code 0 (ABS_X) <- Cross: 127=Neutral, 0=[Left], 255=[Right] # Event code 1 (ABS_Y) <- Cross: 127=Neutral, 0=[Top], 255=[Down] elif e.type.value == 3: # EV_ABS if e.code.value == 0: # ABS_X if e.value == 0: - x = x - 1 + player["delta_x"] = player["delta_x"] - 1 elif e.value == 255: - x = x + 1 + player["delta_x"] = player["delta_x"] + 1 else: # 127/Neutral - x = 0 + player["delta_x"] = 0 else: # ABS_Y if e.value == 0: - y = y + 1 + player["delta_y"] = player["delta_y"] + 1 elif e.value == 255: - y = y - 1 + player["delta_y"] = player["delta_y"] - 1 else: # 127/Neutral - y = 0 - - print("State=",state, "X=", x, "Y=", y) + player["delta_y"] = 0 + bChanged = True + + #if bChanged: + # print("State=",player["state"], "X=", player["delta_x"], "Y=", player["delta_y"]) except libevdev.EventsDroppedException: print("Dropped!") - for e in dev.sync(): + for e in player["dev"].sync(): print_event(e) - return bChanged, state, x, y + return bChanged -def evalposition(sum_x, sum_y, delta_x, delta_y): - sum_x = sum_x + delta_x - sum_y = sum_y + delta_y - if sum_x < 0: - sum_x = 0 - elif sum_x > 16384: - sum_x = 16384 - if sum_y < 0: - sum_y = 0 - elif sum_y > 8192: - sum_y = 8192 - return sum_x, sum_y -def gameloop(dev1, dev2): - state1 = 0 - state2 = 0 - x1 = 0 - x2 = 0 - y1 = 0 - y2 = 0 - player1_x = 0 - player2_x = 0 - player1_y = 0 - player2_y = 0 +def eval_position(player): + bChanged = False + sum_x = player["x"] + player["delta_x"]/255 + sum_y = player["y"] + player["delta_y"]/255 + + if sum_x < GAMEAREA_MIN_X: + sum_x = GAMEAREA_MIN_X + elif sum_x + player["w"] > GAMEAREA_MAX_X: + sum_x = GAMEAREA_MAX_X - player["w"] + + if sum_y < GAMEAREA_MIN_Y: + sum_y = GAMEAREA_MIN_Y + elif sum_y + player["h"] > GAMEAREA_MAX_Y: + sum_y = GAMEAREA_MAX_Y - player["h"] + + if (sum_x != player["x"]) or (sum_y != player["y"]): + bChanged = True + player["x"] = sum_x + player["y"] = sum_y + + return bChanged + + +def eval_object(obj): + sum_x = obj["x"] + obj["delta_x"] + sum_y = obj["y"] + obj["delta_y"] + + if sum_x < GAMEAREA_MIN_X: + sum_x = GAMEAREA_MIN_X + obj["delta_x"] = -obj["delta_x"] + elif sum_x + obj["w"] > GAMEAREA_MAX_X: + sum_x = GAMEAREA_MAX_X - obj["w"] + obj["delta_x"] = -obj["delta_x"] + + if sum_y < GAMEAREA_MIN_Y: + sum_y = GAMEAREA_MIN_Y + obj["delta_y"] = -obj["delta_y"] + elif sum_y + obj["h"] > GAMEAREA_MAX_Y: + sum_y = GAMEAREA_MAX_Y - obj["h"] + obj["delta_y"] = -obj["delta_y"] + + obj["x"] = sum_x + obj["y"] = sum_y + + +def draw_objects(ball, player1, player2): # Update objects on playground + print("\rB: ", ball["x"], "/", ball["y"], end="") + print(" P1: ", player1["x"], "/", player1["y"], " S:", hex(player1["state"]), " ", end="") + print(" P2: ", player2["x"], "/", player2["y"], " S:", hex(player2["state"]), " ", end="") + + +def gameloop(ball, player1, player2): while True: - bChanged, state1, x1, y1 = evalgamepad(dev1, state1, x1, y1) - if (state1 & BTN_BASE4) > 0: # Exit? - print("Player #1 aborted game") - break - bChanged, state2, x2, y2 = evalgamepad(dev2, state2, x2, y2) # Exit? - if (state2 & BTN_BASE4) > 0: - print("Player #2 aborted game") - break - player1_x, player1_y = evalposition(player1_x, player1_y, x1, y1) - print("Player #1: ", player1_x," / ",player1_y) - player2_x, player2_y = evalposition(player2_x, player2_y, x2, y2) - print("Player #2: ", player2_x," / ",player2_y) + # 1. Retrieve user entries + bChanged = eval_gamepad(player1) + if bChanged: + if (player1["state"] & BTN_BASE4) > 0: # Exit? + print("Player #1 aborted game") + break + else: + print("Player #1: {}h".format(hex(player1["state"]))) + bChanged = eval_gamepad(player2) # Exit? + if bChanged: + if (player2["state"] & BTN_BASE4) > 0: + print("Player #2 aborted game") + break + else: + print("Player #2: {}h".format(hex(player2["state"]))) + + # 2. Adjust player positions + bChanged = eval_position(player1) + if bChanged: + print("Player #1: ", player1["x"], " / ", player1["y"]) + bChanged = eval_position(player2) + if bChanged: + print("Player #2: ", player2["x"], " / ", player2["y"]) + + # 3. Adjust object positions + eval_object(ball) + + # 4. Refresh game area drawing + draw_objects(ball, player1, player2) + + # 5. Little delay for testing + time.sleep(0.1) + + +def init_gamearea(): # Create base playground + pass def main(args): - path1 = args[1] - path2 = args[2] try: - # Gamepad #1 init. - fd1 = open(path1, "rb") - fcntl.fcntl(fd1, fcntl.F_SETFL, os.O_NONBLOCK) - dev1 = libevdev.Device(fd1) - # Gamepad #2 init. - fd2 = open(path2, "rb") - fcntl.fcntl(fd2, fcntl.F_SETFL, os.O_NONBLOCK) - dev2 = libevdev.Device(fd2) + # Initialize + init_gamearea() + ball = init_object(10, 10, 15, 15, 2.0, 1.5) + player1 = init_player(args[1]) + player2 = init_player(args[2]) + # Work ... - gameloop(dev1, dev2) + gameloop(ball, player1, player2) + # Quit gracefully - fd2.close() - fd1.close() + exit_player(player2) + exit_player(player1) except KeyboardInterrupt: # Never comes ... (?!) pass