Attempt to fix traceback on game exit with some older games.

This commit is contained in:
Storm Dragon
2025-03-14 23:10:14 -04:00
parent 2ad22ff1ae
commit be6dfdf53a
9 changed files with 483 additions and 457 deletions

View File

@ -29,20 +29,20 @@ class ConfigService:
def __init__(self):
"""Initialize configuration parsers."""
self.local_config = configparser.ConfigParser()
self.global_config = configparser.ConfigParser()
self.game_title = None
self.path_service = None
self.localConfig = configparser.ConfigParser()
self.globalConfig = configparser.ConfigParser()
self.gameTitle = None
self.pathService = None
def set_game_info(self, game_title, path_service):
def set_game_info(self, gameTitle, pathService):
"""Set game information and initialize configs.
Args:
game_title (str): Title of the game
path_service (PathService): Path service instance
gameTitle (str): Title of the game
pathService (PathService): Path service instance
"""
self.game_title = game_title
self.path_service = path_service
self.gameTitle = gameTitle
self.pathService = pathService
# Load existing configurations
self.read_local_config()
@ -51,56 +51,56 @@ class ConfigService:
def read_local_config(self):
"""Read local configuration from file."""
try:
# Try to use path_service if available
if self.path_service and self.path_service.game_path:
with open(os.path.join(self.path_service.game_path, "config.ini"), 'r') as configfile:
self.local_config.read_file(configfile)
# Try to use pathService if available
if self.pathService and self.pathService.gamePath:
with open(os.path.join(self.pathService.gamePath, "config.ini"), 'r') as configFile:
self.localConfig.read_file(configFile)
# Fallback to global gamePath
elif gamePath:
with open(os.path.join(gamePath, "config.ini"), 'r') as configfile:
self.local_config.read_file(configfile)
with open(os.path.join(gamePath, "config.ini"), 'r') as configFile:
self.localConfig.read_file(configFile)
# Delegate to old function as last resort
else:
read_config(False)
self.local_config = configparser.ConfigParser()
self.local_config.read_dict(globals().get('localConfig', {}))
self.localConfig = configparser.ConfigParser()
self.localConfig.read_dict(globals().get('localConfig', {}))
except:
pass
def read_global_config(self):
"""Read global configuration from file."""
try:
# Try to use path_service if available
if self.path_service and self.path_service.global_path:
with open(os.path.join(self.path_service.global_path, "config.ini"), 'r') as configfile:
self.global_config.read_file(configfile)
# Try to use pathService if available
if self.pathService and self.pathService.globalPath:
with open(os.path.join(self.pathService.globalPath, "config.ini"), 'r') as configFile:
self.globalConfig.read_file(configFile)
# Fallback to global globalPath
elif globalPath:
with open(os.path.join(globalPath, "config.ini"), 'r') as configfile:
self.global_config.read_file(configfile)
with open(os.path.join(globalPath, "config.ini"), 'r') as configFile:
self.globalConfig.read_file(configFile)
# Delegate to old function as last resort
else:
read_config(True)
self.global_config = configparser.ConfigParser()
self.global_config.read_dict(globals().get('globalConfig', {}))
self.globalConfig = configparser.ConfigParser()
self.globalConfig.read_dict(globals().get('globalConfig', {}))
except:
pass
def write_local_config(self):
"""Write local configuration to file."""
try:
# Try to use path_service if available
if self.path_service and self.path_service.game_path:
with open(os.path.join(self.path_service.game_path, "config.ini"), 'w') as configfile:
self.local_config.write(configfile)
# Try to use pathService if available
if self.pathService and self.pathService.gamePath:
with open(os.path.join(self.pathService.gamePath, "config.ini"), 'w') as configFile:
self.localConfig.write(configFile)
# Fallback to global gamePath
elif gamePath:
with open(os.path.join(gamePath, "config.ini"), 'w') as configfile:
self.local_config.write(configfile)
with open(os.path.join(gamePath, "config.ini"), 'w') as configFile:
self.localConfig.write(configFile)
# Delegate to old function as last resort
else:
# Update old global config
globals()['localConfig'] = self.local_config
globals()['localConfig'] = self.localConfig
write_config(False)
except Exception as e:
print(f"Warning: Failed to write local config: {e}")
@ -108,18 +108,18 @@ class ConfigService:
def write_global_config(self):
"""Write global configuration to file."""
try:
# Try to use path_service if available
if self.path_service and self.path_service.global_path:
with open(os.path.join(self.path_service.global_path, "config.ini"), 'w') as configfile:
self.global_config.write(configfile)
# Try to use pathService if available
if self.pathService and self.pathService.globalPath:
with open(os.path.join(self.pathService.globalPath, "config.ini"), 'w') as configFile:
self.globalConfig.write(configFile)
# Fallback to global globalPath
elif globalPath:
with open(os.path.join(globalPath, "config.ini"), 'w') as configfile:
self.global_config.write(configfile)
with open(os.path.join(globalPath, "config.ini"), 'w') as configFile:
self.globalConfig.write(configFile)
# Delegate to old function as last resort
else:
# Update old global config
globals()['globalConfig'] = self.global_config
globals()['globalConfig'] = self.globalConfig
write_config(True)
except Exception as e:
print(f"Warning: Failed to write global config: {e}")
@ -139,75 +139,75 @@ class VolumeService:
def __init__(self):
"""Initialize volume settings."""
self.bgm_volume = 0.75 # Default background music volume
self.sfx_volume = 1.0 # Default sound effects volume
self.master_volume = 1.0 # Default master volume
self.bgmVolume = 0.75 # Default background music volume
self.sfxVolume = 1.0 # Default sound effects volume
self.masterVolume = 1.0 # Default master volume
def adjust_master_volume(self, change, pygame_mixer=None):
def adjust_master_volume(self, change, pygameMixer=None):
"""Adjust the master volume for all sounds.
Args:
change (float): Amount to change volume by (positive or negative)
pygame_mixer: Optional pygame.mixer module for real-time updates
pygameMixer: Optional pygame.mixer module for real-time updates
"""
self.master_volume = max(0.0, min(1.0, self.master_volume + change))
self.masterVolume = max(0.0, min(1.0, self.masterVolume + change))
# Update real-time audio if pygame mixer is provided
if pygame_mixer:
if pygameMixer:
# Update music volume
if pygame_mixer.music.get_busy():
pygame_mixer.music.set_volume(self.bgm_volume * self.master_volume)
if pygameMixer.music.get_busy():
pygameMixer.music.set_volume(self.bgmVolume * self.masterVolume)
# Update all sound channels
for i in range(pygame_mixer.get_num_channels()):
channel = pygame_mixer.Channel(i)
for i in range(pygameMixer.get_num_channels()):
channel = pygameMixer.Channel(i)
if channel.get_busy():
current_volume = channel.get_volume()
if isinstance(current_volume, (int, float)):
currentVolume = channel.get_volume()
if isinstance(currentVolume, (int, float)):
# Mono audio
channel.set_volume(current_volume * self.master_volume)
channel.set_volume(currentVolume * self.masterVolume)
else:
# Stereo audio
left, right = current_volume
channel.set_volume(left * self.master_volume, right * self.master_volume)
left, right = currentVolume
channel.set_volume(left * self.masterVolume, right * self.masterVolume)
def adjust_bgm_volume(self, change, pygame_mixer=None):
def adjust_bgm_volume(self, change, pygameMixer=None):
"""Adjust only the background music volume.
Args:
change (float): Amount to change volume by (positive or negative)
pygame_mixer: Optional pygame.mixer module for real-time updates
pygameMixer: Optional pygame.mixer module for real-time updates
"""
self.bgm_volume = max(0.0, min(1.0, self.bgm_volume + change))
self.bgmVolume = max(0.0, min(1.0, self.bgmVolume + change))
# Update real-time audio if pygame mixer is provided
if pygame_mixer and pygame_mixer.music.get_busy():
pygame_mixer.music.set_volume(self.bgm_volume * self.master_volume)
if pygameMixer and pygameMixer.music.get_busy():
pygameMixer.music.set_volume(self.bgmVolume * self.masterVolume)
def adjust_sfx_volume(self, change, pygame_mixer=None):
def adjust_sfx_volume(self, change, pygameMixer=None):
"""Adjust volume for sound effects only.
Args:
change (float): Amount to change volume by (positive or negative)
pygame_mixer: Optional pygame.mixer module for real-time updates
pygameMixer: Optional pygame.mixer module for real-time updates
"""
self.sfx_volume = max(0.0, min(1.0, self.sfx_volume + change))
self.sfxVolume = max(0.0, min(1.0, self.sfxVolume + change))
# Update real-time audio if pygame mixer is provided
if pygame_mixer:
if pygameMixer:
# Update all sound channels except reserved ones
for i in range(pygame_mixer.get_num_channels()):
channel = pygame_mixer.Channel(i)
for i in range(pygameMixer.get_num_channels()):
channel = pygameMixer.Channel(i)
if channel.get_busy():
current_volume = channel.get_volume()
if isinstance(current_volume, (int, float)):
currentVolume = channel.get_volume()
if isinstance(currentVolume, (int, float)):
# Mono audio
channel.set_volume(current_volume * self.sfx_volume * self.master_volume)
channel.set_volume(currentVolume * self.sfxVolume * self.masterVolume)
else:
# Stereo audio
left, right = current_volume
channel.set_volume(left * self.sfx_volume * self.master_volume,
right * self.sfx_volume * self.master_volume)
left, right = currentVolume
channel.set_volume(left * self.sfxVolume * self.masterVolume,
right * self.sfxVolume * self.masterVolume)
def get_bgm_volume(self):
"""Get the current BGM volume with master adjustment.
@ -215,7 +215,7 @@ class VolumeService:
Returns:
float: Current adjusted BGM volume
"""
return self.bgm_volume * self.master_volume
return self.bgmVolume * self.masterVolume
def get_sfx_volume(self):
"""Get the current SFX volume with master adjustment.
@ -223,7 +223,7 @@ class VolumeService:
Returns:
float: Current adjusted SFX volume
"""
return self.sfx_volume * self.master_volume
return self.sfxVolume * self.masterVolume
class PathService:
@ -240,35 +240,35 @@ class PathService:
def __init__(self):
"""Initialize path variables."""
self.global_path = None
self.game_path = None
self.game_name = None
self.globalPath = None
self.gamePath = None
self.gameName = None
# Try to initialize from global variables for backward compatibility
global gamePath, globalPath
if gamePath:
self.game_path = gamePath
self.gamePath = gamePath
if globalPath:
self.global_path = globalPath
self.globalPath = globalPath
def initialize(self, game_title):
def initialize(self, gameTitle):
"""Initialize paths for a game.
Args:
game_title (str): Title of the game
gameTitle (str): Title of the game
"""
self.game_name = game_title
self.global_path = os.path.join(BaseDirectory.xdg_config_home, "storm-games")
self.game_path = os.path.join(self.global_path,
str.lower(str.replace(game_title, " ", "-")))
self.gameName = gameTitle
self.globalPath = os.path.join(BaseDirectory.xdg_config_home, "storm-games")
self.gamePath = os.path.join(self.globalPath,
str.lower(str.replace(gameTitle, " ", "-")))
# Create game directory if it doesn't exist
if not os.path.exists(self.game_path):
os.makedirs(self.game_path)
if not os.path.exists(self.gamePath):
os.makedirs(self.gamePath)
# Update global variables for backward compatibility
global gamePath, globalPath
gamePath = self.game_path
globalPath = self.global_path
gamePath = self.gamePath
globalPath = self.globalPath
return self