diff --git a/.gitignore b/.gitignore index 576f741..32b1aee 100644 --- a/.gitignore +++ b/.gitignore @@ -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 diff --git a/assets/11_lilia_final.csv b/assets/11_lilia_final.csv index bd80bf3..fb9202a 100644 --- a/assets/11_lilia_final.csv +++ b/assets/11_lilia_final.csv @@ -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 \ No newline at end of file diff --git a/assets/build_macos.sh b/assets/build_macos.sh index 38c47bc..ea65917 100644 --- a/assets/build_macos.sh +++ b/assets/build_macos.sh @@ -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 \ No newline at end of file +../png2prg/png2prg_darwin_arm64 -m koala -o ../loader/samples/minexample/falling_star.bin 06_falling_star.csv \ No newline at end of file diff --git a/assets/clouds.png b/assets/clouds.png deleted file mode 100644 index 311418f..0000000 Binary files a/assets/clouds.png and /dev/null differ diff --git a/assets/clouds.prg b/assets/clouds.prg deleted file mode 100644 index 0cd92cb..0000000 Binary files a/assets/clouds.prg and /dev/null differ diff --git a/assets/clouds_sprites.png b/assets/clouds_sprites.png deleted file mode 100644 index 121b654..0000000 Binary files a/assets/clouds_sprites.png and /dev/null differ diff --git a/assets/clouds_sprites.prg b/assets/clouds_sprites.prg deleted file mode 100644 index c651a6b..0000000 Binary files a/assets/clouds_sprites.prg and /dev/null differ diff --git a/assets/ys2/01_badguyz/koala/png/00.png b/assets/ys2/01_badguyz/koala/png/00.png index e0f15f7..e50131d 100644 Binary files a/assets/ys2/01_badguyz/koala/png/00.png and b/assets/ys2/01_badguyz/koala/png/00.png differ diff --git a/assets/ys2/01_badguyz/koala/png/01.png b/assets/ys2/01_badguyz/koala/png/01.png index da2c493..95262e4 100644 Binary files a/assets/ys2/01_badguyz/koala/png/01.png and b/assets/ys2/01_badguyz/koala/png/01.png differ diff --git a/assets/ys2/01_badguyz/koala/png/02.png b/assets/ys2/01_badguyz/koala/png/02.png index f449331..c672408 100644 Binary files a/assets/ys2/01_badguyz/koala/png/02.png and b/assets/ys2/01_badguyz/koala/png/02.png differ diff --git a/assets/ys2/01_badguyz/koala/png/03.png b/assets/ys2/01_badguyz/koala/png/03.png index c5e3982..e770830 100644 Binary files a/assets/ys2/01_badguyz/koala/png/03.png and b/assets/ys2/01_badguyz/koala/png/03.png differ diff --git a/assets/ys2/01_badguyz/koala/png/04.png b/assets/ys2/01_badguyz/koala/png/04.png index 9c1244b..0ec5bdc 100644 Binary files a/assets/ys2/01_badguyz/koala/png/04.png and b/assets/ys2/01_badguyz/koala/png/04.png differ diff --git a/assets/ys2/01_badguyz/koala/png/05.png b/assets/ys2/01_badguyz/koala/png/05.png index 0f5e588..79e0c4e 100644 Binary files a/assets/ys2/01_badguyz/koala/png/05.png and b/assets/ys2/01_badguyz/koala/png/05.png differ diff --git a/assets/ys2/01_badguyz/koala/png/06.png b/assets/ys2/01_badguyz/koala/png/06.png index 9294cb1..bd9085f 100644 Binary files a/assets/ys2/01_badguyz/koala/png/06.png and b/assets/ys2/01_badguyz/koala/png/06.png differ diff --git a/assets/ys2/01_badguyz/koala/png/07.png b/assets/ys2/01_badguyz/koala/png/07.png index 9093780..a5acdc1 100644 Binary files a/assets/ys2/01_badguyz/koala/png/07.png and b/assets/ys2/01_badguyz/koala/png/07.png differ diff --git a/assets/ys2/01_badguyz/koala/png/08.png b/assets/ys2/01_badguyz/koala/png/08.png index de200f4..0788e60 100644 Binary files a/assets/ys2/01_badguyz/koala/png/08.png and b/assets/ys2/01_badguyz/koala/png/08.png differ diff --git a/assets/ys2/01_badguyz/koala/png/09.png b/assets/ys2/01_badguyz/koala/png/09.png index dd50168..1b2bd3c 100644 Binary files a/assets/ys2/01_badguyz/koala/png/09.png and b/assets/ys2/01_badguyz/koala/png/09.png differ diff --git a/assets/ys2/01_badguyz/koala/png/10.png b/assets/ys2/01_badguyz/koala/png/10.png index 8b453f9..f81e8f8 100644 Binary files a/assets/ys2/01_badguyz/koala/png/10.png and b/assets/ys2/01_badguyz/koala/png/10.png differ diff --git a/assets/ys2/01_badguyz/koala/png/11.png b/assets/ys2/01_badguyz/koala/png/11.png index ea31ee1..27f2ca5 100644 Binary files a/assets/ys2/01_badguyz/koala/png/11.png and b/assets/ys2/01_badguyz/koala/png/11.png differ diff --git a/assets/ys2/01_badguyz/koala/png/12.png b/assets/ys2/01_badguyz/koala/png/12.png index 4a23d97..7b60e93 100644 Binary files a/assets/ys2/01_badguyz/koala/png/12.png and b/assets/ys2/01_badguyz/koala/png/12.png differ diff --git a/assets/ys2/01_badguyz/koala/png/13.png b/assets/ys2/01_badguyz/koala/png/13.png index c7e4463..4c18b0b 100644 Binary files a/assets/ys2/01_badguyz/koala/png/13.png and b/assets/ys2/01_badguyz/koala/png/13.png differ diff --git a/assets/ys2/01_badguyz/koala/png/14.png b/assets/ys2/01_badguyz/koala/png/14.png index f545361..a6e6f11 100644 Binary files a/assets/ys2/01_badguyz/koala/png/14.png and b/assets/ys2/01_badguyz/koala/png/14.png differ diff --git a/assets/ys2/01_badguyz/koala/png/15.png b/assets/ys2/01_badguyz/koala/png/15.png index 4020fc0..f2d2473 100644 Binary files a/assets/ys2/01_badguyz/koala/png/15.png and b/assets/ys2/01_badguyz/koala/png/15.png differ diff --git a/assets/ys2/01_badguyz/koala/png/16.png b/assets/ys2/01_badguyz/koala/png/16.png index 8fac2a2..0bd32f5 100644 Binary files a/assets/ys2/01_badguyz/koala/png/16.png and b/assets/ys2/01_badguyz/koala/png/16.png differ diff --git a/assets/ys2/01_badguyz/koala/png/17.png b/assets/ys2/01_badguyz/koala/png/17.png index 8dc26b2..d15bfd9 100644 Binary files a/assets/ys2/01_badguyz/koala/png/17.png and b/assets/ys2/01_badguyz/koala/png/17.png differ diff --git a/assets/ys2/01_badguyz/koala/png/18.png b/assets/ys2/01_badguyz/koala/png/18.png index f500ff9..7736943 100644 Binary files a/assets/ys2/01_badguyz/koala/png/18.png and b/assets/ys2/01_badguyz/koala/png/18.png differ diff --git a/assets/ys2/01_badguyz/koala/png/19.png b/assets/ys2/01_badguyz/koala/png/19.png index 4687b92..38b4331 100644 Binary files a/assets/ys2/01_badguyz/koala/png/19.png and b/assets/ys2/01_badguyz/koala/png/19.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/01.png b/assets/ys2/11_lilia_final/koala/png/01.png index 885dce5..dab148d 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/01.png and b/assets/ys2/11_lilia_final/koala/png/01.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/02.png b/assets/ys2/11_lilia_final/koala/png/02.png index d865bde..ebc9bb2 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/02.png and b/assets/ys2/11_lilia_final/koala/png/02.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/02b.png b/assets/ys2/11_lilia_final/koala/png/02b.png deleted file mode 100644 index c7af2ad..0000000 Binary files a/assets/ys2/11_lilia_final/koala/png/02b.png and /dev/null differ diff --git a/assets/ys2/11_lilia_final/koala/png/03.png b/assets/ys2/11_lilia_final/koala/png/03.png index 25d2206..77f2902 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/03.png and b/assets/ys2/11_lilia_final/koala/png/03.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/03b.png b/assets/ys2/11_lilia_final/koala/png/03b.png deleted file mode 100644 index c6e40fa..0000000 Binary files a/assets/ys2/11_lilia_final/koala/png/03b.png and /dev/null differ diff --git a/assets/ys2/11_lilia_final/koala/png/04.png b/assets/ys2/11_lilia_final/koala/png/04.png index 291e819..9f0abbd 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/04.png and b/assets/ys2/11_lilia_final/koala/png/04.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/05.png b/assets/ys2/11_lilia_final/koala/png/05.png index 12e0bf1..873521d 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/05.png and b/assets/ys2/11_lilia_final/koala/png/05.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/06.png b/assets/ys2/11_lilia_final/koala/png/06.png index 0904981..7a44e5b 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/06.png and b/assets/ys2/11_lilia_final/koala/png/06.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/07.png b/assets/ys2/11_lilia_final/koala/png/07.png index 340a4b3..201bed5 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/07.png and b/assets/ys2/11_lilia_final/koala/png/07.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/08.png b/assets/ys2/11_lilia_final/koala/png/08.png index 19ee819..472e788 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/08.png and b/assets/ys2/11_lilia_final/koala/png/08.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/09.png b/assets/ys2/11_lilia_final/koala/png/09.png index fd11b6b..780e829 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/09.png and b/assets/ys2/11_lilia_final/koala/png/09.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/10.png b/assets/ys2/11_lilia_final/koala/png/10.png index 41f94c2..f1d7864 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/10.png and b/assets/ys2/11_lilia_final/koala/png/10.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/11.png b/assets/ys2/11_lilia_final/koala/png/11.png index 4986e8b..9cad596 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/11.png and b/assets/ys2/11_lilia_final/koala/png/11.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/12.png b/assets/ys2/11_lilia_final/koala/png/12.png index 5b8ba17..c8d0407 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/12.png and b/assets/ys2/11_lilia_final/koala/png/12.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/13.png b/assets/ys2/11_lilia_final/koala/png/13.png index 63f7a7f..d1f9469 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/13.png and b/assets/ys2/11_lilia_final/koala/png/13.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/14.png b/assets/ys2/11_lilia_final/koala/png/14.png index 4a820d7..2995748 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/14.png and b/assets/ys2/11_lilia_final/koala/png/14.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/15.png b/assets/ys2/11_lilia_final/koala/png/15.png index 17fd190..802e95c 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/15.png and b/assets/ys2/11_lilia_final/koala/png/15.png differ diff --git a/assets/ys2/11_lilia_final/koala/png/16.png b/assets/ys2/11_lilia_final/koala/png/16.png index decdf71..6379e9f 100644 Binary files a/assets/ys2/11_lilia_final/koala/png/16.png and b/assets/ys2/11_lilia_final/koala/png/16.png differ diff --git a/loader/samples/minexample/Makefile b/loader/samples/minexample/Makefile index 725b102..4356bd0 100644 --- a/loader/samples/minexample/Makefile +++ b/loader/samples/minexample/Makefile @@ -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) diff --git a/loader/samples/minexample/badguy.bin b/loader/samples/minexample/badguy.bin index 8ade6eb..1c722c9 100644 Binary files a/loader/samples/minexample/badguy.bin and b/loader/samples/minexample/badguy.bin differ diff --git a/loader/samples/minexample/bin.cfg b/loader/samples/minexample/bin.cfg deleted file mode 100644 index 88a98b7..0000000 --- a/loader/samples/minexample/bin.cfg +++ /dev/null @@ -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; -} diff --git a/loader/samples/minexample/build_liltalk.sh b/loader/samples/minexample/build_liltalk.sh deleted file mode 100644 index 79c5207..0000000 --- a/loader/samples/minexample/build_liltalk.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -rm lilia_talk*.* -../../../assets/png2prg_linux_amd64 -m koala -o lilia_talk.bin ../../../assets/11_lilia_final.csv - - diff --git a/loader/samples/minexample/clouds.bin b/loader/samples/minexample/clouds.bin deleted file mode 100644 index 81495c1..0000000 Binary files a/loader/samples/minexample/clouds.bin and /dev/null differ diff --git a/loader/samples/minexample/conv_liltalk.py b/loader/samples/minexample/conv_liltalk.py deleted file mode 100644 index f35b116..0000000 --- a/loader/samples/minexample/conv_liltalk.py +++ /dev/null @@ -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() \ No newline at end of file diff --git a/loader/samples/minexample/font.bin b/loader/samples/minexample/font.bin index 1307827..8328344 100644 Binary files a/loader/samples/minexample/font.bin and b/loader/samples/minexample/font.bin differ diff --git a/loader/samples/minexample/furC64/.gitignore b/loader/samples/minexample/furC64/.gitignore deleted file mode 100644 index 6b8c623..0000000 --- a/loader/samples/minexample/furC64/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -__pycache__ -asm/song.asm -asm/song.bin -*.o -*.lbl -*.lst -*.map -*.prg diff --git a/loader/samples/minexample/furC64/README.md b/loader/samples/minexample/furC64/README.md deleted file mode 100644 index 927b587..0000000 --- a/loader/samples/minexample/furC64/README.md +++ /dev/null @@ -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 - diff --git a/loader/samples/minexample/furC64/asm/bin.cfg b/loader/samples/minexample/furC64/asm/bin.cfg deleted file mode 100644 index bf5f6ea..0000000 --- a/loader/samples/minexample/furC64/asm/bin.cfg +++ /dev/null @@ -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; -} diff --git a/loader/samples/minexample/furC64/asm/exe.cfg b/loader/samples/minexample/furC64/asm/exe.cfg deleted file mode 100644 index bb41d47..0000000 --- a/loader/samples/minexample/furC64/asm/exe.cfg +++ /dev/null @@ -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; -} diff --git a/loader/samples/minexample/furC64/asm/furC64.asm b/loader/samples/minexample/furC64/asm/furC64.asm deleted file mode 100644 index 0459488..0000000 --- a/loader/samples/minexample/furC64/asm/furC64.asm +++ /dev/null @@ -1,2202 +0,0 @@ -.feature c_comments - -.define chnum 3 -.define use_zp 0 -.define porta_once 0 -.define compat_hr 0 -.define CHIP_AMT 1 -.define DIGI 0 -.define HR_ADSR 1 -TEST_AD := $00 -TEST_SR := $00 - -;.define compat_hr 1 -;TEST_AD := $0f -;TEST_SR := $0f - - -.if DIGI = 0 -.define outch chnum -.else -.define outch 4 -.endif - -.macro variables -start_vars = * - -mframeW: .res chnum -doMacroW: .res chnum - -; why -env_reset_buf: .res chnum -env_reset: .res chnum - -fil_lo_n2: .res CHIP_AMT -fil_hi_n2: .res CHIP_AMT -fil_st2: .res CHIP_AMT - -legato: .res chnum - -test_reset: .res chnum - -note_tick: .res chnum - -dur: .res chnum - -vibrato_param: .res chnum -vibrato_phase: .res chnum - -absfil: .res CHIP_AMT - -doMacroC: .res CHIP_AMT -mframeC: .res CHIP_AMT - -instF: .res CHIP_AMT - -wav: .res chnum - -hrframe: .res chnum - -hrc: .res chnum - -ad: .res chnum -sr: .res chnum - -patseq: .res chnum*2 - -duty_lo: .res chnum -duty_hi: .res chnum - -nextpat: .res 1 -patind: .res 1 -jumppat: .res 1 -ch: .res 1 -chm: .res 1 -tick: .res 1 -ins: .res chnum -inst_prev: .res chnum -mframeA: .res chnum -mframeD: .res chnum -doMacroA: .res chnum -doMacroD: .res chnum -arp: .res chnum -absarp: .res chnum -effects_temp: .res 2 -tick_speeds: .res 2 -tick_sel: .res 1 -slide_amt: .res chnum -slide_amt_sign: .res chnum -slide_buffer_lo: .res chnum -slide_buffer_hi: .res chnum -note_pitch_lo: .res chnum -note_pitch_hi: .res chnum -note_n: .res chnum -note_temp: .res chnum -note_dest: .res chnum -finepitch: .res chnum -cut_dur: .res chnum -pw_mod_lo: .res chnum -pw_mod_hi: .res chnum -abspw: .res chnum -retrigger_pw: .res chnum -retrigger_fil: .res CHIP_AMT -triggered_fil: .res CHIP_AMT -.if porta_once = 1 -didporta: .res chnum -.endif -arpeff1: .res chnum -arpeff2: .res chnum -arpind: .res chnum -vol: .res CHIP_AMT -res: .res CHIP_AMT -fil_lo: .res CHIP_AMT -fil_hi: .res CHIP_AMT -fil_lo_n: .res CHIP_AMT -fil_hi_n: .res CHIP_AMT -base: .res 1 -chipnum: .res 1 -has_played: .res chnum -extin: .res 1 -vars_len = *-start_vars - -.endmacro - -inst_buffer = ins - -.if chnum > 4 -.define actual_use_zp 0 -.else -.define actual_use_zp use_zp -.endif - -.ZEROPAGE -.if actual_use_zp = 1 -.org $10 -variables -.endif -patzp := $fe -macroIns := patzp -temp := patzp-4 -flags_temp := temp+3 -patloop = 0 - -.segment "CODE" - -.org $080D -jmp $900 -.res $0900-* -.import __PLAYER_LOAD__, __PLAYER_RUN__, __PLAYER_SIZE__ -main: - sei - lda #$35 - sta $01 - - lda #<__PLAYER_LOAD__ - sta temp - lda #>__PLAYER_LOAD__ - sta temp+1 - lda #<__PLAYER_RUN__ - sta temp+2 - lda #>__PLAYER_RUN__ - sta temp+3 - ldy #0 - ldx #>__PLAYER_SIZE__ - beq :+++ -: - lda (temp),y - sta (temp+2),y - iny - bne :- - inc temp+1 - inc temp+3 - dex - bne :- - beq :++ -: - lda (temp),y - sta (temp+2),y - iny -: - cpy #<__PLAYER_SIZE__ - bne :-- - - lda #127 - sta $dc0d - - and $d011 - sta $d011 - - lda $dc0d - lda $dd0d - - lda #irq - sta $ffff - -.if DIGI <> 0 - lda #$0b - sta $d011 - lda #$00 -.else - lda #$10 -.endif - sta $d012 - - lda #0 - sta $d01a - - lda #$63; <(985248/100) - sta $dc04 - lda #$26;>(985248/100) - sta $dc05 - - lda $dc0d - and #$81 - sta $dc0d - - lda #$40 - sta $dc0c - - lda #$81 - sta $dc0d - - -.if DIGI <> 0 -ldx #0 -: - lda real_addr, x - sta $2, x - inx - cpx #nmi_end-nmi - bne :- -.endif - - lda #0 - jsr init - -.if DIGI <> 0 -lda #nmi -sta $fffb - -lda #$01 -sta $dd0d -sta $dd0e - -lda #$88 ; lo -sta $dd04 -lda #0 -sta $dd05 ; hi - -lda $dd0d -lda #$81 -sta $dd0d - -lda #$40 -sta $dd0c -.endif - - cli - jmp * - -irq: - pha - txa - pha - tya - pha - - .if DIGI = 0 - inc $d020 - .endif - - ;lda $d012 - ;sta rastertime - jsr play - - .if DIGI = 0 - dec $d020 - .endif - - ;lda $d012 - ;sec - ;sbc rastertime - ;sta rastertime - - ;asl $d019 - pla - tay - pla - tax - pla - ;rti - jmp $dc0c - -;rastertime: .res 1 - -.if DIGI <> 0 -real_addr = * -.org $2 -nmi: - sta z:ldat+1 -ldn: - lda $200 - sta $d418 - inc ldn+1 -ldat: - lda #0 - jmp $dd0c -NMI_BUFFER: - ldy #0 -NMI_LOOP: - lda z:nmi_add+2 -nmi_cmp: - cmp #0 - bcc nmi_store -nmi_cmp2: - lda #0 - sta z:nmi_add+2 -nmi_none: - lda vol - and #$f0 - ora #10 - sta $200, y - jmp NMI_LOOP_END - -nmi_store: - lda vol - and #$f0 -nmi_add: - ora $1000 - sta $200, y - clc -nmi_freq_lo2: - lda #0 -nmi_freq_lo: - adc #0 - sta nmi_freq_lo2+1 - lda nmi_add+1 -nmi_freq_hi: - adc #1 - sta nmi_add+1 - bcc NMI_LOOP_END - inc nmi_add+2 -NMI_LOOP_END: - iny - cpy #144 - bne NMI_LOOP - rts -nmi_end: -.org real_addr+(nmi_end-nmi) -.endif - -.segment "PLAYER" -.reloc -init: -jmp initaddr -play: -jmp playaddr -jmp extaddr -.byte " furC64 driver by AArt1256" - -.if actual_use_zp = 0 -variables -.endif -table_1_to_ff: -table_fil: - .byte 0 - .res 15, $ff - -.proc initaddr -.if actual_use_zp = 1 - ldx #vars_len - lda #0 -: - sta start_vars-1, x - dex - bne :- -.endif - - - ldx #(CHIP_AMT)-1 -: - lda #$7f - sta vol, x - lda #$00 - sta res, x - sta retrigger_fil, x - sta triggered_fil, x - lda #$ff - sta fil_lo, x - sta fil_lo_n, x - lda #$07 - sta fil_hi, x - sta fil_hi_n, x - lda #0 - sta doMacroC, x - sta absfil, x - sta fil_lo_n2, x - sta fil_hi_n2, x - sta fil_st2, x - sta mframeC, x - sta has_played, x - dex - bpl :- - - lda #0 - sta tick_sel - - lda ticks_init - sta tick_speeds - lda ticks_init+1 - sta tick_speeds+1 - - lda #0 - sta patind - - ldx #chnum-1 -: - lda #$80 - sta finepitch, x - sta finepitch, x - lda #1 - sta dur, x - lda #$ff - sta cut_dur, x - lda #0 - sta pw_mod_lo, x - sta pw_mod_hi, x -.if porta_once = 1 - sta didporta, x -.endif - sta wav, x - sta retrigger_pw, x - sta abspw, x - sta ins, x - sta inst_prev, x - sta arp, x - sta slide_amt, x - sta slide_amt_sign, x - sta slide_buffer_lo, x - sta slide_buffer_hi, x - sta vibrato_phase, x - sta vibrato_param, x - sta note_dest, x - sta mframeA, x - sta mframeW, x - sta mframeD, x - sta doMacroA, x - sta doMacroW, x - sta doMacroD, x - lda #$ff - sta env_reset_buf, x - lda #8 - sta test_reset, x - lda #4 - sta hrframe, x - sta note_tick, x - dex - bpl :- - - ldx #0 - jsr set_patseq_init - lda #0 - sta tick - sta jumppat - - rts -.endproc - -.macro get_patzp - .local skipW - inc patzp - bne skipW - inc patzp+1 -skipW: - lda (patzp), y -.endmacro - -.macro get_patzp_vol - .local skipW - inc patzp - bne skipW - inc patzp+1 -skipW: - lda vol - and #$f0 - ora (patzp), y -.endmacro - -.macro add_09xx -effectE0: - get_patzp - sta tick_speeds - jmp begnote -.endmacro - - -.macro add_0Fxx -effectE1: - get_patzp - sta tick_speeds+1 - jmp begnote -.endmacro - -.macro add_0Bxx -effectED: - get_patzp - sta patind - lda #$ff - sta jumppat - jmp begnote -.endmacro - - -.macro add_00xx -effectE2: - get_patzp - sta effects_temp+1 - ldx ch - lda #0 - sta arpind, x - lda effects_temp+1 - and #$0f - sta arpeff2, x - lda effects_temp+1 - lsr - lsr - lsr - lsr - sta arpeff1, x - jmp begnote -.endmacro - - -.macro add_01xx -effectE3: - get_patzp - ldx ch - sta slide_amt, x - lda #$ff - sta slide_amt_sign, x - ldx ch - lda #88 - sta note_dest, x -.if porta_once = 1 - lda #$00 - sta didporta, x -.endif - jmp begnote -.endmacro - -.macro add_02xx -effectE4: - get_patzp - ldx ch - sta slide_amt, x - lda #$00 - sta slide_amt_sign, x - ldx ch - lda #0 - sta note_dest, x -.if porta_once = 1 - lda #$00 - sta didporta, x -.endif - jmp begnote -.endmacro - -.macro add_03xx -effectE5: - get_patzp - ldx ch - sta slide_amt, x - ldy #0 - get_patzp - ldx ch - sta note_dest, x - -.if porta_once = 1 - lda #$ff - sta didporta, x -.endif - - lda note_n, x - cmp note_dest, x - bne :+ - lda #0 - sta slide_amt, x - sta slide_amt_sign, x - jmp begnote -: - bcc :+ - lda #$00 - sta slide_amt_sign, x - jmp begnote -: - lda #$ff - sta slide_amt_sign, x - jmp begnote -.endmacro - -.macro add_04xx - .local retskip -effectE6: - get_patzp - ldx ch - sta vibrato_param, x - beq retskip - sta vibrato_phase, x -retskip: - jmp begnote -.endmacro - -.macro add_1Axx -effectF1: - get_patzp - ldx ch - eor #$ff - sta env_reset_buf, x - jmp begnote -.endmacro - - -.macro add_1Bxx - .local retskip -effectE7: - get_patzp - sta effects_temp+1 - and #$0f - tax - lda table_fil, x - ldx ch - beq :+ - ldx chipnum - lda fil_lo_n, x - sta fil_lo, x - lda fil_hi_n, x - sta fil_hi, x - ldx ch -: - lda effects_temp+1 - lsr - lsr - lsr - lsr - tax - lda table_fil, x - ldx chipnum - sta retrigger_fil, x - jmp begnote -.endmacro - -.macro add_1Cxx - .local retskip -effectE8: - get_patzp - sta effects_temp+1 - and #$0f - tax - lda table_fil, x - ldx ch - beq :+ - lda #0 - sta pw_mod_lo, x - sta pw_mod_hi, x -: - lda effects_temp+1 - lsr - lsr - lsr - lsr - tax - lda table_fil, x - ldx ch - sta retrigger_pw, x - jmp begnote -.endmacro - -.macro add_E1xx -effectE9: - get_patzp - ldx ch - asl - asl - sta slide_amt, x - lda #$ff - sta slide_amt_sign, x - ldy #0 - get_patzp - ldx ch - ora #$80 - sta note_dest, x -.if porta_once = 1 - lda #$00 - sta didporta, x -.endif - jmp begnote -.endmacro - -.macro add_E2xx -effectEA: - get_patzp - ldx ch - asl - asl - sta slide_amt, x - lda #$00 - sta slide_amt_sign, x - ldy #0 - get_patzp - ldx ch - ora #$80 - sta note_dest, x -.if porta_once = 1 - lda #$00 - sta didporta, x -.endif - jmp begnote -.endmacro - - -.macro add_E5xx -effectEB: - get_patzp - ldx ch - sta finepitch, x - jmp begnote -.endmacro - -.macro add_ECxx -effectEC: - get_patzp - ldx ch - clc - .if compat_hr = 0 - adc #3 - .else - adc #2 - .endif - sta cut_dur, x - jmp begnote -.endmacro - -.macro add_4xxx -effectEE: - ldx chipnum - lda #0 - sta doMacroC, x - sta fil_hi_n2, x - lda #$ff - sta fil_st2, x - get_patzp - ldx chipnum - sta fil_lo_n2, x - clc - asl fil_lo_n2, x - rol fil_hi_n2, x - clc - asl fil_lo_n2, x - rol fil_hi_n2, x - clc - asl fil_lo_n2, x - rol fil_hi_n2, x - jmp begnote -.endmacro - - -.macro add_EAxx -effectEF: - ldx ch - lda #0 - sta legato, x - jmp begnote - -effectF0: - ldx ch - lda #$ff - sta legato, x - jmp begnote -.endmacro - -.macro add_EExx -effectF2: - get_patzp - ldx extin - beq :+ - sta patind - lda #$ff - sta jumppat -: - jmp begnote -.endmacro - -add_09xx -add_0Fxx -add_00xx -add_01xx -add_02xx -add_03xx -add_04xx -add_0Bxx -add_1Axx -add_1Bxx -add_1Cxx -add_E1xx -add_E2xx -add_E5xx -add_EAxx -add_ECxx -add_4xxx -add_EExx - -other_effects: - lda effects_temp - cmp #$FB - bne :+ - ldx ch - get_patzp - sta ins, x - jmp begnote -: - cmp #$FC - bne :+ - ldx chipnum - get_patzp_vol - sta vol, x - jmp begnote -: - - cmp #$FD - bne :+ - ldx ch - ldy ins, x - lda insArel, y - sta mframeA, x - lda insDrel, y - sta mframeD, x - ldx ch - .if compat_hr = 0 - lda #3 - .else - lda #2 - .endif - sta cut_dur, x - lda #1 - sta dur, x - ldy #0 - jmp end_advance -: - - cmp #$FE - bne :+ - ldx ch - .if compat_hr = 0 - lda #3 - .else - lda #2 - .endif - sta cut_dur, x - lda #1 - sta dur, x - ldy #0 - jmp end_advance -: - lda effects_temp - cmp #224 - bcc cont_advance - - lda effects_temp - and #$1f - tax - lda eff_lo, x - sta effect_smc+1 - lda eff_hi, x - sta effect_smc+2 - ldx ch - lda effects_temp -effect_smc: - jmp cont_advance - -eff_lo: -.repeat $13, I - .lobytes .ident(.concat ("effect", .sprintf("%02X",I+$e0))) -.endrepeat -eff_hi: -.repeat $13, I - .hibytes .ident(.concat ("effect", .sprintf("%02X",I+$e0))) -.endrepeat - -.macro add_advance_routine -advance: - .local skipD, noIns, noVol, beg, blank2, blank3, hasNote, wait -beg: - lda ch - asl - tax - lda patseq, x - sta patzp - lda patseq+1, x - sta patzp+1 - - ldx ch - dec dur, x - lda dur, x - beq begnote - jmp end_advance -begnote: - - ldy #0 - get_patzp - sta temp - sta effects_temp - and #$80 - beq wait - lda temp - cmp #$ff - beq blank2 - jmp other_effects -cont_advance: - lda temp - and #$7f - ldx ch - - ldy env_reset_buf, x - beq :+ - sta note_n, x -: - sta note_temp, x - - lda note_tick, x - cmp #96 - bne :+ - lda #0 - sta slide_amt, x - sta slide_amt_sign, x -: - lda note_tick, x - cmp #2 - bcc :+ - lda legato, x - bne :+ - lda #0 - sta hrframe, x - lda #$ff - sta hrc, x -: - lda #0 - sta slide_buffer_lo, x - sta slide_buffer_hi, x - sta note_tick, x -.if porta_once = 1 - cmp didporta, x - beq :+ - sta didporta, x - sta slide_amt, x - sta slide_amt_sign, x -: -.endif - ldx ch - lda env_reset_buf, x - sta env_reset, x - lda #1 - sta dur, x - sta has_played, x - ldy #0 - jmp end_advance - -wait: - lda temp - and #$40 - beq :+ - ldx ch - lda temp - and #$3f - sta ins, x - jmp begnote -: - lda temp - ldx ch - sta dur, x -blank2: - lda temp - cmp #$ff - bne end_advance - - lda #$ff - sta nextpat - -end_advance: - lda ch - asl - tax - lda patzp - sta patseq, x - lda patzp+1 - sta patseq+1, x - rts -.endmacro - -add_advance_routine - -.macro add_insarp -insarp: - .local end, skip1, beg, skip2 -beg: - ldx ch - lda doMacroA, x - beq end - - ldx ch - ldy inst_buffer, x - lda insAL, y - sta macroIns - lda insAH, y - sta macroIns+1 - ldx ch - ldy mframeA, x - lda (macroIns), y - cmp #$fe - beq skip2 - cmp #$ff - bne skip1 - iny - lda (macroIns), y - cmp #$ff - beq :+ - sta mframeA, x - jmp beg -: - lda #0 - sta doMacroA, x - rts -skip1: - sec - sbc #128 - sta arp, x - lda #0 - sta absarp, x - inc mframeA, x - rts -skip2: - iny - lda (macroIns), y - sta arp, x - lda #$ff - sta absarp, x - inc mframeA, x - inc mframeA, x -end: - rts -.endmacro - -add_insarp - -.macro add_insduty -insduty: - .local end, skip1, beg, skip2 -beg: - ldx ch - lda doMacroD, x - beq end - - ldx ch - ldy inst_buffer, x - lda insDL, y - sta macroIns - lda insDH, y - sta macroIns+1 - - ;ldx ch - - ldy mframeD, x - lda (macroIns), y - sta temp - cmp #$ff - bne skip1 - iny - lda (macroIns), y - cmp #$ff - beq :+ - sta mframeD, x - jmp beg -: - lda #0 - sta doMacroD, x - rts -skip1: - iny - lda (macroIns), y - sta temp+1 - - lda abspw, x - bne :+ - - lda temp+1 - sec - sbc #$80 - sta temp+1 - lda pw_mod_lo, x - clc - adc temp - sta pw_mod_lo, x - lda pw_mod_hi, x - adc temp+1 - sta pw_mod_hi, x - inc mframeD, x - inc mframeD, x - rts -: - lda temp - sta duty_lo, x - lda temp+1 - sta duty_hi, x - lda #0 - sta pw_mod_lo, x - sta pw_mod_hi, x - inc mframeD, x - inc mframeD, x -end: - rts -.endmacro - -add_insduty - -.macro add_inswave -inswave: - .local end, skip1, beg, skip2 -beg: - ldx ch - lda doMacroW, x - beq end - - ldx ch - ldy inst_buffer, x - lda insWL, y - sta macroIns - lda insWH, y - sta macroIns+1 - ldx ch - ldy mframeW, x - lda (macroIns), y - cmp #$ff - bne skip1 - iny - lda (macroIns), y - cmp #$ff - beq :+ - sta mframeW, x - jmp beg -: - lda #0 - sta doMacroW, x - rts -skip1: - ldx ch - pha - lda wav, x - and #$0f - sta wav, x - pla - ora wav, x - sta wav, x - inc mframeW, x -end: - rts -.endmacro - -add_inswave - -.macro add_inscut -inscut: - .local end, skip1, beg, skip2 -beg: - ldx ch - lda doMacroC, x - beq end - - ldx ch - ldy instF, x - lda insCL, y - sta macroIns - lda insCH, y - sta macroIns+1 - ldx ch - ldy mframeC, x - lda (macroIns), y - sta temp - cmp #$ff - bne skip1 - iny - lda (macroIns), y - cmp #$ff - beq :+ - sta mframeC, x - jmp beg -: - lda #0 - sta doMacroC, x - rts -skip1: - iny - lda (macroIns), y - sta temp+1 - - lda absfil, x - bne :+ - - lda temp+1 - sec - sbc #$80 - sta temp+1 - - lda fil_lo, x - clc - adc temp - sta fil_lo, x - lda fil_hi, x - adc temp+1 - sta fil_hi, x - jmp :++ -: - lda temp - sta fil_lo, x - lda temp+1 - sta fil_hi, x -: - inc mframeC, x - inc mframeC, x -end: - rts -.endmacro - -add_inscut - -.macro cmp16 val1, val2 -/* - .if 0 - lda val1 - sec - sbc val2 - php - lda val1+1 - sbc val2+1 - php - pla - sta macroIns - pla - and #%00000010 - ora #%11111101 - and macroIns - pha - plp - .else - lda val1 - sec - sbc val2 - lda val1+1 - sbc val2+1 - .endif - */ - lda val1 - sec - sbc val2 - lda val1+1 - sbc val2+1 -.endmacro - -doFinepitch: - lda vibrato_param, x - lsr - lsr - lsr - lsr - clc - adc vibrato_phase, x - and #63 - sta vibrato_phase, x - tay - lda vibrato_param, x - and #$0f - ora triangle_lookup, y - tay - - - ; this is NOT a typo! - sec - lda note_pitch_lo, x - sbc finepitch, x - sta temp - lda note_pitch_hi, x - sbc #$fe - sta temp+1 - -; bcs skip_pitch -; lda #0 -; sta temp -; sta temp+1 -;skip_pitch: - -.repeat 3 - lda tri_vibrato_lookup, y - ;lsr - ;clc - ;adc tri_vibrato_lookup, y - eor #$ff - - clc - adc temp - sta temp - lda temp+1 - adc #$ff - sta temp+1 -.endrepeat - rts - -.macro add_do_ch -do_ch_jsr: - .local skipHR1, skipHR2, end - ldx ch - lda hrc, x - beq skipHR1 - - lda #0 - sta hrc, x -.if HR_ADSR <> 0 - lda env_reset, x - beq :+ - lda #0 - sta env_reset, x - - lda #TEST_AD - sta ad, x - lda #TEST_SR - sta sr, x - lda wav, x - and #255^1 - ora test_reset, x - sta wav, x -: -.else - lda inst_buffer, x - tax - lda insFL, x - sta patzp - lda insFH, x - sta patzp+1 - ldx ch - ldy #1 - lda (patzp), y - sta ad, x - iny - lda (patzp), y - ldy base - sta sr, x - lda wav, x - and #255^1 - ora test_reset, x - sta wav, x -.endif - lda #0 - sta doMacroA, x - sta doMacroD, x - sta doMacroW, x - -skipHR1: - - lda hrframe, x - cmp #4 - bne :+ - jmp skipHR2 -: - - inc hrframe, x - -.if compat_hr = 0 - cmp #2 -.else - cmp #1 -.endif - beq :+ - jmp skipHR2 -: - - ldx ch - - ; for 1Axx - lda note_temp, x - sta note_n, x - - lda #0 - sta mframeA, x - sta mframeD, x - sta mframeW, x - lda #$ff - sta doMacroA, x - sta doMacroD, x - sta doMacroW, x - - lda inst_buffer, x - tax - lda insFL, x - sta patzp - lda insFH, x - sta patzp+1 - - ldx ch - ldy #1 - lda (patzp), y - sta ad, x - iny - lda (patzp), y - sta sr, x - - iny - lda (patzp), y - sta duty_lo, x - iny - lda (patzp), y - sta duty_hi, x - - iny - lda (patzp), y - sta flags_temp - and #1 - ;tay - ;lda table_1_to_ff, y - sta abspw, x - - lda flags_temp - and #2 - beq :+ - lda #0 - sta pw_mod_lo, x - sta pw_mod_hi, x -: - - lda flags_temp - and #4 - tay - ldx chipnum - lda res, x - ldx chm - and ch_filter_enable_inv, x - cpy #0 - beq :+ - ora ch_filter_enable, x -: - ldx chipnum - sta res, x - - lda flags_temp - and #8 - beq :++ - ldx chipnum - lda #0 - sta doMacroC, x - lda res, x - and #$0f - ldy #6 - ora (patzp), y - sta res, x - iny - lda vol, x - and #$0f - ora (patzp), y - sta vol, x - iny - lda (patzp), y - sta fil_lo_n, x - iny - lda (patzp), y - sta fil_hi_n, x - - lda flags_temp - and #32 - bne :++ - lda triggered_fil, x - beq :+ - lda retrigger_fil, x - beq :++ -: - lda #$ff - sta triggered_fil, x - lda fil_lo_n, x - sta fil_lo, x - lda fil_hi_n, x - sta fil_hi, x -: - - ldx ch - lda inst_buffer, x - cmp inst_prev, x - beq :+ - ldx chipnum - lda fil_lo_n, x - sta fil_lo, x - lda fil_hi_n, x - sta fil_hi, x - ldx ch - lda inst_buffer, x - sta inst_prev, x -: - - lda flags_temp - and #32 - beq :+ - ldx ch - lda inst_buffer, x - ldx chipnum - sta instF, x - lda #0 - sta mframeC, x - lda #$ff - sta doMacroC, x - - lda flags_temp - and #16 - lsr - tay - lda table_1_to_ff, y - ldy chipnum - sta absfil, y - -: - - lda flags_temp - and #64 - lsr - lsr - lsr - ldx ch - sta test_reset, x - - lda retrigger_pw, x - beq :+ - lda #0 - sta pw_mod_lo, x - sta pw_mod_hi, x -: - - lda mframeW, x - beq :+ - ldy #0 - lda (patzp), y - and #$0f - sta temp - lda wav, x - and #%11110000 - ora #1 - ora temp - sta wav, x - jmp skipHR2 -: - ldx ch - ldy #0 - lda (patzp), y - ora #1 - sta wav, x -skipHR2: - rts - -.endmacro - -add_do_ch - -.macro add_do_ch_DIGI -do_ch_DIGI: - .local skipHR1, skipHR2, skipHR_ADSR, end - - ldx #3 - jsr doFinepitch - -.repeat 4 - clc - lsr temp+1 - ror temp -.endrepeat - - lda temp - sta nmi_freq_lo+1 - lda temp+1 - sta nmi_freq_hi+1 - - ldx ch - lda hrc, x - beq skipHR1 - - lda #0 - sta hrc, x - sta doMacroA, x - sta doMacroD, x - sta doMacroW, x - -skipHR1: - - lda hrframe, x - cmp #4 - bne :+ - jmp skipHR2 -: - - inc hrframe, x - -.if compat_hr = 0 - cmp #2 -.else - cmp #1 -.endif - beq :+ - jmp skipHR_ADSR -: - - ldx ch - lda #0 - sta mframeA, x - sta mframeD, x - sta mframeW, x - lda #$ff - sta doMacroA, x - sta doMacroD, x - sta doMacroW, x - - lda inst_buffer, x - tax - lda insSI, x - tax - lda sampleHS, x - sta nmi_add+2 - lda #0 - sta nmi_add+1 - lda sampleHE, x - sta nmi_cmp+1 - sta nmi_cmp2+1 - -skipHR_ADSR: - -skipHR2: - rts - -.endmacro - -.if DIGI <> 0 - add_do_ch_DIGI -.endif - -.proc playaddr -.if DIGI <> 0 - lda #0 - sta ldn+1 - jsr NMI_BUFFER -.endif - - ldx tick_sel - inc tick - lda tick - cmp tick_speeds, x - bcs :+ - jmp skipseq -: - lda #0 - sta tick - -advance_tick: - - lda tick_sel - eor #1 - sta tick_sel - ldx #(CHIP_AMT)-1 - lda #0 -: - sta fil_st2, x - dex - bpl :- - - - .repeat chnum, I - lda #I - sta ch - lda #I/3 - sta chipnum - jsr advance - .endrepeat - - lda nextpat - beq skipnextpat - lda #0 - sta nextpat - lda jumppat - beq :+ - lda #0 - sta jumppat - jmp :++ -: - inc patind - lda patind - cmp #order0len - bne :+ - lda #0 ; #patloop - sta patind -: - jsr set_patseq - ldx #chnum-1 - lda #1 -durloop: - sta dur, x - dex - bpl durloop - jmp advance_tick -skipnextpat: - lda jumppat - beq :+ - lda #$ff - sta nextpat -: -skipseq: - -.if DIGI = 0 -.repeat chnum, I - ldx #I - stx ch - lda #I .mod 3 - sta chm - lda #(I .mod 3)*7+(I/3)*$20 - sta base - lda #I/3 - sta chipnum - jsr do_ch_jsr - ldx ch - lda #$ff - sta env_reset_buf, x -.endrepeat -.else -.repeat 4, I - ldx #I - stx ch - lda #I .mod 3 - sta chm - lda #(I .mod 3)*7+(I/3)*$20 - sta base - lda #I/3 - sta chipnum - .if I = 3 - jsr do_ch_DIGI - .else - jsr do_ch_jsr - .endif - ldx ch - lda #$ff - sta env_reset_buf, x -.endrepeat -.endif - - -.repeat chnum, I - lda #I - sta ch - jsr insarp - jsr inswave - jsr insduty -.endrepeat - -.repeat CHIP_AMT, I - lda #I - sta ch - jsr inscut - ldx ch - lda fil_st2, x - beq :+ - lda fil_lo_n2, x - sta fil_lo, x - lda fil_hi_n2, x - sta fil_hi, x -: - -.endrepeat - - ldx #chnum-1 -note_cut_loop: - lda cut_dur, x - cmp #$ff - beq note_cut_loop_end - dec cut_dur, x - lda cut_dur, x - bne note_cut_loop_end - - lda #$ff - sta cut_dur, x - - lda wav, x - and #%11111110 - sta wav, x - -note_cut_loop_end: - dex - bpl note_cut_loop - - ldx #chnum-1 -relslide_loop: - lda note_dest, x - and #$80 - beq slide_skip - eor note_dest, x - sta macroIns - lda slide_amt_sign, x - beq positive_slide2 - lda note_n, x - clc - adc macroIns - jsr clamp_note - sta note_dest, x - jmp slide_skip -positive_slide2: - lda note_n, x - sec - sbc macroIns - jsr clamp_note - sta note_dest, x -slide_skip: - dex - bpl relslide_loop - - ldx #chnum-1 -note_loop: - lda absarp, x - beq nrel - lda arp, x - and #127 - jmp nout -nrel: - lda note_n, x - clc - ;adc arp, x -nout: - ;clc - jsr add_arpeff - jsr clamp_note - tay - clc - lda note_table_lo, y - adc slide_buffer_lo, x - sta note_pitch_lo, x - lda note_table_hi, y - adc slide_buffer_hi, x - sta note_pitch_hi, x - dex - bpl note_loop - - ldx #chnum-1 -slide_loop: - lda slide_amt, x - beq slide_loop2 - - lda slide_amt_sign, x - bne positive_slide - sec - lda slide_buffer_lo, x - sbc slide_amt, x - sta slide_buffer_lo, x - bcs :+ - dec slide_buffer_hi, x -: - - ldy note_dest, x - lda note_table_lo, y - sec - sbc note_pitch_lo, x - lda note_table_hi, y - sbc note_pitch_hi, x - bcc slide_loop2 - jmp finish_slide -positive_slide: - clc - lda slide_buffer_lo, x - adc slide_amt, x - sta slide_buffer_lo, x - bcc :+ - inc slide_buffer_hi, x -: - jmp :+ -finish_slide: - lda note_dest, x - sta note_n, x - lda #0 - sta slide_buffer_lo, x - sta slide_buffer_hi, x - sta slide_amt, x - sta slide_amt_sign, x - jmp slide_loop2 -: - ldy note_dest, x - lda note_pitch_lo, x - sec - sbc note_table_lo, y - lda note_pitch_hi, x - sbc note_table_hi, y - bcc slide_loop2 - jmp finish_slide - -slide_loop2: - dex - bpl slide_loop - - ldx #chnum-1 -: - lda note_tick, x - cmp #96 - beq note_tick_loop - inc note_tick, x -note_tick_loop: - - lda has_played, x - bne note_tick_loop2 - lda #3 - sta note_tick, x -note_tick_loop2: - dex - bpl :- - -.if DIGI = 0 -lda vol -sta $d418 -.if chnum >= 6 -lda vol+1 -sta $d438 -.endif -.if chnum >= 9 -lda vol+2 -sta $d458 -.endif -.if chnum >= 12 -lda vol+3 -sta $d478 -.endif -.endif - -lda res -sta $d417 -.if chnum >= 6 -lda res+1 -sta $d437 -.endif -.if chnum >= 9 -lda res+2 -sta $d457 -.endif -.if chnum >= 12 -lda res+3 -sta $d477 -.endif - -lda fil_lo -sta temp -lda fil_hi -sta temp+1 - -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp - -lda temp -sta $d416 - -.if chnum >= 6 -lda fil_lo+1 -sta temp -lda fil_hi+1 -sta temp+1 - -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp - -lda temp -sta $d436 -.endif - -.if chnum >= 9 -lda fil_lo+2 -sta temp -lda fil_hi+2 -sta temp+1 - -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp - -lda temp -sta $d456 -.endif - -.if chnum >= 12 -lda fil_lo+2 -sta temp -lda fil_hi+2 -sta temp+1 - -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp -clc -lsr temp+1 -ror temp - -lda temp -sta $d476 -.endif - - ldx #chnum-1 -note_loop3: - lda absarp, x - beq nrel3 - lda arp, x - and #127 - jmp nout3 -nrel3: - lda note_n, x - clc - adc arp, x -nout3: - clc - jsr add_arpeff - jsr clamp_note - tay - clc - lda note_table_lo, y - adc slide_buffer_lo, x - sta note_pitch_lo, x - lda note_table_hi, y - adc slide_buffer_hi, x - sta note_pitch_hi, x - dex - bpl note_loop3 - -.repeat CHIP_AMT, J - ldx #2 -: - txa - clc - adc #J*3 - tax - jsr doFinepitch - txa - sec - sbc #J*3 - tax - - ldy ch_mul_tabl, x - lda temp - sta $d400+J*$20,y - lda temp+1 - sta $d401+J*$20, y - - lda ad+J*3, x - sta $d405+J*$20, y - lda sr+J*3, x - sta $d406+J*$20, y - - lda wav+J*3, x - sta $d404+J*$20, y - lda duty_lo+J*3, x - clc - adc pw_mod_lo+J*3, x - sta $d402+J*$20, y - lda duty_hi+J*3, x - adc pw_mod_hi+J*3, x - and #$0f - sta $d403+J*$20, y - - dex - bpl :- -.endrepeat - rts -.endproc - -set_patseq: - stx temp+2 - - ldx patind - - .repeat chnum, I - lda .ident(.concat ("order", .sprintf("%d",I), "L")), x - sta patseq+0+2*I - lda .ident(.concat ("order", .sprintf("%d",I), "H")), x - sta patseq+1+2*I - .endrepeat - - ldx temp+2 - rts - -set_patseq_init: - .repeat chnum, I - ldx patind - lda .ident(.concat ("order", .sprintf("%d",I), "L")), x - sta patseq+0+2*I - lda .ident(.concat ("order", .sprintf("%d",I), "H")), x - sta patseq+1+2*I - .endrepeat - rts - -add_arpeff: - pha - inc arpind, x - ldy arpind, x - lda arp_mod, y - sta arpind, x - tay - pla - cpy #1 - beq arp1 - cpy #2 - beq arp2 - rts - -arp1: - clc - adc arpeff1, x - rts - -arp2: - clc - adc arpeff2, x - rts - -arp_mod: -.byte 0,1,2,0 - -ch_mul_tabl: -.byte 0,7,14 - -clamp_note: - cmp #95 - bcc :+ - lda #95 -: - rts - -.proc extaddr - sta extin - lda patind - rts -.endproc - -note_table_lo: - .incbin "note_lo.bin" -note_table_hi: - .incbin "note_hi.bin" - -ch_filter_enable: -.byte 1, 2, 4 -ch_filter_enable_inv: -.byte 255^1, 255^2, 255^4 - -triangle_lookup: - .repeat 64, I - .if (I+0)&32 - .byte ((32-(((I+0)&63)-32)-1)>>1)<<4 - .else - .byte (((I+0)&63)>>1)<<4 - .endif - .endrepeat - -tri_vibrato_lookup: - .repeat 16, J - .repeat 16, I - ;.byte ((I*((J>>1)-15)*2)/15)+$1f - VAL .set ((I*((J<<1)-15)*2)/3) - .if (VAL+$80) < 0 - .byte 0 - .elseif (VAL+$80) > 255 - .byte $ff - .else - .byte VAL+$80 - .endif - .endrepeat - .endrepeat - -.include "song.asm" - -;.res 4096, $00 \ No newline at end of file diff --git a/loader/samples/minexample/furC64/asm/note_hi.bin b/loader/samples/minexample/furC64/asm/note_hi.bin deleted file mode 100644 index a472973..0000000 --- a/loader/samples/minexample/furC64/asm/note_hi.bin +++ /dev/null @@ -1,3 +0,0 @@ - - -  "$')+.147:>AEINRW\bhnu|ƒ‹“œ¥¯¹ÄÐÜêøÿ \ No newline at end of file diff --git a/loader/samples/minexample/furC64/asm/note_lo.bin b/loader/samples/minexample/furC64/asm/note_lo.bin deleted file mode 100644 index ee26c5b..0000000 --- a/loader/samples/minexample/furC64/asm/note_lo.bin +++ /dev/null @@ -1 +0,0 @@ -&8K^s‰¡¹Ôð ,Mq–½çBs¨àY›â,{Î'„çQÀ6³7ÄYöN Ï¢mgoˆ²í:œŸDÚÎßdÚu8&?‰´œ¿"È´ëqLh8EhÖã˜ÿ$ÿ \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/__init__.py b/loader/samples/minexample/furC64/chipchune/__init__.py deleted file mode 100644 index fd53fbd..0000000 --- a/loader/samples/minexample/furC64/chipchune/__init__.py +++ /dev/null @@ -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" diff --git a/loader/samples/minexample/furC64/chipchune/_util.py b/loader/samples/minexample/furC64/chipchune/_util.py deleted file mode 100644 index 4fa2842..0000000 --- a/loader/samples/minexample/furC64/chipchune/_util.py +++ /dev/null @@ -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(' int: - """ - 2 bytes - """ - if signed: - return cast(int, struct.unpack(' int: - """ - 1 bytes - """ - if signed: - return cast(int, struct.unpack(' float: - """ - 4 bytes - """ - return cast(float, struct.unpack(' 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') diff --git a/loader/samples/minexample/furC64/chipchune/deflemask/__init__.py b/loader/samples/minexample/furC64/chipchune/deflemask/__init__.py deleted file mode 100644 index 9399e49..0000000 --- a/loader/samples/minexample/furC64/chipchune/deflemask/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -soon! -""" \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/famitracker/__init__.py b/loader/samples/minexample/furC64/chipchune/famitracker/__init__.py deleted file mode 100644 index 9399e49..0000000 --- a/loader/samples/minexample/furC64/chipchune/famitracker/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -""" -soon! -""" \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/furnace/__init__.py b/loader/samples/minexample/furC64/chipchune/furnace/__init__.py deleted file mode 100644 index 32575fc..0000000 --- a/loader/samples/minexample/furC64/chipchune/furnace/__init__.py +++ /dev/null @@ -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) -""" diff --git a/loader/samples/minexample/furC64/chipchune/furnace/data_types.py b/loader/samples/minexample/furC64/chipchune/furnace/data_types.py deleted file mode 100644 index 0d5415e..0000000 --- a/loader/samples/minexample/furC64/chipchune/furnace/data_types.py +++ /dev/null @@ -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 "" % ( - 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 diff --git a/loader/samples/minexample/furC64/chipchune/furnace/enums.py b/loader/samples/minexample/furC64/chipchune/furnace/enums.py deleted file mode 100644 index d8b29c8..0000000 --- a/loader/samples/minexample/furC64/chipchune/furnace/enums.py +++ /dev/null @@ -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 diff --git a/loader/samples/minexample/furC64/chipchune/furnace/instrument.py b/loader/samples/minexample/furC64/chipchune/furnace/instrument.py deleted file mode 100644 index 0eaf3b0..0000000 --- a/loader/samples/minexample/furC64/chipchune/furnace/instrument.py +++ /dev/null @@ -1,1572 +0,0 @@ -from io import BytesIO -from typing import Optional, Union, BinaryIO, TypeVar, Type, List, Dict - -from chipchune._util import read_byte, read_short, read_int, read_str -from .data_types import ( - InsFeatureAbstract, InsFeatureMacro, InsMeta, InstrumentType, InsFeatureName, - InsFeatureFM, InsFeatureOpr1Macro, InsFeatureOpr2Macro, InsFeatureOpr3Macro, InsFeatureOpr4Macro, - InsFeatureC64, InsFeatureGB, GBHwSeq, SingleMacro, InsFeatureAmiga, InsFeatureOPLDrums, InsFeatureSNES, - GainMode, InsFeatureN163, InsFeatureFDS, InsFeatureWaveSynth, _InsFeaturePointerAbstract, InsFeatureSampleList, - InsFeatureWaveList, InsFeatureMultiPCM, InsFeatureSoundUnit, InsFeatureES5506, InsFeatureX1010, GenericADSR, - InsFeatureDPCMMap, InsFeaturePowerNoise, InsFeatureSID2 -) -from .enums import ( - _FurInsImportType, MacroCode, OpMacroCode, MacroItem, MacroType, GBHwCommand, - SNESSusMode, WaveFX, ESFilterMode, MacroSize -) - -FILE_MAGIC_STR = b'-Furnace instr.-' -DEV127_FILE_MAGIC_STR = b'FINS' - -EMBED_MAGIC_STR = b'INST' -DEV127_EMBED_MAGIC_STR = b'INS2' - -T_MACRO = TypeVar('T_MACRO', bound=InsFeatureMacro) # T_MACRO must be subclass of InsFeatureMacro -T_POINTERS = TypeVar('T_POINTERS', bound=_InsFeaturePointerAbstract) - - -class FurnaceInstrument: - def __init__(self, file_name: Optional[str] = None, protocol_version: Optional[int] = 1) -> None: - """ - Creates or opens a new Furnace instrument as a Python object. - - :param file_name: (Optional) - If specified, then it will parse a file as a FurnaceInstrument. If file name (str) is - given, it will load that file. - - Defaults to None. - - :param protocol_version: (Optional) - If specified, it will determine which format the instrument is to be serialized (exported) - to. It is ignored if loading up a file. - - Defaults to 2 (dev127+ ins. format) - """ - self.file_name: Optional[str] = None - """ - Original file name, if the object was initialized with one. - """ - self.protocol_version: Optional[int] = protocol_version - """ - Instrument file "protocol" version. Currently: - - 0: The "unified" instrument format up to Furnace version 126. - - 1: The new "featural" instrument format introduced in version 127. - """ - self.features: List[InsFeatureAbstract] = [] - """ - List of features, regardless of protocol version. - """ - self.meta: InsMeta = InsMeta() - """ - Instrument metadata. - """ - - # self.wavetables: list[] = [] - # self.samples: list[] = [] - - self.__map_to_fn = { - b'NA': self.__load_na_block, - b'FM': self.__load_fm_block, - b'MA': self.__load_ma_block, - b'64': self.__load_c64_block, - b'GB': self.__load_gb_block, - b'SM': self.__load_sm_block, - b'O1': self.__load_o1_block, - b'O2': self.__load_o2_block, - b'O3': self.__load_o3_block, - b'O4': self.__load_o4_block, - b'LD': self.__load_ld_block, - b'SN': self.__load_sn_block, - b'N1': self.__load_n1_block, - b'FD': self.__load_fd_block, - b'WS': self.__load_ws_block, - b'SL': self.__load_sl_block, - b'WL': self.__load_wl_block, - b'MP': self.__load_mp_block, - b'SU': self.__load_su_block, - b'ES': self.__load_es_block, - b'X1': self.__load_x1_block, - b'NE': self.__load_ne_block, - # TODO: No documentation? - #b'EF': self.__load_ef_block, - b'PN': self.__load_pn_block, - b'S2': self.__load_s2_block, - } - - 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, _FurInsImportType.FORMAT_0_FILE) - elif detect_magic[:len(DEV127_FILE_MAGIC_STR)] == DEV127_FILE_MAGIC_STR: - return self.load_from_stream(f, _FurInsImportType.FORMAT_1_FILE) - else: # uncompressed for sure - raise ValueError('No recognized file type magic') - - def load_from_bytes(self, data: bytes, import_as: Union[int, _FurInsImportType]) -> None: - """ - Load an instrument from a series of bytes. - - :param data: Bytes - :param import_as: int - see :method:`FurnaceInstrument.load_from_stream` - - """ - return self.load_from_stream( - BytesIO(data), - import_as - ) - - def load_from_stream(self, stream: BinaryIO, import_as: Union[int, _FurInsImportType]) -> None: - """ - Load a module from an **uncompressed** stream. - - :param stream: File-like object containing the uncompressed module. - :param import_as: int - - 0 = old format instrument file - - 1 = old format, embedded in module - - 2 = new format instrument file - - 3 = new format, embedded in module - """ - if import_as == _FurInsImportType.FORMAT_0_FILE: - if stream.read(len(FILE_MAGIC_STR)) != FILE_MAGIC_STR: - raise ValueError('Bad magic value for a format 1 file') - self.protocol_version = 0 - self.meta.version = read_short(stream) - read_short(stream) # reserved - ins_data_ptr = read_int(stream) - num_waves = read_short(stream) - num_samples = read_short(stream) - read_int(stream) # reserved - - # these don't exist for format 1 instrs. - self.__wavetable_ptr = [ - read_int(stream) for _ in range(num_waves) - ] - self.__sample_ptr = [ - read_int(stream) for _ in range(num_samples) - ] - - stream.seek(ins_data_ptr) - self.__load_format_0_embed(stream) - # TODO: load wavetables and samples - - elif import_as == _FurInsImportType.FORMAT_0_EMBED: - self.protocol_version = 0 - return self.__load_format_0_embed(stream) - - elif import_as == _FurInsImportType.FORMAT_1_FILE: - if stream.read(len(DEV127_FILE_MAGIC_STR)) != DEV127_FILE_MAGIC_STR: - raise ValueError('Bad magic value for a format 1 file') - self.protocol_version = 1 - self.__load_format_1(stream) - # TODO: load wavetables and samples - - elif import_as == _FurInsImportType.FORMAT_1_EMBED: - if stream.read(len(DEV127_EMBED_MAGIC_STR)) != DEV127_EMBED_MAGIC_STR: - raise ValueError('Bad magic value for a format 1 embed') - self.protocol_version = 1 - ins_data = BytesIO(stream.read(read_int(stream))) - return self.__load_format_1(ins_data) - - else: - raise ValueError('Invalid import type') - - def __str__(self) -> str: - return '' % ( - self.get_name(), self.meta.type - ) - - def __load_format_1(self, stream: BinaryIO) -> None: - # skip headers and magic - self.meta.version = read_short(stream) - self.meta.type = InstrumentType(read_short(stream)) - self.features.clear() - - # add all the features - feat = self.__read_format_1_feature(stream) - while isinstance(feat, InsFeatureAbstract): - self.features.append(feat) - feat = self.__read_format_1_feature(stream) - - def __read_format_1_feature(self, stream: BinaryIO) -> Optional[object]: # subclass InsFeatureAbstract - code = stream.read(2) - if code == b'EN' or code == b'': # eof - return None - - len_block = read_short(stream) - feature_block = BytesIO(stream.read(len_block)) - - # if this fails it might be a malformed file - return self.__map_to_fn[code](feature_block) - - def get_name(self) -> str: - """ - Shortcut to fetch the instrument name. - - :return: Instrument name - """ - name = '' - for i in self.features: - if isinstance(i, InsFeatureName): - name = i # InsFeatureName also subclasses 'str' so it's fine - return name - - # format 1 features - - def __load_na_block(self, stream: BytesIO) -> InsFeatureName: - return InsFeatureName( - read_str(stream) - ) - - def __load_fm_block(self, stream: BytesIO) -> InsFeatureFM: - fm = InsFeatureFM() - - # read base data - data = [read_byte(stream) for _ in range(4)] - - current = data.pop(0) - ops = current & 0b1111 - fm.op_list[0].enable = bool(current & 16) - fm.op_list[1].enable = bool(current & 32) - fm.op_list[2].enable = bool(current & 64) - fm.op_list[3].enable = bool(current & 128) - - current = data.pop(0) - fm.alg = (current >> 4) & 0b111 - fm.fb = current & 0b111 - - current = data.pop(0) - fm.fms2 = (current >> 5) & 0b111 - fm.ams = (current >> 3) & 0b11 - fm.fms = current & 0b111 - - current = data.pop(0) - fm.ams2 = (current >> 6) & 0b11 - if current & 32: - fm.ops = 4 - else: - fm.ops = 2 - fm.opll_preset = current & 31 - - # read operators - for op in range(ops): - data = [read_byte(stream) for _ in range(8)] - - current = data.pop(0) - fm.op_list[op].ksr = bool(current & 128) - fm.op_list[op].dt = (current >> 4) & 7 - fm.op_list[op].mult = current & 15 - - current = data.pop(0) - fm.op_list[op].sus = bool(current & 128) - fm.op_list[op].tl = current & 127 - - current = data.pop(0) - fm.op_list[op].rs = (current >> 6) & 3 - fm.op_list[op].vib = bool(current & 32) - fm.op_list[op].ar = current & 31 - - current = data.pop(0) - fm.op_list[op].am = bool(current & 128) - fm.op_list[op].ksl = (current >> 5) & 3 - fm.op_list[op].dr = current & 31 - - current = data.pop(0) - fm.op_list[op].egt = bool(current & 128) - fm.op_list[op].kvs = (current >> 5) & 3 - fm.op_list[op].d2r = current & 31 - - current = data.pop(0) - fm.op_list[op].sl = (current >> 4) & 15 - fm.op_list[op].rr = current & 15 - - current = data.pop(0) - fm.op_list[op].dvb = (current >> 4) & 15 - fm.op_list[op].ssg_env = current & 15 - - current = data.pop(0) - fm.op_list[op].dam = (current >> 5) & 7 - fm.op_list[op].dt2 = (current >> 3) & 3 - fm.op_list[op].ws = current & 7 - - return fm - - def __common_ma_block(self, stream: BytesIO, macro_class: Type[T_MACRO]) -> T_MACRO: - ma = macro_class() - ma.macros.clear() - read_short(stream) # header size - - target_code: Union[MacroCode, OpMacroCode] - - if macro_class in [InsFeatureOpr1Macro, - InsFeatureOpr2Macro, - InsFeatureOpr3Macro, - InsFeatureOpr4Macro]: - target_code = OpMacroCode(read_byte(stream)) - else: - target_code = MacroCode(read_byte(stream)) - - while target_code != MacroCode.STOP: - new_macro = SingleMacro(kind=target_code) - - length = read_byte(stream) - loop = read_byte(stream) - release = read_byte(stream) - - new_macro.mode = read_byte(stream) - flags = read_byte(stream) - - word_size = MacroSize(flags >> 6 & 0b11) # type: ignore - new_macro.type = MacroType(flags >> 1 & 0b11) - new_macro.open = bool(flags & 1) - new_macro.delay = read_byte(stream) - new_macro.speed = read_byte(stream) - - # adsr and lfo will simply be kept as a list - macro_content: List[Union[int, MacroItem]] = [ - int.from_bytes( - stream.read(word_size.num_bytes), - byteorder='little', - signed=word_size.signed - ) - for _ in range(length) - ] - - if loop != 0xff: # hard limit in new macro - macro_content.insert(loop, MacroItem.LOOP) - - if release != 0xff: # ^ - macro_content.insert(release, MacroItem.RELEASE) - - new_macro.data = macro_content - - ma.macros.append(new_macro) - - if macro_class in [InsFeatureOpr1Macro, - InsFeatureOpr2Macro, - InsFeatureOpr3Macro, - InsFeatureOpr4Macro]: - target_code = OpMacroCode(read_byte(stream)) - else: - target_code = MacroCode(read_byte(stream)) - - return ma - - def __load_ma_block(self, stream: BytesIO) -> InsFeatureMacro: - return self.__common_ma_block(stream, InsFeatureMacro) - - def __load_o1_block(self, stream: BytesIO) -> InsFeatureOpr1Macro: - return self.__common_ma_block(stream, InsFeatureOpr1Macro) - - def __load_o2_block(self, stream: BytesIO) -> InsFeatureOpr2Macro: - return self.__common_ma_block(stream, InsFeatureOpr2Macro) - - def __load_o3_block(self, stream: BytesIO) -> InsFeatureOpr3Macro: - return self.__common_ma_block(stream, InsFeatureOpr3Macro) - - def __load_o4_block(self, stream: BytesIO) -> InsFeatureOpr4Macro: - return self.__common_ma_block(stream, InsFeatureOpr4Macro) - - def __load_c64_block(self, stream: BytesIO) -> InsFeatureC64: - c64 = InsFeatureC64() - - data = [read_byte(stream) for _ in range(4)] - - current = data.pop(0) - c64.duty_is_abs = bool((current >> 7) & 1) - c64.init_filter = bool((current >> 6) & 1) - c64.vol_is_cutoff = bool((current >> 5) & 1) - c64.to_filter = bool((current >> 4) & 1) - c64.noise_on = bool((current >> 3) & 1) - c64.pulse_on = bool((current >> 2) & 1) - c64.saw_on = bool((current >> 1) & 1) - c64.tri_on = bool(current & 1) - - current = data.pop(0) - c64.osc_sync = bool((current >> 7) & 1) - c64.ring_mod = bool((current >> 6) & 1) - c64.no_test = bool((current >> 5) & 1) - c64.filter_is_abs = bool((current >> 4) & 1) - c64.ch3_off = bool((current >> 3) & 1) - c64.bp = bool((current >> 2) & 1) - c64.hp = bool((current >> 1) & 1) - c64.lp = bool(current & 1) - - current = data.pop(0) - c64.envelope.a = (current >> 4) & 0b1111 - c64.envelope.d = current & 0b1111 - - current = data.pop(0) - c64.envelope.s = (current >> 4) & 0b1111 - c64.envelope.r = current & 0b1111 - - c64.duty = read_short(stream) - - c_r = read_short(stream) - c64.cut = c_r & 0b11111111111 - c64.res = (c_r >> 12) & 0b1111 - - return c64 - - def __load_gb_block(self, stream: BytesIO) -> InsFeatureGB: - gb = InsFeatureGB() - - data = [read_byte(stream) for _ in range(4)] - - current = data.pop(0) - gb.env_vol = current & 0b1111 - gb.env_dir = (current >> 4) & 1 - gb.env_len = (current >> 5) & 0b111 - - gb.sound_len = data.pop(0) - - current = data.pop(0) - gb.soft_env = bool(current & 1) - gb.always_init = bool((current >> 1) & 1) - - hw_seq_len = data.pop(0) - for i in range(hw_seq_len): - seq_entry = GBHwSeq( - GBHwCommand(read_byte(stream)) - ) - seq_entry.data = [ - read_byte(stream), - read_byte(stream) - ] - gb.hw_seq.append(seq_entry) - - return gb - - def __load_sm_block(self, stream: BytesIO) -> InsFeatureAmiga: - sm = InsFeatureAmiga() - - sm.init_sample = read_short(stream) - - current = read_byte(stream) - sm.use_wave = bool((current >> 2) & 1) - sm.use_sample = bool((current >> 1) & 1) - sm.use_note_map = bool(current & 1) - - sm.wave_len = read_byte(stream) - - if sm.use_note_map: - for i in range(len(sm.sample_map)): - sm.sample_map[i].freq = read_short(stream) - sm.sample_map[i].sample_index = read_short(stream) - - return sm - - def __load_ld_block(self, stream: BytesIO) -> InsFeatureOPLDrums: - return InsFeatureOPLDrums( - fixed_drums=bool(read_byte(stream) & 1), - kick_freq=read_short(stream), - snare_hat_freq=read_short(stream), - tom_top_freq=read_short(stream) - ) - - def __load_sn_block(self, stream: BytesIO) -> InsFeatureSNES: - sn = InsFeatureSNES() - - data = [read_byte(stream) for _ in range(4)] - - current = data.pop(0) - sn.envelope.d = (current >> 4) & 0b1111 - sn.envelope.a = current & 0b1111 - - current = data.pop(0) - sn.envelope.s = (current >> 4) & 0b1111 - sn.envelope.r = current & 0b1111 - - current = data.pop(0) - sn.use_env = bool((current >> 4) & 1) - sn.sus = SNESSusMode((current >> 3) & 1) - - gain_mode = current & 0b111 - if current < 4: - gain_mode = 0 - sn.gain_mode = GainMode(gain_mode) - - sn.gain = data.pop(0) - - if self.meta.version >= 131: - d2s = read_byte(stream) - sn.sus = SNESSusMode((d2s >> 5 & 0b11)) - sn.d2 = d2s & 31 - - return sn - - def __load_n1_block(self, stream: BytesIO) -> InsFeatureN163: - return InsFeatureN163( - wave=read_int(stream), - wave_pos=read_byte(stream), - wave_len=read_byte(stream), - wave_mode=read_byte(stream) - ) - - def __load_fd_block(self, stream: BytesIO) -> InsFeatureFDS: - fd = InsFeatureFDS( - mod_speed=read_int(stream), - mod_depth=read_int(stream), - init_table_with_first_wave=bool(read_byte(stream)) - ) - for i in range(32): - fd.mod_table[i] = read_byte(stream) - return fd - - def __load_ws_block(self, stream: BytesIO) -> InsFeatureWaveSynth: - return InsFeatureWaveSynth( - wave_indices=[ - read_int(stream), read_int(stream) - ], - rate_divider=read_byte(stream), - effect=WaveFX(read_byte(stream)), - enabled=bool(read_byte(stream) & 1), - global_effect=bool(read_byte(stream) & 1), - speed=read_byte(stream), - params=[ - read_byte(stream), read_byte(stream), - read_byte(stream), read_byte(stream) - ] - ) - - def __common_pointers_block(self, stream: BytesIO, ptr_class: Type[T_POINTERS]) -> T_POINTERS: - pt = ptr_class() - num_entries = read_byte(stream) - - for _ in range(num_entries): - pt.pointers[read_byte(stream)] = -1 - - for i in pt.pointers: - pt.pointers[i] = read_int(stream) - - return pt - - def __load_sl_block(self, stream: BytesIO) -> InsFeatureSampleList: - return self.__common_pointers_block(stream, InsFeatureSampleList) - - def __load_wl_block(self, stream: BytesIO) -> InsFeatureWaveList: - return self.__common_pointers_block(stream, InsFeatureWaveList) - - def __load_mp_block(self, stream: BytesIO) -> InsFeatureMultiPCM: - return InsFeatureMultiPCM( - ar=read_byte(stream), - d1r=read_byte(stream), - dl=read_byte(stream), - d2r=read_byte(stream), - rr=read_byte(stream), - rc=read_byte(stream), - lfo=read_byte(stream), - vib=read_byte(stream), - am=read_byte(stream), - ) - - def __load_su_block(self, stream: BytesIO) -> InsFeatureSoundUnit: - return InsFeatureSoundUnit( - switch_roles=bool(read_byte(stream)) - ) - - def __load_es_block(self, stream: BytesIO) -> InsFeatureES5506: - return InsFeatureES5506( - filter_mode=ESFilterMode(read_byte(stream)), - k1=read_short(stream), - k2=read_short(stream), - env_count=read_short(stream), - left_volume_ramp=read_byte(stream), - right_volume_ramp=read_byte(stream), - k1_ramp=read_byte(stream), - k2_ramp=read_byte(stream), - k1_slow=read_byte(stream), - k2_slow=read_byte(stream) - ) - - def __load_x1_block(self, stream: BytesIO) -> InsFeatureX1010: - return InsFeatureX1010( - bank_slot=read_int(stream) - ) - - def __load_ne_block(self, stream: BytesIO) -> InsFeatureDPCMMap: - sm = InsFeatureDPCMMap() - - sm.use_map = bool(read_byte(stream) & 1) - - if sm.use_map: - for i in range(len(sm.sample_map)): - sm.sample_map[i].pitch = read_byte(stream) - sm.sample_map[i].delta = read_byte(stream) - - return sm - - # TODO: No documentation? - #def __load_ef_block(self, stream: BytesIO) -> InsFeatureESFM: - # pass - - def __load_pn_block(self, stream: BytesIO) -> InsFeaturePowerNoise: - return InsFeaturePowerNoise( - octave=read_byte(stream) - ) - - def __load_s2_block(self, stream: BytesIO) -> InsFeatureSID2: - current_byte = read_byte(stream) - return InsFeatureSID2( - volume=current_byte & 0b1111, - wave_mix=(current_byte >> 4) & 0b11, - noise_mode=(current_byte >> 6) & 0b11 - ) - - # format 0; also used for file because it includes the "INST" header too - - def __load_format_0_embed(self, stream: BinaryIO) -> None: - # load format 0 as a series of format 1 feature blocks - - # aux function... - def add_to_macro_data(macro: List[Union[int, MacroItem]], - loop: Optional[int] = 0xffffffff, - release: Optional[int] = 0xffffffff, - data: Optional[List[int]] = None) -> None: - if data is not None: - macro.extend(data) - if loop is not None and loop != 0xffffffff: # old macros have a 4-byte length - macro.insert(loop, MacroItem.LOOP) - if release is not None and release != 0xffffffff: - macro.insert(release, MacroItem.RELEASE) - - # we check the header here - if stream.read(len(EMBED_MAGIC_STR)) != EMBED_MAGIC_STR: - raise RuntimeError('Bad magic value for a format 0 embed') - - blk_size = read_int(stream) - if blk_size > 0: - ins_data = BytesIO(stream.read(blk_size)) - else: - ins_data = stream - - self.meta.version = read_short(ins_data) # overwrites the file header version - self.meta.type = InstrumentType(read_byte(ins_data)) - - read_byte(ins_data) - - # read all features in one go! - self.features.clear() - - # name, insert immediately - self.features.append( - InsFeatureName(read_str(ins_data)) - ) - - # fm - if True: - fm = InsFeatureFM( - alg=read_byte(ins_data), - fb=read_byte(ins_data), - fms=read_byte(ins_data), - ams=read_byte(ins_data), - ops=read_byte(ins_data), - opll_preset=read_byte(ins_data) - ) - read_short(ins_data) - for i in range(4): - fm.op_list[i].am = bool(read_byte(ins_data)) - fm.op_list[i].ar = read_byte(ins_data) - fm.op_list[i].dr = read_byte(ins_data) - fm.op_list[i].mult = read_byte(ins_data) - fm.op_list[i].rr = read_byte(ins_data) - fm.op_list[i].sl = read_byte(ins_data) - fm.op_list[i].tl = read_byte(ins_data) - fm.op_list[i].dt2 = read_byte(ins_data) - fm.op_list[i].rs = read_byte(ins_data) - fm.op_list[i].dt = read_byte(ins_data) - fm.op_list[i].d2r = read_byte(ins_data) - fm.op_list[i].ssg_env = read_byte(ins_data) - fm.op_list[i].dam = read_byte(ins_data) - fm.op_list[i].dvb = read_byte(ins_data) - fm.op_list[i].egt = bool(read_byte(ins_data)) - fm.op_list[i].ksl = read_byte(ins_data) - fm.op_list[i].sus = bool(read_byte(ins_data)) - fm.op_list[i].vib = bool(read_byte(ins_data)) - fm.op_list[i].ws = read_byte(ins_data) - fm.op_list[i].ksr = bool(read_byte(ins_data)) - en = read_byte(ins_data) - if self.meta.version >= 114: - fm.op_list[i].enable = bool(en) - kvs = read_byte(ins_data) - if self.meta.version >= 115: - fm.op_list[i].kvs = kvs - ins_data.read(10) - self.features.append(fm) - - # gameboy - if True: - gb = InsFeatureGB( - env_vol=read_byte(ins_data), - env_dir=read_byte(ins_data), - env_len=read_byte(ins_data), - sound_len=read_byte(ins_data) - ) - self.features.append(gb) - - # c64 - if True: - c64 = InsFeatureC64( - tri_on=bool(read_byte(ins_data)), - saw_on=bool(read_byte(ins_data)), - pulse_on=bool(read_byte(ins_data)), - noise_on=bool(read_byte(ins_data)), - duty=read_short(ins_data), - ring_mod=read_byte(ins_data), - osc_sync=read_byte(ins_data), - to_filter=bool(read_byte(ins_data)), - init_filter=bool(read_byte(ins_data)), - vol_is_cutoff=bool(read_byte(ins_data)), - res=read_byte(ins_data), - lp=bool(read_byte(ins_data)), - bp=bool(read_byte(ins_data)), - hp=bool(read_byte(ins_data)), - ch3_off=bool(read_byte(ins_data)), - cut=read_short(ins_data), - duty_is_abs=bool(read_byte(ins_data)), - filter_is_abs=bool(read_byte(ins_data)) - ) - c64.envelope = GenericADSR( - a=read_byte(ins_data), - d=read_byte(ins_data), - s=read_byte(ins_data), - r=read_byte(ins_data), - ) - self.features.append(c64) - - # amiga - if True: - amiga = InsFeatureAmiga( - init_sample=read_short(ins_data) - ) - - wave = read_byte(ins_data) - wavelen = read_byte(ins_data) - if self.meta.version >= 82: - amiga.use_wave = bool(wave) - amiga.wave_len = wavelen - - for _ in range(12): - read_byte(ins_data) # reserved - - self.features.append(amiga) - - # standard - if True: - mac = InsFeatureMacro() - - vol_mac = SingleMacro(kind=MacroCode.VOL) - arp_mac = SingleMacro(kind=MacroCode.ARP) - duty_mac = SingleMacro(kind=MacroCode.DUTY) - wave_mac = SingleMacro(kind=MacroCode.WAVE) - - vol_mac.data.clear() - arp_mac.data.clear() - duty_mac.data.clear() - wave_mac.data.clear() - - mac_list: List[SingleMacro] = [vol_mac, arp_mac, duty_mac, wave_mac] - mac.macros = mac_list - - vol_mac_len = read_int(ins_data) - arp_mac_len = read_int(ins_data) - duty_mac_len = read_int(ins_data) - wave_mac_len = read_int(ins_data) - - if self.meta.version >= 17: - pitch_mac = SingleMacro(kind=MacroCode.PITCH) - x1_mac = SingleMacro(kind=MacroCode.EX1) - x2_mac = SingleMacro(kind=MacroCode.EX2) - x3_mac = SingleMacro(kind=MacroCode.EX3) - - pitch_mac.data.clear() - x1_mac.data.clear() - x2_mac.data.clear() - x3_mac.data.clear() - - mac_list.extend([pitch_mac, x1_mac, x2_mac, x3_mac]) - - pitch_mac_len = read_int(ins_data) - x1_mac_len = read_int(ins_data) - x2_mac_len = read_int(ins_data) - x3_mac_len = read_int(ins_data) - - vol_mac_loop = read_int(ins_data) - arp_mac_loop = read_int(ins_data) - duty_mac_loop = read_int(ins_data) - wave_mac_loop = read_int(ins_data) - - if self.meta.version >= 17: - pitch_mac_loop = read_int(ins_data) - x1_mac_loop = read_int(ins_data) - x2_mac_loop = read_int(ins_data) - x3_mac_loop = read_int(ins_data) - - arp_mac_mode = read_byte(ins_data) - old_vol_height = read_byte(ins_data) - old_duty_height = read_byte(ins_data) - - read_byte(ins_data) - - add_to_macro_data(vol_mac.data, - loop=vol_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(vol_mac_len)]) - - add_to_macro_data(arp_mac.data, - loop=arp_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(arp_mac_len)]) - - add_to_macro_data(duty_mac.data, - loop=duty_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(duty_mac_len)]) - - add_to_macro_data(wave_mac.data, - loop=wave_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(wave_mac_len)]) - - # adjust values - if self.meta.version < 31: - if arp_mac_mode == 0: - for j in range(len(arp_mac.data)): - if isinstance(arp_mac.data[j], int): - arp_mac.data[j] -= 12 - if self.meta.version < 87: - if c64.vol_is_cutoff and not c64.filter_is_abs: - for j in range(len(vol_mac.data)): - if isinstance(vol_mac.data[j], int): - vol_mac.data[j] -= 18 - if c64.duty_is_abs: # TODO - for j in range(len(duty_mac.data)): - if isinstance(duty_mac.data[j], int): - duty_mac.data[j] -= 12 - if self.meta.version < 112: - if arp_mac_mode == 1: # fixed arp! - for i in range(len(arp_mac.data)): - if isinstance(arp_mac.data[i], int): - arp_mac.data[i] |= (1 << 30) - if len(arp_mac.data) > 0: - if arp_mac_loop != 0xffffffff: - if arp_mac_loop == arp_mac_len+1: - arp_mac.data[-1] = 0 - arp_mac.data.append(MacroItem.LOOP) - elif arp_mac_loop == arp_mac_len: - arp_mac.data.append(0) - else: - arp_mac.data.append(0) - - # read more macros - if self.meta.version >= 17: - add_to_macro_data(pitch_mac.data, - loop=pitch_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(pitch_mac_len)]) - - add_to_macro_data(x1_mac.data, - loop=x1_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(x1_mac_len)]) - - add_to_macro_data(x2_mac.data, - loop=x2_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(x2_mac_len)]) - - add_to_macro_data(x3_mac.data, - loop=x3_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(x3_mac_len)]) - else: - if self.meta.type == InstrumentType.STANDARD: - if old_vol_height == 31: - self.meta.type = InstrumentType.PCE - elif old_duty_height == 31: - self.meta.type = InstrumentType.SSG - - self.features.append(mac) - - # fm macros - if True: - if self.meta.version >= 29: - alg_mac = SingleMacro(kind=MacroCode.ALG) - fb_mac = SingleMacro(kind=MacroCode.FB) - fms_mac = SingleMacro(kind=MacroCode.FMS) - ams_mac = SingleMacro(kind=MacroCode.AMS) - mac_list.extend([alg_mac, fb_mac, fms_mac, ams_mac]) - - alg_mac.data.clear() - fb_mac.data.clear() - fms_mac.data.clear() - ams_mac.data.clear() - - alg_mac_len = read_int(ins_data) - fb_mac_len = read_int(ins_data) - fms_mac_len = read_int(ins_data) - ams_mac_len = read_int(ins_data) - - alg_mac_loop = read_int(ins_data) - fb_mac_loop = read_int(ins_data) - fms_mac_loop = read_int(ins_data) - ams_mac_loop = read_int(ins_data) - - vol_mac.open = bool(read_byte(ins_data)) - arp_mac.open = bool(read_byte(ins_data)) - duty_mac.open = bool(read_byte(ins_data)) - wave_mac.open = bool(read_byte(ins_data)) - pitch_mac.open = bool(read_byte(ins_data)) - x1_mac.open = bool(read_byte(ins_data)) - x2_mac.open = bool(read_byte(ins_data)) - x3_mac.open = bool(read_byte(ins_data)) - - alg_mac.open = bool(read_byte(ins_data)) - fb_mac.open = bool(read_byte(ins_data)) - fms_mac.open = bool(read_byte(ins_data)) - ams_mac.open = bool(read_byte(ins_data)) - - add_to_macro_data(alg_mac.data, - loop=alg_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(alg_mac_len)]) - - add_to_macro_data(fb_mac.data, - loop=fb_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(fb_mac_len)]) - - add_to_macro_data(fms_mac.data, - loop=fms_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(fms_mac_len)]) - - add_to_macro_data(ams_mac.data, - loop=ams_mac_loop, - release=None, - data=[read_int(ins_data) for _ in range(ams_mac_len)]) - - # fm op macros - if True: - if self.meta.version >= 29: - new_ops: Dict[int, InsFeatureMacro] = {} # actual ops - - ops_types: Dict[int, Type[InsFeatureMacro]] = { # classes - 0: InsFeatureOpr1Macro, - 1: InsFeatureOpr2Macro, - 2: InsFeatureOpr3Macro, - 3: InsFeatureOpr4Macro, - } - - ops: Dict[int, Dict[str, Union[int, bool]]] = { # params - 0: {}, - 1: {}, - 2: {}, - 3: {} - } - - for opi in ops: - ops[opi]["am_mac_len"] = read_int(ins_data) - ops[opi]["ar_mac_len"] = read_int(ins_data) - ops[opi]["dr_mac_len"] = read_int(ins_data) - ops[opi]["mult_mac_len"] = read_int(ins_data) - ops[opi]["rr_mac_len"] = read_int(ins_data) - ops[opi]["sl_mac_len"] = read_int(ins_data) - ops[opi]["tl_mac_len"] = read_int(ins_data) - ops[opi]["dt2_mac_len"] = read_int(ins_data) - ops[opi]["rs_mac_len"] = read_int(ins_data) - ops[opi]["dt_mac_len"] = read_int(ins_data) - ops[opi]["d2r_mac_len"] = read_int(ins_data) - ops[opi]["ssg_mac_len"] = read_int(ins_data) - - ops[opi]["am_mac_loop"] = read_int(ins_data) - ops[opi]["ar_mac_loop"] = read_int(ins_data) - ops[opi]["dr_mac_loop"] = read_int(ins_data) - ops[opi]["mult_mac_loop"] = read_int(ins_data) - ops[opi]["rr_mac_loop"] = read_int(ins_data) - ops[opi]["sl_mac_loop"] = read_int(ins_data) - ops[opi]["tl_mac_loop"] = read_int(ins_data) - ops[opi]["dt2_mac_loop"] = read_int(ins_data) - ops[opi]["rs_mac_loop"] = read_int(ins_data) - ops[opi]["dt_mac_loop"] = read_int(ins_data) - ops[opi]["d2r_mac_loop"] = read_int(ins_data) - ops[opi]["ssg_mac_loop"] = read_int(ins_data) - - ops[opi]["am_mac_open"] = read_byte(ins_data) - ops[opi]["ar_mac_open"] = read_byte(ins_data) - ops[opi]["dr_mac_open"] = read_byte(ins_data) - ops[opi]["mult_mac_open"] = read_byte(ins_data) - ops[opi]["rr_mac_open"] = read_byte(ins_data) - ops[opi]["sl_mac_open"] = read_byte(ins_data) - ops[opi]["tl_mac_open"] = read_byte(ins_data) - ops[opi]["dt2_mac_open"] = read_byte(ins_data) - ops[opi]["rs_mac_open"] = read_byte(ins_data) - ops[opi]["dt_mac_open"] = read_byte(ins_data) - ops[opi]["d2r_mac_open"] = read_byte(ins_data) - ops[opi]["ssg_mac_open"] = read_byte(ins_data) - - for opi in ops: - new_op = ops_types[opi]() - new_op.macros = [] - - am_mac = SingleMacro(kind=OpMacroCode.AM) - am_mac.open = bool(ops[opi]["am_mac_open"]) - am_mac.data.clear() - add_to_macro_data(am_mac.data, - loop=ops[opi]["am_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["am_mac_len"])]) - - ar_mac = SingleMacro(kind=OpMacroCode.AR) - ar_mac.open = bool(ops[opi]["ar_mac_open"]) - ar_mac.data.clear() - add_to_macro_data(ar_mac.data, - loop=ops[opi]["ar_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["ar_mac_len"])]) - - dr_mac = SingleMacro(kind=OpMacroCode.DR) - dr_mac.open = bool(ops[opi]["dr_mac_open"]) - dr_mac.data.clear() - add_to_macro_data(dr_mac.data, - loop=ops[opi]["dr_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["dr_mac_len"])]) - - mult_mac = SingleMacro(kind=OpMacroCode.MULT) - mult_mac.open = bool(ops[opi]["mult_mac_open"]) - mult_mac.data.clear() - add_to_macro_data(mult_mac.data, - loop=ops[opi]["mult_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["mult_mac_len"])]) - - rr_mac = SingleMacro(kind=OpMacroCode.RR) - rr_mac.open = bool(ops[opi]["rr_mac_open"]) - rr_mac.data.clear() - add_to_macro_data(rr_mac.data, - loop=ops[opi]["rr_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["rr_mac_len"])]) - - sl_mac = SingleMacro(kind=OpMacroCode.SL) - sl_mac.open = bool(ops[opi]["sl_mac_open"]) - sl_mac.data.clear() - add_to_macro_data(sl_mac.data, - loop=ops[opi]["sl_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["sl_mac_len"])]) - - tl_mac = SingleMacro(kind=OpMacroCode.TL) - tl_mac.open = bool(ops[opi]["tl_mac_open"]) - tl_mac.data.clear() - add_to_macro_data(tl_mac.data, - loop=ops[opi]["tl_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["tl_mac_len"])]) - - dt2_mac = SingleMacro(kind=OpMacroCode.DT2) - dt2_mac.open = bool(ops[opi]["dt2_mac_open"]) - dt2_mac.data.clear() - add_to_macro_data(dt2_mac.data, - loop=ops[opi]["dt2_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["dt2_mac_len"])]) - - rs_mac = SingleMacro(kind=OpMacroCode.RS) - rs_mac.open = bool(ops[opi]["rs_mac_open"]) - rs_mac.data.clear() - add_to_macro_data(rs_mac.data, - loop=ops[opi]["rs_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["rs_mac_len"])]) - - dt_mac = SingleMacro(kind=OpMacroCode.DT) - dt_mac.open = bool(ops[opi]["dt_mac_open"]) - dt_mac.data.clear() - add_to_macro_data(dt_mac.data, - loop=ops[opi]["dt_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["dt_mac_len"])]) - - d2r_mac = SingleMacro(kind=OpMacroCode.D2R) - d2r_mac.open = bool(ops[opi]["d2r_mac_open"]) - d2r_mac.data.clear() - add_to_macro_data(d2r_mac.data, - loop=ops[opi]["d2r_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["d2r_mac_len"])]) - - ssg_mac = SingleMacro(kind=OpMacroCode.SSG_EG) - ssg_mac.open = bool(ops[opi]["ssg_mac_open"]) - ssg_mac.data.clear() - add_to_macro_data(ssg_mac.data, - loop=ops[opi]["ssg_mac_loop"], - release=None, - data=[read_int(ins_data) for _ in range(ops[opi]["ssg_mac_len"])]) - - new_op.macros.extend([ - am_mac, ar_mac, dr_mac, mult_mac, rr_mac, - sl_mac, tl_mac, dt2_mac, rs_mac, dt_mac, - d2r_mac, ssg_mac - ]) # must be in order!! - - new_ops[opi] = new_op - - # release points - if True: - if self.meta.version >= 44: - add_to_macro_data(vol_mac.data, None, read_int(ins_data), None) - add_to_macro_data(arp_mac.data, None, read_int(ins_data), None) - add_to_macro_data(duty_mac.data, None, read_int(ins_data), None) - add_to_macro_data(wave_mac.data, None, read_int(ins_data), None) - add_to_macro_data(pitch_mac.data, None, read_int(ins_data), None) - add_to_macro_data(x1_mac.data, None, read_int(ins_data), None) - add_to_macro_data(x2_mac.data, None, read_int(ins_data), None) - add_to_macro_data(x3_mac.data, None, read_int(ins_data), None) - add_to_macro_data(alg_mac.data, None, read_int(ins_data), None) - add_to_macro_data(fb_mac.data, None, read_int(ins_data), None) - add_to_macro_data(fms_mac.data, None, read_int(ins_data), None) - add_to_macro_data(ams_mac.data, None, read_int(ins_data), None) - - for opi in new_ops: - for i in range(12): - add_to_macro_data(new_ops[opi].macros[i].data, None, read_int(ins_data), None) - - # extended op macros - if True: - if self.meta.version >= 61: - for op in new_ops: - dam_mac = SingleMacro(kind=OpMacroCode.DAM) - dvb_mac = SingleMacro(kind=OpMacroCode.DVB) - egt_mac = SingleMacro(kind=OpMacroCode.EGT) - ksl_mac = SingleMacro(kind=OpMacroCode.KSL) - sus_mac = SingleMacro(kind=OpMacroCode.SUS) - vib_mac = SingleMacro(kind=OpMacroCode.VIB) - ws_mac = SingleMacro(kind=OpMacroCode.WS) - ksr_mac = SingleMacro(kind=OpMacroCode.KSR) - - dam_mac_len = read_int(ins_data) - dvb_mac_len = read_int(ins_data) - egt_mac_len = read_int(ins_data) - ksl_mac_len = read_int(ins_data) - sus_mac_len = read_int(ins_data) - vib_mac_len = read_int(ins_data) - ws_mac_len = read_int(ins_data) - ksr_mac_len = read_int(ins_data) - - dam_mac_loop = read_int(ins_data) - dvb_mac_loop = read_int(ins_data) - egt_mac_loop = read_int(ins_data) - ksl_mac_loop = read_int(ins_data) - sus_mac_loop = read_int(ins_data) - vib_mac_loop = read_int(ins_data) - ws_mac_loop = read_int(ins_data) - ksr_mac_loop = read_int(ins_data) - - dam_mac_rel = read_int(ins_data) - dvb_mac_rel = read_int(ins_data) - egt_mac_rel = read_int(ins_data) - ksl_mac_rel = read_int(ins_data) - sus_mac_rel = read_int(ins_data) - vib_mac_rel = read_int(ins_data) - ws_mac_rel = read_int(ins_data) - ksr_mac_rel = read_int(ins_data) - - dam_mac.open = bool(read_byte(ins_data)) - dvb_mac.open = bool(read_byte(ins_data)) - egt_mac.open = bool(read_byte(ins_data)) - ksl_mac.open = bool(read_byte(ins_data)) - sus_mac.open = bool(read_byte(ins_data)) - vib_mac.open = bool(read_byte(ins_data)) - ws_mac.open = bool(read_byte(ins_data)) - ksr_mac.open = bool(read_byte(ins_data)) - - dam_mac.data.clear() - dvb_mac.data.clear() - egt_mac.data.clear() - ksl_mac.data.clear() - sus_mac.data.clear() - vib_mac.data.clear() - ws_mac.data.clear() - ksr_mac.data.clear() - - add_to_macro_data(dam_mac.data, dam_mac_loop, dam_mac_rel, [ - read_byte(ins_data) for _ in range(dam_mac_len) - ]) - add_to_macro_data(dvb_mac.data, dvb_mac_loop, dvb_mac_rel, [ - read_byte(ins_data) for _ in range(dvb_mac_len) - ]) - add_to_macro_data(egt_mac.data, egt_mac_loop, egt_mac_rel, [ - read_byte(ins_data) for _ in range(egt_mac_len) - ]) - add_to_macro_data(ksl_mac.data, ksl_mac_loop, ksl_mac_rel, [ - read_byte(ins_data) for _ in range(ksl_mac_len) - ]) - add_to_macro_data(sus_mac.data, sus_mac_loop, sus_mac_rel, [ - read_byte(ins_data) for _ in range(sus_mac_len) - ]) - add_to_macro_data(vib_mac.data, vib_mac_loop, vib_mac_rel, [ - read_byte(ins_data) for _ in range(vib_mac_len) - ]) - add_to_macro_data(ws_mac.data, ws_mac_loop, ws_mac_rel, [ - read_byte(ins_data) for _ in range(ws_mac_len) - ]) - add_to_macro_data(ksr_mac.data, ksr_mac_loop, ksr_mac_rel, [ - read_byte(ins_data) for _ in range(ksr_mac_len) - ]) - - new_ops[op].macros.extend([ - dam_mac, dvb_mac, egt_mac, ksl_mac, sus_mac, vib_mac, - ws_mac, ksr_mac - ]) - - # opl drum data - if True: - if self.meta.version >= 63: - opl_drum = InsFeatureOPLDrums( - fixed_drums = bool(read_byte(ins_data)) - ) - read_byte(ins_data) - opl_drum.kick_freq = read_short(ins_data) - opl_drum.snare_hat_freq = read_short(ins_data) - opl_drum.tom_top_freq = read_short(ins_data) - self.features.append(opl_drum) - - # clear macros - if True: - if self.meta.version < 63 and self.meta.type == InstrumentType.PCE: - duty_mac.data.clear() - if self.meta.version < 70 and self.meta.type == InstrumentType.FM_OPLL: - wave_mac.data.clear() - - # sample map - if True: - if self.meta.version >= 67: - note_map = InsFeatureAmiga() - note_map.use_note_map = bool(read_byte(ins_data)) - if note_map.use_note_map: - for i in range(len(note_map.sample_map)): - note_map.sample_map[i].freq = read_int(ins_data) - for i in range(len(note_map.sample_map)): - note_map.sample_map[i].sample_index = read_short(ins_data) - self.features.append(note_map) - - # n163 - if True: - if self.meta.version >= 73: - n163 = InsFeatureN163( - wave=read_int(ins_data), - wave_pos=read_byte(ins_data), - wave_len=read_byte(ins_data), - wave_mode=read_byte(ins_data) - ) - read_byte(ins_data) # reserved - self.features.append(n163) - - # moar macroes - if True: - if self.meta.version >= 76: - pan_l_mac = SingleMacro(kind=MacroCode.PAN_L) - pan_r_mac = SingleMacro(kind=MacroCode.PAN_R) - phase_res_mac = SingleMacro(kind=MacroCode.PHASE_RESET) - x4_mac = SingleMacro(kind=MacroCode.EX4) - x5_mac = SingleMacro(kind=MacroCode.EX5) - x6_mac = SingleMacro(kind=MacroCode.EX6) - x7_mac = SingleMacro(kind=MacroCode.EX7) - x8_mac = SingleMacro(kind=MacroCode.EX8) - - pan_l_mac.data.clear() - pan_r_mac.data.clear() - phase_res_mac.data.clear() - x4_mac.data.clear() - x5_mac.data.clear() - x6_mac.data.clear() - x7_mac.data.clear() - x8_mac.data.clear() - - pan_l_mac_len = read_int(ins_data) - pan_r_mac_len = read_int(ins_data) - phase_res_mac_len = read_int(ins_data) - x4_mac_len = read_int(ins_data) - x5_mac_len = read_int(ins_data) - x6_mac_len = read_int(ins_data) - x7_mac_len = read_int(ins_data) - x8_mac_len = read_int(ins_data) - - pan_l_mac_loop = read_int(ins_data) - pan_r_mac_loop = read_int(ins_data) - phase_res_mac_loop = read_int(ins_data) - x4_mac_loop = read_int(ins_data) - x5_mac_loop = read_int(ins_data) - x6_mac_loop = read_int(ins_data) - x7_mac_loop = read_int(ins_data) - x8_mac_loop = read_int(ins_data) - - pan_l_mac_rel = read_int(ins_data) - pan_r_mac_rel = read_int(ins_data) - phase_res_mac_rel = read_int(ins_data) - x4_mac_rel = read_int(ins_data) - x5_mac_rel = read_int(ins_data) - x6_mac_rel = read_int(ins_data) - x7_mac_rel = read_int(ins_data) - x8_mac_rel = read_int(ins_data) - - pan_l_mac.open = bool(read_byte(ins_data)) - pan_r_mac.open = bool(read_byte(ins_data)) - phase_res_mac.open = bool(read_byte(ins_data)) - x4_mac.open = bool(read_byte(ins_data)) - x5_mac.open = bool(read_byte(ins_data)) - x6_mac.open = bool(read_byte(ins_data)) - x7_mac.open = bool(read_byte(ins_data)) - x8_mac.open = bool(read_byte(ins_data)) - - add_to_macro_data(pan_l_mac.data, pan_l_mac_loop, pan_l_mac_rel, [ - read_int(ins_data) for _ in range(pan_l_mac_len) - ]) - add_to_macro_data(pan_r_mac.data, pan_r_mac_loop, pan_r_mac_rel, [ - read_int(ins_data) for _ in range(pan_r_mac_len) - ]) - add_to_macro_data(phase_res_mac.data, phase_res_mac_loop, phase_res_mac_rel, [ - read_int(ins_data) for _ in range(phase_res_mac_len) - ]) - add_to_macro_data(x4_mac.data, x4_mac_loop, x4_mac_rel, [ - read_int(ins_data) for _ in range(x4_mac_len) - ]) - add_to_macro_data(x5_mac.data, x5_mac_loop, x5_mac_rel, [ - read_int(ins_data) for _ in range(x5_mac_len) - ]) - add_to_macro_data(x6_mac.data, x6_mac_loop, x6_mac_rel, [ - read_int(ins_data) for _ in range(x6_mac_len) - ]) - add_to_macro_data(x7_mac.data, x7_mac_loop, x7_mac_rel, [ - read_int(ins_data) for _ in range(x7_mac_len) - ]) - add_to_macro_data(x8_mac.data, x8_mac_loop, x8_mac_rel, [ - read_int(ins_data) for _ in range(x8_mac_len) - ]) - - mac_list.extend([ - pan_l_mac, pan_r_mac, phase_res_mac, x4_mac, - x5_mac, x6_mac, x7_mac, x8_mac - ]) - - # fds - if True: - if self.meta.version >= 76: - fds = InsFeatureFDS( - mod_speed=read_int(ins_data), - mod_depth=read_int(ins_data), - init_table_with_first_wave=bool(read_byte(ins_data)) - ) - read_byte(ins_data) # reserved - read_byte(ins_data) - read_byte(ins_data) - fds.mod_table = [read_byte(ins_data) for _ in range(32)] - self.features.append(fds) - - # opz - if True: - if self.meta.version >= 77: - fm.fms2 = read_byte(ins_data) - fm.ams2 = read_byte(ins_data) - - # wave synth - if True: - if self.meta.version >= 79: - ws = InsFeatureWaveSynth( - wave_indices=[read_int(ins_data), read_int(ins_data)], - rate_divider=read_byte(ins_data), - effect=WaveFX(read_byte(ins_data)), - enabled=bool(read_byte(ins_data)), - global_effect=bool(read_byte(ins_data)), - speed=read_byte(ins_data), - params=[read_byte(ins_data) for _ in range(4)] - ) - self.features.append(ws) - - # macro moads - if True: - if self.meta.version >= 84: - vol_mac.mode = read_byte(ins_data) - duty_mac.mode = read_byte(ins_data) - wave_mac.mode = read_byte(ins_data) - pitch_mac.mode = read_byte(ins_data) - x1_mac.mode = read_byte(ins_data) - x2_mac.mode = read_byte(ins_data) - x3_mac.mode = read_byte(ins_data) - alg_mac.mode = read_byte(ins_data) - fb_mac.mode = read_byte(ins_data) - fms_mac.mode = read_byte(ins_data) - ams_mac.mode = read_byte(ins_data) - pan_l_mac.mode = read_byte(ins_data) - pan_r_mac.mode = read_byte(ins_data) - phase_res_mac.mode = read_byte(ins_data) - x4_mac.mode = read_byte(ins_data) - x5_mac.mode = read_byte(ins_data) - x6_mac.mode = read_byte(ins_data) - x7_mac.mode = read_byte(ins_data) - x8_mac.mode = read_byte(ins_data) - - # c64 no test - if True: - if self.meta.version >= 89: - c64.no_test = bool(read_byte(ins_data)) - - # multipcm - if True: - if self.meta.version >= 93: - mp = InsFeatureMultiPCM( - ar=read_byte(ins_data), - d1r=read_byte(ins_data), - dl=read_byte(ins_data), - d2r=read_byte(ins_data), - rr=read_byte(ins_data), - rc=read_byte(ins_data), - lfo=read_byte(ins_data), - vib=read_byte(ins_data), - am=read_byte(ins_data) - ) - for _ in range(23): # reserved - read_byte(ins_data) - self.features.append(mp) - - # sound unit - if True: - if self.meta.version >= 104: - amiga.use_sample = bool(read_byte(ins_data)) - su = InsFeatureSoundUnit( - switch_roles=bool(read_byte(ins_data)) - ) - self.features.append(su) - - # gb hw seq - if True: - if self.meta.version >= 105: - gb_hwseq_len = read_byte(ins_data) - gb.hw_seq.clear() - for i in range(gb_hwseq_len): - gb.hw_seq.append( - GBHwSeq( - command=GBHwCommand(read_byte(ins_data)), - data=[read_byte(ins_data), read_byte(ins_data)] - ) - ) - - # additional gb - if True: - if self.meta.version >= 106: - gb.soft_env = bool(read_byte(ins_data)) - gb.always_init = bool(read_byte(ins_data)) - - # es5506 - if True: - if self.meta.version >= 107: - es = InsFeatureES5506( - filter_mode=ESFilterMode(read_byte(ins_data)), - k1=read_short(ins_data), - k2=read_short(ins_data), - env_count=read_short(ins_data), - left_volume_ramp=read_byte(ins_data), - right_volume_ramp=read_byte(ins_data), - k1_ramp=read_byte(ins_data), - k2_ramp=read_byte(ins_data), - k1_slow=read_byte(ins_data), - k2_slow=read_byte(ins_data) - ) - self.features.append(es) - - # snes - if True: - if self.meta.version >= 109: - snes = InsFeatureSNES() - snes.use_env = bool(read_byte(ins_data)) - if self.meta.version >= 118: - snes.gain_mode = GainMode(read_byte(ins_data)) - snes.gain = read_byte(ins_data) - else: - read_byte(ins_data) - read_byte(ins_data) - snes.envelope.a = read_byte(ins_data) - snes.envelope.d = read_byte(ins_data) - snes_env_s = read_byte(ins_data) - snes.envelope.s = snes_env_s & 0b111 - snes.envelope.r = read_byte(ins_data) - snes.sus = SNESSusMode((snes_env_s >> 3) & 1) # ??? - self.features.append(snes) - - # macro speed delay - if True: - if self.meta.version >= 111: - vol_mac.speed = read_byte(ins_data) - arp_mac.speed = read_byte(ins_data) - duty_mac.speed = read_byte(ins_data) - wave_mac.speed = read_byte(ins_data) - pitch_mac.speed = read_byte(ins_data) - x1_mac.speed = read_byte(ins_data) - x2_mac.speed = read_byte(ins_data) - x3_mac.speed = read_byte(ins_data) - alg_mac.speed = read_byte(ins_data) - fb_mac.speed = read_byte(ins_data) - fms_mac.speed = read_byte(ins_data) - ams_mac.speed = read_byte(ins_data) - pan_l_mac.speed = read_byte(ins_data) - pan_r_mac.speed = read_byte(ins_data) - phase_res_mac.speed = read_byte(ins_data) - x4_mac.speed = read_byte(ins_data) - x5_mac.speed = read_byte(ins_data) - x6_mac.speed = read_byte(ins_data) - x7_mac.speed = read_byte(ins_data) - x8_mac.speed = read_byte(ins_data) - - vol_mac.delay = read_byte(ins_data) - arp_mac.delay = read_byte(ins_data) - duty_mac.delay = read_byte(ins_data) - wave_mac.delay = read_byte(ins_data) - pitch_mac.delay = read_byte(ins_data) - x1_mac.delay = read_byte(ins_data) - x2_mac.delay = read_byte(ins_data) - x3_mac.delay = read_byte(ins_data) - alg_mac.delay = read_byte(ins_data) - fb_mac.delay = read_byte(ins_data) - fms_mac.delay = read_byte(ins_data) - ams_mac.delay = read_byte(ins_data) - pan_l_mac.delay = read_byte(ins_data) - pan_r_mac.delay = read_byte(ins_data) - phase_res_mac.delay = read_byte(ins_data) - x4_mac.delay = read_byte(ins_data) - x5_mac.delay = read_byte(ins_data) - x6_mac.delay = read_byte(ins_data) - x7_mac.delay = read_byte(ins_data) - x8_mac.delay = read_byte(ins_data) - - for op in ops: - for i in range(20): - new_ops[op].macros[i].speed = read_byte(ins_data) - for i in range(20): - new_ops[op].macros[i].delay = read_byte(ins_data) - - # old arp mac format - if True: - if self.meta.version < 112: - if arp_mac.mode != 0: - arp_mac.mode = 0 - for i in range(len(arp_mac.data)): - if isinstance(arp_mac.data[i], int): - arp_mac.data[i] ^= 0x40000000 - - # add ops macros at the end - if True: - if self.meta.version >= 29: - for _, op_contents in new_ops.items(): - self.features.append(op_contents) diff --git a/loader/samples/minexample/furC64/chipchune/furnace/module.py b/loader/samples/minexample/furC64/chipchune/furnace/module.py deleted file mode 100644 index e6e7b27..0000000 --- a/loader/samples/minexample/furC64/chipchune/furnace/module.py +++ /dev/null @@ -1,1111 +0,0 @@ -import re -import zlib -from io import BytesIO, BufferedReader -from typing import BinaryIO, Optional, Literal, Union, Dict, List - -from chipchune._util import read_byte, read_short, read_int, read_float, read_str -from .data_types import ( - ModuleMeta, ChipList, ModuleCompatFlags, SubSong, PatchBay, ChannelDisplayInfo, - InputPatchBayEntry, OutputPatchBayEntry, ChipInfo, FurnacePattern, FurnaceRow -) -from .enums import ( - ChipType, LinearPitch, InputPortSet, OutputPortSet, LoopModality, - DelayBehavior, JumpTreatment, _FurInsImportType, _FurWavetableImportType, Note -) -from .instrument import FurnaceInstrument -from .wavetable import FurnaceWavetable -from .sample import FurnaceSample - -MAGIC_STR = b'-Furnace module-' -MAX_CHIPS = 32 - - -class FurnaceModule: - """ - Represents a Furnace .fur file. - - When possible, instrument objects etc. will use the latest format as its internal - representation. For example, old instruments will internally be converted into the - "new" instrument-feature-list format. - """ - - def __init__(self, file_name_or_stream: Optional[Union[BufferedReader, str]] = None) -> None: - """ - Creates or opens a new Furnace module as a Python object. - - :param file_name_or_stream: (Optional) - If specified, then it will parse a file as a FurnaceModule. If file name (str) is - given, it will load that file. If a stream (BufferedReader) instead is given, - it will parse it from the stream. - - Defaults to None. - """ - self.file_name: Optional[str] = None - """ - Original file name, if the object was initialized with one. - """ - self.meta: ModuleMeta = ModuleMeta() - """ - Metadata concerning the module. - """ - self.chips: ChipList = ChipList() - """ - List of chips used in the module. - """ - self.compat_flags: ModuleCompatFlags = ModuleCompatFlags() - """ - Compat flags settings within the module. - """ - self.subsongs: List[SubSong] = [SubSong()] - """ - Subsongs contained within the module. Although the first subsong - and the others are internally stored separately, they're organized - into a list here for convenience. - """ - self.patchbay: List[PatchBay] = [] - """ - List of patchbay connections. - """ - self.instruments: List[FurnaceInstrument] = [] - """ - List of all instruments in the module. - """ - self.patterns: List[FurnacePattern] = [] - """ - List of all patterns in the module. - """ - self.wavetables: List[FurnaceWavetable] = [] - - self.samples: List[FurnaceWavetable] = [] - - if isinstance(file_name_or_stream, BufferedReader): - self.load_from_stream(file_name_or_stream) - elif isinstance(file_name_or_stream, str): - self.load_from_file(file_name_or_stream) - - def load_from_file(self, file_name: Optional[str] = None) -> None: - """ - Load a module from a file name. The file may either be compressed or uncompressed. - - :param file_name: If not specified, it will grab from self.file_name instead. - """ - 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') - with open(self.file_name, 'rb') as f: - detect_magic = f.peek(len(MAGIC_STR))[:len(MAGIC_STR)] - if detect_magic != MAGIC_STR: # this is probably compressed, so try decompressing it first - return self.load_from_bytes( - zlib.decompress(f.read()) - ) - else: # uncompressed for sure - return self.load_from_stream(f) - - @staticmethod - def decompress_to_file(in_name: str, out_name: str) -> int: - """ - Simple zlib wrapper. Decompresses a zlib-compressed .fur - from in_name to out_name. Does not need instantiation. - - :param in_name: input file name - :param out_name: output file name - :return: Results of file.write(). - """ - with open(in_name, 'rb') as fi: - with open(out_name, 'wb') as fo: - return fo.write(zlib.decompress(fi.read())) - - def load_from_bytes(self, data: bytes) -> None: - """ - Load a module from a series of bytes. - - :param data: Bytes - """ - return self.load_from_stream( - BytesIO(data) - ) - - def load_from_stream(self, stream: BinaryIO) -> None: - """ - Load a module from an **uncompressed** stream. - - :param stream: File-like object containing the uncompressed module. - """ - # assumes uncompressed stream - if stream.read(len(MAGIC_STR)) != MAGIC_STR: - raise RuntimeError('Bad magic value; this is not a Furnace file or is corrupt') - - # clear defaults - self.chips.list.clear() - self.patchbay.clear() - self.subsongs[0].order.clear() - self.subsongs[0].speed_pattern.clear() - - self.__read_header(stream) - self.__init_compat_flags() - self.__read_info(stream) - if self.meta.version >= 119: - self.__read_dev119_chip_flags(stream) - self.__read_instruments(stream) - self.__read_wavetables(stream) - self.__read_samples(stream) - if self.meta.version >= 95: - self.__read_subsongs(stream) - self.__read_patterns(stream) - - def get_num_channels(self) -> int: - """ - Retrieve the number of total channels in the module. - - :return: Channel sum across all chips. - """ - num_channels = 0 - for chip in self.chips.list: - num_channels += chip.type.channels - return num_channels - - def get_pattern(self, channel: int, index: int, subsong: int=0) -> Optional[FurnacePattern]: - """ - Gets one pattern object from a module. - - :param channel: Which channel to use (zero-indexed), e.g. to get VRC6 - in a NES+VRC6 module, use `5`. - :param index: The index of the pattern within the subsong. - :param subsong: The subsong number. - :return: FurnacePattern object or None if no such pattern exists. - """ - try: - return next( - filter(lambda x: x.channel==channel and x.index==index and x.subsong==subsong, self.patterns) - ) - except StopIteration: - return None - - def __init_compat_flags(self) -> None: - """ - Initializes appropriate compat flags based on module version - """ - if self.meta.version < 37: - self.compat_flags.limit_slides = True - self.compat_flags.linear_pitch = LinearPitch.ONLY_PITCH_CHANGE - self.compat_flags.loop_modality = LoopModality.HARD_RESET_CHANNELS - if self.meta.version < 43: - self.compat_flags.proper_noise_layout = False - self.compat_flags.wave_duty_is_volume = False - if self.meta.version < 45: - self.compat_flags.reset_macro_on_porta = True - self.compat_flags.legacy_volume_slides = True - self.compat_flags.compatible_arpeggio = True - self.compat_flags.note_off_resets_slides = True - self.compat_flags.target_resets_slides = True - if self.meta.version < 46: - self.compat_flags.arpeggio_inhibits_portamento = True - self.compat_flags.wack_algorithm_macro = True - if self.meta.version < 49: - self.compat_flags.broken_shortcut_slides = True - if self.meta.version < 50: - self.compat_flags.ignore_duplicates_slides = False - if self.meta.version < 62: - self.compat_flags.stop_portamento_on_note_off = True - if self.meta.version < 64: - self.compat_flags.broken_dac_mode = False - if self.meta.version < 65: - self.compat_flags.one_tick_cut = False - if self.meta.version < 66: - self.compat_flags.instrument_change_allowed_in_porta = False - if self.meta.version < 69: - self.compat_flags.reset_note_base_on_arpeggio_stop = False - if self.meta.version < 71: - self.compat_flags.no_slides_on_first_tick = False - self.compat_flags.next_row_reset_arp_pos = False - self.compat_flags.ignore_jump_at_end = True - if self.meta.version < 72: - self.compat_flags.buggy_portamento_after_slide = True - self.compat_flags.gb_ins_affects_env = False - if self.meta.version < 78: - self.compat_flags.shared_extch_state = False - if self.meta.version < 83: - self.compat_flags.ignore_outside_dac_mode_change = True - self.compat_flags.e1e2_takes_priority = False - if self.meta.version < 84: - self.compat_flags.new_sega_pcm = False - if self.meta.version < 85: - self.compat_flags.weird_fnum_pitch_slides = True - if self.meta.version < 86: - self.compat_flags.sn_duty_resets_phase = True - if self.meta.version < 90: - self.compat_flags.linear_pitch_macro = False - if self.meta.version < 97: - self.compat_flags.old_octave_boundary = True - self.compat_flags.disable_opn2_dac_volume_control = True # dev98 - if self.meta.version < 99: - self.compat_flags.new_volume_scaling = False - self.compat_flags.volume_macro_lingers = False - self.compat_flags.broken_out_vol = True - if self.meta.version < 100: - self.compat_flags.e1e2_stop_on_same_note = False - if self.meta.version < 101: - self.compat_flags.broken_porta_after_arp = True - if self.meta.version < 108: - self.compat_flags.sn_no_low_periods = True - if self.meta.version < 110: - self.compat_flags.cut_delay_effect_policy = DelayBehavior.BROKEN - if self.meta.version < 113: - self.compat_flags.jump_treatment = JumpTreatment.FIRST_JUMP_ONLY - if self.meta.version < 115: - self.compat_flags.auto_sys_name = True - if self.meta.version < 117: - self.compat_flags.disable_sample_macro = True - if self.meta.version < 121: - self.compat_flags.broken_out_vol_2 = False - if self.meta.version < 130: - self.compat_flags.old_arp_strategy = True - if self.meta.version < 138: - self.compat_flags.broken_porta_during_legato = True - if self.meta.version < 155: - self.compat_flags.broken_fm_off = True - if self.meta.version < 168: - self.compat_flags.pre_note_no_effect = True - if self.meta.version < 183: - self.compat_flags.old_dpcm = True - if self.meta.version < 184: - self.compat_flags.reset_arp_phase_on_new_note = False - if self.meta.version < 188: - self.compat_flags.ceil_volume_scaling = False - if self.meta.version < 191: - self.compat_flags.old_always_set_volume = True - if self.meta.version < 200: - self.compat_flags.old_sample_offset = True - - # XXX: update my signature whenever a new compat flag block is added - def __read_compat_flags(self, stream: BinaryIO, phase: Literal[1, 2, 3]) -> None: - """ - Reads the set compat flags in the module - """ - if phase == 1: - compat_flags_to_skip = 20 - if self.meta.version < 37: - self.compat_flags.limit_slides = True - self.compat_flags.linear_pitch = LinearPitch.ONLY_PITCH_CHANGE - self.compat_flags.loop_modality = LoopModality.HARD_RESET_CHANNELS - else: # >= 37 - self.compat_flags.limit_slides = bool(read_byte(stream)) - self.compat_flags.linear_pitch = LinearPitch(read_byte(stream)) - self.compat_flags.loop_modality = LoopModality(read_byte(stream)) - compat_flags_to_skip -= 3 - - if self.meta.version >= 43: - self.compat_flags.proper_noise_layout = bool(read_byte(stream)) - self.compat_flags.wave_duty_is_volume = bool(read_byte(stream)) - compat_flags_to_skip -= 2 - - if self.meta.version >= 45: - self.compat_flags.reset_macro_on_porta = bool(read_byte(stream)) - self.compat_flags.legacy_volume_slides = bool(read_byte(stream)) - self.compat_flags.compatible_arpeggio = bool(read_byte(stream)) - self.compat_flags.note_off_resets_slides = bool(read_byte(stream)) - self.compat_flags.target_resets_slides = bool(read_byte(stream)) - compat_flags_to_skip -= 5 - - if self.meta.version >= 47: - self.compat_flags.arpeggio_inhibits_portamento = bool(read_byte(stream)) - self.compat_flags.wack_algorithm_macro = bool(read_byte(stream)) - compat_flags_to_skip -= 2 - - if self.meta.version >= 49: - self.compat_flags.broken_shortcut_slides = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 50: - self.compat_flags.ignore_duplicates_slides = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 62: - self.compat_flags.stop_portamento_on_note_off = bool(read_byte(stream)) - self.compat_flags.continuous_vibrato = bool(read_byte(stream)) - compat_flags_to_skip -= 2 - - if self.meta.version >= 64: - self.compat_flags.broken_dac_mode = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 65: - self.compat_flags.one_tick_cut = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 66: - self.compat_flags.instrument_change_allowed_in_porta = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 69: - self.compat_flags.reset_note_base_on_arpeggio_stop = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - elif phase == 2: - compat_flags_to_skip = 28 - if self.meta.version >= 70: - self.compat_flags.broken_speed_selection = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 71: - self.compat_flags.no_slides_on_first_tick = bool(read_byte(stream)) - self.compat_flags.next_row_reset_arp_pos = bool(read_byte(stream)) - self.compat_flags.ignore_jump_at_end = bool(read_byte(stream)) - compat_flags_to_skip -= 3 - - if self.meta.version >= 72: - self.compat_flags.buggy_portamento_after_slide = bool(read_byte(stream)) - self.compat_flags.gb_ins_affects_env = bool(read_byte(stream)) - compat_flags_to_skip -= 2 - - if self.meta.version >= 78: - self.compat_flags.shared_extch_state = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 83: - self.compat_flags.ignore_outside_dac_mode_change = bool(read_byte(stream)) - self.compat_flags.e1e2_takes_priority = bool(read_byte(stream)) - compat_flags_to_skip -= 2 - - if self.meta.version >= 84: - self.compat_flags.new_sega_pcm = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 85: - self.compat_flags.weird_fnum_pitch_slides = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 86: - self.compat_flags.sn_duty_resets_phase = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 90: - self.compat_flags.linear_pitch_macro = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 94: - self.compat_flags.pitch_slide_speed_in_linear = read_byte(stream) - compat_flags_to_skip -= 1 - - if self.meta.version >= 97: - self.compat_flags.old_octave_boundary = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 98: - self.compat_flags.disable_opn2_dac_volume_control = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 99: - self.compat_flags.new_volume_scaling = bool(read_byte(stream)) - self.compat_flags.volume_macro_lingers = bool(read_byte(stream)) - self.compat_flags.broken_out_vol = bool(read_byte(stream)) - compat_flags_to_skip -= 3 - - if self.meta.version >= 100: - self.compat_flags.e1e2_stop_on_same_note = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 101: - self.compat_flags.broken_porta_after_arp = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 108: - self.compat_flags.sn_no_low_periods = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 110: - self.compat_flags.cut_delay_effect_policy = DelayBehavior(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 113: - self.compat_flags.jump_treatment = JumpTreatment(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 115: - self.compat_flags.auto_sys_name = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 117: - self.compat_flags.disable_sample_macro = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 121: - self.compat_flags.broken_out_vol_2 = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 130: - self.compat_flags.old_arp_strategy = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - elif phase == 3: - compat_flags_to_skip = 8 - if self.meta.version >= 138: - self.compat_flags.broken_porta_during_legato = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 155: - self.compat_flags.broken_fm_off = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 168: - self.compat_flags.pre_note_no_effect = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 183: - self.compat_flags.old_dpcm = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 184: - self.compat_flags.reset_arp_phase_on_new_note = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 188: - self.compat_flags.ceil_volume_scaling = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - - if self.meta.version >= 191: - self.compat_flags.old_always_set_volume = bool(read_byte(stream)) - compat_flags_to_skip -= 1 - else: - raise ValueError( - 'Compat flag phase must be in between: 1, 2, 3' - ) - stream.read(compat_flags_to_skip) - - def __read_dev119_chip_flags(self, stream: BinaryIO) -> None: - for i in range(len(self.chips.list)): - # skip if this chip doesn't have flags - if self.__chip_flag_ptr[i] == 0: - continue - stream.seek(self.__chip_flag_ptr[i]) - - if stream.read(4) != b'FLAG': - raise ValueError('No "FLAG" magic') - - # i assume this will grow, you never know - blk_size = read_int(stream) - flag_blk = BytesIO(stream.read(blk_size)) - - # read entries in FLAG - for entry in [flag.split('=') for flag in read_str(flag_blk).split()]: - key = entry[0] - value = entry[1] - # cast by regex - if re.match(r'true', value): - self.chips.list[i].flags[key] = True - elif re.match(r'false', value): - self.chips.list[i].flags[key] = False - elif re.match(r'\d+$', value): - self.chips.list[i].flags[key] = int(value) - elif re.match(r'\d+\.\d+', value): - self.chips.list[i].flags[key] = float(value) - else: # all other values should be treated as a string - self.chips.list[i].flags[key] = value - - @staticmethod - def __convert_old_chip_flags(chip: ChipType, flag: int) -> Dict[str, Union[bool, int]]: - """ - Convert pre-v119 binary chip flags to the newer dict-style form. - - :param chip: ChipType - :param flag: flag value as a 32-bit number - :return: dictionary containing the flag's equivalent values - """ - n = {} - - if chip in [ChipType.GENESIS, ChipType.GENESIS_EX]: - n['clockSel'] = flag & 2147483647 # bits 0-30 - n['ladderEffect'] = bool((flag >> 31) & 1) - elif chip == ChipType.SMS: - cs = flag & 0xff03 - if cs > 0x100: - cs = cs - 252 # 0x100 + 4 - n['clockSel'] = cs - ct = (flag & 0xcc) // 4 - if ct >= 32: - ct -= 24 - elif ct >= 16: - ct -= 12 - n['chipType'] = ct - n['noPhaseReset'] = flag >> 4 - elif chip == ChipType.GB: - n['chipType'] = flag & 0b11 - n['noAntiClick'] = bool((flag >> 3) & 1) - elif chip == ChipType.PCE: - n['clockSel'] = flag & 1 - n['chipType'] = (flag >> 2) & 1 - n['noAntiClick'] = bool((flag >> 3) & 1) - elif chip in [ChipType.NES, ChipType.VRC6, ChipType.FDS, ChipType.MMC5]: - n['clockSel'] = flag & 0b11 - elif chip in [ChipType.C64_8580, ChipType.C64_6581]: - n['clockSel'] = flag & 0b1111 - elif chip == ChipType.SEGA_ARCADE: - n['clockSel'] = flag & 0b11111111 - elif chip in [ChipType.NEO_GEO_CD, ChipType.NEO_GEO, ChipType.NEO_GEO_EX, - ChipType.NEO_GEO_CD_EX, ChipType.YM2610B, ChipType.YM2610B_EX]: - n['clockSel'] = flag & 0b11111111 - elif chip == ChipType.AY38910: - n['clockSel'] = flag & 0b1111 - n['chipType'] = (flag >> 4) & 0b11 - n['stereo'] = bool((flag >> 6) & 1) - n['halfClock'] = bool((flag >> 7) & 1) - n['stereoSep'] = (flag >> 8) & 0b11111111 - elif chip == ChipType.AMIGA: - n['clockSel'] = flag & 1 - n['chipType'] = (flag >> 1) & 1 - n['bypassLimits'] = bool((flag >> 2) & 1) - n['stereoSep'] = (flag >> 8) & 0b1111111 - elif chip == ChipType.YM2151: - n['clockSel'] = flag & 0b11111111 - elif chip in [ChipType.YM2612, ChipType.YM2612_EX, ChipType.YM2612_PLUS, - ChipType.YM2612_PLUS_EX]: - n['clockSel'] = flag & 2147483647 # bits 0-30 - n['ladderEffect'] = bool((flag >> 31) & 1) - elif chip == ChipType.TIA: - n['clockSel'] = flag & 1 - n['mixingType'] = (flag >> 1) & 0b11 - elif chip == ChipType.VIC20: - n['clockSel'] = flag & 1 - elif chip == ChipType.SNES: - n['volScaleL'] = flag & 0b1111111 - n['volScaleR'] = (flag >> 8) & 0b1111111 - elif chip in [ChipType.OPLL, ChipType.OPLL_DRUMS]: - n['clockSel'] = flag & 0b1111 - n['patchSet'] = flag >> 4 # safe - elif chip == ChipType.N163: - n['clockSel'] = flag & 0b1111 - n['channels'] = (flag >> 4) & 0b111 - n['multiplex'] = bool((flag >> 7) & 1) - elif chip in [ChipType.OPN, ChipType.YM2203_EX]: - n['clockSel'] = flag & 0b11111 - n['prescale'] = (flag >> 5) & 0b11 - elif chip in [ChipType.OPL, ChipType.OPL_DRUMS, ChipType.OPL2, ChipType.OPL2_DRUMS, - ChipType.Y8950, ChipType.Y8950_DRUMS]: - n['clockSel'] = flag & 0b11111111 - elif chip in [ChipType.OPL3, ChipType.OPL3_DRUMS]: - n['clockSel'] = flag & 0b11111111 - elif chip == ChipType.PC_SPEAKER: - n['speakerType'] = flag & 0b11 - elif chip == ChipType.RF5C68: - n['clockSel'] = flag & 0b1111 - n['chipType'] = flag >> 4 # safe - elif chip in [ChipType.SAA1099, ChipType.OPZ]: - n['clockSel'] = flag & 0b11 - elif chip == ChipType.AY8930: - n['clockSel'] = flag & 0b1111 - n['stereo'] = bool((flag >> 6) & 1) - n['halfClock'] = bool((flag >> 7) & 1) - n['stereoSep'] = (flag >> 8) & 0b11111111 - elif chip == ChipType.VRC7: - n['clockSel'] = flag & 0b11 - elif chip == ChipType.ZX_BEEPER: - n['clockSel'] = flag & 1 - elif chip in [ChipType.SCC, ChipType.SCC_PLUS]: - n['clockSel'] = flag & 0b11 - elif chip == ChipType.MSM6295: - n['clockSel'] = flag & 0b1111111 - n['rateSel'] = bool((flag >> 7) & 1) - elif chip == ChipType.MSM6258: - n['clockSel'] = flag & 0b11 - elif chip in [ChipType.OPL4, ChipType.OPL4_DRUMS]: - n['clockSel'] = flag & 0b11111111 - elif chip == ChipType.SETA: - n['clockSel'] = flag & 0b1111 - n['stereo'] = bool((flag >> 4) & 1) - elif chip == ChipType.ES5506: - n['channels'] = flag & 0b11111 - elif chip == ChipType.TSU: - n['clockSel'] = flag & 1 - n['echo'] = bool((flag >> 2) & 1) - n['swapEcho'] = bool((flag >> 3) & 1) - n['sampleMemSize'] = (flag >> 4) & 1 - n['pdm'] = bool((flag >> 5) & 1) - n['echoDelay'] = (flag >> 8) & 0b111111 - n['echoFeedback'] = (flag >> 16) & 0b1111 - n['echoResolution'] = (flag >> 20) & 0b1111 - n['echoVol'] = (flag >> 24) & 0b11111111 - elif chip == ChipType.YMZ280B: - n['clockSel'] = flag & 0b11111111 - elif chip == ChipType.PCM_DAC: - n['rate'] = (flag & 0b1111111111111111) + 1 - n['outDepth'] = (flag >> 16) & 0b1111 - n['stereo'] = bool((flag >> 20) & 1) - elif chip == ChipType.QSOUND: - n['echoDelay'] = flag & 0b1111111111111 - n['echoFeedback'] = (flag >> 16) & 0b11111111 - return n - - def __read_header(self, stream: BinaryIO) -> None: - # assuming we passed the magic number check - self.meta.version = read_short(stream) - stream.read(2) # RESERVED - self.__song_info_ptr = read_int(stream) - stream.read(8) # RESERVED - - def __read_info(self, stream: BinaryIO) -> None: - stream.seek(self.__song_info_ptr) - if stream.read(4) != b'INFO': - raise ValueError('No "INFO" magic') - - if self.meta.version < 100: # don't read size prior to 0.6pre1 - stream.read(4) - info_blk = stream - else: - blk_size = read_int(stream) - info_blk = BytesIO(stream.read(blk_size)) - - # info of first subsong - self.subsongs[0].timing.timebase = (read_byte(info_blk) + 1) - self.subsongs[0].timing.speed = ( - read_byte(info_blk), - read_byte(info_blk) - ) - self.subsongs[0].timing.arp_speed = read_byte(info_blk) - self.subsongs[0].timing.clock_speed = read_float(info_blk) - self.subsongs[0].pattern_length = read_short(info_blk) - len_orders = read_short(info_blk) - self.subsongs[0].timing.highlight = ( - read_byte(info_blk), - read_byte(info_blk) - ) - - # global - num_insts = read_short(info_blk) - num_waves = read_short(info_blk) - num_samples = read_short(info_blk) - num_patterns = read_int(info_blk) - - # fetch chip list - for chip_id in info_blk.read(MAX_CHIPS): - if chip_id == 0: - break # seek position is after chips here - self.chips.list.append( - ChipInfo(ChipType(chip_id)) # type: ignore - ) - - # fetch volume - for i in range(MAX_CHIPS): - vol = read_byte(info_blk, True) / 64.0 - if i >= len(self.chips.list): # cut here - continue - self.chips.list[i].volume = vol - - for i in range(MAX_CHIPS): - pan = read_byte(info_blk, True) / 128.0 - if i >= len(self.chips.list): # cut here - continue - self.chips.list[i].panning = pan - - if self.meta.version >= 119: - self.__chip_flag_ptr: List[int] = [ - read_int(info_blk) for _ in range(MAX_CHIPS) - ] - else: - for i in range(MAX_CHIPS): - flag = read_int(info_blk) - if i < len(self.chips.list): - self.chips.list[i].flags.update( - self.__convert_old_chip_flags(self.chips.list[i].type, flag) - ) - - self.meta.name = read_str(info_blk) - self.meta.author = read_str(info_blk) - self.meta.tuning = read_float(info_blk) - - # Compat flags, part I - self.__read_compat_flags(info_blk, 1) - - self.__instrument_ptr = [ - read_int(info_blk) for _ in range(num_insts) - ] - - self.__wavetable_ptr = [ - read_int(info_blk) for _ in range(num_waves) - ] - - self.__sample_ptr = [ - read_int(info_blk) for _ in range(num_samples) - ] - - self.__pattern_ptr = [ - read_int(info_blk) for _ in range(num_patterns) - ] - - num_channels = self.get_num_channels() - - for channel in range(self.get_num_channels()): - self.subsongs[0].order[channel] = [ - read_byte(info_blk) for _ in range(len_orders) - ] - - self.subsongs[0].effect_columns = [ - read_byte(info_blk) for _ in range(num_channels) - ] - - # set up channels display info - self.subsongs[0].channel_display = [ - ChannelDisplayInfo() for _ in range(num_channels) - ] - - for i in range(num_channels): - self.subsongs[0].channel_display[i].shown = bool(read_byte(info_blk)) - - for i in range(num_channels): - self.subsongs[0].channel_display[i].collapsed = bool(read_byte(info_blk)) - - for i in range(num_channels): - self.subsongs[0].channel_display[i].name = read_str(info_blk) - - for i in range(num_channels): - self.subsongs[0].channel_display[i].abbreviation = read_str(info_blk) - - self.meta.comment = read_str(info_blk) - - # Master volume - if self.meta.version >= 59: - self.chips.master_volume = read_float(info_blk) - - # Compat flags, part II - if self.meta.version >= 70: - self.__read_compat_flags(info_blk, 2) - if self.meta.version >= 96: - self.subsongs[0].timing.virtual_tempo = ( - read_short(info_blk), read_short(info_blk) - ) - else: - info_blk.read(4) # reserved in self.meta.version < 96 - - # Subsongs - if self.meta.version >= 95: - self.subsongs[0].name = read_str(info_blk) - self.subsongs[0].comment = read_str(info_blk) - num_extra_subsongs = read_byte(info_blk) - info_blk.read(3) # reserved - self.__subsong_ptr = [ - read_int(info_blk) for _ in range(num_extra_subsongs) - ] - - # Extra metadata - if self.meta.version >= 103: - self.meta.sys_name = read_str(info_blk) - self.meta.album = read_str(info_blk) - # TODO: need to take encoding into account - self.meta.name_jp = read_str(info_blk) - self.meta.author_jp = read_str(info_blk) - self.meta.sys_name_jp = read_str(info_blk) - self.meta.album_jp = read_str(info_blk) - - # New chip mixer and patchbay - if self.meta.version >= 135: - for i in range(len(self.chips.list)): - # new chip volume/panning format takes precedence over the legacy one - # if you save a .fur with this, legacy and new volume/panning formats - # have the same value. different values shouldn't be possible - self.chips.list[i].volume = read_float(info_blk) - self.chips.list[i].panning = read_float(info_blk) - self.chips.list[i].surround = read_float(info_blk) - num_patchbay_connections = read_int(info_blk) - for _ in range(num_patchbay_connections): - src = read_short(info_blk) - dst = read_short(info_blk) - self.patchbay.append( - PatchBay( - dest=InputPatchBayEntry( - set=InputPortSet(src >> 4), - port=src & 0b1111 - ), - source=OutputPatchBayEntry( - set=OutputPortSet(dst >> 4), - port=dst & 0b1111 - ) - ) - ) - - if self.meta.version >= 136: - self.compat_flags.auto_patchbay = bool(read_byte(info_blk)) - - # Compat flags, part III - if self.meta.version >= 138: - self.__read_compat_flags(info_blk, 3) - - # Speed patterns and grooves - if self.meta.version >= 139: - # speed pattern - len_speed_pattern = read_byte(info_blk) - if (len_speed_pattern < 0) or (len_speed_pattern > 16): - raise ValueError('Invalid speed pattern length value') - self.subsongs[0].speed_pattern = [ - read_byte(info_blk) for _ in range(len_speed_pattern) - ] - info_blk.read(16 - len_speed_pattern) # skip that many bytes, because it's always 0x06 - - # groove - len_groove_list = read_byte(info_blk) - for _ in range(len_groove_list): - len_groove = read_byte(info_blk) - self.subsongs[0].grooves.append([ - read_byte(info_blk) for _ in range(len_groove) - ]) - info_blk.read(16 - len_groove) # TODO: i assume the same as above. i hope i'm right - - def __read_instruments(self, stream: BinaryIO) -> None: - for i in self.__instrument_ptr: - if i == 0: - break - stream.seek(i) - new_ins = FurnaceInstrument() - if self.meta.version < 127: # i trust this not to screw up - new_ins.load_from_stream(stream, _FurInsImportType.FORMAT_0_EMBED) - else: - new_ins.load_from_stream(stream, _FurInsImportType.FORMAT_1_EMBED) - self.instruments.append(new_ins) - - def __read_wavetables(self, stream: BinaryIO) -> None: - for i in self.__wavetable_ptr: - if i == 0: - break - stream.seek(i) - new_wt = FurnaceWavetable() - new_wt.load_from_stream(stream, _FurWavetableImportType.EMBED) - self.wavetables.append(new_wt) - - def __read_samples(self, stream: BinaryIO) -> None: - for i in self.__sample_ptr: - if i == 0: - break - stream.seek(i) - new_wt = FurnaceSample() - new_wt.load_from_stream(stream) - self.samples.append(new_wt) - - def __read_patterns(self, stream: BinaryIO) -> None: - for i in self.__pattern_ptr: - if i == 0: - break - stream.seek(i) - - # Old pattern - if self.meta.version < 157: - if stream.read(4) != b'PATR': - raise ValueError('No "PATR" magic') - sz = read_int(stream) - if sz == 0: - patr_blk = stream - else: - patr_blk = BytesIO(stream.read(sz)) - - new_patr = FurnacePattern() - new_patr.channel = read_short(patr_blk) - new_patr.index = read_short(patr_blk) - new_patr.subsong = read_short(patr_blk) - if self.meta.version < 95: - assert new_patr.subsong == 0 - read_short(patr_blk) # reserved - - num_rows = self.subsongs[new_patr.subsong].pattern_length - - for _ in range(num_rows): - row = FurnaceRow( - note=Note(read_short(patr_blk)), - octave=read_short(patr_blk), - instrument=read_short(patr_blk), - volume=read_short(patr_blk) - ) - row.octave += (1 if row.note == Note.C_ else 0) - effect_columns = self.subsongs[new_patr.subsong].effect_columns[new_patr.channel] - row.effects = [ - (read_short(patr_blk), read_short(patr_blk)) for _ in range(effect_columns) - ] - new_patr.data.append(row) - - if self.meta.version >= 51: - new_patr.name = read_str(patr_blk) - - # New pattern - else: - if stream.read(4) != b'PATN': - raise ValueError('No "PATN" magic') - sz = read_int(stream) - if sz == 0: - patr_blk = stream - else: - patr_blk = BytesIO(stream.read(sz)) - - new_patr = FurnacePattern() - new_patr.subsong = read_byte(patr_blk) - new_patr.channel = read_byte(patr_blk) - new_patr.index = read_short(patr_blk) - new_patr.name = read_str(patr_blk) - - num_rows = self.subsongs[new_patr.subsong].pattern_length - effect_columns = self.subsongs[new_patr.subsong].effect_columns[new_patr.channel] - - empty_row = lambda: FurnaceRow(Note.__, 0, 0xffff, 0xffff, [(0xffff,0xffff)] * effect_columns) - - row_idx = 0 - while row_idx < num_rows: - char = read_byte(patr_blk) - # end of pattern - if char == 0xff: - break - # skip N+2 rows - if char & 0x80: - skip = (char & 0x7f) + 2 - row_idx += skip - for _ in range(skip): - new_patr.data.append(empty_row()) - continue - # check if some values present - effect_present_list = [False] * 8 - effect_val_present_list = [False] * 8 - note_present = bool(char & 0x01) - ins_present = bool(char & 0x02) - volume_present = bool(char & 0x04) - effect_present_list[0] = bool(char & 0x08) - effect_val_present_list[0] = bool(char & 0x10) - effect_0_3_present = bool(char & 0x20) - effect_4_7_present = bool(char & 0x40) - if effect_0_3_present: - char = read_byte(patr_blk) - assert effect_present_list[0] == bool(char & 0x01) - assert effect_val_present_list[0] == bool(char & 0x02) - effect_present_list[1] = bool(char & 0x04) - effect_val_present_list[1] = bool(char & 0x08) - effect_present_list[2] = bool(char & 0x10) - effect_val_present_list[2] = bool(char & 0x20) - effect_present_list[3] = bool(char & 0x40) - effect_val_present_list[3] = bool(char & 0x80) - if effect_4_7_present: - char = read_byte(patr_blk) - effect_present_list[4] = bool(char & 0x01) - effect_val_present_list[4] = bool(char & 0x02) - effect_present_list[5] = bool(char & 0x04) - effect_val_present_list[5] = bool(char & 0x08) - effect_present_list[6] = bool(char & 0x10) - effect_val_present_list[6] = bool(char & 0x20) - effect_present_list[7] = bool(char & 0x40) - effect_val_present_list[7] = bool(char & 0x80) - - # actually read present values - note, octave = Note(0), 0 - if note_present: - raw_note = read_byte(patr_blk) - if raw_note == 180: - note = Note.OFF - elif raw_note == 181: - note = Note.OFF_REL - elif raw_note == 182: - note = Note.REL - else: - note = raw_note % 12 - note = 12 if note == 0 else note - note = Note(note) - octave = -5 + raw_note // 12 - - ins, volume = 0xffff, 0xffff - if ins_present: - ins = read_byte(patr_blk) - if volume_present: - volume = read_byte(patr_blk) - - row = FurnaceRow( - note=note, - octave=octave, - instrument=ins, - volume=volume - ) - - row.effects = [(0xffff,0xffff)] * effect_columns - for i, fx_presents in enumerate(zip(effect_present_list, effect_val_present_list)): - if i >= effect_columns: - break - fx_cmd, fx_val = 0xffff, 0xffff - if fx_presents[0]: - fx_cmd = read_byte(patr_blk) - if fx_presents[1]: - fx_val = read_byte(patr_blk) - row.effects[i] = (fx_cmd, fx_val) - - new_patr.data.append(row) - row_idx += 1 - - # fill the rest of the pattern with EMPTY - while row_idx < num_rows: - new_patr.data.append(empty_row()) - row_idx += 1 - - self.patterns.append(new_patr) - - def __read_subsongs(self, stream: BinaryIO) -> None: - for i in self.__subsong_ptr: - if i == 0: - break - stream.seek(i) - if stream.read(4) != b'SONG': - raise ValueError('No "SONG" magic') - subsong_blk = BytesIO(stream.read(read_int(stream))) - new_subsong = SubSong() - new_subsong.order.clear() - new_subsong.speed_pattern.clear() - - new_subsong.timing.timebase = read_byte(subsong_blk) - new_subsong.timing.speed = ( - read_byte(subsong_blk), read_byte(subsong_blk) - ) - new_subsong.timing.arp_speed = read_byte(subsong_blk) - new_subsong.timing.clock_speed = read_float(subsong_blk) - new_subsong.pattern_length = read_short(subsong_blk) - new_subsong_len_orders = read_short(subsong_blk) - new_subsong.timing.highlight = ( - read_byte(subsong_blk), read_byte(subsong_blk) - ) - new_subsong.timing.virtual_tempo = ( - read_short(subsong_blk), read_short(subsong_blk) - ) - new_subsong.name = read_str(subsong_blk) - new_subsong.comment = read_str(subsong_blk) - - num_channels = self.get_num_channels() - - for channel in range(self.get_num_channels()): - new_subsong.order[channel] = [ - read_byte(subsong_blk) for _ in range(new_subsong_len_orders) - ] - - new_subsong.effect_columns = [ - read_byte(subsong_blk) for _ in range(num_channels) - ] - - # set up channels display info - new_subsong.channel_display = [ - ChannelDisplayInfo() for _ in range(num_channels) - ] - - for i in range(num_channels): - new_subsong.channel_display[i].shown = bool(read_byte(subsong_blk)) - - for i in range(num_channels): - new_subsong.channel_display[i].collapsed = bool(read_byte(subsong_blk)) - - for i in range(num_channels): - new_subsong.channel_display[i].name = read_str(subsong_blk) - - for i in range(num_channels): - new_subsong.channel_display[i].abbreviation = read_str(subsong_blk) - - # Speed patterns and grooves - if self.meta.version >= 139: - # speed pattern - len_speed_pattern = read_byte(subsong_blk) - if (len_speed_pattern < 0) or (len_speed_pattern > 16): - raise ValueError('Invalid speed pattern length value') - new_subsong.speed_pattern = [ - read_byte(subsong_blk) for _ in range(len_speed_pattern) - ] - - self.subsongs.append(new_subsong) - - def __str__(self) -> str: - return '' % ( - self.meta.version, self.meta.name, self.meta.author - ) diff --git a/loader/samples/minexample/furC64/chipchune/furnace/sample.py b/loader/samples/minexample/furC64/chipchune/furnace/sample.py deleted file mode 100644 index 1139050..0000000 --- a/loader/samples/minexample/furC64/chipchune/furnace/sample.py +++ /dev/null @@ -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) diff --git a/loader/samples/minexample/furC64/chipchune/furnace/wavetable.py b/loader/samples/minexample/furC64/chipchune/furnace/wavetable.py deleted file mode 100644 index cec13cb..0000000 --- a/loader/samples/minexample/furC64/chipchune/furnace/wavetable.py +++ /dev/null @@ -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)] diff --git a/loader/samples/minexample/furC64/chipchune/interchange/__init__.py b/loader/samples/minexample/furC64/chipchune/interchange/__init__.py deleted file mode 100644 index ec33a22..0000000 --- a/loader/samples/minexample/furC64/chipchune/interchange/__init__.py +++ /dev/null @@ -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. - -""" diff --git a/loader/samples/minexample/furC64/chipchune/interchange/enums.py b/loader/samples/minexample/furC64/chipchune/interchange/enums.py deleted file mode 100644 index 6d553b6..0000000 --- a/loader/samples/minexample/furC64/chipchune/interchange/enums.py +++ /dev/null @@ -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() diff --git a/loader/samples/minexample/furC64/chipchune/interchange/furnace.py b/loader/samples/minexample/furC64/chipchune/interchange/furnace.py deleted file mode 100644 index 4f39640..0000000 --- a/loader/samples/minexample/furC64/chipchune/interchange/furnace.py +++ /dev/null @@ -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.__ \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/utils/__init__.py b/loader/samples/minexample/furC64/chipchune/utils/__init__.py deleted file mode 100644 index 88e24f3..0000000 --- a/loader/samples/minexample/furC64/chipchune/utils/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -""" -Utilities for manipulating, converting, etc. tracker data. - -- :mod:`chipchune.utils.conversion`: Conversion tools. -""" \ No newline at end of file diff --git a/loader/samples/minexample/furC64/chipchune/utils/conversion.py b/loader/samples/minexample/furC64/chipchune/utils/conversion.py deleted file mode 100644 index 0c6c5b1..0000000 --- a/loader/samples/minexample/furC64/chipchune/utils/conversion.py +++ /dev/null @@ -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 diff --git a/loader/samples/minexample/furC64/convert.bat b/loader/samples/minexample/furC64/convert.bat deleted file mode 100644 index 5044a81..0000000 --- a/loader/samples/minexample/furC64/convert.bat +++ /dev/null @@ -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 diff --git a/loader/samples/minexample/furC64/convert.sh b/loader/samples/minexample/furC64/convert.sh deleted file mode 100755 index ffcc96b..0000000 --- a/loader/samples/minexample/furC64/convert.sh +++ /dev/null @@ -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 diff --git a/loader/samples/minexample/furC64/convert_to_asm.py b/loader/samples/minexample/furC64/convert_to_asm.py deleted file mode 100644 index 531f72f..0000000 --- a/loader/samples/minexample/furC64/convert_to_asm.py +++ /dev/null @@ -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() diff --git a/loader/samples/minexample/guy_amb.fur b/loader/samples/minexample/guy_amb.fur deleted file mode 100644 index 2368704..0000000 Binary files a/loader/samples/minexample/guy_amb.fur and /dev/null differ diff --git a/loader/samples/minexample/guy_appear.fur b/loader/samples/minexample/guy_appear.fur deleted file mode 100644 index 60201fe..0000000 Binary files a/loader/samples/minexample/guy_appear.fur and /dev/null differ diff --git a/loader/samples/minexample/lilia_talk.bin b/loader/samples/minexample/lilia_talk.bin deleted file mode 100644 index c1e4ede..0000000 Binary files a/loader/samples/minexample/lilia_talk.bin and /dev/null differ diff --git a/loader/samples/minexample/liltalk.bin b/loader/samples/minexample/liltalk.bin deleted file mode 100644 index 56a2722..0000000 Binary files a/loader/samples/minexample/liltalk.bin and /dev/null differ diff --git a/loader/samples/minexample/liltalk_full_rebuild.sh b/loader/samples/minexample/liltalk_full_rebuild.sh deleted file mode 100644 index ea59a78..0000000 --- a/loader/samples/minexample/liltalk_full_rebuild.sh +++ /dev/null @@ -1,4 +0,0 @@ -python3 conv_liltalk.py -./build_liltalk.sh -rm main.o main.zx0* -make diff --git a/loader/samples/minexample/liltalk_speak.txt b/loader/samples/minexample/liltalk_speak.txt deleted file mode 100644 index 9e6e97d..0000000 --- a/loader/samples/minexample/liltalk_speak.txt +++ /dev/null @@ -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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/loader/samples/minexample/main.asm b/loader/samples/minexample/main.asm index 0abc99b..3718b33 100644 --- a/loader/samples/minexample/main.asm +++ b/loader/samples/minexample/main.asm @@ -1,693 +1,15 @@ .feature c_comments -.include "../../build/loadersymbols-c64.inc" -.ZEROPAGE -.org $10 -bmp_delay: .res 1 -bmp_addr: .res 2 -bmp_ptr: .res 2 -scr_ptr_lo: .res 1 -scr_ptr: .res 2 -cram_ptr: .res 2 -chr_count: .res 1 -vbl: .res 1 -frame: .res 1 -cur_frame: .res 1 -frame_delay: .res 1 -frame_until: .res 1 -text_ptr: .res 2 -timer: .res 2 -timer_limit: .res 2 -timer_reached: .res 2 -timer_mode: .res 1 -enable_music: .res 1 -temp: .res 3 -dialog_col: .res 1 -dialog_tick: .res 1 - -.include "lz_zp.asm" - -zx02 = $0832 -check_return = $08b8 -CODE_START_ADDR = $e000 -aart_lz_buffer = $fd00 +.zeropage .segment "CODE" -ZP=$e0 -offset = ZP+0 -ZX0_src = ZP+2 -ZX0_dst = ZP+4 -bitr = ZP+6 -pntr = ZP+7 - - - .org CODE_START_ADDR -code_start: - lda #0 - sta $d020 - sta ZX0_dst+0 - lda #$0b - sta $d011 - jsr load_font - .assert * = CODE_START_ADDR + 15, error - lda #0 - sta enable_music - jsr init_2x - jsr clr_txt - ldx #copyright - jsr write_txt3 - ldx #$00 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #badguy - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$90 - ldy #$01 - jsr txt_fade_out - +.org $080D +main: sei - jsr init_bmp - jsr set_irq_badguy - lda #0 - sta vbl - cli + lda #$35 + sta $01 - jsr intro - - lda #$0b - sta $d011 - - sei - ldx #introname - lda #$10 - jsr load_8000_zx02 - - ldx #song0name - lda #$a0 - jsr load_8000_zx02 - - lda #fake_kernal_irq - sta $ffff - inc enable_music - - jsr run_nufli_bmp - sei - jsr init_2x - lda #$0b - sta $d011 - - jsr clr_txt - ldx #story_writ - jsr write_txt3 - ldx #$30 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #towername - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$b8 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #0 - sta vbl - - lda #$11 - jsr wait_frame_until_2x - - ldx #$6c -: - jsr wait_frame - jsr wait_frame - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #scenario_writ - jsr write_txt2 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #towerbeamname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$90 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #0 - sta vbl - - lda #$0d - jsr wait_frame_until_2x - lda bmp_addr - sta temp - lda bmp_addr+1 - sta temp+1 - lda cur_frame - sta temp+2 - - ldx #17 -: - txa - pha - lda temp+2 - sta cur_frame - lda temp - sta bmp_addr - lda temp+1 - sta bmp_addr+1 - lda #$0d+3 - jsr wait_frame_until_2x - pla - tax - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #prog_writ - jsr write_txt2 - ldx #$a8 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #fieldname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #0 - sta vbl - - lda #$08 - jsr wait_frame_until_2x - lda bmp_addr - sta temp - lda bmp_addr+1 - sta temp+1 - lda cur_frame - sta temp+2 - - ldx #2 -: - txa - pha - lda temp+2 - sta cur_frame - lda temp - sta bmp_addr - lda temp+1 - sta bmp_addr+1 - lda #$08+8 - jsr wait_frame_until_2x - pla - tax - dex - bpl :- - - - lda #0 - sta vbl - lda #$27 - jsr wait_frame_until_2x - - ldx #25 -: - jsr wait_frame - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #gart_writ - jsr write_txt5 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #fallingstarname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - lda #$1d - jsr wait_frame_until_2x - - ldx #5 -: - jsr wait_frame - dex - bpl :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #music_writ - jsr write_txt4 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #lilianame - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$10 - ldy #$01 - lda #8*11 - jsr txt_fade_out_offset - - ldx #$c4 - ldy #$01 - jsr init_timer - - jsr init_bmp - - lda #$08 - jsr wait_frame_until_2x - -: - lda timer_reached - beq :- - - lda #$0b - sta $d011 - - jsr clr_txt - ldx #scene_writ - jsr write_txt3 - ldx #$80 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #liliaheroname - jsr load_8000_zx02_2000 - -: - lda timer_reached - beq :- - - ldx #$20 - ldy #$01 - jsr txt_fade_out - - jsr init_bmp - - ldx #4 -: - lda #0 - sta vbl - lda #60 -: - cmp vbl - bne :- - dex - bpl :-- - -part_9: - ; $0400-$07ff buffer 0 tilemap - ; $2000-$3fff buffer 0 bitmap - ; $4000-$5fff buffer 1 bitmap - ; $6000-$63ff buffer 1 tilemap - ; $6400-$6417 next buffer CRAM - ; $7000-$77ff tileset bitmap - ; $7800-$78ff tileset tile colors - ; $7900-$79ff tileset CRAM colors - ; $9000- compressed tilemap - - jsr clr_txt - ldx #art_direct - jsr write_txt2 - ldx #$c0 - ldy #$01 - jsr init_timer - - lda #1 - sta timer_mode - - ldx #islandname - lda #$70 - jsr load_8000_zx02 - ldx #islandmapname - jsr loadraw - ldx #0 - ldy #$90 - jsr LZ_init_decomp - -: - lda timer_reached - beq :- - - ldx #$90 - ldy #$01 - lda #8 - jsr txt_fade_out_offset - - lda #0 - sta $d011 - jsr clear_2bufs - - ; set up sprites to cover scrolling - lda #$ff - ldx #0 -: sta $2000,x - sta $4000,x - inx - bne :- - .repeat 4, I - ldx #I*48+$58 - stx $d000+I*2 - stx $d008+I*2 - .endrepeat - ldx #6 -: - lda #$42 - sta $d001,x - lda #$d7 - sta $d009,x - dex - dex - bpl :- - ldx #7 -: - lda #$80 - sta $07f8,x - lda #0 - sta $63f8,x - sta $d027,x - dex - bpl :- - stx $d01d - stx $d015 - inx - stx $d010 - stx $d017 - stx $d01b - stx $d01c - stx frame - - lda #$18 - sta $d018 - lda #<((17+4)*40+$408) - sta text_ptr - lda #>((17+4)*40+$408) - sta text_ptr+1 - ldx #16 -: - lda #0 - lda text_ptr - sec - sbc #40 - sta text_ptr - sta scr_ptr - sta cram_ptr - sta bmp_ptr - lda text_ptr+1 - sbc #0 - sta text_ptr+1 - sta scr_ptr+1 - ; carry is always set here - adc #$d8-$04-1 - sta cram_ptr+1 - adc #<(($20>>3)-$d8) - asl bmp_ptr - rol a - asl bmp_ptr - rol a - asl bmp_ptr - rol a - sta bmp_ptr+1 - stx temp+1 - jsr drawrow - ldx temp+1 - dex - bpl :- - lda #0 - sta cram_ptr - lda #$64 - sta cram_ptr+1 -: - lda $d011 - bpl :- - lda #$38 - sta $d011 - lda #$18 - sta $d016 - lda #3 - sta timer_mode -@loop: - lda #0 - sta vbl - lda frame - cmp #$e1 - bcc :+ - jmp @finish -: - and #1 - tax - jsr copybuf - jsr drawrow -: - lda vbl - cmp #32 - bcc :- - ; B U M R U S H C R A M C O P Y F U N K - ldy #23 -: .repeat 16, I - lda $d808+(19-I)*40,y - sta $d808+(20-I)*40,y - .endrepeat - lda $6400,y - sta $d808+4*40,y - dey - bpl :- - inc frame - lda frame - lsr a - lda #$18 - ldx #3 - bcc :+ - lda #$80 - ldx #2 -: - sta $d018 - stx $dd00 - jmp @loop - -@finish: - ldx #$a8 - ldy #$01 - jsr init_timer -: - lda timer_reached - beq :- - lda #$0b - sta $d011 - lda #0 - sta $d015 - lda #3 - sta $dd00 - - ; we run out of space before the fixed location vector return now - jmp part_10 - -drawrow: - ldy #0 -charloop: - sty temp - lda #$70>>3 - sta bmp_addr+1 - jsr LZ_get_byte - tax - asl a - rol bmp_addr+1 - asl a - rol bmp_addr+1 - asl a - rol bmp_addr+1 - sta bmp_addr - ldy #0 - .repeat 8, I - lda (bmp_addr),y - sta (bmp_ptr),y - iny - .endrepeat - clc - lda bmp_ptr - adc #8 - sta bmp_ptr - bne :+ - inc bmp_ptr+1 -: - ldy temp - lda $7800,x - sta (scr_ptr),y - lda $7900,x - sta (cram_ptr),y - iny - cpy #24 - bne charloop - rts - -intro: - lda #0 - jsr sfx_init - - lda #7 - jsr wait_frame_until - - lda #64 - sta frame_delay - jsr wait_loop - - lda #1 - jsr sfx_init - - ldx #darmtower_txt - jsr upload_text - ldx #<(darmtower_txt+40) - ldy #>(darmtower_txt+40) - jsr upload_text_bottom - - lda #50*5 - sta frame_delay - jsr wait_loop - - jsr clear_text - - lda #$0d - jsr wait_frame_until - - ldx #adol_win - jsr upload_text - ldx #<(adol_win+40) - ldy #>(adol_win+40) - jsr upload_text_bottom - - lda #50*5 - sta frame_delay - jsr wait_loop - - jsr clear_text - ldx #too_bad_txt - jsr upload_text - - lda #50*5 - sta frame_delay - jsr wait_loop - - jsr clear_text - - lda #$13 - jsr wait_frame_until - - lda #0 - jsr sfx_init - - lda #$1a - jsr wait_frame_until - - lda #120 - sta frame_delay - jmp wait_loop - -wait_frame: -@loop: - bit $d011 - bpl @loop -@loop2: - bit $d011 - bmi @loop2 - rts - -init_2x: lda #127 sta $dc0d @@ -697,9 +19,9 @@ init_2x: lda $dc0d lda $dd0d - lda #irq_music + lda #>irq sta $ffff lda #$0b @@ -707,29 +29,13 @@ init_2x: lda #$00 sta $d012 -position_2x_to_display: - lda #50 -position_2x: -: - bit $d011 - bpl :- -: - bit $d011 - bmi :- -: - cmp $d012 - bne :- - lda #0 sta $d01a - sta $dc0e lda #$63; <(985248/100) sta $dc04 - lda #$26; >(985248/100) + lda #$26;>(985248/100) sta $dc05 - lda #$11 - sta $dc0e lda $dc0d and #$81 @@ -741,43 +47,10 @@ position_2x: lda #$81 sta $dc0d -@loop: - bit $d011 - bpl @loop -@loop2: - bit $d011 - bmi @loop2 - cli - rts - -init_timer: lda #0 - sta timer_reached - sta timer_mode - sta timer - sta timer+1 - stx timer_limit - sty timer_limit+1 - rts - -fade_cols: - .byte 0, 0 - .byte $0, $0, $0, $0, $b, $c, $f, $1 - .res 32-10, $1 - -fake_kernal_irq: - pha - txa - pha - tya - pha - tsx - lda $0104, x - and #$10 - beq :+ - jmp ($0314) -: - jmp ($0314) ; fuck you + jsr $1000 + cli + jmp * irq_music: pha @@ -786,1163 +59,18 @@ irq_music: tya pha - lda $dd00 - and #3 - sta @dd00_arc+1 - and #3 - sta $dd00 - - inc vbl - - ;inc $d020 - lda enable_music - beq :+ - jsr $a003 -: - ;dec $d020 - - lda timer_mode - cmp #1 - bne :+ - lda timer+1 - bne :+ - lda timer - lsr - lsr - lsr - tax - lda fade_cols, x - sta $d021 -: - lda timer_mode - cmp #2 - bne :+ - lda timer+1 - bne :+ - lda timer - lsr - lsr - lsr - eor #31 - tax - lda fade_cols, x - sta $d021 -: - - inc timer - bne :+ - inc timer+1 -: - lda timer - sec - sbc timer_limit - lda timer+1 - sbc timer_limit+1 - bcc :+ - lda #1 - sta timer_reached -: - lda timer_mode - cmp #3 - bne @timer_done - lda vbl - lsr a - bcs @timer_done - lsr a - and #7 - ora #$38 - sta $d011 - -@timer_done: - -@dd00_arc: - lda #0 - sta $dd00 + inc $d020 + jsr $1003 + dec $d020 pla tay pla tax pla + ;rti jmp $dc0c + -wait_loop: -@loop2: - lda vbl - beq @loop2 - - lda #0 - sta vbl - - lda enable_music - bne :+ - jsr sfx_play -: - - dec frame_delay - lda frame_delay - beq :+ - jmp @loop2 -: - rts - -wait_frame_until: - sta frame_until -@loop: - lda vbl - beq @loop - - lda #0 - sta vbl - - lda enable_music - bne :+ - lda cur_frame - cmp #2 - bcc :++ - jsr sfx_play - jmp :++ -: jsr update_dialog -: - - dec bmp_delay - bpl :+ - jsr update_bmp -: - - lda cur_frame - cmp frame_until - beq :+ - - jmp @loop -: - rts - -wait_frame_until_2x: - sta frame_until -@loop: - lda vbl - cmp #2 - bcc @loop - - lda #0 - sta vbl - - dec bmp_delay - bpl :+ - jsr update_bmp -: - - lda cur_frame - cmp frame_until - beq :+ - jmp @loop -: - rts - -init_bmp: - lda #$0b - sta $d011 - lda #$19 - sta $d018 - lda #$d8 - sta $d016 - - lda $4710 - lsr - lsr - lsr - lsr - sta $d020 - - lda $4710 - and #$0f - sta $d021 - - lda #0 - sta cur_frame - sta bmp_delay - - lda #$11 - sta bmp_addr - lda #$47 - sta bmp_addr+1 - - ldx #0 -: - .repeat 4, I - lda $3f40+(I*250), x - sta $400+(I*250), x - lda $4328+(I*250), x - sta $d800+(I*250), x - .endrepeat - inx - cpx #250 - bne :- - - lda #$3b - sta $d011 - rts - -inc_bmp_addr: - inc bmp_addr - bne :+ - inc bmp_addr+1 -: - rts - -update_bmp: - ldy #0 - sty scr_ptr - sty cram_ptr - lda (bmp_addr), y - jsr inc_bmp_addr - sta chr_count - cmp #0 ; tfw flags update in inc_bmp_addr - bne @skip_frame_end - lda (bmp_addr), y - jsr inc_bmp_addr - sta bmp_delay - inc cur_frame - rts -@skip_frame_end: - - lda (bmp_addr), y - sta bmp_ptr - iny - lda (bmp_addr), y - clc - adc #$20 - sta bmp_ptr+1 - - iny - lda (bmp_addr), y - sta scr_ptr_lo - iny - lda (bmp_addr), y - clc - adc #$04 - sta scr_ptr+1 - clc - adc #$d8-$04 - sta cram_ptr+1 - - ldy #0 - lda bmp_addr - clc - adc #4 - sta bmp_addr - bcc :+ - inc bmp_addr+1 -: - - ldx #0 -@loop: - ldy #0 - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - iny - lda (bmp_addr), y - sta (bmp_ptr), y - - lda bmp_ptr - clc - adc #8 - sta bmp_ptr - bcc :+ - inc bmp_ptr+1 -: - - ldy #8 - lda (bmp_addr), y - ldy scr_ptr_lo - sta (scr_ptr), y - - ldy #9 - lda (bmp_addr), y - ldy scr_ptr_lo - sta (cram_ptr), y - - inc scr_ptr_lo - bne :+ - inc scr_ptr+1 - inc cram_ptr+1 -: - - lda bmp_addr - clc - adc #10 - sta bmp_addr - bcc :+ - inc bmp_addr+1 -: - - dec chr_count - ldx chr_count - bne @loop - jmp update_bmp - -irq_badguy: - pha - - pha - pla - pha - pla - pha - pla - lda #$1b - sta $d011 - lda #$c8 - sta $d016 - lda #$13 - sta $d018 - lda #1 - sta $d021 - - lda #irq_badguy2 - sta $ffff - lda #$fb - sta $d012 - - asl $d019 - pla - rti - -irq_badguy2: - pha - - inc vbl - lda #$3b - sta $d011 - lda #$d8 - sta $d016 - lda #$19 - sta $d018 - lda #0 - sta $d021 - - lda #irq_badguy - sta $ffff - lda #$d2 - sta $d012 - - lda enable_music - beq :+ - txa - pha - tya - pha - jsr $a003 - pla - tay - pla - tax -: - asl $d019 - pla - rti - -set_irq_badguy: - lda #127 - sta $dc0d - - and $d011 - sta $d011 - - lda $dc0d - lda $dd0d - - lda #irq_badguy - sta $ffff - - lda #$d2 - sta $d012 - lda #1 - sta $d01a - asl $d019 - rts - -badguy: .byte "badguy",0 -fontname: .byte "font",0 -song0name: .byte "song0", 0 -song1name: .byte "song1", 0 -introname: .byte "intrbmp", 0 -towername: .byte "tower", 0 -towerbeamname: .byte "towerbm", 0 -fieldname: .byte "field", 0 -fallingstarname: .byte "fallstar", 0 -lilianame: .byte "lilia", 0 -liliaheroname: .byte "lilhero", 0 -islandname: .byte "island", 0 -islandmapname: .byte "islandmap", 0 -cloudsname: .byte "clouds", 0 -liliatalkname: .byte "liltalk", 0 - - -darmtower_txt: - .byte " darm's tower has fallen silent. " - .byte " what should we do? " - -adol_win: - .byte " ", 34, "it must be adol, let's see " - .byte " how far he'll get!", 34, " " - -too_bad_txt: - .byte " as you command. " - -upload_text: - stx text_ptr - sty text_ptr+1 - - ldy #39 -: - lda (text_ptr), y - clc - adc #$60 - sta $748, y - dey - bpl :- - rts - -upload_text_bottom: - stx text_ptr - sty text_ptr+1 - - ldy #39 -: - lda (text_ptr), y - clc - adc #$60 - sta $748+40+40, y - dey - bpl :- - rts - -clear_text: - lda #$80 - ldy #39 -: - sta $748, y - sta $748+40+40, y - dey - bpl :- - rts - -run_nufli_bmp: - lda #$01 - sta $81 - lda #$29 - sta $80 - lda #0 - sta $d01a - asl $d019 - jsr $a000 - jsr $3000 -@loop: - bit $d011 - bpl @loop - jsr $a003 -@loop2: - bit $d011 - bmi @loop2 - lda #0 - sta $d020 - sta $d021 - jsr $a003 - lda $80 - bne :+ - dec $81 -: - dec $80 - lda $81 - cmp #$ff - beq :+ - jmp @loop -: - lda #0 - sta $d015 - rts - - -.res $ea31-*, $ff - ;asl $d019 - pla - tay - pla - tax - pla - rti - -.res $ea81-*, $ff - ;asl $d019 - pla - tay - pla - tax - pla - rti - -.include "sfx.asm" -.include "thcmod_lz.asm" - -zx02_8000: - pha - jmp :+ - -load_8000_zx02_2000: - lda #$20 -load_8000_zx02: - pha - jsr loadraw -: - lda #0 - sta ZX0_src - sta ZX0_dst - lda #$80 - sta ZX0_src+1 - pla - jmp zx02 - -load_font: - bcc :+ - pha -: - ldx #fontname - jsr loadraw - bcs :- - rts - -part_10: - ; the sprite data is embedded into first few bitmap pixels - ; which are hidden by black border attributes -@y = 93 - jsr clr_txt - ldx #total_direct - jsr write_txt2 - ldx #$c0 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #cloudsname - jsr load_8000_zx02_2000 -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - lda #$40 - jsr txt_fade_out_offset - - jsr init_bmp - ldx #0 - stx $d010 - stx $d017 - stx $d01d - stx $d025 - stx frame - dex - stx $d01b - stx $d01c - lda #11 - sta $d026 - lda #@y+48 - jsr position_2x - lda #0 - sta vbl - ; draw top half -@loop: - bit $d011 - bpl @loop - ldx #0 - ldy #0 - lda frame - bpl :+ - jmp @finish -: - cmp #$74 - bcc :+ - lda #$74 -: - pha -: - clc - adc @sprxs,x - sta $d000,y - sta temp - lda @sprys,x - sta $d001,y - txa - ora #$80 - sta $7f8,x - lda @sprcols,x - sta $d027,x - lda temp - iny - iny - inx - cpx #8 - bcc :- - lda #$ff - sta $d015 - - ; draw bottom half -: - bit $d011 - bmi :- - lda #@y+37 -: - cmp $d012 - bcs :- - - ldx #0 - ldy #0 - pla - clc -: - adc @sprxs+8,x - sta $d000,y - sta temp - lda @sprys+8,x - sta $d001,y - txa - ora #$88 - sta $7f8,x - lda @sprcols+8,x - sta $d027,x - lda temp - iny - iny - inx - cpx #6 - bcc :- - - lda vbl - and #15 - bne :+ - inc frame -: - jmp @loop - -@sprxs: - .byte 48, <-24, 24, 24, <-64, 24, 24, 24 - .byte 48-40, 24, 24, 24, <-44, 24 - -@sprys: - .byte @y-8, @y, @y, @y, @y+21, @y+21, @y+21, @y+21 - .byte @y+42, @y+42, @y+42, @y+42, @y+63, @y+63 - -@sprcols: - .byte 2, 5, 5, 5, 14, 14, 14, 6 - .byte 2, 2, 2, 9, 2, 2 - -@finish: - lda #$0b - sta $d011 - lda #0 - sta $d015 - - jsr clr_txt - ldx #produced - jsr write_txt2 - ldx #$c0 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode -: - lda timer_reached - beq :- - - ldx #$48 - ldy #$01 - lda #8*11 - jsr txt_fade_out_offset - -part_11: - jsr clr_txt - ldx #presented - jsr write_txt1 - ldx #$c0 - ldy #$01 - jsr init_timer - lda #1 - sta timer_mode - - ldx #liliatalkname - jsr load_8000_zx02_2000 -: - lda timer_reached - beq :- - - ; tell the music to end and wait -;: - ; lda #1 -; jsr $a006 -; cmp #17 -; bne :- - - ldx #$00 - ldy #$01 - lda #8*11 - jsr txt_fade_out_offset -: - lda timer_reached - beq :- - - ; load new music - sei - ldx #song1name - lda #$a0 - jsr load_8000_zx02 - jsr $a000 - jsr init_bmp - ldx #0 - lda #$80 -: - sta $400+(40*(25-5)), x - inx - cpx #40*5 - bne :- - - jsr set_irq_badguy - inc enable_music - lda #0 - sta dialog_tick - lda #dialog - sta text_ptr+1 - cli - - lda #<256 - jsr wait_frame_until - lda #404-256 - jsr wait_frame_until - - sei - lda #$0b - sta $d011 - ldx #64 -: - jsr wait_frame - dex - bpl :- - jsr clr_txt - ldx #turn_disk - jsr write_txt2 - lda #1 - sta $d021 - jmp check_return - -clear_2bufs: - ldy #$44 - .byte $2c ; skip next instruction -clear_buf: - ldy #$20 - lda #$20 - sta @dst+2 - lda #0 - tax -: - sta $400,x - sta $500,x - sta $600,x - sta $700,x - inx - bne :- -@dst: - sta $2000,x - inx - bne @dst - inc @dst+2 - dey - bne @dst - rts - -copybuf: - lda @bsrclo,x - sta bmp_addr - lda @bsrchi,x - sta bmp_addr+1 - lda @bdstlo,x - sta bmp_ptr - lda @bdsthi,x - sta bmp_ptr+1 - lda @tsrclo,x - sta text_ptr - lda @tsrchi,x - sta text_ptr+1 - lda @tdstlo,x - sta scr_ptr - lda @tdsthi,x - sta scr_ptr+1 - ldx #16 -@loop: - ldy #23 -: lda (text_ptr),y - sta (scr_ptr),y - dey - bpl :- - ldy #191 -: lda (bmp_addr),y - sta (bmp_ptr),y - dey - bne :- - lda (bmp_addr),y - sta (bmp_ptr),y - ; math dumb cpu be struggling a lot here - lda text_ptr - sec - sbc #40 - sta text_ptr - bcs :+ - dec text_ptr+1 -: - lda scr_ptr - sec - sbc #40 - sta scr_ptr - bcs :+ - dec scr_ptr+1 -: - lda bmp_addr - sec - sbc #<320 - sta bmp_addr - bcs :+ - dec bmp_addr+1 -: - dec bmp_addr+1 - lda bmp_ptr - sec - sbc #<320 - sta bmp_ptr - bcs :+ - dec bmp_ptr+1 -: - dec bmp_ptr+1 - dex - bne @loop - rts - -@bsrclo: .lobytes (15+4)*320+$2040, (15+4)*320+$4040 -@bsrchi: .hibytes (15+4)*320+$2040, (15+4)*320+$4040 -@bdstlo: .lobytes (16+4)*320+$4040, (16+4)*320+$2040 -@bdsthi: .hibytes (16+4)*320+$4040, (16+4)*320+$2040 -@tsrclo: .lobytes (15+4)*40+$0408, (15+4)*40+$6008 -@tsrchi: .hibytes (15+4)*40+$0408, (15+4)*40+$6008 -@tdstlo: .lobytes (16+4)*40+$6008, (16+4)*40+$0408 -@tdsthi: .hibytes (16+4)*40+$6008, (16+4)*40+$0408 - -copyright: -.byte " ys ^ " -.byte " copyright 1988 falcom " -.byte " all right reserved " - -story_writ: -.byte " story written by " -.byte " takahiro ohura " -.byte " tomoo yamane " - -scenario_writ: -.byte " scenario written by " -.byte " tomoyoshi miyazaki " - -prog_writ: -.byte " programmed by " -.byte " masaya hashimoto " - -gart_writ: -.byte " graphic arts designed by " -.byte " takahiro ohura " -.byte " ayano koshiro " -.byte " kazuhiko tsuzuki " -.byte " tomoo yamane " - -music_writ: -.byte " music composed by " -.byte " mieko ishikawa " -.byte " yuzo koshiro " -.byte " hideya nagata " - -scene_writ: -.byte " scene set by " -.byte " seigo oketani " -.byte " yoshihiko kurata " - -art_direct: -.byte " art directed by " -.byte " seigo oketani " - -total_direct: -.byte " total directed by " -.byte " masaya hashimoto " - -produced: -.byte " produced by " -.byte " masayuki katoh " - -presented: -.byte " presented by falcom " - -turn_disk: -.byte " insert datadisk in " -.byte " drive 8 then return " - -clr_txt: - lda #$80 - ldx #0 -: - .repeat 4, I - sta $400+(I*250), x - .endrepeat - inx - cpx #250 - bne :- - lda #0 - ldx #0 -: - .repeat 4, I - sta $d800+(I*250), x - .endrepeat - inx - cpx #250 - bne :- - lda #$13 - sta $d018 - lda #$1b - sta $d011 - rts - -write_txt5: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+8*40) - ldx #>($400+8*40) - jsr write_txt_to - lda #<($400+10*40) - ldx #>($400+10*40) - jsr write_txt_to - lda #<($400+12*40) - ldx #>($400+12*40) - jsr write_txt_to - lda #<($400+14*40) - ldx #>($400+14*40) - jsr write_txt_to - lda #<($400+16*40) - ldx #>($400+16*40) - jmp write_txt_to - -write_txt4: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+9*40) - ldx #>($400+9*40) - jsr write_txt_to - lda #<($400+11*40) - ldx #>($400+11*40) - jsr write_txt_to - lda #<($400+13*40) - ldx #>($400+13*40) - jsr write_txt_to - lda #<($400+15*40) - ldx #>($400+15*40) - jmp write_txt_to - -write_txt3: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+10*40) - ldx #>($400+10*40) - jsr write_txt_to - lda #<($400+12*40) - ldx #>($400+12*40) - jsr write_txt_to - lda #<($400+14*40) - ldx #>($400+14*40) - jmp write_txt_to - -write_txt2: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+11*40) - ldx #>($400+11*40) - jsr write_txt_to - lda #<($400+13*40) - ldx #>($400+13*40) - jmp write_txt_to - -write_txt1: - stx text_ptr - sty text_ptr+1 - ldy #0 - lda #<($400+12*40) - ldx #>($400+12*40) - ; fall through - -write_txt_to: - sta @dst+1 - stx @dst+2 - ldx #0 -: - lda (text_ptr), y - sec - sbc #$20 - ora #$80 -@dst: - sta $400, x - iny - inx - cpx #40 - bne :- - rts - -txt_fade_out: - lda #0 -txt_fade_out_offset: - pha - jsr init_timer - pla - sta timer - lda #2 - sta timer_mode -: - lda timer_reached - beq :- - rts - -update_dialog: - dec dialog_tick - bmi @skip_tick - rts -@skip_tick: - - ldy #0 - lda (text_ptr),y - cmp #$ff - bne :+ - rts -: - cmp #$fe - bne @skip_reset_col - ldx dialog_col - cpx #40*2 - beq @skip_reset - - ldy #1 - lda (text_ptr), y - sta dialog_col - ldx #0 - lda #$20+$60 -: - sta $748, x - inx - cpx #40*3 - bcc :- - jmp @skip_reset2 -@skip_reset: - ldy #1 - lda (text_ptr), y - clc - adc #40*2 - sta dialog_col -@skip_reset2: - - lda text_ptr - clc - adc #2 - sta text_ptr - bcc :+ - inc text_ptr+1 -: - jmp @skip_tick -@skip_reset_col: - sta dialog_tick - ldy #1 - lda (text_ptr), y - sta temp+2 - lda text_ptr - clc - adc #2 - sta text_ptr - bcc :+ - inc text_ptr+1 -: - - lda temp+2 - beq @skip_text_upload - - ldy #0 -: - lda (text_ptr), y - jsr write_char_dialog - iny - cpy temp+2 - bne :- -@skip_text_upload: - - lda text_ptr - clc - adc temp+2 - sta text_ptr - bcc :+ - inc text_ptr+1 -: - - rts - -write_char_dialog: - cmp #$0a ; newline - bne :+ - lda #40*2 - sta dialog_col - rts -: - ldx dialog_col - clc - adc #$60 - sta $748, x - inc dialog_col - rts - -dialog: .incbin "liltalk.bin" +.res $1000-* +.incbin "ys2_sid.sid", $7e+($1000-$ff6) \ No newline at end of file diff --git a/loader/samples/minexample/minexample.s b/loader/samples/minexample/minexample.s index 3fe7e6b..f52b617 100644 --- a/loader/samples/minexample/minexample.s +++ b/loader/samples/minexample/minexample.s @@ -1,6 +1,30 @@ .feature c_comments .include "../../build/loadersymbols-c64.inc" +.ZEROPAGE +.org $10 +bmp_delay: .res 1 +bmp_addr: .res 2 +bmp_ptr: .res 2 +scr_ptr_lo: .res 1 +scr_ptr: .res 2 +cram_ptr: .res 2 +chr_count: .res 1 +vbl: .res 1 +frame: .res 1 +cur_frame: .res 1 +frame_delay: .res 1 +frame_until: .res 1 +text_ptr: .res 2 +timer: .res 2 +timer_limit: .res 2 +timer_reached: .res 2 +timer_mode: .res 1 +temp: .res 3 + +aart_lz_buffer := $fd00 +.include "lz_zp.asm" + CODE_START_ADDR = $e000 .segment "CODE" @@ -14,60 +38,1406 @@ pntr = ZP+7 .org $080d - jsr print_info copy_start: sei lda #$35 sta $01 - lda #code - sta ZX0_src+1 lda #CODE_START_ADDR - jsr zx02 + sta $fd - inc $01 + lda #code_start + sta $fb + + ldy #0 + ldx #>(code_end-CODE_START_ADDR) + beq :+++ +: + lda ($fa), y + sta ($fc), y + iny + bne :- + inc $fb + inc $fd + dex + bne :- + beq :+ +: + lda ($fa), y + sta ($fc), y + iny +: + cpy #<(code_end-CODE_START_ADDR) + bne :-- + + lda #$36 + sta $01 cli jsr install sei - dec $01 - jmp CODE_START_ADDR - -.include "zx02.asm" - -check_return: - ; for some reason GETIN enable interrupts back - lda #0 - sta $d01a - asl $d019 - lda #$36 + lda #$35 sta $01 -: - jsr $ff9f ; SCNKEY - jsr $ffe4 ; GETIN - cmp #$0d - bne :- - dec $01 jmp CODE_START_ADDR - .assert zx02 = $0832, error, .sprintf("change zx02 address to $%04x", zx02) - .assert check_return = $08b8, error, .sprintf("change check_return address to $%04x", check_return) - .res loadraw - * .incbin "../../build/loader-c64.prg", 2 .res install - * .incbin "../../build/install-c64.prg", 2 -code: .incbin "main.zx0" +code_start: + .org CODE_START_ADDR + + sei + + ldx #fontname + jsr loadraw + + lda #$34 + sta $01 -print_info: - lda #$20 ldx #0 +: + lda $8000, x + sta $d800, x + eor #$ff + sta $c00, x + lda $8100, x + sta $d900, x + eor #$ff + sta $d00, x + inx + bne :- + + lda #0 + tax +: + .repeat 4, I + sta $d000+(I*250), x + .endrepeat + inx + cpx #250 + bne :- + + lda #$35 + sta $01 + + lda #0 + sta ZX0_dst+0 + + ldx #badguy + jsr load_8000_zx02_2000 + + lda #127 + sta $dc0d + + and $d011 + sta $d011 + + lda $dc0d + lda $dd0d + + lda #irq_badguy + sta $ffff + + lda #$1b + sta $d011 + lda #$d0 + sta $d012 + + lda #1 + sta $d01a + sta bmp_delay + jsr init_bmp + + lda #0 + sta vbl + + cli + + lda #64 + sta frame_delay + jsr wait_loop + + jsr intro + + lda #$0b + sta $d011 + + sei + ldx #introname + lda #$10 + jsr load_8000_zx02 + + ldx #sidname + jsr loadraw + + ldx #towername + jsr loadraw + + lda #fake_kernal_irq + sta $ffff + + lda #1 + sta $d01a + + jsr run_nufli_bmp + sei + jsr init_2x + lda #$0b + sta $d011 + + jsr clr_txt + ldx #story_writ + jsr write_txt3 + ldx #$30 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + lda #$20 + jsr zx02_8000 + +: + lda timer_reached + beq :- + + ldx #$b8 + ldy #$01 + jsr init_timer + lda #2 + sta timer_mode +: + lda timer_reached + beq :- + + jsr init_bmp + + lda #0 + sta vbl + + lda #$11 + sta frame_until + jsr wait_frame_until_2x + + ldx #$6c +: + jsr wait_frame + jsr wait_frame + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #scenario_writ + jsr write_txt2 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #towerbeamname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$90 + ldy #$01 + jsr init_timer + lda #2 + sta timer_mode +: + lda timer_reached + beq :- + + jsr init_bmp + + lda #0 + sta vbl + + lda #$0d + sta frame_until + jsr wait_frame_until_2x + lda bmp_addr + sta temp + lda bmp_addr+1 + sta temp+1 + lda cur_frame + sta temp+2 + + ldx #17 +: + txa + pha + lda temp+2 + sta cur_frame + lda temp + sta bmp_addr + lda temp+1 + sta bmp_addr+1 + lda #$0d+3 + sta frame_until + jsr wait_frame_until_2x + pla + tax + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #prog_writ + jsr write_txt2 + ldx #$a8 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #fieldname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + jsr init_timer + lda #2 + sta timer_mode + +: + lda timer_reached + beq :- + + jsr init_bmp + + lda #0 + sta vbl + + lda #$08 + sta frame_until + jsr wait_frame_until_2x + lda bmp_addr + sta temp + lda bmp_addr+1 + sta temp+1 + lda cur_frame + sta temp+2 + + ldx #2 +: + txa + pha + lda temp+2 + sta cur_frame + lda temp + sta bmp_addr + lda temp+1 + sta bmp_addr+1 + lda #$08+8 + sta frame_until + jsr wait_frame_until_2x + pla + tax + dex + bpl :- + + + lda #0 + sta vbl + lda #$27 + sta frame_until + jsr wait_frame_until_2x + + ldx #25 +: + jsr wait_frame + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #gart_writ + jsr write_txt5 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #fallingstarname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$48 + ldy #$01 + jsr init_timer + lda #2 + sta timer_mode + +: + lda timer_reached + beq :- + + jsr init_bmp + + lda #$1d + sta frame_until + jsr wait_frame_until_2x + + ldx #5 +: + jsr wait_frame + dex + bpl :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #music_writ + jsr write_txt4 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #lilianame + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$10 + ldy #$01 + jsr init_timer + lda #8*11 + sta timer + lda #2 + sta timer_mode + +: + lda timer_reached + beq :- + + ldx #$c4 + ldy #$01 + jsr init_timer + + jsr init_bmp + + lda #$08 + sta frame_until + jsr wait_frame_until_2x + +: + lda timer_reached + beq :- + + lda #$0b + sta $d011 + + jsr clr_txt + ldx #scene_writ + jsr write_txt3 + ldx #$80 + ldy #$01 + jsr init_timer + lda #1 + sta timer_mode + + ldx #liliaheroname + jsr load_8000_zx02_2000 + +: + lda timer_reached + beq :- + + ldx #$20 + ldy #$01 + jsr init_timer + lda #2 + sta timer_mode + +: + lda timer_reached + beq :- + +part_9: + ; $0400-$07ff buffer 0 tilemap + ; $2000-$3fff buffer 0 bitmap + ; $4000-$5fff buffer 1 bitmap + ; $6000-$63ff buffer 1 tilemap + ; $6400-$6417 next buffer CRAM + ; $7000-$77ff tileset bitmap + ; $7800-$78ff tileset tile colors + ; $7900-$79ff tileset CRAM colors + ; $9000- compressed tilemap + ldx #skyscrname + lda #$70 + jsr load_8000_zx02 + ldx #skyscrmapname + jsr loadraw + ldx #0 + ldy #$90 + jsr LZ_init_decomp + + lda #0 + sta $d011 + jsr clear_2bufs + + ; set up sprites to cover scrolling + lda #$ff + ldx #0 +: sta $2000,x + sta $4000,x + inx + bne :- + .repeat 4, I + ldx #I*48+$58 + stx $d000+I*2 + stx $d008+I*2 + .endrepeat + ldx #6 +: + lda #$42 + sta $d001,x + lda #$d7 + sta $d009,x + dex + dex + bpl :- + ldx #7 +: + lda #$80 + sta $07f8,x + lda #0 + sta $63f8,x + sta $d027,x + dex + bpl :- + stx $d01d + stx $d015 + inx + stx $d010 + stx $d017 + stx $d01b + stx $d01c + stx frame + + lda #$18 + sta $d018 + lda #<((17+4)*40+$408) + sta text_ptr + lda #>((17+4)*40+$408) + sta text_ptr+1 + ldx #16 +: + lda #0 + lda text_ptr + sec + sbc #40 + sta text_ptr + sta scr_ptr + sta cram_ptr + sta bmp_ptr + lda text_ptr+1 + sbc #0 + sta text_ptr+1 + sta scr_ptr+1 + ; carry is always set here + adc #$d8-$04-1 + sta cram_ptr+1 + adc #<(($20>>3)-$d8) + asl bmp_ptr + rol a + asl bmp_ptr + rol a + asl bmp_ptr + rol a + sta bmp_ptr+1 + stx temp+1 + jsr drawrow + ldx temp+1 + dex + bpl :- + lda #0 + sta cram_ptr + lda #$64 + sta cram_ptr+1 +: + lda $d011 + bpl :- + lda #$38 + sta $d011 + lda #$18 + sta $d016 + lda #3 + sta timer_mode +@loop: + lda #0 + sta vbl + lda frame + cmp #$e0 ; TODO + bcc :+ + jmp @finish +: + and #1 + tax + jsr copybuf + jsr drawrow +: + lda vbl + cmp #32 + bcc :- + ; B U M R U S H C R A M C O P Y F U N K + ldy #23 +: .repeat 16, I + lda $d808+(19-I)*40,y + sta $d808+(20-I)*40,y + .endrepeat + lda $6400,y + sta $d808+4*40,y + dey + bpl :- + inc frame + lda frame + lsr a + lda #$18 + ldx #3 + bcc :+ + lda #$80 + ldx #2 +: + sta $d018 + stx $dd00 + jmp @loop + +@finish: + lda #0 + sta timer_mode + ; TODO is there a delay here + +part_10: + jmp * + +drawrow: + ldy #0 +charloop: + sty temp + lda #$70>>3 + sta bmp_addr+1 + jsr LZ_get_byte + tax + asl a + rol bmp_addr+1 + asl a + rol bmp_addr+1 + asl a + rol bmp_addr+1 + sta bmp_addr + ldy #0 + .repeat 8, I + lda (bmp_addr),y + sta (bmp_ptr),y + iny + .endrepeat + clc + lda bmp_ptr + adc #8 + sta bmp_ptr + bne :+ + inc bmp_ptr+1 +: + ldy temp + lda $7800,x + sta (scr_ptr),y + lda $7900,x + sta (cram_ptr),y + iny + cpy #24 + bne charloop + rts + +intro: + lda #0 + jsr sfx_init + + lda #7 + sta frame_until + jsr wait_frame_until + + lda #64 + sta frame_delay + jsr wait_loop + + lda #1 + jsr sfx_init + + ldx #darmtower_txt + jsr upload_text + ldx #<(darmtower_txt+40) + ldy #>(darmtower_txt+40) + jsr upload_text_bottom + + lda #50*5 + sta frame_delay + jsr wait_loop + + ldx #empty_txt + jsr upload_text + ldx #empty_txt + jsr upload_text_bottom + + lda #$0d + sta frame_until + jsr wait_frame_until + + ldx #adol_win + jsr upload_text + ldx #<(adol_win+40) + ldy #>(adol_win+40) + jsr upload_text_bottom + + lda #50*5 + sta frame_delay + jsr wait_loop + + ldx #too_bad_txt + jsr upload_text + ldx #empty_txt + jsr upload_text_bottom + + lda #50*5 + sta frame_delay + jsr wait_loop + + ldx #empty_txt + jsr upload_text + + lda #$13 + sta frame_until + jsr wait_frame_until + + lda #0 + jsr sfx_init + + lda #$1a + sta frame_until + jsr wait_frame_until + + lda #120 + sta frame_delay + jsr wait_loop + rts + +wait_frame: +@loop: + bit $d011 + bpl @loop +@loop2: + bit $d011 + bmi @loop2 + rts + +init_2x: + lda #127 + sta $dc0d + + and $d011 + sta $d011 + + lda $dc0d + lda $dd0d + + lda #irq_music + sta $ffff + + lda #$0b + sta $d011 + lda #$00 + sta $d012 + +: + bit $d011 + bpl :- +: + bit $d011 + bmi :- + lda #51 +: + cmp $d012 + bne :- + + lda #0 + sta $d01a + sta $dc0e + + lda #$63; <(985248/100) + sta $dc04 + lda #$26; >(985248/100) + sta $dc05 + lda #$11 + sta $dc0e + + lda $dc0d + and #$81 + sta $dc0d + + lda #$40 + sta $dc0c + + lda #$81 + sta $dc0d + +@loop: + bit $d011 + bpl @loop +@loop2: + bit $d011 + bmi @loop2 + cli + rts + +init_timer: + lda #0 + sta timer_reached + sta timer_mode + sta timer + sta timer+1 + stx timer_limit + sty timer_limit+1 + rts + +fade_cols: + .byte 0, 0 + .byte $0, $0, $0, $0, $b, $c, $f, $1 + .res 32-10, $1 + +irq_music: + pha + txa + pha + tya + pha + + lda $dd00 + and #3 + sta @dd00_arc+1 + and #3 + sta $dd00 + + inc vbl + + ;inc $d020 + jsr $a003 + ;dec $d020 + + lda timer_mode + cmp #1 + bne :+ + lda timer+1 + bne :+ + lda timer + lsr + lsr + lsr + tax + lda fade_cols, x + sta $d021 +: + lda timer_mode + cmp #2 + bne :+ + lda timer+1 + bne :+ + lda timer + lsr + lsr + lsr + eor #31 + tax + lda fade_cols, x + sta $d021 +: + + inc timer + bne :+ + inc timer+1 +: + lda timer + cmp timer_limit + bne :+ + lda timer+1 + cmp timer_limit+1 + bne :+ + lda #1 + sta timer_reached +: + lda timer_mode + cmp #3 + bne @timer_done + lda vbl + lsr a + bcs @timer_done + lsr a + and #7 + ora #$38 + sta $d011 + +@timer_done: + +@dd00_arc: + lda #0 + sta $dd00 + + pla + tay + pla + tax + pla + jmp $dc0c + + +fake_kernal_irq: + pha + txa + pha + tya + pha + tsx + lda $0104, x + and #$10 + beq :+ + jmp ($0314) +: + jmp ($0314) ; fuck you + +wait_loop: +@loop2: + lda vbl + beq @loop2 + + lda #0 + sta vbl + + jsr sfx_play + + dec frame_delay + lda frame_delay + beq :+ + jmp @loop2 +: + rts + +wait_frame_until: +@loop: + lda vbl + beq @loop + + lda #0 + sta vbl + + lda cur_frame + cmp #2 + bcc :+ + jsr sfx_play +: + + dec bmp_delay + bpl :+ + jsr update_bmp +: + + lda cur_frame + cmp frame_until + beq :+ + + jmp @loop +: + rts + + +wait_loop_2x: +@loop: + lda vbl + cmp #2 + bcc @loop + + lda #0 + sta vbl + + dec frame_delay + lda frame_delay + beq :+ + jmp @loop +: + rts + +wait_frame_until_2x: +@loop: + lda vbl + cmp #2 + bcc @loop + + lda #0 + sta vbl + + dec bmp_delay + bpl :+ + jsr update_bmp +: + + lda cur_frame + cmp frame_until + beq :+ + jmp @loop +: + rts + + +init_bmp: + lda #$0b + sta $d011 + lda #$19 + sta $d018 + lda #$d8 + sta $d016 + + lda $4710 + lsr + lsr + lsr + lsr + sta $d020 + + lda $4710 + and #$0f + sta $d021 + + lda #0 + sta cur_frame + sta bmp_delay + + lda #$11 + sta bmp_addr + lda #$47 + sta bmp_addr+1 + + ldx #0 +: + .repeat 4, I + lda $3f40+(I*250), x + sta $400+(I*250), x + lda $4328+(I*250), x + sta $d800+(I*250), x + .endrepeat + inx + cpx #250 + bne :- + + lda #$3b + sta $d011 + rts + +inc_bmp_addr: + inc bmp_addr + bne :+ + inc bmp_addr+1 +: + rts + +update_bmp: + ldy #0 + sty scr_ptr + sty cram_ptr + lda (bmp_addr), y + jsr inc_bmp_addr + sta chr_count + cmp #0 ; tfw flags update in inc_bmp_addr + bne @skip_frame_end + lda (bmp_addr), y + jsr inc_bmp_addr + sta bmp_delay + inc cur_frame + rts +@skip_frame_end: + + lda (bmp_addr), y + sta bmp_ptr + iny + lda (bmp_addr), y + clc + adc #$20 + sta bmp_ptr+1 + + iny + lda (bmp_addr), y + sta scr_ptr_lo + iny + lda (bmp_addr), y + clc + adc #$04 + sta scr_ptr+1 + clc + adc #$d8-$04 + sta cram_ptr+1 + + ldy #0 + lda bmp_addr + clc + adc #4 + sta bmp_addr + bcc :+ + inc bmp_addr+1 +: + + ldx #0 +@loop: + ldy #0 + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + iny + lda (bmp_addr), y + sta (bmp_ptr), y + + lda bmp_ptr + clc + adc #8 + sta bmp_ptr + bcc :+ + inc bmp_ptr+1 +: + + ldy #8 + lda (bmp_addr), y + ldy scr_ptr_lo + sta (scr_ptr), y + + ldy #9 + lda (bmp_addr), y + ldy scr_ptr_lo + sta (cram_ptr), y + + inc scr_ptr_lo + bne :+ + inc scr_ptr+1 + inc cram_ptr+1 +: + + lda bmp_addr + clc + adc #10 + sta bmp_addr + bcc :+ + inc bmp_addr+1 +: + + dec chr_count + ldx chr_count + bne @loop + jmp update_bmp + +irq_badguy: + pha + txa + pha + tya + pha + + inc vbl + ;inc $d020 + + lda #$1b + sta $d011 + lda #$19 + sta $d018 + lda #$c8 + sta $d016 + lda $dd00 + and #3 + sta @dd00_arc+1 + lda #0 + sta $dd00 + lda #$47 + sta $d018 + +: + lda $d012 + cmp #$fb + bcc :- + + .res 2, $ea + + lda #$3b + sta $d011 + lda #$19 + sta $d018 + lda #$d8 + sta $d016 +@dd00_arc: + lda #0 + sta $dd00 + + ;dec $d020 + + asl $d019 + pla + tay + pla + tax + pla + rti + +badguy: .byte "badguy",0 +fontname: .byte "font",0 +sidname: .byte "sid", 0 +introname: .byte "intrbmp", 0 +towername: .byte "tower", 0 +towerbeamname: .byte "towerbm", 0 +fieldname: .byte "field", 0 +fallingstarname: .byte "fallstar", 0 +lilianame: .byte "lilia", 0 +liliaheroname: .byte "lilhero", 0 +skyscrname: .byte "skyscr", 0 +skyscrmapname: .byte "skyscrmap", 0 + + +darmtower_txt: + .res (40-32)/2, ' ' + .byte "darm's tower has fallen silent. " + .res (40-32)/2, ' ' + .res (40-32)/2, ' ' + .byte "what should we do? " + .res (40-32)/2, ' ' + +empty_txt: + .res 40, ' ' + .res 40, ' ' + +adol_win: + .res (40-28)/2, ' ' + .byte 34, "it must be adol, let's see " + .res (40-28)/2, ' ' + .res (40-28)/2, ' ' + .byte "how far he'll get!", 34, " " + .res (40-28)/2, ' ' + +too_bad_txt: + .res (40-16)/2, ' ' + .byte "as you command. " + .res (40-16)/2, ' ' + +upload_text: + lda #$34 + sta $01 + + stx text_ptr + sty text_ptr+1 + + ldy #39 +: + lda (text_ptr), y + sec + sbc #$20 + sta $d348, y + dey + bne :- + + lda #$35 + sta $01 + + lda #1 + ldy #39 +: + sta $db48, y + dey + bne :- + rts + +upload_text_bottom: + lda #$34 + sta $01 + + stx text_ptr + sty text_ptr+1 + + ldy #39 +: + lda (text_ptr), y + sec + sbc #$20 + sta $d348+40+40, y + dey + bne :- + + lda #$35 + sta $01 + + lda #1 + ldy #39 +: + sta $db48+40+40, y + dey + bne :- + rts + + +run_nufli_bmp: + lda #$01 + sta $81 + lda #$29 + sta $80 + lda #0 + sta $d01a + jsr $a000 + cli + jsr $3000 +@loop: + bit $d011 + bpl @loop + jsr $a003 +@loop2: + bit $d011 + bmi @loop2 + lda #0 + sta $d020 + sta $d021 + jsr $a003 + lda $80 + bne :+ + dec $81 +: + dec $80 + lda $81 + cmp #$ff + beq :+ + jmp @loop +: + lda #0 + sta $d015 + rts + + +.res $ea31-*, $ff + ;asl $d019 + pla + tay + pla + tax + pla + rti + +.res $ea81-*, $ff + ;asl $d019 + pla + tay + pla + tax + pla + rti + +.include "sfx.asm" +.include "zx02.asm" +.include "thcmod_lz.asm" + +zx02_8000: + pha + jmp :+ + +load_8000_zx02_2000: + lda #$20 +load_8000_zx02: + pha + jsr loadraw +: + lda #0 + sta ZX0_src + sta ZX0_dst + lda #$80 + sta ZX0_src+1 + pla + jmp zx02 + +clear_2bufs: + ldy #$44 + .byte $2c ; skip next instruction +clear_buf: + ldy #$20 + lda #$20 + sta @dst+2 + lda #0 + tax : sta $400,x sta $500,x @@ -75,61 +1445,377 @@ print_info: sta $700,x inx bne :- - lda #41 - sta ZX0_dst - lda #4 - sta ZX0_dst+1 - lda #$17 - sta $d018 - ldy #0 -@print_loop: - lda info,x - bne :++ - lda ZX0_dst - clc - adc #40 - sta ZX0_dst - bcc :+ - inc ZX0_dst+1 -: - ldy #0 - beq :++ -: - sta (ZX0_dst),y - iny -: +@dst: + sta $2000,x inx - cpx #info_end-info - bne @print_loop + bne @dst + inc @dst+2 + dey + bne @dst rts - .macpack cbm -info: - scrcode "Code:" - .byte 0 - scrcode " Aart1256 - engine, music driver" - .byte 0 - scrcode " Natt - engine, tooling" - .byte 0, 0 - scrcode "C64 Graphics:" - .byte 0 - scrcode " Grongy" - .byte 0 - scrcode " Natt" - .byte 0, 0 - scrcode "Music arranges & ported graphics:" - .byte 0 - scrcode " Aleksa Odzakovic (spaztron64)" - .byte 0, 0 - scrcode "Greetz to:" - .byte 0 - scrcode " Gyabo" - .byte 0 - scrcode " Yosshin" - .byte 0 - scrcode " Hadohado" - .byte 0 - scrcode " Kazpulse" - .byte 0 - scrcode " Gam" -info_end: +copybuf: + lda @bsrclo,x + sta bmp_addr + lda @bsrchi,x + sta bmp_addr+1 + lda @bdstlo,x + sta bmp_ptr + lda @bdsthi,x + sta bmp_ptr+1 + lda @tsrclo,x + sta text_ptr + lda @tsrchi,x + sta text_ptr+1 + lda @tdstlo,x + sta scr_ptr + lda @tdsthi,x + sta scr_ptr+1 + ldx #16 +@loop: + ldy #23 +: lda (text_ptr),y + sta (scr_ptr),y + dey + bpl :- + ldy #191 +: lda (bmp_addr),y + sta (bmp_ptr),y + dey + bne :- + lda (bmp_addr),y + sta (bmp_ptr),y + ; math dumb cpu be struggling a lot here + lda text_ptr + sec + sbc #40 + sta text_ptr + bcs :+ + dec text_ptr+1 +: + lda scr_ptr + sec + sbc #40 + sta scr_ptr + bcs :+ + dec scr_ptr+1 +: + lda bmp_addr + sec + sbc #<320 + sta bmp_addr + bcs :+ + dec bmp_addr+1 +: + dec bmp_addr+1 + lda bmp_ptr + sec + sbc #<320 + sta bmp_ptr + bcs :+ + dec bmp_ptr+1 +: + dec bmp_ptr+1 + dex + bne @loop + rts + +@bsrclo: .lobytes (15+4)*320+$2040, (15+4)*320+$4040 +@bsrchi: .hibytes (15+4)*320+$2040, (15+4)*320+$4040 +@bdstlo: .lobytes (16+4)*320+$4040, (16+4)*320+$2040 +@bdsthi: .hibytes (16+4)*320+$4040, (16+4)*320+$2040 +@tsrclo: .lobytes (15+4)*40+$0408, (15+4)*40+$6008 +@tsrchi: .hibytes (15+4)*40+$0408, (15+4)*40+$6008 +@tdstlo: .lobytes (16+4)*40+$6008, (16+4)*40+$0408 +@tdsthi: .hibytes (16+4)*40+$6008, (16+4)*40+$0408 + +story_writ: +.res 11, ' ' +.byte "story written by" +.res 40-(16+11), ' ' +.res 11, ' ' +.res 5, ' ' +.byte "takahiro ohura" +.res 40-(14+11+5), ' ' +.res 11, ' ' +.res 5, ' ' +.byte "tomoo yamane" +.res 40-(12+11+5), ' ' + +scenario_writ: +.res (40-24)/2, ' ' +.byte " scenario written by " +.res (40-24)/2, ' ' +.res (40-24)/2, ' ' +.byte " tomoyoshi miyazaki" +.res (40-24)/2, ' ' + +prog_writ: +.res (40-22)/2, ' ' +.byte " programmed by " +.res (40-22)/2, ' ' +.res (40-22)/2, ' ' +.byte " masaya hashimoto" +.res (40-22)/2, ' ' + +gart_writ: +.res (40-24)/2, ' ' +.byte "graphic arts designed by" +.res (40-24)/2, ' ' +.res (40-24)/2, ' ' +.byte " takahiro ohura " +.res (40-24)/2, ' ' +.res (40-24)/2, ' ' +.byte " ayano koshiro " +.res (40-24)/2, ' ' +.res (40-24)/2, ' ' +.byte " kazuhiko tsuzuki " +.res (40-24)/2, ' ' +.res (40-24)/2, ' ' +.byte " tomoo yamane " +.res (40-24)/2, ' ' + +music_writ: +.res (40-20)/2, ' ' +.byte " music composed by " +.res (40-20)/2, ' ' +.res (40-20)/2, ' ' +.byte " mieko ishikawa" +.res (40-20)/2, ' ' +.res (40-20)/2, ' ' +.byte " yuzo koshiro " +.res (40-20)/2, ' ' +.res (40-20)/2, ' ' +.byte " hideya nagata " +.res (40-20)/2, ' ' + +scene_writ: +.res (40-22)/2, ' ' +.byte "scene set by " +.res (40-22)/2, ' ' +.res (40-22)/2, ' ' +.byte " seigo oketani " +.res (40-22)/2, ' ' +.res (40-22)/2, ' ' +.byte " yoshihiko kurata" +.res (40-22)/2, ' ' + +clr_txt: + lda #$80 + ldx #0 +: + .repeat 4, I + sta $400+(I*250), x + .endrepeat + inx + cpx #250 + bne :- + lda #0 + ldx #0 +: + .repeat 4, I + sta $d800+(I*250), x + .endrepeat + inx + cpx #250 + bne :- + lda #$13 + sta $d018 + lda #$1b + sta $d011 + rts + +write_txt5: + stx text_ptr + sty text_ptr+1 + + ldx #0 + ldy #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+8*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+10*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+12*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+14*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+16*40, x + iny + inx + cpx #40 + bne :- + rts + +write_txt4: + stx text_ptr + sty text_ptr+1 + + ldx #0 + ldy #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+9*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+11*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+13*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+15*40, x + iny + inx + cpx #40 + bne :- + + rts + +write_txt3: + stx text_ptr + sty text_ptr+1 + + ldx #0 + ldy #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+10*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+12*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+14*40, x + iny + inx + cpx #40 + bne :- + rts + +write_txt2: + stx text_ptr + sty text_ptr+1 + + ldx #0 + ldy #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+11*40, x + iny + inx + cpx #40 + bne :- + + ldx #0 +: + lda (text_ptr), y + sec + sbc #$20 + ora #$80 + sta $400+13*40, x + iny + inx + cpx #40 + bne :- + rts + +code_end: diff --git a/loader/samples/minexample/island.bin b/loader/samples/minexample/sky_scroll.bin similarity index 100% rename from loader/samples/minexample/island.bin rename to loader/samples/minexample/sky_scroll.bin diff --git a/loader/samples/minexample/island_map.bin b/loader/samples/minexample/sky_scroll_map.bin similarity index 100% rename from loader/samples/minexample/island_map.bin rename to loader/samples/minexample/sky_scroll_map.bin diff --git a/loader/samples/minexample/test/bin.cfg b/loader/samples/minexample/test/bin.cfg deleted file mode 100644 index ba97093..0000000 --- a/loader/samples/minexample/test/bin.cfg +++ /dev/null @@ -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; -} diff --git a/loader/samples/minexample/test/main.asm b/loader/samples/minexample/test/main.asm deleted file mode 100644 index f831ad0..0000000 --- a/loader/samples/minexample/test/main.asm +++ /dev/null @@ -1,10 +0,0 @@ -.zeropage - -.segment "CODE" - - .word $0c00 - .incbin "font.bin" - .res 12 - -entry: - jmp * diff --git a/loader/samples/minexample/use_this_sid.bin b/loader/samples/minexample/use_this_sid.bin new file mode 100644 index 0000000..7a9ce8f Binary files /dev/null and b/loader/samples/minexample/use_this_sid.bin differ diff --git a/loader/samples/minexample/ys2_fixed_drums.fur b/loader/samples/minexample/ys2_fixed_drums.fur deleted file mode 100644 index 7b8418b..0000000 Binary files a/loader/samples/minexample/ys2_fixed_drums.fur and /dev/null differ diff --git a/loader/samples/minexample/ys2_lilia_sid.fur b/loader/samples/minexample/ys2_lilia_sid.fur deleted file mode 100644 index 96aad77..0000000 Binary files a/loader/samples/minexample/ys2_lilia_sid.fur and /dev/null differ diff --git a/loader/samples/minexample/ys2_new.bin b/loader/samples/minexample/ys2_new.bin new file mode 100644 index 0000000..836c632 Binary files /dev/null and b/loader/samples/minexample/ys2_new.bin differ diff --git a/loader/samples/minexample/ys2_sid.sid b/loader/samples/minexample/ys2_sid.sid new file mode 100644 index 0000000..ef7c8a6 Binary files /dev/null and b/loader/samples/minexample/ys2_sid.sid differ diff --git a/loader/samples/minexample/ys2sid.bin b/loader/samples/minexample/ys2sid.bin new file mode 100644 index 0000000..372de98 Binary files /dev/null and b/loader/samples/minexample/ys2sid.bin differ