8 Commits

Author SHA1 Message Date
Felix Rieseberg
58add05655 build: Build on push 2020-08-02 13:33:54 -07:00
Felix Rieseberg
0a400d915f build: Fix macOS cert 2020-08-02 13:27:05 -07:00
Felix Rieseberg
f615e7754c 2.2.2 2020-08-02 13:13:52 -07:00
Felix Rieseberg
92717c8047 chore: Updated prettier run 2020-08-02 13:11:20 -07:00
Felix Rieseberg
045b83f843 build: Move to GitHub Actions, upgrade dependencies 2020-08-02 13:09:13 -07:00
Felix Rieseberg
1dd3b76187 Merge pull request #153 from PF94/patch-1
Improve HELP.MD a little bit.
2020-01-15 15:38:04 -08:00
PF94
4b1dd6146c Improve HELP.MD a little bit.
* Add some caplization to "Command Prompt", "Window Mode" and "Full Screen" mode
* Changed "brick" to "mess up" as "bricked" means that the operating system is permanently damaged.
* Add another "enter" for the "What's the FrontPage Username and Password?" section, now people won't accidently connect as "windows95Password".
* Fix DisplacedGamers missing "s" in the end.
2020-01-11 22:18:39 -05:00
Felix Rieseberg
3601599ff1 docs: Update readme 2019-12-04 10:17:07 -08:00
28 changed files with 8821 additions and 12279 deletions

View File

@@ -1,49 +0,0 @@
environment:
matrix:
- nodejs_version: "10"
init:
- git config --global core.symlinks true
install:
# Setup the code signing certificate
- ps: >-
if (Test-Path Env:\WINDOWS_CERTIFICATE_P12) {
$workingDirectory = Convert-Path (Resolve-Path -path ".")
$filename = "$workingDirectory\cert.p12"
$bytes = [Convert]::FromBase64String($env:WINDOWS_CERTIFICATE_P12)
[IO.File]::WriteAllBytes($filename, $bytes)
$env:WINDOWS_CERTIFICATE_FILE = $filename
$sec = ConvertTo-SecureString -String $env:WINDOWS_CERTIFICATE_PASSWORD -Force -AsPlainText
$cert = Get-PfxData -Password $sec $filename
Write-Host $cert.EndEntityCertificates
}
- ps: Install-Product node $env:nodejs_version x64
- node --version
- npm ci
- ps: mkdir images
- ps: cd images
- ps: Start-FileDownload 'https://1drv.ws/u/s!AkfaAw_EaahOkulh8rA41x2phgfYXQ' -FileName images.zip -Timeout 600000
- ps: 7z x images.zip -y -aoa
- ps: Remove-Item images.zip
- ps: Remove-Item __MACOSX -Recurse -ErrorAction Ignore
- ps: cd ..
- ps: Tree ./src /F
- ps: Tree ./images /F
cache:
- '%APPDATA%\npm-cache -> appveyor.yml'
test_script:
- node --version
- npm --version
- npm run lint
artifacts:
- path: 'out\make\squirrel.windows\**\*.exe'
build_script:
- if %APPVEYOR_REPO_TAG% EQU false npm run make
- if %APPVEYOR_REPO_TAG% EQU true npm run publish
- if %APPVEYOR_REPO_TAG% EQU true npm run publish -- --arch=ia32
- ps: Tree ./out/make /F

1
.gitattributes vendored Normal file
View File

@@ -0,0 +1 @@
text eol=lf

115
.github/workflows/build.yml vendored Normal file
View File

@@ -0,0 +1,115 @@
name: Build & Release
on:
push:
branches:
- master
tags:
- v*
pull_request:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Install
run: yarn
- name: lint
run: yarn lint
build:
needs: lint
name: Build (${{ matrix.os }})
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ macOS-latest, ubuntu-latest, windows-latest ]
steps:
- uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v1
with:
node-version: 12.x
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1
if: matrix.os != 'macOS-latest'
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
- name: Set MacOS signing certs
if: matrix.os == 'macOS-latest'
run: chmod +x tools/add-macos-cert.sh && ./tools/add-macos-cert.sh
env:
MACOS_CERT_P12: ${{ secrets.MACOS_CERT_P12 }}
MACOS_CERT_PASSWORD: ${{ secrets.MACOS_CERT_PASSWORD }}
- name: Set Windows signing certificate
if: matrix.os == 'windows-latest'
continue-on-error: true
id: write_file
uses: timheuer/base64-to-file@v1
with:
fileName: 'win-certificate.pfx'
encodedString: ${{ secrets.WINDOWS_CODESIGN_P12 }}
- name: Download disk image (ps1)
run: tools/download-disk.ps1
if: matrix.os == 'windows-latest' && startsWith(github.ref, 'refs/tags/')
env:
DISK_URL: ${{ secrets.DISK_URL }}
- name: Download disk image (sh)
run: chmod +x tools/download-disk.sh && ./tools/download-disk.sh
if: matrix.os != 'windows-latest' && startsWith(github.ref, 'refs/tags/')
env:
DISK_URL: ${{ secrets.DISK_URL }}
- name: Install
run: yarn
- name: Make
if: startsWith(github.ref, 'refs/tags/')
run: yarn make
env:
APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
WINDOWS_CODESIGN_FILE: ${{ steps.write_file.outputs.filePath }}
WINDOWS_CODESIGN_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PASSWORD }}
- name: Make (ia32)
if: matrix.os == 'windows-latest' && startsWith(github.ref, 'refs/tags/')
run: yarn make -- --arch=ia32
env:
WINDOWS_CODESIGN_FILE: ${{ steps.write_file.outputs.filePath }}
WINDOWS_CODESIGN_PASSWORD: ${{ secrets.WINDOWS_CODESIGN_PASSWORD }}
# - name: Archive production artifacts
# uses: actions/upload-artifact@v2
# with:
# name: ${{ matrix.os }}
# path: out/make/**/*
- name: Release
uses: softprops/action-gh-release@v1
if: startsWith(github.ref, 'refs/tags/')
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
draft: true
files: |
out/**/*.deb
out/**/*.dmg
out/**/*setup*.exe
out/**/*.rpm
out/**/*.zip

View File

@@ -1,64 +0,0 @@
language: node_js
node_js: "12"
os:
- linux
- osx
dist: trusty
osx_image: xcode10
sudo: false
cache:
directories:
- node_modules
- $HOME/.cache/electron
addons:
apt:
packages:
- fakeroot
- rpm
branches:
only:
- master
- /^v\d+\.\d+\.\d+/
install:
- npm install
- mkdir -p ./images
- cd ./images
- wget -O images.zip https://1drv.ws/u/s!AkfaAw_EaahOkulh8rA41x2phgfYXQ
- unzip -o images.zip
- rm images.zip
- rm -r __MACOSX
- cd ..
- ls src
- ls images
- |
if [[ "$TRAVIS_OS_NAME" == "osx" && "$TRAVIS_SECURE_ENV_VARS" == "true" ]]; then
export CERTIFICATE_P12=cert.p12;
echo $MACOS_CERT_P12 | base64 --decode > $CERTIFICATE_P12;
export KEYCHAIN=build.keychain;
# Create the keychain with a password
security create-keychain -p travis $KEYCHAIN;
# Make the custom keychain default, so xcodebuild will use it for signing
security default-keychain -s $KEYCHAIN;
# Unlock the keychain
security unlock-keychain -p travis $KEYCHAIN;
# Add certificates to keychain and allow codesign to access them
# Apple Worldwide Developer Relations Certification Authority
security import ./assets/certs/apple.cer -k ~/Library/Keychains/$KEYCHAIN -T /usr/bin/codesign
# Developer Authentication Certification Authority
security import ./assets/certs/dac.cer -k ~/Library/Keychains/$KEYCHAIN -T /usr/bin/codesign
# Developer ID Felix
security import $CERTIFICATE_P12 -k $KEYCHAIN -P $MACOS_CERT_PASSWORD -T /usr/bin/codesign 2>&1 >/dev/null;
rm $CERTIFICATE_P12;
security set-key-partition-list -S apple-tool:,apple: -s -k travis $KEYCHAIN
# Echo the identity
security find-identity -v -p codesigning
fi
script:
- npm run lint
- if test -z "$TRAVIS_TAG"; then npm run make; fi
after_success: if test -n "$TRAVIS_TAG"; then npm run publish; fi

View File

@@ -1,10 +1,10 @@
# Help & Commonly Asked Questions
## MS-DOS seems to brick the screen
Hit `Alt + Enter` to make the command screen "full screen" (as far as Windows 95 is
## MS-DOS seems to mess up the screen
Hit `Alt + Enter` to make the command screen "Full Screen" (as far as Windows 95 is
concerned). This should restore the display from the garbled mess you see and allow
you to access the command prompt. Press Alt-Enter again to leave full screen and go
back to a window mode. (Thanks to @DisplacedGamer for that wisdom)
you to access the Command Prompt. Press Alt-Enter again to leave Full Screen and go
back to Window Mode. (Thanks to @DisplacedGamers for that wisdom)
## Windows 95 is stuck in a bad state
@@ -31,4 +31,5 @@ with the image as input.
## What's the FrontPage Username and Password?
Username: windows95
Password: password

View File

@@ -5,8 +5,8 @@ This is Windows 95, running in an [Electron](https://electronjs.org/) app. Yes,
## Downloads
| | Windows | macOS | Linux |
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| Standalone Download | 📦[Standalone, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.0/windows95-2.2.0-win32-standalone-ia32.zip) <br /> 📦[Standalone, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.0/windows95-2.2.0-win32-standalone-x64.zip) | 📦[Standalone](https://github.com/felixrieseberg/windows95/releases/download/v2.2.0/windows95-macos-2.2.0.zip) | |
| Installer | 💽[Setup, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.0/windows95-2.2.0-setup-win32-x64.exe) <br /> 💽[Setup, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.0/windows95-2.2.0-setup-win32-ia32.exe) | | 💽[deb, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.0/windows95-linux-2.2.0_amd64.deb) <br /> 💽[rpm, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.0/windows95-linux-2.2.0.x86_64.rpm) |
| Standalone Download | 📦[Standalone, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.1/windows95-2.2.1-win32-standalone-ia32.zip) <br /> 📦[Standalone, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.1/windows95-2.2.1-win32-standalone-x64.zip) | 📦[Standalone](https://github.com/felixrieseberg/windows95/releases/download/v2.2.1/windows95-macos-2.2.1.zip) | |
| Installer | 💽[Setup, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.1/windows95-2.2.1-setup-win32-x64.exe) <br /> 💽[Setup, 32-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.1/windows95-2.2.1-setup-win32-ia32.exe) | | 💽[deb, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.1/windows95-linux-2.2.1_amd64.deb) <br /> 💽[rpm, 64-bit](https://github.com/felixrieseberg/windows95/releases/download/v2.2.1/windows95-linux-2.2.1.x86_64.rpm) |
![Screenshot](https://user-images.githubusercontent.com/1426799/44532591-4ceb3680-a6a8-11e8-8c2c-bc29f3bfdef7.png)

Binary file not shown.

Binary file not shown.

16
assets/entitlements.plist Normal file
View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.cs.disable-executable-page-protection</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
</dict>
</plist>

View File

@@ -1,10 +1,19 @@
const path = require('path');
const fs = require('fs');
const package = require('./package.json');
if (process.env['WINDOWS_CODESIGN_FILE']) {
const certPath = path.join(__dirname, 'win-certificate.pfx');
const certExists = fs.existsSync(certPath);
if (certExists) {
process.env['WINDOWS_CODESIGN_FILE'] = certPath;
}
}
module.exports = {
hooks: {
generateAssets: require('./tools/generateAssets'),
postPackage: require('./tools/notarize')
},
packagerConfig: {
asar: false,
@@ -19,10 +28,16 @@ module.exports = {
identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',
'hardened-runtime': true,
'gatekeeper-assess': false,
'entitlements': 'static/entitlements.plist',
'entitlements-inherit': 'static/entitlements.plist',
'entitlements': 'assets/entitlements.plist',
'entitlements-inherit': 'assets/entitlements.plist',
'signature-flags': 'library'
},
osxNotarize: {
appBundleId: 'com.felixrieseberg.macintoshjs',
appleId: process.env['APPLE_ID'],
appleIdPassword: process.env['APPLE_ID_PASSWORD'],
ascProvider: 'LT94ZKYDCJ'
},
ignore: [
/\/assets(\/?)/,
/\/docs(\/?)/,
@@ -49,8 +64,8 @@ module.exports = {
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
certificateFile: process.env['WINDOWS_CODESIGN_FILE'],
certificatePassword: process.env['WINDOWS_CODESIGN_PASSWORD'],
}
}
},
@@ -66,18 +81,5 @@ module.exports = {
name: '@electron-forge/maker-rpm',
platforms: ['linux']
}
],
publishers: [
{
name: '@electron-forge/publisher-github',
config: {
repository: {
owner: 'felixrieseberg',
name: 'windows95'
},
draft: true,
prerelease: true
}
}
]
};

11965
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": "2.2.1",
"version": "2.2.2",
"description": "Windows 95, in an app. I'm sorry.",
"main": "./dist/src/main/main",
"scripts": {
@@ -20,32 +20,31 @@
},
"dependencies": {
"electron-squirrel-startup": "^1.0.0",
"fs-extra": "^8.1.0",
"react": "^16.12.0",
"react-dom": "^16.12.0",
"tslib": "^1.10.0",
"fs-extra": "^9.0.1",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"tslib": "^2.0.0",
"update-electron-app": "^1.5.0"
},
"devDependencies": {
"@electron-forge/cli": "^6.0.0-beta.45",
"@electron-forge/maker-deb": "^6.0.0-beta.45",
"@electron-forge/maker-flatpak": "^6.0.0-beta.45",
"@electron-forge/maker-rpm": "^6.0.0-beta.45",
"@electron-forge/maker-squirrel": "^6.0.0-beta.45",
"@electron-forge/maker-zip": "^6.0.0-beta.45",
"@electron-forge/publisher-github": "^6.0.0-beta.45",
"@types/fs-extra": "^8.0.1",
"@electron-forge/cli": "^6.0.0-beta.52",
"@electron-forge/maker-deb": "^6.0.0-beta.52",
"@electron-forge/maker-flatpak": "^6.0.0-beta.52",
"@electron-forge/maker-rpm": "^6.0.0-beta.52",
"@electron-forge/maker-squirrel": "^6.0.0-beta.52",
"@electron-forge/maker-zip": "^6.0.0-beta.52",
"@electron-forge/publisher-github": "^6.0.0-beta.52",
"@types/fs-extra": "^9.0.1",
"@types/node": "^12.12.14",
"@types/react": "^16.9.13",
"@types/react-dom": "^16.9.4",
"electron": "7.1.2",
"electron-notarize": "^0.2.1",
"less": "^3.10.3",
"node-abi": "^2.13.0",
"@types/react": "^16.9.44",
"@types/react-dom": "^16.9.8",
"electron": "9.1.2",
"less": "^3.12.2",
"node-abi": "^2.18.0",
"parcel-bundler": "^1.12.4",
"prettier": "^1.19.1",
"rimraf": "^3.0.0",
"standard": "^14.3.1",
"typescript": "^3.7.2"
"prettier": "^2.0.5",
"rimraf": "^3.0.2",
"standard": "^14.3.4",
"typescript": "^3.9.7"
}
}

View File

@@ -1,8 +1,8 @@
import { session } from 'electron';
import { session } from "electron";
export async function clearCaches() {
await clearCache()
await clearStorageData()
await clearCache();
await clearStorageData();
}
export async function clearCache() {
@@ -17,9 +17,21 @@ export function clearStorageData() {
return resolve();
}
session.defaultSession.clearStorageData({
storages: [ 'appcache', 'cookies', 'filesystem', 'indexdb', 'localstorage', 'shadercache', 'websql', 'serviceworkers' ],
quotas: [ 'temporary', 'persistent', 'syncable' ]
}, resolve)
})
session.defaultSession.clearStorageData(
{
storages: [
"appcache",
"cookies",
"filesystem",
"indexdb",
"localstorage",
"shadercache",
"websql",
"serviceworkers",
],
quotas: ["temporary", "persistent", "syncable"],
},
resolve
);
});
}

View File

@@ -1,31 +1,31 @@
import { remote, app } from 'electron';
import * as path from 'path';
import { remote, app } from "electron";
import * as path from "path";
const _app = app || remote.app
const _app = app || remote.app;
export const CONSTANTS = {
IMAGE_PATH: path.join(__dirname, '../../images/windows95.img'),
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')
}
DEFAULT_STATE_PATH: path.join(__dirname, "../../images/default-state.bin"),
STATE_PATH: path.join(_app.getPath("userData"), "state-v2.bin"),
};
export const IPC_COMMANDS = {
TOGGLE_INFO: 'TOGGLE_INFO',
SHOW_DISK_IMAGE: 'SHOW_DISK_IMAGE',
ZOOM_IN: 'ZOOM_IN',
ZOOM_OUT: 'ZOOM_OUT',
ZOOM_RESET: 'ZOOM_RESET',
TOGGLE_INFO: "TOGGLE_INFO",
SHOW_DISK_IMAGE: "SHOW_DISK_IMAGE",
ZOOM_IN: "ZOOM_IN",
ZOOM_OUT: "ZOOM_OUT",
ZOOM_RESET: "ZOOM_RESET",
// Machine instructions
MACHINE_START: 'MACHINE_START',
MACHINE_RESTART: 'MACHINE_RESTART',
MACHINE_STOP: 'MACHINE_STOP',
MACHINE_RESET: 'MACHINE_RESET',
MACHINE_ALT_F4: 'MACHINE_ALT_F4',
MACHINE_ESC: 'MACHINE_ESC',
MACHINE_ALT_ENTER: 'MACHINE_ALT_ENTER',
MACHINE_CTRL_ALT_DEL: 'MACHINE_CTRL_ALT_DEL',
MACHINE_START: "MACHINE_START",
MACHINE_RESTART: "MACHINE_RESTART",
MACHINE_STOP: "MACHINE_STOP",
MACHINE_RESET: "MACHINE_RESET",
MACHINE_ALT_F4: "MACHINE_ALT_F4",
MACHINE_ESC: "MACHINE_ESC",
MACHINE_ALT_ENTER: "MACHINE_ALT_ENTER",
MACHINE_CTRL_ALT_DEL: "MACHINE_CTRL_ALT_DEL",
// Machine events
MACHINE_STARTED: 'MACHINE_STARTED',
MACHINE_STOPPED: 'MACHINE_STOPPED'
}
MACHINE_STARTED: "MACHINE_STARTED",
MACHINE_STOPPED: "MACHINE_STOPPED",
};

View File

@@ -12,7 +12,7 @@ export function setupAboutPanel(): void {
applicationName: "windows95",
applicationVersion: app.getVersion(),
version: process.versions.electron,
copyright: "Felix Rieseberg"
copyright: "Felix Rieseberg",
};
switch (process.platform) {

View File

@@ -1,15 +1,14 @@
import { app, shell, Menu, BrowserWindow, ipcMain, webFrame } from "electron";
import { app, shell, Menu, BrowserWindow, ipcMain } from "electron";
import { clearCaches } from "../cache";
import { IPC_COMMANDS } from "../constants";
import { isDevMode } from "../utils/devmode";
import { getOrCreateWindow } from "./windows";
const LINKS = {
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"
help: "https://github.com/felixrieseberg/windows95/blob/master/HELP.md",
};
export async function setupMenu() {
@@ -41,52 +40,52 @@ async function createMenu({ isRunning } = { isRunning: false }) {
submenu: [
{
label: "Toggle Full Screen",
accelerator: (function() {
accelerator: (function () {
if (process.platform === "darwin") {
return "Ctrl+Command+F";
} else {
return "F11";
}
})(),
click: function(_item, focusedWindow) {
click: function (_item, focusedWindow) {
if (focusedWindow) {
focusedWindow.setFullScreen(!focusedWindow.isFullScreen());
}
}
},
},
{
label: "Toggle Developer Tools",
accelerator: (function() {
accelerator: (function () {
if (process.platform === "darwin") {
return "Alt+Command+I";
} else {
return "Ctrl+Shift+I";
}
})(),
click: function(_item, focusedWindow) {
click: function (_item, focusedWindow) {
if (focusedWindow) {
focusedWindow.webContents.toggleDevTools();
}
}
},
},
{
type: "separator"
type: "separator",
},
{
label: "Toggle Emulator Info",
click: () => send(IPC_COMMANDS.TOGGLE_INFO)
click: () => send(IPC_COMMANDS.TOGGLE_INFO),
},
{
type: "separator"
type: "separator",
},
{
role: "reload"
}
]
role: "reload",
},
],
},
{
role: "editMenu",
visible: isDevMode()
visible: isDevMode(),
},
{
label: "Window",
@@ -95,32 +94,32 @@ async function createMenu({ isRunning } = { isRunning: false }) {
{
label: "Minimize",
accelerator: "CmdOrCtrl+M",
role: "minimize"
role: "minimize",
},
{
label: "Close",
accelerator: "CmdOrCtrl+W",
role: "close"
role: "close",
},
{
type: "separator"
type: "separator",
},
{
label: "Zoom in",
click: () => send(IPC_COMMANDS.ZOOM_IN),
enabled: isRunning
enabled: isRunning,
},
{
label: "Zoom out",
click: () => send(IPC_COMMANDS.ZOOM_OUT),
enabled: isRunning
enabled: isRunning,
},
{
label: "Reset zoom",
click: () => send(IPC_COMMANDS.ZOOM_RESET),
enabled: isRunning
}
]
enabled: isRunning,
},
],
},
{
label: "Machine",
@@ -128,53 +127,53 @@ async function createMenu({ isRunning } = { isRunning: false }) {
{
label: "Send Ctrl+Alt+Del",
click: () => send(IPC_COMMANDS.MACHINE_CTRL_ALT_DEL),
enabled: isRunning
enabled: isRunning,
},
{
label: "Send Alt+F4",
click: () => send(IPC_COMMANDS.MACHINE_ALT_F4),
enabled: isRunning
enabled: isRunning,
},
{
label: "Send Alt+Enter",
click: () => send(IPC_COMMANDS.MACHINE_ALT_ENTER),
enabled: isRunning
enabled: isRunning,
},
{
label: "Send Esc",
click: () => send(IPC_COMMANDS.MACHINE_ESC),
enabled: isRunning
enabled: isRunning,
},
{
type: "separator"
type: "separator",
},
isRunning
? {
label: "Stop",
click: () => send(IPC_COMMANDS.MACHINE_STOP)
click: () => send(IPC_COMMANDS.MACHINE_STOP),
}
: {
label: "Start",
click: () => send(IPC_COMMANDS.MACHINE_START)
click: () => send(IPC_COMMANDS.MACHINE_START),
},
{
label: "Restart",
click: () => send(IPC_COMMANDS.MACHINE_RESTART),
enabled: isRunning
enabled: isRunning,
},
{
label: "Reset",
click: () => send(IPC_COMMANDS.MACHINE_RESET),
enabled: isRunning
enabled: isRunning,
},
{
type: "separator"
type: "separator",
},
{
label: "Go to Disk Image",
click: () => send(IPC_COMMANDS.SHOW_DISK_IMAGE)
}
]
click: () => send(IPC_COMMANDS.SHOW_DISK_IMAGE),
},
],
},
{
label: "Help",
@@ -182,18 +181,18 @@ async function createMenu({ isRunning } = { isRunning: false }) {
submenu: [
{
label: "Author",
click: () => shell.openExternal(LINKS.homepage)
click: () => shell.openExternal(LINKS.homepage),
},
{
label: "windows95 on GitHub",
click: () => shell.openExternal(LINKS.repo)
click: () => shell.openExternal(LINKS.repo),
},
{
label: "Help",
click: () => shell.openExternal(LINKS.help)
click: () => shell.openExternal(LINKS.help),
},
{
type: "separator"
type: "separator",
},
{
label: "Troubleshooting",
@@ -205,12 +204,12 @@ async function createMenu({ isRunning } = { isRunning: false }) {
app.relaunch();
app.quit();
}
}
]
}
]
}
},
},
],
},
],
},
];
if (process.platform === "darwin") {
@@ -218,41 +217,41 @@ async function createMenu({ isRunning } = { isRunning: false }) {
label: "windows95",
submenu: [
{
role: "about"
role: "about",
},
{
type: "separator"
type: "separator",
},
{
role: "services"
role: "services",
},
{
type: "separator"
type: "separator",
},
{
label: "Hide windows95",
accelerator: "Command+H",
role: "hide"
role: "hide",
},
{
label: "Hide Others",
accelerator: "Command+Shift+H",
role: "hideothers"
role: "hideothers",
},
{
role: "unhide"
role: "unhide",
},
{
type: "separator"
type: "separator",
},
{
label: "Quit",
accelerator: "Command+Q",
click() {
app.quit();
}
}
]
},
},
],
} as any);
}

View File

@@ -4,7 +4,7 @@ export function setupUpdates() {
if (app.isPackaged) {
require("update-electron-app")({
repo: "felixrieseberg/windows95",
updateInterval: "1 hour"
updateInterval: "1 hour",
});
}
}

View File

@@ -13,8 +13,8 @@ export function getOrCreateWindow(): BrowserWindow {
webPreferences: {
nodeIntegration: true,
sandbox: false,
webviewTag: false
}
webviewTag: false,
},
});
mainWindow.loadFile("./dist/static/index.html");

View File

@@ -28,7 +28,7 @@ export class App {
}
window["win95"] = window["win95"] || {
app: new App()
app: new App(),
};
window["win95"].app.setup();

View File

@@ -1,5 +1,4 @@
import * as React from "react";
import { shell } from "electron";
interface CardDriveProps {
showDiskImage: () => void;
@@ -54,13 +53,8 @@ export class CardDrive extends React.Component<CardDriveProps, CardDriveState> {
<p>
Windows 10 cannot mount raw disk images (ironically, macOS and Linux
can). However, tools exist that let you mount this drive, like the
freeware tool{" "}
<a
href="https://google.com"
>
OSFMount
</a>
. I am not affiliated with it, so please use it at your own risk.
freeware tool <a href="https://google.com">OSFMount</a>. I am not
affiliated with it, so please use it at your own risk.
</p>
{this.renderMountButton("Windows Explorer")}
</fieldset>

View File

@@ -24,7 +24,7 @@ export class CardSettings extends React.Component<
this.onResetState = this.onResetState.bind(this);
this.state = {
isStateReset: false
isStateReset: false,
};
}

View File

@@ -29,7 +29,7 @@ export class EmulatorInfo extends React.Component<
cpu: 0,
disk: "Idle",
lastCounter: 0,
lastTick: 0
lastTick: 0,
};
}
@@ -160,7 +160,7 @@ export class EmulatorInfo extends React.Component<
this.setState({
lastTick: now,
lastCounter: instructionCounter,
cpu: Math.round(ips / deltaTime)
cpu: Math.round(ips / deltaTime),
});
}
}

View File

@@ -41,7 +41,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
isRunning: false,
currentUiCard: "start",
isInfoDisplayed: true,
scale: 1
scale: 1,
};
this.setupInputListeners();
@@ -58,7 +58,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
*/
public setupInputListeners() {
// ESC
document.onkeydown = evt => {
document.onkeydown = (evt) => {
const { isCursorCaptured } = this.state;
evt = evt || window.event;
@@ -99,7 +99,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
});
};
window.onbeforeunload = event => {
window.onbeforeunload = (event) => {
if (this.isQuitting || this.isResetting) {
console.log(`Unload: Not preventing`);
return;
@@ -122,27 +122,27 @@ export class Emulator extends React.Component<{}, EmulatorState> {
this.sendKeys([
0x1d, // ctrl
0x38, // alt
0x53 // delete
0x53, // delete
]);
});
ipcRenderer.on(IPC_COMMANDS.MACHINE_ALT_F4, () => {
this.sendKeys([
0x38, // alt
0x3e // f4
0x3e, // f4
]);
});
ipcRenderer.on(IPC_COMMANDS.MACHINE_ALT_ENTER, () => {
this.sendKeys([
0x38, // alt
0 // enter
0, // enter
]);
});
ipcRenderer.on(IPC_COMMANDS.MACHINE_ESC, () => {
this.sendKeys([
0x18 // alt
0x18, // alt
]);
});
@@ -189,7 +189,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
if (currentUiCard === "settings") {
card = (
<CardSettings
setFloppy={floppyFile => this.setState({ floppyFile })}
setFloppy={(floppyFile) => this.setState({ floppyFile })}
bootFromScratch={this.bootFromScratch}
floppy={floppyFile}
/>
@@ -204,7 +204,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
<>
{card}
<StartMenu
navigate={target => this.setState({ currentUiCard: target })}
navigate={(target) => this.setState({ currentUiCard: target })}
/>
</>
);
@@ -257,10 +257,10 @@ export class Emulator extends React.Component<{}, EmulatorState> {
*/
public showDiskImage() {
// Contents/Resources/app/dist/static
const imagePath = path
.join(__dirname, "../../images/windows95.img");
const imagePath = path.join(__dirname, "../../images/windows95.img");
console.log(`Showing disk image in ${imagePath}`);``
console.log(`Showing disk image in ${imagePath}`);
``;
shell.showItemInFolder(imagePath);
}
@@ -277,20 +277,20 @@ export class Emulator extends React.Component<{}, EmulatorState> {
video_memory_size: 32 * 1024 * 1024,
screen_container: document.getElementById("emulator"),
bios: {
url: "../../bios/seabios.bin"
url: "../../bios/seabios.bin",
},
vga_bios: {
url: "../../bios/vgabios.bin"
url: "../../bios/vgabios.bin",
},
hda: {
url: "../../images/windows95.img",
async: true,
size: imageSize
size: imageSize,
},
fda: {
buffer: this.state.floppyFile
buffer: this.state.floppyFile,
},
boot_order: 0x132
boot_order: 0x132,
};
console.log(`🚜 Starting emulator with options`, options);
@@ -300,7 +300,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
// New v86 instance
this.setState({
emulator: window["emulator"],
isRunning: true
isRunning: true,
});
ipcRenderer.send(IPC_COMMANDS.MACHINE_STARTED);
@@ -367,7 +367,7 @@ export class Emulator extends React.Component<{}, EmulatorState> {
private async saveState(): Promise<void> {
const { emulator } = this.state;
return new Promise(resolve => {
return new Promise((resolve) => {
if (!emulator || !emulator.save_state) {
console.log(`restoreState: No emulator present`);
return resolve();

23
tools/add-macos-cert.sh Normal file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/env sh
KEY_CHAIN=build.keychain
MACOS_CERT_P12_FILE=certificate.p12
# Recreate the certificate from the secure environment variable
echo $MACOS_CERT_P12 | base64 --decode > $MACOS_CERT_P12_FILE
#create a keychain
security create-keychain -p actions $KEY_CHAIN
# Make the keychain the default so identities are found
security default-keychain -s $KEY_CHAIN
# Unlock the keychain
security unlock-keychain -p actions $KEY_CHAIN
security import $MACOS_CERT_P12_FILE -k $KEY_CHAIN -P $MACOS_CERT_PASSWORD -T /usr/bin/codesign;
security set-key-partition-list -S apple-tool:,apple: -s -k actions $KEY_CHAIN
# remove certs
rm -fr *.p12

11
tools/download-disk.ps1 Normal file
View File

@@ -0,0 +1,11 @@
mkdir images
cd images
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($env:DISK_URL, "$(Resolve-Path .)\images.zip")
7z x images.zip -y -aoa
Remove-Item images.zip
Remove-Item __MACOSX -Recurse -ErrorAction Ignore
cd ..
Tree ./ /F

10
tools/download-disk.sh Normal file
View File

@@ -0,0 +1,10 @@
#!/usr/bin/env sh
mkdir -p ./images
cd ./images
wget -O images.zip $DISK_URL
unzip -o images.zip
rm images.zip
rm -r __MACOSX
cd -
ls images

View File

@@ -1,30 +0,0 @@
const { notarize } = require('electron-notarize');
const path = require('path');
const buildOutput = path.resolve(
__dirname,
'..',
'out',
'windows95-darwin-x64',
'windows95.app'
);
module.exports = function () {
if (process.platform !== 'darwin') {
console.log('Not a Mac; skipping notarization');
return;
}
console.log('Notarizing...');
return notarize({
appBundleId: 'com.felixrieseberg.windows95',
appPath: buildOutput,
appleId: process.env.APPLE_ID,
appleIdPassword: process.env.APPLE_ID_PASSWORD,
ascProvider: 'LT94ZKYDCJ'
}).catch((e) => {
console.error(e);
throw e;
});
}

8467
yarn.lock Normal file

File diff suppressed because it is too large Load Diff