mirror of
https://github.com/SquidDev-CC/CC-Tweaked
synced 2024-11-19 00:04:53 +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
|
||||
*.jar binary
|
||||
*.dfpwm binary
|
||||
|
21
build.gradle
21
build.gradle
@ -290,18 +290,7 @@ task rollup(type: Exec) {
|
||||
commandLine mkCommand('"node_modules/.bin/rollup" --config rollup.config.js')
|
||||
}
|
||||
|
||||
task minifyWeb(type: Exec, dependsOn: rollup) {
|
||||
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]) {
|
||||
task illuaminateDocs(type: Exec, dependsOn: [rollup, luaJavadoc]) {
|
||||
group = "build"
|
||||
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.file("illuaminate.sexp").withPropertyName("illuaminate.sexp")
|
||||
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")
|
||||
outputs.dir("$buildDir/docs/lua")
|
||||
|
||||
@ -317,9 +306,13 @@ task illuaminateDocs(type: Exec, dependsOn: [minifyWeb, luaJavadoc]) {
|
||||
}
|
||||
|
||||
task docWebsite(type: Copy, dependsOn: [illuaminateDocs]) {
|
||||
from 'doc'
|
||||
from('doc') {
|
||||
include 'logo.png'
|
||||
include 'images/**'
|
||||
}
|
||||
from("$buildDir/rollup") {
|
||||
exclude 'index.js'
|
||||
}
|
||||
into "${project.docsDir}/lua"
|
||||
}
|
||||
|
||||
|
@ -51,5 +51,6 @@ exclude: |
|
||||
src/generated|
|
||||
src/test/resources/test-rom/data/json-parsing/|
|
||||
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
|
||||
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 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
|
||||
[Ring Buffer], which helps makes things a little more efficient.
|
||||
|
||||
```lua
|
||||
```lua {data-peripheral=speaker}
|
||||
local dfpwm = require("cc.audio.dfpwm")
|
||||
local speaker = peripheral.find("speaker")
|
||||
|
||||
@ -157,14 +157,14 @@ for i = 1, samples_n do samples[i] = 0 end
|
||||
|
||||
local decoder = dfpwm.make_decoder()
|
||||
for chunk in io.lines("data/example.dfpwm", 16 * 1024) do
|
||||
local buffer = decoder(input)
|
||||
local buffer = decoder(chunk)
|
||||
|
||||
for i = 1, #buffer do
|
||||
local original_value = buffer[i]
|
||||
|
||||
-- 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.
|
||||
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.
|
||||
samples[samples_i] = original_value
|
||||
|
86
package-lock.json
generated
86
package-lock.json
generated
@ -14,6 +14,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-typescript": "^8.2.5",
|
||||
"@rollup/plugin-url": "^6.1.0",
|
||||
"requirejs": "^2.3.6",
|
||||
"rollup": "^2.33.1",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
@ -73,6 +74,23 @@
|
||||
"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": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
||||
@ -264,12 +282,39 @@
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"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": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"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": {
|
||||
"version": "1.0.7",
|
||||
"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": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||
@ -512,6 +566,17 @@
|
||||
"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": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-3.1.0.tgz",
|
||||
@ -665,12 +730,27 @@
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"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": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"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": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz",
|
||||
@ -740,6 +820,12 @@
|
||||
"integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
|
||||
"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": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-4.0.0.tgz",
|
||||
|
@ -10,6 +10,7 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@rollup/plugin-typescript": "^8.2.5",
|
||||
"@rollup/plugin-url": "^6.1.0",
|
||||
"requirejs": "^2.3.6",
|
||||
"rollup": "^2.33.1",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
|
@ -2,6 +2,7 @@ import { readFileSync } from "fs";
|
||||
import path from "path";
|
||||
|
||||
import typescript from "@rollup/plugin-typescript";
|
||||
import url from '@rollup/plugin-url';
|
||||
import { terser } from "rollup-plugin-terser";
|
||||
|
||||
const input = "src/web";
|
||||
@ -10,7 +11,7 @@ const requirejs = readFileSync("node_modules/requirejs/require.js");
|
||||
export default {
|
||||
input: [`${input}/index.tsx`],
|
||||
output: {
|
||||
file: "build/rollup/index.js",
|
||||
dir: "build/rollup/",
|
||||
// We bundle requirejs (and config) into the header. It's rather gross
|
||||
// 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.
|
||||
@ -18,7 +19,7 @@ export default {
|
||||
${requirejs}
|
||||
require.config({
|
||||
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",
|
||||
@ -33,12 +34,18 @@ export default {
|
||||
plugins: [
|
||||
typescript(),
|
||||
|
||||
url({
|
||||
include: "**/*.dfpwm",
|
||||
fileName: "[name]-[hash][extname]",
|
||||
publicPath: "/",
|
||||
}),
|
||||
|
||||
{
|
||||
name: "cc-tweaked",
|
||||
async transform(code, file) {
|
||||
// Allow loading files in /mount.
|
||||
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`
|
||||
: 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
|
||||
them and then plays them through the speaker.
|
||||
|
||||
```lua
|
||||
```lua {data-peripheral=speaker}
|
||||
local dfpwm = require "cc.audio.dfpwm"
|
||||
local speaker = peripheral.find("speaker")
|
||||
|
||||
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)
|
||||
while not speaker.playAudio(output) do
|
||||
while not speaker.playAudio(decoded) do
|
||||
os.pullEvent("speaker_audio_empty")
|
||||
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 settingsFile from "./mount/.settings";
|
||||
@ -6,6 +6,8 @@ import startupFile from "./mount/startup.lua";
|
||||
import exprTemplate from "./mount/expr_template.lua";
|
||||
import exampleNfp from "./mount/example.nfp";
|
||||
import exampleNft from "./mount/example.nft";
|
||||
import exampleAudioLicense from "./mount/example.dfpwm.LICENSE";
|
||||
import exampleAudioUrl from "./mount/example.dfpwm";
|
||||
|
||||
const defaultFiles: { [filename: string]: string } = {
|
||||
".settings": settingsFile,
|
||||
@ -21,13 +23,23 @@ const clamp = (value: number, min: number, max: number): number => {
|
||||
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 }) =>
|
||||
<button type="button" class="example-run" onClick={options.run}>Run ᐅ</button>
|
||||
|
||||
type WindowProps = {};
|
||||
|
||||
type Example = {
|
||||
files: { [file: string]: string },
|
||||
files: { [file: string]: string | Uint8Array },
|
||||
peripheral: PeripheralKind | null,
|
||||
}
|
||||
|
||||
type WindowState = {
|
||||
@ -69,7 +81,8 @@ class Window extends Component<WindowProps, WindowState> {
|
||||
}
|
||||
|
||||
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">
|
||||
<Computer key={exampleIdx} files={{
|
||||
...example!.files, ...defaultFiles
|
||||
}} />
|
||||
}} peripherals={{ back: example!.peripheral }} />
|
||||
</div>
|
||||
</div> : <div class="example-window example-window-hidden" />;
|
||||
}
|
||||
|
||||
private runExample(example: string, mount: string | null): () => void {
|
||||
return () => {
|
||||
private runExample(example: string, mount: string | null, peripheral: string | null): () => void {
|
||||
return async () => {
|
||||
if (!this.positioned) {
|
||||
this.positioned = true;
|
||||
this.left = 20;
|
||||
this.top = 20;
|
||||
}
|
||||
|
||||
const files: { [file: string]: string } = { "example.lua": example };
|
||||
const files: { [file: string]: string | Uint8Array } = { "example.lua": example };
|
||||
if (mount !== null) {
|
||||
for (const toMount of mount.split(",")) {
|
||||
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) => ({
|
||||
visible: true,
|
||||
example: { files },
|
||||
example: {
|
||||
files,
|
||||
peripheral: peripheral as PeripheralKind | null,
|
||||
},
|
||||
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
|
||||
-- shell.run, but this ensures the program is in shell history, etc...
|
||||
fs.delete("startup.lua")
|
||||
|
@ -19,10 +19,23 @@ declare module "*.settings" {
|
||||
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" {
|
||||
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 type ComputerAccess = unknown;
|
||||
@ -35,6 +48,9 @@ declare module "copycat/embed" {
|
||||
width?: number,
|
||||
height?: number,
|
||||
resolve?: (computer: ComputerAccess) => void,
|
||||
peripherals?: {
|
||||
[side in Side]?: PeripheralKind | null
|
||||
},
|
||||
}
|
||||
|
||||
class Computer extends Component<MainProps, unknown> {
|
||||
|
Loading…
Reference in New Issue
Block a user