mirror of
https://github.com/libretro/libretro-puzzlescript.git
synced 2026-11-08 02:58:17 -10:00
Add js code to move level up and down in a sensible way. Update readme a bit.
167 lines
4.5 KiB
JavaScript
167 lines
4.5 KiB
JavaScript
|
|
compile(["restart"], sourceCode);
|
|
|
|
var simulator_time = -1;
|
|
|
|
function gotoLevel(n) {
|
|
if (n < 0) {
|
|
return;
|
|
}
|
|
if (n >= state.levels.length ) {
|
|
return;
|
|
}
|
|
curlevel = n;
|
|
loadLevelFromState(state, curlevel);
|
|
storage_set(document.URL, curlevel);
|
|
storage_remove(document.URL + "_checkpoint");
|
|
canvasResize();
|
|
redraw();
|
|
}
|
|
|
|
main = function() {
|
|
var evt = native_get_event();
|
|
while (evt.key !== 0) {
|
|
if (evt.key === 78 /* N */) {
|
|
gotoLevel(curlevel + 1);
|
|
evt = native_get_event();
|
|
continue;
|
|
}
|
|
if (evt.key === 80 /* P */) {
|
|
gotoLevel(curlevel - 1);
|
|
evt = native_get_event();
|
|
continue;
|
|
}
|
|
if (evt.isPress) {
|
|
onKeyDown({keyCode: evt.key});
|
|
} else {
|
|
onKeyUp({keyCode: evt.key});
|
|
}
|
|
evt = native_get_event();
|
|
}
|
|
if (simulator_time === -1) {
|
|
simulator_time = native_time_elapsed();
|
|
} else {
|
|
let new_time = native_time_elapsed();
|
|
let delta = simulator_time + deltatime - new_time;
|
|
if (delta > 0) {
|
|
native_sleep(delta / 1000.0);
|
|
update();
|
|
} else {
|
|
// Print underrun if we are very late
|
|
if (-delta > deltatime*2) {
|
|
print('UNDERRUN of ' + -delta + 'ms');
|
|
simulator_time += -delta - deltatime;
|
|
}
|
|
update();
|
|
}
|
|
simulator_time += deltatime;
|
|
}
|
|
}
|
|
|
|
function buf2hex(buffer) {
|
|
// Function to hex encode an Int32Array
|
|
if (buffer.length === 0) {
|
|
return "";
|
|
}
|
|
// Handle negatives
|
|
const buffer2 = new Uint32Array(buffer.buffer);
|
|
return [...buffer2]
|
|
.map(x => x.toString(16).padStart(8, '0'))
|
|
.join('');
|
|
}
|
|
|
|
function hex2buf(value) {
|
|
if (value === "") {
|
|
return new Int32Array(0);
|
|
}
|
|
return new Int32Array(value.match(/[\da-f]{8}/gi).map(function (h) {
|
|
return parseInt(h, 16);
|
|
}));
|
|
}
|
|
|
|
const serialize_keys = [
|
|
'curlevel',
|
|
'restartTarget',
|
|
'backups',
|
|
'titleScreen',
|
|
'randomseed',
|
|
'oldflickscreendat',
|
|
];
|
|
|
|
serialize = function() {
|
|
// JSON stringify can take a function that replaces things as they are encountered
|
|
function replacer(key, value) {
|
|
if (value instanceof Int32Array) {
|
|
return {
|
|
type:'Int32Array',
|
|
value:buf2hex(value),
|
|
};
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
// Collect various things together into one serializable state
|
|
// Include current state of level by calling backupLevel()
|
|
const dstate = {
|
|
bak:backupLevel()
|
|
};
|
|
// Add in various global variables
|
|
for (let i = 0; i < serialize_keys.length; i++) {
|
|
const key = serialize_keys[i];
|
|
dstate[key] = globalThis[key];
|
|
}
|
|
// If option is set to include backups, then include them
|
|
if (globalThis._serialize_truncate_backups) {
|
|
dstate.backups = [];
|
|
}
|
|
// Keep track of local storage
|
|
dstate['localstorage'] = storage_get(document.URL);
|
|
dstate['localstorage_checkpoint'] = storage_get(document.URL + '_checkpoint');
|
|
return JSON.stringify(dstate, replacer);
|
|
}
|
|
|
|
function string_of_array(arr) {
|
|
let result = '';
|
|
for (let i = 0; i < arr.length; i++) {
|
|
if (i > 0) {
|
|
result += ' ';
|
|
}
|
|
result += arr[i];
|
|
}
|
|
return result;
|
|
}
|
|
|
|
deserialize = function(data) {
|
|
// JSON parsing takes a reviver function that reverses replacer function
|
|
function reviver(key, value) {
|
|
if (value && value.type && value.type === 'Int32Array') {
|
|
return hex2buf(value.value);
|
|
} else {
|
|
return value;
|
|
}
|
|
}
|
|
const dstate = JSON.parse(data, reviver);
|
|
// Set localstorage
|
|
storage_set(document.URL, dstate['localstorage']);
|
|
storage_set(document.URL + '_checkpoint', dstate['localstorage_checkpoint']);
|
|
// Add in various global variables
|
|
for (let i = 0; i < serialize_keys.length; i++) {
|
|
const key = serialize_keys[i];
|
|
globalThis[key] = dstate[key];
|
|
}
|
|
loadLevelFromState(state, dstate.curlevel);
|
|
// loadLevelFromState resets restartTarget and backups, so get them again
|
|
restartTarget = dstate.restartTarget;
|
|
backups = dstate.backups;
|
|
if (dstate.bak.dat.length > 0) {
|
|
addUndoState(dstate.bak);
|
|
DoUndo(/*force=*/true, /*ignoreDuplicates=*/false);
|
|
}
|
|
if (dstate.titleScreen) {
|
|
goToTitleScreen();
|
|
}
|
|
canvasResize();
|
|
regenSpriteImages();
|
|
redraw();
|
|
}
|