mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2025-01-29 18:34:47 +00:00
Merge branch 'mc-1.17.x' into mc-1.18.x
This commit is contained in:
commit
2b901f2d5e
1
.gitattributes
vendored
1
.gitattributes
vendored
@ -13,3 +13,4 @@ src/testMod/server-files/structures linguist-generated
|
|||||||
|
|
||||||
*.png binary
|
*.png binary
|
||||||
*.jar binary
|
*.jar binary
|
||||||
|
*.dfpwm binary
|
||||||
|
25
build.gradle
25
build.gradle
@ -290,18 +290,7 @@ task rollup(type: Exec) {
|
|||||||
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
|
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
|
||||||
}
|
}
|
||||||
|
|
||||||
task minifyWeb(type: Exec, dependsOn: rollup) {
|
task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
|
||||||
group = "build"
|
|
||||||
description = "Bundles JS into rollup"
|
|
||||||
|
|
||||||
inputs.file("$buildDir/rollup/index.js").withPropertyName("sources")
|
|
||||||
inputs.file("package-lock.json").withPropertyName("package-lock.json")
|
|
||||||
outputs.file("$buildDir/rollup/index.min.js").withPropertyName("output")
|
|
||||||
|
|
||||||
commandLine mkCommand('"node_modules/.bin/terser"' + " -o '$buildDir/rollup/index.min.js' '$buildDir/rollup/index.js'")
|
|
||||||
}
|
|
||||||
|
|
||||||
task illuaminateDocs(type: Exec, dependsOn: [minifyWeb, luaJavadoc]) {
|
|
||||||
group = "build"
|
group = "build"
|
||||||
description = "Bundles JS into rollup"
|
description = "Bundles JS into rollup"
|
||||||
|
|
||||||
@ -309,7 +298,7 @@ task illuaminateDocs(type: Exec, dependsOn: [minifyWeb, luaJavadoc]) {
|
|||||||
inputs.files(fileTree("src/main/resources/data/computercraft/lua/rom")).withPropertyName("lua rom")
|
inputs.files(fileTree("src/main/resources/data/computercraft/lua/rom")).withPropertyName("lua rom")
|
||||||
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
|
inputs.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
|
||||||
inputs.dir("$buildDir/docs/luaJavadoc")
|
inputs.dir("$buildDir/docs/luaJavadoc")
|
||||||
inputs.file("$buildDir/rollup/index.min.js").withPropertyName("scripts")
|
inputs.file("$buildDir/rollup/index.js").withPropertyName("scripts")
|
||||||
inputs.file("src/web/styles.css").withPropertyName("styles")
|
inputs.file("src/web/styles.css").withPropertyName("styles")
|
||||||
outputs.dir("$buildDir/docs/lua")
|
outputs.dir("$buildDir/docs/lua")
|
||||||
|
|
||||||
@ -317,9 +306,13 @@ task illuaminateDocs(type: Exec, dependsOn: [minifyWeb, luaJavadoc]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
|
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
|
||||||
from 'doc'
|
from('doc') {
|
||||||
include 'logo.png'
|
include 'logo.png'
|
||||||
include 'images/**'
|
include 'images/**'
|
||||||
|
}
|
||||||
|
from("$buildDir/rollup") {
|
||||||
|
exclude 'index.js'
|
||||||
|
}
|
||||||
into "${project.docsDir}/lua"
|
into "${project.docsDir}/lua"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,5 +51,6 @@ exclude: |
|
|||||||
src/generated|
|
src/generated|
|
||||||
src/test/resources/test-rom/data/json-parsing/|
|
src/test/resources/test-rom/data/json-parsing/|
|
||||||
src/testMod/server-files/|
|
src/testMod/server-files/|
|
||||||
config/idea/
|
config/idea/|
|
||||||
|
.*\.dfpwm
|
||||||
)
|
)
|
||||||
|
@ -12,7 +12,7 @@ see: speaker.playAudio To play audio using the speaker
|
|||||||
This uses @{io.lines} to read audio data in blocks of 16KiB from "example_song.dfpwm", and then attempts to play it
|
This uses @{io.lines} to read audio data in blocks of 16KiB from "example_song.dfpwm", and then attempts to play it
|
||||||
using @{speaker.playAudio}. If the speaker's buffer is full, it waits for an event and tries again.
|
using @{speaker.playAudio}. If the speaker's buffer is full, it waits for an event and tries again.
|
||||||
|
|
||||||
```lua
|
```lua {data-peripheral=speaker}
|
||||||
local dfpwm = require("cc.audio.dfpwm")
|
local dfpwm = require("cc.audio.dfpwm")
|
||||||
local speaker = peripheral.find("speaker")
|
local speaker = peripheral.find("speaker")
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ adds the sample from one second ago to it.
|
|||||||
For this, we'll need to keep track of the last 48k samples - exactly one seconds worth of audio. We can do this using a
|
For this, we'll need to keep track of the last 48k samples - exactly one seconds worth of audio. We can do this using a
|
||||||
[Ring Buffer], which helps makes things a little more efficient.
|
[Ring Buffer], which helps makes things a little more efficient.
|
||||||
|
|
||||||
```lua
|
```lua {data-peripheral=speaker}
|
||||||
local dfpwm = require("cc.audio.dfpwm")
|
local dfpwm = require("cc.audio.dfpwm")
|
||||||
local speaker = peripheral.find("speaker")
|
local speaker = peripheral.find("speaker")
|
||||||
|
|
||||||
@ -157,14 +157,14 @@ for i = 1, samples_n do samples[i] = 0 end
|
|||||||
|
|
||||||
local decoder = dfpwm.make_decoder()
|
local decoder = dfpwm.make_decoder()
|
||||||
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
|
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
|
||||||
local buffer = decoder(input)
|
local buffer = decoder(chunk)
|
||||||
|
|
||||||
for i = 1, #buffer do
|
for i = 1, #buffer do
|
||||||
local original_value = buffer[i]
|
local original_value = buffer[i]
|
||||||
|
|
||||||
-- Replace this sample with its current amplitude plus the amplitude from one second ago.
|
-- Replace this sample with its current amplitude plus the amplitude from one second ago.
|
||||||
-- We scale both to ensure the resulting value is still between -128 and 127.
|
-- We scale both to ensure the resulting value is still between -128 and 127.
|
||||||
buffer[i] = original_value * 0.7 + samples[samples_i] * 0.3
|
buffer[i] = original_value * 0.6 + samples[samples_i] * 0.4
|
||||||
|
|
||||||
-- Now store the current sample, and move the "head" of our ring buffer forward one place.
|
-- Now store the current sample, and move the "head" of our ring buffer forward one place.
|
||||||
samples[samples_i] = original_value
|
samples[samples_i] = original_value
|
||||||
|
86
package-lock.json
generated
86
package-lock.json
generated
@ -14,6 +14,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-typescript": "^8.2.5",
|
"@rollup/plugin-typescript": "^8.2.5",
|
||||||
|
"@rollup/plugin-url": "^6.1.0",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"rollup": "^2.33.1",
|
"rollup": "^2.33.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
@ -73,6 +74,23 @@
|
|||||||
"typescript": ">=3.7.0"
|
"typescript": ">=3.7.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@rollup/plugin-url": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-FJNWBnBB7nLzbcaGmu1no+U/LlRR67TtgfRFP+VEKSrWlDTE6n9jMns/N4Q/VL6l4x6kTHQX4HQfwTcldaAfHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"make-dir": "^3.1.0",
|
||||||
|
"mime": "^2.4.6"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=10.0.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"rollup": "^1.20.0||^2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/pluginutils": {
|
"node_modules/@rollup/pluginutils": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
||||||
@ -264,12 +282,39 @@
|
|||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/make-dir": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||||
|
"dev": true,
|
||||||
|
"dependencies": {
|
||||||
|
"semver": "^6.0.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/merge-stream": {
|
"node_modules/merge-stream": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"node_modules/mime": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"mime": "cli.js"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/path-parse": {
|
"node_modules/path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
@ -382,6 +427,15 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/semver": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"semver": "bin/semver.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/serialize-javascript": {
|
"node_modules/serialize-javascript": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||||
@ -512,6 +566,17 @@
|
|||||||
"resolve": "^1.17.0"
|
"resolve": "^1.17.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@rollup/plugin-url": {
|
||||||
|
"version": "6.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@rollup/plugin-url/-/plugin-url-6.1.0.tgz",
|
||||||
|
"integrity": "sha512-FJNWBnBB7nLzbcaGmu1no+U/LlRR67TtgfRFP+VEKSrWlDTE6n9jMns/N4Q/VL6l4x6kTHQX4HQfwTcldaAfHQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@rollup/pluginutils": "^3.1.0",
|
||||||
|
"make-dir": "^3.1.0",
|
||||||
|
"mime": "^2.4.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"@rollup/pluginutils": {
|
"@rollup/pluginutils": {
|
||||||
"version": "3.1.0",
|
"version": "3.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
||||||
@ -665,12 +730,27 @@
|
|||||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"make-dir": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"semver": "^6.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"merge-stream": {
|
"merge-stream": {
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"mime": {
|
||||||
|
"version": "2.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz",
|
||||||
|
"integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"path-parse": {
|
"path-parse": {
|
||||||
"version": "1.0.7",
|
"version": "1.0.7",
|
||||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||||
@ -740,6 +820,12 @@
|
|||||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "6.3.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
|
||||||
|
"integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"serialize-javascript": {
|
"serialize-javascript": {
|
||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-typescript": "^8.2.5",
|
"@rollup/plugin-typescript": "^8.2.5",
|
||||||
|
"@rollup/plugin-url": "^6.1.0",
|
||||||
"requirejs": "^2.3.6",
|
"requirejs": "^2.3.6",
|
||||||
"rollup": "^2.33.1",
|
"rollup": "^2.33.1",
|
||||||
"rollup-plugin-terser": "^7.0.2",
|
"rollup-plugin-terser": "^7.0.2",
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { readFileSync } from "fs";
|
import { readFileSync } from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|
||||||
import typescript from "@rollup/plugin-typescript";
|
import typescript from "@rollup/plugin-typescript";
|
||||||
|
import url from '@rollup/plugin-url';
|
||||||
import { terser } from "rollup-plugin-terser";
|
import { terser } from "rollup-plugin-terser";
|
||||||
|
|
||||||
const input = "src/web";
|
const input = "src/web";
|
||||||
@ -10,7 +11,7 @@ const requirejs = readFileSync("node_modules/requirejs/require.js");
|
|||||||
export default {
|
export default {
|
||||||
input: [`${input}/index.tsx`],
|
input: [`${input}/index.tsx`],
|
||||||
output: {
|
output: {
|
||||||
file: "build/rollup/index.js",
|
dir: "build/rollup/",
|
||||||
// We bundle requirejs (and config) into the header. It's rather gross
|
// We bundle requirejs (and config) into the header. It's rather gross
|
||||||
// but also works reasonably well.
|
// but also works reasonably well.
|
||||||
// Also suffix a ?v=${date} onto the end in the event we need to require a specific copy-cat version.
|
// Also suffix a ?v=${date} onto the end in the event we need to require a specific copy-cat version.
|
||||||
@ -18,7 +19,7 @@ export default {
|
|||||||
${requirejs}
|
${requirejs}
|
||||||
require.config({
|
require.config({
|
||||||
paths: { copycat: "https://copy-cat.squiddev.cc" },
|
paths: { copycat: "https://copy-cat.squiddev.cc" },
|
||||||
urlArgs: function(id) { return id == "copycat/embed" ? "?v=20211127" : ""; }
|
urlArgs: function(id) { return id == "copycat/embed" ? "?v=20211221" : ""; }
|
||||||
});
|
});
|
||||||
`,
|
`,
|
||||||
format: "amd",
|
format: "amd",
|
||||||
@ -33,12 +34,18 @@ export default {
|
|||||||
plugins: [
|
plugins: [
|
||||||
typescript(),
|
typescript(),
|
||||||
|
|
||||||
|
url({
|
||||||
|
include: "**/*.dfpwm",
|
||||||
|
fileName: "[name]-[hash][extname]",
|
||||||
|
publicPath: "/",
|
||||||
|
}),
|
||||||
|
|
||||||
{
|
{
|
||||||
name: "cc-tweaked",
|
name: "cc-tweaked",
|
||||||
async transform(code, file) {
|
async transform(code, file) {
|
||||||
// Allow loading files in /mount.
|
// Allow loading files in /mount.
|
||||||
const ext = path.extname(file);
|
const ext = path.extname(file);
|
||||||
return ext != '.tsx' && ext != '.ts' && path.dirname(file) === path.resolve(`${input}/mount`)
|
return ext != '.dfpwm' && path.dirname(file) === path.resolve(`${input}/mount`)
|
||||||
? `export default ${JSON.stringify(code)};\n`
|
? `export default ${JSON.stringify(code)};\n`
|
||||||
: null;
|
: null;
|
||||||
},
|
},
|
||||||
|
@ -143,14 +143,14 @@ streams, or use different decoders for the same stream, the resulting audio may
|
|||||||
@usage Reads "data/example.dfpwm" in blocks of 16KiB (the speaker can accept a maximum of 128×1024 samples), decodes
|
@usage Reads "data/example.dfpwm" in blocks of 16KiB (the speaker can accept a maximum of 128×1024 samples), decodes
|
||||||
them and then plays them through the speaker.
|
them and then plays them through the speaker.
|
||||||
|
|
||||||
```lua
|
```lua {data-peripheral=speaker}
|
||||||
local dfpwm = require "cc.audio.dfpwm"
|
local dfpwm = require "cc.audio.dfpwm"
|
||||||
local speaker = peripheral.find("speaker")
|
local speaker = peripheral.find("speaker")
|
||||||
|
|
||||||
local decoder = dfpwm.make_decoder()
|
local decoder = dfpwm.make_decoder()
|
||||||
for input in io.lines("data/example.dfpwm", 16 * 1024 * 2) do
|
for input in io.lines("data/example.dfpwm", 16 * 1024) do
|
||||||
local decoded = decoder(input)
|
local decoded = decoder(input)
|
||||||
while not speaker.playAudio(output) do
|
while not speaker.playAudio(decoded) do
|
||||||
os.pullEvent("speaker_audio_empty")
|
os.pullEvent("speaker_audio_empty")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { render, h, Component, Computer } from "copycat/embed";
|
import { render, h, Component, Computer, PeripheralKind } from "copycat/embed";
|
||||||
import type { ComponentChild } from "preact";
|
import type { ComponentChild } from "preact";
|
||||||
|
|
||||||
import settingsFile from "./mount/.settings";
|
import settingsFile from "./mount/.settings";
|
||||||
@ -6,6 +6,8 @@ import startupFile from "./mount/startup.lua";
|
|||||||
import exprTemplate from "./mount/expr_template.lua";
|
import exprTemplate from "./mount/expr_template.lua";
|
||||||
import exampleNfp from "./mount/example.nfp";
|
import exampleNfp from "./mount/example.nfp";
|
||||||
import exampleNft from "./mount/example.nft";
|
import exampleNft from "./mount/example.nft";
|
||||||
|
import exampleAudioLicense from "./mount/example.dfpwm.LICENSE";
|
||||||
|
import exampleAudioUrl from "./mount/example.dfpwm";
|
||||||
|
|
||||||
const defaultFiles: { [filename: string]: string } = {
|
const defaultFiles: { [filename: string]: string } = {
|
||||||
".settings": settingsFile,
|
".settings": settingsFile,
|
||||||
@ -21,13 +23,23 @@ const clamp = (value: number, min: number, max: number): number => {
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const download = async (url: string): Promise<Uint8Array> => {
|
||||||
|
const result = await fetch(url);
|
||||||
|
if (result.status != 200) throw new Error(`${url} responded with ${result.status} ${result.statusText}`);
|
||||||
|
|
||||||
|
return new Uint8Array(await result.arrayBuffer());
|
||||||
|
};
|
||||||
|
|
||||||
|
let dfpwmAudio: Promise<Uint8Array> | null = null;
|
||||||
|
|
||||||
const Click = (options: { run: () => void }) =>
|
const Click = (options: { run: () => void }) =>
|
||||||
<button type="button" class="example-run" onClick={options.run}>Run ᐅ</button>
|
<button type="button" class="example-run" onClick={options.run}>Run ᐅ</button>
|
||||||
|
|
||||||
type WindowProps = {};
|
type WindowProps = {};
|
||||||
|
|
||||||
type Example = {
|
type Example = {
|
||||||
files: { [file: string]: string },
|
files: { [file: string]: string | Uint8Array },
|
||||||
|
peripheral: PeripheralKind | null,
|
||||||
}
|
}
|
||||||
|
|
||||||
type WindowState = {
|
type WindowState = {
|
||||||
@ -69,7 +81,8 @@ class Window extends Component<WindowProps, WindowState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const mount = element.getAttribute("data-mount");
|
const mount = element.getAttribute("data-mount");
|
||||||
render(<Click run={this.runExample(example, mount)} />, element);
|
const peripheral = element.getAttribute("data-peripheral");
|
||||||
|
render(<Click run={this.runExample(example, mount, peripheral)} />, element);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,20 +99,20 @@ class Window extends Component<WindowProps, WindowState> {
|
|||||||
<div class="computer-container">
|
<div class="computer-container">
|
||||||
<Computer key={exampleIdx} files={{
|
<Computer key={exampleIdx} files={{
|
||||||
...example!.files, ...defaultFiles
|
...example!.files, ...defaultFiles
|
||||||
}} />
|
}} peripherals={{ back: example!.peripheral }} />
|
||||||
</div>
|
</div>
|
||||||
</div> : <div class="example-window example-window-hidden" />;
|
</div> : <div class="example-window example-window-hidden" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
private runExample(example: string, mount: string | null): () => void {
|
private runExample(example: string, mount: string | null, peripheral: string | null): () => void {
|
||||||
return () => {
|
return async () => {
|
||||||
if (!this.positioned) {
|
if (!this.positioned) {
|
||||||
this.positioned = true;
|
this.positioned = true;
|
||||||
this.left = 20;
|
this.left = 20;
|
||||||
this.top = 20;
|
this.top = 20;
|
||||||
}
|
}
|
||||||
|
|
||||||
const files: { [file: string]: string } = { "example.lua": example };
|
const files: { [file: string]: string | Uint8Array } = { "example.lua": example };
|
||||||
if (mount !== null) {
|
if (mount !== null) {
|
||||||
for (const toMount of mount.split(",")) {
|
for (const toMount of mount.split(",")) {
|
||||||
const [name, path] = toMount.split(":", 2);
|
const [name, path] = toMount.split(":", 2);
|
||||||
@ -107,9 +120,23 @@ class Window extends Component<WindowProps, WindowState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (example.includes("data/example.dfpwm")) {
|
||||||
|
files["data/example.dfpwm.LICENSE"] = exampleAudioLicense;
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (dfpwmAudio === null) dfpwmAudio = download(exampleAudioUrl);
|
||||||
|
files["data/example.dfpwm"] = await dfpwmAudio;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Cannot download example dfpwm", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.setState(({ exampleIdx }: WindowState) => ({
|
this.setState(({ exampleIdx }: WindowState) => ({
|
||||||
visible: true,
|
visible: true,
|
||||||
example: { files },
|
example: {
|
||||||
|
files,
|
||||||
|
peripheral: peripheral as PeripheralKind | null,
|
||||||
|
},
|
||||||
exampleIdx: exampleIdx + 1,
|
exampleIdx: exampleIdx + 1,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
2982
src/web/mount/example.dfpwm
Normal file
2982
src/web/mount/example.dfpwm
Normal file
File diff suppressed because one or more lines are too long
3
src/web/mount/example.dfpwm.LICENSE
Normal file
3
src/web/mount/example.dfpwm.LICENSE
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
Playing Soliloquy [Remake] by Alcakight
|
||||||
|
Source: https://soundcloud.com/alcaknight/soliloquy-remake
|
||||||
|
License: under CC BY 3.0
|
@ -1,3 +1,12 @@
|
|||||||
|
-- Print out license information if needed
|
||||||
|
if fs.exists("data/example.dfpwm") then
|
||||||
|
local h = io.open("data/example.dfpwm.LICENSE")
|
||||||
|
local contents = h:read("*a")
|
||||||
|
h:close()
|
||||||
|
|
||||||
|
write(contents)
|
||||||
|
end
|
||||||
|
|
||||||
-- Make the startup file invisible, then run the file. We could use
|
-- Make the startup file invisible, then run the file. We could use
|
||||||
-- shell.run, but this ensures the program is in shell history, etc...
|
-- shell.run, but this ensures the program is in shell history, etc...
|
||||||
fs.delete("startup.lua")
|
fs.delete("startup.lua")
|
||||||
|
@ -19,10 +19,23 @@ declare module "*.settings" {
|
|||||||
export default contents;
|
export default contents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare module "*.LICENSE" {
|
||||||
|
const contents: string;
|
||||||
|
export default contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module "*.dfpwm" {
|
||||||
|
const contents: string;
|
||||||
|
export default contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
declare module "copycat/embed" {
|
declare module "copycat/embed" {
|
||||||
import { h, Component, render, ComponentChild } from "preact";
|
import { h, Component, render, ComponentChild } from "preact";
|
||||||
|
|
||||||
|
export type Side = "up" | "down" | "left" | "right" | "front" | "back";
|
||||||
|
export type PeripheralKind = "speaker";
|
||||||
|
|
||||||
export { h, Component, render };
|
export { h, Component, render };
|
||||||
|
|
||||||
export type ComputerAccess = unknown;
|
export type ComputerAccess = unknown;
|
||||||
@ -35,6 +48,9 @@ declare module "copycat/embed" {
|
|||||||
width?: number,
|
width?: number,
|
||||||
height?: number,
|
height?: number,
|
||||||
resolve?: (computer: ComputerAccess) => void,
|
resolve?: (computer: ComputerAccess) => void,
|
||||||
|
peripherals?: {
|
||||||
|
[side in Side]?: PeripheralKind | null
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
class Computer extends Component<MainProps, unknown> {
|
class Computer extends Component<MainProps, unknown> {
|
||||||
|
Loading…
Reference in New Issue
Block a user