let g_viewOffset = 100 let g_data = new Uint8Array() let g_viewWidth = 4 let g_viewHeight = 24 function toHexString(value) { let hex = value.toString(16) while (hex.length < 8) { hex = "0" + hex; } return hex } function updateTextureView(textureView, data, viewOffset) { if (viewOffset == undefined) { viewOffset = 0 } viewSize = g_viewWidth * g_viewHeight endOffset = viewOffset + viewSize textureView.textContent = '' // Clear let textureViewBody = document.createElement('tbody') textureView.appendChild(textureViewBody) for (let offset = viewOffset; offset < endOffset; offset += g_viewWidth) { let tr = document.createElement('tr') let tdOffset = document.createElement('td') let offsetText = document.createTextNode(toHexString(offset)) tdOffset.appendChild(offsetText) tr.appendChild(tdOffset) for (let i = 0; i < g_viewWidth; i++) { if (offset + i >= data.length) { break; } const value = data[offset + i] const color1 = ((value & 0xf0) >> 4) const color2 = ((value & 0x0f)) let td1 = document.createElement('td') td1.classList.add('c1' + color1.toString(16)) td1.appendChild(document.createTextNode(color1.toString(16) + '.')) tr.appendChild(td1) let td2 = document.createElement('td') td2.classList.add('c1' + color2.toString(16)) td2.appendChild(document.createTextNode(color2.toString(16) + '.')) tr.appendChild(td2) } textureViewBody.appendChild(tr) } } function viewMoveDown(step) { g_viewOffset = Math.max(0, Math.min(g_data.length, g_viewOffset + step)) updateTextureView(document.querySelector('table#texture-view'), g_data, g_viewOffset) } function viewGoToOffset() { g_viewOffset = parseInt(document.querySelector('input#offset').value, 16) updateTextureView(document.querySelector('table#texture-view'), g_data, g_viewOffset) } document.querySelector('button#down').addEventListener('click', (event) => { viewMoveDown(g_viewWidth) }) document.querySelector('button#up').addEventListener('click', (event) => { viewMoveDown(-g_viewWidth) }) document.querySelector('button#go').addEventListener('click', (event) => { viewGoToOffset() }) document.querySelector('input#offset').addEventListener('change', (event) => { viewGoToOffset() }) addEventListener("keypress", (event) => { if (event.altKey || event.ctrlKey) { return } switch (event.code) { case 'KeyJ': viewMoveDown(g_viewWidth * (event.shiftKey ? g_viewHeight : 1)) break case 'KeyK': viewMoveDown(g_viewWidth * -(event.shiftKey ? g_viewHeight : 1)) break case 'KeyL': viewMoveDown((event.shiftKey ? g_viewWidth : 1)) break case 'KeyH': viewMoveDown(-(event.shiftKey ? g_viewWidth : 1)) break } }); document.querySelector('input#file').addEventListener('change', (event) => { let files = event.target.files if (files.length == 0) { return } const file = files[0] let reader = new FileReader() reader.onload = (e) => { let arrayBuffer = e.target.result g_data = new Uint8Array(arrayBuffer) updateTextureView(document.querySelector('table#texture-view'), g_data, g_viewOffset) } reader.onerror = (e) => alert(e.target.error.name) reader.readAsArrayBuffer(file) })