From 2b7ce04156e7260426c90f6b882280951af6deb0 Mon Sep 17 00:00:00 2001 From: ERR0RPR0MPT Date: Sat, 13 Apr 2024 00:26:26 +0800 Subject: [PATCH] =?UTF-8?q?update=20v0.0.5=20-=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E4=BB=A3=E7=A0=81=E6=89=A7=E8=A1=8C=E6=95=88=E7=8E=87=20-=20?= =?UTF-8?q?=E9=87=8D=E5=86=99=20sleep=20=E9=80=82=E9=85=8D=E9=83=A8?= =?UTF-8?q?=E5=88=86=E5=BB=B6=E8=BF=9F=E5=A4=A7=E7=9A=84=E6=83=85=E5=86=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 5 +- main.py | 123 +++++++++++++++++++++++++++---------------- microsecond_sleep.py | 15 ++++++ 3 files changed, 95 insertions(+), 48 deletions(-) create mode 100644 microsecond_sleep.py diff --git a/README.md b/README.md index 4517b8d..c43b6e5 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,12 @@ 5. 手机打开 USB 调试, 强烈建议同时使用 USB 网络共享连接电脑, 串流走 WLAN 可能不是很稳定 6. 电脑画面可使用 `IddSampleDriver`, `Sunshine` 和 `Moonlight` 等串流到 Android 设备, 这里不再赘述 7. 手机连接电脑, 先运行脚本 `python main.py`, 再运行游戏, 脚本控制台输出 `已连接到游戏` 即可 -8. 进游戏调整延迟, 一般判定A/B都要调才能正常用, 我这边是 `A:-0.5/B:1.0` +8. 进游戏调整延迟, 一般判定A/B都要调才能正常用, 我这边是 `A:-1.0/B:0.5` 9. 打一把看看蹭不蹭星星/触控是否灵敏, 根据体验修改 `AREA_SCOPE` 变量即可(默认65) +10. 如果单点延迟低但滑动时延迟变高, 请将脚本中 `TOUCH_THREAD_SLEEP` 修改为 False ## 注意 -2P 相关代码已经注释,想要加 2P 的去掉脚本注释即可. +想要加 2P 的重新复制一下脚本并添加串口 COM4 到 COM44 的转发就好 该脚本仅用于测试, 目前来说打12+及以下应该是问题不大, 12+以上水平不够没试过. diff --git a/main.py b/main.py index 57d4edb..b180063 100644 --- a/main.py +++ b/main.py @@ -14,6 +14,10 @@ COM_BAUDRATE = 9600 MAX_SLOT = 12 # 检测区域的像素值范围 AREA_SCOPE = 65 +# touch_thread 是否启用sleep, 默认开启, 如果程序 CPU 占用较高则开启, 如果滑动时延迟极大请关闭 +TOUCH_THREAD_SLEEP_MODE = True +# 每次 sleep 的延迟, 单位: 微秒, 默认 100 微秒 +TOUCH_THREAD_SLEEP_DELAY = 100 exp_list = [ ["A1", "A2", "A3", "A4", "A5", ], @@ -35,7 +39,6 @@ exp_image_dict = { class SerialManager: p1Serial = serial.Serial(COM_PORT, COM_BAUDRATE) - # p2Serial = serial.Serial("COM44", 9600) settingPacket = bytearray([40, 0, 0, 0, 0, 41]) startUp = False recvData = "" @@ -59,23 +62,22 @@ class SerialManager: def touch_thread(self): while True: - # start_time = time.time() + # start_time = time.perf_counter() if self.p1Serial.is_open: self.read_data(self.p1Serial) - # if self.p2Serial.is_open: - # self.read_data(self.p2Serial) if not self.touchQueue.empty(): # print("touchQueue 不为空,开始执行") s_temp = self.touchQueue.get() self.update_touch(s_temp) # 延迟防止消耗 CPU 时间过长 - time.sleep(0.0001) - # print(f"单次循环执行时间:{time.time() - start_time}秒") + if TOUCH_THREAD_SLEEP_MODE: + microsecond_sleep(TOUCH_THREAD_SLEEP_DELAY) + # print("单次执行时间:", (time.perf_counter() - start_time) * 1e3, "毫秒") def write_thread(self): while True: # 延迟匹配波特率 - time.sleep(0.01) # 9600 + time.sleep(0.0075) # 9600 # time.sleep(0.002) # 115200 if not self.startUp: # print("当前没有启动") @@ -87,7 +89,6 @@ class SerialManager: def destroy(self): self.touchThread.join() self.p1Serial.close() - # self.p2Serial.close() def read_data(self, ser): if ser.in_waiting == 6: @@ -110,16 +111,23 @@ class SerialManager: def send_touch(self, ser, data): ser.write(data) + # def build_touch_package(self, sl): + # sum_list = [0, 0, 0, 0, 0, 0, 0] + # for i in range(len(sl)): + # for j in range(len(sl[i])): + # if sl[i][j] == 1: + # sum_list[i] += (2 ** j) + # s = "28 " + # for i in sum_list: + # s += hex(i)[2:].zfill(2).upper() + " " + # s += "29" + # # print(s) + # return bytes.fromhex(s) + def build_touch_package(self, sl): - sum_list = [0, 0, 0, 0, 0, 0, 0] - for i in range(len(sl)): - for j in range(len(sl[i])): - if sl[i][j] == 1: - sum_list[i] += (2 ** j) - s = "28 " - for i in sum_list: - s += hex(i)[2:].zfill(2).upper() + " " - s += "29" + sum_list = [sum(2 ** j for j, val in enumerate(row) if val == 1) for row in sl] + hex_list = [hex(i)[2:].zfill(2).upper() for i in sum_list] + s = "28 " + " ".join(hex_list) + " 29" # print(s) return bytes.fromhex(s) @@ -139,42 +147,67 @@ class SerialManager: self.touchQueue.put([self.build_touch_package(sl), touch_keys]) +def microsecond_sleep(sleep_time): + end_time = time.perf_counter() + (sleep_time - 1.0) / 1e6 # 1.0是时间补偿,需要根据自己PC的性能去实测 + while time.perf_counter() < end_time: + pass + + +# def get_colors_in_area(x, y): +# colors = set() # 使用集合来存储颜色值,以避免重复 +# for dx in [-AREA_SCOPE, 0, AREA_SCOPE]: +# for dy in [-AREA_SCOPE, 0, AREA_SCOPE]: +# if 0 <= (x + dx) < exp_image_width and 0 <= (y + dy) < exp_image_height: +# colors.add(str(exp_image.getpixel((x + dx, y + dy))[0])) +# return list(colors) + + def get_colors_in_area(x, y): - colors = set() # 使用集合来存储颜色值,以避免重复 - for dx in [-AREA_SCOPE, 0, AREA_SCOPE]: - for dy in [-AREA_SCOPE, 0, AREA_SCOPE]: - if 0 <= (x + dx) < exp_image_width and 0 <= (y + dy) < exp_image_height: - colors.add(str(exp_image.getpixel((x + dx, y + dy))[0])) + colors = {str(exp_image.getpixel((x + dx, y + dy))[0]) for dx in [-AREA_SCOPE, 0, AREA_SCOPE] for dy in + [-AREA_SCOPE, 0, AREA_SCOPE] if 0 <= (x + dx) < exp_image_width and 0 <= (y + dy) < exp_image_height} return list(colors) def convert(touch_data): copy_exp_list = copy.deepcopy(exp_list) - touch_keys = set() - touched = 0 - for i in touch_data: - if not i["p"]: - continue - touched += 1 - x = i["x"] - y = i["y"] - for r_str in get_colors_in_area(x, y): - if not r_str in exp_image_dict: - continue - touch_keys.add(exp_image_dict[r_str]) - # print("Touched:", touched) + touch_keys = {exp_image_dict[r_str] for i in touch_data if i["p"] for r_str in get_colors_in_area(i["x"], i["y"]) if + r_str in exp_image_dict} # print("Touch Keys:", touch_keys) + # touched = sum(1 for i in touch_data if i["p"]) + # print("Touched:", touched) touch_keys_list = list(touch_keys) - for i in range(len(copy_exp_list)): - for j in range(len(copy_exp_list[i])): - if copy_exp_list[i][j] in touch_keys_list: - copy_exp_list[i][j] = 1 - else: - copy_exp_list[i][j] = 0 + copy_exp_list = [[1 if item in touch_keys_list else 0 for item in sublist] for sublist in copy_exp_list] # print(copy_exp_list) serial_manager.change_touch(copy_exp_list, touch_keys_list) +# def convert(touch_data): +# copy_exp_list = copy.deepcopy(exp_list) +# touch_keys = set() +# touched = 0 +# for i in touch_data: +# if not i["p"]: +# continue +# touched += 1 +# x = i["x"] +# y = i["y"] +# for r_str in get_colors_in_area(x, y): +# if not r_str in exp_image_dict: +# continue +# touch_keys.add(exp_image_dict[r_str]) +# # print("Touched:", touched) +# # print("Touch Keys:", touch_keys) +# touch_keys_list = list(touch_keys) +# for i in range(len(copy_exp_list)): +# for j in range(len(copy_exp_list[i])): +# if copy_exp_list[i][j] in touch_keys_list: +# copy_exp_list[i][j] = 1 +# else: +# copy_exp_list[i][j] = 0 +# # print(copy_exp_list) +# serial_manager.change_touch(copy_exp_list, touch_keys_list) + + def getevent(): # 存储多点触控数据的列表 touch_data = [{"p": False, "x": 0, "y": 0} for _ in range(MAX_SLOT)] @@ -204,9 +237,9 @@ def getevent(): # print("Touch Data:", touch_data) # 向 convert 函数发送数据 key_is_changed = False - # start_time = time.time() + # start_time = time.perf_counter() convert(touch_data) - # print(f"代码执行时间:{time.time() - start_time}秒") + # print("单次执行时间:", (time.perf_counter() - start_time) * 1e3, "毫秒") elif event_type == 'ABS_MT_SLOT': key_is_changed = True touch_index = int(event_value, 16) @@ -216,9 +249,7 @@ def getevent(): key_is_changed = True if event_value == "ffffffff": touch_data[touch_index]['p'] = False - touch_sum -= 1 - if touch_sum < 0: - touch_sum = 0 + touch_sum = max(0, touch_sum - 1) else: touch_data[touch_index]['p'] = True touch_sum += 1 diff --git a/microsecond_sleep.py b/microsecond_sleep.py new file mode 100644 index 0000000..9d7c693 --- /dev/null +++ b/microsecond_sleep.py @@ -0,0 +1,15 @@ +import time + + +def microsecond_sleep(sleep_time): + end_time = time.perf_counter() + (sleep_time - 1.0) / 1e6 # 1.0是时间补偿,需要根据自己PC的性能去实测 + while time.perf_counter() < end_time: + pass + + +start = time.perf_counter() +microsecond_sleep(10) # 等待10微秒 +end = time.perf_counter() +print(start) +print(end) +print("等待时间:", (end-start) * 1e6, "微秒")