Files
Nathan Whitehead 0a3a0b087f Split out partial sprite rendering, add bindings into JavaScript.
Update PuzzleScriptPlus graphics source to allow custom font to work.
Only clear all sprite context when in PuzzleScript mode.
Use PuzzleScriptPlus mode on pzp files.
Make custom font off by default.
2022-09-25 21:50:21 -06:00

277 lines
8.5 KiB
JavaScript

// navigator
Object.setAttribute = function() {}
var navigator = {}
navigator.userAgent={}
navigator.userAgent.match = function(version) {
return 'version number';
}
navigator.vendor={};
navigator.platform={};
// window
var console = {};
console.log = function(t){
print(t);
};
var consoleCacheDump = function() {}
var window = {};
var setInterval = window.setInterval = function (updateFunc, deltaTime) {}
window.addEventListener = function(type, listener, useCapture) {};
var setTimeout = window.setTimeout = function (updateFunc, deltaTime) {}
window.console = console;
var localStorage = {};
localStorage.removeItem = function (item) {
delete this[item];
}
localStorage.setItem = function(key, value) {
this[key] = value;
}
localStorage.getItem = function(key) {
return this[key] ? this[key] : null;
}
localStorage.serialize = function() {
var data = '';
for(var key in this){
if(typeof this[key] !== 'function' && typeof this[key] !== 'undefined')
{
data += 'localStorage.' + key + '=' + this[key] + ';\n';
}
}
return data;
}
window.localStorage = localStorage;
// document
var HTMLCanvasElement = {};
HTMLCanvasElement.prototype = {};
var document={};
function objToString (obj) {
var str = '';
for (var p in obj) {
if (obj.hasOwnProperty(p)) {
str += p + '::' + obj[p] + '\n';
}
}
return str;
}
function createEvent(keyCode) {
return {keyCode: keyCode};
}
function createContext(width, height) {
var context = {};
context.fillStyle="#000000";
// create a new context in C++ and get it's id
context.nativeId = native_sprite_add(width, height);
context.clearRect = function(x, y, w, h){
// #d8d468 corresponds to RGB565 value 0xDEAD
if (!use_puzzlescript_plus) {
// Always clear entire surface of this context to work around a text rendering bug
// Problem is when switching from graphics to text mode, then rendering new letters in title screen
// Only erases new area, can leave larger old data around
// Even clear beyond starting size, as size may have increased due to sprite resize
// Special value -1, -1 means current width, height
native_fill_rect(this.nativeId, "#d8d468", x, y, -1, -1);
} else {
// PuzzleScriptPlus needs accurate clearing
native_fill_rect(this.nativeId, "#d8d468", x, y, w, h);
}
};
context.fillRect = function(x, y, w, h){
native_fill_rect(this.nativeId, this.fillStyle, x, y, w, h);
};
context.drawImage = function(img, x, y, swidth, sheight, dx, dy, dwidth, dheight){
if (swidth !== undefined && swidth !== 0) {
native_sprite_draw_partial(this.nativeId, img.context.nativeId, x, y, swidth, sheight, dx, dy, dwidth, dheight);
} else {
native_sprite_draw(this.nativeId, img.context.nativeId, x, y);
}
};
return context;
}
function createCanvas(width, height){
var canvas = {};
canvas.width = width;
canvas.height = height;
canvas.context = createContext(width, height);
canvas.getContext = function(contextType){return this.context;};
// Get display width and height from C++ side
canvas.parentNode = {};
canvas.parentNode.clientWidth = native_get_width();
canvas.parentNode.clientHeight = native_get_height();
canvas.addEventListener = function() {}
return canvas;
}
document.getElementById = function(id){
if(id === 'separator') {
return null;
} else {
return createCanvas(native_get_width(), native_get_height());
}
}
document.getElementsByTagName = function(tagName) {
var res = [];
return res;
}
document.createElement = function(tagName, options) {
return createCanvas(cellwidth, cellheight);
}
document.addEventListener = function(type, listener, useCapture) {};
document.body = {};
document.body.style = {};
document.body.style.backgroundColor = '#000000';
document.URL = 'PuzzleScriptGame';
// CodeMirror
var CodeMirror = {};
CodeMirror.defaults = {mode:''};
window.CodeMirror = CodeMirror;
// MODE DEFINITION AND QUERYING
// Known modes, by name and by MIME
var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
// Extra arguments are stored as the mode's dependencies, which is
// used by (legacy) mechanisms like loadmode.js to automatically
// load a mode. (Preferred mechanism is the require/define calls.)
CodeMirror.defineMode = function(name, mode) {
if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
if (arguments.length > 2) {
mode.dependencies = [];
for (var i = 2; i < arguments.length; ++i) mode.dependencies.push(arguments[i]);
}
modes[name] = mode;
};
CodeMirror.defineMIME = function(mime, spec) {
mimeModes[mime] = spec;
};
// STRING STREAM
// Fed to the mode parsers, provides helper functions to make
// parsers more succinct.
var StringStream = CodeMirror.StringStream = function(string, tabSize) {
this.pos = this.start = 0;
this.string = string;
this.tabSize = tabSize || 8;
this.lastColumnPos = this.lastColumnValue = 0;
this.lineStart = 0;
};
StringStream.prototype = {
eol: function() {return this.pos >= this.string.length;},
sol: function() {return this.pos == this.lineStart;},
peek: function() {return this.string.charAt(this.pos) || undefined;},
next: function() {
if (this.pos < this.string.length)
return this.string.charAt(this.pos++);
},
eat: function(match) {
var ch = this.string.charAt(this.pos);
if (typeof match == "string") var ok = ch == match;
else var ok = ch && (match.test ? match.test(ch) : match(ch));
if (ok) {++this.pos; return ch;}
},
eatWhile: function(match) {
var start = this.pos;
while (this.eat(match)){}
return this.pos > start;
},
eatSpace: function() {
var start = this.pos;
while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
return this.pos > start;
},
skipToEnd: function() {this.pos = this.string.length;},
skipTo: function(ch) {
var found = this.string.indexOf(ch, this.pos);
if (found > -1) {this.pos = found; return true;}
},
backUp: function(n) {this.pos -= n;},
column: function() {
if (this.lastColumnPos < this.start) {
this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
this.lastColumnPos = this.start;
}
return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
indentation: function() {
return countColumn(this.string, null, this.tabSize) -
(this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
},
match: function(pattern, consume, caseInsensitive) {
if (typeof pattern == "string") {
var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
var substr = this.string.substr(this.pos, pattern.length);
if (cased(substr) == cased(pattern)) {
if (consume !== false) this.pos += pattern.length;
return true;
}
} else {
var match = this.string.slice(this.pos).match(pattern);
if (match && match.index > 0) return null;
if (match && consume !== false) this.pos += match[0].length;
return match;
}
},
current: function(){return this.string.slice(this.start, this.pos);},
hideFirstChars: function(n, inner) {
this.lineStart += n;
try { return inner(); }
finally { this.lineStart -= n; }
}
};
// PuzzleScriptPlus additions
class Event {}
class CustomEvent {}
document.dispatchEvent = function() {}
// Polyfill Array.includes
if(!Array.prototype.includes){
//or use Object.defineProperty
Array.prototype.includes = function(search){
return !!~this.indexOf(search);
}
}
if(!Array.prototype.indexOf){
Array.prototype.indexOf = (function(Object, max, min){
return function indexOf(member, fromIndex) {
if(this===null||this===undefined)throw TypeError("Array.prototype.indexOf called on null or undefined");
var that = Object(this), Len = that.length >>> 0, i = min(fromIndex | 0, Len);
if (i < 0) i = max(0, Len+i); else if (i >= Len) return -1;
if(member===void 0){ for(; i !== Len; ++i) if(that[i]===void 0 && i in that) return i; // undefined
}else if(member !== member){ for(; i !== Len; ++i) if(that[i] !== that[i]) return i; // NaN
}else for(; i !== Len; ++i) if(that[i] === member) return i; // all else
return -1; // if the value was not found, then return -1
};
})(Object, Math.max, Math.min);
}
// Duktape doesn't seem to have this method
String.prototype.trimRight = function (s) {
if (s == undefined)
s = '\\s';
return this.replace(new RegExp("[" + s + "]*$"), '');
};