mirror of
https://github.com/Yonokid/PyTaiko.git
synced 2026-02-04 03:30:13 +01:00
minor fixes
This commit is contained in:
@@ -21,7 +21,7 @@ from libs.utils import (
|
||||
from scenes.devtest import DevScreen
|
||||
from scenes.entry import EntryScreen
|
||||
from scenes.game import GameScreen
|
||||
from scenes.game_dan import DanGameScreen
|
||||
from scenes.dan.game_dan import DanGameScreen
|
||||
from scenes.two_player.game import TwoPlayerGameScreen
|
||||
from scenes.two_player.result import TwoPlayerResultScreen
|
||||
from scenes.loading import LoadScreen
|
||||
@@ -30,7 +30,7 @@ from scenes.settings import SettingsScreen
|
||||
from scenes.song_select import SongSelectScreen
|
||||
from scenes.title import TitleScreen
|
||||
from scenes.two_player.song_select import TwoPlayerSongSelectScreen
|
||||
from scenes.dan_select import DanSelectScreen
|
||||
from scenes.dan.dan_select import DanSelectScreen
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -3,6 +3,7 @@ import platform
|
||||
import logging
|
||||
from pathlib import Path
|
||||
|
||||
from libs.global_data import VolumeConfig
|
||||
from libs.utils import get_config
|
||||
|
||||
ffi = cffi.FFI()
|
||||
@@ -118,7 +119,7 @@ except OSError as e:
|
||||
|
||||
class AudioEngine:
|
||||
"""Initialize an audio engine for playing sounds and music."""
|
||||
def __init__(self, device_type: int, sample_rate: float, buffer_size: int, volume_presets: dict[str, float]):
|
||||
def __init__(self, device_type: int, sample_rate: float, buffer_size: int, volume_presets: VolumeConfig):
|
||||
self.device_type = device_type
|
||||
if sample_rate < 0:
|
||||
self.target_sample_rate = 44100
|
||||
@@ -142,7 +143,10 @@ class AudioEngine:
|
||||
def get_host_api_name(self, api_id: int) -> str:
|
||||
"""Returns the name of the host API with the given ID"""
|
||||
result = lib.get_host_api_name(api_id) # type: ignore
|
||||
return ffi.string(result).decode('utf-8')
|
||||
result = ffi.string(result)
|
||||
if isinstance(result, bytes):
|
||||
result = result.decode('utf-8')
|
||||
return result
|
||||
|
||||
def init_audio_device(self) -> bool:
|
||||
"""Initialize the audio device"""
|
||||
|
||||
@@ -75,10 +75,6 @@ class DonBG(DonBGBase):
|
||||
self.move = Animation.create_move(10000, total_distance=-1280)
|
||||
self.move.start()
|
||||
self.move.loop = True
|
||||
def draw(self, tex: TextureWrapper):
|
||||
self._draw_textures(tex, 1.0)
|
||||
if self.is_clear:
|
||||
self._draw_textures(tex, self.clear_fade.attribute)
|
||||
def _draw_textures(self, tex: TextureWrapper, fade: float):
|
||||
def _draw_textures(self, tex: TextureWrapper, fade: float, y: float):
|
||||
for i in range(2):
|
||||
tex.draw_texture(self.name, 'background', frame=self.is_clear, fade=fade, x=(i*1280)+self.move.attribute)
|
||||
|
||||
@@ -37,7 +37,5 @@ class DancerGroup(BaseDancerGroup):
|
||||
class BGFever(BGFeverBase):
|
||||
def start(self):
|
||||
self.transitioned = True
|
||||
def update(self, current_time_ms: float):
|
||||
pass
|
||||
def draw(self, tex: TextureWrapper):
|
||||
tex.draw_texture(self.name, 'background')
|
||||
|
||||
@@ -36,8 +36,6 @@ class DancerGroup(BaseDancerGroup):
|
||||
class BGFever(BGFeverBase):
|
||||
def start(self):
|
||||
self.transitioned = True
|
||||
def update(self, current_time_ms: float):
|
||||
pass
|
||||
def draw(self, tex: TextureWrapper):
|
||||
tex.draw_texture(self.name, 'background')
|
||||
tex.draw_texture(self.name, 'overlay')
|
||||
|
||||
@@ -19,8 +19,8 @@ class Background:
|
||||
self.chibi = ChibiController(self.tex_wrapper, 2, bpm, path)
|
||||
|
||||
class DonBG(DonBG6):
|
||||
def __init__(self, tex: TextureWrapper, player_num: int, bpm: float, path: str):
|
||||
super().__init__(tex, player_num, bpm, path)
|
||||
def __init__(self, tex: TextureWrapper, index: int, player_num: int, path: str):
|
||||
super().__init__(tex, index, player_num, path)
|
||||
self.overlay_move_2 = Animation.create_move(8000, total_distance=-760)
|
||||
self.overlay_move_2.loop = True
|
||||
self.overlay_move_2.start()
|
||||
|
||||
@@ -404,7 +404,7 @@ class YellowBox:
|
||||
if self.tja.metadata.course_data[diff].is_branching and (get_current_ms() // 1000) % 2 == 0:
|
||||
tex.draw_texture('yellow_box', 'branch_indicator', x=(diff*60), color=color)
|
||||
|
||||
def _draw_tja_data_diff(self, is_ura: bool, song_box):
|
||||
def _draw_tja_data_diff(self, is_ura: bool, song_box: Optional[SongBox] = None):
|
||||
if self.tja is None:
|
||||
return
|
||||
tex.draw_texture('diff_select', 'back', fade=self.fade_in.attribute)
|
||||
@@ -412,6 +412,8 @@ class YellowBox:
|
||||
tex.draw_texture('diff_select', 'neiro', fade=self.fade_in.attribute)
|
||||
|
||||
for diff in self.tja.metadata.course_data:
|
||||
if song_box is None:
|
||||
continue
|
||||
if diff >= 4:
|
||||
continue
|
||||
elif diff in song_box.scores and song_box.scores[diff] is not None and ((song_box.scores[diff][4] == 2 and song_box.scores[diff][2] == 0) or (song_box.scores[diff][2] == 0 and song_box.scores[diff][3] == 0)):
|
||||
@@ -472,7 +474,7 @@ class YellowBox:
|
||||
tex.draw_texture('yellow_box', 'yellow_box_top', x=self.left_x + self.edge_height, y=self.top_y, x2=self.center_width)
|
||||
tex.draw_texture('yellow_box', 'yellow_box_center', x=self.left_x + self.edge_height, y=self.top_y + self.edge_height, x2=self.center_width, y2=self.center_height)
|
||||
|
||||
def draw(self, song_box: SongBox, fade_override: Optional[float], is_ura: bool):
|
||||
def draw(self, song_box: Optional[SongBox], fade_override: Optional[float], is_ura: bool):
|
||||
self._draw_yellow_box()
|
||||
if self.is_dan:
|
||||
return
|
||||
@@ -604,7 +606,7 @@ class DanBox:
|
||||
|
||||
def _draw_open(self, x: int, y: int, is_ura: bool):
|
||||
if self.yellow_box is not None:
|
||||
self.yellow_box.draw(x, y, False)
|
||||
self.yellow_box.draw(None, None, False)
|
||||
for i, song in enumerate(self.song_text):
|
||||
title, subtitle = song
|
||||
x = i * 140
|
||||
@@ -895,8 +897,8 @@ class DanCourse(FileSystemItem):
|
||||
self.charts = []
|
||||
for chart in data["charts"]:
|
||||
hash = chart["hash"]
|
||||
chart_title = chart["title"]
|
||||
chart_subtitle = chart["subtitle"]
|
||||
#chart_title = chart["title"]
|
||||
#chart_subtitle = chart["subtitle"]
|
||||
difficulty = chart["difficulty"]
|
||||
if hash in global_data.song_hashes:
|
||||
path = Path(global_data.song_hashes[hash][0]["file_path"])
|
||||
@@ -997,10 +999,11 @@ class FileNavigator:
|
||||
song_list = self._read_song_list(self.favorite_folder.path)
|
||||
for song_obj in song_list:
|
||||
if str(song_obj) in self.all_song_files:
|
||||
if isinstance(self.all_song_files[str(song_obj)].box, DanBox):
|
||||
box = self.all_song_files[str(song_obj)].box
|
||||
if isinstance(box, DanBox):
|
||||
logger.warning(f"Cannot favorite DanCourse: {song_obj}")
|
||||
else:
|
||||
self.all_song_files[str(song_obj)].box.is_favorite = True
|
||||
box.is_favorite = True
|
||||
|
||||
logging.info(f"Object generation complete. "
|
||||
f"Directories: {len(self.all_directories)}, "
|
||||
|
||||
@@ -120,7 +120,7 @@ class SessionData:
|
||||
result_bad: int = 0
|
||||
result_max_combo: int = 0
|
||||
result_total_drumroll: int = 0
|
||||
result_gauge_length: int = 0
|
||||
result_gauge_length: float = 0
|
||||
prev_score: int = 0
|
||||
|
||||
@dataclass
|
||||
@@ -142,7 +142,7 @@ class GlobalData:
|
||||
session_data (list[SessionData]): Session data for both players.
|
||||
"""
|
||||
songs_played: int = 0
|
||||
config: Config = field(default_factory=lambda: dict())
|
||||
config: dict = field(default_factory=dict)
|
||||
song_hashes: dict[str, list[dict]] = field(default_factory=lambda: dict()) #Hash to path
|
||||
song_paths: dict[Path, str] = field(default_factory=lambda: dict()) #path to hash
|
||||
song_progress: float = 0.0
|
||||
|
||||
@@ -51,14 +51,17 @@ class Transition:
|
||||
offset = 816 - self.rainbow_up.attribute
|
||||
global_tex.draw_texture('rainbow_transition', 'text_bg', y=-self.rainbow_up.attribute - offset, color=color_2)
|
||||
|
||||
texture = self.title.texture
|
||||
x = 1280//2 - texture.width//2
|
||||
y = 1176 - texture.height//2 - int(self.rainbow_up.attribute) - offset - 20
|
||||
self.title.draw(outline_color=ray.BLACK, x=x, y=y, color=color_1)
|
||||
if isinstance(self.title, OutlinedText):
|
||||
texture = self.title.texture
|
||||
x = 1280//2 - texture.width//2
|
||||
y = 1176 - texture.height//2 - int(self.rainbow_up.attribute) - offset - 20
|
||||
self.title.draw(outline_color=ray.BLACK, x=x, y=y, color=color_1)
|
||||
|
||||
texture = self.subtitle.texture
|
||||
x = 1280//2 - texture.width//2
|
||||
self.subtitle.draw(outline_color=ray.BLACK, x=x, y=y + 50, color=color_1)
|
||||
if isinstance(self.subtitle, OutlinedText):
|
||||
texture = self.subtitle.texture
|
||||
x = 1280//2 - texture.width//2
|
||||
y = 1176 - texture.height//2 - int(self.rainbow_up.attribute) - offset - 20
|
||||
self.subtitle.draw(outline_color=ray.BLACK, x=x, y=y + 50, color=color_1)
|
||||
|
||||
def draw(self):
|
||||
"""Draw the transition effect."""
|
||||
|
||||
@@ -54,9 +54,10 @@ class VideoPlayer:
|
||||
image = ray.Image(frame_data, self.video.w, self.video.h, 1, ray.PixelFormat.PIXELFORMAT_UNCOMPRESSED_R8G8B8)
|
||||
self.texture = ray.load_texture_from_image(image)
|
||||
else:
|
||||
frame_bytes = frame_data.tobytes()
|
||||
pixels_ptr = ray.ffi.cast('void *', ray.ffi.from_buffer('unsigned char[]', frame_bytes))
|
||||
ray.update_texture(self.texture, pixels_ptr)
|
||||
if frame_data is not None:
|
||||
frame_bytes = frame_data.tobytes()
|
||||
pixels_ptr = ray.ffi.cast('void *', ray.ffi.from_buffer('unsigned char[]', frame_bytes))
|
||||
ray.update_texture(self.texture, pixels_ptr)
|
||||
|
||||
self.current_frame_data = frame_data
|
||||
return True
|
||||
|
||||
@@ -183,16 +183,13 @@ class DanSelectPlayer:
|
||||
|
||||
def handle_input(self, state, screen):
|
||||
"""Main input dispatcher. Delegates to state-specific handlers."""
|
||||
if self.is_voice_playing():
|
||||
return
|
||||
|
||||
if state == State.BROWSING:
|
||||
screen.handle_input_browsing()
|
||||
elif state == State.SONG_SELECTED:
|
||||
res = screen.handle_input_selected()
|
||||
|
||||
if res:
|
||||
return res
|
||||
if res:
|
||||
return res
|
||||
|
||||
def handle_input_selected(self):
|
||||
"""Handle input for selecting difficulty. Returns 'cancel', 'confirm', or None"""
|
||||
@@ -12,7 +12,7 @@ from libs.tja import TJAParser
|
||||
from libs.transition import Transition
|
||||
from libs.utils import OutlinedText, get_current_ms
|
||||
from libs.texture import tex
|
||||
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, ResultTransition, SongInfo
|
||||
from scenes.game import ClearAnimation, FCAnimation, FailAnimation, GameScreen, Gauge, ResultTransition, SongInfo
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@@ -91,7 +91,8 @@ class DanGameScreen(GameScreen):
|
||||
session_data.selected_difficulty = difficulty
|
||||
self.player_1.difficulty = difficulty
|
||||
self.tja = TJAParser(song.file_path, start_delay=self.start_delay, distance=SCREEN_WIDTH - GameScreen.JUDGE_X)
|
||||
audio.unload_music_stream(self.song_music)
|
||||
if self.song_music is not None:
|
||||
audio.unload_music_stream(self.song_music)
|
||||
self.song_music = None
|
||||
self.song_started = False
|
||||
|
||||
@@ -326,7 +327,7 @@ class DanTransition:
|
||||
tex.draw_texture('dan', 'transition', index=1, x=-self.move.attribute)
|
||||
|
||||
|
||||
class DanGauge:
|
||||
class DanGauge(Gauge):
|
||||
"""The player's gauge"""
|
||||
def __init__(self, player_num: str, total_notes: int):
|
||||
self.player_num = player_num
|
||||
@@ -122,12 +122,12 @@ class ResultPlayer:
|
||||
plate_info = global_data.config[f'nameplate_{self.player_num}p']
|
||||
self.nameplate = Nameplate(plate_info['name'], plate_info['title'], int(self.player_num), plate_info['dan'], plate_info['gold'], plate_info['title_bg'])
|
||||
self.score, self.good, self.ok, self.bad, self.max_combo, self.total_drumroll = '', '', '', '', '', ''
|
||||
self.update_list: list[tuple[str, int]] = [['score', session_data.result_score],
|
||||
['good', session_data.result_good],
|
||||
['ok', session_data.result_ok],
|
||||
['bad', session_data.result_bad],
|
||||
['max_combo', session_data.result_max_combo],
|
||||
['total_drumroll', session_data.result_total_drumroll]]
|
||||
self.update_list: list[tuple[str, int]] = [('score', session_data.result_score),
|
||||
('good', session_data.result_good),
|
||||
('ok', session_data.result_ok),
|
||||
('bad', session_data.result_bad),
|
||||
('max_combo', session_data.result_max_combo),
|
||||
('total_drumroll', session_data.result_total_drumroll)]
|
||||
self.update_index = 0
|
||||
if session_data.result_ok == 0 and session_data.result_bad == 0:
|
||||
self.crown_type = 'crown_dfc'
|
||||
|
||||
@@ -252,7 +252,7 @@ class SettingsScreen(Screen):
|
||||
display_value = ', '.join(map(str, value))
|
||||
else:
|
||||
display_value = str(value)
|
||||
if key == 'device_type':
|
||||
if key == 'device_type' and not isinstance(value, list):
|
||||
display_value = f'{display_value} ({audio.get_host_api_name(value)})'
|
||||
ray.draw_text(f'{key}: {display_value}', 250, i*25 + 70, 20, color)
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ from pathlib import Path
|
||||
import pyray as ray
|
||||
import logging
|
||||
|
||||
from libs.file_navigator import navigator
|
||||
from libs.file_navigator import DanCourse, navigator
|
||||
from libs.audio import audio
|
||||
from libs.chara_2d import Chara2D
|
||||
from libs.file_navigator import Directory, SongBox, SongFile
|
||||
@@ -74,7 +74,9 @@ class SongSelectScreen(Screen):
|
||||
return self.on_screen_end("ENTRY")
|
||||
|
||||
if str(session_data.selected_song) in self.navigator.all_song_files:
|
||||
self.navigator.mark_crowns_dirty_for_song(self.navigator.all_song_files[str(session_data.selected_song)])
|
||||
selected_song = self.navigator.all_song_files[str(session_data.selected_song)]
|
||||
if not isinstance(selected_song, DanCourse):
|
||||
self.navigator.mark_crowns_dirty_for_song(selected_song)
|
||||
|
||||
curr_item = self.navigator.get_current_item()
|
||||
curr_item.box.get_scores()
|
||||
@@ -214,7 +216,7 @@ class SongSelectScreen(Screen):
|
||||
def handle_input(self):
|
||||
self.player_1.handle_input(self.state, self)
|
||||
|
||||
def update_players(self, current_time):
|
||||
def update_players(self, current_time) -> str:
|
||||
self.player_1.update(current_time)
|
||||
if self.text_fade_out.is_finished:
|
||||
self.player_1.selected_song = True
|
||||
@@ -376,6 +378,7 @@ class SongSelectPlayer:
|
||||
self.selected_difficulty = -3
|
||||
self.prev_diff = -3
|
||||
self.selected_song = False
|
||||
self.is_ready = False
|
||||
self.is_ura = False
|
||||
self.ura_toggle = 0
|
||||
self.diff_select_move_right = False
|
||||
@@ -492,7 +495,7 @@ class SongSelectPlayer:
|
||||
|
||||
def handle_input(self, state, screen):
|
||||
"""Main input dispatcher. Delegates to state-specific handlers."""
|
||||
if self.is_voice_playing():
|
||||
if self.is_voice_playing() or self.is_ready:
|
||||
return
|
||||
|
||||
if state == State.BROWSING:
|
||||
@@ -538,6 +541,7 @@ class SongSelectPlayer:
|
||||
self.neiro_selector = NeiroSelector(self.player_num)
|
||||
return None
|
||||
else:
|
||||
self.is_ready = True
|
||||
return "confirm"
|
||||
|
||||
if is_l_kat_pressed(self.player_num) or is_r_kat_pressed(self.player_num):
|
||||
|
||||
@@ -128,7 +128,7 @@ class TwoPlayerSongSelectScreen(SongSelectScreen):
|
||||
super()._cancel_selection()
|
||||
self.player_2.selected_song = False
|
||||
|
||||
def _confirm_selection(self, player_selected: int):
|
||||
def _confirm_selection(self, player_selected: int = 1):
|
||||
"""Confirm song selection and create game transition"""
|
||||
audio.play_sound('don', 'sound')
|
||||
audio.play_sound(f'voice_start_song_{global_data.player_num}p', 'voice')
|
||||
@@ -160,7 +160,7 @@ class TwoPlayerSongSelectScreen(SongSelectScreen):
|
||||
self.game_transition.start()
|
||||
logger.info(f"Game transition started for song: {title} - {subtitle}")
|
||||
|
||||
def update_players(self, current_time):
|
||||
def update_players(self, current_time) -> str:
|
||||
self.player_1.update(current_time)
|
||||
self.player_2.update(current_time)
|
||||
if self.text_fade_out.is_finished:
|
||||
|
||||
Reference in New Issue
Block a user