diff --git a/index.html b/index.html index a1a853e..bb81bcb 100644 --- a/index.html +++ b/index.html @@ -7,24 +7,11 @@ EJS_core = 'nes'; EJS_gameUrl = 'mega_mountain.nes'; EJS_DEBUG_XX = true; - EJS_AdUrl = "https://www.google.com/search?igu=1"; + //EJS_AdUrl = "https://www.google.com/search?igu=1"; /* EJS_Buttons = { - playPause: false, - restart: false, mute: false, - settings: true, - fullscreen: false, - saveState: false, - loadState: false, - screenRecord: false, - gamepad: false, - cheat: false, volume: true, - quickSave: false, - quickLoad: false, - screenshot: false, - cacheManager: false }*/ diff --git a/src/css/main.css b/src/css/main.css index eda3c92..a4333f6 100644 --- a/src/css/main.css +++ b/src/css/main.css @@ -302,6 +302,7 @@ .ejs_popup_container *, .ejs_popup_container *::after, .ejs_popup_container *::before { box-sizing: border-box; + color: #bcbcbc !important; -webkit-user-select: none; -moz-user-select: none; diff --git a/src/emulator.js b/src/emulator.js index a1de511..0ab4e34 100644 --- a/src/emulator.js +++ b/src/emulator.js @@ -149,6 +149,7 @@ class EmulatorJS { } constructor(element, config) { window.EJS_TESTING = this; + this.currentPopup = null; this.touch = false; this.debug = (window.EJS_DEBUG_XX === true); this.cheats = []; @@ -802,7 +803,7 @@ class EmulatorJS { }) } isPopupOpen() { - return this.cheatMenu.style.display !== "none" || this.controlMenu.style.display !== "none"; + return this.cheatMenu.style.display !== "none" || this.controlMenu.style.display !== "none" || this.currentPopup !== null; } createBottomMenuBar() { this.elements.menu = this.createElement("div"); @@ -916,6 +917,10 @@ class EmulatorJS { this.cheatMenu.style.display = ""; }); + const cache = addButton("Cache Manager", '', () => { + this.openCacheMenu(); + }); + const spacer = this.createElement("span"); spacer.style = "flex:1;"; this.elements.menu.appendChild(spacer); @@ -988,6 +993,7 @@ class EmulatorJS { } }) + if (this.config.buttonOpts) { if (!this.config.buttonOpts.playPause) { pauseButton.style.display = "none"; @@ -1003,8 +1009,62 @@ class EmulatorJS { if (!this.config.buttonOpts.loadState) loadState.setAttribute("hidden", ""); if (!this.config.buttonOpts.gamepad) controlMenu.setAttribute("hidden", ""); if (!this.config.buttonOpts.cheat) cheatMenu.setAttribute("hidden", ""); + if (!this.config.buttonOpts.cacheManager) cache.setAttribute("hidden", ""); } - + } + openCacheMenu() { + (async () => { + const list = this.createElement("table"); + const tbody = this.createElement("tbody"); + const body = this.createPopup("Cache Manager", { + "Clear All": async () => { + const roms = await this.storage.rom.getSizes(); + for (const k in roms) { + await this.storage.rom.remove(k); + } + tbody.innerHTML = ""; + }, + "Close": () => { + this.closePopup(); + } + }); + const roms = await this.storage.rom.getSizes(); + list.style.width = "100%"; + list.style["padding-left"] = "10px"; + list.style["text-align"] = "left"; + body.appendChild(list); + list.appendChild(tbody); + const getSize = function(size) { + let i = -1; + do { + size /= 1024, i++; + } while (size > 1024); + return Math.max(size, 0.1).toFixed(1) + [' kB', ' MB', ' GB', ' TB', 'PB', 'EB', 'ZB', 'YB'][i]; + } + for (const k in roms) { + const line = this.createElement("tr"); + const name = this.createElement("td"); + const size = this.createElement("td"); + const remove = this.createElement("td"); + remove.style.cursor = "pointer"; + name.innerText = k; + size.innerText = getSize(roms[k]); + + const a = this.createElement("a"); + a.innerText = "Remove"; + this.addEventListener(remove, "click", () => { + this.storage.rom.remove(k); + line.remove(); + }) + remove.appendChild(a); + + line.appendChild(name); + line.appendChild(size); + line.appendChild(remove); + tbody.appendChild(line); + } + + })(); } createControlSettingMenu() { let buttonListeners = []; diff --git a/src/storage.js b/src/storage.js index d170b48..68d409b 100644 --- a/src/storage.js +++ b/src/storage.js @@ -3,17 +3,31 @@ class EJS_STORAGE { this.dbName = dbName; this.storeName = storeName; } + addFileToDB(key, add) { + (async () => { + if (key === "?EJS_KEYS!") return; + let keys = await this.get("?EJS_KEYS!"); + if (!keys) keys = []; + if (add) { + if (!keys.includes(key)) keys.push(key); + } else { + const index = keys.indexOf(key); + if (index !== -1) keys.splice(index, 1); + } + this.put("?EJS_KEYS!", keys); + })(); + } get(key) { - if (!window.indexedDB) return null; return new Promise((resolve, reject) => { + if (!window.indexedDB) return resolve(); let openRequest = indexedDB.open(this.dbName, 1); - openRequest.onerror = () => {}; + openRequest.onerror = () => resolve(); openRequest.onsuccess = () => { let db = openRequest.result; let transaction = db.transaction([this.storeName], "readwrite"); let objectStore = transaction.objectStore(this.storeName); let request = objectStore.get(key); - request.onsuccess = async (e) => { + request.onsuccess = (e) => { resolve(request.result); }; request.onerror = () => resolve(); @@ -27,8 +41,8 @@ class EJS_STORAGE { }); } put(key, data) { - if (!window.indexedDB) return null; return new Promise((resolve, reject) => { + if (!window.indexedDB) return resolve(); let openRequest = indexedDB.open(this.dbName, 1); openRequest.onerror = () => {}; openRequest.onsuccess = () => { @@ -37,7 +51,10 @@ class EJS_STORAGE { let objectStore = transaction.objectStore(this.storeName); let request = objectStore.put(data, key); request.onerror = () => resolve(); - request.onsuccess = () => resolve(); + request.onsuccess = () => { + this.addFileToDB(key, true); + resolve(); + } }; openRequest.onupgradeneeded = () => { let db = openRequest.result; @@ -48,8 +65,8 @@ class EJS_STORAGE { }) } remove(key) { - if (!window.indexedDB) return null; return new Promise((resolve, reject) => { + if (!window.indexedDB) return resolve(); let openRequest = indexedDB.open(this.dbName, 1); openRequest.onerror = () => {}; openRequest.onsuccess = () => { @@ -57,6 +74,7 @@ class EJS_STORAGE { let transaction = db.transaction([this.storeName], "readwrite"); let objectStore = transaction.objectStore(this.storeName); let request2 = objectStore.delete(key); + this.addFileToDB(key, false); request2.onsuccess = () => resolve(); request2.onerror = () => {}; }; @@ -68,5 +86,19 @@ class EJS_STORAGE { }; }); } + getSizes() { + return new Promise(async (resolve, reject) => { + if (!window.indexedDB) resolve({}); + const keys = await this.get("?EJS_KEYS!"); + if (!keys) resolve({}); + let rv = {}; + for (let i=0; i