fix insane config bottleneck

This commit is contained in:
Yonokid
2025-06-12 18:58:06 -04:00
parent 014c68c443
commit ebf098d8c2
9 changed files with 44 additions and 33 deletions

View File

@@ -53,8 +53,9 @@ def create_song_db():
def main(): def main():
create_song_db() create_song_db()
song_hash.song_hashes = song_hash.build_song_hashes() song_hash.song_hashes = song_hash.build_song_hashes()
screen_width: int = get_config()["video"]["screen_width"] global_data.config = get_config()
screen_height: int = get_config()["video"]["screen_height"] screen_width: int = global_data.config["video"]["screen_width"]
screen_height: int = global_data.config["video"]["screen_height"]
render_width, render_height = ray.get_render_width(), ray.get_render_height() render_width, render_height = ray.get_render_width(), ray.get_render_height()
dpi_scale = ray.get_window_scale_dpi() dpi_scale = ray.get_window_scale_dpi()
if dpi_scale.x == 0: if dpi_scale.x == 0:
@@ -63,7 +64,7 @@ def main():
else: else:
dpi_scale = int(render_width/dpi_scale.x), int(render_height/dpi_scale.y) dpi_scale = int(render_width/dpi_scale.x), int(render_height/dpi_scale.y)
if get_config()["video"]["vsync"]: if global_data.config["video"]["vsync"]:
ray.set_config_flags(ray.ConfigFlags.FLAG_VSYNC_HINT) ray.set_config_flags(ray.ConfigFlags.FLAG_VSYNC_HINT)
ray.set_config_flags(ray.ConfigFlags.FLAG_MSAA_4X_HINT) ray.set_config_flags(ray.ConfigFlags.FLAG_MSAA_4X_HINT)
ray.set_trace_log_level(ray.TraceLogLevel.LOG_ERROR) ray.set_trace_log_level(ray.TraceLogLevel.LOG_ERROR)
@@ -71,10 +72,10 @@ def main():
#ray.set_window_max_size(screen_width, screen_height) #ray.set_window_max_size(screen_width, screen_height)
#ray.set_window_min_size(screen_width, screen_height) #ray.set_window_min_size(screen_width, screen_height)
ray.init_window(screen_width, screen_height, "PyTaiko") ray.init_window(screen_width, screen_height, "PyTaiko")
if get_config()["video"]["borderless"]: if global_data.config["video"]["borderless"]:
ray.toggle_borderless_windowed() ray.toggle_borderless_windowed()
#ray.clear_window_state(ray.ConfigFlags.FLAG_WINDOW_TOPMOST) #ray.clear_window_state(ray.ConfigFlags.FLAG_WINDOW_TOPMOST)
if get_config()["video"]["fullscreen"]: if global_data.config["video"]["fullscreen"]:
ray.maximize_window() ray.maximize_window()
current_screen = Screens.TITLE current_screen = Screens.TITLE
@@ -119,7 +120,7 @@ def main():
if next_screen is not None: if next_screen is not None:
current_screen = next_screen current_screen = next_screen
if get_config()["general"]["fps_counter"]: if global_data.config["general"]["fps_counter"]:
ray.draw_fps(20, 20) ray.draw_fps(20, 20)
ray.end_blend_mode() ray.end_blend_mode()
ray.end_texture_mode() ray.end_texture_mode()

View File

@@ -19,7 +19,7 @@ right_kat = ['K']
[audio] [audio]
device_type = "Windows WASAPI" device_type = "Windows WASAPI"
buffer_size = 22 buffer_size = 22
sample_rate = 44100 sample_rate = -1
exclusive = false exclusive = false
[video] [video]

View File

@@ -475,13 +475,14 @@ class AudioEngine:
if isinstance(device_info, sd.DeviceList): if isinstance(device_info, sd.DeviceList):
raise Exception("Invalid ASIO Device") raise Exception("Invalid ASIO Device")
print(f"Using default ASIO device: {device_info['name']}") print(f"Using default ASIO device: {device_info['name']}")
print(device_info)
self.buffer_size = rounded(device_info['default_low_output_latency']*1000) self.buffer_size = rounded(device_info['default_low_output_latency']*1000)
if 'buffer_size' in get_config()['audio']: if 'buffer_size' in get_config()['audio']:
self.buffer_size = get_config()['audio']['buffer_size'] self.buffer_size = get_config()['audio']['buffer_size']
self.target_sample_rate = device_info['default_samplerate'] self.target_sample_rate = device_info['default_samplerate']
if 'sample_rate' in get_config()['audio']: if 'sample_rate' in get_config()['audio']:
self.target_sample_rate = get_config()['audio']['sample_rate'] self.target_sample_rate = get_config()['audio']['sample_rate']
if self.target_sample_rate == -1:
self.target_sample_rate = device_info['default_samplerate']
# Set output channels based on device capabilities # Set output channels based on device capabilities
self.output_channels = device_info['max_output_channels'] self.output_channels = device_info['max_output_channels']
if self.output_channels > 2: if self.output_channels > 2:

View File

@@ -35,10 +35,13 @@ class Note:
def __le__(self, other): def __le__(self, other):
return self.hit_ms <= other.hit_ms return self.hit_ms <= other.hit_ms
def __eq__(self, other):
return self.hit_ms == other.hit_ms
def _get_hash_data(self) -> bytes: def _get_hash_data(self) -> bytes:
"""Get deterministic byte representation for hashing""" """Get deterministic byte representation for hashing"""
field_values = [] field_values = []
for f in sorted([f.name for f in fields(self)]): # Sort for consistency for f in sorted([f.name for f in fields(self)]):
value = getattr(self, f, None) value = getattr(self, f, None)
field_values.append((f, value)) field_values.append((f, value))
field_values.append(('__class__', self.__class__.__name__)) field_values.append(('__class__', self.__class__.__name__))
@@ -66,6 +69,9 @@ class Drumroll(Note):
def __repr__(self): def __repr__(self):
return str(self.__dict__) return str(self.__dict__)
def __eq__(self, other):
return self.hit_ms == other.hit_ms
def __post_init__(self): def __post_init__(self):
for field_name in [f.name for f in fields(Note)]: for field_name in [f.name for f in fields(Note)]:
if hasattr(self._source_note, field_name): if hasattr(self._source_note, field_name):
@@ -94,6 +100,9 @@ class Balloon(Note):
def __repr__(self): def __repr__(self):
return str(self.__dict__) return str(self.__dict__)
def __eq__(self, other):
return self.hit_ms == other.hit_ms
def __post_init__(self): def __post_init__(self):
for field_name in [f.name for f in fields(Note)]: for field_name in [f.name for f in fields(Note)]:
if hasattr(self._source_note, field_name): if hasattr(self._source_note, field_name):

View File

@@ -106,7 +106,7 @@ def save_config(config: dict[str, Any]) -> None:
tomlkit.dump(config, f) tomlkit.dump(config, f)
def is_l_don_pressed() -> bool: def is_l_don_pressed() -> bool:
keys = get_config()["keybinds"]["left_don"] keys = global_data.config["keybinds"]["left_don"]
for key in keys: for key in keys:
if ray.is_key_pressed(ord(key)): if ray.is_key_pressed(ord(key)):
return True return True
@@ -126,7 +126,7 @@ def is_l_don_pressed() -> bool:
return False return False
def is_r_don_pressed() -> bool: def is_r_don_pressed() -> bool:
keys = get_config()["keybinds"]["right_don"] keys = global_data.config["keybinds"]["right_don"]
for key in keys: for key in keys:
if ray.is_key_pressed(ord(key)): if ray.is_key_pressed(ord(key)):
return True return True
@@ -146,7 +146,7 @@ def is_r_don_pressed() -> bool:
return False return False
def is_l_kat_pressed() -> bool: def is_l_kat_pressed() -> bool:
keys = get_config()["keybinds"]["left_kat"] keys = global_data.config["keybinds"]["left_kat"]
for key in keys: for key in keys:
if ray.is_key_pressed(ord(key)): if ray.is_key_pressed(ord(key)):
return True return True
@@ -166,7 +166,7 @@ def is_l_kat_pressed() -> bool:
return False return False
def is_r_kat_pressed() -> bool: def is_r_kat_pressed() -> bool:
keys = get_config()["keybinds"]["right_kat"] keys = global_data.config["keybinds"]["right_kat"]
for key in keys: for key in keys:
if ray.is_key_pressed(ord(key)): if ray.is_key_pressed(ord(key)):
return True return True
@@ -212,6 +212,7 @@ class GlobalData:
selected_song: Path = Path() selected_song: Path = Path()
textures: dict[str, list[ray.Texture]] = field(default_factory=lambda: dict()) textures: dict[str, list[ray.Texture]] = field(default_factory=lambda: dict())
songs_played: int = 0 songs_played: int = 0
config: dict = field(default_factory=lambda: dict())
global_data = GlobalData() global_data = GlobalData()

View File

@@ -12,7 +12,6 @@ from libs.backgrounds import Background
from libs.tja import Balloon, Drumroll, Note, TJAParser, calculate_base_score from libs.tja import Balloon, Drumroll, Note, TJAParser, calculate_base_score
from libs.utils import ( from libs.utils import (
OutlinedText, OutlinedText,
get_config,
get_current_ms, get_current_ms,
global_data, global_data,
is_l_don_pressed, is_l_don_pressed,
@@ -114,7 +113,7 @@ class GameScreen:
self.movie.set_volume(0.0) self.movie.set_volume(0.0)
else: else:
self.movie = None self.movie = None
session_data.song_title = self.tja.metadata.title.get(get_config()['general']['language'].lower(), self.tja.metadata.title['en']) session_data.song_title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
self.player_1 = Player(self, 1, difficulty) self.player_1 = Player(self, 1, difficulty)
if not hasattr(self, 'song_music'): if not hasattr(self, 'song_music'):
@@ -144,7 +143,7 @@ class GameScreen:
return 'RESULT' return 'RESULT'
def write_score(self): def write_score(self):
if get_config()['general']['autoplay']: if global_data.config['general']['autoplay']:
return return
with sqlite3.connect('scores.db') as con: with sqlite3.connect('scores.db') as con:
cursor = con.cursor() cursor = con.cursor()
@@ -169,7 +168,7 @@ class GameScreen:
def update(self): def update(self):
self.on_screen_start() self.on_screen_start()
self.current_ms = get_current_ms() - self.start_ms self.current_ms = get_current_ms() - self.start_ms
if (self.current_ms >= self.tja.metadata.offset*1000 + self.start_delay - get_config()["general"]["judge_offset"]) and not self.song_started: if (self.current_ms >= self.tja.metadata.offset*1000 + self.start_delay - global_data.config["general"]["judge_offset"]) and not self.song_started:
if self.song_music is not None: if self.song_music is not None:
if not audio.is_sound_playing(self.song_music): if not audio.is_sound_playing(self.song_music):
audio.play_sound(self.song_music) audio.play_sound(self.song_music)
@@ -227,7 +226,7 @@ class Player:
self.player_number = player_number self.player_number = player_number
self.difficulty = difficulty self.difficulty = difficulty
self.visual_offset = get_config()["general"]["visual_offset"] self.visual_offset = global_data.config["general"]["visual_offset"]
self.play_notes, self.draw_note_list, self.draw_bar_list = game_screen.tja.notes_to_position(self.difficulty) self.play_notes, self.draw_note_list, self.draw_bar_list = game_screen.tja.notes_to_position(self.difficulty)
self.total_notes = len([note for note in self.play_notes if 0 < note.type < 5]) self.total_notes = len([note for note in self.play_notes if 0 < note.type < 5])
@@ -489,14 +488,14 @@ class Player:
self.lane_hit_effect = LaneHitEffect(note_type) self.lane_hit_effect = LaneHitEffect(note_type)
self.draw_drum_hit_list.append(DrumHitEffect(note_type, side)) self.draw_drum_hit_list.append(DrumHitEffect(note_type, side))
if get_config()["general"]["sfx"]: if global_data.config["general"]["sfx"]:
audio.play_sound(sound) audio.play_sound(sound)
self.check_note(game_screen, 1 if note_type == 'DON' else 2) self.check_note(game_screen, 1 if note_type == 'DON' else 2)
self.input_log[game_screen.current_ms] = (note_type, side) self.input_log[game_screen.current_ms] = (note_type, side)
def autoplay_manager(self, game_screen: GameScreen): def autoplay_manager(self, game_screen: GameScreen):
if not get_config()["general"]["autoplay"]: if not global_data.config["general"]["autoplay"]:
return return
if len(self.play_notes) == 0: if len(self.play_notes) == 0:
return return
@@ -674,7 +673,7 @@ class Player:
self.draw_notes(game_screen) self.draw_notes(game_screen)
ray.draw_texture(game_screen.textures['lane_obi'][0], 0, 184, ray.WHITE) ray.draw_texture(game_screen.textures['lane_obi'][0], 0, 184, ray.WHITE)
ray.draw_texture(game_screen.textures['lane_obi'][14], 211, 206, ray.WHITE) ray.draw_texture(game_screen.textures['lane_obi'][14], 211, 206, ray.WHITE)
if get_config()["general"]["autoplay"]: if global_data.config["general"]["autoplay"]:
ray.draw_texture(game_screen.textures['lane_obi'][58], 0, 290, ray.WHITE) ray.draw_texture(game_screen.textures['lane_obi'][58], 0, 290, ray.WHITE)
for anim in self.draw_drum_hit_list: for anim in self.draw_drum_hit_list:
anim.draw(game_screen) anim.draw(game_screen)

View File

@@ -2,7 +2,7 @@ import pyray as ray
import sounddevice as sd import sounddevice as sd
from libs.utils import ( from libs.utils import (
get_config, global_data,
is_l_don_pressed, is_l_don_pressed,
is_l_kat_pressed, is_l_kat_pressed,
is_r_don_pressed, is_r_don_pressed,
@@ -16,7 +16,7 @@ class SettingsScreen:
self.width = width self.width = width
self.height = height self.height = height
self.screen_init = False self.screen_init = False
self.config = get_config() self.config = global_data.config
self.headers = list(self.config.keys()) self.headers = list(self.config.keys())
self.headers.append('Exit') self.headers.append('Exit')
self.header_index = 0 self.header_index = 0
@@ -32,6 +32,7 @@ class SettingsScreen:
def on_screen_end(self): def on_screen_end(self):
self.screen_init = False self.screen_init = False
save_config(self.config) save_config(self.config)
global_data.config = self.config
return "ENTRY" return "ENTRY"
def get_current_settings(self): def get_current_settings(self):
@@ -68,7 +69,7 @@ class SettingsScreen:
elif key == 'buffer_size': elif key == 'buffer_size':
new_value = max(1, min(32, new_value)) new_value = max(1, min(32, new_value))
elif key == 'sample_rate': elif key == 'sample_rate':
valid_rates = [22050, 44100, 48000, 88200, 96000] valid_rates = [-1, 22050, 44100, 48000, 88200, 96000]
current_idx = valid_rates.index(current_value) if current_value in valid_rates else 2 current_idx = valid_rates.index(current_value) if current_value in valid_rates else 2
new_idx = max(0, min(len(valid_rates) - 1, current_idx + increment)) new_idx = max(0, min(len(valid_rates) - 1, current_idx + increment))
new_value = valid_rates[new_idx] new_value = valid_rates[new_idx]

View File

@@ -11,7 +11,6 @@ from libs.audio import audio
from libs.tja import TJAParser from libs.tja import TJAParser
from libs.utils import ( from libs.utils import (
OutlinedText, OutlinedText,
get_config,
get_current_ms, get_current_ms,
global_data, global_data,
is_l_don_pressed, is_l_don_pressed,
@@ -27,7 +26,7 @@ class SongSelectScreen:
BOX_CENTER = 444 BOX_CENTER = 444
def __init__(self, screen_width: int, screen_height: int): def __init__(self, screen_width: int, screen_height: int):
self.screen_init = False self.screen_init = False
self.root_dir = get_config()["paths"]["tja_path"] self.root_dir = global_data.config["paths"]["tja_path"]
self.screen_width = screen_width self.screen_width = screen_width
self.screen_height = screen_height self.screen_height = screen_height
@@ -386,7 +385,7 @@ class SongBox:
def reset(self): def reset(self):
if self.black_name is not None: if self.black_name is not None:
if self.tja is not None: if self.tja is not None:
subtitle = OutlinedText(self.tja.metadata.subtitle.get(get_config()['general']['language'], ''), 30, ray.Color(255, 255, 255, 255), ray.Color(0, 0, 0, 255), outline_thickness=5, vertical=True) subtitle = OutlinedText(self.tja.metadata.subtitle.get(global_data.config['general']['language'], ''), 30, ray.Color(255, 255, 255, 255), ray.Color(0, 0, 0, 255), outline_thickness=5, vertical=True)
else: else:
subtitle = None subtitle = None
self.yellow_box = YellowBox(self.black_name, self.texture_index == 552, tja=self.tja, subtitle=subtitle) self.yellow_box = YellowBox(self.black_name, self.texture_index == 552, tja=self.tja, subtitle=subtitle)
@@ -457,7 +456,7 @@ class SongBox:
#print(f"loaded black name {self.text_name}") #print(f"loaded black name {self.text_name}")
if self.tja is not None or self.texture_index == 552: if self.tja is not None or self.texture_index == 552:
if self.tja is not None: if self.tja is not None:
subtitle = OutlinedText(self.tja.metadata.subtitle.get(get_config()['general']['language'], ''), 30, ray.Color(255, 255, 255, 255), ray.Color(0, 0, 0, 255), outline_thickness=5, vertical=True) subtitle = OutlinedText(self.tja.metadata.subtitle.get(global_data.config['general']['language'], ''), 30, ray.Color(255, 255, 255, 255), ray.Color(0, 0, 0, 255), outline_thickness=5, vertical=True)
else: else:
subtitle = None subtitle = None
self.yellow_box = YellowBox(self.black_name, self.texture_index == 552, tja=self.tja, subtitle=subtitle) self.yellow_box = YellowBox(self.black_name, self.texture_index == 552, tja=self.tja, subtitle=subtitle)
@@ -889,7 +888,7 @@ class SongFile(FileSystemItem):
def __init__(self, path: Path, name: str, texture_index: int, tja=None): def __init__(self, path: Path, name: str, texture_index: int, tja=None):
super().__init__(path, name) super().__init__(path, name)
self.tja = tja or TJAParser(path) self.tja = tja or TJAParser(path)
title = self.tja.metadata.title.get(get_config()['general']['language'].lower(), self.tja.metadata.title['en']) title = self.tja.metadata.title.get(global_data.config['general']['language'].lower(), self.tja.metadata.title['en'])
self.box = SongBox(title, texture_index, False, tja=self.tja) self.box = SongBox(title, texture_index, False, tja=self.tja)
self.box.get_scores() self.box.get_scores()
@@ -1153,7 +1152,7 @@ class FileNavigator:
elif line.startswith("#TITLE:"): elif line.startswith("#TITLE:"):
name = line.split(":", 1)[1].strip() name = line.split(":", 1)[1].strip()
elif line.startswith("#TITLEJA:"): elif line.startswith("#TITLEJA:"):
if get_config()['general']['language'] == 'ja': if global_data.config['general']['language'] == 'ja':
name = line.split(":", 1)[1].strip() name = line.split(":", 1)[1].strip()
except Exception as e: except Exception as e:
print(f"Error parsing box.def in {path}: {e}") print(f"Error parsing box.def in {path}: {e}")

View File

@@ -6,8 +6,8 @@ import pyray as ray
from libs.animation import Animation from libs.animation import Animation
from libs.audio import audio from libs.audio import audio
from libs.utils import ( from libs.utils import (
get_config,
get_current_ms, get_current_ms,
global_data,
is_l_don_pressed, is_l_don_pressed,
is_r_don_pressed, is_r_don_pressed,
load_all_textures_from_zip, load_all_textures_from_zip,
@@ -20,9 +20,9 @@ class TitleScreen:
def __init__(self, width: int, height: int): def __init__(self, width: int, height: int):
self.width = width self.width = width
self.height = height self.height = height
video_dir = Path(get_config()["paths"]["video_path"]) / "op_videos" video_dir = Path(global_data.config["paths"]["video_path"]) / "op_videos"
self.op_video_list = [file for file in video_dir.glob("**/*.mp4")] self.op_video_list = [file for file in video_dir.glob("**/*.mp4")]
video_dir = Path(get_config()["paths"]["video_path"]) / "attract_videos" video_dir = Path(global_data.config["paths"]["video_path"]) / "attract_videos"
self.attract_video_list = [file for file in video_dir.glob("**/*.mp4")] self.attract_video_list = [file for file in video_dir.glob("**/*.mp4")]
self.load_sounds() self.load_sounds()
self.screen_init = False self.screen_init = False