File: gamecom-downloader/gamecom_downloader.py
GloomyBackground, draw_nerdymark_brand, draw_title_with_glow, create_panel,
get_theme, VOID_BLACK, DEEP_GRAY, SMOKE_GRAY, MIST_GRAY, PALE_GRAY, FOG_WHITE
)
+from git_update import UpdateChecker
BASE_URL = "https://myrient.erista.me/files/No-Intro/Tiger%20-%20Game.com/"
ROM_DIR = "/run/media/deck/SK256/Emulation/roms/gamecom"
def __init__(self):
self.font_brand = pygame.font.Font(None, 24)
self.background = GloomyBackground(self.width, self.height, accent_color=ACCENT)
self.clock = pygame.time.Clock()
+ # Git update checker
+ self.update_checker = UpdateChecker()
+ self.update_banner_visible = False
def get_existing_games(self):
existing = set()
def draw_main_menu(self):
controls_surf = self.font_small.render(controls, True, MIST_GRAY)
self.screen.blit(controls_surf, (self.width//2 - controls_surf.get_width()//2, self.height - 40))
draw_nerdymark_brand(self.screen, self.font_brand, ACCENT_DIM)
+ self.draw_update_banner()
def draw_keyboard(self):
overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
def download_game(self, game_name, href):
self.filter_games()
return True
+ def draw_update_banner(self):
+ """Draw update available notification banner at top of screen"""
+ if not self.update_banner_visible:
+ return
+ banner_height = 30
+ banner_surface = pygame.Surface((self.width, banner_height), pygame.SRCALPHA)
+ pygame.draw.rect(banner_surface, (80, 60, 20, 200), (0, 0, self.width, banner_height))
+ msg = self.update_checker.message
+ if self.update_checker.can_update:
+ msg += " - Press SELECT to update"
+ text_surf = self.font_tiny.render(msg, True, (255, 220, 100))
+ banner_surface.blit(text_surf, (self.width//2 - text_surf.get_width()//2, 6))
+ self.screen.blit(banner_surface, (0, 0))
+
+ def check_for_updates(self):
+ """Check for updates and show dialog if update can be applied"""
+ self.draw_message("Checking for updates...", "Please wait")
+ pygame.display.flip()
+
+ status = self.update_checker.check()
+ if status['update_available']:
+ self.update_banner_visible = True
+ if status['can_update']:
+ return self.offer_update_dialog()
+ return False
+
+ def offer_update_dialog(self):
+ """Show dialog offering to update. Returns True if user chose to update."""
+ selected = 0
+ options = ["Update Now", "Skip"]
+
+ while True:
+ self.background.update()
+ self.background.draw(self.screen)
+ draw_title_with_glow(self.screen, self.font_large, "UPDATE AVAILABLE", ACCENT, self.height//2 - 100)
+
+ msg = f"{self.update_checker._status['behind']} new commits available"
+ msg_surf = self.font_medium.render(msg, True, PALE_GRAY)
+ self.screen.blit(msg_surf, (self.width//2 - msg_surf.get_width()//2, self.height//2 - 40))
+
+ for i, opt in enumerate(options):
+ y = self.height//2 + 20 + i * 50
+ color = ACCENT if i == selected else MIST_GRAY
+ opt_surf = self.font_medium.render(f"{'> ' if i == selected else ' '}{opt}", True, color)
+ self.screen.blit(opt_surf, (self.width//2 - opt_surf.get_width()//2, y))
+
+ draw_nerdymark_brand(self.screen, self.font_brand, ACCENT_DIM)
+ pygame.display.flip()
+
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ return False
+ if event.type == pygame.KEYDOWN:
+ if event.key == pygame.K_UP:
+ selected = max(0, selected - 1)
+ elif event.key == pygame.K_DOWN:
+ selected = min(len(options) - 1, selected + 1)
+ elif event.key == pygame.K_RETURN:
+ if selected == 0:
+ return self.perform_update()
+ return False
+ elif event.key == pygame.K_ESCAPE:
+ return False
+ if event.type == pygame.JOYBUTTONDOWN:
+ if event.button == 0:
+ if selected == 0:
+ return self.perform_update()
+ return False
+ elif event.button == 1:
+ return False
+
+ if self.joystick and self.joystick.get_numhats() > 0:
+ hat = self.joystick.get_hat(0)
+ if hat[1] == 1:
+ selected = max(0, selected - 1)
+ pygame.time.wait(150)
+ elif hat[1] == -1:
+ selected = min(len(options) - 1, selected + 1)
+ pygame.time.wait(150)
+
+ self.clock.tick(30)
+
+ def perform_update(self):
+ """Perform the git update and show result"""
+ self.draw_message("Updating...", "Pulling latest changes from git")
+ pygame.display.flip()
+
+ success, message = self.update_checker.update()
+
+ if success:
+ self.draw_message("Update Complete!", "Please restart the tool")
+ pygame.display.flip()
+ pygame.time.wait(3000)
+ pygame.quit()
+ sys.exit(0)
+ else:
+ self.draw_message("Update Failed", message[:50])
+ pygame.display.flip()
+ pygame.time.wait(3000)
+ return False
+
+
def download_all(self):
missing_games = [(name, href) for name, href, status in self.filtered_games if not status]
if not missing_games:
def download_all(self):
def run(self):
os.makedirs(ROM_DIR, exist_ok=True)
+
+ # Check for updates at startup
+ self.check_for_updates()
self.existing_games = self.get_existing_games()
self.games = self.fetch_game_list()
File: gamecube-downloader/gamecube_downloader.py
GloomyBackground, draw_nerdymark_brand, draw_title_with_glow, create_panel,
get_theme, VOID_BLACK, DEEP_GRAY, SMOKE_GRAY, MIST_GRAY, PALE_GRAY, FOG_WHITE
)
+from git_update import UpdateChecker
BASE_URL = "https://myrient.erista.me/files/Redump/Nintendo%20-%20GameCube%20-%20NKit%20RVZ%20%5Bzstd-19-128k%5D/"
GC_ROM_DIR = "/run/media/deck/SK256/Emulation/roms/gc"
def __init__(self):
self.background = GloomyBackground(self.width, self.height, accent_color=ACCENT)
self.clock = pygame.time.Clock()
+ # Git update checker
+ self.update_checker = UpdateChecker()
+ self.update_banner_visible = False
def get_existing_games(self):
"""Get list of already downloaded games"""
def draw_main_menu(self):
self.screen.blit(controls_surf, (self.width//2 - controls_surf.get_width()//2, self.height - 40))
draw_nerdymark_brand(self.screen, self.font_brand, ACCENT_DIM)
+ self.draw_update_banner()
def draw_keyboard(self):
overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
def download_game(self, game_name, href):
self.filter_games()
return True
+ def draw_update_banner(self):
+ """Draw update available notification banner at top of screen"""
+ if not self.update_banner_visible:
+ return
+ banner_height = 30
+ banner_surface = pygame.Surface((self.width, banner_height), pygame.SRCALPHA)
+ pygame.draw.rect(banner_surface, (80, 60, 20, 200), (0, 0, self.width, banner_height))
+ msg = self.update_checker.message
+ if self.update_checker.can_update:
+ msg += " - Press SELECT to update"
+ text_surf = self.font_tiny.render(msg, True, (255, 220, 100))
+ banner_surface.blit(text_surf, (self.width//2 - text_surf.get_width()//2, 6))
+ self.screen.blit(banner_surface, (0, 0))
+
+ def check_for_updates(self):
+ """Check for updates and show dialog if update can be applied"""
+ self.draw_message("Checking for updates...", "Please wait")
+ pygame.display.flip()
+
+ status = self.update_checker.check()
+ if status['update_available']:
+ self.update_banner_visible = True
+ if status['can_update']:
+ return self.offer_update_dialog()
+ return False
+
+ def offer_update_dialog(self):
+ """Show dialog offering to update. Returns True if user chose to update."""
+ selected = 0
+ options = ["Update Now", "Skip"]
+
+ while True:
+ self.background.update()
+ self.background.draw(self.screen)
+ draw_title_with_glow(self.screen, self.font_large, "UPDATE AVAILABLE", ACCENT, self.height//2 - 100)
+
+ msg = f"{self.update_checker._status['behind']} new commits available"
+ msg_surf = self.font_medium.render(msg, True, PALE_GRAY)
+ self.screen.blit(msg_surf, (self.width//2 - msg_surf.get_width()//2, self.height//2 - 40))
+
+ for i, opt in enumerate(options):
+ y = self.height//2 + 20 + i * 50
+ color = ACCENT if i == selected else MIST_GRAY
+ opt_surf = self.font_medium.render(f"{'> ' if i == selected else ' '}{opt}", True, color)
+ self.screen.blit(opt_surf, (self.width//2 - opt_surf.get_width()//2, y))
+
+ draw_nerdymark_brand(self.screen, self.font_brand, ACCENT_DIM)
+ pygame.display.flip()
+
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ return False
+ if event.type == pygame.KEYDOWN:
+ if event.key == pygame.K_UP:
+ selected = max(0, selected - 1)
+ elif event.key == pygame.K_DOWN:
+ selected = min(len(options) - 1, selected + 1)
+ elif event.key == pygame.K_RETURN:
+ if selected == 0:
+ return self.perform_update()
+ return False
+ elif event.key == pygame.K_ESCAPE:
+ return False
+ if event.type == pygame.JOYBUTTONDOWN:
+ if event.button == 0:
+ if selected == 0:
+ return self.perform_update()
+ return False
+ elif event.button == 1:
+ return False
+
+ if self.joystick and self.joystick.get_numhats() > 0:
+ hat = self.joystick.get_hat(0)
+ if hat[1] == 1:
+ selected = max(0, selected - 1)
+ pygame.time.wait(150)
+ elif hat[1] == -1:
+ selected = min(len(options) - 1, selected + 1)
+ pygame.time.wait(150)
+
+ self.clock.tick(30)
+
+ def perform_update(self):
+ """Perform the git update and show result"""
+ self.draw_message("Updating...", "Pulling latest changes from git")
+ pygame.display.flip()
+
+ success, message = self.update_checker.update()
+
+ if success:
+ self.draw_message("Update Complete!", "Please restart the tool")
+ pygame.display.flip()
+ pygame.time.wait(3000)
+ pygame.quit()
+ sys.exit(0)
+ else:
+ self.draw_message("Update Failed", message[:50])
+ pygame.display.flip()
+ pygame.time.wait(3000)
+ return False
+
+
def download_all(self):
"""Download all missing games from the filtered list"""
missing_games = [(name, href) for name, href, status in self.filtered_games if not status]
def download_all(self):
def run(self):
os.makedirs(GC_ROM_DIR, exist_ok=True)
+ # Check for updates at startup
+ self.check_for_updates()
+
self.existing_games = self.get_existing_games()
self.games = self.fetch_game_list()
File: jaguar-downloader/jaguar_downloader.py
GloomyBackground, draw_nerdymark_brand, draw_title_with_glow, create_panel,
get_theme, VOID_BLACK, DEEP_GRAY, SMOKE_GRAY, MIST_GRAY, PALE_GRAY, FOG_WHITE
)
+from git_update import UpdateChecker
BASE_URL = "https://myrient.erista.me/files/No-Intro/Atari%20-%20Atari%20Jaguar%20%28J64%29/"
ROM_DIR = "/run/media/deck/SK256/Emulation/roms/atarijaguar"
def __init__(self):
self.font_brand = pygame.font.Font(None, 24)
self.background = GloomyBackground(self.width, self.height, accent_color=ACCENT)
self.clock = pygame.time.Clock()
+ # Git update checker
+ self.update_checker = UpdateChecker()
+ self.update_banner_visible = False
def get_existing_games(self):
existing = set()
def draw_main_menu(self):
controls_surf = self.font_small.render(controls, True, MIST_GRAY)
self.screen.blit(controls_surf, (self.width//2 - controls_surf.get_width()//2, self.height - 40))
draw_nerdymark_brand(self.screen, self.font_brand, ACCENT_DIM)
+ self.draw_update_banner()
def draw_keyboard(self):
overlay = pygame.Surface((self.width, self.height), pygame.SRCALPHA)
def download_game(self, game_name, href):
self.filter_games()
return True
+ def draw_update_banner(self):
+ """Draw update available notification banner at top of screen"""
+ if not self.update_banner_visible:
+ return
+ banner_height = 30
+ banner_surface = pygame.Surface((self.width, banner_height), pygame.SRCALPHA)
+ pygame.draw.rect(banner_surface, (80, 60, 20, 200), (0, 0, self.width, banner_height))
+ msg = self.update_checker.message
+ if self.update_checker.can_update:
+ msg += " - Press SELECT to update"
+ text_surf = self.font_tiny.render(msg, True, (255, 220, 100))
+ banner_surface.blit(text_surf, (self.width//2 - text_surf.get_width()//2, 6))
+ self.screen.blit(banner_surface, (0, 0))
+
+ def check_for_updates(self):
+ """Check for updates and show dialog if update can be applied"""
+ self.draw_message("Checking for updates...", "Please wait")
+ pygame.display.flip()
+
+ status = self.update_checker.check()
+ if status['update_available']:
+ self.update_banner_visible = True
+ if status['can_update']:
+ return self.offer_update_dialog()
+ return False
+
+ def offer_update_dialog(self):
+ """Show dialog offering to update. Returns True if user chose to update."""
+ selected = 0
+ options = ["Update Now", "Skip"]
+
+ while True:
+ self.background.update()
+ self.background.draw(self.screen)
+ draw_title_with_glow(self.screen, self.font_large, "UPDATE AVAILABLE", ACCENT, self.height//2 - 100)
+
+ msg = f"{self.update_checker._status['behind']} new commits available"
+ msg_surf = self.font_medium.render(msg, True, PALE_GRAY)
+ self.screen.blit(msg_surf, (self.width//2 - msg_surf.get_width()//2, self.height//2 - 40))
+
+ for i, opt in enumerate(options):
+ y = self.height//2 + 20 + i * 50
+ color = ACCENT if i == selected else MIST_GRAY
+ opt_surf = self.font_medium.render(f"{'> ' if i == selected else ' '}{opt}", True, color)
+ self.screen.blit(opt_surf, (self.width//2 - opt_surf.get_width()//2, y))
+
+ draw_nerdymark_brand(self.screen, self.font_brand, ACCENT_DIM)
+ pygame.display.flip()
+
+ for event in pygame.event.get():
+ if event.type == pygame.QUIT:
+ return False
+ if event.type == pygame.KEYDOWN:
+ if event.key == pygame.K_UP:
+ selected = max(0, selected - 1)
+ elif event.key == pygame.K_DOWN:
+ selected = min(len(options) - 1, selected + 1)
+ elif event.key == pygame.K_RETURN:
+ if selected == 0:
+ return self.perform_update()
+ return False
+ elif event.key == pygame.K_ESCAPE:
+ return False
+ if event.type == pygame.JOYBUTTONDOWN:
+ if event.button == 0:
+ if selected == 0:
+ return self.perform_update()
+ return False
+ elif event.button == 1:
+ return False
+
+ if self.joystick and self.joystick.get_numhats() > 0:
+ hat = self.joystick.get_hat(0)
+ if hat[1] == 1:
+ selected = max(0, selected - 1)
+ pygame.time.wait(150)
+ elif hat[1] == -1:
+ selected = min(len(options) - 1, selected + 1)
+ pygame.time.wait(150)
+
+ self.clock.tick(30)
+
+ def perform_update(self):
+ """Perform the git update and show result"""
+ self.draw_message("Updating...", "Pulling latest changes from git")
+ pygame.display.flip()
+
+ success, message = self.update_checker.update()
+
+ if success:
+ self.draw_message("Update Complete!", "Please restart the tool")
+ pygame.display.flip()
+ pygame.time.wait(3000)
+ pygame.quit()
+ sys.exit(0)
+ else:
+ self.draw_message("Update Failed", message[:50])
+ pygame.display.flip()
+ pygame.time.wait(3000)
+ return False
+
+
def download_all(self):
missing_games = [(name, href) for name, href, status in self.filtered_games if not status]
if not missing_games:
def download_all(self):
def run(self):
os.makedirs(ROM_DIR, exist_ok=True)
+
+ # Check for updates at startup
+ self.check_for_updates()
self.existing_games = self.get_existing_games()
self.games = self.fetch_game_list()