Skip to content

Commit

Permalink
playdate control polling, examples for screen and controls
Browse files Browse the repository at this point in the history
  • Loading branch information
jaames committed Aug 28, 2021
1 parent 0fe04fa commit 52c626b
Show file tree
Hide file tree
Showing 21 changed files with 2,103 additions and 2,445 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
# Debug stuff
playdate_usb_captures

# lockfiles not needed for library
yarn.lock
package-lock.json

# Logs
logs
*.log
Expand Down
80 changes: 80 additions & 0 deletions examples/assets/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
:root {
--color-black: #282732;
--color-yellow: #ffb738;
}

html, body {
margin: 0;
font-size: 14px;
line-height: 1.75;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
background: #dcdef0;
box-sizing: border-box;
}

* > * {
box-sizing: inherit;
}

button {
background: var(--color-black);
color: var(--color-yellow);
border: 0;
border-radius: 4px;
padding: 7px 11px;
font-size: 14px;
cursor: pointer;
}

button:disabled {
background: lightgrey;
color: lightslategray;
pointer-events: none;
cursor: not-allowed;
}

.wrapper {
margin: 0 auto;
width: 100%;
max-width: 960px;
padding: 4rem 0;
}

.panel {
background: #fff;
padding: 21px;
border-radius: 12px;
margin-bottom: 15px;
}

.row {
display: flex;
width: 100%;
}

.row-even > * {
flex: 1;
}

.pull-left {
margin-right: auto;
}

.pull-right {
margin-left: auto;
}

.example-list {
list-style: square;
font-size: 16px;
}

a {
color: slateblue;
text-decoration: none;
border-bottom: 0.1em solid currentColor;
}

#serial {
padding: 0 .5em;
}
6 changes: 0 additions & 6 deletions examples/example-basic.js

This file was deleted.

132 changes: 132 additions & 0 deletions examples/example-controller.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Playdate USB demo - reading controls</title>
<link rel="stylesheet" href="./assets/styles.css">
<script src="./playdate-usb.js"></script>
</head>
<body>
<div class="wrapper">
<header>
<h1>Playdate USB demo - reading controls</h1>
</header>
<main>
<div class="panel">
<div class="row">
<div class="pull-left">
<button onclick="connect()" id="connectButton"> connect to playdate </button>
<span id="serial"></span>
</div>
<div class="pull-right">
<button onclick="start()" id="startButton" disabled> begin polling controls </button>
<button onclick="stop()" id="stopButton" disabled> stop polling controls </button>
</div>
</div>
</div>
<div class="panel">
<div class="row row-even">
<div>
<div>A: <span id="inputA"></span></div>
<div>B: <span id="inputB"></span></div>
<div>Menu: <span id="inputMenu"></span></div>
<div>Lock: <span id="inputLock"></span></div>
</div>
<div>
<div>Up: <span id="inputUp"></span></div>
<div>Down: <span id="inputDown"></span></div>
<div>Left: <span id="inputLeft"></span></div>
<div>Right: <span id="inputRight"></span></div>
</div>
<div>
<div>Crank: <span id="inputCrank"></span></div>
<div>Docked: <span id="inputDocked"></span></div>
</div>
</div>
</div>
</main>
<footer class="row">
<div class="pull-left">
<a href="//github.com/jaames/playdate-usb">playdate-usb</a> | <a href="//github.com/jaames/playdate-usb/blob/main/examples/example-controller.html">page source</a>
</div>
<div class="pull-right">
built by <a href="//github.com/jaames">james daniel</a>
</div>
</footer>
</div>

<script>
var device;

const inputA = document.getElementById('inputA');
const inputB = document.getElementById('inputB');
const inputMenu = document.getElementById('inputMenu');
const inputLock = document.getElementById('inputLock');
const inputUp = document.getElementById('inputUp');
const inputDown = document.getElementById('inputDown');
const inputLeft = document.getElementById('inputLeft');
const inputRight = document.getElementById('inputRight');
const inputCrank = document.getElementById('inputCrank');
const inputDocked = document.getElementById('inputDocked');

// Check WebUSB support, display error if not supported
try {
playdateUsb.assertUsbSupported();
}
catch (e) {
document.getElementById('serial').innerHTML = e.message;
document.getElementById('connectButton').disabled = true;
}

async function connect() {
device = await playdateUsb.requestConnectPlaydate();
try {
await device.open();

device.on('controls:update', handleControlUpdate);
const serial = await device.getSerial();

document.getElementById('serial').innerHTML = `Connected to Playdate ${ serial }`;
document.getElementById('startButton').disabled = false;

device.on('disconnect', () => {
document.getElementById('serial').innerHTML = `Playdate disconnected`;
document.getElementById('startButton').disabled = true;
document.getElementById('stopButton').disabled = true;
});
}
catch {
document.getElementById('serial').innerHTML = 'Error connecting to Playdate, try again'
}
}

async function start() {
document.getElementById('startButton').disabled = true;
document.getElementById('stopButton').disabled = false;
device.startPollingControls();
}

async function stop() {
await device.stopPollingControls();
document.getElementById('startButton').disabled = false;
document.getElementById('stopButton').disabled = true;
}

function handleControlUpdate(state) {
inputCrank.innerHTML = state.crank;
inputDocked.innerHTML = state.crankDocked;

inputA.innerHTML = state.button.a ? 'pressed' : '';
inputB.innerHTML = state.button.b ? 'pressed' : '';
inputMenu.innerHTML = state.button.menu ? 'pressed' : '';
inputLock.innerHTML = state.button.lock ? 'pressed' : '';
inputUp.innerHTML = state.button.up ? 'pressed' : '';
inputDown.innerHTML = state.button.down ? 'pressed' : '';
inputLeft.innerHTML = state.button.left ? 'pressed' : '';
inputRight.innerHTML = state.button.right ? 'pressed' : '';
}
</script>
</body>
</html>
102 changes: 102 additions & 0 deletions examples/example-screen.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Playdate USB demo - reading controls</title>
<link rel="stylesheet" href="./assets/styles.css">
<script src="./playdate-usb.js"></script>
</head>
<body>
<div class="wrapper">
<header>
<h1>Playdate USB demo - get screenshot</h1>
</header>
<main>
<div class="panel">
<div class="row">
<div class="pull-left">
<button onclick="connect()" id="connectButton"> connect to playdate </button>
<span id="serial"></span>
</div>
<div class="pull-right">
<button onclick="getScreen()" id="screenButton" disabled> get screen </button>
</div>
</div>
</div>
<div class="panel">
<canvas id="canvas"></canvas>
<p>(pssst, right-click to save the image!)</p>
</div>
</main>
<footer class="row">
<div class="pull-left">
<a href="//github.com/jaames/playdate-usb">playdate-usb</a> | <a href="//github.com/jaames/playdate-usb/blob/main/examples/example-screen.html">page source</a>
</div>
<div class="pull-right">
built by <a href="//github.com/jaames">james daniel</a>
</div>
</footer>
</div>

<script>
var device;

const canvas = document.getElementById('canvas');
const ctx = canvas.getContext('2d');
canvas.width = playdateUsb.PLAYDATE_WIDTH;
canvas.height = playdateUsb.PLAYDATE_HEIGHT;
const imgData = ctx.createImageData(canvas.width, canvas.height);
const rgbaBuffer = new Uint32Array(imgData.data.buffer);

// Check WebUSB support, display error if not supported
try {
playdateUsb.assertUsbSupported();
}
catch (e) {
document.getElementById('serial').innerHTML = e.message;
document.getElementById('connectButton').disabled = true;
}

async function connect() {
try {
device = await playdateUsb.requestConnectPlaydate();

if (device == null)
throw new Error('Could not find playdate')

await device.open();
const serial = await device.getSerial();

document.getElementById('serial').innerHTML = `Connected to Playdate ${ serial }`;
document.getElementById('screenButton').disabled = false;

device.on('disconnect', () => {
document.getElementById('serial').innerHTML = 'Playdate disconnected';
document.getElementById('screenButton').disabled = true;
});
}
catch(e) {
console.warn(e.message);
document.getElementById('serial').innerHTML = 'Error connecting to Playdate, try again';
}
}

async function getScreen() {
try {
const pixels = await device.getScreenIndexed();
const palette = [0xff000000, 0xffffffff];
for (let i = 0; i < pixels.length; i++) {
rgbaBuffer[i] = palette[pixels[i]];
}
ctx.putImageData(imgData, 0, 0);
}
catch (e) {
document.getElementById('serial').innerHTML = 'Error getting screen, lock and unlock the Playdate and reconnect';
document.getElementById('screenButton').disabled = true;
}
}
</script>
</body>
</html>
23 changes: 19 additions & 4 deletions examples/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,26 @@
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<title>Playdate USB demos</title>
<link rel="stylesheet" href="./assets/styles.css">
<script src="./playdate-usb.js"></script>
</head>
<body>
<button onclick="usbInit()">connect</button>
<script src="./playdate-usb.js"></script>
<script src="./example-basic.js"></script>
<div class="wrapper">
<header>
<h1>Playdate USB demos</h1>
</header>
<main>
<div class="panel">
<ul class="example-list">
<li>
<a href="./example-screen.html">get screenshot</a>
</li>
<li>
<a href="./example-controller.html">read control inputs</a>
</li>
</ul>
</div>
</main>
</body>
</html>

0 comments on commit 52c626b

Please sign in to comment.