lucky / index 22.html
Studytime171's picture
Duplicate from Studytime171/Lalitgangwani
89610f7
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover">
<title>GBA.js Emulator - Touch Controls</title>
<style>
* { margin:0; padding:0; box-sizing:border-box; }
html, body {
height:100%;
overflow:hidden;
background:#000;
touch-action: manipulation;
font-family: Arial, sans-serif;
}
#screen-container {
position:relative;
width:100%;
height:100%;
display:flex;
justify-content:center;
align-items:center;
background:#111;
}
#screen {
width:100%;
height:auto;
max-width:100%;
max-height:80vh;
image-rendering:pixelated;
touch-action:none;
}
#ui {
position:absolute;
top:10px;
left:10px;
z-index:30;
background:rgba(0,0,0,0.7);
color:white;
padding:10px;
border-radius:8px;
font-size:14px;
}
button { padding:8px 16px; margin:4px; font-size:16px; cursor:pointer; }
#touchControls {
position:absolute;
inset:0;
pointer-events:none;
display:none;
z-index:20;
padding:4vmin;
}
.btn {
font-weight:bold;
color:white;
border:none;
border-radius:50%;
opacity:0.75;
touch-action:manipulation;
-webkit-tap-highlight-color:transparent;
}
.btn:active { opacity:1; }
#dpad {
display:grid;
grid-template-columns:repeat(3, 20vmin);
grid-template-rows:repeat(3, 20vmin);
gap:1.5vmin;
}
#face {
display:flex;
flex-direction:column;
align-items:flex-end;
gap:3vmin;
}
.shoulder, .sys {
width:20vmin;
height:10vmin;
border-radius:10vmin;
background:rgba(180,180,180,0.7);
font-size:4vmin;
}
#a { background:rgba(220,60,60,0.85); width:24vmin; height:24vmin; font-size:6vmin; }
#b { background:rgba(60,60,220,0.85); width:24vmin; height:24vmin; font-size:6vmin; }
@media (orientation: landscape) {
#touchControls { display:flex; flex-direction:row; justify-content:space-between; align-items:flex-end; }
#dpad { grid-template-columns:repeat(3, 16vmin); grid-template-rows:repeat(3, 16vmin); }
#face { flex-direction:row; gap:5vmin; }
}
@media (orientation: portrait) {
#touchControls { display:flex; flex-direction:column; justify-content:flex-end; gap:4vmin; }
#dpad { align-self:flex-start; }
#face { align-self:flex-end; }
}
</style>
<!-- Include all GBA.js scripts (adjust paths if needed) -->
<script src="js/util.js"></script>
<script src="js/core.js"></script>
<script src="js/arm.js"></script>
<script src="js/thumb.js"></script>
<script src="js/mmu.js"></script>
<script src="js/io.js"></script>
<script src="js/audio.js"></script>
<script src="js/video.js"></script>
<script src="js/video/proxy.js"></script>
<script src="js/video/software.js"></script>
<script src="js/irq.js"></script>
<script src="js/keypad.js"></script>
<script src="js/sio.js"></script>
<script src="js/savedata.js"></script>
<script src="js/gpio.js"></script>
<script src="js/gba.js"></script>
<script src="resources/xhr.js"></script>
<script>
var gba = null;
var runCommands = [];
try {
gba = new GameBoyAdvance();
gba.keypad.eatInput = true;
gba.setLogger((level, msg) => console.log("[GBA]", msg));
} catch (e) {
console.error("Failed to init GBA:", e);
}
window.onload = () => {
if (!gba) {
alert("Emulator failed to initialize. Check console for errors.");
return;
}
const canvas = document.getElementById('screen');
gba.setCanvas(canvas);
gba.logLevel = 1; // LOG_ERROR or adjust
// Load BIOS
const xhr = new XMLHttpRequest();
xhr.open('GET', 'resources/bios.bin', true);
xhr.responseType = 'arraybuffer';
xhr.onload = () => {
if (xhr.status === 200) {
gba.setBios(new Uint8Array(xhr.response));
console.log("BIOS loaded");
} else {
console.warn("BIOS not found – some games may not boot correctly");
}
};
xhr.send();
// Touch device detection
if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
document.getElementById('touchControls').style.display = 'flex';
canvas.style.maxHeight = '70vh';
}
// Focus canvas on touch
canvas.addEventListener('touchstart', () => canvas.focus());
setupTouch();
};
function run(file) {
if (!gba) return;
document.getElementById('select').textContent = 'Loading...';
gba.loadRomFromFile(file, success => {
if (success) {
gba.runStable();
document.getElementById('ui').innerHTML = '<button onclick="gba.pause(); this.innerText=gba.paused?\'Run\':\'Pause\'">Pause</button> <button onclick="gba.reset()">Reset</button>';
} else {
alert("Failed to load ROM. Try another file.");
document.getElementById('select').textContent = 'SELECT ROM';
}
});
}
function setupTouch() {
const press = code => window.dispatchEvent(new KeyboardEvent('keydown', {keyCode: code, bubbles: true}));
const release = code => window.dispatchEvent(new KeyboardEvent('keyup', {keyCode: code, bubbles: true}));
const mapping = {
up: 38, down: 40, left: 37, right: 39,
a: 88, // X
b: 90, // Z
l: 81, // Q (common L)
r: 69, // E (common R)
start: 13, // Enter
select:16 // Shift
};
document.querySelectorAll('.btn').forEach(btn => {
const action = btn.id;
if (!mapping[action]) return;
btn.addEventListener('touchstart', e => { e.preventDefault(); press(mapping[action]); });
btn.addEventListener('touchend', e => { e.preventDefault(); release(mapping[action]); });
btn.addEventListener('touchcancel',e => { e.preventDefault(); release(mapping[action]); });
});
}
</script>
</head>
<body>
<div id="screen-container">
<canvas id="screen" width="480" height="320" tabindex="0"></canvas>
</div>
<div id="ui">
<button id="select" onclick="document.getElementById('romfile').click()">SELECT ROM</button>
<input id="romfile" type="file" accept=".gba" onchange="run(this.files[0])" style="display:none;">
</div>
<div id="touchControls">
<div id="dpad">
<button id="up" class="btn"></button>
<button id="left" class="btn"></button>
<button id="right" class="btn"></button>
<button id="down" class="btn"></button>
</div>
<div id="face">
<div>
<button id="l" class="shoulder btn">L</button>
<button id="r" class="shoulder btn">R</button>
</div>
<div>
<button id="select" class="sys btn">SEL</button>
<button id="start" class="sys btn">STR</button>
</div>
<div>
<button id="b" class="btn">B</button>
<button id="a" class="btn">A</button>
</div>
</div>
</div>
</body>
</html>