lucky / index 19.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">
<title>GBA.js - Touch Enabled</title>
<link rel="stylesheet" href="resources/main.css">
<style>
body, html {
margin: 0;
padding: 0;
height: 100%;
overflow: hidden;
touch-action: manipulation; /* Helps reduce double-tap zoom globally */
background: #000;
}
#screen-container {
position: relative;
width: 100%;
height: 100%;
max-width: 100vw;
max-height: 100vh;
display: flex;
justify-content: center;
align-items: center;
background: #111;
}
#screen {
width: 100%;
height: auto;
max-width: 100%;
max-height: 100%;
image-rendering: pixelated; /* Optional: keep crisp pixels */
touch-action: none; /* Prevent zoom/pan on canvas itself */
}
#touchControls {
position: absolute;
inset: 0;
pointer-events: none;
display: none;
z-index: 10;
padding: 2vmin;
box-sizing: border-box;
}
#dpad, #faceButtons {
pointer-events: auto;
}
button {
font-size: 4vmin;
font-weight: bold;
color: white;
border: none;
border-radius: 50%;
opacity: 0.6;
touch-action: manipulation;
user-select: none;
-webkit-tap-highlight-color: transparent;
}
button:active {
opacity: 0.9;
}
#dpad {
display: grid;
grid-template-columns: repeat(3, 18vmin);
grid-template-rows: repeat(3, 18vmin);
gap: 1vmin;
}
#faceButtons {
display: flex;
flex-direction: column;
align-items: flex-end;
gap: 2vmin;
}
.shoulder {
width: 18vmin;
height: 10vmin;
border-radius: 10vmin;
background: rgba(200,200,200,0.5);
font-size: 3.5vmin;
}
.start-select {
width: 18vmin;
height: 10vmin;
border-radius: 8vmin;
background: rgba(0,180,0,0.5);
font-size: 3vmin;
}
#a { background: rgba(255,80,80,0.7); width: 22vmin; height: 22vmin; }
#b { background: rgba(80,80,255,0.7); width: 22vmin; height: 22vmin; }
@media (orientation: landscape) {
#touchControls { flex-direction: row; justify-content: space-between; align-items: flex-end; }
#dpad { grid-template-columns: repeat(3, 14vmin); grid-template-rows: repeat(3, 14vmin); }
#faceButtons { flex-direction: row; align-items: flex-end; gap: 4vmin; }
#faceButtons > div { flex-direction: column; }
}
@media (orientation: portrait) {
#touchControls { flex-direction: column; justify-content: flex-end; }
#dpad { align-self: flex-start; }
#faceButtons { align-self: flex-end; }
}
</style>
<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>
// ... (keep all your original script code here: gba init, onload, fadeOut, run, reset, etc.)
// Add these inside window.onload after gba setup:
window.onload = function() {
if (gba && FileReader) {
var canvas = document.getElementById('screen');
gba.setCanvas(canvas);
gba.logLevel = gba.LOG_ERROR;
loadRom('resources/bios.bin', function(bios) {
gba.setBios(bios);
});
// ... (keep original audio/pixelated/IE checks)
// Detect touch and show controls
if ('ontouchstart' in window || navigator.maxTouchPoints > 0) {
document.getElementById('touchControls').style.display = 'flex';
// Make canvas fit screen better
canvas.style.width = '100%';
canvas.style.height = 'auto';
canvas.style.maxHeight = '85vh'; // Leave space for controls
}
setupTouchControls();
} else {
// ... original fallback
}
};
// Your original functions here (fadeOut, run, reset, togglePause, screenshot, etc.)
function setupTouchControls() {
function press(code) {
window.dispatchEvent(new KeyboardEvent('keydown', {keyCode: code, bubbles: true}));
}
function release(code) {
window.dispatchEvent(new KeyboardEvent('keyup', {keyCode: code, bubbles: true}));
}
// Standard GBA.js mappings (adjust if your keypad.js uses different keys)
const keys = {
up: 38, // ↑
down: 40, // ↓
left: 37, // ←
right: 39, // β†’
a: 88, // X β†’ A button
b: 90, // Z β†’ B button
l: 65, // A β†’ L
r: 83, // S β†’ R
start: 13, // Enter
select: 16 // Shift
};
// Attach to each button
['up','down','left','right','a','b','l','r','start','select'].forEach(id => {
const btn = document.getElementById(id);
if (btn) {
btn.addEventListener('touchstart', e => { e.preventDefault(); press(keys[id]); });
btn.addEventListener('touchend', e => { e.preventDefault(); release(keys[id]); });
btn.addEventListener('touchcancel',e => { e.preventDefault(); release(keys[id]); });
}
});
}
</script>
</head>
<body>
<div id="screen-container">
<canvas id="screen" width="480" height="320"></canvas>
</div>
<section id="controls">
<!-- Your original preload & ingame UI here (SELECT, PAUSE, etc.) -->
<div id="preload">
<button class="bigbutton" id="select" onclick="document.getElementById('loader').click()">SELECT</button>
<input id="loader" type="file" accept=".gba" onchange="run(this.files[0]);">
<button onclick="document.getElementById('saveloader').click()">Upload Savegame</button>
<input id="saveloader" type="file" onchange="uploadSavedataPending(this.files[0]);">
</div>
<div id="ingame" class="hidden">
<button id="pause" class="bigbutton" onclick="togglePause()">PAUSE</button>
<button class="bigbutton" onclick="reset()">RESET</button>
<button onclick="gba.downloadSavedata()">Download Savegame</button>
<button onclick="screenshot()">Screenshot</button>
<!-- ... rest of ingame controls -->
</div>
</section>
<!-- Responsive Touch Overlay -->
<div id="touchControls">
<!-- Left: D-Pad -->
<div id="dpad">
<button id="up">↑</button>
<button id="left">←</button>
<button id="right">β†’</button>
<button id="down">↓</button>
</div>
<!-- Right: Buttons -->
<div id="faceButtons">
<div>
<button id="l" class="shoulder">L</button>
<button id="r" class="shoulder">R</button>
</div>
<div>
<button id="select" class="start-select">Select</button>
<button id="start" class="start-select">Start</button>
</div>
<div>
<button id="b">B</button>
<button id="a">A</button>
</div>
</div>
</div>
</body>
</html>