brew install wine
rm -rf ~/.wine WINEARCH=win32 WINEPREFIX=~/.wine wine wineboot
brew cask install Caskroom/cask/xquartz
npm init --yes
--yes
argument just runs through all of the prompts that you would otherwise have to fill out or skip. Now that we have a package.json
for our app, let’s install the necessary libraries with the following shell commands:npm install [email protected] --save npm install [email protected] --save npm install [email protected] --save
wine
followed by the filename of the VBA executable.pokemon.lua
in the directory where you want your code to live, and add the following Lua code:function read_file(filename) local f = io.open(filename, 'r') if f ~= nil then io.input(f) local content = io.read() io.close(f) return content end end function press(button) local input_table = {} input_table[button] = true joypad.set(1, input_table) end emu.message('Hello World!') while true do local button = read_file('button.txt') if button ~= nil then press(button) emu.message('Pressing: ' .. button) os.remove('button.txt') end emu.frameadvance() end
button.txt
on every frame of the game. The while true do
infinite loop will execute before each frame, allowing our JavaScript code to pipe button presses directly into the game’s input by writing to button.txt
whenever a text message is received.index.js
in the same directory as your package.json
and add the following code to it:const fs = require('fs'); const express = require('express'); const bodyParser = require('body-parser'); const MessagingResponse = require('twilio').twiml.MessagingResponse; const app = express(); const buttons = ['a', 'b', 'up', 'down', 'left', 'right', 'start', 'select']; app.use(bodyParser.urlencoded({ extended: false })); app.post('/sms', (req, res) => { const twiml = new MessagingResponse(); let button = req.body.Body.toLowerCase(); // Check to see if the user's input was a valid Gameboy button. if(buttons.includes(button)) { twiml.message('Thanks for playing Pokemon with me!'); // The Lua Joypad API expects A and B buttons to be uppercase. if(['a', 'b'].includes(button)) { button = button.toUpperCase(); } fs.writeFileSync('button.txt', button, 'utf8'); } else { twiml.message('Please text a valid Gameboy button.'); } res.writeHead(200, { 'Content-Type': 'text/xml' }); res.end(twiml.toString()); }); app.listen(3000, console.log('Express app listening on port 3000.'));
/sms
route, the body-parser
middleware is used to access data in the request body in order to grab the text of the message, which is going to be the button the user wants us to press in the game./sms
route is going to handle requests representing text messages to our Twilio number, which will be controlling the game. If the user sends a message corresponding to a button on the Gameboy, we'll write it to the button.txt
file for the Lua script to read and press in the game.node index.js
ngrok http 3000
./ngrok http 3000
from the directory that the ngrok executable is in.