Skip to content

Commit

Permalink
Update the Inform 7 template to use AsyncDialog and Emglken
Browse files Browse the repository at this point in the history
  • Loading branch information
curiousdannii committed Oct 13, 2024
1 parent 3e09f87 commit 5e1a6ba
Show file tree
Hide file tree
Showing 19 changed files with 203 additions and 185 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ node_modules
package-lock.json
tests/ifsitegen.py
tests/Release
tools/make-single-file.js
tools/*.js

/*.js
/*.ulx
Expand Down
49 changes: 27 additions & 22 deletions build.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,36 @@ async function readdir(path) {
return (await fs.readdir(path)).map(file => `${path}/${file}`)
}

// To avoid breaking .min.js files, we'll copy jQuery by itself
function jquery_copier(outdir) {
return {
entryPoints: {
'jquery.min': 'node_modules/jquery/dist/jquery.min.js',
},
loader: {
'.min.js': 'copy',
},
outdir,
}
}

const projects_to_build = []

if (projects.includes('ifcomp')) {
projects_to_build.push({
entryPoints: {
bocfel: 'node_modules/emglken/build/bocfel.*',
glulxe: 'node_modules/emglken/build/glulxe.*',
ie: 'src/common/ie.js',
'jquery.min': 'node_modules/jquery/dist/jquery.min.js',
quixe: 'src/common/quixe.js',
tads: 'node_modules/emglken/build/tads.*',
waiting: 'src/upstream/glkote/waiting.gif',
waiting: 'src/common/waiting.gif',
web: 'src/common/launcher.ts',
zvm: 'src/common/zvm.js',
},
outdir: 'dist/ifcomp/interpreter',
sourcemap: true,
}, {
},
jquery_copier('dist/ifcomp/interpreter'),
{
entryPoints: ['src/fonts/iosevka/*.woff2'],
outdir: 'dist/fonts/iosevka',
})
Expand All @@ -54,17 +68,15 @@ if (projects.includes('inform7')) {
projects_to_build.push({
entryPoints: {
ie: 'src/common/ie.js',
'jquery.min': 'node_modules/jquery/dist/jquery.min.js',
main: 'src/inform7/index.js',
parchment: 'src/inform7/inform7.css',
quixe: 'src/inform7/quixe.js',
waiting: 'src/upstream/glkote/waiting.gif',
zvm: 'src/inform7/zvm.js',
parchment: 'src/inform7/index.ts',
waiting: 'src/common/waiting.gif',
},
format: 'iife',
logOverride: {'empty-import-meta': 'silent'},
outdir: 'dist/inform7/Parchment',
}, {
},
jquery_copier('dist/inform7/Parchment'),
{
entryPoints: ['src/upstream/quixe/media/resourcemap.js'],
loader: {'.js': 'copy'},
outdir: 'dist/inform7/Parchment',
Expand All @@ -88,6 +100,7 @@ if (projects.includes('lectrote')) {
if (projects.includes('tools')) {
projects_to_build.push({
entryPoints: {
'inform7-wasm': 'src/tools/inform7-wasm-cli.ts',
'make-single-file': 'src/tools/single-file-cli.ts',
},
minify: false,
Expand All @@ -114,23 +127,15 @@ if (projects.includes('web')) {
//quixe: 'src/common/quixe.js',
scare: 'node_modules/emglken/build/scare.*',
tads: 'node_modules/emglken/build/tads.*',
waiting: 'src/upstream/glkote/waiting.gif',
waiting: 'src/common/waiting.gif',
web: 'src/common/launcher.ts',
//zvm: 'src/common/zvm.js',
},
outdir: 'dist/web',
sourcemap: true,
},
// To avoid breaking .min.js files, we'll copy jQuery by itself
jquery_copier('dist/web'),
{
entryPoints: {
'jquery.min': 'node_modules/jquery/dist/jquery.min.js',
},
loader: {
'.min.js': 'copy',
},
outdir: 'dist/web',
}, {
entryPoints: ['src/fonts/iosevka/*.woff2'],
outdir: 'dist/fonts/iosevka',
})
Expand Down
18 changes: 17 additions & 1 deletion src/common/file.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ https://github.com/curiousdannii/parchment
*/

import {parse_base64, type ProgressCallback, read_response} from '../upstream/asyncglk/src/index-browser.js'
import {parse_base64, type ProgressCallback, read_response} from '../upstream/asyncglk/src/index-common.js'
import type {ParchmentOptions} from './interface.js'

/** Fetch a VM resource */
Expand Down Expand Up @@ -41,4 +41,20 @@ export async function fetch_vm_resource(options: ParchmentOptions, path: string,
}
const response = await fetch(url)
return read_response(response, progress_callback)
}

export async function Uint8Array_to_base64(data: Uint8Array): Promise<string> {
if (typeof Buffer !== 'undefined') {
return Buffer.from(data.buffer).toString('base64')
}
// From https://stackoverflow.com/a/66046176/2854284
else if (typeof FileReader !== 'undefined') {
const data_url: string = await new Promise(resolve => {
const reader = new FileReader()
reader.onload = () => resolve(reader.result as string)
reader.readAsDataURL(new Blob([data]))
})
return data_url.split(',', 2)[1]
}
throw new Error('Cannot encode base64')
}
9 changes: 0 additions & 9 deletions src/common/quixe.js

This file was deleted.

Binary file added src/common/waiting.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 0 additions & 6 deletions src/common/zvm.js

This file was deleted.

104 changes: 0 additions & 104 deletions src/inform7/index.js

This file was deleted.

108 changes: 108 additions & 0 deletions src/inform7/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
Parchment Launcher for Inform 7
===============================
Copyright (c) 2024 Dannii Willis
MIT licenced
https://github.com/curiousdannii/parchment
*/

import {gunzipSync} from 'fflate'

import {Blorb, FileView, parse_base64} from '../upstream/asyncglk/src/index-browser.ts'
import {default as Bocfel} from '../upstream/emglken/build/bocfel.js'
import {default as Glulxe} from '../upstream/emglken/build/glulxe.js'
import type {ParchmentOptions} from '../common/interface.js'
import {get_default_options, get_query_options} from '../common/options.js'

import './inform7.css'

interface Inform7ParchmentOptions extends ParchmentOptions {
arguments?: string[],
story_name: string,
}

interface ParchmentWindow extends Window {
parchment_options?: Inform7ParchmentOptions
}
declare let window: ParchmentWindow

async function launch() {
const options: Inform7ParchmentOptions = Object.assign({}, get_default_options(), window.parchment_options, get_query_options(['do_vm_autosave']))

if (!options.default_story) {
return options.GlkOte.error('No storyfile specified')
}

// Update the Dialog storage version
await options.Dialog.init(this.options)

// Discriminate
const storyfilepath = options.default_story[0]
let format
if (/\.(zblorb|zlb|z3|z4|z5|z8)(\.js)?$/.test(storyfilepath)) {
format = 'zcode'
}
else if (/\.(gblorb|glb|ulx)(\.js)?$/.test(storyfilepath)) {
format = 'glulx'
}
else {
return options.GlkOte.error('Unknown storyfile format')
}

// When running from a file: URL we must use <script> tags and nothing else
$.ajaxSetup({
cache: true,
crossDomain: true,
})

const engine = format === 'zcode' ? Bocfel : Glulxe
const wasm_base_filename = format === 'zcode' ? 'bocfel.js' : 'glulxe.js'
let wasm_base64: string
try {
wasm_base64 = await $.ajax({
dataType: 'jsonp',
jsonp: false,
jsonpCallback: 'processBase64Zcode',
url: options.lib_path + wasm_base_filename,
})
}
catch (err) {
return options.GlkOte.error(`Error loading engine: ${err.status}`)
}

let base64data
try {
base64data = await $.ajax({
dataType: 'jsonp',
jsonp: false,
jsonpCallback: 'processBase64Zcode',
url: storyfilepath,
})
}
catch (err) {
return options.GlkOte.error(`Error loading storyfile: ${err.status}`)
}

try {
const data = await parse_base64(base64data)
const view = new FileView(data)
if (view.getFourCC(0) === 'FORM' && view.getFourCC(8) === 'IFRS') {
options.Blorb = new Blorb(data)
}
const storyfile_name = options.story_name.substring(0, options.story_name.length - 3)
options.arguments = [await options.Dialog.upload(new File([data], storyfile_name))]

const wasmBinary_gz = await parse_base64(wasm_base64)
const wasmBinary = gunzipSync(wasmBinary_gz)
const vm = await engine({wasmBinary})
vm.start(options)
}
catch (err) {
options.GlkOte.error(err)
}
}

$(launch)
1 change: 0 additions & 1 deletion src/inform7/inform7.css
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,4 @@
Note this means no gameport wrapper styles, and no fonts */

@import url('../upstream/asyncglk/src/glkote/web/glkote.css');
@import url('../upstream/glkote/dialog.css');
@import url('../upstream/asyncglk/src/glkote/web/light.css');
Loading

0 comments on commit 5e1a6ba

Please sign in to comment.