diff --git a/src/common/ecs/binpack.ts b/src/common/ecs/binpack.ts index 61a576cb..163f4c6f 100644 --- a/src/common/ecs/binpack.ts +++ b/src/common/ecs/binpack.ts @@ -7,6 +7,7 @@ export interface BoxConstraints { width: number; height: number; box?: PlacedBox; + label?: string; } enum BoxPlacement { @@ -76,9 +77,10 @@ export class Bin { let dx = (f.right - f.left) - b.width; let dy = (f.bottom - f.top) - b.height; if (dx >= 0 && dy >= 0) { - let score = 1 / (1 + dx + dy); + let score = 1 / (1 + dx + dy + f.left * 0.001); if (score > bestscore) { best = f; + bestscore = score; if (score == 1) break; } } @@ -188,7 +190,7 @@ export class Packer { box.left = parent.right - w; box.right = parent.right; } - if (debug) console.log('place',box.left,box.top,box.right,box.bottom,parent?.left,parent?.top); + if (debug) console.log('place',b.label,box.left,box.top,box.right,box.bottom,parent?.left,parent?.top); let parents = [parent]; // if approx match, might overlap multiple free boxes if (approx) parents = bin.getBoxes(box, 100, bin.free); @@ -198,4 +200,40 @@ export class Packer { if (debug) console.log('cannot place!', b.left,b.top,b.width,b.height); return null; } + toSVG() { + let s = ''; + let r = {width:100,height:70} + for (let bin of this.bins) { + r.width = Math.max(r.width, bin.binbounds.right); + r.height = Math.max(r.height, bin.binbounds.bottom); + } + s += ``; + for (let bin of this.bins) { + let be = bin.extents; + s += '' + s += ``; + let textx = be.right+1; + let texty = 0; + for (let box of this.boxes) { + let b = box.box; + if (b) { + if (b.bin == bin) s += ``; + if (b.top == texty) textx += 10; else textx = be.right+1; + texty = b.top; + if (box.label) s += `${box.label}`; + } + } + /* + for (let b of bin.free) { + s += ``; + } + */ + s += '' + } + s += ``; + return s; + } + toSVGUrl() { + return `data:image/svg+xml;base64,${btoa(this.toSVG())}`; + } } diff --git a/src/common/ecs/ecs.ts b/src/common/ecs/ecs.ts index 2fdfa13a..c09dd9e1 100644 --- a/src/common/ecs/ecs.ts +++ b/src/common/ecs/ecs.ts @@ -1389,6 +1389,7 @@ export class EntityScope implements SourceLocated { bottom: stats.tempendseq+1, width: instance.system.tempbytes, height: stats.tempendseq - stats.tempstartseq + 1, + label: instance.system.name }; pack.boxes.push(v); } @@ -1404,6 +1405,7 @@ export class EntityScope implements SourceLocated { //this.bss.equates[this.dialect.tempLabel(inst)] = `TEMP+${b.box?.left}`; } } + console.log(pack.toSVGUrl()); } private analyzeEntities() { this.buildSegments(); @@ -1439,6 +1441,7 @@ export class EntityScope implements SourceLocated { } replaceSubroutines(code: string) { // TODO: bin-packing for critical code + // TODO: doesn't work with nested subroutines? let allsubs : string[] = []; for (let stats of Object.values(this.eventStats)) { if (stats.count > 1) { diff --git a/test/ecs/sprites.txt b/test/ecs/sprites.txt index c56905b2..0f32e4f4 100644 --- a/test/ecs/sprites.txt +++ b/test/ecs/sprites.txt @@ -28,11 +28,11 @@ SpriteSlot_sprite_b0: TEMP: Kernel2Sprite__2__tmp: Joystick__3__tmp: +SpriteHider__9__tmp: .res 1 SpriteShuffler__8__tmp: .res 1 .res 1 -SpriteHider__9__tmp: .res 1 .res 1 .res 1 diff --git a/test/ecs/sprites1.txt b/test/ecs/sprites1.txt index db5a6be4..254293c0 100644 --- a/test/ecs/sprites1.txt +++ b/test/ecs/sprites1.txt @@ -28,11 +28,11 @@ HasColormap_colormap_b0: TEMP: Kernel2Sprite__2__tmp: Joystick__3__tmp: +SpriteHider__9__tmp: .res 1 SpriteShuffler__8__tmp: .res 1 .res 1 -SpriteHider__9__tmp: .res 1 .res 1 .res 1