Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-111997.svg)](#build--distribution)
[![Electron](https://img.shields.io/badge/Electron-43-47848F.svg)](https://www.electronjs.org/)
[![Downloads](https://img.shields.io/github/downloads/CaYatur/SoundVisualizer/total?label=downloads)](https://github.com/CaYatur/SoundVisualizer/releases)
[![Tests](https://img.shields.io/badge/tests-2202%20passing-2ea043.svg)](#tests)
[![Tests](https://img.shields.io/badge/tests-2227%20passing-2ea043.svg)](#tests)
[![cayadev.com](https://img.shields.io/badge/cayadev.com-e11d2a.svg)](https://cayadev.com)

</div>
Expand Down Expand Up @@ -263,6 +263,11 @@ that asserts the bar profile has no step in it.
first missing number, integer settings drop their fractions, and equation lines are glued the way
MilkDrop glues them, `\\` comments included. 32 presets of the corpus read differently; with
fidelity off the old parser stays.
- **Equations run by MilkDrop 2's compiler rules.** With fidelity on, truth and equality tests use
its 0.00001 tolerance, `%` works on whole numbers without sign, `&` and `|` on 64-bit integers,
`megabuf` and `gmegabuf` indices are rounded and bounded the way it does, `rand(n)` returns a
real number (5,361 corpus presets call it), and the compiler's internal names such as `_aboeq`
run. With fidelity off nothing changes.
- **Composite shaders get the hue colour MilkDrop gives them.** MilkDrop passes every composite
shader four slowly drifting corner colours as `hue_shader`, whatever the preset's `fShader`
says; `fShader` only scales them on the fixed pipeline. The engine applied `fShader` to shaders
Expand Down Expand Up @@ -1315,7 +1320,7 @@ npm test
npm start -- --smoke
```

**2202 unit tests, all passing.** They are written to check answers, not to exercise lines:
**2227 unit tests, all passing.** They are written to check answers, not to exercise lines:

- **Formulas** are checked against values derived by hand from their definitions — Viviani's curve
staying on its sphere, the torus tube radius, Chladni's m↔n antisymmetry, every attractor
Expand Down
9 changes: 7 additions & 2 deletions README.tr.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20macOS%20%7C%20Linux-111997.svg)](#paketleme--dağıtım)
[![Electron](https://img.shields.io/badge/Electron-43-47848F.svg)](https://www.electronjs.org/)
[![İndirme](https://img.shields.io/github/downloads/CaYatur/SoundVisualizer/total?label=indirme)](https://github.com/CaYatur/SoundVisualizer/releases)
[![Test](https://img.shields.io/badge/test-2202%20geçiyor-2ea043.svg)](#testler)
[![Test](https://img.shields.io/badge/test-2227%20geçiyor-2ea043.svg)](#testler)
[![cayadev.com](https://img.shields.io/badge/cayadev.com-e11d2a.svg)](https://cayadev.com)

</div>
Expand Down Expand Up @@ -256,6 +256,11 @@ profilinde basamak olmadığını doğruluyor.
numaralı kod ilk eksik numarada bitiyor, tam sayı ayarları kesirlerini atıyor ve denklem satırları
MilkDrop'un yapıştırdığı gibi, `\\` yorumları dahil, yapışıyor. Korpusta 32 preset farklı
okunuyor; uyum kapalıyken eski ayrıştırıcı duruyor.
- **Denklemler MilkDrop 2 derleyicisinin kurallarıyla çalışıyor.** Uyum açıkken doğruluk ve eşitlik
sınamaları onun 0.00001 toleransını kullanıyor, `%` işaretsiz tam sayılarla, `&` ve `|` 64 bit
tam sayılarla çalışıyor, `megabuf` ve `gmegabuf` indisleri onun yuvarladığı ve sınırladığı gibi
hesaplanıyor, `rand(n)` gerçel sayı döndürüyor (korpusta 5.361 preset çağırıyor) ve derleyicinin
`_aboeq` gibi iç adları çalışıyor. Uyum kapalıyken hiçbir şey değişmiyor.
- **Birleştirme shader'ları MilkDrop'un verdiği ton rengini alıyor.** MilkDrop her birleştirme
shader'ına `hue_shader` olarak dört köşede yavaşça gezinen renkler veriyor, presetin `fShader`ı
ne derse desin; `fShader` onları yalnız sabit yolda ölçekliyor. Motor `fShader`ı shader'lara da
Expand Down Expand Up @@ -1313,7 +1318,7 @@ npm test
npm start -- --smoke
```

**2202 birim testi, hepsi geçiyor.** Satır çalıştırmak için değil, cevap denetlemek için yazıldılar:
**2227 birim testi, hepsi geçiyor.** Satır çalıştırmak için değil, cevap denetlemek için yazıldılar:

- **Formüller**, tanımlarından elle türetilmiş değerlerle sınanıyor — Viviani eğrisinin küre
üzerinde kalması, simidin boru yarıçapı, Chladni'nin m↔n antisimetrisi, her çekicinin sınırlı
Expand Down
91 changes: 79 additions & 12 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,9 +129,9 @@ npm test
npm start -- --smoke
```

- **2202 unit tests, all passing** on `main`. 703 of those shipped in v3.1.0;
- **2227 unit tests, all passing** on `main`. 703 of those shipped in v3.1.0;
105 came with v3.1.1; 163 came with v3.1.2; 157 came with v3.1.3 — 1128 at
that tag — 469 more with v3.1.4, most of them from the MilkDrop work, and 600
that tag — 469 more with v3.1.4, most of them from the MilkDrop work, and 630
on `main` since.
Formulas are checked against values derived
by hand from their definitions — Viviani's curve staying on its sphere, the
Expand Down Expand Up @@ -2033,12 +2033,17 @@ rest after. No version number yet.
the old ring nouns, the " · " in mash-up names or removing the
module's script tag each fails a test.
- **Fidelity follow-ups (#580)** · the fixed composite, the stage rule,
MilkDrop's defaults, the hue colour, the values that stay in the file and
MilkDrop's way of reading a file are done; the other audits are next.
MilkDrop's defaults, the hue colour, the values that stay in the file,
MilkDrop's way of reading a file and its expression compiler's rules are
done; the other audits are next.
- **Checked against the source.** Nullsoft's own code
(jecassis/foo_vis_milk2 5b44cea) and, for the fixed pipeline's blend
passes, the D3D9 code the D3D11 fork was ported from (BeatDrop
53d83ee). Both agree on everything below.
53d83ee). Both agree on everything below. Expressions are the
exception: the D3D11 fork evaluates them with projectM's
re-implementation by default, which differs from MilkDrop in places
(its `%` keeps the sign, its memory index adds 0.0001), so there the
reference is Nullsoft's compiler, ns-eel2, as BeatDrop carries it.
- **Which stage draws.** MilkDrop picks a preset's warp and composite
shaders by version, not by whether shader text exists. A file with no
`MILKDROP_PRESET_VERSION`, or one below 200, is a MilkDrop 1 preset and
Expand Down Expand Up @@ -2213,24 +2218,75 @@ rest after. No version number yet.
differently, 15 change with fidelity on, 12 by more than 1% (up to
32%), and all 32 are identical with it off. The 900-preset sample sorts
into the same classes, preset for preset.
- **Expressions follow MilkDrop 2's compiler.** With fidelity on the
equations run by the rules of ns-eel2 as MilkDrop 2 builds it:
- truth tests (`if`, `!`, `&&`, `||`, `while`, `bnot`) count |x| of
0.00001 or more as true, `band` and `bor` need more than 0.00001,
`==`, `!=` and `equal` compare with the same tolerance, and `<`, `>`,
`above`, `below` stay exact; NaN is false, and equal to anything;
- the compiler's own operator names compile (`_aboeq`, `_if`, `_and`,
`_or`, `_equal`, `_set`, `_addop` and the rest, `_mem`, `_gmem`);
`_and` and `_or` skip their right side like `&&` and `||`;
- `%` works on whole numbers without sign — both sides lose their
sign and fraction, so `-7 % 3` is 1 and `5 % 0.5` is 0 — and a value
outside the signed 32-bit range turns into 2^31, as the x87
conversion does;
- `&` and `|` work on 64-bit integers;
- a `megabuf` index is rounded down after adding 0.00001, reaches
8,388,608 cells, and reads 0 outside them; `gmegabuf` has 2^20
cells and its index wraps;
- `rand(n)` returns a real number between 0 and n, not an integer.
Every block of a preset and its sprites read one switch, so turning
fidelity over changes all of them in the same frame, and a preset that
uses the internal names is rebuilt. With fidelity off nothing changes.
- **Measured** against the previous step, the last ten of 60 frames, 120
presets per group. Truth tests: 119 of 120 presets with conditions are
identical, and one moves 4% — it asks `equal(sin(ang), 0)`, where
sin(π) is 1.2e-16; the three `_aboeq` presets change by up to 29%,
since the engine did not run that code before. `%`: 118 of 120
identical; one takes the remainder of negative samples (6%), one
hashes with numbers past 2^31 and its points pile up (48%). `&` and
`|`: 120 of 120 identical. Memory: 119 of 120; one computes its
`gmegabuf` indices (3%). `rand`, which 5,361 presets call: 92 of 120
identical, 14 change by more than 1%, up to 18%, the median of those
that change 1.07%. Control groups without the feature are identical,
and every group is identical with fidelity off. The whole change costs
no time: 0.62-0.64 ms for a 1,728-point per-pixel frame, 0.71-0.75 ms
before. The 900-preset sample keeps 899 of 900 classes; the one that
moves, Goody's Molten Wavepool (blown → clean), uses none of these
features and renders the same alone before and after (clean,
brightness 0.038); main itself classed it blown in the sample run, so
its class there depends on the order of the run, not on this change.
- **Not done yet:** the fixed warp path, the blur chain, borders and
centre darkening, and the rest of the blend snap points; whether `uv`
in preset shaders runs the way MilkDrop's does — read back from the
screen, our `uv.y` is 1 at the top, where MilkDrop's texture
coordinate is 0; sampling agrees, but a shader doing arithmetic on
`uv.y` may come out mirrored, which needs its own check; MilkDrop's
internal comparison functions such as `_aboeq`, which three corpus
presets call and our compiler does not know; the reference comparison
with an external renderer, which needs one installed and waits for the
user's approval. Left out of the reader on purpose: MilkDrop reads
`uv.y` may come out mirrored, which needs its own check; the scope of
expression variables — MilkDrop gives per-frame, per-pixel, each
wave's per-frame and per-point and each shape their own variables and
`megabuf`, and hands per-pixel only a fixed list, where the engine
shares one set between init, per-frame and per-pixel (next); division
by zero, which is infinity in MilkDrop and 0 here; the loop cap —
MilkDrop stops `loop` and `while` at 1,048,576 turns a call, the engine
at a budget, which six corpus presets reach (five in init, one in a
shape); the reference comparison with an external renderer, which
needs one installed and waits for the user's approval. Left out of
the compiler: syntax newer than MilkDrop 2's grammar (`?:`, `&=`,
`|=`, `^=`, `<<`, `$` constants) and the functions `invsqrt`,
`memcpy`, `memset` and `freembuf`, which no corpus preset uses in code;
and the old grammar's `%`, which ns-eel2's parser table maps to a
function that returns its right side — the corpus writes `%` as a
remainder, and the operator function MilkDrop compiles is the
remainder above. Left out of the reader on purpose: MilkDrop reads
bytes and the engine gets decoded text, so its two byte rules — a
0xFF byte ends the file, a value over 251 characters splits into a
second index line — cannot be kept exactly, and neither touches a
corpus file; values stay double where MilkDrop stores float, a
difference below 1e-7; and a block that fails to compile is dropped
whole in MilkDrop but recovered statement by statement here, because
our parser and MilkDrop's do not agree on what an error is (`_aboeq`
is one case), so dropping whole blocks would drop some MilkDrop runs.
our parser and MilkDrop's may still disagree on what an error is, and
dropping whole blocks would then drop code MilkDrop runs.
- **Tests.** 14 new: the version rule and the stage choice, the two
generated shaders (float rounding, samplers, echo, hue, flag order,
and that they translate), echo orientation and gamma cases, the
Expand Down Expand Up @@ -2270,6 +2326,17 @@ rest after. No version number yet.
donor's reading. The own-presets test also requires both readings to
agree, and the mash-up part test compares with the new reader.
23 of 23 mutations are caught.
The expression rules add 25 (`milkdrop-md2-eel.test.js`): the internal
names with fidelity on and off, their arity and case, `_and` and `_or`
skipping their right side, the truth boundaries at 0.00001 for every
test, NaN, `while`, switching mode at run time, the remainder's sign,
fractions and values outside the signed 32-bit range, 64-bit `&` and
`|`, the memory index, capacity and wrap (with a compound write past
the old limit and two `gmegabuf` indices that alias only under the
wrong mask), the real
`rand` and its repeatability, the Preset switching all its blocks,
`readingsDiffer` seeing the names, sprites, and every expression compile
in `src` passing the mode. 71 of 71 mutations are caught.

## v3.1.6 — Comprehensive video export

Expand Down
2 changes: 1 addition & 1 deletion src/main/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -5096,7 +5096,7 @@ async function runSmoke() {
try {
var m = window.SVMilkdrop;
var pool = new m.Pool();
var c = m.compile('x = 2 + 3; y = x * 5; z = sqrt(y); w = if(above(y,10), 7, 9); v = 10 % 3; u = 2 ^ 3; t = 1/0;', pool);
var c = m.compile('x = 2 + 3; y = x * 5; z = sqrt(y); w = if(above(y,10), 7, 9); v = 10 % 3; u = 2 ^ 3; t = 1/0;', pool, { mode: { md2: true }, md2Funcs: true });
c.run();
return JSON.stringify({
hata: '',
Expand Down
12 changes: 10 additions & 2 deletions src/shared/milkdrop-sprites.js
Original file line number Diff line number Diff line change
Expand Up @@ -149,8 +149,15 @@
this.M = M;
this.slots = new Array(SLOTS).fill(null);
this.launches = 0; // başlatma sırası: en yeni / en eski buradan
/* MilkDrop 2 uyumu (#580): sprite kodu da MilkDrop'un ifade
derleyicisiyle koşuyor. Derlenen kodun paylaştığı anahtar; motor
her karede yazıyor (setAccurate). İç işlev adları (`_aboeq` …)
sprite başlatılırken o anki değere göre tanınıyor. */
this.mode = { md2: true };
}

setAccurate(on) { this.mode.md2 = on !== false; }

count() { return this.slots.reduce((n, s) => n + (s ? 1 : 0), 0); }

/* Sprite'ı başlatır, yuvasını döndürür (-1: başlatılamadı).
Expand Down Expand Up @@ -183,8 +190,9 @@
for (const k of INPUTS) pool.set(k, 0);
for (const k of Object.keys(DEFAULTS)) pool.set(k, DEFAULTS[k]);
const seed = (Number(opt.seed) >>> 0) || 1;
const init = M.compile(def.init || '', pool, { seed });
const code = M.compile(def.code || '', pool, { seed: (seed ^ 0x9e3779b9) >>> 0 || 1 });
const eel = { mode: this.mode, md2Funcs: this.mode.md2 };
const init = M.compile(def.init || '', pool, Object.assign({ seed }, eel));
const code = M.compile(def.code || '', pool, Object.assign({ seed: (seed ^ 0x9e3779b9) >>> 0 || 1 }, eel));
init.run(pool.values);
this.slots[slot] = {
num: def.num,
Expand Down
Loading
Loading