lucky / 1text.html
Studytime171's picture
Duplicate from Studytime171/Lalitgangwani
89610f7
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<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>
<script src="resources/xhr.js"></script>
<style>
body, html {
background: #1a1a1a; color: #fff; margin: 0; padding: 0;
width: 100%; height: 100%; overflow: hidden; font-family: sans-serif;
display: flex; flex-direction: column;
}
#screen-container {
flex: 1; display: flex; align-items: center; justify-content: center;
background: #000; position: relative;
}
canvas#screen {
max-width: 100%; max-height: 100%;
image-rendering: pixelated;
border: 2px solid #333;
}
/* Controller Overlay */
#touch-controls {
height: 45vh;
background: radial-gradient(circle, #2c2c2c 0%, #1a1a1a 100%);
display: grid;
grid-template-columns: 1fr 1fr;
position: relative;
border-top: 4px solid #444;
}
/* Joystick Area */
.joystick-zone { display: flex; align-items: center; justify-content: center; position: relative; }
#joystick-base {
width: 150px; height: 150px;
background: rgba(255, 255, 255, 0.05);
border: 3px solid rgba(255, 255, 255, 0.2);
border-radius: 50%; position: relative;
touch-action: none;
}
#joystick-handle {
width: 70px; height: 70px;
background: linear-gradient(145deg, #555, #222);
border: 2px solid #666; border-radius: 50%;
position: absolute; top: 50%; left: 50%;
transform: translate(-50%, -50%);
box-shadow: 0 8px 15px rgba(0,0,0,0.6);
pointer-events: none;
}
/* Action Cluster */
.action-zone { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 20px; }
.button-group { display: grid; grid-template-columns: repeat(2, 1fr); gap: 15px; transform: rotate(-10deg); }
.btn-circle {
width: 70px; height: 70px; border-radius: 50%;
display: flex; align-items: center; justify-content: center;
font-weight: bold; font-size: 20px; color: #fff;
border: 4px solid rgba(0,0,0,0.3);
box-shadow: 0 5px 0 #000;
}
.btn-a { background: #e91e63; } /* Pink/Red A */
.btn-b { background: #ffc107; color: #000; } /* Yellow B */
.btn-circle:active { transform: translateY(4px) rotate(-10deg); box-shadow: 0 1px 0 #000; }
.meta-btns { display: flex; gap: 20px; margin-top: 10px; }
.pill { background: #333; padding: 10px 20px; border-radius: 20px; font-size: 11px; font-weight: bold; border: 1px solid #555; }
#loader-overlay { position: absolute; z-index: 5; }
.hidden { display: none !important; }
</style>
</head>
<body>
<div id="screen-container">
<canvas id="screen" width="480" height="320"></canvas>
<div id="loader-overlay">
<button class="pill" style="padding: 20px; font-size: 16px; color: #00eaff; border-color: #00eaff;" onclick="document.getElementById('loader').click()">SELECT ROM</button>
<input id="loader" type="file" accept=".gba" class="hidden" onchange="run(this.files[0]);">
</div>
</div>
<div id="touch-controls">
<div class="joystick-zone">
<div id="joystick-base">
<div id="joystick-handle"></div>
</div>
</div>
<div class="action-zone">
<div class="button-group">
<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-btns">
<div class="pill" data-key="10">SELECT</div>
<div class="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'));
loadRom('resources/bios.bin', function(bios) { gba.setBios(bios); });
} catch (e) { gba = null; }
function run(file) {
gba.loadRomFromFile(file, function(result) {
if (result) {
document.getElementById('loader-overlay').classList.add('hidden');
gba.runStable();
}
});
}
// --- JOYSTICK IMPLEMENTATION ---
const base = document.getElementById('joystick-base');
const handle = document.getElementById('joystick-handle');
const centerX = 75; // Half of base width
const centerY = 75;
const limit = 55; // Maximum handle movement radius
let activeDirections = { 0: false, 1: false, 2: false, 3: false }; // Up, Down, Left, Right
base.addEventListener('touchstart', moveJoystick, {passive: false});
base.addEventListener('touchmove', moveJoystick, {passive: false});
base.addEventListener('touchend', endJoystick, {passive: false});
function moveJoystick(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 > limit) {
x = x * (limit / distance);
y = y * (limit / distance);
}
handle.style.left = (centerX + x) + 'px';
handle.style.top = (centerY + y) + 'px';
// Map to GBA Directions (0:Up, 1:Down, 2:Left, 3:Right)
const deadzone = 15;
updateKey(2, x < -deadzone); // Left
updateKey(3, x > deadzone); // Right
updateKey(0, y < -deadzone); // Up
updateKey(1, y > deadzone); // Down
}
function endJoystick(e) {
handle.style.left = '50%';
handle.style.top = '50%';
for (let key in activeDirections) updateKey(key, false);
}
function updateKey(key, isPressed) {
if (isPressed && !activeDirections[key]) {
gba.keypad.keydown(key);
activeDirections[key] = true;
} else if (!isPressed && activeDirections[key]) {
gba.keypad.keyup(key);
activeDirections[key] = false;
}
}
// --- ACTION BUTTONS ---
document.querySelectorAll('[data-key]').forEach(btn => {
const key = parseInt(btn.getAttribute('data-key'));
btn.addEventListener('touchstart', (e) => {
e.preventDefault();
gba.keypad.keydown(key);
if(navigator.vibrate) navigator.vibrate(15);
});
btn.addEventListener('touchend', (e) => {
e.preventDefault();
gba.keypad.keyup(key);
});
});
</script>
</body>
</html>