1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-05-28 08:41:30 +00:00

refactored pixel compositor for metasprites

This commit is contained in:
Steven Hugg 2019-03-22 15:59:34 -04:00
parent f55da302ed
commit f49ce33f97
2 changed files with 87 additions and 40 deletions

View File

@ -783,8 +783,8 @@ export class Palettizer extends PixNode {
ncolors : number;
context : EditorContext;
options : SelectablePalette[];
selindex : number = 0;
paloptions : SelectablePalette[];
palindex : number = 0;
// TODO: control to select palette for bitmaps
@ -805,7 +805,7 @@ export class Palettizer extends PixNode {
});
}
updateRight() {
this.updatePalette();
this.updateRefs();
this.images = this.left.images;
var mask = this.palette.length - 1; // must be power of 2
// for each image, map bytes to RGB colors
@ -817,11 +817,11 @@ export class Palettizer extends PixNode {
return out;
});
}
updatePalette() {
updateRefs() {
if (this.context != null) {
this.options = this.context.getPalettes(this.ncolors);
if (this.options && this.options.length > 0) {
this.palette = this.options[this.selindex].palette;
this.paloptions = this.context.getPalettes(this.ncolors);
if (this.paloptions && this.paloptions.length > 0) {
this.palette = this.paloptions[this.palindex].palette;
}
}
if (this.palette == null) {
@ -876,40 +876,79 @@ export class PaletteFormatToRGB extends PixNode {
}
}
export class NESNametableConverter extends PixNode {
export abstract class Compositor extends PixNode {
palette : Uint32Array;
tilemap : Uint8Array[]; // tilemap images
rgbimgs : Uint32Array[]; // output (1 image)
images : Uint8Array[]; // output (1 image)
width : number;
height : number;
cols : number;
rows : number;
baseofs : number;
context : EditorContext;
paloptions : SelectablePalette[];
tileoptions : SelectableTilemap[];
palindex : number = 0;
tileindex : number = 0;
constructor(context:EditorContext) {
super();
this.context = context;
}
updateRefs() {
if (this.context != null) {
this.tileoptions = this.context.getTilemaps(256);
if (this.tileoptions && this.tileoptions.length > 0) {
this.tilemap = this.tileoptions[this.tileindex].images;
}
}
}
}
export type MetaspriteEntry = {
x:number, y:number, tile:number, attr:number
};
export class MetaspriteCompositor extends Compositor {
metadefs : MetaspriteEntry[];
constructor(context:EditorContext, metadefs) {
super(context);
this.metadefs = metadefs;
}
updateLeft() {
// TODO
}
updateRight() {
this.updateRefs();
this.width = 16; // TODO
this.height = 16; // TODO
var idata = new Uint8Array(this.width * this.height);
this.images = [idata];
this.metadefs.forEach((meta) => {
// TODO
});
}
}
export class NESNametableConverter extends Compositor {
cols : number;
rows : number;
baseofs : number;
constructor(context:EditorContext) {
super(context);
}
updateLeft() {
// TODO
}
updateRight() {
this.words = this.left.words;
this.updatePalette();
this.updateRefs();
this.cols = 32;
this.rows = 30;
this.width = this.cols * 8;
this.height = this.rows * 8;
this.baseofs = 0;
var idata = new Uint32Array(this.width * this.height);
this.rgbimgs = [idata];
var idata = new Uint8Array(this.width * this.height);
this.images = [idata];
var a = 0;
var attraddr;
for (var row=0; row<this.rows; row++) {
@ -927,8 +966,7 @@ export class NESNametableConverter extends PixNode {
for (var x=0; x<8; x++) {
var color = t[j++];
if (color) color += coloradd;
var rgb = this.palette[color];
idata[i++] = rgb | 0xff000000;
idata[i++] = color;
}
i += this.cols*8-8;
}
@ -937,18 +975,6 @@ export class NESNametableConverter extends PixNode {
}
// TODO
}
updatePalette() {
if (this.context != null) {
this.paloptions = this.context.getPalettes(16);
if (this.paloptions && this.paloptions.length > 0) {
this.palette = this.paloptions[this.palindex].palette;
}
this.tileoptions = this.context.getTilemaps(256);
if (this.tileoptions && this.tileoptions.length > 0) {
this.tilemap = this.tileoptions[this.tileindex].images;
}
}
}
}
///// UI CONTROLS
@ -1073,17 +1099,17 @@ export class CharmapEditor extends PixNode {
// add palette selector
// TODO: only view when editing?
var palizer = this.left;
if (palizer instanceof Palettizer && palizer.options.length > 1) {
if (palizer instanceof Palettizer && palizer.paloptions.length > 1) {
var palselect = $(document.createElement('select'));
palizer.options.forEach((palopt, i) => {
palizer.paloptions.forEach((palopt, i) => {
// TODO: full identifier
var sel = $(document.createElement('option')).text(palopt.name).val(i).appendTo(palselect);
if (i == (palizer as Palettizer).selindex)
if (i == (palizer as Palettizer).palindex)
sel.attr('selected','selected');
});
palselect.appendTo(agrid).change((e) => {
var index = $(e.target).val() as number;
(palizer as Palettizer).selindex = index;
(palizer as Palettizer).palindex = index;
palizer.refreshRight();
});
}

View File

@ -1029,8 +1029,8 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
while (node != null) {
if (node instanceof pixed.Palettizer) {
// TODO: move to node class?
var rgbimgs = node.rgbimgs;
if (rgbimgs.length >= matchlen) {
var rgbimgs = node.rgbimgs; // TODO: why is null?
if (rgbimgs && rgbimgs.length >= matchlen) {
result.push({node:node, name:"Tilemap", images:node.images, rgbimgs:rgbimgs}); // TODO
}
}
@ -1072,7 +1072,9 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
var start = m.index + m[0].length;
var end;
// TODO: verilog end
if (m[0].startsWith(';;')) {
if (platform_id == 'verilog') {
end = data.indexOf("end", start); // asm
} else if (m[0].startsWith(';;')) {
end = data.indexOf(';;', start); // asm
} else {
end = data.indexOf(';', start); // C
@ -1089,6 +1091,24 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
}
}
}
// look for DEF_METASPRITE_2x2(playerRStand, 0xd8, 0)
// TODO: could also look in ROM
var re2 = /DEF_METASPRITE_(\d+)x(\d+)[(](\w+),\s*(\w+),\s*(\w+)/gi;
while (m = re2.exec(data)) {
var width = parseInt(m[1]);
var height = parseInt(m[2]);
var ident = m[3];
var tile = parseInt(m[4]);
var attr = parseInt(m[5]);
var metadefs = [];
for (var x=0; x<width; x++) {
for (var y=0; y<height; y++) {
metadefs.push({x:x*8, y:y*8, tile:tile, attr:attr});
}
}
var meta = {defs:metadefs,width:width*8,height:height*8};
result.push({fileid:id,label:ident,meta:meta});
}
return result;
}
@ -1197,6 +1217,7 @@ export class AssetEditorView implements ProjectView, pixed.EditorContext {
// is this a nes nametable?
if (frag.fmt.map == 'nesnt') {
node = node.addRight(new pixed.NESNametableConverter(this)); // TODO?
node = node.addRight(new pixed.Palettizer(this, {w:8,h:8,bpp:4})); // TODO?
const fmt = {w:8*32,h:8*30,count:1}; // TODO
node = node.addRight(new pixed.CharmapEditor(this, newDiv(filediv), fmt));
this.registerAsset("nametable", first, true);