lucky / 0text.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 - Joystick Edition</title>
<link rel="stylesheet" href="resources/main.css">
<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>
<style>
body, html {
background: #000; color: #fff; margin: 0; padding: 0;
width: 100%; height: 100%; overflow: hidden; font-family: sans-serif;
display: flex; flex-direction: column;
}
/* Screen Area */
#screen-container {
flex: 1; display: flex; align-items: center; justify-content: center;
background: #111; position: relative;
}
canvas#screen { max-width: 100%; max-height: 100%; image-rendering: pixelated; }
/* Controller Area */
#touch-controller {
height: 45vh; background: #1a1a1a; border-top: 3px solid #333;
display: grid; grid-template-columns: 1fr 1fr;
position: relative;
}
/* JOYSTICK STYLING */
.joystick-zone { display: flex; align-items: center; justify-content: center; position: relative; }
#joystick-base {
width: 140px; height: 140px; background: rgba(255,255,255,0.1);
border-radius: 50%; border: 2px solid #444; position: relative;
touch-action: none;
}
#joystick-handle {
width: 60px; height: 60px; background: #555;
border: 2px solid #888; border-radius: 50%;
position: absolute; top: 50%; left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 4px 10px rgba(0,0,0,0.5);
pointer-events: none;
}
/* ACTION BUTTONS */
.action-zone { display: flex; align-items: center; justify-content: center; flex-direction: column; gap: 20px; }
.ab-buttons { display: flex; gap: 25px; transform: rotate(-15deg); }
.btn-circle {
width: 75px; height: 75px; border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-weight: bold; font-size: 24px; color: #fff;
box-shadow: 0 6px 0 #000;
}
.btn-a { background: #ff1744; } /* Red A */
.btn-b { background: #ffea00; color: #000; } /* Yellow B */
.btn-circle:active { transform: translateY(4px); box-shadow: 0 2px 0 #000; opacity: 0.9; }
.meta-row { display: flex; gap: 20px; margin-top: 30px; }
.btn-pill { background: #444; padding: 8px 20px; border-radius: 20px; font-size: 11px; font-weight: bold; }
#load-btn { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); padding: 15px 30px; background: #00eaff; color: #000; border: none; font-weight: bold; border-radius: 8px; z-index: 5; }
.hidden { display: none; }
</style>
</head>
<body>
<div id="screen-container">
<canvas id="screen" width="480" height="320"></canvas>
<button id="load-btn" onclick="document.getElementById('file-input').click()">CHOOSE GBA GAME</button>
<input id="file-input" type="file" accept=".gba" class="hidden" onchange="loadGame(this.files[0])">
</div>
[attachment_0](attachment)
<div id="touch-controller">
<div class="joystick-zone">
<div id="joystick-base">
<div id="joystick-handle"></div>
</div>
</div>
<div class="action-zone">
<div class="ab-buttons">
<div class="btn-circle btn-b" data-key="5">B</div>
<div class="btn-circle btn-a" data-key="4">A</div>
</div>
<div class="meta-row">
<div class="btn-pill" data-key="10">SELECT</div>
<div class="btn-pill" data-key="11">START</div>
</div>
</div>
</div>
<script>
var gba;
try {
gba = new GameBoyAdvance();
gba.keypad.eatInput = true;
gba.setCanvas(document.getElementById('screen'));
} catch (e) { console.error(e); }
function loadGame(file) {
var reader = new FileReader();
reader.onload = (e) => {
gba.loadRomFromFile(e.target.result, (res) => {
if(res) { gba.runMain(); document.getElementById('load-btn').classList.add('hidden'); }
});
};
reader.readAsArrayBuffer(file);
}
// --- JOYSTICK LOGIC ---
const base = document.getElementById('joystick-base');
const handle = document.getElementById('joystick-handle');
const baseRect = base.getBoundingClientRect();
const centerX = baseRect.width / 2;
const centerY = baseRect.height / 2;
const maxLimit = 50; // Radius
let activeKeys = { 0:false, 1:false, 2:false, 3:false }; // Up, Down, Left, Right
base.addEventListener('touchstart', handleJoystick, {passive: false});
base.addEventListener('touchmove', handleJoystick, {passive: false});
base.addEventListener('touchend', () => {
handle.style.left = '50%';
handle.style.top = '50%';
resetDirections();
}, {passive: false});
function handleJoystick(e) {
e.preventDefault();
const touch = e.touches[0];
const rect = base.getBoundingClientRect();
let x = touch.clientX - rect.left - centerX;
let y = touch.clientY - rect.top - centerY;
const distance = Math.sqrt(x*x + y*y);
if (distance > maxLimit) {
x = x * (maxLimit / distance);
y = y * (maxLimit / distance);
}
handle.style.left = (centerX + x) + 'px';
handle.style.top = (centerY + y) + 'px';
// Map to GBA Directions
const threshold = 15;
updateKey(2, x < -threshold); // Left
updateKey(3, x > threshold); // Right
updateKey(0, y < -threshold); // Up
updateKey(1, y > threshold); // Down
}
function updateKey(keyId, isPressed) {
if (isPressed && !activeKeys[keyId]) {
gba.keypad.keydown(keyId);
activeKeys[keyId] = true;
} else if (!isPressed && activeKeys[keyId]) {
gba.keypad.keyup(keyId);
activeKeys[keyId] = false;
}
}
function resetDirections() {
for(let i=0; i<4; i++) updateKey(i, false);
}
// --- BUTTON LOGIC ---
document.querySelectorAll('[data-key]').forEach(btn => {
const k = parseInt(btn.getAttribute('data-key'));
btn.addEventListener('touchstart', (e) => { e.preventDefault(); gba.keypad.keydown(k); if(navigator.vibrate) navigator.vibrate(15); });
btn.addEventListener('touchend', (e) => { e.preventDefault(); gba.keypad.keyup(k); });
});
</script>
</body>
</html>