ARCADE / index.html
0VSol13's picture
fix: emulator black screen + Google Drive ROM integration
e169894 verified
Raw History Blame Contribute Delete
8.74 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>NOMADZ CLOUD ARCADE</title>
<style>
*{margin:0;padding:0;box-sizing:border-box}
body{background:#000;color:#0ff;font-family:'Courier New',monospace;min-height:100vh;overflow-x:hidden}
.scanlines{position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:9999;background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,0,0,0.15) 2px,rgba(0,0,0,0.15) 4px)}
.header{text-align:center;padding:20px;border-bottom:2px solid #0ff;text-shadow:0 0 20px #0ff}
.header h1{font-size:2.5em;letter-spacing:8px;color:#0ff;animation:glow 2s ease-in-out infinite alternate}
.header p{color:#f0f;letter-spacing:4px;margin-top:8px;font-size:0.9em}
@keyframes glow{from{text-shadow:0 0 10px #0ff,0 0 20px #0ff}to{text-shadow:0 0 20px #0ff,0 0 40px #0ff,0 0 60px #0ff}}
.portal{max-width:1000px;margin:30px auto;padding:0 20px}
.controls{display:grid;grid-template-columns:1fr 1fr 1fr;gap:15px;margin-bottom:25px}
.ctrl-group{background:#001a1a;border:1px solid #0ff;padding:15px;border-radius:4px}
.ctrl-group label{display:block;color:#0ff;font-size:0.75em;letter-spacing:2px;margin-bottom:8px}
select,input[type=file],input[type=text]{width:100%;background:#000;color:#0ff;border:1px solid #0ff;padding:8px;font-family:inherit;font-size:0.85em;cursor:pointer}
select:focus,input:focus{outline:none;border-color:#f0f;box-shadow:0 0 8px #f0f}
.tab-bar{display:flex;gap:0;margin-bottom:0}
.tab-btn{flex:1;padding:6px 2px;background:#000;border:1px solid #0ff;color:#0ff;font-family:'Courier New',monospace;font-size:0.65em;letter-spacing:1px;cursor:pointer;transition:all 0.2s}
.tab-btn.active{background:#0ff;color:#000}
.tab-panel{display:none;padding-top:10px}
.tab-panel.active{display:block}
.drive-hint{font-size:0.65em;color:#f0f;margin-top:5px;letter-spacing:1px}
.launch-btn{display:block;width:100%;padding:15px;background:transparent;border:2px solid #0ff;color:#0ff;font-family:'Courier New',monospace;font-size:1.2em;letter-spacing:6px;cursor:pointer;text-align:center;transition:all 0.3s;margin-bottom:25px}
.launch-btn:hover{background:#0ff;color:#000;box-shadow:0 0 30px #0ff}
.launch-btn:disabled{opacity:0.4;cursor:not-allowed}
#game-container{width:100%;background:#000;border:2px solid #0ff;min-height:500px;height:600px;position:relative;display:none}
#game-container.active{display:block;height:600px}
.idle-screen{text-align:center;padding:60px 20px;border:2px solid #0ff;background:#000}
.idle-screen pre{color:#0ff;font-size:0.7em;line-height:1.2;text-shadow:0 0 5px #0ff}
.idle-screen p{color:#f0f;margin-top:20px;letter-spacing:3px;animation:blink 1s step-end infinite}
@keyframes blink{50%{opacity:0}}
.status-bar{display:flex;justify-content:space-between;padding:8px 15px;background:#001a1a;border:1px solid #0ff;margin-bottom:25px;font-size:0.75em;letter-spacing:2px}
.status-dot{width:8px;height:8px;border-radius:50%;background:#0f0;display:inline-block;margin-right:6px;animation:pulse 1.5s infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:0.3}}
.error-msg{color:#f00;padding:20px;text-align:center;letter-spacing:2px;font-size:0.85em}
.footer{text-align:center;padding:20px;border-top:1px solid #0ff;color:#0ff;font-size:0.7em;letter-spacing:3px;margin-top:30px}
</style>
</head>
<body>
<div class="scanlines"></div>
<div class="header">
<h1>NOMADZ</h1>
<p>// CLOUD ARCADE // VULTURE:INC // 0VSol13 //</p>
</div>
<div class="portal">
<div class="status-bar">
<span><span class="status-dot"></span>SYSTEM ONLINE</span>
<span>NODE: ARCADE-01</span>
<span>EMULATORJS v4.0</span>
</div>
<div class="controls">
<div class="ctrl-group">
<label>// SYSTEM CORE //</label>
<select id="core">
<option value="snes">SNES</option>
<option value="nes">NES</option>
<option value="gba">GBA</option>
<option value="n64">N64</option>
<option value="genesis">GENESIS</option>
<option value="arcade">ARCADE</option>
</select>
</div>
<div class="ctrl-group">
<label>// ROM SOURCE //</label>
<div class="tab-bar">
<button class="tab-btn active" onclick="switchTab(event,'local')">LOCAL</button>
<button class="tab-btn" onclick="switchTab(event,'drive')">DRIVE</button>
<button class="tab-btn" onclick="switchTab(event,'vault')">VAULT</button>
</div>
<div id="tab-local" class="tab-panel active">
<input type="file" id="rom-file" accept=".smc,.sfc,.nes,.gba,.n64,.z64,.v64,.md,.bin,.rom,.zip">
</div>
<div id="tab-drive" class="tab-panel">
<input type="text" id="drive-url" placeholder="Paste Google Drive share link...">
<div class="drive-hint">Must be set to Anyone with link can view</div>
</div>
<div id="tab-vault" class="tab-panel">
<input type="text" id="vault-path" placeholder="/ROM_VAULT/filename.sfc">
<div class="drive-hint">Files in ROM_VAULT/ folder of this Space</div>
</div>
</div>
<div class="ctrl-group">
<label>// BIOS (OPTIONAL) //</label>
<input type="file" id="bios-file" accept=".bin,.bios">
</div>
</div>
<button class="launch-btn" onclick="launchGame()" id="launch-btn">[ INSERT COIN // LAUNCH ]</button>
<div class="idle-screen" id="idle-screen">
<pre>
___ _ ___ ___ __ ___ __
| .| | \/ || \ / || \
| | | |\ /| || Y || |
|___/|_|_| v |_||___| |___|_/__|
ARCADE
</pre>
<p>>> SELECT CORE + LOAD ROM TO BEGIN &lt;&lt;</p>
</div>
<div id="game-container"></div>
</div>
<div class="footer">NOMADZ UNIVERSE // COSMIC-KEY PRODUCTIONS // ALL SYSTEMS NOMINAL</div>
<script>
var activeTab='local';
function switchTab(e,tab){
activeTab=tab;
document.querySelectorAll('.tab-btn').forEach(function(b){b.classList.remove('active');});
document.querySelectorAll('.tab-panel').forEach(function(p){p.classList.remove('active');});
e.target.classList.add('active');
document.getElementById('tab-'+tab).classList.add('active');
}
function driveShareToDirect(url){
var match=url.match(/\/file\/d\/([a-zA-Z0-9_-]+)/);
if(!match)match=url.match(/[?&]id=([a-zA-Z0-9_-]+)/);
if(!match)return null;
return 'https://drive.google.com/uc?export=download&id='+match[1]+'&confirm=t';
}
function launchGame(){
var coreSelect=document.getElementById('core');
var biosInput=document.getElementById('bios-file');
var gc=document.getElementById('game-container');
var btn=document.getElementById('launch-btn');
var romUrl=null;
if(activeTab==='local'){
var romInput=document.getElementById('rom-file');
if(!romInput.files||!romInput.files[0]){alert('LOAD A ROM FILE TO LAUNCH');return;}
window._romBlobUrl=URL.createObjectURL(romInput.files[0]);
romUrl=window._romBlobUrl;
}else if(activeTab==='drive'){
var rawUrl=document.getElementById('drive-url').value.trim();
if(!rawUrl){alert('PASTE A GOOGLE DRIVE SHARE LINK');return;}
romUrl=driveShareToDirect(rawUrl);
if(!romUrl){alert('INVALID GOOGLE DRIVE URL');return;}
}else if(activeTab==='vault'){
var vaultPath=document.getElementById('vault-path').value.trim();
if(!vaultPath){alert('ENTER A ROM_VAULT PATH');return;}
romUrl=vaultPath.startsWith('/')?vaultPath:'/'+vaultPath;
}
var biosUrl=null;
if(biosInput.files&&biosInput.files[0]){
window._biosBlobUrl=URL.createObjectURL(biosInput.files[0]);
biosUrl=window._biosBlobUrl;
}
document.getElementById('idle-screen').style.display='none';
btn.disabled=true;
btn.textContent='[ LOADING... ]';
gc.style.height='600px';
gc.style.display='block';
gc.className='active';
gc.innerHTML='';
window.EJS_player='#game-container';
window.EJS_core=coreSelect.value;
window.EJS_gameUrl=romUrl;
window.EJS_pathtodata='https://cdn.emulatorjs.org/latest/data/';
window.EJS_startOnLoaded=true;
if(biosUrl)window.EJS_biosUrl=biosUrl;
window.EJS_onGameStart=function(){
btn.textContent='[ RUNNING ]';
if(window._romBlobUrl&&activeTab==='local'){URL.revokeObjectURL(window._romBlobUrl);}
};
window.EJS_onLoadError=function(msg){
gc.innerHTML='<div class="error-msg">EMULATOR LOAD ERROR: '+(msg||'UNKNOWN')+'</div>';
btn.disabled=false;
btn.textContent='[ INSERT COIN // LAUNCH ]';
};
var s=document.createElement('script');
s.src='https://cdn.emulatorjs.org/latest/data/loader.js';
s.onerror=function(){
gc.innerHTML='<div class="error-msg">FAILED TO LOAD EMULATOR CORE FROM CDN</div>';
btn.disabled=false;
btn.textContent='[ INSERT COIN // LAUNCH ]';
};
document.body.appendChild(s);
}
</script>
</body>
</html>