search

Home  >  Q&A  >  body text

Getting emulator errors

<p>I've been trying to reverse engineer a GBA emulator (https://gba.44670.org/) that I found online and using an HTML extractor to try to replicate it. I wanted it to work offline, so I downloaded all the scripts to my computer and ran them there. However, after this, the "Select File" button no longer appears, replaced by the "Loading, please wait..." text line. Digging deeper into the code I found that it has something to do with WASM. The code is as follows: </p> <pre class="brush:php;toolbar:false;"><div id="wasm-loading"> Loading, please wait... </div> <div id="select-rom" hidden> <input type="file" id="romFile" onchange="onFileSelected()" hidden /></p> <button onclick="$id('romFile').click()" id="btn-choose">Choose File...</button> </div></pre> <p>Other references to WASM in the code are in the .js file app.js: </p> <pre class="brush:php;toolbar:false;">function wasmReady() { romBuffer = Module._emuGetSymbol(1) var ptr = Module._emuGetSymbol(2) wasmSaveBuf = Module.HEAPU8.subarray(ptr, ptr wasmSaveBufLen) ptr = Module._emuGetSymbol(3) imgFrameBuffer = new Uint8ClampedArray(Module.HEAPU8.buffer).subarray(ptr, ptr 240 * 160 * 4) idata = new ImageData(imgFrameBuffer, 240, 160) isWasmReady = true document.getElementById('wasm-loading').hidden = true document.getElementById('select-rom').hidden = false }</pre> <p>I expected that once I downloaded the script it would work like normal. I mean, it still has access to the scripts it needs, right? I've tried hiding the text by changing the true/false statements in <code>document.getElementById('select-rom').hidden = false</code> and vice versa, but nothing seems to work. Any ideas? Thanks in advance. </p> <p>(BTW, I'm looking for the file path in vscode.dev. It looks like this: <code><script src="/Scripts/44gba.js"></script> < ;script src="/Scripts /app.js"></script> <script src="/Scripts/localforage.js"></script> <script src=/Scripts/pako.min .js></script></code> )</p>
P粉447495069P粉447495069445 days ago823

reply all(1)I'll reply

  • P粉550823577

    P粉5508235772023-09-02 11:05:59

    To use a script to keep an application local, remember two things:

    1. The script has been written and will search for resources (js, css, pictures) in the current App directory structure
    2. Requests and file reads are blocked by CORS in most browsers unless you disable CORS preflight checks.

    That is, copy the same HTML you get in the response (https://gba.44670.org/ ), which will preserve the file structure. This is what I get (index.html):

    <html lang="en"><head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height">
        <link rel="apple-touch-icon" href="icon.png">
        <link rel="manifest" href="manifest.json">
        <title>44VBA</title>
    
    </head>
    
    <body>
        <style>
            a,
            a:visited {
                color: white;
            }
    
            html,
            body {
                position: fixed;
                overflow: hidden;
                -webkit-user-select: none;
                user-select: none;
                -webkit-touch-callout: none;
                touch-action: none;
                cursor: inherit;
            }
    
            body {
    
                background-color: #000000;
                color: #FFFFFF;
                padding: 0;
                margin: 0;
                width: 100vw;
                height: 100vh;
                font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;
            }
    
            hr {
                color: white;
            }
    
            button {
                border: 2px solid white;
                background: transparent;
                color: white;
                padding: .5em;
            }
    
            .vk-round {
                text-align: center;
                vertical-align: middle;
                border-radius: 50%;
                display: inline-block;
            }
    
    
            .vk {
                color: rgba(0, 0, 0, 0.2);
                background-color: rgba(255, 255, 255, 0.25);
                position: absolute;
                z-index: 1;
                text-align: center;
                vertical-align: middle;
                display: inline-block;
            }
    
            .vk-hide {
                background-color: transparent !important
            }
    
            .vk-touched {
                background-color: rgba(255, 255, 255, 0.75) !important
            }
    
            .menu {
                background: rgb(32, 43, 56);
                position: absolute;
                left: 0;
                top: 0;
                width: 100vw;
                height: 100vh;
                z-index: 999;
            }
    
            #gba-canvas {
                position: absolute;
                z-index: -1;
            }
    
            #vk-layer {
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                z-index: 3;
                touch-action: none;
            }
    
            #msg-layer {
                position: absolute;
                left: 0;
                width: 100%;
                top: 40vh;
                background: rgba(0, 0, 0, 0.5);
                z-index: 2;
            }
    
            textarea {
                background: transparent;
                color: #fff;
                border: 2px solid white;
    
            }
    
            /* textarea placeholder */
            textarea::placeholder {
                color: #666;
            }
        </style>
        <div id="pause-menu" class="menu" style="background: rgba(32,43,56,0.7);" hidden="">
            <button onclick="setPauseMenu(false)"> ← Back </button>
            <hr>
            Savegame management:<br>
            <button onclick="savBackupBtn()">Backup</button>
            <input type="file" id="sav-file" onchange="savRestoreBtn()" hidden="">
            <button onclick="$id('sav-file').click()">Restore</button>
            <hr>
            <label for="cfg-scale-mode">Screen filter:</label>
            <select id="cfg-scale-mode">
                <option value="0">Pixelated</option>
                <option value="1">Smooth</option>
                <option value="2">XBRZ</option>
            </select><br>
            <input type="checkbox" id="cfg-mute">
            <label for="cfg-mute">Mute Sound</label><br>
            <input type="checkbox" id="cfg-turbo">
            <label for="cfg-turbo">Turbo mode</label><br>
            <div id="div-cht">
                Cheat Codes(backup your savegame before using it):<br>
                <textarea id="txt-code" style="width:100%" rows="10" placeholder="Cheat code:
    GamesharkAdv: XXXXXXXX YYYYYYYY
    CodeBreaker: XXXXXXXX YYYY"></textarea><br>
                <button onclick="chtSaveBtn()">Save Cheat Codes</button>
            </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="welcome" class="menu">
            <h1 id="title">44VBA</h1>
            <hr>
            <div id="wasm-loading" hidden="">
                Loading, please wait...
            </div>
            <div id="select-rom">
                <input type="file" id="romFile" onchange="onFileSelected()" hidden=""><p></p>
                <button onclick="$id('romFile').click()" id="btn-choose">Choose File...</button>
            </div>
            <hr>
            Ver. 20230107 | <a href="https://github.com/44670/44vba">GitHub</a>
            <p>
                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>
                "GBA", "Game Boy Advance" are trademarks of Nintendo Co.,Ltd, This site is not associated with Nintendo in
                any way.
            </p>
            <div id="ios-hint" hidden="">
                Due to iOS limitations, please open this site(https://gba.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>
        <div id="msg-layer" hidden="">
            <p id="msg-text">Gamepad disconnected.</p>
        </div>
        <div id="vk-layer" hidden="">
            <div class="vk-rect vk" data-k="menu" style="top: 25px; left: 591px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">Menu</div>
            <div class="vk-rect vk" data-k="turbo" style="top: 25px; left: 0px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">F.F.</div>
            <div class="vk-rect vk" data-k="l" style="top: 75px; left: 0px; width: 150px; height: 50px; font-size: 35px; line-height: 50px;">L</div>
            <div class="vk-rect vk" data-k="r" style="top: 75px; left: 591px; width: 150px; height: 50px; font-size: 35px; line-height: 50px;">R</div>
            <div class="vk-round vk" data-k="a" style="top: 175px; left: 676px; width: 65px; height: 65px; font-size: 35px; line-height: 65px;">A</div>
            <div class="vk-round vk" data-k="b" style="top: 200px; left: 585px; width: 65px; height: 65px; font-size: 35px; line-height: 65px;">B</div>
            <div class="vk-rect vk" data-k="select" style="top: 605px; left: 205.5px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">Select</div>
            <div class="vk-rect vk" data-k="start" style="top: 605px; left: 385.5px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">Start</div>
            <div class=" vk" data-k="left" style="top: 200px; left: 0px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">←</div>
            <div class=" vk" data-k="right" style="top: 200px; left: 100px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">→</div>
            <div class=" vk" data-k="up" style="top: 150px; left: 50px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">↑</div>
            <div class=" vk" data-k="down" style="top: 250px; left: 50px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">↓</div>
            <div class=" vk vk-hide" style="top: 150px; left: 0px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="ul"></div>
            <div class=" vk vk-hide" style="top: 150px; left: 100px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="ur"></div>
            <div class=" vk vk-hide" style="top: 250px; left: 0px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="dl"></div>
            <div class=" vk vk-hide" style="top: 250px; left: 100px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="dr"></div>
        </div>
        <canvas width="240" height="160" id="gba-canvas" style="width: 741px; height: 494px; left: 0px; image-rendering: pixelated;"></canvas>
        <script src="pako.min.js"></script>
        <script src="localforage.js"></script>
        <script src="app.js"></script>
        <script src="build/44gba.js"></script>
    
    
    
    
    </body></html>

    Then you can see the script path where you will create the file:

    <script src="pako.min.js"></script>
    <script src="localforage.js"></script>
    <script src="app.js"></script>
    <script src="build/44gba.js"></script>

    Additionally, you will need to download the WASM file (651KB compressed, 7.7MB uncompressed). You can download the tarball here (you can find it in the "Network" tab of the dev tools): https://gba.44670.org/build/44gba.wasm

    Finally, download all necessary files (you can also download icons and images if you want, but they are not required):

    You will get a structure like this:

    Now, it would be great if you could deactivate CORS from your browser. But if not, you have to serve it from a local HTTP server. One option is to install the NPM package: https://www.npmjs.com/package/http-server, run npm install --global http-server. After that, just navigate to the project directory in the terminal and start the server:

    npx http-server ./ --port 4000

    You will see the correct screen and load the ROM, then you are done.

    Edit: Solving local CORS issues with a simple Hack

    Since I know you are now using ChromeOS and technically don't know how to use Node, NPM and HTTP-Server to handle it, I made some modifications for you and put the WASM binary content directly Enter < code>build/44gba.js and return the binary content on the function readBinary to bypass the CORS issue. You can launch index.html directly. Here is the link to the new build/44gba.js file, just replace its contents with the following file: https://sendeyo.com/en/b02f94b524 You're all good . The following are the changes:

    const wasmData = `0061 736d 0100 0000 01c9 011e 6001 7f00
    6002 7f7f 0060 0000 6001 7f01 7f60 037f
    ...  ...  ...  ...  ...  ...  ...  ...
    0a00 41c0 8106 0b04 7064 6202`;
    
    // other codes ...
    
    readBinary = filename=>{
        var ret = new Uint8Array(wasmData);
        return ret;
        /* var ret = read_(filename, true);
        if (!ret.buffer) {
            ret = new Uint8Array(ret)
        }
        return ret
        */
    }
    
    // other codes ...

    reply
    0
  • Cancelreply