inital commit
This commit is contained in:
commit
06855542a1
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
rom.gb
|
||||
node_modules/
|
||||
pnpm-lock.yaml
|
58
app.js
Normal file
58
app.js
Normal file
|
@ -0,0 +1,58 @@
|
|||
const imageboy = require("imageboy");
|
||||
const fastify = require("fastify")();
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
let lastFrame = "";
|
||||
let emulator;
|
||||
const mainHTML = fs.readFileSync(path.join(__dirname, "html", "gb.html"), "utf8");
|
||||
const KEYMAP = {
|
||||
RIGHT: 0,
|
||||
LEFT: 1,
|
||||
UP: 2,
|
||||
DOWN: 3,
|
||||
A: 4,
|
||||
B: 5,
|
||||
SELECT: 6,
|
||||
START: 7
|
||||
};
|
||||
|
||||
async function run() {
|
||||
if (!fs.existsSync(path.join(__dirname, "rom.gb"))) {
|
||||
console.log("rom.gb missing.")
|
||||
return;
|
||||
}
|
||||
emulator = imageboy.run({
|
||||
path: "./rom.gb",
|
||||
interval: 16.6666667,
|
||||
onFrame: function(frame) {
|
||||
if (lastFrame !== frame) {
|
||||
lastFrame = frame;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fastify.get("/", async(request, reply) => {
|
||||
reply.type("text/html");
|
||||
reply.send(mainHTML);
|
||||
});
|
||||
|
||||
fastify.get("/image", async(request, reply) => {
|
||||
reply.type("image/png").send(lastFrame);
|
||||
});
|
||||
|
||||
fastify.get("/control", async(request, reply) => {
|
||||
const button = request.query.button;
|
||||
if (button) {
|
||||
const mappedButton = KEYMAP[button.toUpperCase()];
|
||||
if (mappedButton) emulator.pressKeys(emulator.gameboy, [mappedButton]);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
await fastify.listen({ port: 3000 });
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
}
|
||||
}
|
||||
|
||||
run();
|
112
html/gb.html
Normal file
112
html/gb.html
Normal file
|
@ -0,0 +1,112 @@
|
|||
<style>
|
||||
.button {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
<body>
|
||||
<ul id='messages'></ul>
|
||||
</body>
|
||||
|
||||
<body style="background-color: #121212">
|
||||
<div>
|
||||
<img id="image" src="http://localhost:3000/image" width="700" style="display: block; margin: auto;" />
|
||||
<br>
|
||||
<div style="position: absolute; left: 50%; transform: translate(-50%, 0);">
|
||||
<a id="UP" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/up.png" width="35" />
|
||||
</a>
|
||||
<br>
|
||||
<a id="LEFT" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/left.png" width="35" />
|
||||
</a>
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<a id="RIGHT" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/right.png" width="35" />
|
||||
</a>
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<a id="B" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/B.png" width="35" />
|
||||
</a>
|
||||
<a id="A" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/A.png" width="35" />
|
||||
</a>
|
||||
<br>
|
||||
<a id="DOWN" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/down.png" width="35" />
|
||||
</a>
|
||||
<br>
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/blank.png" width="35" />
|
||||
<a id="SELECT" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/select.png" height="35" />
|
||||
</a>
|
||||
<a id="START" class="button">
|
||||
<img src="https://raw.githubusercontent.com/Giingu/Giingu/main/images/start.png" height="35" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/js-base64@3.7.2/base64.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
function updateImage() {
|
||||
toDataURL('http://localhost:3000/image', function(dataUrl) {
|
||||
$('#image').attr('src', dataUrl);
|
||||
updateImage();
|
||||
});
|
||||
}
|
||||
|
||||
function toDataURL(url, callback) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.onload = function() {
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function() {
|
||||
callback(reader.result);
|
||||
}
|
||||
reader.readAsDataURL(xhr.response);
|
||||
};
|
||||
xhr.open('GET', url);
|
||||
xhr.responseType = 'blob';
|
||||
xhr.send();
|
||||
}
|
||||
|
||||
updateImage();
|
||||
|
||||
const controls = ["UP", "DOWN", "LEFT", "RIGHT", "A", "B", "SELECT", "START"];
|
||||
const keyboard_key = {
|
||||
"UP": "ArrowUp",
|
||||
"DOWN": "ArrowDown",
|
||||
"LEFT": "ArrowLeft",
|
||||
"RIGHT": "ArrowRight",
|
||||
"A": "Enter",
|
||||
"B": "Return",
|
||||
"SELECT": "KeyS",
|
||||
"START": "KeyP"
|
||||
};
|
||||
|
||||
$("body").keypress(function(key) {
|
||||
console.log("key pressed: " + key);
|
||||
});
|
||||
|
||||
for (const key in controls) {
|
||||
const control = controls[key];
|
||||
$("#" + control).click(() => {
|
||||
console.log("click " + control);
|
||||
var settings = {
|
||||
"url": "http://localhost:3000/control?button=" + control,
|
||||
"method": "GET",
|
||||
"timeout": 0,
|
||||
};
|
||||
|
||||
$.ajax(settings).done(function(response) {});
|
||||
})
|
||||
}
|
||||
});
|
||||
</script>
|
24
package.json
Normal file
24
package.json
Normal file
|
@ -0,0 +1,24 @@
|
|||
{
|
||||
"name": "gbonline",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"start": "node app.js"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@tensorflow/tfjs": ">=3.19.0 <4.0.0\n",
|
||||
"@tensorflow/tfjs-node": "^3.19.0",
|
||||
"fastify": "^4.4.0",
|
||||
"fastify-socket.io": "^4.0.0",
|
||||
"imageboy": "^1.1.1",
|
||||
"seedrandom": "^3.0.5",
|
||||
"serverboy": "^0.0.7",
|
||||
"socket.io": "^4.5.1",
|
||||
"upscaler": "1.0.0-beta.6",
|
||||
"waifu2x": "^1.0.9"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user