Compare commits
No commits in common. "main" and "sky-scroll" have entirely different histories.
main
...
sky-scroll
15
.gitignore
vendored
|
|
@ -2,13 +2,8 @@
|
|||
loader/build
|
||||
loader/tools/cc1541/cc1541
|
||||
|
||||
loader/samples/minexample/**/*.bak
|
||||
loader/samples/minexample/**/*.o
|
||||
loader/samples/minexample/**/*.zx0.prg
|
||||
loader/samples/minexample/**/*.lz.prg
|
||||
loader/samples/minexample/**/*.tmp
|
||||
loader/samples/minexample/main.zx0
|
||||
loader/samples/minexample/song0.bin
|
||||
loader/samples/minexample/song1.bin
|
||||
loader/samples/minexample/font.prg
|
||||
loader/samples/minexample/test/*.prg
|
||||
loader/samples/minexample/*.bak
|
||||
loader/samples/minexample/*.o
|
||||
loader/samples/minexample/*.zx0.prg
|
||||
loader/samples/minexample/*.lz.prg
|
||||
loader/samples/minexample/*.tmp
|
||||
|
|
|
|||
|
|
@ -1,423 +1,66 @@
|
|||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
50,ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
20,ys2/11_lilia_final/koala/png/04.png
|
||||
3,ys2/11_lilia_final/koala/png/05.png
|
||||
3,ys2/11_lilia_final/koala/png/06.png
|
||||
3,ys2/11_lilia_final/koala/png/07.png
|
||||
3,ys2/11_lilia_final/koala/png/06.png
|
||||
3,ys2/11_lilia_final/koala/png/05.png
|
||||
3,ys2/11_lilia_final/koala/png/04.png
|
||||
|
||||
6,../../../assets/ys2/11_lilia_final/koala/png/04.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/05.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/06.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/07.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/06.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/05.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/04.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,ys2/11_lilia_final/koala/png/08.png
|
||||
3,ys2/11_lilia_final/koala/png/09.png
|
||||
3,ys2/11_lilia_final/koala/png/10.png
|
||||
3,ys2/11_lilia_final/koala/png/11.png
|
||||
3,ys2/11_lilia_final/koala/png/10.png
|
||||
3,ys2/11_lilia_final/koala/png/09.png
|
||||
3,ys2/11_lilia_final/koala/png/08.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/01.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
7,ys2/11_lilia_final/koala/png/03.png
|
||||
7,ys2/11_lilia_final/koala/png/02.png
|
||||
50,ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/08.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/09.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/10.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/11.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/10.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/09.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/08.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
6,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/01.png
|
||||
1,../../../assets/ys2/11_lilia_final/koala/png/02.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/03b.png
|
||||
3,../../../assets/ys2/11_lilia_final/koala/png/02b.png
|
||||
20,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/13.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/14.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/15.png
|
||||
2,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
10,../../../assets/ys2/11_lilia_final/koala/png/16.png
|
||||
3,ys2/11_lilia_final/koala/png/12.png
|
||||
3,ys2/11_lilia_final/koala/png/13.png
|
||||
3,ys2/11_lilia_final/koala/png/14.png
|
||||
3,ys2/11_lilia_final/koala/png/15.png
|
||||
200,ys2/11_lilia_final/koala/png/16.png
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
../png2prg/png2prg_darwin_arm64 -m koala -bpc 0,6,14,-1 -o ../loader/samples/minexample/badguy.bin 01_badguyz_cut.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/badguy.bin 01_badguyz_cut.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/tower_beam.bin 04_tower_beam.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/tower.bin 03_tower.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/lilia_hero.bin ys2/08_lilia_hero/koala/png/01.png
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/lilia.bin lilia.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/field.bin 05_field_will_loop.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/falling_star.bin 06_falling_star.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -bpc 0,-1,-1,-1 -o ../loader/samples/minexample/lilia_talk.bin 11_lilia_final.csv
|
||||
../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/falling_star.bin 06_falling_star.csv
|
||||
|
Before Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 689 B After Width: | Height: | Size: 721 B |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 5.1 KiB After Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.5 KiB |
|
Before Width: | Height: | Size: 7.2 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 2.7 KiB |
|
Before Width: | Height: | Size: 2 KiB After Width: | Height: | Size: 2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 856 B After Width: | Height: | Size: 892 B |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 5.8 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 7.2 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 5 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 7.1 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 7 KiB |
|
Before Width: | Height: | Size: 4.8 KiB After Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 4.7 KiB After Width: | Height: | Size: 6.8 KiB |
|
|
@ -97,7 +97,6 @@ C1541 = c1541
|
|||
CC1541 = ../../tools/cc1541/cc1541
|
||||
ZX02 = zx02/build/zx02
|
||||
ZX02_SRC = zx02
|
||||
FURC64 = furC64
|
||||
PYTHON = python3
|
||||
|
||||
MKDIR = mkdir -p
|
||||
|
|
@ -116,7 +115,7 @@ CAT = cat
|
|||
|
||||
BUILDDIR = ../../build
|
||||
INTERMDIR = ../../build/intermediate
|
||||
LOADER_SRC = ../..
|
||||
LOADER_SRC = ../../src
|
||||
LOADER = $(BUILDDIR)/loader-$(_PLATFORM_).prg
|
||||
|
||||
RESOURCESDIR = ../resources
|
||||
|
|
@ -131,8 +130,6 @@ DISKIMAGE = $(BUILDDIR)/$(NAME)-$(_PLATFORM_).d64
|
|||
AS_FLAGS = -Wa -I../../../shared -I ../../include -u __EXEHDR__
|
||||
|
||||
ZX0PRGS = \
|
||||
song0.zx0.prg \
|
||||
song1.zx0.prg \
|
||||
badguy.zx0.prg \
|
||||
title_320-prepared.zx0.prg \
|
||||
tower.zx0.prg \
|
||||
|
|
@ -141,12 +138,10 @@ ZX0PRGS = \
|
|||
falling_star.zx0.prg \
|
||||
lilia.zx0.prg \
|
||||
lilia_hero.zx0.prg \
|
||||
island.zx0.prg \
|
||||
clouds.zx0.prg \
|
||||
lilia_talk.zx0.prg
|
||||
sky_scroll.zx0.prg
|
||||
|
||||
LZPRGS = \
|
||||
island_map.lz.prg
|
||||
sky_scroll_map.lz.prg
|
||||
|
||||
|
||||
default: diskimage
|
||||
|
|
@ -164,7 +159,7 @@ $(LOADER): $(LOADERCFG)
|
|||
|
||||
assemble: $(ASSEMBLE)
|
||||
|
||||
$(ASSEMBLE): $(SOURCE) $(LOADER) main.zx0
|
||||
$(ASSEMBLE): $(SOURCE) $(LOADER) $(LOADERCFG)
|
||||
$(MKDIR) $(BUILDDIR)
|
||||
$(MKDIR) $(INTERMDIR)
|
||||
ifeq ($(_PLATFORM_),c64)
|
||||
|
|
@ -178,14 +173,13 @@ endif
|
|||
|
||||
diskimage: $(DISKIMAGE)
|
||||
|
||||
$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.prg
|
||||
$(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS)
|
||||
$(RM) $@
|
||||
$(CC1541) -n "otomata labs" -i " 2025" \
|
||||
-f "ys2intro" -w $< \
|
||||
-f "song0" -w song0.zx0.prg \
|
||||
-f "song1" -w song1.zx0.prg \
|
||||
-f "sid" -w use_this_sid.bin \
|
||||
-f "badguy" -w badguy.zx0.prg \
|
||||
-f "font" -w font.prg \
|
||||
-f "font" -w font.bin \
|
||||
-f "intrbmp" -w title_320-prepared.zx0.prg \
|
||||
-f "tower" -w tower.zx0.prg \
|
||||
-f "towerbm" -w tower_beam.zx0.prg \
|
||||
|
|
@ -193,10 +187,8 @@ $(DISKIMAGE): $(ASSEMBLE) $(CC1541) $(ZX0PRGS) $(LZPRGS) font.prg
|
|||
-f "fallstar" -w falling_star.zx0.prg \
|
||||
-f "lilia" -w lilia.zx0.prg \
|
||||
-f "lilhero" -w lilia_hero.zx0.prg \
|
||||
-f "island" -w island.zx0.prg \
|
||||
-f "islandmap" -w island_map.lz.prg \
|
||||
-f "clouds" -w clouds.zx0.prg \
|
||||
-f "liltalk" -w lilia_talk.zx0.prg \
|
||||
-f "skyscr" -w sky_scroll.zx0.prg \
|
||||
-f "skyscrmap" -w sky_scroll_map.lz.prg \
|
||||
$@
|
||||
|
||||
|
||||
|
|
@ -211,6 +203,9 @@ run71: $(DISKIMAGE)
|
|||
$(EMU71) $(realpath $^)
|
||||
endif
|
||||
|
||||
$(INTERMDIR)/%.prg: $(RESOURCESDIR)/%.bin
|
||||
$(PRINTF) '\000\140' | $(CAT) - $? > $@ # octal 140 = hex 60
|
||||
|
||||
$(CC1541):
|
||||
make -C $(LOADER_SRC) cc1541
|
||||
|
||||
|
|
@ -219,31 +214,14 @@ $(ZX02):
|
|||
|
||||
%.zx0.prg: %.bin $(ZX02)
|
||||
$(ZX02) $< $@.tmp
|
||||
$(PRINTF) "\000\200" | $(CAT) - $@.tmp > $@
|
||||
$(PRINTF) "\x00\x80" | cat - $@.tmp > $@
|
||||
$(RM) $@.tmp
|
||||
|
||||
%.lz.prg: %.bin
|
||||
$(PYTHON) aart_lz.py $< $@.tmp
|
||||
$(PRINTF) "\000\220" | $(CAT) - $@.tmp > $@
|
||||
$(PRINTF) "\x00\x90" | cat - $@.tmp > $@
|
||||
$(RM) $@.tmp
|
||||
|
||||
main.zx0: main.asm
|
||||
$(RM) $@
|
||||
$(AS) -t c64 -C bin.cfg -o $@.tmp $<
|
||||
$(ZX02) $@.tmp $@
|
||||
$(RM) $@.tmp
|
||||
|
||||
song0.bin: ys2_fixed_drums.fur
|
||||
cd $(FURC64) && ./convert.sh $(abspath $<)
|
||||
cp $(FURC64)/asm/song.bin $@
|
||||
|
||||
song1.bin: ys2_lilia_sid.fur
|
||||
cd $(FURC64) && ./convert.sh $(abspath $<)
|
||||
cp $(FURC64)/asm/song.bin $@
|
||||
|
||||
font.prg: test/main.asm font.bin #test/logo.bin test/txtbg.bin
|
||||
$(AS) -t c64 -C test/bin.cfg -o $@ $<
|
||||
|
||||
clean:
|
||||
-$(RM) $(ZX0PRGS) $(LZPRGS)
|
||||
-$(RM) *.o $(ASSEMBLE) $(DISKIMAGE)
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
MEMORY {
|
||||
ZP: file = "", start = $0002, size = $00FE, define = yes;
|
||||
MAIN: file = %O, start = $E000, size = $1FFA;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, optional = yes;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = ro, optional = yes;
|
||||
DATA: load = MAIN, type = rw, optional = yes;
|
||||
BSS: load = MAIN, type = bss, optional = yes, define = yes;
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
#!/bin/bash
|
||||
|
||||
rm lilia_talk*.*
|
||||
../../../assets/png2prg_linux_amd64 -m koala -o lilia_talk.bin ../../../assets/11_lilia_final.csv
|
||||
|
||||
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
f = open("liltalk_speak.txt","r").readlines()
|
||||
f = [x[:-1] for x in f]
|
||||
|
||||
line_addrs = []
|
||||
char_cnt = 0
|
||||
for line in f:
|
||||
if line == '':
|
||||
line_addrs.append(char_cnt)
|
||||
char_cnt = 0
|
||||
else:
|
||||
num = 0
|
||||
i = 0
|
||||
while i < len(line) and line[i] in "0123456789":
|
||||
num = num*10+int(line[i])
|
||||
i += 1
|
||||
str = line[i+1:]
|
||||
str = str.upper()
|
||||
if "\\N" in str: str = str.split("\\N")[0]
|
||||
print(str)
|
||||
#str = str.replace("\\N","")
|
||||
char_cnt += len(str)
|
||||
line_addrs.append(char_cnt)
|
||||
|
||||
out = [0xFE, (40-line_addrs[0])//2]
|
||||
cnt = 1
|
||||
for line in f:
|
||||
if line == '':
|
||||
out.append(0xFE) # set line addr to beginning
|
||||
out.append((40-line_addrs[cnt])//2)
|
||||
cnt += 1
|
||||
else:
|
||||
num = 0
|
||||
i = 0
|
||||
while i < len(line) and line[i] in "0123456789":
|
||||
num = num*10+int(line[i])
|
||||
i += 1
|
||||
str = line[i+1:]
|
||||
str = str.upper()
|
||||
str = str.replace("\\N","\n")
|
||||
out.append(num)
|
||||
out.append(len(str))
|
||||
for x in str: out.append(ord(x))
|
||||
out.append(0xFF)
|
||||
|
||||
f = open("liltalk.bin","wb")
|
||||
f.write(bytearray(out))
|
||||
f.close()
|
||||
8
loader/samples/minexample/furC64/.gitignore
vendored
|
|
@ -1,8 +0,0 @@
|
|||
__pycache__
|
||||
asm/song.asm
|
||||
asm/song.bin
|
||||
*.o
|
||||
*.lbl
|
||||
*.lst
|
||||
*.map
|
||||
*.prg
|
||||
|
|
@ -1,42 +0,0 @@
|
|||
# furC64
|
||||
a C64/SID sound driver for Furnace
|
||||
|
||||
### **THIS SOUND DRIVER IS CURRENTLY A WIP**
|
||||
|
||||
A SID driver that's easy to make music with? It's more likely than you think.
|
||||
|
||||
* You have to have [Python](https://www.python.org/) and the [CC65 toolchain](https://cc65.github.io/) installed
|
||||
* You **have** to set the pitch linearity option to "None". You can do this by going to `window -> song -> compatability flags -> Pitch/Playback -> Pitch linearity` and then setting the option to "None".
|
||||
|
||||
* The driver only supports **arpeggio, waveform, duty and cutoff** macros in each instrument and it DOESN'T support LFO and ADSR macros nor delay and step length, **although you can use LFO macros in the duty and cutoff macros (as in range-sweeping)**
|
||||
|
||||
* The furC64 driver only supports these effects:
|
||||
* 00xx: arpeggio
|
||||
* 01xx: pitch slide up
|
||||
* 02xx: pitch slide down
|
||||
* 03xx: portamento
|
||||
* 04xx: vibrato
|
||||
* 09xx: set speed 1
|
||||
* 0Bxx: jump to pattern
|
||||
* 0Dxx: jump to next pattern
|
||||
* 0Fxx: set speed 2
|
||||
* 1Axx: disable/enable envelope reset
|
||||
* 1Bxx: reset cutoff
|
||||
* 1Cxx: reset pulse-width
|
||||
* 4xxx: set filter cutoff
|
||||
* E1xx: note slide up
|
||||
* E2xx: note slide down
|
||||
* E5xx: note fine-pitch
|
||||
* EAxx: legato
|
||||
* ECxx: note cut
|
||||
|
||||
when you've finished / want to test out this driver:
|
||||
* open the terminal/command prompt **to the furC64 directory**
|
||||
* run `convert.sh your_fur_file.fur` or `convert.bat file.fur` (depending on your OS)
|
||||
* in the `furC64/asm` directory you'll hopefully see a file called **`furC64-test.prg`**
|
||||
* that's your .prg file that you can run on hardware or on an emulator like VICE!
|
||||
|
||||
Hopefully you'll have fun with this driver alongside [furNES](https://github.com/AnnoyedArt1256/furNES) :D
|
||||
|
||||
Libraries used: chipchune
|
||||
|
||||
|
|
@ -1,16 +0,0 @@
|
|||
FEATURES {
|
||||
STARTADDRESS: default = $0801;
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", start = $0002, size = $00FE, define = yes;
|
||||
MAIN: file = "", start = %S, size = $A000 - %S;
|
||||
PLAYER: file = %O, start = $A000, size = $5FFA;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, optional = yes;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = ro, optional = yes;
|
||||
DATA: load = MAIN, type = rw, optional = yes;
|
||||
BSS: load = MAIN, type = bss, optional = yes, define = yes;
|
||||
PLAYER: load = PLAYER, type = rw, define = yes;
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
FEATURES {
|
||||
STARTADDRESS: default = $0801;
|
||||
}
|
||||
SYMBOLS {
|
||||
__LOADADDR__: type = import;
|
||||
}
|
||||
MEMORY {
|
||||
ZP: file = "", start = $0002, size = $00FE, define = yes;
|
||||
LOADADDR: file = %O, start = %S - 2, size = $0002;
|
||||
MAIN: file = %O, start = %S, size = $A000 - %S;
|
||||
PLAYER: file = %O, start = $A000, size = $5FFA;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, optional = yes;
|
||||
LOADADDR: load = LOADADDR, type = ro;
|
||||
EXEHDR: load = MAIN, type = ro, optional = yes;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = ro, optional = yes;
|
||||
DATA: load = MAIN, type = rw, optional = yes;
|
||||
BSS: load = MAIN, type = bss, optional = yes, define = yes;
|
||||
PLAYER: load = MAIN, run = PLAYER, type = rw, define = yes;
|
||||
}
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
|
||||
|
||||
"$')+.147:>AEINRW\bhnu|<7C><><EFBFBD><EFBFBD>ク皇俑褻<E4BF91>
|
||||
|
|
@ -1 +0,0 @@
|
|||
&8K^s‰¡¹Ôð
,Mq–½çBs¨àY›â,{Î'„çQÀ6³7ÄYö<59>N Ï¢<C38F>mgoˆ²í:œŸDÚÎßdÚu8&?‰´œ¿"È´ëqLh8E<7F>hÖã˜ÿ$ÿ
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
"""
|
||||
:mod:`chipchune` is a Python library for manipulating several
|
||||
different kinds of chiptune music files.
|
||||
|
||||
Currently supports:
|
||||
- Furnace (:mod:`chipchune.furnace`) (almost!)
|
||||
|
||||
Plans to support:
|
||||
- DefleMask (:mod:`chipchune.deflemask`)
|
||||
- FamiTracker (:mod:`chipchune.famitracker`)
|
||||
|
||||
### Installation
|
||||
|
||||
`pip install git+https://github.com/ZoomTen/chipchune@master`
|
||||
|
||||
"""
|
||||
|
||||
__version__ = "0.0.1"
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
import struct
|
||||
from enum import Enum
|
||||
from typing import BinaryIO, Any, cast
|
||||
import io
|
||||
|
||||
known_sizes = {
|
||||
'c': 1,
|
||||
'b': 1, 'B': 1,
|
||||
'?': 1,
|
||||
'h': 2, 'H': 2,
|
||||
'i': 4, 'I': 4,
|
||||
'l': 4, 'L': 4,
|
||||
'q': 8, 'Q': 8,
|
||||
'e': 2, 'f': 4,
|
||||
'd': 8
|
||||
}
|
||||
|
||||
|
||||
class EnumShowNameOnly(Enum):
|
||||
"""
|
||||
Just an Enum, except its string repr is
|
||||
just the enum's name
|
||||
"""
|
||||
def __repr__(self) -> str:
|
||||
return self.name
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.__repr__()
|
||||
|
||||
|
||||
class EnumValueEquals(Enum):
|
||||
"""
|
||||
Enum that can be compared to its raw value.
|
||||
"""
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
return cast(bool, self.value == other)
|
||||
|
||||
|
||||
def truthy_to_boolbyte(value: Any) -> bytes:
|
||||
"""
|
||||
If value is truthy, output b'\x01'. Else output b'\x00'.
|
||||
|
||||
:param value: anything
|
||||
"""
|
||||
if value:
|
||||
return b'\x01'
|
||||
else:
|
||||
return b'\x00'
|
||||
|
||||
|
||||
# these are just to make the typehinter happy
|
||||
# cast(dolphin, foobar) should've been named trust_me_bro_im_a(dolphin, foobar)
|
||||
|
||||
|
||||
def read_int(file: BinaryIO, signed: bool = False) -> int:
|
||||
"""
|
||||
4 bytes
|
||||
"""
|
||||
if signed:
|
||||
return cast(int, struct.unpack('<i', file.read(known_sizes['i']))[0])
|
||||
return cast(int, struct.unpack('<I', file.read(known_sizes['I']))[0])
|
||||
|
||||
|
||||
def read_short(file: BinaryIO, signed: bool = False) -> int:
|
||||
"""
|
||||
2 bytes
|
||||
"""
|
||||
if signed:
|
||||
return cast(int, struct.unpack('<h', file.read(known_sizes['h']))[0])
|
||||
return cast(int, struct.unpack('<H', file.read(known_sizes['H']))[0])
|
||||
|
||||
|
||||
def read_byte(file: BinaryIO, signed: bool = False) -> int:
|
||||
"""
|
||||
1 bytes
|
||||
"""
|
||||
if signed:
|
||||
return cast(int, struct.unpack('<b', file.read(known_sizes['b']))[0])
|
||||
return cast(int, struct.unpack('<B', file.read(known_sizes['B']))[0])
|
||||
|
||||
|
||||
def read_float(file: BinaryIO) -> float:
|
||||
"""
|
||||
4 bytes
|
||||
"""
|
||||
return cast(float, struct.unpack('<f', file.read(known_sizes['f']))[0])
|
||||
|
||||
|
||||
def read_str(file: BinaryIO) -> str:
|
||||
"""
|
||||
variable string (ends in \\x00)
|
||||
"""
|
||||
buffer = bytearray()
|
||||
char = file.read(1)
|
||||
while char != b'\x00':
|
||||
buffer += char
|
||||
char = file.read(1)
|
||||
return buffer.decode('utf-8')
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
"""
|
||||
soon!
|
||||
"""
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
"""
|
||||
soon!
|
||||
"""
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
"""
|
||||
Tools to manipulate Furnace .fur files.
|
||||
|
||||
- :mod:`chipchune.furnace.module`: Tools to inspect and manipulate module files.
|
||||
- :mod:`chipchune.furnace.instrument`: Tools to inspect and manipulate instrument data from within or without the module.
|
||||
- :mod:`chipchune.furnace.sample`: Tools to inspect and manipulate sample data (might be merged with inst?)
|
||||
- :mod:`chipchune.furnace.wavetable`: Tools to inspect and manipulate wavetable data
|
||||
- :mod:`chipchune.furnace.enums`: Various constants that apply to Furnace.
|
||||
- :mod:`chipchune.furnace.data_types`: Various data types that apply to Furnace.
|
||||
|
||||
|
||||
### Example
|
||||
|
||||
from chipchune.furnace.module import FurnaceModule
|
||||
|
||||
module = FurnaceModule("tests/samples/furnace/skate_or_die.143.fur")
|
||||
|
||||
pattern = module.get_pattern(0, 0, 0)
|
||||
|
||||
print(pattern.as_clipboard())
|
||||
|
||||
for row in pattern.data:
|
||||
print(row)
|
||||
"""
|
||||
|
|
@ -1,706 +0,0 @@
|
|||
from dataclasses import dataclass, field
|
||||
from typing import Tuple, List, TypedDict, Any, Union, Dict
|
||||
|
||||
from .enums import (
|
||||
ChipType, LinearPitch, LoopModality, DelayBehavior, JumpTreatment, InputPortSet, OutputPortSet,
|
||||
InstrumentType, MacroCode, OpMacroCode, MacroType, MacroItem, GBHwCommand, WaveFX, ESFilterMode,
|
||||
SNESSusMode, GainMode, Note
|
||||
)
|
||||
|
||||
|
||||
# modules
|
||||
@dataclass
|
||||
class ChipInfo:
|
||||
"""
|
||||
Information on a single chip.
|
||||
"""
|
||||
type: ChipType
|
||||
#: shall be a simple dict, no enums needed
|
||||
flags: Dict[str, Any] = field(default_factory=dict)
|
||||
panning: float = 0.0
|
||||
surround: float = 0.0
|
||||
"""
|
||||
Chip front/rear balance.
|
||||
"""
|
||||
volume: float = 1.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class ModuleMeta:
|
||||
"""
|
||||
Module metadata.
|
||||
"""
|
||||
name: str = ''
|
||||
name_jp: str = ''
|
||||
author: str = ''
|
||||
author_jp: str = ''
|
||||
album: str = ''
|
||||
"""
|
||||
Can also be the game name or container name.
|
||||
"""
|
||||
album_jp: str = ''
|
||||
sys_name: str = 'Sega Genesis/Mega Drive'
|
||||
sys_name_jp: str = ''
|
||||
comment: str = ''
|
||||
version: int = 0
|
||||
tuning: float = 440.0
|
||||
|
||||
|
||||
@dataclass
|
||||
class TimingInfo:
|
||||
"""
|
||||
Timing information for a single subsong.
|
||||
"""
|
||||
arp_speed = 1
|
||||
clock_speed = 60.0
|
||||
highlight: Tuple[int, int] = (4, 16)
|
||||
speed: Tuple[int, int] = (0, 0)
|
||||
timebase = 1
|
||||
virtual_tempo: Tuple[int, int] = (150, 150)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChipList:
|
||||
"""
|
||||
Information about chips used in the module.
|
||||
"""
|
||||
list: List[ChipInfo] = field(default_factory=list)
|
||||
master_volume: float = 2.0
|
||||
|
||||
|
||||
@dataclass(repr=False)
|
||||
class ChannelDisplayInfo:
|
||||
"""
|
||||
Relating to channel display in Pattern and Order windows.
|
||||
"""
|
||||
name: str = ''
|
||||
abbreviation: str = ''
|
||||
collapsed: bool = False
|
||||
shown: bool = True
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "ChannelDisplayInfo(name='%s', abbreviation='%s', collapsed=%s, shown=%s)" % (
|
||||
self.name,
|
||||
self.abbreviation,
|
||||
self.collapsed,
|
||||
self.shown
|
||||
)
|
||||
|
||||
|
||||
@dataclass
|
||||
class ModuleCompatFlags:
|
||||
"""
|
||||
Module compatibility flags, a.k.a. "The Motherload"
|
||||
|
||||
Default values correspond with fileOps.cpp in the furnace src.
|
||||
"""
|
||||
|
||||
# compat 1
|
||||
|
||||
limit_slides: bool = False
|
||||
linear_pitch: LinearPitch = field(default_factory=lambda: LinearPitch.FULL_LINEAR)
|
||||
loop_modality: LoopModality = field(default_factory=lambda: LoopModality.DO_NOTHING)
|
||||
proper_noise_layout: bool = True
|
||||
wave_duty_is_volume: bool = False
|
||||
reset_macro_on_porta: bool = False
|
||||
legacy_volume_slides: bool = False
|
||||
compatible_arpeggio: bool = False
|
||||
note_off_resets_slides: bool = True
|
||||
target_resets_slides: bool = True
|
||||
arpeggio_inhibits_portamento: bool = False
|
||||
wack_algorithm_macro: bool = False
|
||||
broken_shortcut_slides: bool = False
|
||||
ignore_duplicates_slides: bool = False
|
||||
stop_portamento_on_note_off: bool = False
|
||||
continuous_vibrato: bool = False
|
||||
broken_dac_mode: bool = False
|
||||
one_tick_cut: bool = False
|
||||
instrument_change_allowed_in_porta: bool = True
|
||||
reset_note_base_on_arpeggio_stop: bool = True
|
||||
|
||||
# compat 2 (>= dev70)
|
||||
|
||||
broken_speed_selection: bool = False
|
||||
no_slides_on_first_tick: bool = False
|
||||
next_row_reset_arp_pos: bool = False
|
||||
ignore_jump_at_end: bool = False
|
||||
buggy_portamento_after_slide: bool = False
|
||||
gb_ins_affects_env: bool = True
|
||||
shared_extch_state: bool = True
|
||||
ignore_outside_dac_mode_change: bool = False
|
||||
e1e2_takes_priority: bool = False
|
||||
new_sega_pcm: bool = True
|
||||
weird_fnum_pitch_slides: bool = False
|
||||
sn_duty_resets_phase: bool = False
|
||||
linear_pitch_macro: bool = True
|
||||
pitch_slide_speed_in_linear: int = 4
|
||||
old_octave_boundary: bool = False
|
||||
disable_opn2_dac_volume_control: bool = False
|
||||
new_volume_scaling: bool = True
|
||||
volume_macro_lingers: bool = True
|
||||
broken_out_vol: bool = False
|
||||
e1e2_stop_on_same_note: bool = False
|
||||
broken_porta_after_arp: bool = False
|
||||
sn_no_low_periods: bool = False
|
||||
cut_delay_effect_policy: DelayBehavior = field(default_factory=lambda: DelayBehavior.LAX)
|
||||
jump_treatment: JumpTreatment = field(default_factory=lambda: JumpTreatment.ALL_JUMPS)
|
||||
auto_sys_name: bool = True
|
||||
disable_sample_macro: bool = False
|
||||
broken_out_vol_2: bool = False
|
||||
old_arp_strategy: bool = False
|
||||
|
||||
# not-a-compat (>= dev135)
|
||||
|
||||
auto_patchbay: bool = True
|
||||
|
||||
# compat 3 (>= dev138)
|
||||
|
||||
broken_porta_during_legato: bool = False
|
||||
|
||||
broken_fm_off: bool = False
|
||||
pre_note_no_effect: bool = False
|
||||
old_dpcm: bool = False
|
||||
reset_arp_phase_on_new_note: bool = False
|
||||
ceil_volume_scaling: bool = False
|
||||
old_always_set_volume: bool = False
|
||||
old_sample_offset: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class SubSong:
|
||||
"""
|
||||
Information on a single subsong.
|
||||
"""
|
||||
name: str = ''
|
||||
comment: str = ''
|
||||
speed_pattern: List[int] = field(default_factory=lambda: [6])
|
||||
"""
|
||||
Maximum 16 entries.
|
||||
"""
|
||||
grooves: List[List[int]] = field(default_factory=list)
|
||||
timing: TimingInfo = field(default_factory=TimingInfo)
|
||||
pattern_length = 64
|
||||
order: Dict[int, List[int]] = field(default_factory=lambda: {
|
||||
0: [0], 1: [0], 2: [0], 3: [0], 4: [0],
|
||||
5: [0], 6: [0], 7: [0], 8: [0], 9: [0]
|
||||
})
|
||||
effect_columns: List[int] = field(default_factory=lambda: [
|
||||
1 for _ in range(
|
||||
ChipType.YM2612.channels + ChipType.SMS.channels
|
||||
)
|
||||
])
|
||||
channel_display: List[ChannelDisplayInfo] = field(default_factory=lambda: [
|
||||
ChannelDisplayInfo() for _ in range(
|
||||
ChipType.YM2612.channels + ChipType.SMS.channels
|
||||
)
|
||||
])
|
||||
|
||||
|
||||
@dataclass
|
||||
class FurnaceRow:
|
||||
"""
|
||||
Represents a single row in a pattern.
|
||||
"""
|
||||
note: Note
|
||||
octave: int
|
||||
instrument: int
|
||||
volume: int
|
||||
effects: List[Tuple[int, int]] = field(default_factory=list)
|
||||
|
||||
def as_clipboard(self) -> str:
|
||||
"""
|
||||
Renders the selected row in Furnace clipboard format (without header!)
|
||||
|
||||
:return: Furnace clipboard data (str)
|
||||
"""
|
||||
note_maps = {
|
||||
Note.Cs: "C#",
|
||||
Note.D_: "D-",
|
||||
Note.Ds: "D#",
|
||||
Note.E_: "E-",
|
||||
Note.F_: "F-",
|
||||
Note.Fs: "F#",
|
||||
Note.G_: "G-",
|
||||
Note.Gs: "G#",
|
||||
Note.A_: "A-",
|
||||
Note.As: "A#",
|
||||
Note.B_: "B-",
|
||||
Note.C_: "C-",
|
||||
}
|
||||
if self.note == Note.OFF:
|
||||
note_str = "OFF"
|
||||
elif self.note == Note.OFF_REL:
|
||||
note_str = "==="
|
||||
elif self.note == Note.REL:
|
||||
note_str = "REL"
|
||||
elif self.note == Note.__:
|
||||
note_str = "..."
|
||||
else:
|
||||
note_str = "%s%d" % (note_maps[self.note], self.octave)
|
||||
|
||||
vol = ".." if self.volume==0xffff else "%02X" % self.volume
|
||||
ins = ".." if self.instrument==0xffff else "%02X" % self.instrument
|
||||
|
||||
rep_str = "%s%s%s"
|
||||
|
||||
for fx in self.effects:
|
||||
cmd, val = fx
|
||||
cmd_str = ".." if cmd == 0xffff else "%02X" % cmd
|
||||
val_str = ".." if val == 0xffff else "%02X" % val
|
||||
rep_str += "%s%s" % (cmd_str, val_str)
|
||||
|
||||
return rep_str % (
|
||||
note_str,
|
||||
ins, vol
|
||||
) + "|"
|
||||
|
||||
def __str__(self) -> str:
|
||||
if self.note == Note.OFF:
|
||||
note_str = "OFF"
|
||||
elif self.note == Note.OFF_REL:
|
||||
note_str = "==="
|
||||
elif self.note == Note.REL:
|
||||
note_str = "///"
|
||||
elif self.note == Note.__:
|
||||
note_str = "---"
|
||||
else:
|
||||
note_str = "%s%d" % (self.note, self.octave)
|
||||
|
||||
vol = "--" if self.volume==0xffff else "%02x" % self.volume
|
||||
ins = "--" if self.instrument==0xffff else "%02x" % self.instrument
|
||||
|
||||
rep_str = "row data: %s %s %s"
|
||||
|
||||
for fx in self.effects:
|
||||
cmd, val = fx
|
||||
cmd_str = "--" if cmd == 0xffff else "%02x" % cmd
|
||||
val_str = "--" if val == 0xffff else "%02x" % val
|
||||
rep_str += " %s%s" % (cmd_str, val_str)
|
||||
|
||||
return "<" + rep_str % (
|
||||
note_str,
|
||||
ins, vol
|
||||
) + ">"
|
||||
|
||||
|
||||
@dataclass
|
||||
class FurnacePattern:
|
||||
"""
|
||||
Represents one pattern in a module.
|
||||
"""
|
||||
channel: int = 0
|
||||
index: int = 0
|
||||
subsong: int = 0
|
||||
data: List[FurnaceRow] = field(default_factory=list) # yeah...
|
||||
name: str = ""
|
||||
|
||||
def as_clipboard(self) -> str:
|
||||
"""
|
||||
Renders the selected pattern in Furnace clipboard format.
|
||||
|
||||
:return: Furnace clipboard data
|
||||
"""
|
||||
return "org.tildearrow.furnace - Pattern Data\n0\n" + "\n".join([x.as_clipboard() for x in self.data])
|
||||
|
||||
def __str__(self) -> str:
|
||||
return "<Furnace pattern %s for ch.%02d of subsong %02d>" % (
|
||||
self.name if len(self.name) > 0 else "%02x" % self.index,
|
||||
self.channel,
|
||||
self.subsong
|
||||
)
|
||||
|
||||
|
||||
class InputPatchBayEntry(TypedDict):
|
||||
"""
|
||||
A patch that has an "input" connector.
|
||||
"""
|
||||
set: InputPortSet
|
||||
"""
|
||||
The set that the patch belongs to.
|
||||
"""
|
||||
port: int
|
||||
"""
|
||||
Which port to connect to.
|
||||
"""
|
||||
|
||||
|
||||
class OutputPatchBayEntry(TypedDict):
|
||||
"""
|
||||
A patch that has an "output" connector.
|
||||
"""
|
||||
set: OutputPortSet
|
||||
"""
|
||||
The set that the patch belongs to.
|
||||
"""
|
||||
port: int
|
||||
"""
|
||||
Which port to connect from.
|
||||
"""
|
||||
|
||||
|
||||
@dataclass
|
||||
class PatchBay:
|
||||
"""
|
||||
A single patchbay connection.
|
||||
"""
|
||||
source: OutputPatchBayEntry
|
||||
dest: InputPatchBayEntry
|
||||
|
||||
|
||||
# instruments
|
||||
@dataclass
|
||||
class InsFeatureAbstract:
|
||||
"""
|
||||
Base class for all InsFeature* classes. Not really to be used.
|
||||
"""
|
||||
_code: str = field(init=False)
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
if len(self._code) != 2:
|
||||
raise ValueError('No code defined for this instrument feature')
|
||||
|
||||
# def serialize(self) -> bytes:
|
||||
# raise Exception('Method serialize() has not been overridden...')
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureName(InsFeatureAbstract, str):
|
||||
"""
|
||||
Instrument's name block. Can be used as a string.
|
||||
"""
|
||||
_code = 'NA'
|
||||
name: str = ''
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.name
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsMeta:
|
||||
version: int = 143
|
||||
type: InstrumentType = InstrumentType.FM_4OP
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFMOperator:
|
||||
am: bool = False
|
||||
ar: int = 0
|
||||
dr: int = 0
|
||||
mult: int = 0
|
||||
rr: int = 0
|
||||
sl: int = 0
|
||||
tl: int = 0
|
||||
dt2: int = 0
|
||||
rs: int = 0
|
||||
dt: int = 0
|
||||
d2r: int = 0
|
||||
ssg_env: int = 0
|
||||
dam: int = 0
|
||||
dvb: int = 0
|
||||
egt: bool = False
|
||||
ksl: int = 0
|
||||
sus: bool = False
|
||||
vib: bool = False
|
||||
ws: int = 0
|
||||
ksr: bool = False
|
||||
enable: bool = True
|
||||
kvs: int = 2
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureFM(InsFeatureAbstract):
|
||||
_code = 'FM'
|
||||
alg: int = 0
|
||||
fb: int = 4
|
||||
fms: int = 0
|
||||
ams: int = 0
|
||||
fms2: int = 0
|
||||
ams2: int = 0
|
||||
ops: int = 2
|
||||
opll_preset: int = 0
|
||||
op_list: List[InsFMOperator] = field(default_factory=lambda: [
|
||||
InsFMOperator(
|
||||
tl=42, ar=31, dr=8,
|
||||
sl=15, rr=3, mult=5,
|
||||
dt=5
|
||||
),
|
||||
InsFMOperator(
|
||||
tl=48, ar=31, dr=4,
|
||||
sl=11, rr=1, mult=1,
|
||||
dt=5
|
||||
),
|
||||
InsFMOperator(
|
||||
tl=18, ar=31, dr=10,
|
||||
sl=15, rr=4, mult=1,
|
||||
dt=0
|
||||
),
|
||||
InsFMOperator(
|
||||
tl=2, ar=31, dr=9,
|
||||
sl=15, rr=9, mult=1,
|
||||
dt=0
|
||||
),
|
||||
])
|
||||
|
||||
|
||||
@dataclass
|
||||
class SingleMacro:
|
||||
kind: Union[MacroCode, OpMacroCode] = field(default_factory=lambda: MacroCode.VOL)
|
||||
mode: int = 0
|
||||
type: MacroType = field(default_factory=lambda: MacroType.SEQUENCE)
|
||||
delay: int = 0
|
||||
speed: int = 1
|
||||
open: bool = False
|
||||
data: List[Union[int, MacroItem]] = field(default_factory=list)
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureMacro(InsFeatureAbstract):
|
||||
_code = 'MA'
|
||||
macros: List[SingleMacro] = field(default_factory=lambda: [SingleMacro()])
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureOpr1Macro(InsFeatureMacro):
|
||||
_code = 'O1'
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureOpr2Macro(InsFeatureMacro):
|
||||
_code = 'O2'
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureOpr3Macro(InsFeatureMacro):
|
||||
_code = 'O3'
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureOpr4Macro(InsFeatureMacro):
|
||||
_code = 'O4'
|
||||
|
||||
|
||||
@dataclass
|
||||
class GBHwSeq:
|
||||
command: GBHwCommand
|
||||
data: List[int] = field(default_factory=lambda: [0, 0])
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureGB(InsFeatureAbstract):
|
||||
_code = 'GB'
|
||||
env_vol: int = 15
|
||||
env_dir: int = 0
|
||||
env_len: int = 2
|
||||
sound_len: int = 0
|
||||
soft_env: bool = False
|
||||
always_init: bool = False
|
||||
hw_seq: List[GBHwSeq] = field(default_factory=list)
|
||||
|
||||
|
||||
@dataclass
|
||||
class GenericADSR:
|
||||
a: int = 0
|
||||
d: int = 0
|
||||
s: int = 0
|
||||
r: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureC64(InsFeatureAbstract):
|
||||
_code = '64'
|
||||
tri_on: bool = False
|
||||
saw_on: bool = True
|
||||
pulse_on: bool = False
|
||||
noise_on: bool = False
|
||||
envelope: GenericADSR = field(default_factory=lambda: GenericADSR(a=0, d=8, s=0, r=0))
|
||||
duty: int = 2048
|
||||
ring_mod: int = 0
|
||||
osc_sync: int = 0
|
||||
to_filter: bool = False
|
||||
vol_is_cutoff: bool = False
|
||||
init_filter: bool = False
|
||||
duty_is_abs: bool = False
|
||||
filter_is_abs: bool = False
|
||||
no_test: bool = False
|
||||
res: int = 0
|
||||
cut: int = 0
|
||||
hp: bool = False
|
||||
lp: bool = False
|
||||
bp: bool = False
|
||||
ch3_off: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class SampleMap:
|
||||
freq: int = 0
|
||||
sample_index: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class DPCMMap:
|
||||
pitch: int = 0
|
||||
delta: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureAmiga(InsFeatureAbstract): # Sample data
|
||||
_code = 'SM'
|
||||
init_sample: int = 0
|
||||
use_note_map: bool = False
|
||||
use_sample: bool = False
|
||||
use_wave: bool = False
|
||||
wave_len: int = 31
|
||||
sample_map: List[SampleMap] = field(default_factory=lambda: [SampleMap() for _ in range(120)])
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureDPCMMap(InsFeatureAbstract): # DPCM sample data
|
||||
_code = 'NE'
|
||||
use_map: bool = False
|
||||
sample_map: List[DPCMMap] = field(default_factory=lambda: [SampleMap() for _ in range(120)])
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureX1010(InsFeatureAbstract):
|
||||
_code = 'X1'
|
||||
bank_slot: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeaturePowerNoise(InsFeatureAbstract):
|
||||
_code = 'PN'
|
||||
octave: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureSID2(InsFeatureAbstract):
|
||||
_code = 'S2'
|
||||
noise_mode: int = 0
|
||||
wave_mix: int = 0
|
||||
volume: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureN163(InsFeatureAbstract):
|
||||
_code = 'N1'
|
||||
wave: int = -1
|
||||
wave_pos: int = 0
|
||||
wave_len: int = 32
|
||||
wave_mode: int = 3
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureFDS(InsFeatureAbstract): # Virtual Boy
|
||||
_code = 'FD'
|
||||
mod_speed: int = 0
|
||||
mod_depth: int = 0
|
||||
init_table_with_first_wave: bool = False # compat
|
||||
mod_table: List[int] = field(default_factory=lambda: [0 for i in range(32)])
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureMultiPCM(InsFeatureAbstract):
|
||||
_code = 'MP'
|
||||
ar: int = 15
|
||||
d1r: int = 15
|
||||
dl: int = 0
|
||||
d2r: int = 0
|
||||
rr: int = 15
|
||||
rc: int = 15
|
||||
lfo: int = 0
|
||||
vib: int = 0
|
||||
am: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureWaveSynth(InsFeatureAbstract):
|
||||
_code = 'WS'
|
||||
wave_indices: List[int] = field(default_factory=lambda: [0, 0])
|
||||
rate_divider: int = 1
|
||||
effect: WaveFX = WaveFX.NONE
|
||||
enabled: bool = False
|
||||
global_effect: bool = False
|
||||
speed: int = 0
|
||||
params: List[int] = field(default_factory=lambda: [0, 0, 0, 0])
|
||||
one_shot: bool = False # not read?
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureSoundUnit(InsFeatureAbstract):
|
||||
_code = 'SU'
|
||||
switch_roles: bool = False
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureES5506(InsFeatureAbstract):
|
||||
_code = 'ES'
|
||||
filter_mode: ESFilterMode = ESFilterMode.LPK2_LPK1
|
||||
k1: int = 0xffff
|
||||
k2: int = 0xffff
|
||||
env_count: int = 0
|
||||
left_volume_ramp: int = 0
|
||||
right_volume_ramp: int = 0
|
||||
k1_ramp: int = 0
|
||||
k2_ramp: int = 0
|
||||
k1_slow: int = 0
|
||||
k2_slow: int = 0
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureSNES(InsFeatureAbstract):
|
||||
_code = 'SN'
|
||||
use_env: bool = True
|
||||
sus: SNESSusMode = SNESSusMode.DIRECT
|
||||
gain_mode: GainMode = GainMode.DIRECT
|
||||
gain: int = 127
|
||||
d2: int = 0
|
||||
envelope: GenericADSR = field(default_factory=lambda: GenericADSR(a=15, d=7, s=7, r=0))
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureOPLDrums(InsFeatureAbstract):
|
||||
_code = 'LD'
|
||||
fixed_drums: bool = False
|
||||
kick_freq: int = 1312
|
||||
snare_hat_freq: int = 1360
|
||||
tom_top_freq: int = 448
|
||||
|
||||
|
||||
@dataclass
|
||||
class _InsFeaturePointerAbstract(InsFeatureAbstract):
|
||||
"""
|
||||
Also not really to be used. Container for all "list" features.
|
||||
"""
|
||||
_code = 'LL'
|
||||
pointers: Dict[int, int] = field(default_factory=dict)
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureSampleList(_InsFeaturePointerAbstract):
|
||||
"""
|
||||
List of pointers to all samples used by this instrument.
|
||||
"""
|
||||
_code = 'SL'
|
||||
|
||||
|
||||
@dataclass
|
||||
class InsFeatureWaveList(_InsFeaturePointerAbstract):
|
||||
"""
|
||||
List of pointers to all wave tables used by this instrument.
|
||||
"""
|
||||
_code = 'WL'
|
||||
|
||||
@dataclass
|
||||
class WavetableMeta:
|
||||
name: str = ''
|
||||
width: int = 32
|
||||
height: int = 32
|
||||
|
||||
@dataclass
|
||||
class SampleMeta:
|
||||
name: str = ''
|
||||
length: int = 0
|
||||
sample_rate: int = 0
|
||||
bitdepth: int = 0
|
||||
loop_start: int = 0
|
||||
loop_end: int = 0
|
||||
|
|
@ -1,648 +0,0 @@
|
|||
from chipchune._util import EnumShowNameOnly, EnumValueEquals
|
||||
from typing import Tuple
|
||||
|
||||
class LinearPitch(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.linear_pitch`.
|
||||
"""
|
||||
NON_LINEAR = 0
|
||||
ONLY_PITCH_CHANGE = 1
|
||||
FULL_LINEAR = 2
|
||||
|
||||
|
||||
class LoopModality(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.loop_modality`.
|
||||
"""
|
||||
HARD_RESET_CHANNELS = 0
|
||||
SOFT_RESET_CHANNELS = 1
|
||||
DO_NOTHING = 2
|
||||
|
||||
|
||||
class DelayBehavior(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.cut_delay_effect_policy`.
|
||||
"""
|
||||
STRICT = 0
|
||||
BROKEN = 1
|
||||
LAX = 2
|
||||
|
||||
|
||||
class JumpTreatment(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Options for :attr:`chipchune.furnace.data_types.ModuleCompatFlags.jump_treatment`.
|
||||
"""
|
||||
ALL_JUMPS = 0
|
||||
FIRST_JUMP_ONLY = 1
|
||||
ROW_JUMP_PRIORITY = 2
|
||||
|
||||
|
||||
class Note(EnumShowNameOnly):
|
||||
"""
|
||||
All notes recognized by Furnace
|
||||
"""
|
||||
__ = 0
|
||||
Cs = 1
|
||||
D_ = 2
|
||||
Ds = 3
|
||||
E_ = 4
|
||||
F_ = 5
|
||||
Fs = 6
|
||||
G_ = 7
|
||||
Gs = 8
|
||||
A_ = 9
|
||||
As = 10
|
||||
B_ = 11
|
||||
C_ = 12
|
||||
OFF = 100
|
||||
OFF_REL = 101
|
||||
REL = 102
|
||||
|
||||
|
||||
class MacroItem(EnumShowNameOnly):
|
||||
"""
|
||||
Special values used only in this parser, to allow data editing similar to that
|
||||
of Furnace itself.
|
||||
"""
|
||||
LOOP = 0
|
||||
RELEASE = 1
|
||||
|
||||
|
||||
class MacroCode(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Marks what aspect of an instrument does a macro change.
|
||||
"""
|
||||
|
||||
VOL = 0
|
||||
"""
|
||||
Also:
|
||||
- C64 cutoff
|
||||
"""
|
||||
|
||||
ARP = 1
|
||||
"""
|
||||
Not applicable to MSM6258 and MSM6295.
|
||||
"""
|
||||
|
||||
DUTY = 2
|
||||
"""
|
||||
Also:
|
||||
- AY noise freq
|
||||
- POKEY audctl
|
||||
- Mikey duty/int
|
||||
- MSM5232 group ctrl
|
||||
- Beeper/Pokemon Mini pulse width
|
||||
- T6W28 noise type
|
||||
- Virtual Boy noise length
|
||||
- PC Engine/Namco/WonderSwan noise type
|
||||
- SNES noise freq
|
||||
- Namco 163 waveform pos.
|
||||
- ES5506 filter mode
|
||||
- MSM6258/MSM6295 freq. divider
|
||||
- ADPCMA global volume
|
||||
- QSound echo level
|
||||
"""
|
||||
|
||||
WAVE = 3
|
||||
"""
|
||||
Also:
|
||||
- OPLL patch
|
||||
- OPZ/OPM lfo1 shape
|
||||
"""
|
||||
|
||||
PITCH = 4
|
||||
|
||||
EX1 = 5
|
||||
"""
|
||||
- OPZ/OPM am depth
|
||||
- C64 filter mode
|
||||
- SAA1099 envelope
|
||||
- X1-010 env. mode
|
||||
- Namco 163 wave length
|
||||
- FDS mod depth
|
||||
- TSU cutoff
|
||||
- ES5506 filter k1
|
||||
- MSM6258 clk divider
|
||||
- QSound echo feedback
|
||||
- SNES special
|
||||
- MSM5232 group attack
|
||||
- AY8930 duty?
|
||||
"""
|
||||
|
||||
EX2 = 6
|
||||
"""
|
||||
- C64 resonance
|
||||
- Namco 163 wave update
|
||||
- FDS mod speed
|
||||
- TSU resonance
|
||||
- ES5506 filter k2
|
||||
- QSound echo length
|
||||
- SNES gain
|
||||
- MSM5232 group decay
|
||||
- AY3/AY8930 envelope
|
||||
"""
|
||||
|
||||
EX3 = 7
|
||||
"""
|
||||
- C64 special
|
||||
- AY/AY8930 autoenv num
|
||||
- X1-010 autoenv num
|
||||
- Namco 163 waveload wave
|
||||
- FDS mod position
|
||||
- TSU control
|
||||
- MSM5232 noise
|
||||
"""
|
||||
|
||||
ALG = 8
|
||||
"""
|
||||
Also:
|
||||
- AY/AY8930 autoenv den
|
||||
- X1-010 autoenv den
|
||||
- Namco 163 waveload pos
|
||||
- ES5506 control
|
||||
"""
|
||||
|
||||
FB = 9
|
||||
"""
|
||||
Also:
|
||||
- AY8930 noise & mask
|
||||
- Namco 163 waveload len
|
||||
- ES5506 outputs
|
||||
"""
|
||||
|
||||
FMS = 10
|
||||
"""
|
||||
Also:
|
||||
- AY8930 noise | mask
|
||||
- Namco 163 waveload trigger
|
||||
"""
|
||||
|
||||
AMS = 11
|
||||
|
||||
PAN_L = 12
|
||||
|
||||
PAN_R = 13
|
||||
|
||||
PHASE_RESET = 14
|
||||
|
||||
EX4 = 15
|
||||
"""
|
||||
- C64 test/gate
|
||||
- TSU phase reset timer
|
||||
- FM/OPM opmask
|
||||
"""
|
||||
|
||||
EX5 = 16
|
||||
"""
|
||||
- OPZ am depth 2
|
||||
"""
|
||||
|
||||
EX6 = 17
|
||||
"""
|
||||
- OPZ pm depth 2
|
||||
"""
|
||||
|
||||
EX7 = 18
|
||||
"""
|
||||
- OPZ lfo2 speed
|
||||
"""
|
||||
|
||||
EX8 = 19
|
||||
"""
|
||||
- OPZ lfo2 shape
|
||||
"""
|
||||
|
||||
STOP = 255
|
||||
"""
|
||||
Marks end of macro reading.
|
||||
"""
|
||||
|
||||
|
||||
class OpMacroCode(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Controls which FM parameter a macro should change.
|
||||
"""
|
||||
AM = 0
|
||||
AR = 1
|
||||
DR = 2
|
||||
MULT = 3
|
||||
RR = 4
|
||||
SL = 5
|
||||
TL = 6
|
||||
DT2 = 7
|
||||
RS = 8
|
||||
DT = 9
|
||||
D2R = 10
|
||||
SSG_EG = 11
|
||||
DAM = 12
|
||||
DVB = 13
|
||||
EGT = 14
|
||||
KSL = 15
|
||||
SUS = 16
|
||||
VIB = 17
|
||||
WS = 18
|
||||
KSR = 19
|
||||
|
||||
|
||||
class MacroType(EnumShowNameOnly):
|
||||
"""
|
||||
Instrument macro type (version 120+).
|
||||
"""
|
||||
SEQUENCE = 0
|
||||
ADSR = 1
|
||||
LFO = 2
|
||||
|
||||
|
||||
class MacroSize(EnumShowNameOnly):
|
||||
"""
|
||||
Type of value stored in the instrument file.
|
||||
"""
|
||||
_value_: int
|
||||
num_bytes: int
|
||||
signed: bool
|
||||
|
||||
UINT8: Tuple[int, int, bool] = (0, 1, False)
|
||||
INT8: Tuple[int, int, bool] = (1, 1, True)
|
||||
INT16: Tuple[int, int, bool] = (2, 2, True)
|
||||
INT32: Tuple[int, int, bool] = (3, 4, True)
|
||||
|
||||
def __new__(cls, id: int, num_bytes: int, signed: bool): # type: ignore[no-untyped-def]
|
||||
member = object.__new__(cls)
|
||||
member._value_ = id
|
||||
setattr(member, 'num_bytes', num_bytes)
|
||||
setattr(member, 'signed', signed)
|
||||
return member
|
||||
|
||||
|
||||
class GBHwCommand(EnumShowNameOnly):
|
||||
"""
|
||||
Game Boy hardware envelope commands.
|
||||
"""
|
||||
ENVELOPE = 0
|
||||
SWEEP = 1
|
||||
WAIT = 2
|
||||
WAIT_REL = 3
|
||||
LOOP = 4
|
||||
LOOP_REL = 5
|
||||
|
||||
|
||||
class SampleType(EnumShowNameOnly):
|
||||
"""
|
||||
Sample types used in Furnace
|
||||
"""
|
||||
ZX_DRUM = 0
|
||||
NES_DPCM = 1
|
||||
QSOUND_ADPCM = 4
|
||||
ADPCM_A = 5
|
||||
ADPCM_B = 6
|
||||
X68K_ADPCM = 7
|
||||
PCM_8 = 8
|
||||
SNES_BRR = 9
|
||||
VOX = 10
|
||||
PCM_16 = 16
|
||||
|
||||
|
||||
class InstrumentType(EnumShowNameOnly):
|
||||
"""
|
||||
Instrument types currently available as of version 144.
|
||||
"""
|
||||
STANDARD = 0
|
||||
FM_4OP = 1
|
||||
GB = 2
|
||||
C64 = 3
|
||||
AMIGA = 4
|
||||
PCE = 5
|
||||
SSG = 6
|
||||
AY8930 = 7
|
||||
TIA = 8
|
||||
SAA1099 = 9
|
||||
VIC = 10
|
||||
PET = 11
|
||||
VRC6 = 12
|
||||
FM_OPLL = 13
|
||||
FM_OPL = 14
|
||||
FDS = 15
|
||||
VB = 16
|
||||
N163 = 17
|
||||
KONAMI_SCC = 18
|
||||
FM_OPZ = 19
|
||||
POKEY = 20
|
||||
PC_BEEPER = 21
|
||||
WONDERSWAN = 22
|
||||
LYNX = 23
|
||||
VERA = 24
|
||||
X1010 = 25
|
||||
VRC6_SAW = 26
|
||||
ES5506 = 27
|
||||
MULTIPCM = 28
|
||||
SNES = 29
|
||||
TSU = 30
|
||||
NAMCO_WSG = 31
|
||||
OPL_DRUMS = 32
|
||||
FM_OPM = 33
|
||||
NES = 34
|
||||
MSM6258 = 35
|
||||
MSM6295 = 36
|
||||
ADPCM_A = 37
|
||||
ADPCM_B = 38
|
||||
SEGAPCM = 39
|
||||
QSOUND = 40
|
||||
YMZ280B = 41
|
||||
RF5C68 = 42
|
||||
MSM5232 = 43
|
||||
T6W28 = 44
|
||||
K007232 = 45
|
||||
GA20 = 46
|
||||
POKEMON_MINI = 47
|
||||
SM8521 = 48
|
||||
PV1000 = 49
|
||||
|
||||
|
||||
class ChipType(EnumShowNameOnly):
|
||||
"""
|
||||
Furnace chip database, either planned or implemented.
|
||||
Contains console name, chip ID and number of channels.
|
||||
"""
|
||||
_value_: int
|
||||
channels: int
|
||||
|
||||
YMU759 = (0x01, 17)
|
||||
GENESIS = (0x02, 10) # YM2612 + SN76489
|
||||
SMS = (0x03, 4) # SN76489
|
||||
GB = (0x04, 4) # LR53902
|
||||
PCE = (0x05, 6) # HuC6280
|
||||
NES = (0x06, 5) # RP2A03
|
||||
C64_8580 = (0x07, 3) # SID r8580
|
||||
SEGA_ARCADE = (0x08, 13) # YM2151 + SegaPCM
|
||||
NEO_GEO_CD = (0x09, 13)
|
||||
|
||||
GENESIS_EX = (0x42, 13) # YM2612 + SN76489
|
||||
SMS_JP = (0x43, 13) # SN76489 + YM2413
|
||||
NES_VRC7 = (0x46, 11) # RP2A03 + YM2413
|
||||
C64_6581 = (0x47, 3) # SID r6581
|
||||
NEO_GEO_CD_EX = (0x49, 16)
|
||||
|
||||
AY38910 = (0x80, 3)
|
||||
AMIGA = (0x81, 4) # Paula
|
||||
YM2151 = (0x82, 8) # YM2151
|
||||
YM2612 = (0x83, 6) # YM2612
|
||||
TIA = (0x84, 2)
|
||||
VIC20 = (0x85, 4)
|
||||
PET = (0x86, 1)
|
||||
SNES = (0x87, 8) # SPC700
|
||||
VRC6 = (0x88, 3)
|
||||
OPLL = (0x89, 9) # YM2413
|
||||
FDS = (0x8a, 1)
|
||||
MMC5 = (0x8b, 3)
|
||||
N163 = (0x8c, 8)
|
||||
OPN = (0x8d, 6) # YM2203
|
||||
PC98 = (0x8e, 16) # YM2608
|
||||
OPL = (0x8f, 9) # YM3526
|
||||
|
||||
OPL2 = (0x90, 9) # YM3812
|
||||
OPL3 = (0x91, 18) # YMF262
|
||||
MULTIPCM = (0x92, 24)
|
||||
PC_SPEAKER = (0x93, 1) # Intel 8253
|
||||
POKEY = (0x94, 4)
|
||||
RF5C68 = (0x95, 8)
|
||||
WONDERSWAN = (0x96, 4)
|
||||
SAA1099 = (0x97, 6)
|
||||
OPZ = (0x98, 8)
|
||||
POKEMON_MINI = (0x99, 1)
|
||||
AY8930 = (0x9a, 3)
|
||||
SEGAPCM = (0x9b, 16)
|
||||
VIRTUAL_BOY = (0x9c, 6)
|
||||
VRC7 = (0x9d, 6)
|
||||
YM2610B = (0x9e, 16)
|
||||
ZX_BEEPER = (0x9f, 6) # tildearrow's engine
|
||||
|
||||
YM2612_EX = (0xa0, 9)
|
||||
SCC = (0xa1, 5)
|
||||
OPL_DRUMS = (0xa2, 11)
|
||||
OPL2_DRUMS = (0xa3, 11)
|
||||
OPL3_DRUMS = (0xa4, 20)
|
||||
NEO_GEO = (0xa5, 14)
|
||||
NEO_GEO_EX = (0xa6, 17)
|
||||
OPLL_DRUMS = (0xa7, 11)
|
||||
LYNX = (0xa8, 4)
|
||||
SEGAPCM_DMF = (0xa9, 5)
|
||||
MSM6295 = (0xaa, 4)
|
||||
MSM6258 = (0xab, 1)
|
||||
COMMANDER_X16 = (0xac, 17) # VERA
|
||||
BUBBLE_SYSTEM_WSG = (0xad, 2)
|
||||
OPL4 = (0xae, 42)
|
||||
OPL4_DRUMS = (0xaf, 44)
|
||||
|
||||
SETA = (0xb0, 16) # Allumer X1-010
|
||||
ES5506 = (0xb1, 32)
|
||||
Y8950 = (0xb2, 10)
|
||||
Y8950_DRUMS = (0xb3, 12)
|
||||
SCC_PLUS = (0xb4, 5)
|
||||
TSU = (0xb5, 8)
|
||||
YM2203_EX = (0xb6, 9)
|
||||
YM2608_EX = (0xb7, 19)
|
||||
YMZ280B = (0xb8, 8)
|
||||
NAMCO = (0xb9, 3) # Namco WSG
|
||||
N15XX = (0xba, 8) # Namco 15xx
|
||||
CUS30 = (0xbb, 8) # Namco CUS30
|
||||
MSM5232 = (0xbc, 8)
|
||||
YM2612_PLUS_EX = (0xbd, 11)
|
||||
YM2612_PLUS = (0xbe, 7)
|
||||
T6W28 = (0xbf, 4)
|
||||
|
||||
PCM_DAC = (0xc0, 1)
|
||||
YM2612_CSM = (0xc1, 10)
|
||||
NEO_GEO_CSM = (0xc2, 18) # YM2610 CSM
|
||||
YM2203_CSM = (0xc3, 10)
|
||||
YM2608_CSM = (0xc4, 20)
|
||||
YM2610B_CSM = (0xc5, 20)
|
||||
K007232 = (0xc6, 2)
|
||||
GA20 = (0xc7, 4)
|
||||
SM8521 = (0xc8, 3)
|
||||
M114S = (0xc9, 16)
|
||||
ZX_BEEPER_QUADTONE: Tuple[int, int] = (0xca, 5) # Natt Akuma's engine
|
||||
PV_1000: Tuple[int, int] = (0xcb, 3) # NEC D65010G031
|
||||
K053260 = (0xcc, 4)
|
||||
TED = (0xcd, 2)
|
||||
NAMCO_C140 = (0xce, 24)
|
||||
NAMCO_C219 = (0xcf, 16)
|
||||
|
||||
NAMCO_C352 = (0xd0, 32)
|
||||
ESFM = (0xd1, 18)
|
||||
ES5503 = (0xd2, 32)
|
||||
POWERNOISE = (0xd4, 4)
|
||||
DAVE = (0xd5, 6)
|
||||
NDS = (0xd6, 16)
|
||||
GBA = (0xd7, 2)
|
||||
GBA_MINMOD = (0xd8, 16)
|
||||
BIFURCATOR = (0xd9, 4)
|
||||
YM2610B_EX = (0xde, 19)
|
||||
|
||||
QSOUND = (0xe0, 19)
|
||||
|
||||
SID2 = (0xf0, 3) # SID2
|
||||
FIVEE01 = (0xf1, 5) # 5E01
|
||||
PONG = (0xfc, 1)
|
||||
DUMMY = (0xfd, 1)
|
||||
|
||||
RESERVED_1 = (0xfe, 1)
|
||||
RESERVED_2 = (0xff, 1)
|
||||
|
||||
def __new__(cls, id: int, channels: int): # type: ignore[no-untyped-def]
|
||||
member = object.__new__(cls)
|
||||
member._value_ = id
|
||||
setattr(member, 'channels', channels)
|
||||
return member
|
||||
|
||||
def __repr__(self) -> str:
|
||||
# repr abuse
|
||||
# about as stupid as "mapping for the renderer"...
|
||||
return "%s (0x%02x), %d channel%s" % (
|
||||
self.name, self._value_, self.channels,
|
||||
"s" if self.channels != 1 else ""
|
||||
)
|
||||
|
||||
|
||||
class InputPortSet(EnumShowNameOnly):
|
||||
"""
|
||||
Devices which contain an "input" port.
|
||||
"""
|
||||
SYSTEM = 0
|
||||
NULL = 0xFFF
|
||||
|
||||
|
||||
class OutputPortSet(EnumShowNameOnly):
|
||||
"""
|
||||
Devices which contain an "output" port.
|
||||
"""
|
||||
CHIP_1 = 0
|
||||
CHIP_2 = 1
|
||||
CHIP_3 = 2
|
||||
CHIP_4 = 3
|
||||
CHIP_5 = 4
|
||||
CHIP_6 = 5
|
||||
CHIP_7 = 6
|
||||
CHIP_8 = 7
|
||||
CHIP_9 = 8
|
||||
CHIP_10 = 9
|
||||
CHIP_11 = 10
|
||||
CHIP_12 = 11
|
||||
CHIP_13 = 12
|
||||
CHIP_14 = 13
|
||||
CHIP_15 = 14
|
||||
CHIP_16 = 15
|
||||
CHIP_17 = 16
|
||||
CHIP_18 = 17
|
||||
CHIP_19 = 18
|
||||
CHIP_20 = 19
|
||||
CHIP_21 = 20
|
||||
CHIP_22 = 21
|
||||
CHIP_23 = 22
|
||||
CHIP_24 = 23
|
||||
CHIP_25 = 24
|
||||
CHIP_26 = 25
|
||||
CHIP_27 = 26
|
||||
CHIP_28 = 27
|
||||
CHIP_29 = 28
|
||||
CHIP_30 = 29
|
||||
CHIP_31 = 30
|
||||
CHIP_32 = 31
|
||||
PREVIEW = 0xFFD
|
||||
METRONOME = 0xFFE
|
||||
NULL = 0xFFF
|
||||
|
||||
|
||||
class WaveFX(EnumShowNameOnly):
|
||||
"""
|
||||
Used in :attr:`chipchune.furnace.data_types.InsFeatureWaveSynth.effect`.
|
||||
"""
|
||||
NONE = 0
|
||||
|
||||
# single waveform
|
||||
INVERT = 1
|
||||
ADD = 2
|
||||
SUBTRACT = 3
|
||||
AVERAGE = 4
|
||||
PHASE = 5
|
||||
CHORUS = 6
|
||||
|
||||
# double waveform
|
||||
NONE_DUAL = 128
|
||||
WIPE = 129
|
||||
FADE = 130
|
||||
PING_PONG = 131
|
||||
OVERLAY = 132
|
||||
NEGATIVE_OVERLAY = 133
|
||||
SLIDE = 134
|
||||
MIX = 135
|
||||
PHASE_MOD = 136
|
||||
|
||||
|
||||
class ESFilterMode(EnumShowNameOnly):
|
||||
"""
|
||||
Used in :attr:`chipchune.furnace.data_types.InsFeatureES5506.filter_mode`.
|
||||
"""
|
||||
HPK2_HPK2 = 0
|
||||
HPK2_LPK1 = 1
|
||||
LPK2_LPK2 = 2
|
||||
LPK2_LPK1 = 3
|
||||
|
||||
|
||||
class GainMode(EnumShowNameOnly):
|
||||
"""
|
||||
Used in :attr:`chipchune.furnace.data_types.InsFeatureSNES.gain_mode`.
|
||||
"""
|
||||
DIRECT = 0
|
||||
DEC_LINEAR = 4
|
||||
DEC_LOG = 5
|
||||
INC_LINEAR = 6
|
||||
INC_INVLOG = 7
|
||||
|
||||
|
||||
class SNESSusMode(EnumShowNameOnly):
|
||||
"""
|
||||
Used in :attr:`chipchune.furnace.data_types.InsFeatureSNES.sus`.
|
||||
"""
|
||||
DIRECT = 0
|
||||
SUS_WITH_DEC = 1
|
||||
SUS_WITH_EXP = 2
|
||||
SUS_WITH_REL = 3
|
||||
|
||||
|
||||
class _FurInsImportType(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Also only used in this parser to differentiate between different types of instrument formats.
|
||||
"""
|
||||
# Old format
|
||||
FORMAT_0_FILE = 0
|
||||
FORMAT_0_EMBED = 1
|
||||
|
||||
# Dev127 format
|
||||
FORMAT_1_FILE = 2
|
||||
FORMAT_1_EMBED = 3
|
||||
|
||||
class _FurWavetableImportType(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Also only used in this parser to differentiate between different types of wavetable formats.
|
||||
"""
|
||||
FILE = 0
|
||||
EMBED = 1
|
||||
|
||||
class _FurSampleType(EnumShowNameOnly, EnumValueEquals):
|
||||
"""
|
||||
Also only used in this parser to differentiate between different types of sample formats.
|
||||
"""
|
||||
PCM_1_BIT = 0
|
||||
DPCM = 1
|
||||
YMZ = 3
|
||||
QSOUND = 4
|
||||
ADPCM_A = 5
|
||||
ADPCM_B = 6
|
||||
K05_ADPCM = 7
|
||||
PCM_8_BIT = 8
|
||||
BRR = 9
|
||||
VOX = 10
|
||||
ULAW = 11
|
||||
C219 = 12
|
||||
IMA = 13
|
||||
PCM_16_BIT = 16
|
||||
|
|
@ -1,47 +0,0 @@
|
|||
from io import BytesIO
|
||||
from typing import Optional, Union, BinaryIO, List
|
||||
|
||||
from chipchune._util import read_short, read_int, read_str
|
||||
from .data_types import SampleMeta
|
||||
from .enums import _FurSampleType
|
||||
|
||||
FILE_MAGIC_STR = b'SMP2'
|
||||
|
||||
|
||||
class FurnaceSample:
|
||||
def __init__(self) -> None:
|
||||
self.meta: SampleMeta = SampleMeta()
|
||||
"""
|
||||
Sample metadata.
|
||||
"""
|
||||
self.data: bytearray = b''
|
||||
"""
|
||||
Sample data.
|
||||
"""
|
||||
|
||||
def load_from_stream(self, stream: BinaryIO) -> None:
|
||||
"""
|
||||
Load a sample from an **uncompressed** stream.
|
||||
|
||||
:param stream: File-like object containing the uncompressed wavetable.
|
||||
"""
|
||||
if stream.read(len(FILE_MAGIC_STR)) != FILE_MAGIC_STR:
|
||||
raise ValueError('Bad magic value for a wavetable file')
|
||||
blk_size = read_int(stream)
|
||||
if blk_size > 0:
|
||||
smp_data = BytesIO(stream.read(blk_size))
|
||||
else:
|
||||
smp_data = stream
|
||||
|
||||
self.meta.name = read_str(smp_data)
|
||||
self.meta.length = read_int(smp_data)
|
||||
read_int(smp_data) # compatablity rate
|
||||
self.meta.sample_rate = read_int(smp_data)
|
||||
self.meta.depth = int(smp_data.read(1)[0])
|
||||
smp_data.read(1) # loop direction
|
||||
smp_data.read(1) # flags
|
||||
smp_data.read(1) # flags 2
|
||||
self.meta.loop_start = read_int(smp_data)
|
||||
self.meta.loop_end = read_int(smp_data)
|
||||
smp_data.read(16) # sample presence bitfields
|
||||
self.data = smp_data.read(self.meta.length)
|
||||
|
|
@ -1,101 +0,0 @@
|
|||
from io import BytesIO
|
||||
from typing import Optional, Union, BinaryIO, List
|
||||
|
||||
from chipchune._util import read_short, read_int, read_str
|
||||
from .data_types import WavetableMeta
|
||||
from .enums import _FurWavetableImportType
|
||||
|
||||
FILE_MAGIC_STR = b'-Furnace waveta-'
|
||||
EMBED_MAGIC_STR = b'WAVE'
|
||||
|
||||
|
||||
class FurnaceWavetable:
|
||||
def __init__(self, file_name: Optional[str] = None) -> None:
|
||||
"""
|
||||
Creates or opens a new Furnace wavetable as a Python object.
|
||||
|
||||
:param file_name: (Optional)
|
||||
If specified, then it will parse a file as a FurnaceWavetable. If file name (str) is
|
||||
given, it will load that file.
|
||||
|
||||
Defaults to None.
|
||||
"""
|
||||
self.file_name: Optional[str] = None
|
||||
"""
|
||||
Original file name, if the object was initialized with one.
|
||||
"""
|
||||
self.meta: WavetableMeta = WavetableMeta()
|
||||
"""
|
||||
Wavetable metadata.
|
||||
"""
|
||||
self.data: List[int] = []
|
||||
"""
|
||||
Wavetable data.
|
||||
"""
|
||||
|
||||
if isinstance(file_name, str):
|
||||
self.load_from_file(file_name)
|
||||
|
||||
def load_from_file(self, file_name: Optional[str] = None) -> None:
|
||||
if isinstance(file_name, str):
|
||||
self.file_name = file_name
|
||||
if self.file_name is None:
|
||||
raise RuntimeError('No file name set, either set self.file_name or pass file_name to the function')
|
||||
|
||||
# since we're loading from an uncompressed file, we can just check the file magic number
|
||||
with open(self.file_name, 'rb') as f:
|
||||
detect_magic = f.peek(len(FILE_MAGIC_STR))[:len(FILE_MAGIC_STR)]
|
||||
if detect_magic == FILE_MAGIC_STR:
|
||||
return self.load_from_stream(f, _FurWavetableImportType.FILE)
|
||||
else: # uncompressed for sure
|
||||
raise ValueError('No recognized file type magic')
|
||||
|
||||
def load_from_bytes(self, data: bytes, import_as: Union[int, _FurWavetableImportType]) -> None:
|
||||
"""
|
||||
Load a wavetable from a series of bytes.
|
||||
|
||||
:param data: Bytes
|
||||
"""
|
||||
return self.load_from_stream(
|
||||
BytesIO(data),
|
||||
import_as
|
||||
)
|
||||
|
||||
def load_from_stream(self, stream: BinaryIO, import_as: Union[int, _FurWavetableImportType]) -> None:
|
||||
"""
|
||||
Load a wavetable from an **uncompressed** stream.
|
||||
|
||||
:param stream: File-like object containing the uncompressed wavetable.
|
||||
:param import_as: int
|
||||
- 0 = wavetable file
|
||||
- 1 = wavetable embedded in module
|
||||
"""
|
||||
if import_as == _FurWavetableImportType.FILE:
|
||||
if stream.read(len(FILE_MAGIC_STR)) != FILE_MAGIC_STR:
|
||||
raise ValueError('Bad magic value for a wavetable file')
|
||||
version = read_short(stream)
|
||||
read_short(stream) # reserved
|
||||
self.__load_embed(stream)
|
||||
|
||||
elif import_as == _FurWavetableImportType.EMBED:
|
||||
return self.__load_embed(stream)
|
||||
|
||||
else:
|
||||
raise ValueError('Invalid import type')
|
||||
|
||||
def __load_embed(self, stream: BinaryIO) -> None:
|
||||
if stream.read(len(EMBED_MAGIC_STR)) != EMBED_MAGIC_STR:
|
||||
raise RuntimeError('Bad magic value for a wavetable embed')
|
||||
|
||||
blk_size = read_int(stream)
|
||||
if blk_size > 0:
|
||||
wt_data = BytesIO(stream.read(blk_size))
|
||||
else:
|
||||
wt_data = stream
|
||||
|
||||
self.meta.name = read_str(wt_data)
|
||||
self.meta.width = read_int(wt_data)
|
||||
read_int(wt_data) # reserved
|
||||
self.meta.height = read_int(wt_data) + 1 # serialized height is 1 lower than actual value
|
||||
|
||||
self.data = [read_int(wt_data) for _ in range(self.meta.width)]
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
"""
|
||||
Generic format for manipulating to, from, and between tracker formats.
|
||||
|
||||
- :mod:`chipchune.interchange.enums`: Various constants.
|
||||
- :mod:`chipchune.interchange.furnace`: Adapters for Furnace.
|
||||
|
||||
"""
|
||||
|
|
@ -1,24 +0,0 @@
|
|||
import enum
|
||||
from chipchune._util import EnumShowNameOnly
|
||||
|
||||
class InterNote(EnumShowNameOnly):
|
||||
"""
|
||||
Common note interchange format.
|
||||
"""
|
||||
__ = enum.auto() # Signifies a blank space in tracker
|
||||
C_ = enum.auto()
|
||||
Cs = enum.auto()
|
||||
D_ = enum.auto()
|
||||
Ds = enum.auto()
|
||||
E_ = enum.auto()
|
||||
F_ = enum.auto()
|
||||
Fs = enum.auto()
|
||||
G_ = enum.auto()
|
||||
Gs = enum.auto()
|
||||
A_ = enum.auto()
|
||||
As = enum.auto()
|
||||
B_ = enum.auto()
|
||||
Off = enum.auto()
|
||||
OffRel = enum.auto()
|
||||
Rel = enum.auto()
|
||||
Echo = enum.auto()
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
from chipchune.furnace.enums import Note as FurnaceNote
|
||||
from chipchune.interchange.enums import InterNote
|
||||
|
||||
def furnace_note_to_internote(note: FurnaceNote) -> InterNote:
|
||||
"""
|
||||
Convert a Furnace note into an InterNote.
|
||||
|
||||
Raises:
|
||||
- Exception: If the supplied note is out of range.
|
||||
"""
|
||||
if note == FurnaceNote.__: return InterNote.__
|
||||
elif note == FurnaceNote.C_: return InterNote.C_
|
||||
elif note == FurnaceNote.Cs: return InterNote.Cs
|
||||
elif note == FurnaceNote.D_: return InterNote.D_
|
||||
elif note == FurnaceNote.Ds: return InterNote.Ds
|
||||
elif note == FurnaceNote.E_: return InterNote.E_
|
||||
elif note == FurnaceNote.F_: return InterNote.F_
|
||||
elif note == FurnaceNote.Fs: return InterNote.Fs
|
||||
elif note == FurnaceNote.G_: return InterNote.G_
|
||||
elif note == FurnaceNote.Gs: return InterNote.Gs
|
||||
elif note == FurnaceNote.A_: return InterNote.A_
|
||||
elif note == FurnaceNote.As: return InterNote.As
|
||||
elif note == FurnaceNote.B_: return InterNote.B_
|
||||
elif note == FurnaceNote.OFF: return InterNote.Off
|
||||
elif note == FurnaceNote.OFF_REL: return InterNote.OffRel
|
||||
elif note == FurnaceNote.REL: return InterNote.Rel
|
||||
else:
|
||||
raise Exception("Invalid note value %s" % note)
|
||||
|
||||
def internote_to_furnace_note(note: InterNote) -> FurnaceNote:
|
||||
"""
|
||||
Convert an InterNote into a Furnace note. If the equivalent
|
||||
value is unable to be determined, a blank note `__` is returned.
|
||||
"""
|
||||
if note == InterNote.__: return FurnaceNote.__
|
||||
elif note == InterNote.C_: return FurnaceNote.C_
|
||||
elif note == InterNote.Cs: return FurnaceNote.Cs
|
||||
elif note == InterNote.D_: return FurnaceNote.D_
|
||||
elif note == InterNote.Ds: return FurnaceNote.Ds
|
||||
elif note == InterNote.E_: return FurnaceNote.E_
|
||||
elif note == InterNote.F_: return FurnaceNote.F_
|
||||
elif note == InterNote.Fs: return FurnaceNote.Fs
|
||||
elif note == InterNote.G_: return FurnaceNote.G_
|
||||
elif note == InterNote.Gs: return FurnaceNote.Gs
|
||||
elif note == InterNote.A_: return FurnaceNote.A_
|
||||
elif note == InterNote.As: return FurnaceNote.As
|
||||
elif note == InterNote.B_: return FurnaceNote.B_
|
||||
elif note == InterNote.Off: return FurnaceNote.OFF
|
||||
elif note == InterNote.OffRel: return FurnaceNote.OFF_REL
|
||||
elif note == InterNote.Rel: return FurnaceNote.REL
|
||||
else:
|
||||
return FurnaceNote.__
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
"""
|
||||
Utilities for manipulating, converting, etc. tracker data.
|
||||
|
||||
- :mod:`chipchune.utils.conversion`: Conversion tools.
|
||||
"""
|
||||
|
|
@ -1,94 +0,0 @@
|
|||
from chipchune.furnace.module import FurnacePattern
|
||||
from chipchune.interchange.enums import InterNote
|
||||
from chipchune.interchange.furnace import furnace_note_to_internote
|
||||
from typing import Union, List, Tuple
|
||||
from dataclasses import dataclass, field
|
||||
|
||||
@dataclass
|
||||
class SequenceEntry:
|
||||
"""
|
||||
A representation of a row in note-length format. Such a format is commonly
|
||||
used across different sound engines and sequenced data.
|
||||
|
||||
A pattern can be turned into a list of SequenceEntries, which should be easier
|
||||
to convert into a format of your choice.
|
||||
"""
|
||||
note: InterNote
|
||||
length: int
|
||||
volume: int
|
||||
"""
|
||||
Tracker-defined volume; although this should be -1 for undefined values.
|
||||
"""
|
||||
octave: int
|
||||
"""
|
||||
Tracker-defined octave; although this should be -1 for undefined values.
|
||||
"""
|
||||
instrument: int
|
||||
"""
|
||||
Tracker-defined instrument number; although this should be -1 for undefined values.
|
||||
"""
|
||||
effects: List[Tuple[int, int]] = field(default_factory=list)
|
||||
"""
|
||||
Tracker-defined effects list; if undefined, this should be empty.
|
||||
"""
|
||||
|
||||
def pattern_to_sequence(pattern: Union[FurnacePattern, None]) -> List[SequenceEntry]:
|
||||
"""
|
||||
Interface to convert a pattern from tracker rows to a "sequence", which is
|
||||
really a list of SequenceEntries.
|
||||
|
||||
:param pattern:
|
||||
A pattern object. Supported types at the moment: `FurnacePattern`.
|
||||
Anything outside of the supported types will throw a `TypeError`.
|
||||
"""
|
||||
if isinstance(pattern, FurnacePattern):
|
||||
return furnace_pattern_to_sequence(pattern)
|
||||
else:
|
||||
raise TypeError("Invalid pattern type; must be one of: FurnacePattern")
|
||||
|
||||
def furnace_pattern_to_sequence(pattern: FurnacePattern) -> List[SequenceEntry]:
|
||||
converted: List[SequenceEntry] = []
|
||||
last_volume = -1
|
||||
for i in pattern.data:
|
||||
note = furnace_note_to_internote(i.note)
|
||||
effects = i.effects
|
||||
volume = i.volume
|
||||
instrument = i.instrument
|
||||
|
||||
if effects == [(65535, 65535)]:
|
||||
effects = []
|
||||
|
||||
if volume == 65535:
|
||||
volume = last_volume
|
||||
else:
|
||||
last_volume = volume
|
||||
|
||||
if instrument == 65535:
|
||||
instrument = -1
|
||||
|
||||
if note == InterNote.__:
|
||||
if len(converted) == 0:
|
||||
converted.append(
|
||||
SequenceEntry(
|
||||
note=InterNote.__,
|
||||
length=1,
|
||||
volume=volume,
|
||||
octave=i.octave,
|
||||
instrument=instrument,
|
||||
effects=effects,
|
||||
)
|
||||
)
|
||||
else:
|
||||
converted[-1].length += 1
|
||||
else:
|
||||
converted.append(
|
||||
SequenceEntry(
|
||||
note=note,
|
||||
length=1,
|
||||
volume=volume,
|
||||
octave=i.octave,
|
||||
instrument=instrument,
|
||||
effects=effects,
|
||||
)
|
||||
)
|
||||
return converted
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
@echo off
|
||||
if [%1]==[] goto usage
|
||||
python3 convert_to_asm.py %1
|
||||
echo converted .fur file to .asm!
|
||||
cd asm
|
||||
cl65 -d -vm -l furC64.lst -g -u __EXEHDR__ -t c64 -C .\c64-asm.cfg -m furC64.map -Ln furC64.lbl -o furC64-test.prg furC64.asm
|
||||
@echo compiled .prg file at asm/furC64-test.prg
|
||||
cd ..
|
||||
goto :eof
|
||||
:usage
|
||||
@echo No arguments supplied
|
||||
@echo Make sure to run this command with an argument
|
||||
@echo example: convert.bat test_file.fur
|
||||
exit /B 1
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
#!/bin/bash
|
||||
if [ $# -eq 0 ]
|
||||
then
|
||||
echo "No arguments supplied"
|
||||
echo "Make sure to run this command with an argument"
|
||||
echo "example: convert.sh test_file.fur"
|
||||
else
|
||||
python3 convert_to_asm.py $1
|
||||
echo "converted .fur file to .asm!"
|
||||
cd asm
|
||||
cl65 -d -vm -l furC64.lst -g -u __EXEHDR__ -t c64 -C ./exe.cfg -m furC64.map -Ln furC64.lbl -o furC64-test.prg furC64.asm
|
||||
cl65 -d -C ./bin.cfg -o song.bin furC64.asm
|
||||
echo "compiled .prg file at asm/furC64-test.prg"
|
||||
cd ..
|
||||
fi
|
||||
|
|
@ -1,786 +0,0 @@
|
|||
from chipchune.furnace.module import FurnaceModule
|
||||
from chipchune.furnace.data_types import InsFeatureMacro, InsFeatureC64, InsFeatureAmiga
|
||||
from chipchune.furnace.enums import MacroCode, MacroItem, MacroType
|
||||
from chipchune.furnace.enums import InstrumentType
|
||||
import sys
|
||||
|
||||
subsong = 0
|
||||
note_transpose = 0
|
||||
dups = {}
|
||||
|
||||
print(sys.argv)
|
||||
module = FurnaceModule(sys.argv[1])
|
||||
chnum = module.get_num_channels()
|
||||
|
||||
speed_type = len(module.subsongs[subsong].speed_pattern)
|
||||
|
||||
notes = ["C_","Cs","D_","Ds","E_","F_","Fs","G_","Gs","A_","As","B_"]
|
||||
|
||||
def comp(pat):
|
||||
i = 0
|
||||
o = []
|
||||
n = 0
|
||||
while i < len(pat):
|
||||
j = i
|
||||
k = 0
|
||||
if pat[i] >= 0x40 and pat[i] < 128: i += 1
|
||||
elif pat[i] == 0xFB: i += 2
|
||||
elif pat[i] == 0xFC: i += 2
|
||||
elif pat[i] == 0xE0: i += 2
|
||||
elif pat[i] == 0xE1: i += 2
|
||||
elif pat[i] == 0xE2: i += 2
|
||||
elif pat[i] == 0xE3: i += 2
|
||||
elif pat[i] == 0xE4: i += 2
|
||||
elif pat[i] == 0xE5: i += 3
|
||||
elif pat[i] == 0xE6: i += 2
|
||||
elif pat[i] == 0xE7: i += 2
|
||||
elif pat[i] == 0xE8: i += 2
|
||||
elif pat[i] == 0xE9: i += 3
|
||||
elif pat[i] == 0xEA: i += 3
|
||||
elif pat[i] == 0xEB: i += 2
|
||||
elif pat[i] == 0xEC: i += 2
|
||||
elif pat[i] == 0xED: i += 2
|
||||
elif pat[i] == 0xEE: i += 2
|
||||
elif pat[i] == 0xEF: i += 1
|
||||
elif pat[i] == 0xF0: i += 1
|
||||
elif pat[i] == 0xF1: i += 2
|
||||
elif pat[i] == 0xF2: i += 2
|
||||
elif pat[i] == 0xFF: i += 2
|
||||
elif pat[i] == 0xFD:
|
||||
i += 1
|
||||
n = 2
|
||||
elif pat[i] == 0xFE:
|
||||
i += 1
|
||||
n = 2
|
||||
elif pat[i] >= 128:
|
||||
i += 1
|
||||
n = 2
|
||||
else:
|
||||
k = 1
|
||||
if n == 0:
|
||||
o.append(pat[i])
|
||||
elif pat[i] > 1:
|
||||
o.append(pat[i]-1)
|
||||
#print(i,pat[i])
|
||||
i += 1
|
||||
n = max(n-1,0)
|
||||
if k == 0:
|
||||
o.extend(pat[j:i])
|
||||
#print(pat,"\n",o,"\n")
|
||||
return o
|
||||
|
||||
def conv_pattern(pattern):
|
||||
out = [0]
|
||||
oldtemp = [0,0]
|
||||
r = 0
|
||||
bitind = 0
|
||||
oldins = -1
|
||||
for row in pattern.data:
|
||||
has03xx = 0
|
||||
for l in row.effects:
|
||||
k = list(l)
|
||||
if k[0] == 0x03 and k[1] > 0:
|
||||
has03xx = 1
|
||||
break
|
||||
|
||||
temp = []
|
||||
notnote = 0
|
||||
new_byte = 0
|
||||
if row.instrument != 65535 and oldins != row.instrument:
|
||||
new_byte = 1
|
||||
if row.instrument < 0x40:
|
||||
temp.append(row.instrument+0x40)
|
||||
else:
|
||||
temp.append(0xFB)
|
||||
temp.append(row.instrument)
|
||||
oldins = row.instrument
|
||||
if row.volume != 65535:
|
||||
new_byte = 1
|
||||
temp.append(0xFC)
|
||||
temp.append(row.volume)
|
||||
|
||||
hasEffect = [-1,-1]
|
||||
has0Dxx = -1
|
||||
for l in row.effects:
|
||||
k = list(l)
|
||||
if k[1] == 65535:
|
||||
k[1] = 0
|
||||
|
||||
if k[0] == 0xD:
|
||||
new_byte = 1
|
||||
has0Dxx = k[1]
|
||||
continue
|
||||
if k[0] == 0x0B:
|
||||
new_byte = 1
|
||||
temp.extend([0xED, k[1]])
|
||||
has0Dxx = 0
|
||||
continue
|
||||
if k[0] == 0xEE:
|
||||
new_byte = 1
|
||||
temp.extend([0xF2, k[1]])
|
||||
has0Dxx = 0
|
||||
continue
|
||||
if (k[0] == 0x09 or k[0] == 0x0F) and (speed_type == 1):
|
||||
new_byte = 1
|
||||
temp.extend([0xE1, k[1]])
|
||||
temp.extend([0xE0, k[1]])
|
||||
continue
|
||||
if k[0] == 0x0F and (speed_type == 2):
|
||||
new_byte = 1
|
||||
temp.extend([0xE1, k[1]])
|
||||
continue
|
||||
if k[0] == 0x09 and (speed_type == 2):
|
||||
new_byte = 1
|
||||
temp.extend([0xE0, k[1]])
|
||||
continue
|
||||
if k[0] == 0x00:
|
||||
new_byte = 1
|
||||
temp.extend([0xE2, k[1]])
|
||||
continue
|
||||
if k[0] == 0x01:
|
||||
new_byte = 1
|
||||
temp.extend([0xE3, k[1]])
|
||||
continue
|
||||
if k[0] == 0x02:
|
||||
new_byte = 1
|
||||
temp.extend([0xE4, k[1]])
|
||||
continue
|
||||
if k[0] == 0x03 and k[1] == 0:
|
||||
new_byte = 1
|
||||
temp.extend([0xE4, 0])
|
||||
continue
|
||||
if k[0] == 0x03 and k[1] > 0:
|
||||
new_byte = 1
|
||||
temp.extend([0xE5, k[1], max(min(notes.index(str(row.note))+(row.octave*12)+note_transpose,95),0)])
|
||||
continue
|
||||
if k[0] == 0x04:
|
||||
new_byte = 1
|
||||
temp.extend([0xE6, k[1]])
|
||||
continue
|
||||
if k[0] == 0x1B:
|
||||
new_byte = 1
|
||||
temp.extend([0xE7, k[1]])
|
||||
continue
|
||||
if k[0] == 0x1C:
|
||||
new_byte = 1
|
||||
temp.extend([0xE8, k[1]])
|
||||
continue
|
||||
if k[0] == 0xE1:
|
||||
new_byte = 1
|
||||
temp.extend([0xE9, k[1]>>4, k[1]&15])
|
||||
continue
|
||||
if k[0] == 0xE2:
|
||||
new_byte = 1
|
||||
temp.extend([0xEA, k[1]>>4, k[1]&15])
|
||||
continue
|
||||
if k[0] == 0xE5:
|
||||
new_byte = 1
|
||||
temp.extend([0xEB, k[1]])
|
||||
continue
|
||||
if k[0] == 0xEC:
|
||||
new_byte = 1
|
||||
temp.extend([0xEC, k[1]])
|
||||
continue
|
||||
if (k[0]>>4) == 4:
|
||||
new_byte = 1
|
||||
temp.extend([0xEE, (k[1]|(k[0]&0xf)<<8)>>3])
|
||||
continue
|
||||
if k[0] == 0xEA:
|
||||
new_byte = 1
|
||||
if k[1] == 0:
|
||||
temp.extend([0xEF])
|
||||
else:
|
||||
temp.extend([0xF0])
|
||||
continue
|
||||
if k[0] == 0x1A:
|
||||
new_byte = 1
|
||||
if k[1] > 0:
|
||||
temp.extend([0xF1, 0x00])
|
||||
else:
|
||||
temp.extend([0xF1, 0xFF])
|
||||
continue
|
||||
if str(row.note) == "OFF_REL":
|
||||
notnote = 1
|
||||
new_byte = 1
|
||||
temp.append(0xFD)
|
||||
elif str(row.note) == "REL":
|
||||
notnote = 1
|
||||
new_byte = 1
|
||||
temp.append(0xFD)
|
||||
elif str(row.note) == "OFF":
|
||||
notnote = 1
|
||||
new_byte = 1
|
||||
temp.append(0xFE)
|
||||
elif str(row.note) == "__" or (has03xx == 1):
|
||||
if has03xx == 0:
|
||||
notnote = 1
|
||||
#temp.append(0x80)
|
||||
else:
|
||||
new_byte = 1
|
||||
temp.append(max(min(notes.index(str(row.note))+(row.octave*12)+note_transpose,95),0)+0x80)
|
||||
|
||||
if new_byte == 1:
|
||||
temp.append(0)
|
||||
out.extend(temp)
|
||||
durpass = False
|
||||
if out[-1] >= 63:
|
||||
out.append(0)
|
||||
if has0Dxx > -1:
|
||||
out[-1] += 1
|
||||
if out[0] == 0: out = out[1:]
|
||||
out.extend([0xFF, has0Dxx])
|
||||
return out
|
||||
out[-1] += 1
|
||||
r += 1
|
||||
out.extend([0xFF, 0])
|
||||
if out[0] == 0: out = out[1:]
|
||||
return out
|
||||
|
||||
f = open("asm/song.asm","w")
|
||||
|
||||
relW = []
|
||||
relA = []
|
||||
relD = []
|
||||
relC = []
|
||||
|
||||
f.write("ticks_init:")
|
||||
f.write(".byte ")
|
||||
if speed_type == 1:
|
||||
f.write(str(module.subsongs[subsong].speed_pattern[0])+", ")
|
||||
f.write(str(module.subsongs[subsong].speed_pattern[0])+"\n")
|
||||
elif speed_type == 2:
|
||||
f.write(str(module.subsongs[subsong].speed_pattern[0])+", ")
|
||||
f.write(str(module.subsongs[subsong].speed_pattern[1])+"\n")
|
||||
|
||||
f.write("insFL:\n")
|
||||
f.write(".lobytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"F")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
f.write("insFH:\n")
|
||||
f.write(".hibytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"F")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
f.write("insAL:\n")
|
||||
f.write(".lobytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"A")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
f.write("insAH:\n")
|
||||
f.write(".hibytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"A")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
f.write("insDL:\n")
|
||||
f.write(".lobytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"D")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
f.write("insDH:\n")
|
||||
f.write(".hibytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"D")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
f.write("insWL:\n")
|
||||
f.write(".lobytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"W")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
f.write("insWH:\n")
|
||||
f.write(".hibytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"W")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
f.write("insCL:\n")
|
||||
f.write(".lobytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"C")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
f.write("insCH:\n")
|
||||
f.write(".hibytes ")
|
||||
for i in range(len(module.instruments)):
|
||||
f.write("ins"+str(i)+"C")
|
||||
if i == len(module.instruments)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
for i in range(len(module.instruments)):
|
||||
features = module.instruments[i].features
|
||||
a = filter(
|
||||
lambda x: (
|
||||
type(x) == InsFeatureMacro
|
||||
), features
|
||||
)
|
||||
macros = []
|
||||
for j in a:
|
||||
macros = j.macros
|
||||
hasWaveMacro = 0
|
||||
hasCutMacro = 0
|
||||
for j in macros:
|
||||
kind = j.kind
|
||||
if kind == MacroCode.WAVE:
|
||||
hasWaveMacro = 1
|
||||
continue
|
||||
if kind == MacroCode.ALG:
|
||||
hasCutMacro = 1
|
||||
continue
|
||||
|
||||
hasAbsFilter = False
|
||||
hasAbsDuty = False
|
||||
written_ins = False
|
||||
|
||||
a = filter(
|
||||
lambda x: (
|
||||
type(x) == InsFeatureMacro
|
||||
), features
|
||||
)
|
||||
macros = []
|
||||
for j in a:
|
||||
macros = j.macros
|
||||
for j in macros:
|
||||
kind = j.kind
|
||||
if kind == MacroCode.DUTY and j.type == MacroType.LFO:
|
||||
hasAbsDuty = True
|
||||
|
||||
a = filter(
|
||||
lambda x: (
|
||||
type(x) == InsFeatureC64
|
||||
), features
|
||||
)
|
||||
for j in a:
|
||||
wave = j.tri_on
|
||||
wave |= j.saw_on<<1
|
||||
wave |= j.pulse_on<<2
|
||||
wave |= j.noise_on<<3
|
||||
wave <<= 4
|
||||
wave |= j.ring_mod<<2
|
||||
wave |= j.osc_sync<<1
|
||||
f.write("ins"+str(i)+"F:\n")
|
||||
f.write(".byte ")
|
||||
f.write(str(wave)+", ")
|
||||
ad = (j.envelope.a<<4)|j.envelope.d
|
||||
sr = (j.envelope.s<<4)|j.envelope.r
|
||||
f.write(str(ad)+", ")
|
||||
f.write(str(sr)+", ")
|
||||
f.write(str(j.duty&0xff)+", ")
|
||||
f.write(str(j.duty>>8)+", ")
|
||||
flags = 0
|
||||
if j.duty_is_abs:
|
||||
flags |= 1
|
||||
if hasWaveMacro:
|
||||
flags |= 2
|
||||
if j.to_filter:
|
||||
flags |= 4
|
||||
if j.init_filter:
|
||||
flags |= 8
|
||||
if j.filter_is_abs:
|
||||
flags |= 16
|
||||
if hasCutMacro:
|
||||
flags |= 32
|
||||
if not j.no_test:
|
||||
flags |= 64
|
||||
f.write(str(flags)+", ")
|
||||
fil = 0
|
||||
fil = j.lp<<4
|
||||
fil |= j.bp<<5
|
||||
fil |= j.hp<<6
|
||||
fil |= j.ch3_off<<7
|
||||
f.write(str(j.res<<4)+", ")
|
||||
f.write(str(fil)+", ")
|
||||
f.write(str(j.cut&0xff)+", ")
|
||||
f.write(str((j.cut>>8)&15)+"\n")
|
||||
f.write("\n")
|
||||
written_ins = True
|
||||
hasAbsDuty |= j.duty_is_abs
|
||||
hasAbsFilter = j.filter_is_abs
|
||||
if written_ins == False:
|
||||
f.write("ins"+str(i)+"F:\n")
|
||||
f.write(".byte 32, 8, 0, 255, 7, 0\n")
|
||||
a = filter(
|
||||
lambda x: (
|
||||
type(x) == InsFeatureMacro
|
||||
), features
|
||||
)
|
||||
arp = [128,0xFF,0xFF]
|
||||
duty = [0xFF,0xFF]
|
||||
wave = [0xFF,0xFF]
|
||||
cutoff = [0xFF,0xFF]
|
||||
macros = []
|
||||
for j in a:
|
||||
macros = j.macros
|
||||
hasRelTotal = [0,0,0,0]
|
||||
for j in macros:
|
||||
kind = j.kind
|
||||
if kind == MacroCode.ARP:
|
||||
s = j.speed
|
||||
arp = []
|
||||
loop = 0xff
|
||||
hasRel = 0
|
||||
oldlen = 0
|
||||
if j.data[-1] == MacroItem.LOOP:
|
||||
arr = [MacroItem.LOOP, j.data[-2]]
|
||||
j.data = j.data[:-2] + arr
|
||||
for k in j.data:
|
||||
if k == MacroItem.LOOP:
|
||||
loop = oldlen
|
||||
elif k == MacroItem.RELEASE:
|
||||
arp.append(0xFF)
|
||||
arp.append(loop)
|
||||
relA.append(len(arp))
|
||||
oldlen = max(len(arp),0)
|
||||
hasRel = 1
|
||||
elif (k>>30) > 0:
|
||||
arp.append(0xFE)
|
||||
k = abs(k^(1<<30))
|
||||
k = max(min(k,95),0)
|
||||
arp.append(k%120)
|
||||
oldlen = max(len(arp),0)
|
||||
else:
|
||||
if k < 0:
|
||||
arp.append((k%120)-120+128)
|
||||
else:
|
||||
arp.append((k%120)+128)
|
||||
oldlen = max(len(arp),0)
|
||||
if hasRel == 0:
|
||||
relA.append(len(arp))
|
||||
hasRelTotal[1] = 1
|
||||
len_temp = len(arp)
|
||||
arp.append(0xFF)
|
||||
arp.append(loop if loop!=len_temp else 0xff)
|
||||
if kind == MacroCode.DUTY and j.type == MacroType.LFO:
|
||||
while type(j.data[0]) is not int:
|
||||
j.data = j.data[1:]
|
||||
|
||||
s = j.speed
|
||||
duty = []
|
||||
hasRel = 0
|
||||
lfo = j.data[13]
|
||||
while lfo <= 1023:
|
||||
lfo += j.data[11]
|
||||
if lfo > 1023: break
|
||||
k = lfo
|
||||
if k & 512:
|
||||
k = 1023-lfo
|
||||
k >>= 1
|
||||
k = j.data[0]+((k+(j.data[1]-j.data[0])*k)>>8)
|
||||
if (k&0xff) == 255:
|
||||
duty.append(254)
|
||||
else:
|
||||
duty.append(k&0xff)
|
||||
duty.append(k>>8)
|
||||
if hasRel == 0:
|
||||
relD.append(0)
|
||||
hasRelTotal[2] = 1
|
||||
duty.append(0xFF)
|
||||
duty.append(0)
|
||||
elif kind == MacroCode.DUTY:
|
||||
s = j.speed
|
||||
duty = []
|
||||
loop = 0xff
|
||||
loop2 = 0
|
||||
hasRel = 0
|
||||
for k in j.data:
|
||||
if k == MacroItem.LOOP:
|
||||
loop = loop2
|
||||
elif k == MacroItem.RELEASE:
|
||||
duty.append(0xFF)
|
||||
duty.append(loop)
|
||||
relD.append(len(duty))
|
||||
hasRel = 1
|
||||
else:
|
||||
loop2 = len(duty)+2
|
||||
if hasAbsDuty:
|
||||
if (k&0xff) == 255:
|
||||
duty.append(254)
|
||||
else:
|
||||
duty.append(k&0xff)
|
||||
duty.append(k>>8)
|
||||
else:
|
||||
k = 32768-(k*4) #4)
|
||||
duty.append(k&0xff)
|
||||
duty.append(k>>8)
|
||||
if hasRel == 0:
|
||||
relD.append(len(duty))
|
||||
hasRelTotal[2] = 1
|
||||
len_temp = len(duty)
|
||||
duty.append(0xFF)
|
||||
duty.append(loop if loop!=len_temp else 0xff)
|
||||
if kind == MacroCode.ALG and j.type == MacroType.LFO:
|
||||
while type(j.data[0]) is not int:
|
||||
j.data = j.data[1:]
|
||||
|
||||
s = j.speed
|
||||
cutoff = []
|
||||
hasRel = 0
|
||||
lfo = j.data[13]
|
||||
while lfo <= 1023:
|
||||
lfo += j.data[11]
|
||||
k = lfo
|
||||
if k & 512:
|
||||
k = 1023-lfo
|
||||
k >>= 1
|
||||
k = j.data[0]+((k+(j.data[1]-j.data[0])*k)>>8)
|
||||
if (k&0xff) == 255:
|
||||
cutoff.append(254)
|
||||
else:
|
||||
cutoff.append(k&0xff)
|
||||
cutoff.append(k>>8)
|
||||
if hasRel == 0:
|
||||
relC.append(len(cutoff))
|
||||
hasRelTotal[3] = 1
|
||||
cutoff.append(0xFF)
|
||||
cutoff.append(0)
|
||||
elif kind == MacroCode.ALG:
|
||||
s = j.speed
|
||||
cutoff = []
|
||||
loop = 0xff
|
||||
loop2 = 0
|
||||
hasRel = 0
|
||||
for k in j.data:
|
||||
if k == MacroItem.LOOP:
|
||||
loop = loop2
|
||||
elif k == MacroItem.RELEASE:
|
||||
cutoff.append(0xFF)
|
||||
cutoff.append(loop)
|
||||
relC.append(len(cutoff))
|
||||
hasRel = 1
|
||||
else:
|
||||
loop2 = len(cutoff)+1
|
||||
if hasAbsFilter:
|
||||
if (k&0xff) == 255:
|
||||
cutoff.append(254)
|
||||
else:
|
||||
cutoff.append(k&0xff)
|
||||
cutoff.append(k>>8)
|
||||
else:
|
||||
k = 32768+k*7
|
||||
cutoff.append(k&0xff)
|
||||
cutoff.append(k>>8)
|
||||
if hasRel == 0:
|
||||
relC.append(len(cutoff))
|
||||
hasRelTotal[3] = 1
|
||||
len_temp = len(cutoff)
|
||||
cutoff.append(0xFF)
|
||||
cutoff.append(loop if loop!=len_temp else 0xff)
|
||||
if kind == MacroCode.WAVE:
|
||||
s = j.speed
|
||||
wave = []
|
||||
loop = 0xff
|
||||
loop2 = 0
|
||||
hasRel = 0
|
||||
for k in j.data:
|
||||
if k == MacroItem.LOOP:
|
||||
loop = len(wave)
|
||||
elif k == MacroItem.RELEASE:
|
||||
wave.append(0xFF)
|
||||
wave.append(loop)
|
||||
relW.append(len(wave))
|
||||
hasRel = 1
|
||||
else:
|
||||
wave.append(k<<4)
|
||||
if hasRel == 0:
|
||||
relW.append(len(wave))
|
||||
hasRelTotal[0] = 1
|
||||
len_temp = len(wave)
|
||||
wave.append(0xFF)
|
||||
wave.append(loop if loop!=len_temp else 0xff)
|
||||
if hasRelTotal[0] == 0:
|
||||
relW.append(0)
|
||||
if hasRelTotal[1] == 0:
|
||||
relA.append(0)
|
||||
if hasRelTotal[2] == 0:
|
||||
relD.append(0)
|
||||
if hasRelTotal[3] == 0:
|
||||
relC.append(0)
|
||||
wave = str(wave)[1:-1]
|
||||
duty = str(duty)[1:-1]
|
||||
arp = str(arp)[1:-1]
|
||||
cutoff = str(cutoff)[1:-1]
|
||||
if arp in dups:
|
||||
f.write("ins"+str(i)+"A = "+dups[arp]+"\n")
|
||||
else:
|
||||
f.write("ins"+str(i)+"A:\n")
|
||||
f.write(".byte "+arp+"\n")
|
||||
dups[arp] = "ins"+str(i)+"A"
|
||||
|
||||
if duty in dups:
|
||||
f.write("ins"+str(i)+"D = "+dups[duty]+"\n")
|
||||
else:
|
||||
f.write("ins"+str(i)+"D:\n")
|
||||
f.write(".byte "+duty+"\n")
|
||||
dups[duty] = "ins"+str(i)+"D"
|
||||
|
||||
if wave in dups:
|
||||
f.write("ins"+str(i)+"W = "+dups[wave]+"\n")
|
||||
else:
|
||||
f.write("ins"+str(i)+"W:\n")
|
||||
f.write(".byte "+wave+"\n")
|
||||
dups[wave] = "ins"+str(i)+"W"
|
||||
|
||||
if cutoff in dups:
|
||||
f.write("ins"+str(i)+"C = "+dups[cutoff]+"\n")
|
||||
else:
|
||||
f.write("ins"+str(i)+"C:\n")
|
||||
f.write(".byte "+cutoff+"\n")
|
||||
dups[cutoff] = "ins"+str(i)+"C"
|
||||
|
||||
relW = str(relW)[1:-1]
|
||||
relD = str(relD)[1:-1]
|
||||
relA = str(relA)[1:-1]
|
||||
f.write("insArel:\n")
|
||||
f.write(".byte "+relA+"\n")
|
||||
f.write("insDrel:\n")
|
||||
f.write(".byte "+relD+"\n")
|
||||
f.write("insWrel:\n")
|
||||
f.write(".byte "+relW+"\n")
|
||||
|
||||
for i in range(chnum):
|
||||
order = module.subsongs[subsong].order[i]
|
||||
f.write("order"+str(i)+"len = "+str(len(order))+"\n")
|
||||
f.write("order"+str(i)+"L:\n")
|
||||
f.write(".byte ")
|
||||
for o in range(len(order)):
|
||||
f.write("<(patCH"+str(i)+"N"+str(order[o])+"-1)")
|
||||
if o == len(order)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
f.write("order"+str(i)+"H:\n")
|
||||
f.write(".byte ")
|
||||
for o in range(len(order)):
|
||||
f.write(">(patCH"+str(i)+"N"+str(order[o])+"-1)")
|
||||
if o == len(order)-1:
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
for i in range(chnum):
|
||||
order = module.subsongs[subsong].order[i]
|
||||
avail_patterns = filter(
|
||||
lambda x: (
|
||||
x.channel == i and
|
||||
x.subsong == subsong
|
||||
),
|
||||
module.patterns
|
||||
)
|
||||
for p in avail_patterns:
|
||||
patnum = p.index
|
||||
#print(patnum,i)
|
||||
g = str(comp(conv_pattern(p)))[1:-1]
|
||||
f.write("patCH"+str(i)+"N"+str(patnum)+":\n")
|
||||
f.write(".byte "+g+"\n")
|
||||
|
||||
if chnum == 4:
|
||||
f.write("sampleHS:\n.hibytes ")
|
||||
for i in range(len(module.samples)):
|
||||
f.write("PCM"+str(i))
|
||||
if i == (len(module.samples)-1):
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
f.write("sampleHE:\n.hibytes ")
|
||||
for i in range(len(module.samples)):
|
||||
f.write("PCMe"+str(i))
|
||||
if i == (len(module.samples)-1):
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
total_maps = []
|
||||
f.write("insSI:\n.byte ")
|
||||
for i in range(len(module.instruments)):
|
||||
features = module.instruments[i].features
|
||||
a = filter(
|
||||
lambda x: (
|
||||
type(x) == InsFeatureAmiga
|
||||
), features
|
||||
)
|
||||
init_sample = 0
|
||||
for j in a:
|
||||
if j.init_sample > 0 and j.init_sample != 65535:
|
||||
init_sample = j.init_sample
|
||||
break
|
||||
f.write(str(init_sample))
|
||||
if i == (len(module.instruments)-1):
|
||||
f.write("\n")
|
||||
else:
|
||||
f.write(", ")
|
||||
|
||||
f.write(".res 256-(*&$ff), 0\n")
|
||||
for i in range(len(module.samples)):
|
||||
sample = []
|
||||
rate = max(min(module.samples[i].meta.sample_rate,384000),100)
|
||||
smp = list(module.samples[i].data)
|
||||
k = 0
|
||||
while k < len(smp):
|
||||
j = smp[int(k)]
|
||||
s = float(((int(j)+128)&0xff))
|
||||
s = ((s-128)/1.65)+128
|
||||
#s = ((s-128)/1.6)+128
|
||||
s = int(s/16)
|
||||
#s = (s>>1)+8
|
||||
sample.append(s)
|
||||
k += rate/7812
|
||||
s = sample[-1]
|
||||
if (len(sample)%256) == 0:
|
||||
sample.extend([s]*256)
|
||||
else:
|
||||
while (len(sample)%256) != 0:
|
||||
sample.append(s)
|
||||
f.write("PCM"+str(i)+":\n.byte "+str(sample)[1:-1]+"\n")
|
||||
f.write("PCMe"+str(i)+":\n")
|
||||
|
||||
f.close()
|
||||
|
||||
# frequency calculation code taken from
|
||||
# https://codebase64.org/doku.php?id=base:how_to_calculate_your_own_sid_frequency_table
|
||||
|
||||
tuning = module.meta.tuning
|
||||
f = open("asm/note_lo.bin","wb")
|
||||
for i in range(96):
|
||||
hz = tuning * (2**(float(i-57)/12.0))
|
||||
cnst = (256**3)/985248.0 # PAL frequency
|
||||
freq = min(max(hz*cnst,0),0xffff)
|
||||
f.write(bytearray([int(freq)&0xff]))
|
||||
f.close()
|
||||
f = open("asm/note_hi.bin","wb")
|
||||
for i in range(96):
|
||||
hz = tuning * (2**(float(i-57)/12.0))
|
||||
cnst = (256**3)/985248.0 # PAL frequency
|
||||
freq = min(max(hz*cnst,0),0xffff)
|
||||
f.write(bytearray([(int(freq)>>8)&0xff]))
|
||||
f.close()
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
python3 conv_liltalk.py
|
||||
./build_liltalk.sh
|
||||
rm main.o main.zx0*
|
||||
make
|
||||
|
|
@ -1,454 +0,0 @@
|
|||
3 A
|
||||
3 r
|
||||
3 e
|
||||
3
|
||||
3 y
|
||||
3 o
|
||||
3 u
|
||||
3
|
||||
3 O
|
||||
3 K
|
||||
3 ?
|
||||
20
|
||||
|
||||
3 .
|
||||
3 .
|
||||
3 .
|
||||
3
|
||||
3 W
|
||||
3 h
|
||||
3 o
|
||||
3
|
||||
3 a
|
||||
3 r
|
||||
3 e
|
||||
3
|
||||
3 y
|
||||
3 o
|
||||
3 u
|
||||
20 ?
|
||||
|
||||
6
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
|
||||
3 T
|
||||
3 h
|
||||
3 a
|
||||
3 n
|
||||
3 k
|
||||
3
|
||||
3 g
|
||||
3 o
|
||||
3 o
|
||||
3 d
|
||||
3 n
|
||||
3 e
|
||||
3 s
|
||||
3 s
|
||||
2 .\n
|
||||
1
|
||||
|
||||
3 I
|
||||
3 '
|
||||
3 m
|
||||
3
|
||||
3 L
|
||||
3 i
|
||||
3 l
|
||||
3 i
|
||||
3 a
|
||||
3
|
||||
3 f
|
||||
3 r
|
||||
3 o
|
||||
3 m
|
||||
3
|
||||
3 L
|
||||
3 a
|
||||
3 n
|
||||
3 c
|
||||
3 e
|
||||
3
|
||||
3 v
|
||||
3 i
|
||||
3 l
|
||||
3 l
|
||||
3 a
|
||||
3 g
|
||||
3 e
|
||||
3 .
|
||||
20
|
||||
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
1
|
||||
|
||||
3 H
|
||||
3 a
|
||||
3 v
|
||||
3 i
|
||||
3 n
|
||||
3 g
|
||||
3
|
||||
3 s
|
||||
3 o
|
||||
3 m
|
||||
3 e
|
||||
3
|
||||
3 k
|
||||
3 i
|
||||
3 n
|
||||
3 d
|
||||
3
|
||||
3 o
|
||||
3 f
|
||||
3
|
||||
3 p
|
||||
3 r
|
||||
3 e
|
||||
3 m
|
||||
3 o
|
||||
3 n
|
||||
3 i
|
||||
3 t
|
||||
3 i
|
||||
3 o
|
||||
3 n
|
||||
2 ,\n
|
||||
1
|
||||
|
||||
3 I
|
||||
3
|
||||
3 c
|
||||
3 a
|
||||
3 m
|
||||
3 e
|
||||
3
|
||||
3 h
|
||||
3 e
|
||||
3 r
|
||||
3 e
|
||||
3
|
||||
3 t
|
||||
3 o
|
||||
3
|
||||
3 h
|
||||
3 a
|
||||
3 v
|
||||
3 e
|
||||
3
|
||||
3 a
|
||||
3
|
||||
3 l
|
||||
3 o
|
||||
3 o
|
||||
3 k
|
||||
3 .
|
||||
20
|
||||
|
||||
3 S
|
||||
3 u
|
||||
3 d
|
||||
3 d
|
||||
3 e
|
||||
3 n
|
||||
3 l
|
||||
3 y
|
||||
3 ,
|
||||
3 t
|
||||
3 h
|
||||
3 e
|
||||
3
|
||||
3 a
|
||||
3 r
|
||||
3 e
|
||||
3 a
|
||||
3
|
||||
3 w
|
||||
3 a
|
||||
3 s
|
||||
3
|
||||
3 e
|
||||
3 n
|
||||
3 v
|
||||
3 e
|
||||
3 l
|
||||
3 o
|
||||
3 p
|
||||
3 e
|
||||
3 d
|
||||
2 \n
|
||||
1
|
||||
|
||||
3 b
|
||||
3 y
|
||||
3
|
||||
3 a
|
||||
3
|
||||
3 l
|
||||
3 i
|
||||
3 g
|
||||
3 h
|
||||
3 t
|
||||
3
|
||||
3 a
|
||||
3 n
|
||||
3 d
|
||||
3
|
||||
3 y
|
||||
3 o
|
||||
3 u
|
||||
3
|
||||
3 c
|
||||
3 o
|
||||
3 l
|
||||
3 l
|
||||
3 a
|
||||
3 p
|
||||
3 s
|
||||
3 e
|
||||
3 d.
|
||||
20
|
||||
|
||||
3 W
|
||||
3 h
|
||||
3 e
|
||||
3 r
|
||||
3 e
|
||||
3
|
||||
3 a
|
||||
3 m
|
||||
3
|
||||
3 I
|
||||
20 ?
|
||||
|
||||
3 T
|
||||
3 h
|
||||
3 i
|
||||
3 s
|
||||
3
|
||||
3 i
|
||||
3 s
|
||||
3
|
||||
3 t
|
||||
3 h
|
||||
3 e
|
||||
3
|
||||
3 k
|
||||
3 i
|
||||
3 n
|
||||
3 g
|
||||
3 d
|
||||
3 o
|
||||
3 m
|
||||
3
|
||||
3 c
|
||||
3 a
|
||||
3 l
|
||||
3 l
|
||||
3 e
|
||||
3 d
|
||||
3
|
||||
3 Y
|
||||
3 s
|
||||
3 .
|
||||
6
|
||||
|
||||
3 T
|
||||
3 h
|
||||
3 e
|
||||
3 r
|
||||
3 e
|
||||
3 '
|
||||
3 r
|
||||
3 e
|
||||
3
|
||||
3 m
|
||||
3 o
|
||||
3 n
|
||||
3 s
|
||||
3 t
|
||||
3 e
|
||||
3 r
|
||||
3 s
|
||||
3
|
||||
3 n
|
||||
3 e
|
||||
3 a
|
||||
3 r
|
||||
3 .
|
||||
2 \n
|
||||
20
|
||||
|
||||
3 W
|
||||
3 e
|
||||
3
|
||||
3 s
|
||||
3 h
|
||||
3 o
|
||||
3 u
|
||||
3 l
|
||||
3 d
|
||||
3
|
||||
3 g
|
||||
3 o.
|
||||
20
|
||||
|
||||
3 H
|
||||
3 o
|
||||
3 w
|
||||
3
|
||||
3 a
|
||||
3 b
|
||||
3 o
|
||||
3 u
|
||||
3 t
|
||||
3
|
||||
3 i
|
||||
3 t
|
||||
2 ,\n
|
||||
1
|
||||
|
||||
3 c
|
||||
3 a
|
||||
3 n
|
||||
3
|
||||
3 y
|
||||
3 o
|
||||
3 u
|
||||
3
|
||||
3 s
|
||||
3 t
|
||||
3 a
|
||||
3 n
|
||||
3 d
|
||||
3
|
||||
3 u
|
||||
3 p?
|
||||
20
|
||||
|
||||
3 Y
|
||||
3 e
|
||||
3 a
|
||||
3 h
|
||||
3 ,
|
||||
3 I
|
||||
3 '
|
||||
3 m
|
||||
3
|
||||
3 a
|
||||
3 l
|
||||
3 r
|
||||
3 i
|
||||
3 g
|
||||
3 h
|
||||
3 t
|
||||
3 .
|
||||
3
|
||||
3 S
|
||||
3 h
|
||||
3 o
|
||||
3 u
|
||||
3 l
|
||||
3 d
|
||||
3
|
||||
3 w
|
||||
3 e\n
|
||||
|
||||
3
|
||||
3 G
|
||||
3 o
|
||||
3
|
||||
3 b
|
||||
3 e
|
||||
3 f
|
||||
3 o
|
||||
3 r
|
||||
3 e
|
||||
3
|
||||
3 t
|
||||
3 h
|
||||
3 e
|
||||
3
|
||||
3 m
|
||||
3 o
|
||||
3 n
|
||||
3 s
|
||||
3 t
|
||||
3 e
|
||||
3 r
|
||||
3 s
|
||||
3
|
||||
3 c
|
||||
3 o
|
||||
3 m
|
||||
3 e
|
||||
20 ?
|
||||
|
||||
3 S
|
||||
3 u
|
||||
3 r
|
||||
3 e
|
||||
20 .
|
||||
210
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -1,11 +0,0 @@
|
|||
MEMORY {
|
||||
ZP: file = "", start = $0002, size = $00FE, define = yes;
|
||||
MAIN: file = %O, start = $0BFE, size = $C402;
|
||||
}
|
||||
SEGMENTS {
|
||||
ZEROPAGE: load = ZP, type = zp, optional = yes;
|
||||
CODE: load = MAIN, type = rw;
|
||||
RODATA: load = MAIN, type = ro, optional = yes;
|
||||
DATA: load = MAIN, type = rw, optional = yes;
|
||||
BSS: load = MAIN, type = bss, optional = yes, define = yes;
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
.zeropage
|
||||
|
||||
.segment "CODE"
|
||||
|
||||
.word $0c00
|
||||
.incbin "font.bin"
|
||||
.res 12
|
||||
|
||||
entry:
|
||||
jmp *
|
||||