17 Commits

Author SHA1 Message Date
Felix Rieseberg
6aa39e66ec 2.0.0 2019-02-03 15:40:31 -08:00
Felix Rieseberg
ed42ea8e0e fix: Ensure smooth migration 2019-02-03 15:38:06 -08:00
Felix Rieseberg
0779f18071 fix: Handle missing state 2019-02-03 15:24:29 -08:00
Felix Rieseberg
a9c4e38386 feat: Allow resetting the machien 2019-02-03 15:23:20 -08:00
Felix Rieseberg
62b0909cb4 fix: Correctly capture the mouse 2019-02-03 14:08:09 -08:00
Felix Rieseberg
873cb75241 fix: the various things I just broke 2019-02-03 14:02:30 -08:00
Felix Rieseberg
6467acb0c8 fix: Cleanup 2019-02-03 13:49:09 -08:00
Felix Rieseberg
ed1bd0a1e0 chore: Custom menu 2019-02-03 13:44:57 -08:00
Felix Rieseberg
ac84f4164e fix: Don't clear the cache on each start 2019-02-03 12:36:06 -08:00
Felix Rieseberg
77569d4ce6 infra: Update dependencies 2019-02-03 12:33:11 -08:00
Felix Rieseberg
68b7c181ad Merge pull request #109 from samuell/patch-1
Update README.md: Fix broken download links
2018-12-30 09:25:24 +01:00
Felix Rieseberg
293491477b Merge pull request #111 from malept/forge-arch-squirrel
chore: automatically add arch to squirrel installer filename
2018-12-30 09:24:56 +01:00
Felix Rieseberg
7eb750752b infra: Update to Electron 4.0 2018-12-30 09:22:32 +01:00
Mark Lee
f1488cedc2 Make it look more like a function 2018-12-26 22:41:56 -08:00
Mark Lee
9f366063eb chore: automatically add arch to squirrel installer filename 2018-12-26 22:40:08 -08:00
Samuel Lampa
55135f052e Update README.md: Fix download links
Fixes download links for Windows and the .deb Linux installer
2018-12-21 15:08:18 +01:00
Felix Rieseberg
95fd8e4925 chore: Update the readme with new download links 2018-12-20 11:25:33 -08:00
19 changed files with 1282 additions and 877 deletions

View File

@@ -7,8 +7,8 @@ Interested in Electron? Join as at [CovalenceConf](http://covalenceconf.com) in
## Downloads
| | Windows | macOS | Linux |
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Standalone Download | 📦[Standalone, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.3.0/windows95-win32-1.3.0-standalone-ia32.zip) <br /> 📦[Standalone, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.3.0/windows95-win32-1.3.0-standalone-x64.zip) | 📦[Standalone](https://github.com/felixrieseberg/windows95/releases/download/v1.3.0/windows95-macos-1.3.0.zip) | |
| Installer | 💽[Setup, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.3.0/windows95-win32-1.3.0-setup-x64.exe) <br /> 💽[Setup, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.3.0/windows95-win32-1.3.0-setup-ia32.exe) | | 💽[deb, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.3.0/windows95-linux_1.3.0_amd64.deb) <br /> 💽[rpm, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.3.0/windows95-linux-1.3.0.x86_64.rpm) |
| Standalone Download | 📦[Standalone, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.4.0/windows95-1.4.0-win32-standalone-ia32.zip) <br /> 📦[Standalone, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.4.0/windows95-1.4.0-win32-standalone-x64.zip) | 📦[Standalone](https://github.com/felixrieseberg/windows95/releases/download/v1.4.0/windows95-macos-1.4.0.zip) | |
| Installer | 💽[Setup, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.4.0/windows95-1.4.0-setup-win32-x64.exe) <br /> 💽[Setup, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.4.0/windows95-1.4.0-setup-win32-ia32.exe) | | 💽[deb, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.4.0/windows95-linux-1.4.0_amd64.deb) <br /> 💽[rpm, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v1.4.0/windows95-linux-1.4.0.x86_64.rpm) |
![Screenshot](https://user-images.githubusercontent.com/1426799/44532591-4ceb3680-a6a8-11e8-8c2c-bc29f3bfdef7.png)

View File

@@ -21,16 +21,18 @@ module.exports = {
{
name: '@electron-forge/maker-squirrel',
platforms: ['win32'],
config: {
name: 'windows95',
authors: 'Felix Rieseberg',
exe: 'windows95.exe',
noMsi: true,
remoteReleases: '',
setupExe: `windows95-${package.version}-setup-${process.arch}.exe`,
setupIcon: path.resolve(__dirname, 'assets', 'icon.ico'),
certificateFile: process.env.WINDOWS_CERTIFICATE_FILE,
certificatePassword: process.env.WINDOWS_CERTIFICATE_PASSWORD
config: (arch) => {
return {
name: 'windows95',
authors: 'Felix Rieseberg',
exe: 'windows95.exe',
noMsi: true,
remoteReleases: '',
setupExe: `windows95-${package.version}-setup-${arch}.exe`,
setupIcon: path.resolve(__dirname, 'assets', 'icon.ico'),
certificateFile: process.env.WINDOWS_CERTIFICATE_FILE,
certificatePassword: process.env.WINDOWS_CERTIFICATE_PASSWORD
}
}
},
{

1536
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
{
"name": "windows95",
"productName": "windows95",
"version": "1.4.0",
"version": "2.0.0",
"description": "Windows 95, in an app. I'm sorry.",
"main": "src/index.js",
"scripts": {
@@ -28,19 +28,19 @@
]
},
"dependencies": {
"electron-default-menu": "^1.0.1",
"electron-squirrel-startup": "^1.0.0",
"fs-extra": "^7.0.0",
"fs-extra": "^7.0.1",
"update-electron-app": "^1.3.0"
},
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.30",
"@electron-forge/maker-deb": "^6.0.0-beta.30",
"@electron-forge/maker-flatpak": "^6.0.0-beta.30",
"@electron-forge/maker-rpm": "^6.0.0-beta.30",
"@electron-forge/maker-squirrel": "^6.0.0-beta.30",
"@electron-forge/maker-zip": "^6.0.0-beta.30",
"electron": "3.0.13",
"standard": "^11.0.1"
"@electron-forge/cli": "^6.0.0-beta.32",
"@electron-forge/maker-deb": "^6.0.0-beta.32",
"@electron-forge/maker-flatpak": "^6.0.0-beta.32",
"@electron-forge/maker-rpm": "^6.0.0-beta.32",
"@electron-forge/maker-squirrel": "^6.0.0-beta.32",
"@electron-forge/maker-zip": "^6.0.0-beta.32",
"electron": "4.0.4",
"node-abi": "^2.6.0",
"standard": "^12.0.1"
}
}

24
src/constants.js Normal file
View File

@@ -0,0 +1,24 @@
const { remote, app } = require('electron')
const path = require('path')
const _app = app || remote.app
const CONSTANTS = {
IMAGE_PATH: path.join(__dirname, 'images/windows95.img'),
IMAGE_DEFAULT_SIZE: 1073741824, // 1GB
DEFAULT_STATE_PATH: path.join(__dirname, 'images/default-state.bin'),
STATE_PATH: path.join(_app.getPath('userData'), 'state-v2.bin')
}
const IPC_COMMANDS = {
TOGGLE_INFO: 'TOGGLE_INFO',
MACHINE_RESTART: 'MACHINE_RESTART',
MACHINE_RESET: 'MACHINE_RESET',
MACHINE_CTRL_ALT_DEL: 'MACHINE_CTRL_ALT_DEL',
SHOW_DISK_IMAGE: 'SHOW_DISK_IMAGE'
}
module.exports = {
CONSTANTS,
IPC_COMMANDS
}

View File

@@ -1,7 +1,6 @@
const { app, BrowserWindow } = require('electron')
const path = require('path')
const { clearCaches } = require('./cache')
const { createMenu } = require('./menu')
const { setupProtocol } = require('./es6')
@@ -21,8 +20,8 @@ let mainWindow
const createWindow = () => {
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1280,
height: 800,
width: 1024,
height: 768,
useContentSize: true,
webPreferences: {
nodeIntegration: false,
@@ -40,7 +39,6 @@ const createWindow = () => {
app.on('ready', async () => {
await setupProtocol()
await createMenu()
await clearCaches()
createWindow()
})

View File

@@ -1,8 +1,10 @@
const { app, shell, Menu, BrowserWindow } = require('electron')
const defaultMenu = require('electron-default-menu')
const { clearCaches } = require('./cache')
const { IPC_COMMANDS } = require('./constants')
const LINKS = {
homepage: 'https://www.felixrieseberg.com',
homepage: 'https://www.twitter.com/felixrieseberg',
repo: 'https://github.com/felixrieseberg/windows95',
credits: 'https://github.com/felixrieseberg/windows95/blob/master/CREDITS.md',
help: 'https://github.com/felixrieseberg/windows95/blob/master/HELP.md'
@@ -17,74 +19,162 @@ function send (cmd) {
}
async function createMenu () {
const menu = defaultMenu(app, shell)
.map((item) => {
if (item.label === 'View') {
item.submenu = item.submenu.filter((subItem) => {
return subItem.label !== 'Reload'
})
}
if (item.label === 'Help') {
item.submenu = [
{
label: 'Author',
click() {
shell.openExternal(LINKS.homepage)
},
},
{
label: 'Learn More',
click() {
shell.openExternal(LINKS.repo)
},
},
{
type: 'separator'
},
{
label: 'Help',
click() {
shell.openExternal(LINKS.help)
}
},
{
label: 'Credits',
click() {
shell.openExternal(LINKS.credits)
}
const template = [
{
label: 'View',
submenu: [
{
label: 'Toggle Full Screen',
accelerator: (function () {
if (process.platform === 'darwin') { return 'Ctrl+Command+F' } else { return 'F11' }
})(),
click: function (_item, focusedWindow) {
if (focusedWindow) { focusedWindow.setFullScreen(!focusedWindow.isFullScreen()) }
}
]
}
},
{
label: 'Toggle Developer Tools',
accelerator: (function () {
if (process.platform === 'darwin') { return 'Alt+Command+I' } else { return 'Ctrl+Shift+I' }
})(),
click: function (_item, focusedWindow) {
if (focusedWindow) { focusedWindow.toggleDevTools() }
}
},
{
type: 'separator'
},
{
label: 'Toggle Emulator Info',
click: () => send(IPC_COMMANDS.TOGGLE_INFO)
}
]
},
{
label: 'Window',
role: 'window',
submenu: [
{
label: 'Minimize',
accelerator: 'CmdOrCtrl+M',
role: 'minimize'
},
{
label: 'Close',
accelerator: 'CmdOrCtrl+W',
role: 'close'
}
]
},
{
label: 'Machine',
submenu: [
{
label: 'Send Ctrl+Alt+Del',
click: () => send(IPC_COMMANDS.MACHINE_CTRL_ALT_DEL)
},
{
label: 'Restart',
click: () => send(IPC_COMMANDS.MACHINE_RESTART)
},
{
label: 'Reset',
click: () => send(IPC_COMMANDS.MACHINE_RESET)
},
{
type: 'separator'
},
{
label: 'Go to Disk Image',
click: () => send(IPC_COMMANDS.SHOW_DISK_IMAGE)
}
]
},
{
label: 'Help',
role: 'help',
submenu: [
{
label: 'Author',
click: () => shell.openExternal(LINKS.homepage)
},
{
label: 'windows95 on GitHub',
click: () => shell.openExternal(LINKS.repo)
},
{
label: 'Help',
click: () => shell.openExternal(LINKS.help)
},
{
type: 'separator'
},
{
label: 'Troubleshooting',
submenu: [
{
label: 'Clear Cache and Restart',
async click () {
await clearCaches()
return item
})
.filter((item) => {
return item.label !== 'Edit'
app.relaunch()
app.quit()
}
}
]
}
]
}
]
if (process.platform === 'darwin') {
template.unshift({
label: 'windows95',
submenu: [
{
label: 'About windows95',
role: 'about'
},
{
type: 'separator'
},
{
label: 'Services',
role: 'services',
submenu: []
},
{
type: 'separator'
},
{
label: 'Hide windows95',
accelerator: 'Command+H',
role: 'hide'
},
{
label: 'Hide Others',
accelerator: 'Command+Shift+H',
role: 'hideothers'
},
{
label: 'Show All',
role: 'unhide'
},
{
type: 'separator'
},
{
label: 'Quit',
accelerator: 'Command+Q',
click () {
app.quit()
}
}
]
})
}
menu.splice(1, 0, {
label: 'Machine',
submenu: [
{
label: 'Send Ctrl+Alt+Del',
click: () => send('ctrlaltdel')
},
{
label: 'Restart',
click: () => send('restart')
},
{
type: 'separator'
},
{
label: 'Go to Disk Image',
click: () => send('disk-image')
}
]
})
Menu.setApplicationMenu(Menu.buildFromTemplate(menu))
Menu.setApplicationMenu(Menu.buildFromTemplate(template))
}
module.exports = {

View File

@@ -1,45 +1,42 @@
const { remote, shell, ipcRenderer } = require('electron')
const path = require('path')
const EventEmitter = require('events')
const { STATE_PATH, resetState, restoreState, saveState } = require('./state')
const { resetState, restoreState, saveState } = require('./state')
const { getDiskImageSize } = require('./utils/disk-image-size')
const { IPC_COMMANDS, CONSTANTS } = require('./constants')
window.windows95 = {
STATE_PATH,
restoreState,
resetState,
saveState,
class Windows95 extends EventEmitter {
constructor () {
super()
// Constants
this.CONSTANTS = CONSTANTS
this.IPC_COMMANDS = IPC_COMMANDS
// Methods
this.getDiskImageSize = getDiskImageSize
this.restoreState = restoreState
this.resetState = resetState
this.saveState = saveState
Object.keys(IPC_COMMANDS).forEach((command) => {
ipcRenderer.on(command, (...args) => {
this.emit(command, args)
})
})
}
showDiskImage () {
const imagePath = path.join(__dirname, 'images/windows95.img')
.replace('app.asar', 'app.asar.unpacked')
shell.showItemInFolder(imagePath)
},
}
quit: () => remote.app.quit()
quit () {
remote.app.quit()
}
}
ipcRenderer.on('ctrlaltdel', () => {
if (!window.emulator || !window.emulator.is_running) return
window.emulator.keyboard_send_scancodes([
0x1D, // ctrl
0x38, // alt
0x53, // delete
// break codes
0x1D | 0x80,
0x38 | 0x80,
0x53 | 0x80
])
})
ipcRenderer.on('restart', () => {
if (!window.emulator || !window.emulator.is_running) return
window.emulator.restart()
})
ipcRenderer.on('disk-image', () => {
windows95.showDiskImage()
})
window.windows95 = new Windows95()

View File

@@ -1,8 +1,9 @@
export function setupState () {
window.appState = {
isResetting: false,
isQuitting: false,
cursorCaptured: false,
floppyFile: null,
bootFresh: false,
infoInterval: null
bootFresh: false
}
}

Binary file not shown.

Binary file not shown.

View File

@@ -13,7 +13,7 @@ export function setupButtons (start) {
$('#discard-state').addEventListener('click', () => {
window.appState.bootFresh = true
start('win95')
start()
})
// Floppy

View File

@@ -14,7 +14,7 @@
<div id="status">
Disk: <span id="disk-status">Idle</span>
| CPU Speed: <span id="cpu-status">0</span>
| <a onclick="document.querySelector('#status').style.display='none'">Hide</a>
| <a href="#" id="toggle-status">Hide</a>
</div>
<div id="buttons">
<div id="start-buttons">

View File

@@ -1,28 +1,63 @@
const $ = document.querySelector.bind(document)
const status = $('#status')
const diskStatus = $('#disk-status')
const cpuStatus = $('#cpu-status')
const toggleStatus = $('#toggle-status')
export function setupInfo () {
const diskStatus = $('#disk-status')
const cpuStatus = $('#cpu-status')
let lastCounter = 0
let lastTick = 0
let lastCounter = 0
let lastTick = 0
let infoInterval = null
window.emulator.add_listener('ide-read-start', () => {
diskStatus.innerHTML = 'Read'
})
const onIDEReadStart = () => {
diskStatus.innerHTML = 'Read'
}
window.emulator.add_listener('ide-read-end', () => {
diskStatus.innerHTML = 'Idle'
})
const onIDEReadWriteEnd = () => {
diskStatus.innerHTML = 'Idle'
}
window.emulator.add_listener('ide-write-end', () => {
diskStatus.innerHTML = 'Idle'
})
toggleStatus.onclick = toggleInfo
window.emulator.add_listener('screen-set-size-graphical', (...args) => {
console.log(...args)
})
/**
* Toggle the information display
*/
export function toggleInfo () {
if (status.style.display !== 'none') {
disableInfo()
} else {
enableInfo()
}
}
setInterval(() => {
/**
* Start information gathering, but only if the panel is visible
*/
export function startInfoMaybe () {
if (status.style.display !== 'none') {
enableInfo()
}
}
/**
* Enable the gathering of information (and hide the little information tab)
*/
export function enableInfo () {
// Show the info thingy
status.style.display = 'block'
// We can only do the rest with an emulator
if (!window.emulator.add_listener) {
return
}
// Set listeners
window.emulator.add_listener('ide-read-start', onIDEReadStart)
window.emulator.add_listener('ide-read-end', onIDEReadWriteEnd)
window.emulator.add_listener('ide-write-end', onIDEReadWriteEnd)
window.emulator.add_listener('screen-set-size-graphical', console.log)
// Set an interval
infoInterval = setInterval(() => {
const now = Date.now()
const instructionCounter = window.emulator.get_instruction_counter()
const ips = instructionCounter - lastCounter
@@ -34,3 +69,26 @@ export function setupInfo () {
cpuStatus.innerHTML = Math.round(ips / deltaTime)
}, 500)
}
/**
* Disable the gathering of information (and hide the little information tab)
*/
export function disableInfo () {
// Hide the info thingy
status.style.display = 'none'
// Clear the interval
clearInterval(infoInterval)
infoInterval = null
// We can only do the rest with an emulator
if (!window.emulator.remove_listener) {
return
}
// Unset the listeners
window.emulator.remove_listener('ide-read-start', onIDEReadStart)
window.emulator.remove_listener('ide-read-end', onIDEReadWriteEnd)
window.emulator.remove_listener('ide-write-end', onIDEReadWriteEnd)
window.emulator.remove_listener('screen-set-size-graphical', console.log)
}

44
src/renderer/ipc.js Normal file
View File

@@ -0,0 +1,44 @@
import { toggleInfo } from 'es6://info.js'
export function setupIpcListeners (start) {
const { windows95 } = window
windows95.addListener(windows95.IPC_COMMANDS.TOGGLE_INFO, () => {
toggleInfo()
})
windows95.addListener(windows95.IPC_COMMANDS.MACHINE_RESTART, () => {
console.log(`Restarting machine`)
if (!window.emulator || !window.emulator.is_running) return
window.emulator.restart()
})
windows95.addListener(windows95.IPC_COMMANDS.MACHINE_RESET, () => {
console.log(`Resetting machine`)
window.appState.isResetting = true
document.location.hash = `#AUTO_START`
document.location.reload()
})
windows95.addListener(windows95.IPC_COMMANDS.MACHINE_CTRL_ALT_DEL, () => {
if (!window.emulator || !window.emulator.is_running) return
window.emulator.keyboard_send_scancodes([
0x1D, // ctrl
0x38, // alt
0x53, // delete
// break codes
0x1D | 0x80,
0x38 | 0x80,
0x53 | 0x80
])
})
windows95.addListener(windows95.IPC_COMMANDS.SHOW_DISK_IMAGE, () => {
windows95.showDiskImage()
})
}

View File

@@ -9,6 +9,7 @@ export function setupCloseListener () {
window.onbeforeunload = (event) => {
if (window.appState.isQuitting) return
if (window.appState.isResetting) return
handleClose()
event.preventDefault()
@@ -22,6 +23,7 @@ export function setupEscListener () {
if (evt.keyCode === 27) {
if (window.appState.cursorCaptured) {
window.appState.cursorCaptured = false
window.emulator.mouse_set_status(false)
document.exitPointerLock()
} else {
window.appState.cursorCaptured = true
@@ -31,11 +33,15 @@ export function setupEscListener () {
}
}
export function setupClickListener () {
document.addEventListener('click', () => {
if (!window.appState.cursorCaptured) {
window.appState.cursorCaptured = true
window.emulator.lock_mouse()
}
})
function onDocumentClick () {
if (!window.appState.cursorCaptured) {
window.appState.cursorCaptured = true
window.emulator.mouse_set_status(true)
window.emulator.lock_mouse()
}
}
export function setupClickListener () {
document.removeEventListener('click', onDocumentClick)
document.addEventListener('click', onDocumentClick)
}

View File

@@ -1,7 +1,9 @@
/* We're using modern esm imports here */
import { setupState } from 'es6://app-state.js'
import { setupClickListener, setupEscListener, setupCloseListener } from 'es6://listeners.js'
import { toggleButtons, setupButtons } from 'es6://buttons.js'
import { setupInfo } from 'es6://info.js'
import { startInfoMaybe } from 'es6://info.js'
import { setupIpcListeners } from 'es6://ipc.js'
setupState()
@@ -9,9 +11,10 @@ setupState()
* The main method executing the VM.
*/
async function main () {
// New v86 instance
window.emulator = new V86Starter({
memory_size: 64 * 1024 * 1024,
const imageSize = await window.windows95.getDiskImageSize()
const options = {
memory_size: 128 * 1024 * 1024,
video_memory_size: 32 * 1024 * 1024,
screen_container: document.getElementById('emulator'),
bios: {
url: './bios/seabios.bin'
@@ -22,21 +25,19 @@ async function main () {
hda: {
url: '../images/windows95.img',
async: true,
size: 242049024
size: imageSize
},
fda: {
buffer: window.appState.floppyFile || undefined
},
boot_order: 0x132
})
// High DPI support
if (navigator.userAgent.includes('Windows')) {
const scale = window.devicePixelRatio
window.emulator.screen_adapter.set_scale(scale, scale)
}
console.log(`Starting emulator with options`, options)
// New v86 instance
window.emulator = new V86Starter(options)
// Restore state. We can't do this right away
// and randomly chose 500ms as the appropriate
// wait time (lol)
@@ -45,7 +46,7 @@ async function main () {
windows95.restoreState()
}
setupInfo()
startInfoMaybe()
window.appState.cursorCaptured = true
window.emulator.lock_mouse()
@@ -61,6 +62,11 @@ function start () {
main()
}
setupIpcListeners(start)
setupEscListener()
setupCloseListener()
setupButtons(start)
if (document.location.hash.includes('AUTO_START')) {
start()
}

View File

@@ -1,9 +1,6 @@
const fs = require('fs-extra')
const path = require('path')
const { remote } = require('electron')
const DEFAULT_PATH = path.join(__dirname, 'images/default-state.bin')
const STATE_PATH = path.join(remote.app.getPath('userData'), 'state.bin')
const { CONSTANTS } = require('./constants')
/**
* Returns the current machine's state - either what
@@ -12,11 +9,13 @@ const STATE_PATH = path.join(remote.app.getPath('userData'), 'state.bin')
* @returns {ArrayBuffer}
*/
function getState () {
const statePath = fs.existsSync(STATE_PATH)
? STATE_PATH
: DEFAULT_PATH
const statePath = fs.existsSync(CONSTANTS.STATE_PATH)
? CONSTANTS.STATE_PATH
: CONSTANTS.DEFAULT_STATE_PATH
return fs.readFileSync(statePath).buffer
if (fs.existsSync(statePath)) {
return fs.readFileSync(statePath).buffer
}
}
/**
@@ -25,8 +24,8 @@ function getState () {
* @returns {Promise<void>}
*/
async function resetState () {
if (fs.existsSync(STATE_PATH)) {
return fs.remove(STATE_PATH)
if (fs.existsSync(CONSTANTS.STATE_PATH)) {
return fs.remove(CONSTANTS.STATE_PATH)
}
}
@@ -43,13 +42,13 @@ async function saveState () {
window.emulator.save_state(async (error, newState) => {
if (error) {
console.log(error)
console.warn(`State: Could not save state`, error)
return
}
await fs.outputFile(STATE_PATH, Buffer.from(newState))
await fs.outputFile(CONSTANTS.STATE_PATH, Buffer.from(newState))
console.log(`Saved state to ${STATE_PATH}`)
console.log(`State: Saved state to ${CONSTANTS.STATE_PATH}`)
resolve()
})
@@ -60,15 +59,21 @@ async function saveState () {
* Restores the VM's state.
*/
function restoreState () {
const state = getState()
// Nothing to do with if we don't have a state
if (!state) {
console.log(`State: No state present, not restoring.`)
}
try {
window.emulator.restore_state(getState())
window.emulator.restore_state(state)
} catch (error) {
console.log(`Could not read state file. Maybe none exists?`, error)
console.log(`State: Could not read state file. Maybe none exists?`, error)
}
}
module.exports = {
STATE_PATH,
saveState,
restoreState,
resetState,

View File

@@ -0,0 +1,26 @@
const fs = require('fs-extra')
const { CONSTANTS } = require('../constants')
/**
* Get the size of the disk image
*
* @returns {number}
*/
async function getDiskImageSize () {
try {
const stats = await fs.stat(CONSTANTS.IMAGE_PATH)
if (stats) {
return stats.size
}
} catch (error) {
console.warn(`Could not determine image size`, error)
}
return CONSTANTS.IMAGE_DEFAULT_SIZE
}
module.exports = {
getDiskImageSize
}