This commit is contained in:
Brooke Vibber 2023-03-25 19:43:57 -07:00
parent 38e9af3843
commit 9631e2e026
3 changed files with 53 additions and 21 deletions

View file

@ -585,6 +585,26 @@ function decimate(input, palette, n) {
// preface the reserved bits // preface the reserved bits
let buckets = reserved.slice().map((c) => [atariRGB[c]]).concat([input.slice()]); let buckets = reserved.slice().map((c) => [atariRGB[c]]).concat([input.slice()]);
/*
let buckets = [input.slice()];
if (reserved.length > 0) {
let pxPerReserved = input.length;
for (let c of reserved) {
for (let i = 0; i < pxPerReserved; i++) {
buckets[0].unshift(atariRGB[c]);
}
}
console.log(buckets[0].length, 'xxx');
}
*/
let magicSort = (picker) => (a, b) => {
let bychannel = picker(b) - picker(a);
if (bychannel) return bychannel;
let byluma = b.luma() - a.luma();
return byluma;
};
let medianCut = (bucket, range) => { let medianCut = (bucket, range) => {
if (bucket.length < 2) { if (bucket.length < 2) {
console.log(bucket); console.log(bucket);
@ -594,15 +614,21 @@ function decimate(input, palette, n) {
// Sort by the channel with the greatest range, // Sort by the channel with the greatest range,
// then cut the bucket in two at the median. // then cut the bucket in two at the median.
if (range.g >= range.r && range.g >= range.b) { if (range.g >= range.r && range.g >= range.b) {
bucket.sort((a, b) => b.g - a.g); //bucket.sort((a, b) => b.g - a.g);
bucket.sort(magicSort((rgb) => rgb.g));
} else if (range.r >= range.g && range.r >= range.b) { } else if (range.r >= range.g && range.r >= range.b) {
bucket.sort((a, b) => b.r - a.r); //bucket.sort((a, b) => b.r - a.r);
bucket.sort(magicSort((rgb) => rgb.r));
} else if (range.b >= range.g && range.b >= range.r) { } else if (range.b >= range.g && range.b >= range.r) {
bucket.sort((a, b) => b.b - a.b); //bucket.sort((a, b) => b.b - a.b);
bucket.sort(magicSort((rgb) => rgb.b));
} }
let half = bucket.length >> 1; let half = bucket.length >> 1;
//console.log('cutting', half, bucket.length); //console.log('cutting', half, bucket.length);
return [bucket.slice(0, half), bucket.slice(half)]; let [bottom, top] = [bucket.slice(0, half), bucket.slice(half)];
//console.log({bottom, top});
return [bottom, top];
//return [bucket.slice(0, half), bucket.slice(half)];
}; };
while (buckets.length < n) { while (buckets.length < n) {
// Find the bucket with the greatest range in any channel // Find the bucket with the greatest range in any channel
@ -729,8 +755,11 @@ function decimate(input, palette, n) {
}); });
// hack // hack
decimated.sort((a, b) => a - b); decimated.sort((a, b) => a - b);
//console.log(decimated); console.log(decimated);
decimated[0] = 0;
// we shouldn't have to do this
//decimated[0] = 0;
console.log(decimated);
// Palette fits // Palette fits
return dither(decimated); return dither(decimated);
@ -837,7 +866,7 @@ async function convert(source) {
.slice(y * width, (y + 1) * width); .slice(y * width, (y + 1) * width);
if (y > 0) { if (y > 0) {
let error = lines[y - 1].error; let error = lines[y - 1].error;
inputLine = inputLine.map((rgb, x) => rgb.add(error[x])); inputLine = inputLine.map((rgb, x) => rgb.add(error[x]).clamp());
} }
let line = decimate(inputLine, allColors, 4, y); let line = decimate(inputLine, allColors, 4, y);
lines.push(line); lines.push(line);
@ -904,12 +933,14 @@ function genAssembly(width, height, nbits, lines) {
return `.data return `.data
.export frame1_top .export frame1_top
.export frame1_bottom .export frame1_bottom
.export frame1_palette1_even .export frame1_palette1_even
.export frame1_palette1_odd .export frame1_palette1_odd
.export frame1_palette2_even .export frame1_palette2_even
.export frame1_palette2_odd .export frame1_palette2_odd
.export frame1_palette3_even .export frame1_palette3_even
.export frame1_palette3_odd .export frame1_palette3_odd
.export displaylist .export displaylist
.segment "BUFFERS" .segment "BUFFERS"
@ -918,30 +949,30 @@ function genAssembly(width, height, nbits, lines) {
frame1_top: frame1_top:
${byte2byte(frame.bitmap.slice(0, half))} ${byte2byte(frame.bitmap.slice(0, half))}
.align 128
frame1_palette1_even:
${byte2byte(even(frame.palette1))}
.align 128
frame1_palette2_even:
${byte2byte(even(frame.palette2))}
.align 128
frame1_palette3_even:
${byte2byte(even(frame.palette3))}
.align 4096 .align 4096
frame1_bottom: frame1_bottom:
${byte2byte(frame.bitmap.slice(half))} ${byte2byte(frame.bitmap.slice(half))}
.align 128
frame1_palette1_even:
${byte2byte(even(frame.palette1))}
.align 128 .align 128
frame1_palette1_odd: frame1_palette1_odd:
${byte2byte(odd(frame.palette1))} ${byte2byte(odd(frame.palette1))}
.align 128
frame1_palette2_even:
${byte2byte(even(frame.palette2))}
.align 128 .align 128
frame1_palette2_odd: frame1_palette2_odd:
${byte2byte(odd(frame.palette2))} ${byte2byte(odd(frame.palette2))}
.align 128
frame1_palette3_even:
${byte2byte(even(frame.palette3))}
.align 128 .align 128
frame1_palette3_odd: frame1_palette3_odd:
${byte2byte(odd(frame.palette3))} ${byte2byte(odd(frame.palette3))}
@ -951,7 +982,7 @@ ${byte2byte(odd(frame.palette3))}
.align 1024 .align 1024
displaylist: displaylist:
; 40 lines overscan ; 24 lines overscan
.repeat 4 .repeat 4
.byte $70 ; 8 blank lines .byte $70 ; 8 blank lines
.endrep .endrep

View file

@ -34,6 +34,7 @@ bytes_per_line = 40
pages_per_frame = 32 pages_per_frame = 32
lines_per_frame = 262 lines_per_frame = 262
;scanline_offset = 31 + (40 - 24) / 2 ;scanline_offset = 31 + (40 - 24) / 2
;scanline_offset = 46
scanline_offset = 46 scanline_offset = 46
scanline_max = (lines_per_frame - scanline_offset) / 2 scanline_max = (lines_per_frame - scanline_offset) / 2

View file

@ -2,7 +2,7 @@ set -a
mkdir -p frames mkdir -p frames
TIME=37 TIME=37.5
ffmpeg \ ffmpeg \
-i 'doom-speedrun.webm' \ -i 'doom-speedrun.webm' \