| import NESPalette from "/app/js/models/NESPalette.js"; | import NESPalette from "/app/js/models/NESPalette.js"; | ||||
| function LRIdx2TileIdxCo(index){ | |||||
| var res = { | |||||
| lid: 0, | |||||
| index: 0, | |||||
| x: 0, | |||||
| y: 0 | |||||
| }; | |||||
| var x = Math.floor(index % 256); | |||||
| var y = Math.floor(index / 256); | |||||
| if (x < 128){ | |||||
| res.index = (Math.floor(y/8) * 16) + Math.floor(x / 8); | |||||
| } else { | |||||
| res.index = (Math.floor(y/8) * 16) + Math.floor((x - 128) / 8); | |||||
| res.lid = 1; | |||||
| } | |||||
| res.x = x % 8; | |||||
| res.y = y % 8; | |||||
| return res; | |||||
| } | |||||
| export default class NESBank { | export default class NESBank { | ||||
| constructor(){ | constructor(){ | ||||
| this.__LP = []; // Left Patterns (Sprites) | this.__LP = []; // Left Patterns (Sprites) | ||||
| this.__RP = []; // Right Patterns (Backgrounds) | this.__RP = []; // Right Patterns (Backgrounds) | ||||
| this.__default_pi = [ | |||||
| "#080808", | |||||
| "#343434", | |||||
| "#a2a2a2", | |||||
| "#efefef", | |||||
| "#666666" // Out of bounds color. | |||||
| ]; | |||||
| for (var i=0; i < 256; i++){ | for (var i=0; i < 256; i++){ | ||||
| this.__LP.push(new NESTile()); | this.__LP.push(new NESTile()); | ||||
| } | } | ||||
| } | } | ||||
| get coloridx(){ | |||||
| return new Proxy(this, { | |||||
| get:function(obj, prop){ | |||||
| var len = (obj.__LP.length * 8) + (obj.__RP.length * 8); | |||||
| if (prop === "length") | |||||
| return len; | |||||
| if (!Utils.isInt(prop)) | |||||
| throw new TypeError("Expected integer index."); | |||||
| prop = parseInt(prop); | |||||
| if (prop < 0 || prop >= len) | |||||
| return this.__default_pi[4]; | |||||
| var res = LRIdx2TileIdxCo(prop); | |||||
| var list = (res.lid === 0) ? obj.__LP : obj.__RP; | |||||
| return list[res.index].getPixelIndex(res.x, res.y); | |||||
| }, | |||||
| set:function(obj, prop, value){ | |||||
| if (!Utils.isInt(prop)) | |||||
| throw new TypeError("Expected integer index."); | |||||
| if (!Utils.isInt(value)) | |||||
| throw new TypeError("Color expected to be integer."); | |||||
| prop = parseInt(prop); | |||||
| value = parseInt(value); | |||||
| if (prop < 0 || prop >= len) | |||||
| throw new RangeError("Index out of bounds."); | |||||
| if (value < 0 || value >= 4) | |||||
| throw new RangeError("Color index out of bounds."); | |||||
| var res = LRIdx2TileIdxCo(prop); | |||||
| var list = (res.lid === 0) ? obj.__LP : obj.__RP; | |||||
| list[res.index].setPixelIndex(res.x, res.y, value); | |||||
| return true; | |||||
| } | |||||
| }); | |||||
| } | |||||
| get lp(){ | get lp(){ | ||||
| return new Proxy(this, { | return new Proxy(this, { | ||||
| get: function(obj, prop){ | get: function(obj, prop){ | ||||
| prop = parseInt(prop); | prop = parseInt(prop); | ||||
| if (prop < 0 || prop >= 256) | if (prop < 0 || prop >= 256) | ||||
| throw new RangeError("Index out of bounds."); | throw new RangeError("Index out of bounds."); | ||||
| return this.__LP[prop]; | |||||
| return obj.__LP[prop]; | |||||
| }, | }, | ||||
| set: function(obj, prop, value){ | set: function(obj, prop, value){ | ||||
| prop = parseInt(prop); | prop = parseInt(prop); | ||||
| if (prop < 0 || prop >= 256) | if (prop < 0 || prop >= 256) | ||||
| throw new RangeError("Index out of bounds."); | throw new RangeError("Index out of bounds."); | ||||
| this.__LP[prop].copy(value); | |||||
| obj.__LP[prop].copy(value); | |||||
| return true; | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| prop = parseInt(prop); | prop = parseInt(prop); | ||||
| if (prop < 0 || prop >= 256) | if (prop < 0 || prop >= 256) | ||||
| throw new RangeError("Index out of bounds."); | throw new RangeError("Index out of bounds."); | ||||
| return this.__RP[prop]; | |||||
| return obj.__RP[prop]; | |||||
| }, | }, | ||||
| set: function(obj, prop, value){ | set: function(obj, prop, value){ | ||||
| prop = parseInt(prop); | prop = parseInt(prop); | ||||
| if (prop < 0 || prop >= 256) | if (prop < 0 || prop >= 256) | ||||
| throw new RangeError("Index out of bounds."); | throw new RangeError("Index out of bounds."); | ||||
| this.__RP[prop].copy(value); | |||||
| obj.__RP[prop].copy(value); | |||||
| return true; | |||||
| } | } | ||||
| }); | }); | ||||
| } | } | ||||
| clone(){ | clone(){ | ||||
| return (new NESBank()).copy(this); | return (new NESBank()).copy(this); | ||||
| } | } | ||||
| getColor(x,y){ | |||||
| if (x < 0 || x >= 256 || y < 0 || y >= 128) | |||||
| return this.__default_pi[4]; | |||||
| var res = LRIdx2TileIdxCo((y*256)+x); | |||||
| var list = (res.lid === 0) ? this.__LP : this.__RP; | |||||
| var pi = list[res.index].paletteIndex; | |||||
| var ci = list[res.index].getPixelIndex(res.x, res.y); | |||||
| if (this.__palette !== null){ | |||||
| return this.__palette.get_palette_color(pi, ci); | |||||
| } | |||||
| return this.__default_pi[ci]; | |||||
| } | |||||
| setColorIndex(x, y, ci, pi){ | |||||
| if (x < 0 || x >= 256 || y < 0 || y > 128) | |||||
| throw new RangeError("Coordinates out of bounds."); | |||||
| if (!Utils.isInt(pi)) | |||||
| pi = -1; | |||||
| if (!Utils.isInt(ci)) | |||||
| ci = 0; | |||||
| if (pi < 0){ | |||||
| this.coloridx[(y*256)+x] = ci; | |||||
| } else { | |||||
| var res = LRIdx2TileIdxCo((y*256)+x); | |||||
| var list = (res.lid === 0) ? this.__LP : this.__RP; | |||||
| list[res.index].paletteIndex = pi; | |||||
| list[res.index].setPixelIndex(res.x, res.y, ci); | |||||
| } | |||||
| return this; | |||||
| } | |||||
| } | } | ||||