This commit is contained in:
Ethan O'Brien 2023-06-29 10:35:25 -05:00
parent 83351a4fa3
commit 46322c1973
3 changed files with 345 additions and 5 deletions

View file

@ -11,7 +11,9 @@ class EJS_GameManager {
simulateInput: this.Module.cwrap('simulate_input', 'null', ['number', 'number', 'number']),
toggleMainLoop: this.Module.cwrap('toggleMainLoop', 'null', ['number']),
getCoreOptions: this.Module.cwrap('get_core_options', 'string', []),
setVariable: this.Module.cwrap('set_variable', 'null', ['string', 'string'])
setVariable: this.Module.cwrap('set_variable', 'null', ['string', 'string']),
setCheat: this.Module.cwrap('set_cheat', 'null', ['number', 'number', 'string']),
resetCheat: this.Module.cwrap('reset_cheat', 'null', [])
}
this.mkdir("/home");
this.mkdir("/home/web_user");
@ -101,7 +103,12 @@ class EJS_GameManager {
setVariable(option, value) {
this.functions.setVariable(option, value);
}
setCheat(index, enabled, code) {
this.functions.setCheat(index, enabled, code);
}
resetCheat() {
this.functions.resetCheat();
}
}
window.EJS_GameManager = EJS_GameManager;

View file

@ -247,6 +247,11 @@
.ejs_popup_container *, .ejs_popup_container *::after, .ejs_popup_container *::before {
box-sizing: border-box;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
.ejs_popup_container h4 {
@ -694,3 +699,189 @@
background: rgba(var(--ejs-primary-color),1);
color: #fff;
}
.ejs_cheat_heading {
margin-top: 0 !important;
margin-bottom: 0 !important;
font-weight: 600 !important;
font-size: 1.25rem;
line-height: 1.25 !important;
color: rgba(var(--ejs-primary-color),1) !important;
}
.ejs_cheat_close {
font: inherit;
line-height: inherit;
width: auto;
background: transparent;
border: 0;
color: #bcbcbc !important;
cursor: pointer;
}
.ejs_cheat_close::before {
content: "\2715";
color: #bcbcbc !important;
font: inherit;
line-height: inherit;
width: auto;
}
.ejs_cheat_header {
display: flex;
justify-content: space-between;
align-items: center;
}
.ejs_cheat_main {
margin-top: 2rem;
margin-bottom: 2rem;
line-height: 1.5;
color: rgba(0,0,0,0.8);
text-align: left;
color: #bcbcbc !important;
border: unset;
}
.ejs_cheat_code {
color: #000 !important;
font-size: 1rem;
padding: .4rem;
max-width: 100%;
}
@keyframes ejs_cheat_animation{
from{
transform:translateY(15%)
}
to{
transform:translateY(0)
}
}
.ejs_cheat_parent {
background-color: rgba(0,0,0,0.8);
border: 1px solid rgba(238,238,238,0.2);
padding: 30px;
min-width: 200px;
max-width: 500px;
max-height: 100vh;
border-radius: 4px;
overflow-y: auto;
box-sizing: border-box;
will-change: transform;
animation: ejs_cheat_animation .3s cubic-bezier(0,0,0.2,1);
font-size: 14px;
}
.ejs_popup_container_box {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0,0,0,0.6);
display: flex;
justify-content: center;
align-items: center;
}
.ejs_popup_submit {
touch-action: manipulation;
font: inherit;
line-height: inherit;
width: auto;
}
.ejs_button_button {
color: #fff !important;
padding-left: 1rem;
padding-right: 1rem;
padding-top: .5rem;
padding-bottom: .5rem;
background-color: #929292;
border-radius: .25rem;
border-style: none;
border-width: 0;
cursor: pointer;
-webkit-appearance: button;
text-transform: none;
overflow: visible;
margin: 0;
will-change: transform;
transition: transform .25s ease-out,-webkit-transform .25s ease-out;
}
.ejs_button_button:hover {
transform: scale(1.05);
}
.ejs_cheat_rows {
max-width: 320px;
margin: 0 auto;
text-align: left;
width: 100%;
float: none;
user-select: text !important;
}
.ejs_cheat_row {
padding-left: 2.25rem;
position: relative;
padding: .2em 0;
clear: both;
}
.ejs_cheat_row:hover {
background-color: rgba(0,0,0,0.8);
}
.ejs_cheat_row input[type=checkbox] {
position: absolute;
z-index: -1;
opacity: 0;
box-sizing: border-box;
width: auto;
}
.ejs_cheat_row label {
position: relative;
margin-bottom: 0;
vertical-align: top;
word-break: break-word;
}
.ejs_cheat_row label::before {
position: absolute;
top: .325rem;
display: block;
height: 1rem;
content: "";
background-color: #fff;
border: #adb5bd solid 1px;
left: -2.25rem;
width: 1.75rem;
pointer-events: all;
border-radius: .5rem;
}
.ejs_cheat_row input:checked+label::before {
color: #fff;
border-color: rgba(var(--ejs-primary-color),1);
background-color: rgba(var(--ejs-primary-color),1);
}
.ejs_cheat_row label::after {
position: absolute;
display: block;
content: "";
background-repeat: no-repeat;
background-position: center center;
top: calc(.325rem + 2px);
left: calc(-2.25rem + 2px);
width: calc(1rem - 4px);
height: calc(1rem - 4px);
background-color: #adb5bd;
border-radius: .5rem;
transition: transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out,-webkit-transform .15s ease-in-out;
}
.ejs_cheat_row input:checked+label::after {
background-color: #fff;
-webkit-transform: translateX(0.75rem);
transform: translateX(0.75rem);
}
.ejs_cheat_row_button {
position: absolute;
padding: .1rem .5rem;
background-color: rgba(var(--ejs-primary-color),1);
color: #fff !important;
border-radius: .25rem;
cursor: pointer;
right: .025rem;
border: 0;
}

View file

@ -80,6 +80,7 @@ class EmulatorJS {
window.EJS_TESTING = this;
this.touch = false;
this.debug = (window.EJS_DEBUG_XX === true);
this.cheats = [];
this.setElements(element);
this.started = false;
this.paused = true;
@ -448,6 +449,7 @@ class EmulatorJS {
startGame() {
this.textElem.remove();
this.textElem = null;
this.game.classList.remove("ejs_game");
this.game.appendChild(this.canvas);
const args = [];
@ -464,11 +466,13 @@ class EmulatorJS {
this.setupSettingsMenu();
this.handleResize();
this.updateCheatUI();
}
bindListeners() {
this.createContextMenu();
this.createBottomMenuBar();
this.createControlSettingMenu();
this.createCheatsMenu()
this.setVirtualGamepad();
this.addEventListener(document, "keydown keyup", this.keyChange.bind(this));
this.addEventListener(window, "resize", this.handleResize.bind(this));
@ -701,6 +705,9 @@ class EmulatorJS {
addButton("Control Settings", '<svg viewBox="0 0 640 512"><path fill="currentColor" d="M480 96H160C71.6 96 0 167.6 0 256s71.6 160 160 160c44.8 0 85.2-18.4 114.2-48h91.5c29 29.6 69.5 48 114.2 48 88.4 0 160-71.6 160-160S568.4 96 480 96zM256 276c0 6.6-5.4 12-12 12h-52v52c0 6.6-5.4 12-12 12h-40c-6.6 0-12-5.4-12-12v-52H76c-6.6 0-12-5.4-12-12v-40c0-6.6 5.4-12 12-12h52v-52c0-6.6 5.4-12 12-12h40c6.6 0 12 5.4 12 12v52h52c6.6 0 12 5.4 12 12v40zm184 68c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48zm80-80c-26.5 0-48-21.5-48-48s21.5-48 48-48 48 21.5 48 48-21.5 48-48 48z"/></svg>', () => {
this.controlMenu.style.display = "";
});
addButton("Cheats", '<svg viewBox="0 0 496 512"><path fill="currentColor" d="M248 8C111 8 0 119 0 256s111 248 248 248 248-111 248-248S385 8 248 8zm0 448c-110.3 0-200-89.7-200-200S137.7 56 248 56s200 89.7 200 200-89.7 200-200 200zm-80-216c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm160 0c17.7 0 32-14.3 32-32s-14.3-32-32-32-32 14.3-32 32 14.3 32 32 32zm4 72.6c-20.8 25-51.5 39.4-84 39.4s-63.2-14.3-84-39.4c-8.5-10.2-23.7-11.5-33.8-3.1-10.2 8.5-11.5 23.6-3.1 33.8 30 36 74.1 56.6 120.9 56.6s90.9-20.6 120.9-56.6c8.5-10.2 7.1-25.3-3.1-33.8-10.1-8.4-25.3-7.1-33.8 3.1z" class=""></path></svg>', () => {
this.cheatMenu.style.display = "";
});
const spacer = this.createElement("span");
spacer.style = "flex:1;";
@ -957,7 +964,7 @@ class EmulatorJS {
popup.classList.add("ejs_popup_container");
const popupMsg = this.createElement("div");
popupMsg.classList.add("ejs_popup_box");
popupMsg.innerText = "yes";
popupMsg.innerText = "";
popup.setAttribute("hidden", "");
this.controlPopup = popupMsg;
popup.appendChild(popupMsg);
@ -1037,6 +1044,7 @@ class EmulatorJS {
controls;
keyChange(e) {
if (!this.started) return;
if (this.cheatMenu.style.display !== "none" || this.settingsMenu.style.display !== "none") return;
e.preventDefault();
if (this.controlPopup.parentElement.getAttribute("hidden") === null) {
const num = this.controlPopup.getAttribute("button-num");
@ -1594,15 +1602,149 @@ class EmulatorJS {
this.settingsMenu.appendChild(nested);
this.settingParent.appendChild(this.settingsMenu);
this.settingParent.style.position = "relative";
const homeSize = this.getElementSize(home);
nested.style.width = homeSize.width + "px";
nested.style.height = homeSize.height + "px";
this.settingsMenu.style.display = "none";
}
createSubPopup(hidden) {
const popup = this.createElement('div');
popup.classList.add("ejs_popup_container");
popup.classList.add("ejs_popup_container_box");
const popupMsg = this.createElement("div");
popupMsg.innerText = "";
if (hidden) popup.setAttribute("hidden", "");
popup.appendChild(popupMsg);
return [popup, popupMsg];
}
createCheatsMenu() {
const body = this.createPopup("Cheats", {
"Add Cheat": () => {
const popups = this.createSubPopup();
this.cheatMenu.appendChild(popups[0]);
popups[1].classList.add("ejs_cheat_parent");
popups[1].style.width = "100%";
const popup = popups[1];
const header = this.createElement("div");
header.classList.add("ejs_cheat_header");
const title = this.createElement("h2");
title.innerText = "Add Cheat Code";
title.classList.add("ejs_cheat_heading");
const close = this.createElement("button");
close.classList.add("ejs_cheat_close");
header.appendChild(title);
header.appendChild(close);
popup.appendChild(header);
this.addEventListener(close, "click", (e) => {
popups[0].remove();
})
const main = this.createElement("div");
main.classList.add("ejs_cheat_main");
const header3 = this.createElement("strong");
header3.innerText = "Code";
main.appendChild(header3);
main.appendChild(this.createElement("br"));
const mainText = this.createElement("textarea");
mainText.classList.add("ejs_cheat_code");
mainText.style.width = "100%";
mainText.style.height = "80px";
main.appendChild(mainText);
main.appendChild(this.createElement("br"));
const header2 = this.createElement("strong");
header2.innerText = "Description";
main.appendChild(header2);
main.appendChild(this.createElement("br"));
const mainText2 = this.createElement("input");
mainText2.type = "text";
mainText2.classList.add("ejs_cheat_code");
main.appendChild(mainText2);
main.appendChild(this.createElement("br"));
popup.appendChild(main);
const footer = this.createElement("footer");
const submit = this.createElement("button");
const closeButton = this.createElement("button");
submit.innerText = "Submit";
closeButton.innerText = "Close";
submit.classList.add("ejs_button_button");
closeButton.classList.add("ejs_button_button");
submit.classList.add("ejs_popup_submit");
closeButton.classList.add("ejs_popup_submit");
submit.style["background-color"] = "rgba(var(--ejs-primary-color),1)";
footer.appendChild(submit);
const span = this.createElement("span");
span.innerText = " ";
footer.appendChild(span);
footer.appendChild(closeButton);
popup.appendChild(footer);
this.addEventListener(submit, "click", (e) => {
if (!mainText.value.trim() || !mainText2.value.trim()) return;
popups[0].remove();
this.cheats.push({
code: mainText.value,
desc: mainText2.value,
checked: false
});
this.updateCheatUI();
})
this.addEventListener(closeButton, "click", (e) => {
popups[0].remove();
})
},
"Close": () => {
this.cheatMenu.style.display = "none";
}
}, true);
this.cheatMenu = body.parentElement;
const rows = this.createElement("div");
body.appendChild(rows);
rows.classList.add("ejs_cheat_rows");
this.elements.cheatRows = rows;
}
updateCheatUI() {
if (!this.cheats) this.cheats = [];
this.elements.cheatRows.innerHTML = "";
const addToMenu = (desc, checked, code, i) => {
const row = this.createElement("div");
row.classList.add("ejs_cheat_row");
const input = this.createElement("input");
input.type = "checkbox";
input.checked = checked;
input.value = i;
input.id = "ejs_cheat_switch_"+i;
row.appendChild(input);
const label = this.createElement("label");
label.for = "ejs_cheat_switch_"+i;
label.innerText = desc;
row.appendChild(label);
label.addEventListener("click", (e) => {
input.checked = !input.checked;
this.cheats[i].checked = input.checked;
this.cheatChanged(input.checked, code, i);
})
const close = this.createElement("a");
close.classList.add("ejs_cheat_row_button");
close.innerText = "×";
row.appendChild(close);
this.elements.cheatRows.appendChild(row);
this.cheatChanged(checked, code, i);
}
this.gameManager.resetCheat();
for (let i=0; i<this.cheats.length; i++) {
addToMenu(this.cheats[i].desc, this.cheats[i].checked, this.cheats[i].code, i);
}
}
cheatChanged(checked, code, index) {
this.gameManager.setCheat(index, checked, code);
}
}