#wip: SFFModel.
This commit is contained in:
commit
9b6983e556
7
.gitignore
vendored
Normal file
7
.gitignore
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
/Data
|
||||
/Public/data
|
||||
*.[Ss]ecrets.*
|
||||
*.[Ss]ecret.*
|
||||
*.[Ss]ecrets
|
||||
*.[Ss]ecret
|
||||
*.deleted
|
||||
65
Public/ecma/Models/BinaryStructureModel.ecma.js
Normal file
65
Public/ecma/Models/BinaryStructureModel.ecma.js
Normal file
@ -0,0 +1,65 @@
|
||||
"use strict";
|
||||
|
||||
import {Common} from "http://localhost:18000/Public/ecma/Utils/Common.ecma.js";
|
||||
import {Check} from "http://localhost:18000/Public/ecma/Utils/Checks.ecma.js";
|
||||
|
||||
/**
|
||||
* @class BinaryStructureModel
|
||||
* @constructor
|
||||
* @param {!string} type
|
||||
* @param {!string} name
|
||||
* @param {!number} from
|
||||
* @param {?number} size
|
||||
* @param {!Array.<BinaryStructureModel>} [childs = []]
|
||||
* @returns {void}
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
export const BinaryStructureModel = (function(){
|
||||
|
||||
/**
|
||||
* @constructs BinaryStructureModel
|
||||
* @param {!string} type
|
||||
* @param {!string} name
|
||||
* @param {!number} from
|
||||
* @param {?number} size
|
||||
* @param {!Array.<BinaryStructureModel>} [childs = []]
|
||||
* @returns {void}
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
const BinaryStructureModel = function(type, name, from, size, childs = []){
|
||||
|
||||
/** @type {BinaryStructureModel} */
|
||||
const self = this;
|
||||
|
||||
/** @type {string} */
|
||||
this.name = name;
|
||||
/** @type {string} */
|
||||
this.type = type;
|
||||
/** @type {number} */
|
||||
this.from = from;
|
||||
/** @type {number|null} */
|
||||
this.size = null;
|
||||
/** @type {Array.<BinaryStructureModel>} */
|
||||
this.childs = childs || [];
|
||||
/** @type {number|null} */
|
||||
this.next = null;
|
||||
|
||||
/**
|
||||
* @returns {void}
|
||||
* @access private
|
||||
*/
|
||||
const constructor = () => {
|
||||
if(Check.is_array(size))
|
||||
self.next = size[0];
|
||||
else if(Check.is_number(size))
|
||||
self.size = size;
|
||||
};
|
||||
|
||||
constructor();
|
||||
|
||||
};
|
||||
|
||||
return BinaryStructureModel;
|
||||
})();
|
||||
177
Public/ecma/Models/SFFv1Model.ecma.js
Normal file
177
Public/ecma/Models/SFFv1Model.ecma.js
Normal file
@ -0,0 +1,177 @@
|
||||
"use strict";
|
||||
|
||||
import {Common} from "http://localhost:18000/Public/ecma/Utils/Common.ecma.js";
|
||||
import {Tools} from "../Utils/Tools.ecma.js";
|
||||
|
||||
export const SFFPCXModel = (function(){
|
||||
|
||||
const SFFPCXModel = function(pcx, palette_size = 0){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.id = null;
|
||||
this.version = null;
|
||||
this.encoding = null;
|
||||
this.bit = null;
|
||||
this.x = null;
|
||||
this.y = null;
|
||||
this.width = null;
|
||||
this.height = null;
|
||||
this.horizontal = null;
|
||||
this.vertical = null;
|
||||
this.color_map = null;
|
||||
this.reserved = null;
|
||||
this.planes = null;
|
||||
this.bytes_per_line = null;
|
||||
this.information = null;
|
||||
this.filler = null;
|
||||
this.data = null;
|
||||
this.ok = null;
|
||||
this.palette = null;
|
||||
|
||||
const constructor = () => {
|
||||
|
||||
Object.entries(Tools.load_binary(pcx, [
|
||||
["id", "integer", 1],
|
||||
["version", "integer", 1],
|
||||
["encoding", "integer", 1],
|
||||
["bit", "integer", 1],
|
||||
["x", "integer", 2],
|
||||
["y", "integer", 2],
|
||||
["width", "integer", 2],
|
||||
["height", "integer", 2],
|
||||
["horizontal", "integer", 2],
|
||||
["vertical", "integer", 2],
|
||||
["color_map", (bytes, _) => bytes.reduce((map, byte, j) => {
|
||||
|
||||
const k = j / 3 >> 0;
|
||||
|
||||
(map[k] || (map[k] = []))[j % 3] = byte;
|
||||
|
||||
return map;
|
||||
}), 48],
|
||||
["reserved", "integer", 1],
|
||||
["planes", "integer", 1],
|
||||
["bytes_per_line", "integer", 2],
|
||||
["information", "integer", 2],
|
||||
["filler", "bytes", 58],
|
||||
["data", "bytes", object => pcx.length - 128 - palette_size - (palette_size ? 1 : 0)],
|
||||
["ok", (bytes, _) => !bytes.length || bytes[0] == 12, palette_size ? 1 : 0],
|
||||
["palette", "bytes", palette_size]
|
||||
])).forEach(([key, value]) => {
|
||||
self[key] = value;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
constructor();
|
||||
|
||||
};
|
||||
|
||||
return SFFPCXModel;
|
||||
})();
|
||||
|
||||
export const SFFv1ImageModel = (function(){
|
||||
|
||||
const SFFv1ImageModel = function(version, data){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.next = null;
|
||||
this.length = null;
|
||||
this.x = null;
|
||||
this.y = null;
|
||||
this.group = null;
|
||||
this.i = null;
|
||||
this.shared_flag = null;
|
||||
this.comments = null;
|
||||
this.image = null;
|
||||
|
||||
const constructor = () => {
|
||||
|
||||
Object.entries(Tools.load_binary(data, [
|
||||
["next", "integer", 4],
|
||||
["length", "integer", 4],
|
||||
["x", "integer", 2],
|
||||
["y", "integer", 2],
|
||||
["group", "integer", 2],
|
||||
["i", "integer", 2],
|
||||
["shared_flag", "boolean", 1],
|
||||
["comments", "string", 15],
|
||||
["image", "bytes", object => object.length]
|
||||
])).forEach(([key, value]) => {
|
||||
if(key == "image"){
|
||||
self[key] = new SFFPCXModel(value, self.shared_flag ? 0 : 768);
|
||||
}else
|
||||
self[key] = value;
|
||||
});
|
||||
|
||||
};
|
||||
|
||||
constructor();
|
||||
|
||||
};
|
||||
|
||||
return SFFv1ImageModel;
|
||||
})();
|
||||
|
||||
export const SFFv1Model = (function(){
|
||||
|
||||
const SFFv1Model = function(sff, callback = null){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.signature = "";
|
||||
this.version = [];
|
||||
this.groups = {};
|
||||
this.images = [];
|
||||
this.next = null;
|
||||
this.offset_palette = null;
|
||||
this.shared_palette = null;
|
||||
this.comments = "";
|
||||
|
||||
const constructor = () => {
|
||||
|
||||
let images_l,
|
||||
groups_l,
|
||||
offset;
|
||||
|
||||
Object.entries(Tools.load_binary(sff, [
|
||||
["signature", "string", 12],
|
||||
["version", "bytes", 4],
|
||||
["groups", "integer", 4],
|
||||
["images", "integer", 4],
|
||||
["next", "integer", 4],
|
||||
["offset_palette", "integer", 4],
|
||||
["shared_palette", "boolean", 4],
|
||||
["comments", "string", object => object.next - 36]
|
||||
])).forEach(([key, value]) => {
|
||||
if(key == "images")
|
||||
images_l = value;
|
||||
else if(key == "groups")
|
||||
groups_l = value;
|
||||
else
|
||||
self[key] = value;
|
||||
});
|
||||
|
||||
offset = self.next;
|
||||
|
||||
while(self.images.length < images_l){
|
||||
|
||||
const image = new SFFImageModel(self.version, sff.slice(offset));
|
||||
|
||||
self.images.push(image);
|
||||
offset = image.next;
|
||||
|
||||
};
|
||||
|
||||
Common.execute(callback, self);
|
||||
|
||||
};
|
||||
|
||||
constructor();
|
||||
|
||||
};
|
||||
|
||||
return SFFv1Model;
|
||||
})();
|
||||
153
Public/ecma/Models/SFFv2Model.ecma.js
Normal file
153
Public/ecma/Models/SFFv2Model.ecma.js
Normal file
@ -0,0 +1,153 @@
|
||||
"use strict";
|
||||
|
||||
import {Common} from "http://localhost:18000/Public/ecma/Utils/Common.ecma.js";
|
||||
import {Tools} from "../Utils/Tools.ecma.js";
|
||||
|
||||
export const SFFv2PaletteModel = (function(){
|
||||
|
||||
const SFFv2PaletteModel = function(data, sff){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.group = null;
|
||||
this.item = null;
|
||||
this.columns = null;
|
||||
this.link = null;
|
||||
this.data_offset = null;
|
||||
this.data_length = null;
|
||||
this.palette = null;
|
||||
|
||||
const constructor = () => {
|
||||
|
||||
Object.entries(Tools.load_binary(data, [
|
||||
["group", "integer", 2],
|
||||
["item", "integer", 2],
|
||||
["columns", "integer", 2],
|
||||
["link", "integer", 2],
|
||||
["data_offset", "integer", 4],
|
||||
["data_length", "integer", 4]
|
||||
])).forEach(([key, value]) => {
|
||||
self[key] = value;
|
||||
});
|
||||
|
||||
if(self.data_length > 0)
|
||||
self.palette = sff.slice(self.data_offset, self.data_offset + self.data_length);
|
||||
|
||||
};
|
||||
|
||||
constructor();
|
||||
};
|
||||
|
||||
return SFFv2PaletteModel;
|
||||
})();
|
||||
|
||||
export const SFFv2SpriteModel = (function(){
|
||||
|
||||
const SFFv2SpriteModel = function(data, sff){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.group = null;
|
||||
this.item = null;
|
||||
this.width = null;
|
||||
this.height = null;
|
||||
this.x = null;
|
||||
this.y = null;
|
||||
this.link = null;
|
||||
this.format = null;
|
||||
this.depth = null;
|
||||
this.data_offset = null;
|
||||
this.data_length = null;
|
||||
this.palette_index = null;
|
||||
this.flags = null;
|
||||
this.data = null;
|
||||
|
||||
const constructor = () => {
|
||||
|
||||
Object.entries(Tools.load_binary(data, [
|
||||
["group", "integer", 2],
|
||||
["item", "integer", 2],
|
||||
["width", "integer", 2],
|
||||
["height", "integer", 2],
|
||||
["x", "integer", 2],
|
||||
["y", "integer", 2],
|
||||
["link", "integer", 2],
|
||||
["format", "integer", 1],
|
||||
["depth", "integer", 1],
|
||||
["data_offset", "integer", 4],
|
||||
["data_length", "integer", 4],
|
||||
["palette_index", "integer", 2],
|
||||
["flags", "integer", 2]
|
||||
])).forEach(([key, value]) => {
|
||||
self[key] = value;
|
||||
});
|
||||
|
||||
if(self.data_length > 0)
|
||||
self.data = sff.slice(self.data_offset, self.data_offset + self.data_length);
|
||||
|
||||
};
|
||||
|
||||
constructor();
|
||||
};
|
||||
|
||||
return SFFv2SpriteModel;
|
||||
})();
|
||||
|
||||
export const SFFv2Model = (function(){
|
||||
|
||||
const SFFv2Model = function(sff, callback = null){
|
||||
|
||||
const self = this;
|
||||
|
||||
this.signature = "";
|
||||
this.version = [];
|
||||
this.sprites = [];
|
||||
this.palettes = [];
|
||||
this.sprite_offset = null;
|
||||
this.sprite_count = null;
|
||||
this.palette_offset = null;
|
||||
this.palette_count = null;
|
||||
|
||||
const constructor = () => {
|
||||
|
||||
Object.entries(Tools.load_binary(sff.slice(0, 512), [
|
||||
["signature", "string", 12],
|
||||
["version", "bytes", 4],
|
||||
["reserved1", "bytes", 4],
|
||||
["reserved2", "bytes", 4],
|
||||
["compat_ver", "bytes", 4],
|
||||
["reserved3", "bytes", 4],
|
||||
["sprite_offset", "integer", 4],
|
||||
["sprite_count", "integer", 4],
|
||||
["palette_offset", "integer", 4],
|
||||
["palette_count", "integer", 4],
|
||||
["literal_data_offset", "integer", 4],
|
||||
["literal_data_length", "integer", 4],
|
||||
["translated_data_offset", "integer", 4],
|
||||
["translated_data_length", "integer", 4],
|
||||
["filler", "bytes", 448]
|
||||
])).forEach(([key, value]) => {
|
||||
if(self[key] !== undefined)
|
||||
self[key] = value;
|
||||
});
|
||||
|
||||
while(self.sprite_offset < self.sprite_count){
|
||||
self.sprites.push(new SFFv2SpriteModel(sff.slice(self.sprite_offset, self.sprite_offset + 16), sff));
|
||||
self.sprite_offset += 16;
|
||||
};
|
||||
|
||||
while(self.palette_offset < self.palette_count){
|
||||
self.palettes.push(new SFFv2PaletteModel(sff.slice(self.palette_offset, self.palette_offset + 28), sff));
|
||||
self.palette_offset += 28;
|
||||
};
|
||||
|
||||
Common.call(callback, self);
|
||||
|
||||
};
|
||||
|
||||
constructor();
|
||||
|
||||
};
|
||||
|
||||
return SFFv2Model;
|
||||
})();
|
||||
79
Public/ecma/Utils/Tools.ecma.js
Normal file
79
Public/ecma/Utils/Tools.ecma.js
Normal file
@ -0,0 +1,79 @@
|
||||
"use strict";
|
||||
|
||||
import {BinaryStructureModel} from "../Models/BinaryStructureModel.ecma.js";
|
||||
import {Check} from "http://localhost:18000/Public/ecma/Utils/Checks.ecma.js";
|
||||
|
||||
/**
|
||||
* @class Tools
|
||||
* @constructor
|
||||
* @returns {void}
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
export const Tools = (function(){
|
||||
|
||||
/**
|
||||
* @callback load_binary_type_callback
|
||||
* @param {!Uint8Array|Array.<number>} data
|
||||
* @param {!Object.<string, any|null>} object
|
||||
* @returns {any|null}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @callback load_binary_size_callback
|
||||
* @param {!Object.<string, any|null>} object
|
||||
* @returns {any|null}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @constructs Tools
|
||||
* @returns {void}
|
||||
* @access private
|
||||
* @static
|
||||
*/
|
||||
const Tools = function(){};
|
||||
|
||||
/**
|
||||
* @param {!Uint8Array|Array.<number>} data
|
||||
* @param {!Array.<Array.<[string, string|load_binary_type_callback, number|load_binary_size_callback]>>} structure
|
||||
* @returns {Object.<string, any|null>}
|
||||
* @access public
|
||||
* @static
|
||||
*/
|
||||
Tools.load_binary = (data, structure) => {
|
||||
|
||||
/** @type {number} */
|
||||
let i = 0;
|
||||
|
||||
return structure.reduce((object, [name, type, size]) => {
|
||||
|
||||
if(Check.is_function(size))
|
||||
size = size(object);
|
||||
|
||||
if(Check.is_function(type))
|
||||
object[name] = type(data.slice(i, i + size), object);
|
||||
else{
|
||||
|
||||
/** @type {any} */
|
||||
const value = data.slice(i, i + size);
|
||||
|
||||
object[name] = (
|
||||
type == "string" ? String.fromCharCode(...value).replace(/\0/g, "") :
|
||||
type == "integer" ? value.reduce((accurate, byte, j) => accurate | (byte << j * 8), 0) :
|
||||
type == "boolean" ? !!value.reduce((accurate, byte, j) => accurate | (byte << j * 8), 0) :
|
||||
type == "bytes" ? Array.from(value) :
|
||||
value);
|
||||
|
||||
if(type == "integer" && size < 4 && object[name] >> size * 8 - 1)
|
||||
object[name] -= 1 << size * 8;
|
||||
|
||||
};
|
||||
|
||||
i += size;
|
||||
|
||||
return object;
|
||||
}, {});
|
||||
};
|
||||
|
||||
return Tools;
|
||||
})();
|
||||
0
Public/index.html
Normal file
0
Public/index.html
Normal file
Loading…
Reference in New Issue
Block a user