-
Notifications
You must be signed in to change notification settings - Fork 0
/
dolphin.py
69 lines (55 loc) · 1.89 KB
/
dolphin.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
import os.path
import struct
import subprocess
import time
import Xlib.X
import torch
from Xlib.display import Display
DOLPHIN_COMMAND = "dolphin-emu"
GAME_FILE = "mario_kart.nkit.iso"
GAME_NAME = "Mario Kart Wii"
GAME_INI_FILE = "~/.local/share/dolphin-emu/GameSettings/RMCE01.ini"
class Dolphin:
def __init__(self, course_file, virtual_control=False):
with open(os.path.expanduser(GAME_INI_FILE), 'w') as f:
f.write(f'[Controls]\nWiimoteProfile1 = mario_kart_linux{"_uinput" if virtual_control else ""}')
args = [DOLPHIN_COMMAND, '-e', GAME_FILE, '-s', course_file]
self.process = subprocess.Popen(args)
time.sleep(3)
display = Display()
root = display.screen().root
self.window = find_window(root)
if self.window is None:
self.close()
raise Exception(f"{GAME_NAME} window not found in X11 tree")
def screenshot(self):
geom = self.window.get_geometry()
w, h = geom.width, geom.height
raw = self.window.get_image(0, 0, w, h, Xlib.X.ZPixmap, 0xffffffff)
d = struct.unpack('B' * len(raw.data), raw.data)
t = torch.tensor(d)
i = t.reshape((h, w, 4))
i = i.movedim(2, 0)
i = i.to(dtype=torch.uint8)[:3, :, :]
i = i.flip(0)
return i
def close(self):
self.process.terminate()
def wait(self):
self.process.wait()
def find_window(window):
name = window.get_wm_name()
if name is not None and type(name) == str and GAME_NAME in name:
return window
children = window.query_tree().children
for w in children:
res = find_window(w)
if res is not None:
return res
return None
if __name__ == '__main__':
import torchvision
dolphin = Dolphin('luigi-circuit')
im = dolphin.screenshot()
torchvision.io.write_png(im, 'sample_image.png')
dolphin.close()