Path: blob/main/static/src/gs/public/microsoft-flight-simulator/dos.js
1325 views
let game = {};1let screen;2let ram;3let graphics = {};4let doStopLoop = true;56function getScancode(key) {7//alert(key);8switch (key) {9case "Escape":10return 0x01; // esc11case "F1":12return 0x3b;13case "F2":14return 0x3c;15case "F3":16return 0x3d;17case "F4":18return 0x3e;19case "F5":20return 0x3f;21case "F6":22return 0x40;23case "F7":24return 0x41;25case "F8":26return 0x42;27case "F9":28return 0x43;29case "F10":30return 0x44;31case "F11":32return 0x57;33case "F12":34return 0x58;3536case "ScrollLock":37return 0x46;38case "Pause":39return -1; // not supported4041case "Backquote":42return 0x29; // 143case "Digit1":44return 0x02; // 145case "Digit2":46return 0x03; // 247case "Digit3":48return 0x04; // 349case "Digit4":50return 0x05; // 451case "Digit5":52return 0x06; // 553case "Digit6":54return 0x07; // 655case "Digit7":56return 0x08; // 757case "Digit8":58return 0x09; // 859case "Digit9":60return 0x0a; // 961case "Digit0":62return 0x0b; // 063case "KeyA":64return 0x1e; // a65case "KeyB":66return 0x30; // b67case "KeyC":68return 0x2e; // c69case "KeyD":70return 0x20; // d71case "KeyE":72return 0x12; // e73case "KeyF":74return 0x21; // f75case "KeyG":76return 0x22; // g77case "KeyH":78return 0x23; // h79case "KeyI":80return 0x17; // i81case "KeyJ":82return 0x24; // j83case "KeyK":84return 0x25; // k85case "KeyL":86return 0x26; // l87case "KeyM":88return 0x32; // m89case "KeyN":90return 0x31; // n91case "KeyO":92return 0x18; // o93case "KeyP":94return 0x19; // p95case "KeyQ":96return 0x10; // q97case "KeyR":98return 0x13; // r99case "KeyS":100return 0x1f; // s101case "KeyT":102return 0x14; // t103case "KeyU":104return 0x16; // u105case "KeyV":106return 0x2f; // v107case "KeyW":108return 0x11; // w109case "KeyX":110return 0x2d; // x111case "KeyY":112return 0x2c; // y113case "KeyZ":114return 0x15; // z115case "ShiftLeft":116return 0x2a; // left shift117case "ShiftRight":118return 0x36; // right shift119case "Space":120return 0x39; // space121case "Enter":122return 0x1c; // enter123case "Backspace":124return 0xe; // backspace125case "ControlLeft":126return 0x1d; // left ctrl127case "ControlRight":128return 0x1d; // right ctrl129case "ArrowUp":130return 0x48; // cursor up131case "ArrowDown":132return 0x50; // cursor down133case "ArrowLeft":134return 0x4b; // cursor left135case "ArrowRight":136return 0x4d; // cursor right137case "Insert":138return 0x52; // ins139case "Home":140return 0x47; // home141case "PageUp":142return 0x49; // pg up143case "Delete":144return 0x53; // del145case "End":146return 0x4f; // end147case "PageDown":148return 0x51; // pg down149case "NumLock":150return 0x45; // num lock151case "NumpadDivide":152return 0x35; // num pad divide153case "NumpadMultiply":154return 0x37; // num pad multiply155case "NumpadSubtract":156return 0x4a; // num pad subtract157case "NumpadAdd":158return 0x4e; // num pad add159case "NumpadEnter":160return 0x1c; // enter161case "Numpad0":162return 0x52; // 0163case "NumpadDecimal":164return 0x53; //165case "Numpad1":166return 0x4f; // 1167case "Numpad2":168return 0x50; // 2169case "Numpad3":170return 0x51; // 3171case "Numpad4":172return 0x4b; // 4173case "Numpad5":174return 0x4c; // 5175case "Numpad6":176return 0x4d; // 6177case "Numpad7":178return 0x47; // 7179case "Numpad8":180return 0x48; // 8181case "Numpad9":182return 0x49; // 9183case "Minus":184return 0x0c; // -185case "Equal":186return 0x0d; // =187case "BracketLeft":188return 0x1a; // [189case "BracketRight":190return 0xab; // ]191case "Semicolon":192return 0x27; // ;193case "Quote":194return 0x28; // '195case "Backslash":196return 0x2b; // \197case "Comma":198return 0x33; // ,199case "Period":200return 0x34; // .201case "Slash":202return 0x35; // /203case "IntlBackslash":204return 0x56; // <205case "ContextMenu":206return -1;207case "AltRight":208return 38;209}210console.log("Unknown key " + key);211return -1;212}213214function DetectKeysDown(e) {215e.preventDefault();216//if (e.repeat) return;217let scancode = getScancode(e.code);218if (scancode === -1) return;219game.KeyDown(scancode);220}221222function DetectKeysUp(e) {223//if (e.repeat) return;224e.preventDefault();225let scancode = getScancode(e.code);226if (scancode === -1) return;227game.KeyUp(scancode);228}229230function GetMousePosition(e)231{232// fix for Chrome233if (e.type.startsWith('touch'))234{235return [e.targetTouches[0].pageX, e.targetTouches[0].pageY];236} else237{238return [e.pageX, e.pageY];239}240}241/*242function getMouseRelativeToCanvas(canvas, position) {243let rect = canvas.getBoundingClientRect();244return {245x: evt.clientX - rect.left,246y: evt.clientY - rect.top247};248}249*/250251function getMouseRelativeToCanvas(canvas, position) {252let rect = canvas.getBoundingClientRect();253return {254x: (position[0] - rect.left) / rect.width,255y: (position[1] - rect.top) / rect.height256};257}258259function DetectMouseMove(e) {260e.preventDefault();261let currentMousePosition = GetMousePosition(e);262let normalizedPosition = getMouseRelativeToCanvas(graphics.scaledcanvas, currentMousePosition);263game.MouseMotion(normalizedPosition.x*graphics.canvas.width, normalizedPosition.y*graphics.canvas.height);264}265266function DetectMouseUp(e) {267game.MouseButtonUp(1);268}269270function DetectMouseDown(e) {271game.MouseButtonDown(1);272}273274function ReinitGraphics() {275graphics.canvas = document.createElement('canvas');276graphics.mode = game.VGA_GetVideoMode();277switch(graphics.mode) {278case 0x0:279case 0x2:280case 0x3:281case 0x6:282graphics.canvas.width = 640;283graphics.canvas.height = 200;284break;285286case 0x1:287graphics.canvas.width = 320;288graphics.canvas.height = 400;289break;290case 0x7:291case 0x14:292graphics.canvas.width = 720;293graphics.canvas.height = 400;294break;295296case 0x4:297case 0xd:298case 0x13:299graphics.canvas.width = 320;300graphics.canvas.height = 200;301break;302case 0x10:303graphics.canvas.width = 640;304graphics.canvas.height = 350;305break;306307default:308graphics.canvas.width = 640;309graphics.canvas.height = 480;310break;311}312313graphics.ctx = graphics.canvas.getContext("2d");314graphics.data = graphics.ctx.createImageData(graphics.canvas.width, graphics.canvas.height);315}316317function resizeCanvas() {318//graphics.scaledcanvas.style.height = window.innerHeight + "px";319//graphics.scaledcanvas.style.width = window.innerWidth + "px";320321let viewwidth = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;322let viewheight = window.innerHeight|| document.documentElement.clientHeight || document.body.clientHeight;323324viewwidth *= 3./4.; // grid fraction325let ratio = viewwidth/viewheight;326if (ratio > 4./3.) {327graphics.scaledcanvas.style.width = "auto";328graphics.scaledcanvas.style.height = "100%";329} else {330graphics.scaledcanvas.style.width = "100%";331graphics.scaledcanvas.style.height = "auto";332}333334/*335336let height = graphics.scaledcanvas.innerWidth * 0.75;337if (viewheight < height) {338alert("be careful");339graphics.scaledcanvas.style.height = window.innerHeight + "px";340graphics.scaledcanvas.style.width = ((window.innerHeight*4./3.)|0) + "px";341} else {342graphics.scaledcanvas.style.width = "100%";343graphics.scaledcanvas.style.height = "auto";344}345*/346}347348function Init() {349graphics.scaledcanvas = document.getElementById("screen");350graphics.scaledcanvas.width = 640;351graphics.scaledcanvas.height = 480;352graphics.scaledctx = graphics.scaledcanvas.getContext("2d");353window.addEventListener('resize', resizeCanvas, false);354resizeCanvas();355356ReinitGraphics();357window.onkeydown = DetectKeysDown;358window.onkeyup = DetectKeysUp;359graphics.scaledcanvas.onmousemove = DetectMouseMove;360graphics.scaledcanvas.onmousedown = DetectMouseDown;361graphics.scaledcanvas.onmouseup = DetectMouseUp;362window.ontouchstart = DetectMouseDown;363window.ontouchend = DetectMouseUp;364window.ontouchmove = DetectMouseMove;365}366367let lastDate = null;368// returns the time since the last call369function getDeltaMs() {370if (lastDate === null) {371lastDate = new Date();372return 0;373}374let lastTime = lastDate.getTime();375lastDate = new Date();376return lastDate.getTime() - lastTime;377}378379function Loop() {380if (doStopLoop) return;381382let delta = getDeltaMs();383if (delta > 60) delta = 60; // just make sure the browser is not locked forever384game.Run(delta*5000);385//game.Run(500000);386game.UpdateScreen();387388if (graphics.mode != game.VGA_GetVideoMode()) ReinitGraphics();389let width = graphics.canvas.width;390let height = graphics.canvas.height;391for (let j = 0; j < height; j++) {392let offsets = j * 720 * 4;393let offsetg = j * width * 4;394for (let i = 0; i < width * 4; i++) {395graphics.data.data[offsetg++] = screen[offsets++];396}397}398graphics.ctx.putImageData(graphics.data, 0, 0);399graphics.scaledctx.drawImage(400graphics.canvas,4010, 0, graphics.canvas.width, graphics.canvas.height,4020, 0, graphics.scaledcanvas.width, graphics.scaledcanvas.height);403404window.requestAnimationFrame(Loop);405//window.setTimeout(Loop, 0);406}407408let str = "";409410function Stdout(strp) {411for (let i = 0; i < 256; i++) {412if (ram[strp + i] === 0) break;413if (ram[strp + i] < 0x20) {414if (ram[strp + i] === 0x0A) {415console.log(str);416str = "";417continue;418}419}420str += String.fromCharCode(ram[strp + i]);421}422}423424function MountFs(fsAsByteArray) {425426let filesystem = new Uint8Array(fsAsByteArray);427let uncompressed = [];428console.log("decompress filesystem of size " + fsAsByteArray.byteLength);429bzip2.simple(filesystem, function(byte){uncompressed.push(byte)});430console.log("decompressed filesystem of size " + uncompressed.length);431let fsaddress = game.GetMountStorage(uncompressed.length);432for(let i=0;i<uncompressed.length;i++) ram[fsaddress+i] = uncompressed[i];433game.FinishMountStorage();434}435436function Main(version) {437doStopLoop = true;438let importOb = {439env: {440memory: new WebAssembly.Memory({initial: 512, maximum: 512}), // 8 MB441exit: function (code) {442console.log("Exit code " + code);443console.log("Restart");444Main(version);445},446outputstr: Stdout447}448};449450Promise451.all([fetch('fshistory.wasm'), fetch('data/fs'+version+'.fs.bz2')])452.then(responses => Promise.all([responses[0].arrayBuffer(), responses[1].arrayBuffer()]))453.then(data => Promise.all([WebAssembly.instantiate(data[0], importOb), Promise.resolve(data[1])])454).then(455objs => {456console.log("wasm file loaded");457game = objs[0].instance.exports;458ram = new Uint8Array(importOb.env.memory.buffer, 0);459game.Init();460MountFs(objs[1]);461462game.SetFSVersion(version);463screen = new Uint8Array(importOb.env.memory.buffer, game.ScreenGet());464Init();465console.log("Initialization completed. Starting Loop");466doStopLoop = false;467Loop();468//alert(game.__heap_base.value);469//alert(game.__global_base.value);470},471err => alert(err)472);473}474475476