Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Noteblock Studio file (.nbs) player for MiscPeripherals (a ComputerCraft mod)
- -- You are free to copy, alter, and distribute this under the following conditions:
- -- 1) You leave these comments and credits attached
- -- 2) You do not make money off of this
- -- Program by James0x57 - http://www.youtube.com/watch?v=ro4EK8smULQ
- -- Noteblock Studio by _Davve_ - http://www.minecraftforum.net/topic/136749-minecraft-note-block-studio-150000-downloads/
- -- MiscPeripherals by RichardG867 - http://www.computercraft.info/forums2/index.php?/topic/4587-cc1481mc146-miscperipherals-23/
- -- ComputerCraft by Dan - http://www.computercraft.info/
- local args = {...};
- local menu = {};
- local box = nil;
- local song = nil;
- local action = 'mainList';
- local maxtoshow = 12;
- local selected = 0;
- local startat = 1;
- for _,side in ipairs({"left"; "right"; "back"; "bottom"; "top"; "front"}) do
- if peripheral.getType(side) == "note" then
- box = peripheral.wrap(side);
- break;
- end
- end
- if turtle ~= nil then
- maxtoshow = 7;
- end
- function newSong(x)
- return {
- fh = x;
- length = 0;
- height = 0;
- name = "";
- author = "";
- originalAuthor = "";
- description = "";
- tempo = 10.00; --tks per second
- autoSaving = 0;
- autoSaveDur = 0;
- timeSig = 4;
- minSpent = 0;
- leftClicks = 0;
- rightClicks = 0;
- blocksAdded = 0;
- blocksRemoved = 0;
- midi = "";
- music = { wait={}; inst={}; note={}; };
- };
- end
- if args[1] == nil or fs.isDir(args[1]) == false then
- args[1] = "songs";
- if fs.isDir(args[1]) == false then
- fs.makeDir("songs");
- end
- end
- for _, file in ipairs(fs.list(args[1])) do
- if fs.isDir(file) == false and string.find(file, ".nbs", -4, true) ~= nil then -- if file and ends in ".nbs"
- menu[#menu+1] = file;
- end
- end
- function showInfo()
- term.clear();
- print("Now Playing: \n\n\n\n\n\n " .. song.name);
- print("\n\n\n\n\n\nAuthor: " .. song.author);
- print("Original Author: " .. song.originalAuthor);
- print("Description: ");
- print(song.description);
- end
- function readInt(fh) --little endian, fh is open in rb mode
- local ret = 0;
- local x = fh.read();
- if x == nil then return nil; end
- ret = x;
- x = fh.read();
- if x == nil then return nil; end
- ret = (x * 0x100) + ret;
- x = fh.read();
- if x == nil then return nil; end
- ret = (x * 0x10000) + ret;
- x = fh.read();
- if x == nil then return nil; end
- ret = (x * 0x1000000) + ret;
- return ret;
- end
- function readShort(fh) --little endian, fh is open in rb mode
- local ret = 0;
- local x = fh.read();
- if x == nil then return nil; end
- ret = x;
- x = fh.read();
- if x == nil then return nil; end
- ret = (x * 0x100) + ret;
- return ret;
- end
- function readString(fh, len) --fh is open in rb mode
- local ret = "";
- local x = 0;
- for i = 1, len do
- x = fh.read();
- if x == nil then return nil; end
- ret = ret .. string.char(x);
- end
- return ret;
- end
- function readHeader()
- song.length = readShort(song.fh);
- song.height = readShort(song.fh);
- song.name = readString(song.fh, readInt(song.fh));
- song.author = readString(song.fh, readInt(song.fh));
- song.originalAuthor = readString(song.fh, readInt(song.fh));
- song.description = readString(song.fh, readInt(song.fh));
- song.tempo = 1.000 / ( readShort(song.fh) / 100.00 );
- song.autoSaving = song.fh.read();
- song.autoSaveDur = song.fh.read();
- song.timeSig = song.fh.read();
- song.minSpent = readInt(song.fh);
- song.leftClicks = readInt(song.fh);
- song.rightClicks = readInt(song.fh);
- song.blocksAdded = readInt(song.fh);
- song.blocksRemoved = readInt(song.fh);
- song.midi = readString(song.fh, readInt(song.fh));
- end
- function readNotes()
- local curtk = 1;
- local tk = -1;
- local layer = -1;
- local inst = 0;
- local note = 33; -- MC is 33 to 57
- while true do
- tk = readShort(song.fh);
- if tk == nil then return false; end
- if tk == 0 then break; end
- while true do
- song.music.wait[curtk] = (tk * song.tempo) * 0.975; -- * 0.975 to speed it up a bit because lua slow
- layer = readShort(song.fh); --can't do anything with this info (yet?)
- if layer == nil then return false; end
- if layer == 0 then break; end
- song.music.inst[curtk]=song.fh.read();
- if song.music.inst[curtk] == 0 then
- song.music.inst[curtk] = 0;
- elseif song.music.inst[curtk] == 2 then
- song.music.inst[curtk] = 1;
- elseif song.music.inst[curtk] == 3 then
- song.music.inst[curtk] = 2;
- elseif song.music.inst[curtk] == 4 then
- song.music.inst[curtk] = 3;
- elseif song.music.inst[curtk] == 1 then
- song.music.inst[curtk] = 4;
- end
- song.music.note[curtk]=song.fh.read()-33;
- tk = 0;
- curtk = curtk + 1;
- end
- end
- return true;
- end
- function playNotes()
- for i = 1, #song.music.wait - 1 do
- if song.music.wait[i] ~= 0 then
- os.sleep(song.music.wait[i]);
- end
- --box.playNote(song.music.inst[i], song.music.note[i]);
- pcall(box.playNote, song.music.inst[i], song.music.note[i]);
- end
- end
- function printSongs(x)
- action = 'mainList';
- term.clear();
- for i = x, #menu do
- if x + maxtoshow <= i then break end
- print(i .. ") " .. menu[i]);
- end
- print("----------------------\n0) [More]\n\nEnter the song number to play it: ");
- term.setCursorBlink(true);
- selected = tonumber(read());
- print(selected);
- term.setCursorBlink(false);
- if selected > 0 and selected <= #menu then
- action = 'playSong';
- else
- action = 'backNextMenu';
- if true then
- return 2, x; -- just goes to the next page instead of new menu
- else
- term.clear();
- print("1) Previous Page of Songs...");
- print("2) Next Page of Songs...");
- print("\n\n0) [Back]\n\nEnter the option number: ");
- term.setCursorBlink(true);
- selected = tonumber(read());
- term.setCursorBlink(false);
- end
- end
- return selected, x;
- end
- if box == nil then
- print("No Iron Noteblock Detected");
- else
- selected, startat = printSongs(1);
- while true do
- if action == 'playSong' then
- song = newSong(fs.open(args[1] .. "/" .. menu[selected], "rb"));
- readHeader();
- showInfo();
- readNotes();
- song.fh.close();
- playNotes();
- --loops if don't change action
- action = 'mainList';
- else
- if action == 'backNextMenu' then
- if selected == 1 then
- startat = startat - maxtoshow;
- if startat < 1 then startat = 1; end
- selected, startat = printSongs(startat);
- elseif selected == 2 then
- startat = startat + maxtoshow
- if startat > #menu then startat = 1; end
- selected, startat = printSongs(startat);
- else --if selected == 0 then
- selected, startat = printSongs(startat);
- end
- elseif action =='mainList' then
- selected, startat = printSongs(startat);
- end
- end
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement