Spaces:
Paused
Paused
| import gradio as gr | |
| import os | |
| import zipfile | |
| from pathlib import Path | |
| import shutil | |
| import urllib.parse | |
| # Define constants | |
| ZIP_FILE = "nes.zip" | |
| EXTRACTED_FOLDER = "extracted_nes" | |
| PUBLIC_FOLDER = "public/roms" | |
| # Ensure public ROM folder exists | |
| os.makedirs(PUBLIC_FOLDER, exist_ok=True) | |
| # Function to extract ROMs from the zip | |
| def extract_roms(): | |
| try: | |
| if os.path.exists(ZIP_FILE): | |
| with zipfile.ZipFile(ZIP_FILE, 'r') as zip_ref: | |
| zip_ref.extractall(EXTRACTED_FOLDER) | |
| print(f"Extracted into {EXTRACTED_FOLDER}") | |
| # Move ROMs into the public folder | |
| for root, dirs, files in os.walk(EXTRACTED_FOLDER): | |
| for file in files: | |
| if file.lower().endswith(".nes"): | |
| source_path = os.path.join(root, file) | |
| target_path = os.path.join(PUBLIC_FOLDER, file) | |
| shutil.move(source_path, target_path) | |
| print(f"Moved ROM: {file} -> {target_path}") | |
| else: | |
| raise FileNotFoundError("`nes.zip` not found.") | |
| except PermissionError as e: | |
| print(f"Permission error: {e}") | |
| # Function to list available ROMs | |
| def list_roms(): | |
| if not os.path.exists(PUBLIC_FOLDER): | |
| print("No ROMs found.") | |
| return [] | |
| roms = [f for f in os.listdir(PUBLIC_FOLDER) if f.endswith(".nes")] | |
| print("Available ROMs:", roms) | |
| return roms | |
| # Function to generate the HTML content for the selected ROM | |
| def generate_rom_page(rom_name): | |
| rom_url = f"/roms/{urllib.parse.quote(rom_name)}" | |
| html_content = f""" | |
| <div style='width:640px;height:480px;max-width:100%'> | |
| <div id='game'></div> | |
| </div> | |
| <script> | |
| if (typeof EJS_player === 'undefined') {{ | |
| var script = document.createElement('script'); | |
| script.src = "https://cdn.emulatorjs.org/stable/data/loader.js"; | |
| script.onload = function() {{ | |
| window.addEventListener('load', function() {{ | |
| EJS_player = "#game"; | |
| EJS_core = "nes"; | |
| EJS_color = "#0064ff"; | |
| EJS_pathtodata = "https://cdn.emulatorjs.org/stable/data/"; | |
| EJS_gameUrl = "{rom_url}"; | |
| }}); | |
| }}; | |
| document.body.appendChild(script); | |
| }} | |
| </script> | |
| <style> | |
| #game {{ | |
| width: 100%; | |
| height: 100%; | |
| background-color: #000; | |
| position: relative; | |
| }} | |
| .fullscreen-btn {{ | |
| position: absolute; | |
| top: 10px; | |
| right: 10px; | |
| background: rgba(0, 100, 255, 0.7); | |
| padding: 10px 20px; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| color: white; | |
| }} | |
| </style> | |
| <button class="fullscreen-btn" onclick="toggleFullScreen()">Full Screen</button> | |
| <button class="fullscreen-btn" onclick="reloadGame()">Reload</button> | |
| <script> | |
| function toggleFullScreen() {{ | |
| const gameContainer = document.getElementById('game'); | |
| if (gameContainer.requestFullscreen) {{ | |
| gameContainer.requestFullscreen(); | |
| }} else if (gameContainer.mozRequestFullScreen) {{ | |
| gameContainer.mozRequestFullScreen(); | |
| }} else if (gameContainer.webkitRequestFullscreen) {{ | |
| gameContainer.webkitRequestFullscreen(); | |
| }} else if (gameContainer.msRequestFullscreen) {{ | |
| gameContainer.msRequestFullscreen(); | |
| }} | |
| }} | |
| function reloadGame() {{ | |
| const iframe = document.querySelector('iframe'); | |
| if (iframe) {{ | |
| iframe.src = iframe.src; | |
| }} | |
| }} | |
| </script> | |
| """ | |
| return html_content | |
| # Main Gradio app function | |
| def gradio_app(): | |
| with gr.Blocks() as app: | |
| gr.Markdown("# 🎮 Play NES ROMs in Browser!") | |
| rom_files = list_roms() | |
| with gr.Column(): | |
| rom_dropdown = gr.Dropdown(choices=rom_files, label="Select a ROM", interactive=True) | |
| output_html = gr.HTML(value="Select a ROM to start playing!", elem_id="emulator") | |
| rom_dropdown.change(fn=generate_rom_page, inputs=rom_dropdown, outputs=output_html) | |
| app.css = """ | |
| .gradio-dropdown { | |
| max-height: 400px; | |
| overflow-y: auto; | |
| margin-bottom: 20px; | |
| } | |
| .gradio-button { | |
| margin-top: 10px; | |
| margin-bottom: 10px; | |
| } | |
| """ | |
| app.launch(server_name="0.0.0.0", server_port=7860) | |
| if __name__ == "__main__": | |
| extract_roms() | |
| gradio_app() | |