123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548 |
- "use strict";
- var goog = goog || {};
- goog.exportSymbol = function() {};
- goog.exportProperty = function() {};
- var v86util = v86util || {};
- // pad string with spaces on the right
- v86util.pads = function(str, len)
- {
- str = (str || str === 0) ? str + "" : "";
- return str.padEnd(len, " ");
- };
- // pad string with zeros on the left
- v86util.pad0 = function(str, len)
- {
- str = (str || str === 0) ? str + "" : "";
- return str.padStart(len, "0");
- };
- // generates array given size with zeros
- v86util.zeros = function(size)
- {
- return Array(size).fill(0);
- };
- // generates [0, 1, 2, ..., size-1]
- v86util.range = function(size)
- {
- return Array.from(Array(size).keys());
- };
- v86util.view = function(constructor, memory, offset, length)
- {
- return new Proxy({},
- {
- get: function(target, property, receiver)
- {
- const b = new constructor(memory.buffer, offset, length);
- const x = b[property];
- if(typeof x === "function")
- {
- return x.bind(b);
- }
- dbg_assert(/^\d+$/.test(property) || property === "buffer" || property === "length" ||
- property === "BYTES_PER_ELEMENT" || property === "byteOffset");
- return x;
- },
- set: function(target, property, value, receiver)
- {
- dbg_assert(/^\d+$/.test(property));
- new constructor(memory.buffer, offset, length)[property] = value;
- return true;
- },
- });
- };
- /**
- * number to hex
- * @param {number} n
- * @param {number=} len
- * @return {string}
- */
- function h(n, len)
- {
- if(!n)
- {
- var str = "";
- }
- else
- {
- var str = n.toString(16);
- }
- return "0x" + v86util.pad0(str.toUpperCase(), len || 1);
- }
- if(typeof crypto !== "undefined" && crypto.getRandomValues)
- {
- let rand_data = new Int32Array(1);
- v86util.get_rand_int = function()
- {
- crypto.getRandomValues(rand_data);
- return rand_data[0];
- };
- }
- else if(typeof require !== "undefined")
- {
- /** @type {{ randomBytes: Function }} */
- const crypto = require("crypto");
- v86util.get_rand_int = function()
- {
- return crypto.randomBytes(4)["readInt32LE"](0);
- };
- }
- else
- {
- dbg_assert(false, "Unsupported platform: No cryptographic random values");
- }
- /**
- * Synchronous access to ArrayBuffer
- * @constructor
- */
- function SyncBuffer(buffer)
- {
- dbg_assert(buffer instanceof ArrayBuffer);
- this.buffer = buffer;
- this.byteLength = buffer.byteLength;
- this.onload = undefined;
- this.onprogress = undefined;
- }
- SyncBuffer.prototype.load = function()
- {
- this.onload && this.onload({ buffer: this.buffer });
- };
- /**
- * @param {number} start
- * @param {number} len
- * @param {function(!Uint8Array)} fn
- */
- SyncBuffer.prototype.get = function(start, len, fn)
- {
- dbg_assert(start + len <= this.byteLength);
- fn(new Uint8Array(this.buffer, start, len));
- };
- /**
- * @param {number} start
- * @param {!Uint8Array} slice
- * @param {function()} fn
- */
- SyncBuffer.prototype.set = function(start, slice, fn)
- {
- dbg_assert(start + slice.byteLength <= this.byteLength);
- new Uint8Array(this.buffer, start, slice.byteLength).set(slice);
- fn();
- };
- /**
- * @param {function(!ArrayBuffer)} fn
- */
- SyncBuffer.prototype.get_buffer = function(fn)
- {
- fn(this.buffer);
- };
- SyncBuffer.prototype.get_state = function()
- {
- const state = [];
- state[0] = this.byteLength;
- state[1] = new Uint8Array(this.buffer);
- return state;
- };
- SyncBuffer.prototype.set_state = function(state)
- {
- this.byteLength = state[0];
- this.buffer = state[1].slice().buffer;
- };
- (function()
- {
- if(typeof Math.clz32 === "function" && Math.clz32(0) === 32 &&
- Math.clz32(0x12345) === 15 && Math.clz32(-1) === 0)
- {
- /**
- * calculate the integer logarithm base 2 of a byte
- * @param {number} x
- * @return {number}
- */
- v86util.int_log2_byte = function(x)
- {
- dbg_assert(x > 0);
- dbg_assert(x < 0x100);
- return 31 - Math.clz32(x);
- };
- /**
- * calculate the integer logarithm base 2
- * @param {number} x
- * @return {number}
- */
- v86util.int_log2 = function(x)
- {
- dbg_assert(x > 0);
- return 31 - Math.clz32(x);
- };
- return;
- }
- var int_log2_table = new Int8Array(256);
- for(var i = 0, b = -2; i < 256; i++)
- {
- if(!(i & i - 1))
- b++;
- int_log2_table[i] = b;
- }
- /**
- * calculate the integer logarithm base 2 of a byte
- * @param {number} x
- * @return {number}
- */
- v86util.int_log2_byte = function(x)
- {
- dbg_assert(x > 0);
- dbg_assert(x < 0x100);
- return int_log2_table[x];
- };
- /**
- * calculate the integer logarithm base 2
- * @param {number} x
- * @return {number}
- */
- v86util.int_log2 = function(x)
- {
- x >>>= 0;
- dbg_assert(x > 0);
- // http://jsperf.com/integer-log2/6
- var tt = x >>> 16;
- if(tt)
- {
- var t = tt >>> 8;
- if(t)
- {
- return 24 + int_log2_table[t];
- }
- else
- {
- return 16 + int_log2_table[tt];
- }
- }
- else
- {
- var t = x >>> 8;
- if(t)
- {
- return 8 + int_log2_table[t];
- }
- else
- {
- return int_log2_table[x];
- }
- }
- };
- })();
- /**
- * @constructor
- *
- * Queue wrapper around Uint8Array
- * Used by devices such as the PS2 controller
- */
- function ByteQueue(size)
- {
- var data = new Uint8Array(size),
- start,
- end;
- dbg_assert((size & size - 1) === 0);
- this.length = 0;
- this.push = function(item)
- {
- if(this.length === size)
- {
- // intentional overwrite
- }
- else
- {
- this.length++;
- }
- data[end] = item;
- end = end + 1 & size - 1;
- };
- this.shift = function()
- {
- if(!this.length)
- {
- return -1;
- }
- else
- {
- var item = data[start];
- start = start + 1 & size - 1;
- this.length--;
- return item;
- }
- };
- this.peek = function()
- {
- if(!this.length)
- {
- return -1;
- }
- else
- {
- return data[start];
- }
- };
- this.clear = function()
- {
- start = 0;
- end = 0;
- this.length = 0;
- };
- this.clear();
- }
- /**
- * @constructor
- *
- * Queue wrapper around Float32Array
- * Used by devices such as the sound blaster sound card
- */
- function FloatQueue(size)
- {
- this.size = size;
- this.data = new Float32Array(size);
- this.start = 0;
- this.end = 0;
- this.length = 0;
- dbg_assert((size & size - 1) === 0);
- }
- FloatQueue.prototype.push = function(item)
- {
- if(this.length === this.size)
- {
- // intentional overwrite
- this.start = this.start + 1 & this.size - 1;
- }
- else
- {
- this.length++;
- }
- this.data[this.end] = item;
- this.end = this.end + 1 & this.size - 1;
- };
- FloatQueue.prototype.shift = function()
- {
- if(!this.length)
- {
- return undefined;
- }
- else
- {
- var item = this.data[this.start];
- this.start = this.start + 1 & this.size - 1;
- this.length--;
- return item;
- }
- };
- FloatQueue.prototype.shift_block = function(count)
- {
- var slice = new Float32Array(count);
- if(count > this.length)
- {
- count = this.length;
- }
- var slice_end = this.start + count;
- var partial = this.data.subarray(this.start, slice_end);
- slice.set(partial);
- if(slice_end >= this.size)
- {
- slice_end -= this.size;
- slice.set(this.data.subarray(0, slice_end), partial.length);
- }
- this.start = slice_end;
- this.length -= count;
- return slice;
- };
- FloatQueue.prototype.peek = function()
- {
- if(!this.length)
- {
- return undefined;
- }
- else
- {
- return this.data[this.start];
- }
- };
- FloatQueue.prototype.clear = function()
- {
- this.start = 0;
- this.end = 0;
- this.length = 0;
- };
- /**
- * Simple circular queue for logs
- *
- * @param {number} size
- * @constructor
- */
- function CircularQueue(size)
- {
- this.data = [];
- this.index = 0;
- this.size = size;
- }
- CircularQueue.prototype.add = function(item)
- {
- this.data[this.index] = item;
- this.index = (this.index + 1) % this.size;
- };
- CircularQueue.prototype.toArray = function()
- {
- return [].slice.call(this.data, this.index).concat([].slice.call(this.data, 0, this.index));
- };
- CircularQueue.prototype.clear = function()
- {
- this.data = [];
- this.index = 0;
- };
- /**
- * @param {Array} new_data
- */
- CircularQueue.prototype.set = function(new_data)
- {
- this.data = new_data;
- this.index = 0;
- };
- function dump_file(ab, name)
- {
- if(!(ab instanceof Array))
- {
- ab = [ab];
- }
- var blob = new Blob(ab);
- download(blob, name);
- }
- function download(file_or_blob, name)
- {
- var a = document.createElement("a");
- a["download"] = name;
- a.href = window.URL.createObjectURL(file_or_blob);
- a.dataset["downloadurl"] = ["application/octet-stream", a["download"], a.href].join(":");
- if(document.createEvent)
- {
- var ev = document.createEvent("MouseEvent");
- ev.initMouseEvent("click", true, true, window,
- 0, 0, 0, 0, 0, false, false, false, false, 0, null);
- a.dispatchEvent(ev);
- }
- else
- {
- a.click();
- }
- window.URL.revokeObjectURL(a.href);
- }
- /**
- * A simple 1d bitmap
- * @constructor
- */
- v86util.Bitmap = function(length_or_buffer)
- {
- if(typeof length_or_buffer === "number")
- {
- this.view = new Uint8Array(length_or_buffer + 7 >> 3);
- }
- else if(length_or_buffer instanceof ArrayBuffer)
- {
- this.view = new Uint8Array(length_or_buffer);
- }
- else
- {
- console.assert(false);
- }
- };
- v86util.Bitmap.prototype.set = function(index, value)
- {
- const bit_index = index & 7;
- const byte_index = index >> 3;
- const bit_mask = 1 << bit_index;
- this.view[byte_index] =
- value ? this.view[byte_index] | bit_mask : this.view[byte_index] & ~bit_mask;
- };
- v86util.Bitmap.prototype.get = function(index)
- {
- const bit_index = index & 7;
- const byte_index = index >> 3;
- return this.view[byte_index] >> bit_index & 1;
- };
- v86util.Bitmap.prototype.get_buffer = function()
- {
- return this.view.buffer;
- };
|