diff --git a/data/css/main.css b/data/css/main.css
index 5f4ddb9..be96401 100644
--- a/data/css/main.css
+++ b/data/css/main.css
@@ -1229,3 +1229,49 @@
.ejs_virtualGamepad_open svg {
fill: currentColor;
}
+
+.ejs_netplay_name_input {
+ margin-top: .5rem;
+ margin-bottom: .5rem;
+ line-height: 1.5;
+ color: rgba(0,0,0,.8);
+ text-align: left;
+}
+.ejs_netplay_name_input input {
+ font-size: 1rem;
+ padding: .4rem;
+ max-width: 100%;
+ color: #000!important;
+ background-color: #fff!important;
+ margin: 0;
+ height: 2rem;
+ display: block;
+ font-family: Arial;
+}
+.ejs_netplay_name_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;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+}
+.ejs_netplay_table {
+ font-family: Avenir,"Avenir Next","Helvetica Neue","Segoe UI",Helvetica,Arial,sans-serif;
+ font-size: 0.8rem;
+ padding: 0 10px;
+}
+.ejs_netplay_join_button {
+ float: none;
+ padding: .1rem .5rem;
+ background-color: rgba(var(--ejs-primary-color),1);
+ color: #fff!important;
+ border-radius: .25rem;
+ cursor: pointer;
+}
+.ejs_netplay_table_row:hover {
+ background-color: #2d2d2d;
+}
diff --git a/data/emulator.js b/data/emulator.js
index f2ad54f..ee5d143 100644
--- a/data/emulator.js
+++ b/data/emulator.js
@@ -882,6 +882,7 @@ class EmulatorJS {
this.createBottomMenuBar();
this.createControlSettingMenu();
this.createCheatsMenu()
+ this.createNetplayMenu();
this.setVirtualGamepad();
this.addEventListener(this.elements.parent, "keydown keyup", this.keyChange.bind(this));
this.addEventListener(this.elements.parent, "mousedown touchstart", (e) => {
@@ -1082,7 +1083,7 @@ class EmulatorJS {
})
}
isPopupOpen() {
- return this.cheatMenu.style.display !== "none" || this.controlMenu.style.display !== "none" || this.currentPopup !== null;
+ return this.cheatMenu.style.display !== "none" || this.netplayMenu.style.display !== "none" || this.controlMenu.style.display !== "none" || this.currentPopup !== null;
}
isChild(first, second) {
if (!first || !second) return false;
@@ -1295,6 +1296,9 @@ class EmulatorJS {
FS.writeFile(path, sav);
this.gameManager.loadSaveFiles();
});
+ const netplay = addButton("Netplay", '', async () => {
+ this.openNetplayMenu();
+ });
const spacer = this.createElement("span");
spacer.classList.add("ejs_menu_bar_spacer");
@@ -2796,6 +2800,140 @@ class EmulatorJS {
popup.appendChild(popupMsg);
return [popup, popupMsg];
}
+ createNetplayMenu() {
+ const body = this.createPopup("Netplay", {
+ "Create a Room": () => {
+ console.log("aaaaaaaaaaaa");
+ },
+ "Close": () => {
+ this.netplayMenu.style.display = "none";
+ this.netplay.updateList.stop();
+ }
+ }, true);
+ this.netplayMenu = body.parentElement;
+ const rooms = this.createElement("div");
+ const title = this.createElement("strong");
+ title.innerText = "Rooms";
+ const table = this.createElement("table");
+ table.classList.add("ejs_netplay_table");
+ table.style.width = "100%";
+ table.setAttribute("cellspacing", "0");
+ const thead = this.createElement("thead");
+ const row = this.createElement("tr");
+ const addToHeader = (text) => {
+ const item = this.createElement("td");
+ item.innerText = text;
+ item.style["text-align"] = "center";
+ row.appendChild(item);
+ return item;
+ }
+ thead.appendChild(row);
+ addToHeader("Room Name").style["text-align"] = "left";
+ addToHeader("Players").style.width = "80px";
+ addToHeader("").style.width = "80px"; //"join" button
+ table.appendChild(thead);
+ const tbody = this.createElement("tbody");
+
+ table.appendChild(tbody);
+ rooms.appendChild(title);
+ rooms.appendChild(table);
+ body.appendChild(rooms);
+
+ this.openNetplayMenu = () => {
+ this.netplayMenu.style.display = "";
+ if (!this.netplay) {
+ this.netplay = {};
+ this.netplay.table = tbody;
+ this.defineNetplayFunctions();
+ const popups = this.createSubPopup();
+ this.netplayMenu.appendChild(popups[0]);
+ popups[1].classList.add("ejs_cheat_parent"); //Hehe
+ const popup = popups[1];
+
+ const header = this.createElement("div");
+ const title = this.createElement("h2");
+ title.innerText = this.localization("Set Player Name");
+ title.classList.add("ejs_netplay_name_heading");
+ header.appendChild(title);
+ popup.appendChild(header);
+
+ const main = this.createElement("div");
+ main.classList.add("ejs_netplay_name_input");
+ const head = this.createElement("strong");
+ head.innerText = "Player Name";
+ const input = this.createElement("input");
+ input.type = "text";
+ input.setAttribute("maxlength", 20);
+
+ main.appendChild(head);
+ main.appendChild(this.createElement("br"));
+ main.appendChild(input);
+ popup.appendChild(main);
+
+ popup.appendChild(this.createElement("br"));
+ const submit = this.createElement("button");
+ submit.classList.add("ejs_button_button");
+ submit.classList.add("ejs_popup_submit");
+ submit.style["background-color"] = "rgba(var(--ejs-primary-color),1)";
+ submit.innerText = "Submit";
+ popup.appendChild(submit);
+ this.addEventListener(submit, "click", (e) => {
+ if (!input.value.trim()) return;
+ this.netplay.name = input.value.trim();
+ popups[0].remove();
+ })
+ }
+ this.netplay.updateList.start();
+ }
+ }
+ defineNetplayFunctions() {
+ this.netplay.getOpenRooms = async () => {
+ //async because it will need to pull from server. This is for testing
+ return [{name:"Room 1", players:1, max:2},{name:"Room 2", players:2, max:2}];
+ }
+ this.netplay.updateTableList = async () => {
+ const addToTable = (name, current, max) => {
+ const row = this.createElement("tr");
+ row.classList.add("ejs_netplay_table_row");
+ const addToHeader = (text) => {
+ const item = this.createElement("td");
+ item.innerText = text;
+ item.style.padding = "10px 0";
+ item.style["text-align"] = "center";
+ row.appendChild(item);
+ return item;
+ }
+ addToHeader(name).style["text-align"] = "left";
+ addToHeader(current + "/" + max).style.width = "80px";
+
+ const parent = addToHeader("");
+ parent.style.width = "80px";
+ if (current < max) {
+ const join = this.createElement("button");
+ join.classList.add("ejs_netplay_join_button");
+ join.classList.add("ejs_button_button");
+ join.style["background-color"] = "rgba(var(--ejs-primary-color),1)";
+ join.innerText = "Join";
+ parent.appendChild(join);
+ }
+ this.netplay.table.appendChild(row);
+ }
+ this.netplay.table.innerHTML = "";
+ const open = await this.netplay.getOpenRooms();
+ for (let i=0; i {
+ this.netplay.updateList.interval = setInterval(this.netplay.updateTableList.bind(this), 1000);
+ },
+ stop: () => {
+ clearInterval(this.netplay.updateList.interval);
+ }
+ }
+ }
createCheatsMenu() {
const body = this.createPopup("Cheats", {
"Add Cheat": () => {