on mobile devices require a touch to start the emulator loading

This commit is contained in:
Corwin 2024-04-09 02:31:17 +01:00
parent 362e0d864f
commit 9ad67ae494
No known key found for this signature in database
3 changed files with 33 additions and 25 deletions

View file

@ -43,13 +43,12 @@ const AppContainer = styled.main`
const StartButtonWrapper = styled.button`
margin: auto;
font-size: 3em;
font-size: 2em;
padding: 1em;
text-transform: uppercase;
background-color: black;
color: white;
border: none;
border-radius: 0.5em;
aspect-ratio: 240 / 160;
width: 100%;
height: 100%;
@ -62,7 +61,8 @@ const StartButtonWrapper = styled.button`
interface MgbaWrapperProps {
gameUrl: string;
startNotPlaying?: boolean;
isPlaying?: boolean;
setIsPlaying?: (isPlaying: boolean) => void;
}
export const MgbaStandalone: FC<MgbaWrapperProps> = (props) => (
@ -71,12 +71,8 @@ export const MgbaStandalone: FC<MgbaWrapperProps> = (props) => (
</AppContainer>
);
export interface MgbaWrapperHandle extends MgbaHandle {
hardReset: () => void;
}
export const MgbaWrapper = forwardRef<MgbaWrapperHandle, MgbaWrapperProps>(
({ gameUrl, startNotPlaying = false }, ref) => {
export const MgbaWrapper = forwardRef<MgbaHandle, MgbaWrapperProps>(
({ gameUrl, isPlaying = true, setIsPlaying }, ref) => {
const [{ volume, bindings }, setState] = useLocalStorage(
{ volume: 1.0, bindings: DefaultBindingsSet() },
"agbrswebplayer"
@ -108,8 +104,6 @@ export const MgbaWrapper = forwardRef<MgbaWrapperHandle, MgbaWrapperProps>(
useAvoidItchIoScrolling();
const [isPlaying, setIsPlaying] = useState(!startNotPlaying);
return (
<>
{showBindings && (
@ -133,7 +127,7 @@ export const MgbaWrapper = forwardRef<MgbaWrapperHandle, MgbaWrapperProps>(
paused={paused}
/>
) : (
<StartButton onClick={() => setIsPlaying(true)} />
<StartButton onClick={() => setIsPlaying && setIsPlaying(true)} />
)}
</>
);
@ -179,7 +173,7 @@ function BindingsWindow({
function StartButton({ onClick }: { onClick: () => void }) {
return (
<StartButtonWrapper onClick={onClick}>Press to start</StartButtonWrapper>
<StartButtonWrapper onClick={onClick}>Touch to start</StartButtonWrapper>
);
}

View file

@ -8,8 +8,8 @@ import DPad from "./gba-parts/dpad.png";
import ABButtons from "./gba-parts/ab.png";
import Select from "./gba-parts/SELECT.png";
import Start from "./gba-parts/START.png";
import { MgbaWrapperHandle } from "./mgba/mgbaWrapper";
import { GbaKey } from "./mgba/bindings";
import { MgbaHandle } from "./mgba/mgba";
const MobileControls = styled.div`
display: flex;
@ -48,7 +48,7 @@ const MobileControlsRow = styled.div<{
${(props) => props.$centered && `justify-content: center;`}
`;
const useSimpleButton = (mgba: MgbaWrapperHandle, button: GbaKey) => {
const useSimpleButton = (mgba: MgbaHandle, button: GbaKey) => {
return useMemo(() => {
return {
onTouchStart: () => {
@ -80,7 +80,7 @@ const relativeTouch = (touch: Touch) => {
return relativePosition;
};
const useDpadTouch = (mgba: MgbaWrapperHandle) => {
const useDpadTouch = (mgba: MgbaHandle) => {
const [previouslyPressedButtons, setTouchedButtons] = useState<Set<GbaKey>>(
new Set()
);
@ -139,7 +139,7 @@ const useDpadTouch = (mgba: MgbaWrapperHandle) => {
}, [mgba, previouslyPressedButtons]);
};
const useAbTouch = (mgba: MgbaWrapperHandle) => {
const useAbTouch = (mgba: MgbaHandle) => {
const [previouslyPressedButtons, setTouchedButtons] = useState<Set<GbaKey>>(
new Set()
);
@ -182,7 +182,7 @@ const useAbTouch = (mgba: MgbaWrapperHandle) => {
}, [mgba, previouslyPressedButtons]);
};
export const MobileController: FC<{ mgba: MgbaWrapperHandle }> = ({ mgba }) => {
export const MobileController: FC<{ mgba: MgbaHandle }> = ({ mgba }) => {
return (
<MobileControls onContextMenu={(evt) => evt.preventDefault()}>
<MobileControlsRow $size={MobileControlsSize.Small}>
@ -218,7 +218,7 @@ export const MobileController: FC<{ mgba: MgbaWrapperHandle }> = ({ mgba }) => {
/>
</MobileControlsRow>
<MobileControlsRow $size={MobileControlsSize.Small} $centered>
<button onClick={() => mgba.hardReset()}>Restart</button>
<button onClick={() => mgba.restart()}>Restart</button>
</MobileControlsRow>
</MobileControls>
);

View file

@ -2,15 +2,16 @@
import styled from "styled-components";
import { CenteredBlock, ContentBlock } from "./contentBlock";
import MgbaWrapper, { MgbaWrapperHandle } from "./mgba/mgbaWrapper";
import MgbaWrapper from "./mgba/mgbaWrapper";
import Image from "next/image";
import left from "./gba-parts/left.png";
import right from "./gba-parts/right.png";
import { MobileController } from "./mobileController";
import { useMemo, useRef } from "react";
import { useMemo, useRef, useState } from "react";
import { GbaKey } from "./mgba/bindings";
import { useClientValue } from "./useClientValue.hook";
import { MgbaHandle } from "./mgba/mgba";
const ExternalLink = styled.a`
text-decoration: none;
@ -36,7 +37,7 @@ const GameDisplay = styled.div`
const GamePanelWrapper = styled.div`
display: flex;
justify-content: center;
align-items: baseline;
align-items: end;
height: 100%;
`;
@ -60,12 +61,16 @@ const GameSide = styled.div`
const isTouchScreen = () => navigator.maxTouchPoints > 1;
function shouldStartPlaying(isTouchScreen: boolean | undefined) {
if (isTouchScreen === undefined) return false;
return !isTouchScreen;
}
const MgbaWithControllerSides = () => {
const mgba = useRef<MgbaWrapperHandle>(null);
const mgba = useRef<MgbaHandle>(null);
const mgbaHandle = useMemo(
() => ({
hardReset: () => mgba.current?.hardReset(),
restart: () => mgba.current?.restart(),
buttonPress: (key: GbaKey) => mgba.current?.buttonPress(key),
buttonRelease: (key: GbaKey) => mgba.current?.buttonRelease(key),
@ -73,8 +78,12 @@ const MgbaWithControllerSides = () => {
[]
);
const [isPlaying, setIsPlaying] = useState<boolean>();
const shouldUseTouchScreenInput = useClientValue(isTouchScreen);
const playEmulator =
isPlaying ?? shouldStartPlaying(shouldUseTouchScreenInput);
return (
<>
<GameDisplay>
@ -83,7 +92,12 @@ const MgbaWithControllerSides = () => {
<Image src={left} alt="" />
</GameSide>
<GameDisplayWindow>
<MgbaWrapper gameUrl="combo.gba.gz" ref={mgba} />
<MgbaWrapper
gameUrl="combo.gba.gz"
ref={mgba}
isPlaying={playEmulator}
setIsPlaying={setIsPlaying}
/>
</GameDisplayWindow>
<GameSide>
<Image src={right} alt="" />