Update DS emu

This commit is contained in:
2023-01-19 13:07:46 +01:00
parent c8326e953b
commit ba33a4e087
3 changed files with 442 additions and 587 deletions

View File

@ -9,10 +9,10 @@
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<link rel="apple-touch-icon" href="https://ds.44670.org/icon.png"> <link rel="apple-touch-icon" href="https://ds.44670.org/icon.png">
<link href="dark.css" rel="stylesheet"> <link href="dark.css" rel="stylesheet">
<title>DS Player</title> <title>DeSmuME-WASM Fork</title>
<!-- Add hint for search engine --> <!-- Add hint for search engine -->
<meta name="description" <meta name="description"
content="DS Player is a web emulator for playing NDS and GBA games, designed for iOS(iPhone and iPad) and also workable for other devices."> content="This is a personal fork of DeSmuME-WASM, a web emulator for playing NDS games, designed for iOS (iPhone and iPad) and also workable for other devices.">
<meta name="keywords" content="NDS, GBA, iOS, iPhone, iPad, emulator, DS, Safari, online, PWA"> <meta name="keywords" content="NDS, GBA, iOS, iPhone, iPad, emulator, DS, Safari, online, PWA">
<meta name="author" content="44670"> <meta name="author" content="44670">
</head> </head>
@ -126,138 +126,14 @@
} }
</style> </style>
<div id="welcome" class="menu"> <div id="welcome" class="menu">
<h1>DS Player</h1> <h1>Redirecting</h1>
<div id="loading">Loading...</div> <div id="loading">Click <a href="./">here</a> if not redirected automatically</div>
<div id="loadrom" hidden>
<input id="rom" type="file" hidden>
<button style="width:calc(100% - 2em);margin: 1em;" id="btn-choose-file">Choose File (or
drag/drop)...</button><br>
</div>
<p style="color: #888;">
Your files are processed locally and won't be uploaded to any server.<br>
This software should not be used to play games you have not legally obtained.<br>
"Nintendo DS" is a trademark of Nintendo Co., Ltd. This site is not associated with Nintendo in any way.
</p>
<hr>
<p><span id="ver-info"></span><a onclick="whatsNew()" id="whats-new" href="index.html#">What's New</a>&nbsp;|&nbsp;<a
href="index.html#" onclick="uiSwitchTo('menu')">⚙ Settings...</a></p>
<p id="p-sns">
<a href="https://ds.44670.org/gba/">GBA Player</a>
</p>
<p>
<a href="https://github.com/44670/desmume-wasm">Help</a>&nbsp;|&nbsp;<a href="index.html#" id="a-gamepad">No
Gamepad</a>
</p>
<p>
Powered by <a
href="https://github.com/44670/desmume-wasm">desmume-wasm.</a>&nbsp;|&nbsp;https://ds.44670.org<br>
</p>
<div id="pro" style="background-color: #333">
</div>
<p id="ios-power-hint" hidden>
Please <b>turn off "Low Power Mode"</b> in iOS Control Center for better performance.
</p>
<div id="mac-warning" hidden>
WARNING:<br>
It looks like you are using macOS.<br>
Due to macOS Safari <a href="https://webkit.org/tracking-prevention/">limitations</a>, ALL of you save data
will be LOST after 7 days of inactivity.<br>
For this reason, it is highly recommended to use a different browser. (For example: <a
href="https://www.google.com/chrome/">Chrome</a>)
</div>
</div>
<div id="ios-hint" hidden>
<h1>DS Player</h1>
Due to iOS limitations, please open this site(https://ds.44670.org) in <b>Safari</b>, and add it to your
<b>Home Screen</b> by <b>Share Menu</b> to continue.
<p style="text-align: center;">⬇⬇⬇</p>
</div>
<div id="vk-layer" hidden>
<div class="vk-rect vk" data-k="menu" id="vk-menu">M</div>
<div class="vk-rect vk" data-k="l">L</div>
<div class="vk-rect vk" data-k="r">R</div>
<div class="vk-round vk" data-k="a">A</div>
<div class="vk-round vk" data-k="b">B</div>
<div class="vk-round vk" data-k="x">X</div>
<div class="vk-round vk" data-k="y">Y</div>
<div class="vk-rect vk" data-k="select">SE</div>
<div class="vk-rect vk" data-k="start">ST</div>
<div class="vk-round vk" data-k="stick" id="vk-stick"></div>
<div id="vk-dpad-1" class="vk vk-round-rect"></div>
<div id="vk-dpad-2" class="vk vk-round-rect"></div>
</div>
<div style="z-index: 2;position: absolute;bottom: 20px;" id="fps"></div>
<div id="msg-layer" hidden>
<p id="msg-text"></p>
</div>
<div id="menu" hidden>
<button onclick="uiMenuBack()"> Back</button>
<hr>
<div id="cfg-ea" hidden>
<b>Early Access features</b><br>
Please note that these features are experimental and may not be stable.<br>
<input type="checkbox" id="cfg-turbo">
<label for="cfg-turbo">Turbo mode</label><br>
<br>
<label for="cfg-ls-layout">Landscape Screen Layout</label>
<select id="cfg-ls-layout" value="">
<option value="0">TB</option>
<option value="1">LR 1:1</option>
<option value="2">LR X:1</option>
</select><br>
<label for="cfg-scale-mode">Screen filter(restart required)</label>
<select id="cfg-scale-mode" value="">
<option value="0">Pixelated</option>
<option value="1">Smooth</option>
<option value="2">XBRZ</option>
</select><br>
</div>
<hr>
<input type="checkbox" id="power-save">
<label for="power-save">30FPS limit</label><br>
<input type="checkbox" id="vk-enabled">
<label for="vk-enabled">Virtual gamepad</label><br>
<input type="checkbox" id="cfg-mute-sound">
<label for="cfg-mute-sound">Mute sound</label><br>
<label for="vk-direction">Virtual gamepad Style</label>
<select id="vk-direction" value="">
<option value="0">Circle-Pad</option>
<option value="1">D-Pad</option>
</select><br>
<label for="cfg-lang">Firmware Language</label>
<select id="cfg-lang">
<option value="0">Japanese</option>
<option value="1">English</option>
<option value="2">French</option>
<option value="3">German</option>
<option value="4">Italian</option>
<option value="5">Spanish</option>
</select><br>
<input type="checkbox" id="cfg-swap-abxy">
<label for="cfg-swap-abxy">Gamepad: Swap A/B and X/Y</label><br>
<input type="checkbox" id="lid-closed" onchange="window.lidClosed = this.checked">
<label for="lid-closed">Close the lid</label><br>
<hr>
<div id="menu-savegame" hidden>
<input type="file" id="restore-file" onchange="uiSaveRestore()" hidden>
Save Data: <button onclick="uiSaveExport()">Backup</button>|<button
onclick="$id('restore-file').click()">Restore</button><br>
</div>
<hr>
Cloud Save:<span id="span-cloud-id"></span><br>
<button onclick="dpOnConnectButtonClicked()" id="btn-dp-connect">Connect Dropbox</button><br>
<button onclick="dpManualBtn(true)">↑ Upload</button>|<button
onclick="dpManualBtn(false)">↓ Download</button><br>
</div>
<div id="player" hidden>
<canvas id="top" width="256" height="192"></canvas>
<canvas id="bottom" width="256" height="192"></canvas>
</div> </div>
<script src="localforage.js"></script> <script src="localforage.js"></script>
<script src="pako.min.js"></script> <script src="pako.min.js"></script>
<script src="app.js"></script> <script src="app.js"></script>
<script src="build/nds.js"></script> <script>
window.location = "https://octospacc.gitlab.io/Web-Archives-Misc/Repo/DeSmuME" + window.location.hash;
</script>
</body> </body>
</html> </html>

View File

@ -1,5 +1,20 @@
var VER = 'v20230106' var VER = 'v2023-01-19'
const whatsNew = _ => {
alert(`\
{{ DeSmuME-WASM - OctoSpacc Fork }}
< Changelog >
[ 2023-01-19 ]
- Add this changelog and copyright notice
- Fix URL loading happening prematurely
- Change notices and visible options in the HTML
[ 2023-01-18 ]
- Add support for loading ROMs from URL
`)};
var EngineIsReady = false;
var isIOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform); var isIOS = !!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform);
var isMacOS = !!navigator.platform && /Mac/.test(navigator.platform); var isMacOS = !!navigator.platform && /Mac/.test(navigator.platform);
if (isMacOS) { if (isMacOS) {
@ -197,7 +212,6 @@ async function uiSaveRestore() {
}) })
} }
var gameID = '' var gameID = ''
var emuKeyState = new Array(14) var emuKeyState = new Array(14)
const emuKeyNames = ["right", "left", "down", "up", "select", "start", "b", "a", "y", "x", "l", "r", "debug", "lid"] const emuKeyNames = ["right", "left", "down", "up", "select", "start", "b", "a", "y", "x", "l", "r", "debug", "lid"]
var vkMap = {} var vkMap = {}
@ -209,20 +223,16 @@ for (var i = 0; i < emuKeyNames.length; i++) {
keyNameToKeyId[emuKeyNames[i]] = i keyNameToKeyId[emuKeyNames[i]] = i
} }
var isLandscape = false var isLandscape = false
const emuKeyboardMapping = [39, 37, 40, 38, 16, 13, 90, 88, 65, 83, 81, 87, -1, 8] const emuKeyboardMapping = [39, 37, 40, 38, 16, 13, 90, 88, 65, 83, 81, 87, -1, 8]
var emuIsRunning = false var emuIsRunning = false
var emuIsGameLoaded = false var emuIsGameLoaded = false
var fps = 0 var fps = 0
var divFPS = $id('fps') var divFPS = $id('fps')
var fileInput = $id('rom') var fileInput = $id('rom')
var romSize = 0 var romSize = 0
var FB = [0, 0] var FB = [0, 0]
var screenCanvas = [document.getElementById('top'), document.getElementById('bottom')] var screenCanvas = [document.getElementById('top'), document.getElementById('bottom')]
var ctx2d; var ctx2d;
var audioContext var audioContext
var audioBuffer var audioBuffer
var scriptNode var scriptNode
@ -231,8 +241,6 @@ var audioFifoL = new Int16Array(audioFifoCap)
var audioFifoR = new Int16Array(audioFifoCap) var audioFifoR = new Int16Array(audioFifoCap)
var audioFifoHead = 0 var audioFifoHead = 0
var audioFifoLen = 0 var audioFifoLen = 0
var frameCount = 0 var frameCount = 0
var prevCalcFPSTime = 0 var prevCalcFPSTime = 0
var touched = 0 var touched = 0
@ -242,7 +250,6 @@ var prevSaveFlag = 0
var lastTwoFrameTime = 10 var lastTwoFrameTime = 10
var fbSize var fbSize
function callPlugin(type, arg) { function callPlugin(type, arg) {
for (var k in plugins) { for (var k in plugins) {
if (plugins[k].handler) { if (plugins[k].handler) {
@ -299,10 +306,8 @@ function emuRunFrame() {
Module._runFrame(0, keyMask, touched, touchX, touchY) Module._runFrame(0, keyMask, touched, touchX, touchY)
emuRunAudio() emuRunAudio()
} }
Module._runFrame(1, keyMask, touched, touchX, touchY) Module._runFrame(1, keyMask, touched, touchX, touchY)
emuRunAudio() emuRunAudio()
if (optScaleMode < 2) { if (optScaleMode < 2) {
ctx2d[0].putImageData(FB[0], 0, 0) ctx2d[0].putImageData(FB[0], 0, 0)
ctx2d[1].putImageData(FB[1], 0, 0) ctx2d[1].putImageData(FB[1], 0, 0)
@ -310,8 +315,6 @@ function emuRunFrame() {
gpuDraw(screenCanvas[0], FB[0]) gpuDraw(screenCanvas[0], FB[0])
gpuDraw(screenCanvas[1], FB[1]) gpuDraw(screenCanvas[1], FB[1])
} }
frameCount += 1 frameCount += 1
if (frameCount % 120 == 0) { if (frameCount % 120 == 0) {
var time = performance.now() var time = performance.now()
@ -324,7 +327,6 @@ function emuRunFrame() {
} }
} }
function wasmReady() { function wasmReady() {
Module._setSampleRate(47856) Module._setSampleRate(47856)
setTimeout(() => { setTimeout(() => {
@ -347,6 +349,7 @@ function wasmReady() {
} else { } else {
gpuInit() gpuInit()
} }
EngineIsReady = true;
} }
function emuCopySavBuffer() { function emuCopySavBuffer() {
@ -481,7 +484,6 @@ function makeVKStyle(top, left, w, h, fontSize) {
return 'top:' + top + 'px;left:' + left + 'px;width:' + w + 'px;height:' + h + 'px;' + 'font-size:' + fontSize + 'px;line-height:' + h + 'px;' return 'top:' + top + 'px;left:' + left + 'px;width:' + w + 'px;height:' + h + 'px;' + 'font-size:' + fontSize + 'px;line-height:' + h + 'px;'
} }
function uiAdjustVKLayout() { function uiAdjustVKLayout() {
var baseSize = Math.min(window.innerWidth, window.innerHeight) * 0.14 * config.vkScale var baseSize = Math.min(window.innerWidth, window.innerHeight) * 0.14 * config.vkScale
var fontSize = baseSize * 0.7 var fontSize = baseSize * 0.7
@ -491,7 +493,6 @@ function uiAdjustVKLayout() {
var abxyHeight = baseSize * 3 var abxyHeight = baseSize * 3
var vkw = baseSize var vkw = baseSize
var vkh = baseSize var vkh = baseSize
vkw = baseSize * 1.5 vkw = baseSize * 1.5
vkh = baseSize * 0.6 vkh = baseSize * 0.6
fontSize = baseSize * 0.5 fontSize = baseSize * 0.5
@ -500,8 +501,6 @@ function uiAdjustVKLayout() {
vkw = baseSize * 0.4 vkw = baseSize * 0.4
vkh = baseSize * 0.4 vkh = baseSize * 0.4
$id('vk-menu').style = makeVKStyle(offTop, window.innerWidth / 2 - vkw / 2, vkw, vkh, fontSize) $id('vk-menu').style = makeVKStyle(offTop, window.innerWidth / 2 - vkw / 2, vkw, vkh, fontSize)
offTop += baseSize * 0.62 offTop += baseSize * 0.62
vkw = baseSize vkw = baseSize
vkh = baseSize vkh = baseSize
@ -510,13 +509,11 @@ function uiAdjustVKLayout() {
vkMap['b'].style = makeVKStyle(offTop + abxyHeight - vkh, offLeft + abxyWidth / 2 - vkw / 2, vkw, vkh, fontSize) vkMap['b'].style = makeVKStyle(offTop + abxyHeight - vkh, offLeft + abxyWidth / 2 - vkw / 2, vkw, vkh, fontSize)
vkMap['x'].style = makeVKStyle(offTop, offLeft + abxyWidth / 2 - vkw / 2, vkw, vkh, fontSize) vkMap['x'].style = makeVKStyle(offTop, offLeft + abxyWidth / 2 - vkw / 2, vkw, vkh, fontSize)
vkMap['y'].style = makeVKStyle(offTop + abxyHeight / 2 - vkh / 2, offLeft, vkw, vkh, fontSize) vkMap['y'].style = makeVKStyle(offTop + abxyHeight / 2 - vkh / 2, offLeft, vkw, vkh, fontSize)
vkw = baseSize * 1.0 vkw = baseSize * 1.0
vkh = baseSize * 1.0 vkh = baseSize * 1.0
offLeft = 0 offLeft = 0
$id('vk-stick').style = config.useDPad ? 'display:none;' : makeVKStyle(offTop + abxyHeight / 2 - vkh / 2, offLeft + abxyHeight / 2 - vkw / 2, vkw, vkh, fontSize) $id('vk-stick').style = config.useDPad ? 'display:none;' : makeVKStyle(offTop + abxyHeight / 2 - vkh / 2, offLeft + abxyHeight / 2 - vkw / 2, vkw, vkh, fontSize)
vkStickPos = [offTop + abxyHeight / 2, offLeft + abxyHeight / 2, vkw, vkh, fontSize] vkStickPos = [offTop + abxyHeight / 2, offLeft + abxyHeight / 2, vkw, vkh, fontSize]
var dpadW = abxyWidth var dpadW = abxyWidth
var dpadH = abxyHeight var dpadH = abxyHeight
var dpadX = offLeft var dpadX = offLeft
@ -554,7 +551,6 @@ function setScreenPos(c, left, top, w, h) {
} }
} }
function uiUpdateLayout() { function uiUpdateLayout() {
isLandscape = isScreenLandscape() isLandscape = isScreenLandscape()
if ((!isLandscape) || (config.lsLayout == 0)) { if ((!isLandscape) || (config.lsLayout == 0)) {
@ -597,11 +593,9 @@ function uiUpdateLayout() {
} }
} }
uiAdjustVKLayout() uiAdjustVKLayout()
} }
function uiSwitchTo(mode) { function uiSwitchTo(mode) {
if (mode == uiCurrentMode) { if (mode == uiCurrentMode) {
return return
@ -614,7 +608,6 @@ function uiSwitchTo(mode) {
body.style = '' body.style = ''
html.style = '' html.style = ''
emuIsRunning = false emuIsRunning = false
if (mode == 'player') { if (mode == 'player') {
body.style = 'touch-action: none;' body.style = 'touch-action: none;'
html.style = 'position: fixed;overflow:hidden;touch-action: none;' html.style = 'position: fixed;overflow:hidden;touch-action: none;'
@ -709,7 +702,6 @@ function tryInitSound() {
function emuLoop() { function emuLoop() {
window.requestAnimationFrame(emuLoop) window.requestAnimationFrame(emuLoop)
if (emuIsRunning && (!emuUseTimer33)) { if (emuIsRunning && (!emuUseTimer33)) {
prevRunFrameTime = performance.now() prevRunFrameTime = performance.now()
emuRunFrame() emuRunFrame()
@ -753,32 +745,25 @@ function handleTouch(event) {
} }
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
var isDown = false var isDown = false
var x = 0 var x = 0
var y = 0 var y = 0
var needUpdateStick = false var needUpdateStick = false
var stickY = vkStickPos[0] var stickY = vkStickPos[0]
var stickX = vkStickPos[1] var stickX = vkStickPos[1]
var stickW = vkStickPos[2] var stickW = vkStickPos[2]
var stickH = vkStickPos[3] var stickH = vkStickPos[3]
var stickPressed = false var stickPressed = false
var stickDeadZone = stickW * 0.2 var stickDeadZone = stickW * 0.2
var nextStickTouchID = null var nextStickTouchID = null
var nextTpadTouchID = null var nextTpadTouchID = null
var tsRect = screenCanvas[1].getBoundingClientRect() var tsRect = screenCanvas[1].getBoundingClientRect()
for (var i = 0; i < emuKeyState.length; i++) { for (var i = 0; i < emuKeyState.length; i++) {
emuKeyState[i] = false emuKeyState[i] = false
} }
for (var k in vkState) { for (var k in vkState) {
vkState[k][1] = 0 vkState[k][1] = 0
} }
for (var i = 0; i < event.touches.length; i++) { for (var i = 0; i < event.touches.length; i++) {
var t = event.touches[i]; var t = event.touches[i];
var tid = t.identifier var tid = t.identifier
@ -805,7 +790,6 @@ function handleTouch(event) {
} else { } else {
if ((tid === stickTouchID) || ((dom == vkMap['stick']) && (tid != tpadTouchID))) { if ((tid === stickTouchID) || ((dom == vkMap['stick']) && (tid != tpadTouchID))) {
stickPressed = true stickPressed = true
vkState['stick'][1] = 1 vkState['stick'][1] = 1
var sx = t.clientX var sx = t.clientX
var sy = t.clientY var sy = t.clientY
@ -844,11 +828,9 @@ function handleTouch(event) {
continue continue
} }
} }
touched = isDown ? 1 : 0; touched = isDown ? 1 : 0;
touchX = x touchX = x
touchY = y touchY = y
for (var k in vkState) { for (var k in vkState) {
if (vkState[k][0] != vkState[k][1]) { if (vkState[k][0] != vkState[k][1]) {
var dom = vkMap[k] var dom = vkMap[k]
@ -867,7 +849,6 @@ function handleTouch(event) {
} }
} }
for (var i = 0; i < emuKeyState.length; i++) { for (var i = 0; i < emuKeyState.length; i++) {
var k = emuKeyNames[i] var k = emuKeyNames[i]
if (vkState[k]) { if (vkState[k]) {
@ -876,11 +857,9 @@ function handleTouch(event) {
} }
} }
} }
if (needUpdateStick) { if (needUpdateStick) {
vkMap['stick'].style = makeVKStyle(stickY - stickW / 2, stickX - stickW / 2, stickW, stickH, vkStickPos[4]) vkMap['stick'].style = makeVKStyle(stickY - stickW / 2, stickX - stickW / 2, stickW, stickH, vkStickPos[4])
} }
stickTouchID = nextStickTouchID stickTouchID = nextStickTouchID
tpadTouchID = nextTpadTouchID tpadTouchID = nextTpadTouchID
} }
@ -888,9 +867,6 @@ function handleTouch(event) {
window.addEventListener(val, handleTouch) window.addEventListener(val, handleTouch)
}) })
window.onmousedown = window.onmouseup = window.onmousemove = (e) => { window.onmousedown = window.onmouseup = window.onmousemove = (e) => {
if (!emuIsRunning) { if (!emuIsRunning) {
return return
@ -981,7 +957,6 @@ if (isSaveSupported) {
}); });
} }
function processGamepadInput() { function processGamepadInput() {
var padMap = gamePadKeyMap var padMap = gamePadKeyMap
if (config.swapABXY) { if (config.swapABXY) {
@ -1023,8 +998,6 @@ function processGamepadInput() {
} }
} }
var isMicrophoneEnabled = false var isMicrophoneEnabled = false
var micPtr var micPtr
var micBuf var micBuf
@ -1080,7 +1053,6 @@ function enableMicrophone() {
} }
} }
micScriptNode.connect(audioContext.destination); micScriptNode.connect(audioContext.destination);
}); });
} }
@ -1088,8 +1060,6 @@ function isScreenLandscape() {
return (window.innerWidth / window.innerHeight) > 1.2 return (window.innerWidth / window.innerHeight) > 1.2
} }
if (location.origin == 'https://ds.44670.org') { if (location.origin == 'https://ds.44670.org') {
if (isSaveSupported) { if (isSaveSupported) {
// Register Service Worker // Register Service Worker
@ -1110,7 +1080,6 @@ if (location.origin == 'https://ds.44670.org') {
} }
} }
(function () { (function () {
var cnt = 0; var cnt = 0;
// Prompt to install PWA // Prompt to install PWA
window.onbeforeinstallprompt = function (e) { window.onbeforeinstallprompt = function (e) {
@ -1497,7 +1466,6 @@ function gpuDraw(canvas, idata) {
gl.drawArrays(gl.TRIANGLES, 0, 6); gl.drawArrays(gl.TRIANGLES, 0, 6);
} }
function gpuInit() { function gpuInit() {
if (!gpuInitWithCanvas(screenCanvas[0])) { if (!gpuInitWithCanvas(screenCanvas[0])) {
return return
@ -1505,7 +1473,6 @@ function gpuInit() {
gpuInitWithCanvas(screenCanvas[1]); gpuInitWithCanvas(screenCanvas[1]);
} }
var DP_BASE_PATH = "/dssav" var DP_BASE_PATH = "/dssav"
var DP_EXT = ".4dsaz" var DP_EXT = ".4dsaz"
@ -1519,8 +1486,6 @@ function dpGetCurrentDayInt() {
return retInt; return retInt;
} }
function dpIsConnected() { function dpIsConnected() {
return localStorage['d-token'] ? true : false return localStorage['d-token'] ? true : false
} }
@ -1536,7 +1501,6 @@ async function dpIDHash(gameID) {
return digestHex.substring(0, 8) return digestHex.substring(0, 8)
} }
async function dpGameLoaded() { async function dpGameLoaded() {
if (dpIsConnected()) { if (dpIsConnected()) {
var hash = await dpIDHash(gameID) var hash = await dpIDHash(gameID)
@ -1544,7 +1508,6 @@ async function dpGameLoaded() {
} }
} }
async function dpConnect() { async function dpConnect() {
var redirectUri = encodeURIComponent(location.origin) var redirectUri = encodeURIComponent(location.origin)
var url = "https://www.dropbox.com/oauth2/authorize?client_id=zro5k6xlnsxu4gz&response_type=code&token_access_type=offline" var url = "https://www.dropbox.com/oauth2/authorize?client_id=zro5k6xlnsxu4gz&response_type=code&token_access_type=offline"
@ -1705,9 +1668,6 @@ async function dpTryUploadCloudSave(gameID, tag, u8Arr, mode) {
return false return false
} }
async function dpTryAutoBackup() { async function dpTryAutoBackup() {
if (!dpIsConnected()) { if (!dpIsConnected()) {
return false return false
@ -1724,9 +1684,6 @@ async function dpTryAutoBackup() {
return false return false
} }
function dpOnConnectButtonClicked() { function dpOnConnectButtonClicked() {
if (dpIsConnected()) { if (dpIsConnected()) {
if (confirm("Are you sure to disconnect from Dropbox?")) { if (confirm("Are you sure to disconnect from Dropbox?")) {
@ -1742,7 +1699,6 @@ function dpOnConnectButtonClicked() {
} }
async function dpManualBtn(isUpload) { async function dpManualBtn(isUpload) {
if (!dpIsConnected()) { if (!dpIsConnected()) {
alert("Please connect to Dropbox first.") alert("Please connect to Dropbox first.")
return return
@ -1792,11 +1748,25 @@ const LoadRomFromUrl = _ => {
Req.open('GET', RomUrl, true); Req.open('GET', RomUrl, true);
Req.responseType = 'blob'; Req.responseType = 'blob';
Req.onload = function() { Req.onload = function() {
while (!EngineIsReady) {};
tryLoadROM(Req.response); tryLoadROM(Req.response);
}; };
Req.send(); Req.send();
}; };
}; };
/*
const RomUrlBoxChange = _ => {
if (RomUrlBox.value) {
$id('btn-choose-file').innerHTML = 'Load from URL!';
} else {
$id('btn-choose-file').innerHTML = 'Choose File (or drag/drop)...';
};
};
['onchange', 'oninput', 'onpaste'].forEach(function (i) {
RomUrlBox[i] = RomUrlBoxChange;
});
*/
dpOnLoad(); dpOnLoad();
LoadRomFromUrl(); LoadRomFromUrl();

View File

@ -9,10 +9,10 @@
<link rel="manifest" href="manifest.json"> <link rel="manifest" href="manifest.json">
<link rel="apple-touch-icon" href="https://ds.44670.org/icon.png"> <link rel="apple-touch-icon" href="https://ds.44670.org/icon.png">
<link href="dark.css" rel="stylesheet"> <link href="dark.css" rel="stylesheet">
<title>DS Player</title> <title>DeSmuME-WASM Fork</title>
<!-- Add hint for search engine --> <!-- Add hint for search engine -->
<meta name="description" <meta name="description"
content="DS Player is a web emulator for playing NDS and GBA games, designed for iOS(iPhone and iPad) and also workable for other devices."> content="This is a personal fork of DeSmuME-WASM, a web emulator for playing NDS games, designed for iOS (iPhone and iPad) and also workable for other devices.">
<meta name="keywords" content="NDS, GBA, iOS, iPhone, iPad, emulator, DS, Safari, online, PWA"> <meta name="keywords" content="NDS, GBA, iOS, iPhone, iPad, emulator, DS, Safari, online, PWA">
<meta name="author" content="44670"> <meta name="author" content="44670">
</head> </head>
@ -126,33 +126,42 @@
} }
</style> </style>
<div id="welcome" class="menu"> <div id="welcome" class="menu">
<h1>DS Player</h1> <h1>DeSmuME-WASM Fork</h1>
<div id="loading">Loading...</div> <div id="loading">Loading...</div>
<div id="loadrom" hidden> <div id="loadrom" hidden>
<!--<input id="RomUrlBox" type="text" placeholder="Paste a ROM URL to load from that...">-->
<input id="rom" type="file" hidden> <input id="rom" type="file" hidden>
<button style="width:calc(100% - 2em);margin: 1em;" id="btn-choose-file">Choose File (or <button style="width:calc(100% - 2em);margin: 1em;" id="btn-choose-file">Choose File (or
drag/drop)...</button><br> drag/drop)...</button><br>
</div> </div>
<p style="color: #888;"> <p style="color: #888; font-size: smaller;">
Your files are processed locally and won't be uploaded to any server.<br> Your files are processed locally and won't be uploaded to any server.<br>
This software should not be used to play games you have not legally obtained.<br> This software should not be used to play games you have not legally obtained.<br>
"Nintendo DS" is a trademark of Nintendo Co., Ltd. This site is not associated with Nintendo in any way. This software is released under the GPL-2 license. Visit the original repo to read the terms.
<br>Changes in this fork from the original version are stated in the changelog.
<br>Modified parts of the source are "index.html" and "app.js" of this website, you can view their code directly.
<br>Compiled parts ("nds.js", "nds.wasm") are not modified and you can find their source on the original repo.
</p> </p>
<hr> <hr>
<p><span id="ver-info"></span><a onclick="whatsNew()" id="whats-new" href="index.html#">What's New</a>&nbsp;|&nbsp;<a <p><span id="ver-info"></span><a onclick="whatsNew()" id="whats-new" href="index.html#">What's New</a>&nbsp;|&nbsp;<a
href="index.html#" onclick="uiSwitchTo('menu')">⚙ Settings...</a></p> href="index.html#" onclick="uiSwitchTo('menu')">⚙ Settings...</a></p>
<p id="p-sns"> <p id="p-sns">
<a href="https://ds.44670.org/gba/">GBA Player</a> <a href="https://gba.44670.org">GBA Player</a>
</p> </p>
<p> <p>
<a href="https://github.com/44670/desmume-wasm">Help</a>&nbsp;|&nbsp;<a href="index.html#" id="a-gamepad">No <a href="https://github.com/44670/desmume-wasm">Help</a><!--&nbsp;|&nbsp;<a href="index.html#" id="a-gamepad">No
Gamepad</a> Gamepad--></a>
</p> </p>
<p> <p>
Powered by <a Powered by <a
href="https://github.com/44670/desmume-wasm">desmume-wasm.</a>&nbsp;|&nbsp;https://ds.44670.org<br> href="https://github.com/44670/desmume-wasm">desmume-wasm.</a>&nbsp;|&nbsp;OctoSpacc Fork <span style="font-size: smaller;">(Click on "What's New" for more information - DO NOT report issues with this fork to the original developer!)</span><br>
</p> </p>
<!--
<p>
Powered by <a
href="https://github.com/octospacc/DeSmuME-WASM">DeSmuME-WASM - OctoSpacc Fork</a> (GPLv2)--&nbsp;|&nbsp;OctoSpacc fork--<br>
</p>
-->
<div id="pro" style="background-color: #333"> <div id="pro" style="background-color: #333">
</div> </div>
@ -195,7 +204,7 @@
<div id="menu" hidden> <div id="menu" hidden>
<button onclick="uiMenuBack()"> Back</button> <button onclick="uiMenuBack()"> Back</button>
<hr> <hr>
<div id="cfg-ea" hidden> <div id="cfg-ea">
<b>Early Access features</b><br> <b>Early Access features</b><br>
Please note that these features are experimental and may not be stable.<br> Please note that these features are experimental and may not be stable.<br>
<input type="checkbox" id="cfg-turbo"> <input type="checkbox" id="cfg-turbo">