mirror of
https://github.com/He4eT/cheap-glkote.git
synced 2026-11-01 14:58:31 +00:00
Move player.stdio
This commit is contained in:
parent
1a9bf1ad0d
commit
b9e4269aa4
4 changed files with 6 additions and 5 deletions
62
bin/player.stdio.js
Normal file
62
bin/player.stdio.js
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see: https://github.com/curiousdannii/emglken/blob/master/bin/emglken.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
const fs = require('fs')
|
||||||
|
const minimist = require('minimist')
|
||||||
|
|
||||||
|
const CheapGlkOte = require('../src/')
|
||||||
|
const { handlers } = require('./stdio')
|
||||||
|
|
||||||
|
const formats = [
|
||||||
|
{
|
||||||
|
id: 'bocfel',
|
||||||
|
extensions: /z([3458]|blorb)$/,
|
||||||
|
engine: 'bocfel.js',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'glulxe',
|
||||||
|
extensions: /(gblorb|ulx)$/,
|
||||||
|
engine: 'glulxe.js',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'git',
|
||||||
|
extensions: /(gblorb|ulx)$/,
|
||||||
|
engine: 'git.js',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'hugo',
|
||||||
|
extensions: /hex$/,
|
||||||
|
engine: 'hugo.js',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'tads',
|
||||||
|
extensions: /(gam|t3)$/,
|
||||||
|
engine: 'tads.js',
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
const argv = minimist(process.argv.slice(2))
|
||||||
|
const storyfile = argv._[0]
|
||||||
|
|
||||||
|
const format = formats.find(x =>
|
||||||
|
x.extensions.test(storyfile))
|
||||||
|
|
||||||
|
if (!format) {
|
||||||
|
console.error('Unknown storyfile format.')
|
||||||
|
process.exit(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const { glkInterface, sendFn } = CheapGlkOte(handlers)
|
||||||
|
handlers.setSend(sendFn)
|
||||||
|
|
||||||
|
const engine = require('emglken/src/' + format.engine)
|
||||||
|
const vm = new engine()
|
||||||
|
|
||||||
|
vm.prepare(
|
||||||
|
fs.readFileSync(storyfile),
|
||||||
|
glkInterface)
|
||||||
|
vm.start()
|
||||||
145
bin/stdio.js
Normal file
145
bin/stdio.js
Normal file
|
|
@ -0,0 +1,145 @@
|
||||||
|
/**
|
||||||
|
* @see: https://github.com/curiousdannii/glkote-term/blob/master/src/glkote-dumb.js
|
||||||
|
*/
|
||||||
|
|
||||||
|
const readline = require('readline')
|
||||||
|
const MuteStream = require('mute-stream')
|
||||||
|
const ansiEscapes = require('ansi-escapes')
|
||||||
|
|
||||||
|
const stdin = process.stdin
|
||||||
|
const stdout = new MuteStream()
|
||||||
|
stdout.pipe(process.stdout)
|
||||||
|
const rl = readline.createInterface({
|
||||||
|
input: stdin,
|
||||||
|
output: stdout,
|
||||||
|
prompt: ''
|
||||||
|
})
|
||||||
|
|
||||||
|
let send = _ => _
|
||||||
|
|
||||||
|
const setSend = fn => {
|
||||||
|
send = fn
|
||||||
|
}
|
||||||
|
|
||||||
|
const onInit = () => {
|
||||||
|
if (stdin.isTTY) {
|
||||||
|
stdin.setRawMode(true)
|
||||||
|
}
|
||||||
|
readline.emitKeypressEvents(stdin)
|
||||||
|
rl.resume()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onUpdateContent = messages =>
|
||||||
|
messages.text.forEach(({ append, content }) => {
|
||||||
|
if (!append) {
|
||||||
|
stdout.write('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (content) {
|
||||||
|
content.forEach(x => {
|
||||||
|
if (x.text === '>') return null
|
||||||
|
|
||||||
|
if (x.style === 'input') {
|
||||||
|
if (stdout.isTTY) {
|
||||||
|
stdout.write(ansiEscapes.eraseLines(2))
|
||||||
|
stdout.write('> ')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stdout.write(
|
||||||
|
typeof x === 'string'
|
||||||
|
? x
|
||||||
|
: x.text)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const onUpdateInputs = type => {
|
||||||
|
type
|
||||||
|
? attach_handlers(type)
|
||||||
|
: detach_handlers()
|
||||||
|
}
|
||||||
|
|
||||||
|
const onExit = () => {
|
||||||
|
detach_handlers()
|
||||||
|
rl.close()
|
||||||
|
stdout.write('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
const onDisable = disable =>
|
||||||
|
disable
|
||||||
|
? detach_handlers()
|
||||||
|
: attach_handlers()
|
||||||
|
|
||||||
|
const onFileNameRequest = (tosave, usage, gameid, callback) => {
|
||||||
|
stdout.write('\n')
|
||||||
|
rl.question(
|
||||||
|
'Please enter a file name: ',
|
||||||
|
filename => callback(filename
|
||||||
|
? { filename, usage }
|
||||||
|
: null))
|
||||||
|
}
|
||||||
|
|
||||||
|
const onFileRead = (dirent, israw) =>
|
||||||
|
void console.log('onFileRead:', dirent)
|
||||||
|
|
||||||
|
const onFileWrite = (dirent, content, israw) =>
|
||||||
|
void console.log('onFileWrite:', dirent, content.length)
|
||||||
|
|
||||||
|
const handle_char_input = (str, key) => {
|
||||||
|
const key_replacements = {
|
||||||
|
'\x7F': 'delete',
|
||||||
|
'\t': 'tab',
|
||||||
|
}
|
||||||
|
|
||||||
|
detach_handlers()
|
||||||
|
|
||||||
|
// Make sure this char isn't being remembered for the next line input
|
||||||
|
rl._line_buffer = null
|
||||||
|
rl.line = ''
|
||||||
|
|
||||||
|
// Process special keys
|
||||||
|
const res =
|
||||||
|
key_replacements[str] ||
|
||||||
|
str ||
|
||||||
|
key.name.replace(/f(\d+)/, 'func$1')
|
||||||
|
|
||||||
|
send(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
const attach_handlers = type => {
|
||||||
|
if (type === 'char') {
|
||||||
|
stdout.mute()
|
||||||
|
stdin.on('keypress', handle_char_input)
|
||||||
|
}
|
||||||
|
if (type === 'line') {
|
||||||
|
rl.on('line', handle_line_input)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const detach_handlers = () => {
|
||||||
|
stdin.removeListener('keypress', handle_char_input)
|
||||||
|
rl.removeListener('line', handle_line_input)
|
||||||
|
stdout.unmute()
|
||||||
|
}
|
||||||
|
|
||||||
|
const handle_line_input = line => {
|
||||||
|
if (stdout.isTTY) {
|
||||||
|
stdout.write(ansiEscapes.eraseLines(1))
|
||||||
|
}
|
||||||
|
detach_handlers()
|
||||||
|
|
||||||
|
send(line)
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports.handlers = {
|
||||||
|
onInit,
|
||||||
|
onUpdateContent,
|
||||||
|
onDisable,
|
||||||
|
onUpdateInputs,
|
||||||
|
onFileNameRequest,
|
||||||
|
onFileRead,
|
||||||
|
onFileWrite,
|
||||||
|
onExit,
|
||||||
|
setSend
|
||||||
|
}
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
"interactive-fiction"
|
"interactive-fiction"
|
||||||
],
|
],
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
|
"bin": "bin/player.stdio.js",
|
||||||
"repository": "https://github.com/He4eT/cheap-glkote",
|
"repository": "https://github.com/He4eT/cheap-glkote",
|
||||||
"bugs": "https://github.com/He4eT/cheap-glkote/issues",
|
"bugs": "https://github.com/He4eT/cheap-glkote/issues",
|
||||||
"dependencies": {},
|
"dependencies": {},
|
||||||
|
|
@ -21,7 +22,7 @@
|
||||||
"mute-stream": "0.0.8"
|
"mute-stream": "0.0.8"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"play": "node ./tests/player.stdio.js",
|
"play": "node ./bin/player.stdio.js",
|
||||||
"test": "./tests/runtests.sh"
|
"test": "./tests/runtests.sh"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,4 +2,4 @@
|
||||||
|
|
||||||
cd "$(dirname "$0")"
|
cd "$(dirname "$0")"
|
||||||
|
|
||||||
node player.stdio.js praxix.z5 < <(sleep 1 && echo 'all')
|
node ../bin/player.stdio.js praxix.z5 < <(sleep 1 && echo 'all')
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue