Add english version
BIN
www.eng/js/porting/assets/omori_a_button.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
www.eng/js/porting/assets/omori_b_button.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
BIN
www.eng/js/porting/assets/omori_dpad.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
www.eng/js/porting/assets/omori_l_button.png
Normal file
After Width: | Height: | Size: 598 B |
BIN
www.eng/js/porting/assets/omori_r_button.png
Normal file
After Width: | Height: | Size: 644 B |
BIN
www.eng/js/porting/assets/omori_show_button.png
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
www.eng/js/porting/assets/omori_switch_button.png
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
www.eng/js/porting/assets/omori_x_button.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
www.eng/js/porting/assets/omori_y_button.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
715
www.eng/js/porting/compat/CordovaPromiseFS.js
Normal file
|
@ -0,0 +1,715 @@
|
|||
var CordovaPromiseFS =
|
||||
/******/ (function(modules) { // webpackBootstrap
|
||||
/******/ // The module cache
|
||||
/******/ var installedModules = {};
|
||||
/******/
|
||||
/******/ // The require function
|
||||
/******/ function __webpack_require__(moduleId) {
|
||||
/******/
|
||||
/******/ // Check if module is in cache
|
||||
/******/ if(installedModules[moduleId]) {
|
||||
/******/ return installedModules[moduleId].exports;
|
||||
/******/ }
|
||||
/******/ // Create a new module (and put it into the cache)
|
||||
/******/ var module = installedModules[moduleId] = {
|
||||
/******/ i: moduleId,
|
||||
/******/ l: false,
|
||||
/******/ exports: {}
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Execute the module function
|
||||
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
|
||||
/******/
|
||||
/******/ // Flag the module as loaded
|
||||
/******/ module.l = true;
|
||||
/******/
|
||||
/******/ // Return the exports of the module
|
||||
/******/ return module.exports;
|
||||
/******/ }
|
||||
/******/
|
||||
/******/
|
||||
/******/ // expose the modules object (__webpack_modules__)
|
||||
/******/ __webpack_require__.m = modules;
|
||||
/******/
|
||||
/******/ // expose the module cache
|
||||
/******/ __webpack_require__.c = installedModules;
|
||||
/******/
|
||||
/******/ // identity function for calling harmony imports with the correct context
|
||||
/******/ __webpack_require__.i = function(value) { return value; };
|
||||
/******/
|
||||
/******/ // define getter function for harmony exports
|
||||
/******/ __webpack_require__.d = function(exports, name, getter) {
|
||||
/******/ if(!__webpack_require__.o(exports, name)) {
|
||||
/******/ Object.defineProperty(exports, name, {
|
||||
/******/ configurable: false,
|
||||
/******/ enumerable: true,
|
||||
/******/ get: getter
|
||||
/******/ });
|
||||
/******/ }
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // getDefaultExport function for compatibility with non-harmony modules
|
||||
/******/ __webpack_require__.n = function(module) {
|
||||
/******/ var getter = module && module.__esModule ?
|
||||
/******/ function getDefault() { return module['default']; } :
|
||||
/******/ function getModuleExports() { return module; };
|
||||
/******/ __webpack_require__.d(getter, 'a', getter);
|
||||
/******/ return getter;
|
||||
/******/ };
|
||||
/******/
|
||||
/******/ // Object.prototype.hasOwnProperty.call
|
||||
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
|
||||
/******/
|
||||
/******/ // __webpack_public_path__
|
||||
/******/ __webpack_require__.p = "";
|
||||
/******/
|
||||
/******/ // Load entry module and return exports
|
||||
/******/ return __webpack_require__(__webpack_require__.s = 0);
|
||||
/******/ })
|
||||
/************************************************************************/
|
||||
/******/ ([
|
||||
/* 0 */
|
||||
/***/ (function(module, exports) {
|
||||
|
||||
/**
|
||||
* Static Private functions
|
||||
*/
|
||||
|
||||
/* createDir, recursively */
|
||||
function __createDir(rootDirEntry, folders, success,error) {
|
||||
rootDirEntry.getDirectory(folders[0], {create: true}, function(dirEntry) {
|
||||
// Recursively add the new subfolder (if we still have another to create).
|
||||
if (folders.length > 1) {
|
||||
__createDir(dirEntry, folders.slice(1),success,error);
|
||||
} else {
|
||||
success(dirEntry);
|
||||
}
|
||||
}, error);
|
||||
}
|
||||
|
||||
function dirname(str) {
|
||||
str = str.substr(0,str.lastIndexOf('/')+1);
|
||||
if(str[0] === '/') str = str.substr(1);
|
||||
return str;
|
||||
}
|
||||
|
||||
function filename(str) {
|
||||
return str.substr(str.lastIndexOf('/')+1);
|
||||
}
|
||||
|
||||
function normalize(str){
|
||||
str = str || '';
|
||||
if(str[0] === '/') str = str.substr(1);
|
||||
|
||||
var tokens = str.split('/'), last = tokens[0];
|
||||
|
||||
// check tokens for instances of .. and .
|
||||
for(var i=1;i < tokens.length;i++) {
|
||||
last = tokens[i];
|
||||
if (tokens[i] === '..') {
|
||||
// remove the .. and the previous token
|
||||
tokens.splice(i-1,2);
|
||||
// rewind 'cursor' 2 tokens
|
||||
i = i - 2;
|
||||
} else if (tokens[i] === '.') {
|
||||
// remove the .. and the previous token
|
||||
tokens.splice(i,1);
|
||||
// rewind 'cursor' 1 token
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
str = tokens.join('/');
|
||||
if(str === './') {
|
||||
str = '';
|
||||
} else if(last && last.indexOf('.') < 0 && str[str.length - 1] != '/'){
|
||||
str += '/';
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
var transferQueue = [], // queued fileTransfers
|
||||
inprogress = 0; // currently active filetransfers
|
||||
|
||||
/**
|
||||
* Factory function: Create a single instance (based on single FileSystem)
|
||||
*/
|
||||
module.exports = function(options){
|
||||
/* Promise implementation */
|
||||
var Promise = options.Promise || window.Promise;
|
||||
var CDV_INTERNAL_URL_ROOT = 'cdvfile://localhost/'+(options.persistent? 'persistent/':'temporary/');
|
||||
var CDV_URL_ROOT = '';
|
||||
if(!Promise) { throw new Error("No Promise library given in options.Promise"); }
|
||||
|
||||
/* default options */
|
||||
options = options || {};
|
||||
options.crosswalk = !!options.crosswalk;
|
||||
options.persistent = options.persistent !== undefined? options.persistent: true;
|
||||
options.storageSize = options.storageSize || 20*1024*1024;
|
||||
options.concurrency = options.concurrency || 3;
|
||||
options.retry = options.retry || [];
|
||||
options.debug = !!options.debug;
|
||||
|
||||
/* Cordova deviceready promise */
|
||||
var deviceready,
|
||||
isCordova = typeof cordova !== 'undefined' && !options.crosswalk,
|
||||
isCrosswalk = options.crosswalk;
|
||||
if(isCordova){
|
||||
deviceready = new Promise(function(resolve,reject){
|
||||
document.addEventListener("deviceready", resolve, false);
|
||||
setTimeout(function(){ reject(new Error('deviceready has not fired after 5 seconds.')); },5100);
|
||||
});
|
||||
} else if(isCrosswalk) {
|
||||
deviceready = ResolvedPromise(true);
|
||||
} else {
|
||||
/* FileTransfer implementation for Chrome */
|
||||
deviceready = ResolvedPromise(true);
|
||||
if(typeof webkitRequestFileSystem !== 'undefined'){
|
||||
window.requestFileSystem = webkitRequestFileSystem;
|
||||
} else {
|
||||
window.requestFileSystem = function(x,y,z,fail){
|
||||
fail(new Error('requestFileSystem not supported!'));
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// Polyfill Filetransfer
|
||||
if(!isCordova){
|
||||
window.FileTransfer = function FileTransfer(){};
|
||||
FileTransfer.prototype.download = function download(url,file,win,fail) {
|
||||
var xhr = new XMLHttpRequest();
|
||||
xhr.open('GET', url);
|
||||
xhr.responseType = "blob";
|
||||
xhr.onreadystatechange = function(onSuccess, onError, cb) {
|
||||
if (xhr.readyState == 4) {
|
||||
if(xhr.status === 200 && !this._aborted){
|
||||
write(file,xhr.response).then(win,fail);
|
||||
} else {
|
||||
fail(xhr.status);
|
||||
}
|
||||
}
|
||||
};
|
||||
xhr.send();
|
||||
return xhr;
|
||||
};
|
||||
FileTransfer.prototype.abort = function(){
|
||||
this._aborted = true;
|
||||
};
|
||||
window.ProgressEvent = function ProgressEvent(){};
|
||||
window.FileEntry = function FileEntry(){};
|
||||
}
|
||||
|
||||
/* Promise resolve helper */
|
||||
function ResolvedPromise(value){
|
||||
return new Promise(function(resolve){
|
||||
return resolve(value);
|
||||
});
|
||||
}
|
||||
|
||||
/* the filesystem! */
|
||||
var fs = new Promise(function(resolve,reject){
|
||||
deviceready.then(function(){
|
||||
var type = options.persistent? 1: 0;
|
||||
if(options.fileSystem && isCordova){
|
||||
type = options.fileSystem;
|
||||
}
|
||||
// Crosswalk
|
||||
if(isCrosswalk){
|
||||
var system = options.fileSystem || 'cachedir';
|
||||
xwalk.experimental.native_file_system.requestNativeFileSystem(system,resolve,reject);
|
||||
// On chrome, request quota to store persistent files
|
||||
} else if (!isCordova && type === 1 && navigator.webkitPersistentStorage) {
|
||||
navigator.webkitPersistentStorage.requestQuota(options.storageSize, function(grantedBytes) {
|
||||
window.requestFileSystem(type, grantedBytes, resolve, reject);
|
||||
}, reject);
|
||||
|
||||
// Exotic Cordova Directories (options.fileSystem = string)
|
||||
} else if(isNaN(type)) {
|
||||
window.resolveLocalFileSystemURL(type,function(directory){
|
||||
resolve(directory.filesystem);
|
||||
},reject);
|
||||
// Normal browser usage
|
||||
} else {
|
||||
window.requestFileSystem(type, options.storageSize, resolve, reject);
|
||||
}
|
||||
|
||||
setTimeout(function(){ reject(new Error('Could not retrieve FileSystem after 5 seconds.')); },5100);
|
||||
},reject);
|
||||
});
|
||||
|
||||
/* debug */
|
||||
fs.then(function(fs){
|
||||
CDV_URL_ROOT = fs.root.toURL();
|
||||
CDV_INTERNAL_URL_ROOT = isCordova? fs.root.toInternalURL(): CDV_URL_ROOT;
|
||||
window.__fs = fs;
|
||||
},function(err){
|
||||
console.error('Could not get Cordova FileSystem:',err);
|
||||
});
|
||||
|
||||
/* ensure directory exists */
|
||||
function ensure(folders) {
|
||||
return new Promise(function(resolve,reject){
|
||||
return fs.then(function(fs){
|
||||
if(!folders) {
|
||||
resolve(fs.root);
|
||||
} else {
|
||||
folders = folders.split('/').filter(function(folder) {
|
||||
return folder && folder.length > 0 && folder !== '.' && folder !== '..';
|
||||
});
|
||||
__createDir(fs.root,folders,resolve,reject);
|
||||
}
|
||||
},reject);
|
||||
});
|
||||
}
|
||||
|
||||
/* get file file */
|
||||
function file(path,options){
|
||||
return new Promise(function(resolve,reject){
|
||||
if(typeof path === 'object') {
|
||||
return resolve(path);
|
||||
}
|
||||
path = normalize(path);
|
||||
options = options || {};
|
||||
return fs.then(function(fs){
|
||||
fs.root.getFile(path,options,resolve,reject);
|
||||
},reject);
|
||||
});
|
||||
}
|
||||
|
||||
/* get directory entry */
|
||||
function dir(path,options){
|
||||
path = normalize(path);
|
||||
options = options || {};
|
||||
return new Promise(function(resolve,reject){
|
||||
return fs.then(function(fs){
|
||||
if(!path || path === '/') {
|
||||
resolve(fs.root);
|
||||
} else {
|
||||
fs.root.getDirectory(path,options,resolve,reject);
|
||||
}
|
||||
},reject);
|
||||
});
|
||||
}
|
||||
|
||||
/* list contents of a directory */
|
||||
function list(path,mode) {
|
||||
mode = mode || '';
|
||||
var recursive = mode.indexOf('r') > -1;
|
||||
var getAsEntries = mode.indexOf('e') > -1;
|
||||
var onlyFiles = mode.indexOf('f') > -1;
|
||||
var onlyDirs = mode.indexOf('d') > -1;
|
||||
if(onlyFiles && onlyDirs) {
|
||||
onlyFiles = false;
|
||||
onlyDirs = false;
|
||||
}
|
||||
|
||||
return dir(path)
|
||||
.then(function(dirEntry){
|
||||
return new Promise(function(resolve, reject){
|
||||
var entries = [];
|
||||
var dirReader = dirEntry.createReader();
|
||||
var fetchEntries = function(){
|
||||
dirReader.readEntries(function(newEntries){
|
||||
if(newEntries.length === 0) {
|
||||
resolve(entries);
|
||||
} else {
|
||||
var args = [0,0].concat(newEntries);
|
||||
entries.splice.apply(entries,args);
|
||||
fetchEntries();
|
||||
}
|
||||
});
|
||||
}
|
||||
fetchEntries();
|
||||
});
|
||||
})
|
||||
.then(function(entries){
|
||||
var promises = [ResolvedPromise(entries)];
|
||||
if(recursive) {
|
||||
entries
|
||||
.filter(function(entry){return entry.isDirectory; })
|
||||
.forEach(function(entry){
|
||||
promises.push(list(entry.fullPath,'re'));
|
||||
});
|
||||
}
|
||||
return Promise.all(promises);
|
||||
})
|
||||
.then(function(values){
|
||||
var entries = [];
|
||||
entries = entries.concat.apply(entries,values);
|
||||
if(onlyFiles) entries = entries.filter(function(entry) { return entry.isFile; });
|
||||
if(onlyDirs) entries = entries.filter(function(entry) { return entry.isDirectory; });
|
||||
if(!getAsEntries) entries = entries.map(function(entry) { return entry.fullPath; });
|
||||
return entries;
|
||||
});
|
||||
}
|
||||
|
||||
/* does file exist? If so, resolve with fileEntry, if not, resolve with false. */
|
||||
function exists(path){
|
||||
return new Promise(function(resolve,reject){
|
||||
file(path).then(
|
||||
function(fileEntry){
|
||||
resolve(fileEntry);
|
||||
},
|
||||
function(err){
|
||||
if(err.code === 1) {
|
||||
resolve(false);
|
||||
} else {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/* does dir exist? If so, resolve with fileEntry, if not, resolve with false. */
|
||||
function existsDir(path){
|
||||
return new Promise(function(resolve,reject){
|
||||
dir(path).then(
|
||||
function(dirEntry){
|
||||
resolve(dirEntry);
|
||||
},
|
||||
function(err){
|
||||
if(err.code === 1) {
|
||||
resolve(false);
|
||||
} else {
|
||||
reject(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function create(path){
|
||||
return ensure(dirname(path)).then(function(){
|
||||
return file(path,{create:true});
|
||||
});
|
||||
}
|
||||
|
||||
/* convert path to URL to be used in JS/CSS/HTML */
|
||||
function toURL(path) {
|
||||
return file(path).then(function(fileEntry) {
|
||||
return fileEntry.toURL();
|
||||
});
|
||||
}
|
||||
|
||||
/* convert path to URL to be used in JS/CSS/HTML */
|
||||
var toInternalURL,toInternalURLSync,toURLSync;
|
||||
if(isCordova) {
|
||||
/* synchronous helper to get internal URL. */
|
||||
toInternalURLSync = function(path){
|
||||
path = normalize(path);
|
||||
return path.indexOf('://') < 0? CDV_INTERNAL_URL_ROOT + path: path;
|
||||
};
|
||||
/* synchronous helper to get native URL. */
|
||||
toURLSync = function(path){
|
||||
path = normalize(path);
|
||||
return path.indexOf('://') < 0? CDV_URL_ROOT + path: path;
|
||||
};
|
||||
|
||||
toInternalURL = function(path) {
|
||||
return file(path).then(function(fileEntry) {
|
||||
return fileEntry.toInternalURL();
|
||||
});
|
||||
};
|
||||
} else if(isCrosswalk){
|
||||
var system = options.fileSystem || 'cachedir';
|
||||
/* synchronous helper to get internal URL. */
|
||||
toInternalURLSync = function(path){
|
||||
path = normalize(path);
|
||||
return path.indexOf(system) < 0? '/'+system+'/' + path: path;
|
||||
};
|
||||
toInternalURL = function(path) {
|
||||
return file(path).then(function(fileEntry) {
|
||||
return fileEntry.toURL();
|
||||
});
|
||||
};
|
||||
toURLSync = toInternalURLSync;
|
||||
} else {
|
||||
/* synchronous helper to get internal URL. */
|
||||
toInternalURLSync = function(path){
|
||||
path = normalize(path);
|
||||
return 'filesystem:'+location.origin+(options.persistent? '/persistent/':'/temporary/') + path;
|
||||
};
|
||||
|
||||
toInternalURL = function(path) {
|
||||
return file(path).then(function(fileEntry) {
|
||||
return fileEntry.toURL();
|
||||
});
|
||||
};
|
||||
toURLSync = toInternalURLSync;
|
||||
}
|
||||
|
||||
/* return contents of a file */
|
||||
function read(path,method) {
|
||||
method = method || 'readAsText';
|
||||
return file(path).then(function(fileEntry) {
|
||||
return new Promise(function(resolve,reject){
|
||||
fileEntry.file(function(file){
|
||||
var reader = new FileReader();
|
||||
reader.onloadend = function(){
|
||||
resolve(this.result);
|
||||
};
|
||||
reader[method](file);
|
||||
},reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* convert path to base64 date URI */
|
||||
function toDataURL(path) {
|
||||
return read(path,'readAsDataURL');
|
||||
}
|
||||
|
||||
|
||||
function readJSON(path){
|
||||
return read(path).then(JSON.parse);
|
||||
}
|
||||
|
||||
/* write contents to a file */
|
||||
function write(path,blob,mimeType) {
|
||||
return ensure(dirname(path))
|
||||
.then(function() { return file(path,{create:true}); })
|
||||
.then(function(fileEntry) {
|
||||
return new Promise(function(resolve,reject){
|
||||
fileEntry.createWriter(function(writer){
|
||||
writer.onwriteend = resolve;
|
||||
writer.onerror = reject;
|
||||
if(typeof blob === 'string') {
|
||||
blob = createBlob([blob], mimeType || 'text/plain');
|
||||
} else if(blob instanceof Blob !== true){
|
||||
blob = createBlob([JSON.stringify(blob,null,4)], mimeType || 'application/json');
|
||||
}
|
||||
writer.write(blob);
|
||||
},reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function createBlob(parts, type) {
|
||||
var BlobBuilder,
|
||||
bb;
|
||||
try {
|
||||
return new Blob(parts, {type: type});
|
||||
} catch(e) {
|
||||
BlobBuilder = window.BlobBuilder ||
|
||||
window.WebKitBlobBuilder ||
|
||||
window.MozBlobBuilder ||
|
||||
window.MSBlobBuilder;
|
||||
if(BlobBuilder) {
|
||||
bb = new BlobBuilder();
|
||||
bb.append(parts);
|
||||
return bb.getBlob(type);
|
||||
} else {
|
||||
throw new Error("Unable to create blob");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* move a file */
|
||||
function move(src,dest) {
|
||||
return ensure(dirname(dest))
|
||||
.then(function(dir) {
|
||||
return file(src).then(function(fileEntry){
|
||||
return new Promise(function(resolve,reject){
|
||||
fileEntry.moveTo(dir,filename(dest),resolve,reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* move a dir */
|
||||
function moveDir(src,dest) {
|
||||
src = src.replace(/\/$/, '');
|
||||
dest = dest.replace(/\/$/, '');
|
||||
return ensure(dirname(dest))
|
||||
.then(function(destDir) {
|
||||
return dir(src).then(function(dirEntry){
|
||||
return new Promise(function(resolve,reject){
|
||||
dirEntry.moveTo(destDir,filename(dest),resolve,reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* copy a file */
|
||||
function copy(src,dest) {
|
||||
return ensure(dirname(dest))
|
||||
.then(function(dir) {
|
||||
return file(src).then(function(fileEntry){
|
||||
return new Promise(function(resolve,reject){
|
||||
fileEntry.copyTo(dir,filename(dest),resolve,reject);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/* delete a file */
|
||||
function remove(path,mustExist) {
|
||||
var method = mustExist? file:exists;
|
||||
return new Promise(function(resolve,reject){
|
||||
method(path).then(function(fileEntry){
|
||||
if(fileEntry !== false) {
|
||||
fileEntry.remove(resolve,reject);
|
||||
} else {
|
||||
resolve(1);
|
||||
}
|
||||
},reject);
|
||||
}).then(function(val){
|
||||
return val === 1? false: true;
|
||||
});
|
||||
}
|
||||
|
||||
/* delete a directory */
|
||||
function removeDir(path) {
|
||||
return dir(path).then(function(dirEntry){
|
||||
return new Promise(function(resolve,reject) {
|
||||
dirEntry.removeRecursively(resolve,reject);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Whenever we want to start a transfer, we call popTransferQueue
|
||||
function popTransferQueue(){
|
||||
// while we are not at max concurrency
|
||||
while(transferQueue.length > 0 && inprogress < options.concurrency){
|
||||
// increment activity counter
|
||||
inprogress++;
|
||||
|
||||
// fetch filetranfer, method-type (isDownload) and arguments
|
||||
var args = transferQueue.pop();
|
||||
var ft = args.fileTransfer,
|
||||
isDownload = args.isDownload,
|
||||
serverUrl = args.serverUrl,
|
||||
localPath = args.localPath,
|
||||
trustAllHosts = args.trustAllHosts,
|
||||
transferOptions = args.transferOptions,
|
||||
win = args.win,
|
||||
fail = args.fail;
|
||||
|
||||
if(ft._aborted) {
|
||||
inprogress--;
|
||||
} else if(isDownload){
|
||||
ft.download.call(ft,serverUrl,localPath,win,fail,trustAllHosts,transferOptions);
|
||||
if(ft.onprogress) ft.onprogress(new ProgressEvent());
|
||||
} else {
|
||||
ft.upload.call(ft,localPath,serverUrl,win,fail,transferOptions,trustAllHosts);
|
||||
}
|
||||
}
|
||||
// if we are at max concurrency, popTransferQueue() will be called whenever
|
||||
// the transfer is ready and there is space avaialable.
|
||||
}
|
||||
|
||||
// Promise callback to check if there are any more queued transfers
|
||||
function nextTransfer(result){
|
||||
inprogress--; // decrement counter to free up one space to start transfers again!
|
||||
popTransferQueue(); // check if there are any queued transfers
|
||||
return result;
|
||||
}
|
||||
|
||||
function filetransfer(isDownload,serverUrl,localPath,transferOptions,onprogress){
|
||||
if(typeof transferOptions === 'function') {
|
||||
onprogress = transferOptions;
|
||||
transferOptions = {};
|
||||
}
|
||||
if(isCordova && localPath.indexOf('://') < 0) localPath = toURLSync(localPath);
|
||||
|
||||
transferOptions = transferOptions || {};
|
||||
if(!transferOptions.retry || !transferOptions.retry.length) {
|
||||
transferOptions.retry = options.retry;
|
||||
}
|
||||
transferOptions.retry = transferOptions.retry.concat();
|
||||
if(!transferOptions.file && !isDownload){
|
||||
transferOptions.fileName = filename(localPath);
|
||||
}
|
||||
|
||||
var ft = new FileTransfer();
|
||||
onprogress = onprogress || transferOptions.onprogress;
|
||||
if(typeof onprogress === 'function') ft.onprogress = onprogress;
|
||||
var promise = new Promise(function(resolve,reject){
|
||||
var attempt = function(err){
|
||||
if(transferOptions.retry.length === 0) {
|
||||
if(options.debug) console.log('FileTransfer Error: '+serverUrl,err);
|
||||
reject(err);
|
||||
} else {
|
||||
|
||||
var transferJob = {
|
||||
fileTransfer:ft,
|
||||
isDownload:isDownload,
|
||||
serverUrl:serverUrl,
|
||||
localPath:localPath,
|
||||
trustAllHosts:transferOptions.trustAllHosts || false,
|
||||
transferOptions:transferOptions,
|
||||
win:resolve,
|
||||
fail:attempt
|
||||
};
|
||||
transferQueue.unshift(transferJob);
|
||||
var timeout = transferOptions.retry.shift();
|
||||
if(timeout > 0) {
|
||||
setTimeout(nextTransfer,timeout);
|
||||
} else {
|
||||
nextTransfer();
|
||||
}
|
||||
}
|
||||
};
|
||||
transferOptions.retry.unshift(0);
|
||||
inprogress++;
|
||||
attempt();
|
||||
});
|
||||
promise.then(nextTransfer,nextTransfer);
|
||||
promise.progress = function(onprogress){
|
||||
ft.onprogress = onprogress;
|
||||
return promise;
|
||||
};
|
||||
promise.abort = function(){
|
||||
ft._aborted = true;
|
||||
ft.abort();
|
||||
return promise;
|
||||
};
|
||||
return promise;
|
||||
}
|
||||
|
||||
function download(url,dest,options,onprogress){
|
||||
return filetransfer(true,url,dest,options,onprogress);
|
||||
}
|
||||
|
||||
function upload(source,dest,options,onprogress){
|
||||
return filetransfer(false,dest,source,options,onprogress);
|
||||
}
|
||||
|
||||
return {
|
||||
fs: fs,
|
||||
normalize: normalize,
|
||||
file: file,
|
||||
filename: filename,
|
||||
dir: dir,
|
||||
dirname: dirname,
|
||||
create:create,
|
||||
read: read,
|
||||
readJSON: readJSON,
|
||||
write: write,
|
||||
move: move,
|
||||
moveDir: moveDir,
|
||||
copy: copy,
|
||||
remove: remove,
|
||||
removeDir: removeDir,
|
||||
list: list,
|
||||
ensure: ensure,
|
||||
exists: exists,
|
||||
existsDir: existsDir,
|
||||
download: download,
|
||||
upload: upload,
|
||||
toURL:toURL,
|
||||
toURLSync: toURLSync,
|
||||
isCordova:isCordova,
|
||||
toInternalURLSync: toInternalURLSync,
|
||||
toInternalURL:toInternalURL,
|
||||
toDataURL:toDataURL,
|
||||
deviceready: deviceready,
|
||||
options: options,
|
||||
Promise: Promise
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/***/ })
|
||||
/******/ ]);
|
15
www.eng/js/porting/compat/config.js
Normal file
|
@ -0,0 +1,15 @@
|
|||
const ROOT_PATH = ".";
|
||||
|
||||
window.platform = "android";
|
||||
window.process = {
|
||||
env: {},
|
||||
mainModule: {
|
||||
filename: `${ROOT_PATH}/OMORI.exe`
|
||||
}
|
||||
};
|
||||
|
||||
window.process.env = {
|
||||
ROOT_PATH: ROOT_PATH,
|
||||
LOCALAPPDATA: `${ROOT_PATH}/appdata`
|
||||
};
|
||||
|
14079
www.eng/js/porting/compat/corejs.js
Normal file
530
www.eng/js/porting/compat/nwjs.js
Normal file
|
@ -0,0 +1,530 @@
|
|||
"use strict";
|
||||
|
||||
window._MEMO_PATHS = {}
|
||||
|
||||
/**
|
||||
* String.prototype.replaceAll() polyfill
|
||||
* https://gomakethings.com/how-to-replace-a-section-of-a-string-with-another-one-with-vanilla-js/
|
||||
* @author Chris Ferdinandi
|
||||
* @license MIT
|
||||
*/
|
||||
if (!String.prototype.replaceAll) {
|
||||
String.prototype.replaceAll = function(str, newStr){
|
||||
|
||||
// If a regex pattern
|
||||
if (Object.prototype.toString.call(str).toLowerCase() === '[object regexp]') {
|
||||
return this.replace(str, newStr);
|
||||
}
|
||||
|
||||
// If a string
|
||||
return this.replace(new RegExp(str, 'g'), newStr);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
function replaceSpecialSymbols(s) {
|
||||
const memoized = _MEMO_PATHS[s];
|
||||
if (memoized != undefined) {
|
||||
return memoized;
|
||||
}
|
||||
if (s == null || s == undefined) {
|
||||
return s;
|
||||
}
|
||||
try {
|
||||
s = decodeURIComponent(s)
|
||||
} catch (e) {
|
||||
}
|
||||
|
||||
const result = s.replaceAll('!', '_PIDOR_').replaceAll('[', '_SUPER_').replaceAll(']', '_PEDIK_').replaceAll('$', '_SEMENCUM_').replaceAll('%', '_RAZRABI_PIDORASI').replaceAll('(', '_SOSI_').replaceAll(')', '_BEBRA_');
|
||||
_MEMO_PATHS[s] = result;
|
||||
return result
|
||||
}
|
||||
|
||||
function require(libname) {
|
||||
if (!libname.startsWith('/')) {
|
||||
libname = `/${libname}`;
|
||||
}
|
||||
|
||||
if (require.libs[libname] !== undefined) {
|
||||
return require.libs[libname];
|
||||
} else {
|
||||
if (libname[0] !== "/" && require.dirstack.length > 0) {
|
||||
// Solve relative path
|
||||
libname = require.libs.path.join(require.dirstack[require.dirstack.length - 1], libname);
|
||||
}
|
||||
libname = require.libs.path._solve_dots(libname);
|
||||
|
||||
if (require.libs[libname] !== undefined) {
|
||||
// Try to load cached version again, this time using expanded path
|
||||
return require.libs[libname];
|
||||
}
|
||||
|
||||
console.log(`First time load ${libname}`);
|
||||
|
||||
// Try to load the library .js file
|
||||
var dirpath = require.libs.path.dirname(libname);
|
||||
var xhr = new XMLHttpRequest();
|
||||
|
||||
let extended_name = libname.endsWith(".js") ? libname : (libname + ".js");
|
||||
if (libname.startsWith('js-yaml/')) {
|
||||
extended_name = "js/libs/js-yaml-master/lib/" + libname + '.js';
|
||||
}
|
||||
if (extended_name == "lib/js-yaml.js" || extended_name == "js/libs/js-yaml-master.js") {
|
||||
extended_name = "js/libs/js-yaml-master/lib/js-yaml.js";
|
||||
}
|
||||
|
||||
console.log(`extended name = ${extended_name}`);
|
||||
xhr.open("GET", extended_name, false);
|
||||
let status;
|
||||
try {
|
||||
xhr.send();
|
||||
status = xhr.status;
|
||||
} catch (e) {
|
||||
if (e.message.startsWith("Failed to execute 'send'")) {
|
||||
status = 404;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
if (status === 404) {
|
||||
dirpath = libname;
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", require.libs.path.join(libname, "index.js"), false);
|
||||
try {
|
||||
xhr.send();
|
||||
status = xhr.status;
|
||||
} catch (e) {
|
||||
if (e.message.startsWith("Failed to execute 'send'")) {
|
||||
status = 404;
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (status !== 200 && status !== 0) {
|
||||
throw `Couldn't find the ${libname} library`;
|
||||
}
|
||||
|
||||
// Execute the library in a semi-isolated scope
|
||||
require.dirstack.push(dirpath);
|
||||
try {
|
||||
require.libs[libname] = {};
|
||||
(function (text) {
|
||||
// Module scope
|
||||
var module = { exports: {} };
|
||||
eval(text);
|
||||
require.libs[libname] = module.exports;
|
||||
})(xhr.responseText);
|
||||
|
||||
} catch (e) {
|
||||
console.log(`Loading ${libname} failed`);
|
||||
throw e;
|
||||
|
||||
} finally {
|
||||
require.dirstack.pop();
|
||||
}
|
||||
|
||||
return require.libs[libname];
|
||||
}
|
||||
}
|
||||
|
||||
require.dirstack = [process.env.ROOT_PATH];
|
||||
|
||||
class Buffer extends Uint8Array {
|
||||
constructor(arg) {
|
||||
super(arg);
|
||||
}
|
||||
toString() {
|
||||
return new TextDecoder().decode(this);
|
||||
}
|
||||
|
||||
static concat(rest) {
|
||||
if (rest.length == 0)
|
||||
return new Buffer();
|
||||
|
||||
let total = 0;
|
||||
for (let i = 0; i < rest.length; i++) {
|
||||
total += rest[i].length;
|
||||
}
|
||||
let buffer = new Buffer(total);
|
||||
let i = 0;
|
||||
for (let argc = 0; argc < rest.length; argc++) {
|
||||
for (let j = 0; j < rest[argc].length; j++) {
|
||||
buffer[i] = rest[argc][j];
|
||||
i++;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
||||
require.libs = {};
|
||||
|
||||
require.libs.path = {
|
||||
delimiter: "/",
|
||||
|
||||
dirname: function (s) {
|
||||
let delimiter = require.libs["path"].delimiter;
|
||||
|
||||
let arr = s.split(delimiter);
|
||||
let out = arr.slice(0, arr.length - 1);
|
||||
return out.join("/");
|
||||
},
|
||||
|
||||
join: function (...rest) {
|
||||
let delimiter = require.libs["path"].delimiter;
|
||||
|
||||
let path = rest.join(delimiter);
|
||||
let s = "";
|
||||
for (let i = 0; i < path.length; i++) {
|
||||
while (i !== 0 && i < path.length && path[i - 1] === "/" && path[i] === "/")
|
||||
i++;
|
||||
if (i < path.length)
|
||||
s += path[i];
|
||||
}
|
||||
|
||||
return s;
|
||||
},
|
||||
|
||||
extname: function (path) {
|
||||
let arr = path.split(".");
|
||||
return "." + arr[arr.length - 1];
|
||||
},
|
||||
|
||||
basename: function (path, ext) {
|
||||
let delimiter = require.libs["path"].delimiter;
|
||||
|
||||
if (ext !== undefined) {
|
||||
while (ext[0] === ".") {
|
||||
ext = ext.substr(1);
|
||||
}
|
||||
if (path.endsWith("." + ext)) {
|
||||
path = path.substr(0, path.length - ext.length - 1);
|
||||
}
|
||||
}
|
||||
let arr = path.split(delimiter);
|
||||
return arr[arr.length - 1];
|
||||
},
|
||||
|
||||
_solve_dots: function (path) {
|
||||
let delimiter = require.libs["path"].delimiter;
|
||||
|
||||
let arr = path.split(delimiter);
|
||||
let new_arr = [];
|
||||
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
if (arr[i] === "..") {
|
||||
new_arr.pop();
|
||||
} else if (arr[i] === ".") {
|
||||
// Do nothing
|
||||
} else if (arr[i] === "") {
|
||||
// Also do nothing
|
||||
} else {
|
||||
new_arr.push(arr[i]);
|
||||
}
|
||||
}
|
||||
return new_arr.join(delimiter);
|
||||
}
|
||||
};
|
||||
|
||||
function capitalizeImpl(s) {
|
||||
if (s.length == 0) {
|
||||
return ""
|
||||
}
|
||||
return s.charAt(0).toUpperCase() + s.slice(1);
|
||||
}
|
||||
window.ALT_CACHE = {}
|
||||
|
||||
require.libs.fs = {
|
||||
cachedAlternativeName: function (path) {
|
||||
if (path == null || path == undefined) {
|
||||
return path;
|
||||
}
|
||||
if (ALT_CACHE[path] != undefined) {
|
||||
return ALT_CACHE[path];
|
||||
}
|
||||
|
||||
if (require.libs.fs.existsSync(path)) {
|
||||
return path;
|
||||
}
|
||||
|
||||
const alt = require.libs.fs.findAlternativeName(path);
|
||||
ALT_CACHE[path] = alt;
|
||||
return alt;
|
||||
},
|
||||
|
||||
findAlternativeName: function (path) {
|
||||
const dirname = require.libs.path.dirname(path);
|
||||
const basename = require.libs.path.basename(path);
|
||||
|
||||
const listing = require.libs.fs.readdirSync(dirname);
|
||||
for (const listingFile of listing) {
|
||||
if (listingFile.toLowerCase() == basename.toLowerCase()) {
|
||||
const alt = require.libs.path.join(dirname, listingFile);
|
||||
console.log(`tried to access ${path}: not found, found alternative: ${alt}`) //Remove in release
|
||||
return alt;
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`tried to access ${path}: not found, alternative name was not found too!`) //Remove in release
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
readFileSync: function (path, options = {}) {
|
||||
let tmparr = require.libs.path._solve_dots(path).split("/");
|
||||
if (tmparr[tmparr.length - 2] === "save") {
|
||||
console.log("Using NativeFunctions.readSaveFileUTF8");
|
||||
let res = NativeFunctions.readSaveFileUTF8(path);
|
||||
if (res === null || res === undefined) {
|
||||
throw "Server returned status code 404";
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
if (typeof (path) !== "string") {
|
||||
throw "Reading files by file handle not implemented yet";
|
||||
}
|
||||
|
||||
let components = path.split('/');
|
||||
let last_component = components.slice(-1)[0];
|
||||
let without_last_component = components.slice(0, -1).join('/');
|
||||
|
||||
let variants = [
|
||||
`${without_last_component}/${last_component}`,
|
||||
`${without_last_component}/${capitalizeImpl(last_component)}`,
|
||||
`${without_last_component}/${last_component.toLowerCase()}`
|
||||
];
|
||||
let error_stack = [];
|
||||
|
||||
for (let eblan of variants) {
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.overrideMimeType('application/octet-stream; charset=x-user-defined');
|
||||
xhr.open("GET", eblan, false);
|
||||
try {
|
||||
xhr.send();
|
||||
} catch (e) {
|
||||
if (e.message.startsWith("Failed to execute 'send'")) {
|
||||
error_stack.push(`Server returned status code 404 (${path})`);
|
||||
} else {
|
||||
error_stack.push(e);
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
if (xhr.status !== 200 && xhr.status !== 0) {
|
||||
error_stack.push(`Server returned status code ${xhr.status}`);
|
||||
continue;
|
||||
}
|
||||
let res = Uint8Array.from(xhr.response, c => c.charCodeAt(0));
|
||||
if (options.encoding === "utf8" || options.encoding === "utf-8")
|
||||
return (new TextDecoder()).decode(res);
|
||||
return new Buffer(res);
|
||||
}
|
||||
|
||||
console.log(error_stack);
|
||||
throw error_stack[0];
|
||||
},
|
||||
|
||||
writeFileSync: function (path, data) {
|
||||
console.log(path);
|
||||
let tmparr = require.libs.path._solve_dots(path).split("/");
|
||||
if (tmparr[tmparr.length - 2] === "save") {
|
||||
console.log("Using NativeFunctions.writeSaveFileUTF8");
|
||||
return NativeFunctions.writeSaveFileUTF8(path, data);
|
||||
}
|
||||
throw "Cannot write file outside of the save directory";
|
||||
},
|
||||
|
||||
writeFile: function (path, data, callback) {
|
||||
let tmparr = require.libs.path._solve_dots(path).split("/");
|
||||
if (tmparr[tmparr.length - 2] === "save") {
|
||||
console.log("Using NativeFunctions.writeSaveFileUTF8");
|
||||
let res = NativeFunctions.writeSaveFileUTF8(path, data)
|
||||
callback(null);
|
||||
return res;
|
||||
}
|
||||
callback(new Error("Cannot write file outside of the save directory"));
|
||||
},
|
||||
|
||||
readFile: function (path, callback) {
|
||||
if (path.startsWith(".") && !path.startsWith("./")) {
|
||||
path = "./" + path.substr(1);
|
||||
}
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.responseType = "arraybuffer";
|
||||
xhr.open("GET", path, true);
|
||||
xhr.onload = (_event) => {
|
||||
if (xhr.status !== 200 && xhr.status !== 0) {
|
||||
callback(new Error(`Server returned status code ${xhr.status}`));
|
||||
|
||||
} else if (xhr.response) {
|
||||
var buffer = new Buffer(xhr.response);
|
||||
callback(null, buffer);
|
||||
|
||||
} else {
|
||||
callback(new Error("Empty response"));
|
||||
}
|
||||
};
|
||||
xhr.send(null);
|
||||
},
|
||||
|
||||
readdirSync: function (path) {
|
||||
// This whole function is one big hack
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", require("path").join(path, "_DIRECTORY.json"), false);
|
||||
try {
|
||||
xhr.send();
|
||||
} catch (e) {
|
||||
if (e.message.startsWith("Failed to execute 'send'")) {
|
||||
throw new Error(`Server returned status code 404 for file ${path}, either path is invalid or doesn't contain a _DIRECTORY.json file`);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
if (xhr.status === 404) {
|
||||
throw new Error(`Server returned status code 404 for file ${path}, either path is invalid or doesn't contain a _DIRECTORY.json file`);
|
||||
}
|
||||
if (xhr.status !== 200 && xhr.status !== 0) {
|
||||
throw new Error(`Server returned status code ${xhr.status}`);
|
||||
}
|
||||
|
||||
return JSON.parse(xhr.responseText);
|
||||
},
|
||||
|
||||
statSync: function (path) {
|
||||
// TODO: Implement everything besides just "isDirectory"
|
||||
let tmparr = require.libs.path._solve_dots(path).split("/");
|
||||
if (tmparr[tmparr.length - 2] === "save") {
|
||||
return { isDirectory: () => false };
|
||||
}
|
||||
if (tmparr[tmparr.length - 1] === "save") {
|
||||
return { isDirectory: () => true };
|
||||
}
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", require("path").join(path, "_DIRECTORY.json"), false);
|
||||
try {
|
||||
xhr.send();
|
||||
} catch (e) {
|
||||
if (e.message.startsWith("Failed to execute 'send'")) {
|
||||
return { isDirectory: () => false };
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
if (xhr.status === 404) {
|
||||
return { isDirectory: () => false };
|
||||
}
|
||||
return { isDirectory: () => true };
|
||||
},
|
||||
|
||||
existsSync: function (path) {
|
||||
let tmparr = require.libs.path._solve_dots(path).split("/");
|
||||
|
||||
if (tmparr[tmparr.length - 2] === "save") {
|
||||
return NativeFunctions.saveFileExists(`${process.env.ROOT_PATH}/save/` + tmparr[tmparr.length - 1]);
|
||||
}
|
||||
if (tmparr[tmparr.length - 1] === "save") {
|
||||
return true;
|
||||
}
|
||||
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("GET", path, false);
|
||||
try {
|
||||
xhr.send();
|
||||
} catch (e) {
|
||||
if (e.message.startsWith("Failed to execute 'send'")) {
|
||||
return false;
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
return xhr.status === 200 || xhr.status === 0;
|
||||
},
|
||||
|
||||
unlinkSync: function () {
|
||||
// Literally just do nothing
|
||||
}
|
||||
};
|
||||
|
||||
require.libs.os = {
|
||||
platform: () => window.platform
|
||||
};
|
||||
|
||||
const nw_window = {
|
||||
get: () => {
|
||||
return window;
|
||||
},
|
||||
|
||||
focus: () => { },
|
||||
}
|
||||
const nw_impl = {
|
||||
App: {
|
||||
argv: "--"
|
||||
},
|
||||
Window: nw_window,
|
||||
window: nw_window,
|
||||
|
||||
Screen: {
|
||||
Init: function () { },
|
||||
on: function (name, callback) {
|
||||
//console.log("require('nw.gui').Screen.on", name, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
window.nw = nw_impl;
|
||||
require.libs["nw.gui"] = nw_impl;
|
||||
|
||||
window.on = function (...rest) {
|
||||
console.log("on", rest);
|
||||
}
|
||||
|
||||
window.onerror = function (message, source, lineno, colno, error) {
|
||||
if (error === undefined) {
|
||||
console.log(message);
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(error.stack)
|
||||
}
|
||||
|
||||
// var origConsoleLog = console.log;
|
||||
// console.log = function (...rest) {
|
||||
// origConsoleLog(`[LOG] ${String(rest)}`)
|
||||
// //origConsoleLog(...rest);
|
||||
// }
|
||||
|
||||
var setSizesInterval;
|
||||
// setSizesInterval = setInterval(function() {
|
||||
// console.log("Interval fired!");
|
||||
|
||||
// document.getElementById("ErrorPrinter").style["font-size"] = "10px";
|
||||
|
||||
// document.getElementById("GameCanvas").style["width"] = `${Math.floor(window.screen.height * 4 / 3)}px`;
|
||||
// document.getElementById("GameCanvas").style["height"] = `${window.screen.height}px`;
|
||||
// document.getElementById("GameCanvas").style["inset"] = "0px 0px 0px 0px";
|
||||
// document.getElementById("GameCanvas").style["margin"] = "0";
|
||||
// document.getElementById("GameCanvas").style["margin-left"] = "auto";
|
||||
// document.getElementById("GameCanvas").style["margin-right"] = "auto";
|
||||
|
||||
// clearInterval(setSizesInterval);
|
||||
|
||||
// for (let element of document.getElementsByClassName("controler-button")) {
|
||||
// element.style["display"] = "inline";
|
||||
// }
|
||||
// }, 500);
|
||||
|
||||
|
||||
// setTimeout(function() {
|
||||
// console.log("Size is", window.innerWidth, window.innerHeight)
|
||||
// }, 1000);
|
||||
|
||||
function button_down(event_data) {
|
||||
// console.log("In button_down");
|
||||
document.dispatchEvent(new KeyboardEvent("keydown", event_data));
|
||||
}
|
||||
|
||||
function button_up(event_data) {
|
||||
// console.log("In button_up");
|
||||
document.dispatchEvent(new KeyboardEvent("keyup", event_data));
|
||||
}
|
1489
www.eng/js/porting/compat/rpgmaker.js
Normal file
179
www.eng/js/porting/css/controls.css
Normal file
|
@ -0,0 +1,179 @@
|
|||
#joyDiv {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
color: whitesmoke;
|
||||
width: 50vh;
|
||||
height: 50vh;
|
||||
|
||||
z-index: 1488;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.show-gamepad-button {
|
||||
z-index: 1489;
|
||||
position: absolute;
|
||||
right: 3vh;
|
||||
bottom: 3vh;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-image: url('../assets/omori_show_button.png');
|
||||
min-width: 6vh;
|
||||
min-height: 6vh;
|
||||
}
|
||||
|
||||
.switch-button {
|
||||
z-index: 1489;
|
||||
position: absolute;
|
||||
left: 3vh;
|
||||
bottom: 3vh;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-image: url('../assets/omori_switch_button.png');
|
||||
min-width: 6vh;
|
||||
min-height: 6vh;
|
||||
}
|
||||
|
||||
.fps-button {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
top: 5px;
|
||||
width: 90px;
|
||||
height: 40px;
|
||||
z-index: 1489;
|
||||
}
|
||||
|
||||
.gamepad-buttons {
|
||||
opacity: 0.6;
|
||||
z-index: 1488;
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
}
|
||||
|
||||
.gamepad-buttons-row {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
gap: 9vh;
|
||||
}
|
||||
|
||||
.gamepad-button {
|
||||
min-width: 18vh;
|
||||
min-height: 18vh;
|
||||
display: flex;
|
||||
position: relative;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.gamepad-bumper {
|
||||
z-index: 1488;
|
||||
position: absolute;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-width: 18vh;
|
||||
min-height: 12vh;
|
||||
}
|
||||
|
||||
.A {
|
||||
background-image: url('../assets/omori_a_button.png');
|
||||
}
|
||||
|
||||
.B {
|
||||
background-image: url('../assets/omori_b_button.png');
|
||||
top: 4.5vh;
|
||||
}
|
||||
|
||||
.X {
|
||||
background-image: url('../assets/omori_x_button.png');
|
||||
top: 4.5vh;
|
||||
}
|
||||
|
||||
.Y {
|
||||
background-image: url('../assets/omori_y_button.png');
|
||||
top: 9vh;
|
||||
}
|
||||
|
||||
.LB {
|
||||
background-image: url('../assets/omori_l_button.png');
|
||||
opacity: 0.6;
|
||||
left: 16px;
|
||||
bottom: 56vh;
|
||||
}
|
||||
|
||||
.RB {
|
||||
background-image: url('../assets/omori_r_button.png');
|
||||
opacity: 0.6;
|
||||
right: 16px;
|
||||
bottom: 56vh;
|
||||
}
|
||||
|
||||
.dpad-buttons {
|
||||
opacity: 0.6;
|
||||
z-index: 1488;
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
left: 32px;
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
background-image: url('../assets/omori_dpad.png');
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
min-width: 42vh;
|
||||
min-height: 42vh;
|
||||
}
|
||||
|
||||
.dpad-buttons-row {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
}
|
||||
|
||||
.dpad-button {
|
||||
min-width: 12vh;
|
||||
min-height: 12vh;
|
||||
display: flex;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.up {
|
||||
/* background-color: blue; */
|
||||
bottom: 7.5vh;
|
||||
right: 6vh;
|
||||
}
|
||||
|
||||
.left {
|
||||
/* background-color: red; */
|
||||
right: 7.5vh;
|
||||
top: 6vh;
|
||||
}
|
||||
|
||||
.right {
|
||||
/* background-color: green; */
|
||||
left: 7.5vh;
|
||||
bottom: 6vh;
|
||||
}
|
||||
|
||||
.down {
|
||||
/* background-color: yellow; */
|
||||
top: 7.5vh;
|
||||
left: 6vh;
|
||||
}
|
421
www.eng/js/porting/joy.js
Normal file
|
@ -0,0 +1,421 @@
|
|||
/*
|
||||
* Name : joy.js
|
||||
* @author : Roberto D'Amico (Bobboteck)
|
||||
* Last modified : 30.06.2022
|
||||
* Revision : 2.0.0
|
||||
*
|
||||
* Modification History:
|
||||
* Date Version Modified By Description
|
||||
* 2021-12-21 2.0.0 Roberto D'Amico New version of the project that integrates the callback functions, while
|
||||
* maintaining compatibility with previous versions. Fixed Issue #27 too,
|
||||
* thanks to @artisticfox8 for the suggestion.
|
||||
* 2020-06-09 1.1.6 Roberto D'Amico Fixed Issue #10 and #11
|
||||
* 2020-04-20 1.1.5 Roberto D'Amico Correct: Two sticks in a row, thanks to @liamw9534 for the suggestion
|
||||
* 2020-04-03 Roberto D'Amico Correct: InternalRadius when change the size of canvas, thanks to
|
||||
* @vanslipon for the suggestion
|
||||
* 2020-01-07 1.1.4 Roberto D'Amico Close #6 by implementing a new parameter to set the functionality of
|
||||
* auto-return to 0 position
|
||||
* 2019-11-18 1.1.3 Roberto D'Amico Close #5 correct indication of East direction
|
||||
* 2019-11-12 1.1.2 Roberto D'Amico Removed Fix #4 incorrectly introduced and restored operation with touch
|
||||
* devices
|
||||
* 2019-11-12 1.1.1 Roberto D'Amico Fixed Issue #4 - Now JoyStick work in any position in the page, not only
|
||||
* at 0,0
|
||||
*
|
||||
* The MIT License (MIT)
|
||||
*
|
||||
* This file is part of the JoyStick Project (https://github.com/bobboteck/JoyStick).
|
||||
* Copyright (c) 2015 Roberto D'Amico (Bobboteck).
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all
|
||||
* copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
let StickStatus =
|
||||
{
|
||||
xPosition: 0,
|
||||
yPosition: 0,
|
||||
x: 0,
|
||||
y: 0,
|
||||
cardinalDirection: "C"
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc Principal object that draw a joystick, you only need to initialize the object and suggest the HTML container
|
||||
* @costructor
|
||||
* @param container {String} - HTML object that contains the Joystick
|
||||
* @param parameters (optional) - object with following keys:
|
||||
* title {String} (optional) - The ID of canvas (Default value is 'joystick')
|
||||
* width {Int} (optional) - The width of canvas, if not specified is setted at width of container object (Default value is the width of container object)
|
||||
* height {Int} (optional) - The height of canvas, if not specified is setted at height of container object (Default value is the height of container object)
|
||||
* internalFillColor {String} (optional) - Internal color of Stick (Default value is '#00AA00')
|
||||
* internalLineWidth {Int} (optional) - Border width of Stick (Default value is 2)
|
||||
* internalStrokeColor {String}(optional) - Border color of Stick (Default value is '#003300')
|
||||
* externalLineWidth {Int} (optional) - External reference circonference width (Default value is 2)
|
||||
* externalStrokeColor {String} (optional) - External reference circonference color (Default value is '#008000')
|
||||
* autoReturnToCenter {Bool} (optional) - Sets the behavior of the stick, whether or not, it should return to zero position when released (Default value is True and return to zero)
|
||||
* @param callback {StickStatus} -
|
||||
*/
|
||||
var JoyStick = (function(container, parameters, callback)
|
||||
{
|
||||
parameters = parameters || {};
|
||||
var title = (typeof parameters.title === "undefined" ? "joystick" : parameters.title),
|
||||
width = (typeof parameters.width === "undefined" ? 0 : parameters.width),
|
||||
height = (typeof parameters.height === "undefined" ? 0 : parameters.height),
|
||||
internalFillColor = (typeof parameters.internalFillColor === "undefined" ? "#00AA00" : parameters.internalFillColor),
|
||||
internalLineWidth = (typeof parameters.internalLineWidth === "undefined" ? 2 : parameters.internalLineWidth),
|
||||
internalStrokeColor = (typeof parameters.internalStrokeColor === "undefined" ? "#003300" : parameters.internalStrokeColor),
|
||||
externalLineWidth = (typeof parameters.externalLineWidth === "undefined" ? 2 : parameters.externalLineWidth),
|
||||
externalStrokeColor = (typeof parameters.externalStrokeColor === "undefined" ? "#008000" : parameters.externalStrokeColor),
|
||||
autoReturnToCenter = (typeof parameters.autoReturnToCenter === "undefined" ? true : parameters.autoReturnToCenter);
|
||||
|
||||
callback = callback || function(StickStatus) {};
|
||||
|
||||
// Create Canvas element and add it in the Container object
|
||||
var objContainer = document.getElementById(container);
|
||||
|
||||
// Fixing Unable to preventDefault inside passive event listener due to target being treated as passive in Chrome [Thanks to https://github.com/artisticfox8 for this suggestion]
|
||||
objContainer.style.touchAction = "none";
|
||||
|
||||
var canvas = document.createElement("canvas");
|
||||
canvas.id = title;
|
||||
if(width === 0) { width = objContainer.clientWidth; }
|
||||
if(height === 0) { height = objContainer.clientHeight; }
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
objContainer.appendChild(canvas);
|
||||
var context=canvas.getContext("2d");
|
||||
|
||||
var pressed = 0; // Bool - 1=Yes - 0=No
|
||||
var circumference = 2 * Math.PI;
|
||||
var internalRadius = (canvas.width-((canvas.width/2)+10))/2;
|
||||
var maxMoveStick = internalRadius + 5;
|
||||
var externalRadius = internalRadius + 30;
|
||||
var centerX = canvas.width / 2;
|
||||
var centerY = canvas.height / 2;
|
||||
var directionHorizontalLimitPos = canvas.width / 10;
|
||||
var directionHorizontalLimitNeg = directionHorizontalLimitPos * -1;
|
||||
var directionVerticalLimitPos = canvas.height / 10;
|
||||
var directionVerticalLimitNeg = directionVerticalLimitPos * -1;
|
||||
// Used to save current position of stick
|
||||
var movedX=centerX;
|
||||
var movedY=centerY;
|
||||
|
||||
// Check if the device support the touch or not
|
||||
if("ontouchstart" in document.documentElement)
|
||||
{
|
||||
canvas.addEventListener("touchstart", onTouchStart, false);
|
||||
document.addEventListener("touchmove", onTouchMove, false);
|
||||
document.addEventListener("touchend", onTouchEnd, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
canvas.addEventListener("mousedown", onMouseDown, false);
|
||||
document.addEventListener("mousemove", onMouseMove, false);
|
||||
document.addEventListener("mouseup", onMouseUp, false);
|
||||
}
|
||||
// Draw the object
|
||||
drawExternal();
|
||||
drawInternal();
|
||||
|
||||
/******************************************************
|
||||
* Private methods
|
||||
*****************************************************/
|
||||
|
||||
/**
|
||||
* @desc Draw the external circle used as reference position
|
||||
*/
|
||||
function drawExternal()
|
||||
{
|
||||
context.beginPath();
|
||||
context.arc(centerX, centerY, externalRadius, 0, circumference, false);
|
||||
context.lineWidth = externalLineWidth;
|
||||
context.strokeStyle = externalStrokeColor;
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Draw the internal stick in the current position the user have moved it
|
||||
*/
|
||||
function drawInternal()
|
||||
{
|
||||
context.beginPath();
|
||||
if(movedX<internalRadius) { movedX=maxMoveStick; }
|
||||
if((movedX+internalRadius) > canvas.width) { movedX = canvas.width-(maxMoveStick); }
|
||||
if(movedY<internalRadius) { movedY=maxMoveStick; }
|
||||
if((movedY+internalRadius) > canvas.height) { movedY = canvas.height-(maxMoveStick); }
|
||||
context.arc(movedX, movedY, internalRadius, 0, circumference, false);
|
||||
// create radial gradient
|
||||
var grd = context.createRadialGradient(centerX, centerY, 5, centerX, centerY, 200);
|
||||
// Light color
|
||||
grd.addColorStop(0, internalFillColor);
|
||||
// Dark color
|
||||
grd.addColorStop(1, internalStrokeColor);
|
||||
context.fillStyle = grd;
|
||||
context.fill();
|
||||
context.lineWidth = internalLineWidth;
|
||||
context.strokeStyle = internalStrokeColor;
|
||||
context.stroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Events for manage touch
|
||||
*/
|
||||
let touchId = null;
|
||||
function onTouchStart(event)
|
||||
{
|
||||
pressed = 1;
|
||||
touchId = event.targetTouches[0].identifier;
|
||||
}
|
||||
|
||||
function onTouchMove(event)
|
||||
{
|
||||
if(pressed === 1 && event.targetTouches[0].target === canvas)
|
||||
{
|
||||
movedX = event.targetTouches[0].pageX;
|
||||
movedY = event.targetTouches[0].pageY;
|
||||
// Manage offset
|
||||
if(canvas.offsetParent.tagName.toUpperCase() === "BODY")
|
||||
{
|
||||
movedX -= canvas.offsetLeft;
|
||||
movedY -= canvas.offsetTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
movedX -= canvas.offsetParent.offsetLeft;
|
||||
movedY -= canvas.offsetParent.offsetTop;
|
||||
}
|
||||
// Delete canvas
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// Redraw object
|
||||
drawExternal();
|
||||
drawInternal();
|
||||
|
||||
// Set attribute of callback
|
||||
StickStatus.xPosition = movedX;
|
||||
StickStatus.yPosition = movedY;
|
||||
StickStatus.x = (100*((movedX - centerX)/maxMoveStick)).toFixed();
|
||||
StickStatus.y = ((100*((movedY - centerY)/maxMoveStick))*-1).toFixed();
|
||||
StickStatus.cardinalDirection = getCardinalDirection();
|
||||
callback(StickStatus);
|
||||
}
|
||||
}
|
||||
|
||||
function onTouchEnd(event)
|
||||
{
|
||||
if (event.changedTouches[0].identifier !== touchId) return;
|
||||
|
||||
pressed = 0;
|
||||
// If required reset position store variable
|
||||
if(autoReturnToCenter)
|
||||
{
|
||||
movedX = centerX;
|
||||
movedY = centerY;
|
||||
}
|
||||
// Delete canvas
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// Redraw object
|
||||
drawExternal();
|
||||
drawInternal();
|
||||
|
||||
// Set attribute of callback
|
||||
StickStatus.xPosition = movedX;
|
||||
StickStatus.yPosition = movedY;
|
||||
StickStatus.x = (100*((movedX - centerX)/maxMoveStick)).toFixed();
|
||||
StickStatus.y = ((100*((movedY - centerY)/maxMoveStick))*-1).toFixed();
|
||||
StickStatus.cardinalDirection = getCardinalDirection();
|
||||
callback(StickStatus);
|
||||
}
|
||||
|
||||
/**
|
||||
* @desc Events for manage mouse
|
||||
*/
|
||||
function onMouseDown(event)
|
||||
{
|
||||
pressed = 1;
|
||||
}
|
||||
|
||||
/* To simplify this code there was a new experimental feature here: https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/offsetX , but it present only in Mouse case not metod presents in Touch case :-( */
|
||||
function onMouseMove(event)
|
||||
{
|
||||
if(pressed === 1)
|
||||
{
|
||||
movedX = event.pageX;
|
||||
movedY = event.pageY;
|
||||
// Manage offset
|
||||
if(canvas.offsetParent.tagName.toUpperCase() === "BODY")
|
||||
{
|
||||
movedX -= canvas.offsetLeft;
|
||||
movedY -= canvas.offsetTop;
|
||||
}
|
||||
else
|
||||
{
|
||||
movedX -= canvas.offsetParent.offsetLeft;
|
||||
movedY -= canvas.offsetParent.offsetTop;
|
||||
}
|
||||
// Delete canvas
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// Redraw object
|
||||
drawExternal();
|
||||
drawInternal();
|
||||
|
||||
// Set attribute of callback
|
||||
StickStatus.xPosition = movedX;
|
||||
StickStatus.yPosition = movedY;
|
||||
StickStatus.x = (100*((movedX - centerX)/maxMoveStick)).toFixed();
|
||||
StickStatus.y = ((100*((movedY - centerY)/maxMoveStick))*-1).toFixed();
|
||||
StickStatus.cardinalDirection = getCardinalDirection();
|
||||
callback(StickStatus);
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseUp(event)
|
||||
{
|
||||
pressed = 0;
|
||||
// If required reset position store variable
|
||||
if(autoReturnToCenter)
|
||||
{
|
||||
movedX = centerX;
|
||||
movedY = centerY;
|
||||
}
|
||||
// Delete canvas
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
// Redraw object
|
||||
drawExternal();
|
||||
drawInternal();
|
||||
|
||||
// Set attribute of callback
|
||||
StickStatus.xPosition = movedX;
|
||||
StickStatus.yPosition = movedY;
|
||||
StickStatus.x = (100*((movedX - centerX)/maxMoveStick)).toFixed();
|
||||
StickStatus.y = ((100*((movedY - centerY)/maxMoveStick))*-1).toFixed();
|
||||
StickStatus.cardinalDirection = getCardinalDirection();
|
||||
callback(StickStatus);
|
||||
}
|
||||
|
||||
function getCardinalDirection()
|
||||
{
|
||||
let result = "";
|
||||
let orizontal = movedX - centerX;
|
||||
let vertical = movedY - centerY;
|
||||
|
||||
if(vertical >= directionVerticalLimitNeg && vertical <= directionVerticalLimitPos)
|
||||
{
|
||||
result = "C";
|
||||
}
|
||||
if(vertical < directionVerticalLimitNeg)
|
||||
{
|
||||
result = "N";
|
||||
}
|
||||
if(vertical > directionVerticalLimitPos)
|
||||
{
|
||||
result = "S";
|
||||
}
|
||||
|
||||
if(orizontal < directionHorizontalLimitNeg)
|
||||
{
|
||||
if(result === "C")
|
||||
{
|
||||
result = "W";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += "W";
|
||||
}
|
||||
}
|
||||
if(orizontal > directionHorizontalLimitPos)
|
||||
{
|
||||
if(result === "C")
|
||||
{
|
||||
result = "E";
|
||||
}
|
||||
else
|
||||
{
|
||||
result += "E";
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/******************************************************
|
||||
* Public methods
|
||||
*****************************************************/
|
||||
|
||||
/**
|
||||
* @desc The width of canvas
|
||||
* @return Number of pixel width
|
||||
*/
|
||||
this.GetWidth = function ()
|
||||
{
|
||||
return canvas.width;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc The height of canvas
|
||||
* @return Number of pixel height
|
||||
*/
|
||||
this.GetHeight = function ()
|
||||
{
|
||||
return canvas.height;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc The X position of the cursor relative to the canvas that contains it and to its dimensions
|
||||
* @return Number that indicate relative position
|
||||
*/
|
||||
this.GetPosX = function ()
|
||||
{
|
||||
return movedX;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc The Y position of the cursor relative to the canvas that contains it and to its dimensions
|
||||
* @return Number that indicate relative position
|
||||
*/
|
||||
this.GetPosY = function ()
|
||||
{
|
||||
return movedY;
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc Normalizzed value of X move of stick
|
||||
* @return Integer from -100 to +100
|
||||
*/
|
||||
this.GetX = function ()
|
||||
{
|
||||
return (100*((movedX - centerX)/maxMoveStick)).toFixed();
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc Normalizzed value of Y move of stick
|
||||
* @return Integer from -100 to +100
|
||||
*/
|
||||
this.GetY = function ()
|
||||
{
|
||||
return ((100*((movedY - centerY)/maxMoveStick))*-1).toFixed();
|
||||
};
|
||||
|
||||
/**
|
||||
* @desc Get the direction of the cursor as a string that indicates the cardinal points where this is oriented
|
||||
* @return String of cardinal point N, NE, E, SE, S, SW, W, NW and C when it is placed in the center
|
||||
*/
|
||||
this.GetDir = function()
|
||||
{
|
||||
return getCardinalDirection();
|
||||
};
|
||||
});
|
318
www.eng/js/porting/jscontrols.js
Normal file
|
@ -0,0 +1,318 @@
|
|||
// by VienDesu! Poring Team 2023
|
||||
|
||||
function create_control_buttons() {
|
||||
|
||||
// A-Y Buttons
|
||||
const DivBMain = document.createElement("div");
|
||||
DivBMain.className = "gamepad-buttons";
|
||||
DivBMain.id = "gamepad-div";
|
||||
const DivBRow1 = document.createElement("div");
|
||||
DivBRow1.className = "gamepad-buttons-row";
|
||||
const DivBRow2 = document.createElement("div");
|
||||
DivBRow2.className = "gamepad-buttons-row";
|
||||
const DivBRow3 = document.createElement("div");
|
||||
DivBRow3.className = "gamepad-buttons-row";
|
||||
|
||||
const DivB_Y = document.createElement("div");
|
||||
DivB_Y.className = "gamepad-button Y";
|
||||
DivB_Y.id = "buttonA";
|
||||
const DivB_X = document.createElement("div");
|
||||
DivB_X.className = "gamepad-button X";
|
||||
DivB_X.id = "buttonShift";
|
||||
const DivB_B = document.createElement("div");
|
||||
DivB_B.className = "gamepad-button B";
|
||||
DivB_B.id = "buttonX";
|
||||
const DivB_A = document.createElement("div");
|
||||
DivB_A.className = "gamepad-button A";
|
||||
DivB_A.id = "buttonZ";
|
||||
|
||||
// LB-RB Buttons
|
||||
const DivB_LB = document.createElement("div");
|
||||
DivB_LB.className = "gamepad-bumper LB";
|
||||
DivB_LB.id = "buttonW";
|
||||
const DivB_RB = document.createElement("div");
|
||||
DivB_RB.className = "gamepad-bumper RB";
|
||||
DivB_RB.id = "buttonQ";
|
||||
|
||||
// Adding
|
||||
document.body.appendChild(DivB_LB);
|
||||
document.body.appendChild(DivB_RB);
|
||||
|
||||
DivBMain.appendChild(DivBRow1);
|
||||
DivBMain.appendChild(DivBRow2);
|
||||
DivBMain.appendChild(DivBRow3);
|
||||
|
||||
DivBRow1.appendChild(DivB_Y);
|
||||
DivBRow2.appendChild(DivB_X);
|
||||
DivBRow2.appendChild(DivB_B);
|
||||
DivBRow3.appendChild(DivB_A);
|
||||
|
||||
document.body.appendChild(DivBMain);
|
||||
}
|
||||
|
||||
function create_fps_button() {
|
||||
// Remove in release
|
||||
const keys = [{ key: 'F2', keyCode: 113 }];
|
||||
|
||||
const FPSBtn = document.createElement("div");
|
||||
FPSBtn.className = "fps-button";
|
||||
FPSBtn.id = "buttonF2";
|
||||
document.body.appendChild(FPSBtn);
|
||||
|
||||
for (const key of keys) {
|
||||
const elementId = key.id === undefined ? `button${key.key}` : key.id;
|
||||
console.log(`Setting up the ${elementId} key...`);
|
||||
setupKey(elementId, key.key, key.keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
function create_dpad_buttons() {
|
||||
// Скуфting elements
|
||||
const DivDMain = document.createElement("div");
|
||||
DivDMain.className = "dpad-buttons";
|
||||
DivDMain.id = "dpad-div";
|
||||
const DivDRow1 = document.createElement("div");
|
||||
DivDRow1.className = "dpad-buttons-row";
|
||||
const DivDRow2 = document.createElement("div");
|
||||
DivDRow2.className = "dpad-buttons-row";
|
||||
|
||||
const DivD_L = document.createElement("div");
|
||||
DivD_L.className = "dpad-button left";
|
||||
DivD_L.id = "buttonLeft";
|
||||
const DivD_U = document.createElement("div");
|
||||
DivD_U.className = "dpad-button up";
|
||||
DivD_U.id = "buttonUp";
|
||||
const DivD_D = document.createElement("div");
|
||||
DivD_D.className = "dpad-button down";
|
||||
DivD_D.id = "buttonDown";
|
||||
const DivD_R = document.createElement("div");
|
||||
DivD_R.className = "dpad-button right";
|
||||
DivD_R.id = "buttonRight";
|
||||
|
||||
// Adding
|
||||
DivDMain.appendChild(DivDRow1);
|
||||
DivDMain.appendChild(DivDRow2);
|
||||
|
||||
DivDRow1.appendChild(DivD_L);
|
||||
DivDRow1.appendChild(DivD_U);
|
||||
DivDRow2.appendChild(DivD_D);
|
||||
DivDRow2.appendChild(DivD_R);
|
||||
|
||||
document.body.appendChild(DivDMain);
|
||||
|
||||
currentControlElement = "dpad";
|
||||
}
|
||||
|
||||
function create_joystick() {
|
||||
const JoyDiv = document.createElement("div");
|
||||
JoyDiv.id = "joyDiv";
|
||||
document.body.appendChild(JoyDiv);
|
||||
const kbd = joyStates;
|
||||
const joy = new JoyStick('joyDiv', {internalFillColor: "#373737", internalStrokeColor: "#FFFFFF", externalStrokeColor: "#FFFFFF"}, (stickData) => {
|
||||
disableActive();
|
||||
switch (stickData.cardinalDirection) {
|
||||
case 'NE':
|
||||
case 'NW':
|
||||
case 'N':
|
||||
kbd.up.status = true;
|
||||
sendEvent(false, kbd.up.code);
|
||||
break;
|
||||
case 'E':
|
||||
kbd.right.status = true;
|
||||
sendEvent(false, kbd.right.code);
|
||||
break;
|
||||
case 'W':
|
||||
kbd.left.status = true;
|
||||
sendEvent(false, kbd.left.code);
|
||||
break;
|
||||
case 'SE':
|
||||
case 'SW':
|
||||
case 'S':
|
||||
kbd.down.status = true;
|
||||
sendEvent(false, kbd.down.code);
|
||||
break;
|
||||
case 'C':
|
||||
disableActive();
|
||||
break;
|
||||
}
|
||||
});
|
||||
currentControlElement = "joystick";
|
||||
}
|
||||
|
||||
function create_switch_button() {
|
||||
const newDiv = document.createElement("div");
|
||||
newDiv.className = "switch-button";
|
||||
newDiv.id = "switch";
|
||||
|
||||
document.body.appendChild(newDiv);
|
||||
|
||||
newDiv.addEventListener("pointerdown", (event) => {
|
||||
if (document.getElementById("joyDiv") === null) {
|
||||
document.getElementById("dpad-div").remove();
|
||||
create_joystick();
|
||||
} else {
|
||||
document.getElementById("joyDiv").remove();
|
||||
create_dpad_buttons();
|
||||
setupDpad();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function create_show_button() {
|
||||
const newDiv = document.createElement("div");
|
||||
newDiv.className = "show-gamepad-button";
|
||||
newDiv.id = "show-gamepad";
|
||||
|
||||
document.body.appendChild(newDiv);
|
||||
|
||||
newDiv.addEventListener("pointerdown", (event) => {
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
var DivBMain = document.getElementById("gamepad-div");
|
||||
var DivB_LB = document.getElementById("buttonW");
|
||||
var DivB_RB = document.getElementById("buttonQ");
|
||||
var DivDMain = document.getElementById("dpad-div");
|
||||
var DivJoy = document.getElementById("joyDiv");
|
||||
var ShowB = document.getElementById("switch");
|
||||
|
||||
if (DivBMain !== null) {
|
||||
DivBMain.remove();
|
||||
DivB_LB.remove();
|
||||
DivB_RB.remove();
|
||||
ShowB.remove();
|
||||
switch (currentControlElement) {
|
||||
case "dpad":
|
||||
DivDMain.remove();
|
||||
break;
|
||||
case "joystick":
|
||||
DivJoy.remove();
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
create_control_buttons();
|
||||
switch (currentControlElement) {
|
||||
case "dpad":
|
||||
create_dpad_buttons();
|
||||
setupDpad();
|
||||
break;
|
||||
case "joystick":
|
||||
create_joystick();
|
||||
break;
|
||||
}
|
||||
setupButtons();
|
||||
create_switch_button();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var currentControlElement = null;
|
||||
|
||||
const keys = [
|
||||
{ key: 'Z', keyCode: 90 },
|
||||
{ key: 'X', keyCode: 88 },
|
||||
{ key: 'Shift', keyCode: 16 },
|
||||
{ key: 'A', keyCode: 87 },
|
||||
|
||||
{ key: 'Q', keyCode: 81 },
|
||||
{ key: 'W', keyCode: 68 }
|
||||
];
|
||||
|
||||
const dpadkeys = [
|
||||
{ key: "Left", keyCode: 37 },
|
||||
{ key: "Up", keyCode: 38 },
|
||||
{ key: "Right", keyCode: 39 },
|
||||
{ key: "Down", keyCode: 40 }
|
||||
];
|
||||
|
||||
const joyStates = {
|
||||
left: { status: false, code: 37 },
|
||||
right: { status: false, code: 39 },
|
||||
|
||||
up: { status: false, code: 38 },
|
||||
down: { status: false, code: 40 }
|
||||
};
|
||||
|
||||
function createButton(key, keyCode) {
|
||||
return { key: key, keyCode: keyCode };
|
||||
}
|
||||
|
||||
function sendEvent(isUp, keycode) {
|
||||
document.getElementById("GameCanvas").focus();
|
||||
document.dispatchEvent(new KeyboardEvent(isUp ? 'keyup' : 'keydown', { 'key': '', keyCode: keycode }))
|
||||
}
|
||||
|
||||
function disableActive() {
|
||||
for (const kbdKey in joyStates) {
|
||||
const kbd = joyStates[kbdKey];
|
||||
if (kbd.status) {
|
||||
sendEvent(true, kbd.code);
|
||||
kbd.status = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function setupButtons() {
|
||||
for (const key of keys) {
|
||||
const elementId = key.id === undefined ? `button${key.key}` : key.id;
|
||||
console.log(`Setting up the ${elementId} key...`); //Remove in release
|
||||
setupKey(elementId, key.key, key.keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
function setupDpad() {
|
||||
for (const key of dpadkeys) {
|
||||
const elementId = key.id === undefined ? `button${key.key}` : key.id;
|
||||
console.log(`Setting up the ${elementId} key...`); //Remove in release
|
||||
setupKey(elementId, key.key, key.keyCode);
|
||||
}
|
||||
}
|
||||
|
||||
function setupKey(id, key, keyCode) {
|
||||
const element = document.getElementById(id);
|
||||
element.addEventListener("pointerdown", (event) => {
|
||||
console.log(`Pointer down for ${id}`); //Remove in release
|
||||
event.stopImmediatePropagation();
|
||||
event.preventDefault();
|
||||
sendEvent(false, keyCode);
|
||||
});
|
||||
|
||||
element.addEventListener("pointerup", () => {
|
||||
sendEvent(true, keyCode);
|
||||
});
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
create_fps_button(); // Remove in release
|
||||
if (navigator.getGamepads().length == 0) {
|
||||
create_control_buttons();
|
||||
create_dpad_buttons();
|
||||
create_show_button();
|
||||
create_switch_button();
|
||||
setupButtons();
|
||||
setupDpad();
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('gamepadconnected', () => {
|
||||
var DivBMain = document.getElementById("gamepad-div");
|
||||
var DivB_LB = document.getElementById("buttonW");
|
||||
var DivB_RB = document.getElementById("buttonQ");
|
||||
var DivDMain = document.getElementById("dpad-div");
|
||||
var DivJoy = document.getElementById("joyDiv");
|
||||
var ShowB = document.getElementById("switch");
|
||||
|
||||
if (DivBMain !== null) {
|
||||
DivBMain.remove();
|
||||
DivB_LB.remove();
|
||||
DivB_RB.remove();
|
||||
ShowB.remove();
|
||||
switch (currentControlElement) {
|
||||
case "dpad":
|
||||
DivDMain.remove();
|
||||
break;
|
||||
case "joystick":
|
||||
DivJoy.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
47
www.eng/js/porting/persistent.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
// by VienDesu! Poring Team 2023
|
||||
|
||||
window.PERSISTENT_IMPLEMENTATIONS = {
|
||||
stub: stubImplementation,
|
||||
localStorage: localStorageImplementation,
|
||||
}
|
||||
|
||||
function localStorageImplementation() {
|
||||
return {
|
||||
readSaveFileUTF8(path) {
|
||||
console.log(`Failed to get externalStorage. Using localStorage to read save at ${path}`);
|
||||
return localStorage.getItem(path);
|
||||
},
|
||||
|
||||
saveFileExists(path) {
|
||||
console.log(`Using localStorage while checking save file ${path} existence`);
|
||||
return localStorage.getItem(path) != null;
|
||||
},
|
||||
|
||||
writeSaveFileUTF8(path, data) {
|
||||
console.log(`Failed to get externalStorage. Writing ${path} save file to the localStorage`);
|
||||
localStorage.setItem(path, data);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function stubImplementation() {
|
||||
return {
|
||||
readSaveFileUTF8(path) {
|
||||
console.log(`Tried to read save from ${path}, but it is stub!`);
|
||||
return ``;
|
||||
},
|
||||
|
||||
saveFileExists(path) {
|
||||
console.log(`Tried to check save file at ${path}, stub will always report false`);
|
||||
return false;
|
||||
},
|
||||
|
||||
writeSaveFileUTF8(path, data) {
|
||||
console.log(`Tried to write save file at ${path}, but I'm just a stub, not a real back-end`);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
if (typeof NativeFunctions == 'undefined') {
|
||||
window.NativeFunctions = PERSISTENT_IMPLEMENTATIONS.localStorage();
|
||||
}
|