1- import ctypes
2- import fcntl
1+ import time
2+ from asyncio import sleep
33import json
4- import math
54from pathlib import Path
65import subprocess
76import threading
8- import time
9- from zoneinfo import reset_tzpath
7+ import os
8+ from utils . logger import PyUiLogger
109from controller .controller_inputs import ControllerInput
1110from controller .key_state import KeyState
1211from controller .key_watcher import KeyWatcher
13- import os
1412from controller .key_watcher_controller_miyoo_mini import InputResult , KeyEvent , KeyWatcherControllerMiyooMini
1513from devices .miyoo .mini .miyoo_mini_flip_shared_memory_writer import MiyooMiniFlipSharedMemoryWriter
1614from devices .miyoo .mini .miyoo_mini_flip_specific_model_variables import MiyooMiniSpecificModelVariables
2018from devices .miyoo_trim_common import MiyooTrimCommon
2119from devices .utils .file_watcher import FileWatcher
2220from devices .utils .process_runner import ProcessRunner
23- from display .display import Display
2421from menus .games .utils .rom_info import RomInfo
25- from menus .settings .timezone_menu import TimezoneMenu
2622from utils import throttle
2723from utils .config_copier import ConfigCopier
2824from utils .ffmpeg_image_utils import FfmpegImageUtils
29- from utils .logger import PyUiLogger
3025from utils .py_ui_config import PyUiConfig
26+ from utils .time_logger import log_timing
3127
3228MAX_VOLUME = 20
3329MIN_RAW_VALUE = - 60
@@ -43,47 +39,21 @@ class MiyooMiniCommon(MiyooDevice):
4339
4440
4541 def __init__ (self , device_name , main_ui_mode , miyoo_mini_specific_model_variables : MiyooMiniSpecificModelVariables ):
42+
4643 self .device_name = device_name
4744 self .miyoo_mini_specific_model_variables = miyoo_mini_specific_model_variables
4845 self .controller_interface = self .build_controller_interface ()
49- self .unknown_axis_ranges = {} # axis -> (min, max)
50- self .unknown_axis_stats = {} # axis -> (sum, count)
51- self .sdl_axis_names = {
52- 0 : "SDL_CONTROLLER_AXIS_LEFTX" ,
53- 1 : "SDL_CONTROLLER_AXIS_LEFTY" ,
54- 2 : "SDL_CONTROLLER_AXIS_RIGHTX" ,
55- 3 : "SDL_CONTROLLER_AXIS_RIGHTY" ,
56- 4 : "SDL_CONTROLLER_AXIS_TRIGGERLEFT" ,
57- 5 : "SDL_CONTROLLER_AXIS_TRIGGERRIGHT"
58- }
59-
6046
6147 ConfigCopier .ensure_config ("/mnt/SDCARD/Saves/mini-flip-system.json" , Path (__file__ ).resolve ().parent / 'mini-flip-system.json' )
6248 self .system_config = SystemConfig ("/mnt/SDCARD/Saves/mini-flip-system.json" )
49+
6350 if (main_ui_mode ):
64- os .environ ["TZPATH" ] = "/mnt/SDCARD/miyoo285/zoneinfo"
65- reset_tzpath () # reload TZPATH
6651 self .miyoo_mini_flip_shared_memory_writer = MiyooMiniFlipSharedMemoryWriter ()
6752 self .miyoo_games_file_parser = MiyooGamesFileParser ()
68- self ._set_lumination_to_config ()
69- self ._set_contrast_to_config ()
70- self ._set_saturation_to_config ()
71- self ._set_brightness_to_config ()
72- self .ensure_wpa_supplicant_conf ()
73- self .init_gpio ()
7453 self .mainui_volume = None
7554 self .mainui_config_thread , self .mainui_config_thread_stop_event = FileWatcher ().start_file_watcher (
7655 "/appconfigs/system.json" , self .on_mainui_config_change , interval = 0.2 )
7756 threading .Thread (target = self .startup_init , daemon = True ).start ()
78-
79- if (PyUiConfig .enable_button_watchers ()):
80- from controller .controller import Controller
81- #/dev/miyooio if we want to get rid of miyoo_inputd
82- # debug in terminal: hexdump /dev/miyooio
83- self .volume_key_watcher = KeyWatcher ("/dev/input/event0" )
84- Controller .add_button_watcher (self .volume_key_watcher .poll_keyboard )
85- volume_key_polling_thread = threading .Thread (target = self .volume_key_watcher .poll_keyboard , daemon = True )
86- volume_key_polling_thread .start ()
8757
8858 super ().__init__ ()
8959
@@ -100,19 +70,31 @@ def on_mainui_config_change(self):
10070 old_volume = self .mainui_volume
10171 self .mainui_volume = data .get ("vol" )
10272 if (old_volume != self .mainui_volume ):
73+ from display .display import Display
10374 Display .volume_changed (self .mainui_volume * 5 )
10475
10576 except Exception as e :
10677 PyUiLogger .get_logger ().warning (f"Error reading { path } : { e } " )
10778 return None
10879
10980 def startup_init (self , include_wifi = True ):
110- config_volume = self .system_config .get_volume ()
111- self ._set_volume (config_volume )
11281 if (self .is_wifi_enabled ()):
11382 self .start_wifi_services ()
11483 self .on_mainui_config_change ()
115- self .apply_timezone (self .system_config .get_timezone ())
84+ self ._set_lumination_to_config ()
85+ self ._set_contrast_to_config ()
86+ self ._set_saturation_to_config ()
87+ self ._set_brightness_to_config ()
88+ self .ensure_wpa_supplicant_conf ()
89+ self .init_gpio ()
90+ if (PyUiConfig .enable_button_watchers ()):
91+ from controller .controller import Controller
92+ #/dev/miyooio if we want to get rid of miyoo_inputd
93+ # debug in terminal: hexdump /dev/miyooio
94+ self .volume_key_watcher = KeyWatcher ("/dev/input/event0" )
95+ Controller .add_button_watcher (self .volume_key_watcher .poll_keyboard )
96+ volume_key_polling_thread = threading .Thread (target = self .volume_key_watcher .poll_keyboard , daemon = True )
97+ volume_key_polling_thread .start ()
11698
11799 def build_controller_interface (self ):
118100 key_mappings = {}
@@ -346,63 +328,64 @@ def get_volume(self):
346328 return self .mainui_volume * 5
347329 except :
348330 return 0
349-
350- def _set_volume_raw (self , value : int , add : int = 0 ) -> int :
351- try :
352- fd = os .open ("/dev/mi_ao" , os .O_RDWR )
353- except OSError :
354- return 0
355-
356- # Prepare buffers
357- buf2 = (ctypes .c_int * 2 )(0 , 0 )
358- buf1 = (ctypes .c_uint64 * 2 )(ctypes .sizeof (buf2 ), ctypes .cast (buf2 , ctypes .c_void_p ).value )
359331
360- # Get previous volume
361- fcntl .ioctl (fd , MI_AO_GETVOLUME , buf1 )
362- prev_value = buf2 [1 ]
332+ def volume_up (self ):
333+ try :
334+ subprocess .run (
335+ ["send_event" , "/dev/input/event0" , "115:1" ],
336+ check = False
337+ )
338+ except Exception as e :
339+ PyUiLogger .get_logger ().exception (f"Failed to set volume via input events: { e } " )
363340
364- if add :
365- value = prev_value + add
341+ def volume_down (self ):
342+ try :
343+ subprocess .run (
344+ ["send_event" , "/dev/input/event0" , "114:1" ],
345+ check = False
346+ )
347+ except Exception as e :
348+ PyUiLogger .get_logger ().exception (f"Failed to set volume via input events: { e } " )
349+
350+ def change_volume (self , amount ):
351+ self .system_config .reload_config ()
352+ volume = self .get_volume () + amount
353+ if (volume < 0 ):
354+ volume = 0
355+ elif (volume > 100 ):
356+ volume = 100
357+ if (amount > 0 ):
358+ self .volume_up ()
366359 else :
367- value += MIN_RAW_VALUE
368-
369- # Clamp value
370- value = max (MIN_RAW_VALUE , min (MAX_RAW_VALUE , value ))
371-
372- if value == prev_value :
373- os .close (fd )
374- return prev_value
375-
376- buf2 [1 ] = value
377- fcntl .ioctl (fd , MI_AO_SETVOLUME , buf1 )
378-
379- # Handle mute
380- if prev_value <= MIN_RAW_VALUE < value :
381- buf2 [1 ] = 0
382- fcntl .ioctl (fd , MI_AO_SETMUTE , buf1 )
383- elif prev_value > MIN_RAW_VALUE >= value :
384- buf2 [1 ] = 1
385- fcntl .ioctl (fd , MI_AO_SETMUTE , buf1 )
386-
387- os .close (fd )
388- return value
389-
360+ self .volume_down ()
361+ sleep (0.1 )
362+ self .on_mainui_config_change ()
390363
391364 def _set_volume (self , volume : int ) -> int :
392- #Breaks keymon somehow
393- if (False ):
394- volume = max (0 , min (MAX_VOLUME , volume ))
365+ event_dev = "/dev/input/event0"
395366
396- volume_raw = 0
397- if volume != 0 :
398- volume_raw = round (48 * math .log10 (1 + volume )) # volume curve
367+ try :
368+ # Send volume-down (114) 20 times
369+ for _ in range (20 ):
370+ subprocess .run (
371+ ["send_event" , event_dev , "114:1" ],
372+ check = False
373+ )
374+ time .sleep (0.2 )
375+ # Send volume-up (115) volume//5 times
376+ for _ in range (volume // 5 ):
377+ subprocess .run (
378+ ["send_event" , event_dev , "115:1" ],
379+ check = False
380+ )
381+
382+ except Exception as e :
383+ PyUiLogger .get_logger ().exception (f"Failed to set volume via input events: { e } " )
399384
400- self ._set_volume_raw (volume_raw , 0 )
401385 return volume
402386
403387 def fix_sleep_sound_bug (self ):
404- config_volume = self .system_config .get_volume ()
405- self ._set_volume (config_volume )
388+ pass #uneeded
406389
407390
408391 def run_game (self , rom_info : RomInfo ) -> subprocess .Popen :
@@ -468,14 +451,8 @@ def supports_timezone_setting(self):
468451 return True
469452
470453 def prompt_timezone_update (self ):
471- timezone_menu = TimezoneMenu ()
472- tz = timezone_menu .ask_user_for_timezone (timezone_menu .list_timezone_files ('/mnt/SDCARD/miyoo285/zoneinfo/' , verify_via_datetime = False ))
473-
474- if (tz is not None ):
475- self .system_config .set_timezone (tz )
476- self .apply_timezone (tz )
477- Display .display_message_multiline (["Timezone changed" ,"Reloading UI..." ],2000 )
478- self .exit_pyui ()
454+ #No timezone update for miyoo mini
455+ pass
479456
480457 def apply_timezone (self , timezone ):
481458 ProcessRunner .run (["rm" , "-f" , "/tmp/localtime" ])
0 commit comments