var worker = new Worker("./src/worker/workermain.js"); var current_output = null; var current_preset_idx = -1; // TODO: use URL var current_preset_id = null; var offset2line = null; var line2offset = null; var trace_pending_at_pc; var PRESETS = [ {id:'examples/hello', chapter:4, name:'Hello 6502 and TIA'}, {id:'examples/vsync', chapter:5, name:'VSYNC and Color Bars', title:'Color Bars'}, {id:'examples/playfield', chapter:6, name:'The Playfield'}, {id:'examples/sprite', chapter:7, name:'Sprite Basics'}, {id:'examples/timing2', chapter:9, name:'Sprite Positioning', title:'Sprite Position'}, {id:'examples/missiles', chapter:10, name:'Two Missiles and a Ball', title:'Missles and Ball'}, {id:'examples/complexscene', chapter:15, name:'Playfield + Sprite I', title:'PF+Sprite 1'}, {id:'examples/complexscene2', chapter:16, name:'Playfield + Sprite II', title:'PF+Sprite 2'}, {id:'examples/scoreboard', chapter:18, name:'Scoreboard'}, {id:'examples/collisions', chapter:19, name:'Collisions'}, {id:'examples/bitmap', chapter:20, name:'Fullscreen Bitmap'}, {id:'examples/brickgame', chapter:21, name:'Brick Game'}, // {id:'examples/multisprite1', chapter:8, name:'Sprite Kernel'}, {id:'examples/bigsprite', chapter:22, name:'48-Pixel Sprite'}, {id:'examples/tinyfonts2', chapter:23, name:'Tiny Fonts'}, {id:'examples/score6', chapter:24, name:'6-Digit Score'}, {id:'examples/retrigger', chapter:26, name:'Formation Flying'}, // {id:'examples/tinyfonts', chapter:23, name:'Tiny Fonts, Slow'}, {id:'examples/multisprite3', chapter:28, name:'Multple Sprites'}, {id:'examples/procgen1', chapter:30, name:'Procedural Generation'}, {id:'examples/lines', chapter:31, name:'Drawing Lines'}, // {id:'examples/piatable', name:'Timer Table'}, {id:'examples/musicplayer', chapter:32, name:'Music Player'}, {id:'examples/road', chapter:33, name:'Pseudo 3D Road'}, {id:'examples/bankswitching', chapter:35, name:'Bankswitching'}, {id:'examples/wavetable', chapter:36, name:'Wavetable Sound'}, // {id:'examples/fullgame', name:'Thru Hike: The Game', title:'Thru Hike'}, ]; Javatari.SHOW_ERRORS = false; Javatari.CARTRIDGE_CHANGE_DISABLED = true; Javatari.DEBUG_SCANLINE_OVERFLOW = false; // TODO: make a switch Javatari.AUDIO_BUFFER_SIZE = 256; var CODE = 'code1'; var editor = CodeMirror(document.getElementById('editor'), { mode: '6502', theme: 'mbo', lineNumbers: true, tabSize: 8, gutters: ["CodeMirror-linenumbers", "gutter-offset", "gutter-bytes", "gutter-clock", "gutter-info"], }); //editor.setSize("100%", "95%"); // TODO editor.on('changes', function(ed, changeobj) { text = editor.getValue() || ""; setCode(text); }); function getCurrentPresetTitle() { if (current_preset_idx < 0) return "ROM"; else return PRESETS[current_preset_idx].title || PRESETS[current_preset_idx].name || "ROM"; } function setLastPreset(id) { localStorage.setItem("__lastid", id); } function updatePreset(current_preset_id, text) { if (text.trim().length) { localStorage.setItem(current_preset_id, text); } } function loadCode(text) { editor.setValue(text); current_output = null; setCode(text); } function loadFile(fileid, filename, index) { current_preset_id = fileid; current_preset_idx = index; var text = (localStorage.getItem(fileid) || ""); if (text) { loadCode(text); setLastPreset(fileid); } else if (!text && index >= 0) { filename += ".a"; console.log("Loading preset", fileid, filename, index, PRESETS[index]); if (text.length == 0) { console.log("Fetching", filename); $.get( filename, function( text ) { console.log("GET",text.length,'bytes'); loadCode(text); setLastPreset(fileid); }, 'text'); } } else { $.get( "presets/skeleton.a", function( text ) { loadCode(text); setLastPreset(fileid); updatePreset(fileid, text); }, 'text'); } } function loadPreset(preset_id) { // TODO var index = parseInt(preset_id+""); for (var i=0; i= 0) { // load the preset loadFile(preset_id, "presets/" + PRESETS[index].id, index); } else { // no preset found? load local loadFile(preset_id, "local/" + preset_id, -1); } } function gotoPresetAt(index) { var index = (index + PRESETS.length) % PRESETS.length; qs['file'] = PRESETS[index].id; window.location = "?" + $.param(qs); } function gotoPresetNamed(id) { if (id.startsWith("_")) { var result = eval(id+"()"); console.log(id, result); if (!result) { updateSelector(); } } else { qs['file'] = id; window.location = "?" + $.param(qs); } } function _createNewFile(e) { var filename = prompt("Create New File", "newfile.a"); if (filename && filename.length) { if (filename.indexOf(".") < 0) { filename += ".a"; } qs['file'] = "local/" + filename; window.location = "?" + $.param(qs); return true; } else { return false; } } function _shareFile(e) { if (current_output == null) { alert("Cannot share until errors are fixed."); return false; } var text = editor.getValue(); console.log("POST",text.length,'bytes'); $.post({ url: 'share.php', data: { 'platform':'vcs', /// TODO 'filename':current_preset_id.split('/').pop(), 'text':text, }, error: function(e) { console.log(e); alert("Error sharing file."); }, success: function(result) { if (confirm("Share link to file?")) { console.log(result); var sharekey = result['key']; var url = "http://8bitworkshop.com/?sharekey=" + sharekey; alert("Copy this link to your clipboard:\n\n" + url); } } }); return false; } function _resetPreset(e) { if (current_preset_idx >= 0 && confirm("Reset '" + PRESETS[current_preset_idx].name + "' to default?")) { qs['reset'] = '1'; window.location = "?" + $.param(qs); return true; } else { return false; } } function populateExamples(sel) { sel.append($("