instrument list rendering with FT2 font.
This commit is contained in:
parent
54809c2b81
commit
f092f847f7
2 changed files with 74 additions and 16 deletions
11
index.html
11
index.html
|
|
@ -4,13 +4,14 @@
|
||||||
<script src="xmeffects.js"></script>
|
<script src="xmeffects.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body onload="main()">
|
<body onload="main()">
|
||||||
<div><button id='playpause' disabled=true style="width: 100px">Play</button></div>
|
<div style="background:#000">
|
||||||
<div><canvas id='vu' width=224 height=64></canvas></div>
|
<div><canvas id='vu' width=224 height=64></canvas></div>
|
||||||
<div><canvas id='gfxpattern' width=640 height=200></canvas></div>
|
<div><canvas id='gfxpattern' width=640 height=200></canvas></div>
|
||||||
|
<div id='instruments'></div>
|
||||||
|
<div><button id='playpause' disabled=true style="width: 100px">Play</button></div>
|
||||||
|
</div>
|
||||||
<pre id='debug'>
|
<pre id='debug'>
|
||||||
</pre>
|
</pre>
|
||||||
<pre id='instruments'>
|
|
||||||
</pre>
|
|
||||||
<pre>
|
<pre>
|
||||||
code: <a href="http://github.com/a1k0n/jsxm/">github.com/a1k0n/jsxm</a>
|
code: <a href="http://github.com/a1k0n/jsxm/">github.com/a1k0n/jsxm</a>
|
||||||
todo:
|
todo:
|
||||||
|
|
|
||||||
79
xm.js
79
xm.js
|
|
@ -8,10 +8,37 @@ fontimg.src = "ft2font.png";
|
||||||
// canvas to render patterns onto
|
// canvas to render patterns onto
|
||||||
var pat_canvas = document.createElement('canvas');
|
var pat_canvas = document.createElement('canvas');
|
||||||
|
|
||||||
//
|
// for pretty-printing notes
|
||||||
var _note_names = ["C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"];
|
var _note_names = ["C-", "C#", "D-", "D#", "E-", "F-", "F#", "G-", "G#", "A-", "A#", "B-"];
|
||||||
|
|
||||||
var f_smp = 44100; // updated by play callback, default value here
|
var f_smp = 44100; // updated by play callback, default value here
|
||||||
|
|
||||||
|
// pixel widths of each character in the proportional font
|
||||||
|
var _fontwidths = [
|
||||||
|
4, 7, 3, 6, 6, 6, 6, 5, 4, 5, 5, 5, 5, 5, 7, 7,
|
||||||
|
5, 5, 5, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 7, 7, 7,
|
||||||
|
4, 2, 5, 7, 7, 7, 7, 3, 4, 4, 6, 6, 3, 6, 2, 7,
|
||||||
|
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 2, 3, 6, 6, 6, 7,
|
||||||
|
7, 7, 7, 7, 7, 7, 7, 7, 7, 2, 7, 7, 7, 8, 8, 7,
|
||||||
|
7, 7, 7, 7, 8, 7, 7, 8, 8, 8, 7, 4, 7, 4, 4, 5,
|
||||||
|
3, 6, 6, 6, 6, 6, 4, 6, 6, 2, 4, 6, 2, 8, 6, 6,
|
||||||
|
6, 6, 4, 6, 4, 6, 7, 8, 7, 6, 6, 4, 2, 4, 4, 4];
|
||||||
|
|
||||||
|
// draw FT2 proportional font text to a drawing context
|
||||||
|
// returns width rendered
|
||||||
|
function DrawText(text, dx, dy, ctx) {
|
||||||
|
var dx0 = dx;
|
||||||
|
for (var i = 0; i < text.length; i++) {
|
||||||
|
var n = text.charCodeAt(i);
|
||||||
|
var sx = (n&63)*8;
|
||||||
|
var sy = (n>>6)*10 + 7*8;
|
||||||
|
var width = _fontwidths[n];
|
||||||
|
ctx.drawImage(fontimg, sx, sy, width, 10, dx, dy, width, 10);
|
||||||
|
dx += width + 1;
|
||||||
|
}
|
||||||
|
return dx - dx0;
|
||||||
|
}
|
||||||
|
|
||||||
var _fontmap_notes = [8*5, 8*22, 8*28];
|
var _fontmap_notes = [8*5, 8*22, 8*28];
|
||||||
var _pattern_cellwidth = 16 + 4 + 8 + 4 + 8 + 16 + 4;
|
var _pattern_cellwidth = 16 + 4 + 8 + 4 + 8 + 16 + 4;
|
||||||
var _scope_width = _pattern_cellwidth - 1;
|
var _scope_width = _pattern_cellwidth - 1;
|
||||||
|
|
@ -176,10 +203,7 @@ function RedrawScreen() {
|
||||||
for (var j = 0; j < xm.nchan; j++) {
|
for (var j = 0; j < xm.nchan; j++) {
|
||||||
var x = _pattern_border + j * _pattern_cellwidth;
|
var x = _pattern_border + j * _pattern_cellwidth;
|
||||||
// render channel number
|
// render channel number
|
||||||
if (j >= 10) {
|
DrawText(j, x, 1, ctx);
|
||||||
ctx.drawImage(fontimg, 8*((j/10)|0), 4*8, 4, 8, x, 1, 4, 8);
|
|
||||||
}
|
|
||||||
ctx.drawImage(fontimg, 8*(j%10), 4*8, 4, 8, x+4, 1, 4, 8);
|
|
||||||
|
|
||||||
// volume in dB as a green bar
|
// volume in dB as a green bar
|
||||||
var vu_y = -Math.log(VU[j])*10;
|
var vu_y = -Math.log(VU[j])*10;
|
||||||
|
|
@ -969,13 +993,46 @@ function loadXM(arrayBuf) {
|
||||||
debug.innerHTML = xm.songname;
|
debug.innerHTML = xm.songname;
|
||||||
|
|
||||||
var instrlist = document.getElementById("instruments");
|
var instrlist = document.getElementById("instruments");
|
||||||
var namelist = [];
|
var instrcols = ((xm.instruments.length + 7) / 8) | 0;
|
||||||
for (var j = 0; j < xm.instruments.length; j++) {
|
for (var i = 0; i < instrcols; i++) {
|
||||||
var n = (j+1).toString(16);
|
var canvas = document.createElement('canvas');
|
||||||
if (j < 15) n = ' ' + n;
|
var ctx = canvas.getContext('2d');
|
||||||
namelist.push(n + " " + xm.instruments[j].name);
|
var instrcolumnwidth = 8*22;
|
||||||
|
canvas.width = instrcolumnwidth;
|
||||||
|
canvas.height = 8 * 10;
|
||||||
|
ctx.fillStyle = '#000';
|
||||||
|
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||||
|
var hasname = 0, hasdata = 0;
|
||||||
|
for (var j = 8*i; j < Math.min(8*i+8, xm.instruments.length); j++) {
|
||||||
|
var y = 10*(j - 8*i);
|
||||||
|
var n = (j+1).toString(16);
|
||||||
|
if (j < 15) n = '0' + n;
|
||||||
|
var data = xm.instruments[j].samples;
|
||||||
|
if (data) {
|
||||||
|
var len = data[0].len;
|
||||||
|
data = data[0].sampledata;
|
||||||
|
var scale = Math.ceil(len / instrcolumnwidth);
|
||||||
|
ctx.strokeStyle = '#55acff';
|
||||||
|
ctx.beginPath();
|
||||||
|
for (var k = 0; k < Math.min(len / scale, instrcolumnwidth - 20); k++) {
|
||||||
|
ctx.lineTo(k + 20, y + data[k*scale] * 4 + 4);
|
||||||
|
}
|
||||||
|
ctx.stroke();
|
||||||
|
hasdata++;
|
||||||
|
}
|
||||||
|
var name = xm.instruments[j].name;
|
||||||
|
ctx.globalCompositeOperation = 'lighten';
|
||||||
|
DrawText(n, 1, y, ctx);
|
||||||
|
if (name != '') {
|
||||||
|
DrawText(xm.instruments[j].name, 20, y, ctx);
|
||||||
|
hasname++;
|
||||||
|
}
|
||||||
|
ctx.globalCompositeOperation = 'source-over';
|
||||||
|
}
|
||||||
|
if (hasname || hasdata) {
|
||||||
|
instrlist.appendChild(canvas);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
instrlist.innerHTML = namelist.join("\n");
|
|
||||||
|
|
||||||
return xm;
|
return xm;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue