Compare commits

...

12 Commits

Author SHA1 Message Date
Felix Rieseberg
7dda450bf6 v1.2.3 2023-03-13 17:20:24 -07:00
Felix Rieseberg
d68097b59b GitHub Actions: Limit arch 2023-03-13 17:20:19 -07:00
Felix Rieseberg
34eccc706c v1.2.2 2023-03-13 17:14:42 -07:00
Felix Rieseberg
cc94f198e2 No Linux ia32 2023-03-13 17:14:29 -07:00
Felix Rieseberg
f5ef5da750 v1.2.1 2023-03-13 17:01:45 -07:00
Felix Rieseberg
1482f6d443 Upgrade Node in GitHub Actions 2023-03-13 16:41:10 -07:00
Felix Rieseberg
1533ba7ec0 Upgrade Node in GitHub Actions 2023-03-13 16:33:43 -07:00
Felix Rieseberg
8a8aa0e7eb v1.2.0 2023-03-13 16:06:14 -07:00
Felix Rieseberg
05136c28c1 Update Electron 2023-03-13 16:06:00 -07:00
Felix Rieseberg
e5b24cc04a
Merge pull request #118 from kipdec/scaling
Added basic window resizing
2023-03-13 15:38:05 -07:00
Kip DeCastro
8821a4749f Cleaned up some unnecessary spaces 2021-07-27 23:34:52 -04:00
Kip DeCastro
4d57fc494c Added basic window resizing to the application 2021-07-27 23:32:18 -04:00
6 changed files with 1165 additions and 1580 deletions

View File

@ -12,15 +12,15 @@ jobs:
lint: lint:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v1 uses: actions/setup-node@v3
with: with:
node-version: 15.x node-version: lts/*
- name: Get yarn cache directory path - name: Get yarn cache directory path
id: yarn-cache-dir-path id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)" run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1 - uses: actions/cache@v3
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with: with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }} path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
@ -37,17 +37,32 @@ jobs:
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
# Build for supported platforms
# https://github.com/electron/electron-packager/blob/ebcbd439ff3e0f6f92fa880ff28a8670a9bcf2ab/src/targets.js#L9
# 32-bit Linux unsupported as of 2019: https://www.electronjs.org/blog/linux-32bit-support
os: [ macOS-latest, ubuntu-latest, windows-latest ] os: [ macOS-latest, ubuntu-latest, windows-latest ]
arch: [ x64, arm64 ]
include:
- os: windows-latest
arch: ia32
- os: ubuntu-latest
arch: armv7l
# Publishing artifacts for multiple Windows architectures has
# a bug which can cause the wrong architecture to be downloaded
# for an update, so until that is fixed, only build Windows x64
exclude:
- os: windows-latest
arch: arm64
steps: steps:
- uses: actions/checkout@v2 - uses: actions/checkout@v3
- name: Setup Node.js - name: Setup Node.js
uses: actions/setup-node@v1 uses: actions/setup-node@v3
with: with:
node-version: 12.x node-version: lts/*
- name: Get yarn cache directory path - name: Get yarn cache directory path
id: yarn-cache-dir-path id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)" run: echo "::set-output name=dir::$(yarn cache dir)"
- uses: actions/cache@v1 - uses: actions/cache@v3
if: matrix.os != 'macOS-latest' if: matrix.os != 'macOS-latest'
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`) id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with: with:
@ -83,7 +98,7 @@ jobs:
run: yarn run: yarn
- name: Make - name: Make
if: startsWith(github.ref, 'refs/tags/') if: startsWith(github.ref, 'refs/tags/')
run: yarn make --arch=all run: yarn make --arch=${{ matrix.arch }}
env: env:
APPLE_ID: ${{ secrets.APPLE_ID }} APPLE_ID: ${{ secrets.APPLE_ID }}
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }} APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}

View File

@ -1,7 +1,7 @@
{ {
"name": "macintosh.js", "name": "macintosh.js",
"productName": "macintosh.js", "productName": "macintosh.js",
"version": "1.1.0", "version": "1.2.3",
"description": "Macintosh's System 8 in an Electron app. I'm sorry.", "description": "Macintosh's System 8 in an Electron app. I'm sorry.",
"main": "src/main/index.js", "main": "src/main/index.js",
"scripts": { "scripts": {
@ -10,7 +10,7 @@
"make": "electron-forge make", "make": "electron-forge make",
"publish": "electron-forge publish", "publish": "electron-forge publish",
"lint": "npx prettier --check src/{main,renderer}/*.{js,css} && npm run check-links", "lint": "npx prettier --check src/{main,renderer}/*.{js,css} && npm run check-links",
"fix": "npx prettier --write src/{main,renderer}/*.{js,css}", "fix": "npx prettier --write \"src/{main,renderer}/**.{js,css}\"",
"check-links": "node tools/check-links.js" "check-links": "node tools/check-links.js"
}, },
"keywords": [], "keywords": [],
@ -27,12 +27,12 @@
"update-electron-app": "^2.0.1" "update-electron-app": "^2.0.1"
}, },
"devDependencies": { "devDependencies": {
"@electron-forge/cli": "6.0.0-beta.54", "@electron-forge/cli": "6.0.5",
"@electron-forge/maker-deb": "6.0.0-beta.54", "@electron-forge/maker-deb": "6.0.5",
"@electron-forge/maker-rpm": "6.0.0-beta.54", "@electron-forge/maker-rpm": "6.0.5",
"@electron-forge/maker-squirrel": "6.0.0-beta.54", "@electron-forge/maker-squirrel": "6.0.5",
"@electron-forge/maker-zip": "6.0.0-beta.54", "@electron-forge/maker-zip": "6.0.5",
"electron": "11.1.1", "electron": "23.1.3",
"node-fetch": "^2.6.1" "node-fetch": "^2.6.1"
} }
} }

View File

@ -1,4 +1,5 @@
const { app, dialog } = require("electron"); const { app, dialog } = require("electron");
const { getIsDevMode } = require("./devmode");
// If the app doesn't run from the /Applications folder, // If the app doesn't run from the /Applications folder,
// we don't get to create files, which keeps the emulator from // we don't get to create files, which keeps the emulator from
@ -8,6 +9,10 @@ function moveToAppFolderMaybe() {
return; return;
} }
if (getIsDevMode()) {
return;
}
if (app.isInApplicationsFolder()) { if (app.isInApplicationsFolder()) {
return; return;
} }

View File

@ -1,4 +1,4 @@
const { app, BrowserWindow, shell } = require("electron"); const { BrowserWindow, shell } = require("electron");
const path = require("path"); const path = require("path");
const { getIsDevMode } = require("./devmode"); const { getIsDevMode } = require("./devmode");
@ -61,18 +61,31 @@ function createWindow() {
width: 900, width: 900,
height: 730, height: 730,
useContentSize: true, useContentSize: true,
frame: false, frame: true,
transparent: true, transparent: true,
resizable: false, resizable: true,
webPreferences: { webPreferences: {
nodeIntegration: true, nodeIntegration: true,
nodeIntegrationInWorker: true,
nativeWindowOpen: true, nativeWindowOpen: true,
contextIsolation: false,
navigateOnDragDrop: false, navigateOnDragDrop: false,
nodeIntegrationInWorker: true, nodeIntegrationInWorker: true,
sandbox: false, sandbox: false,
}, },
}); });
// Ensure that we have access to SharedArrayBuffer
mainWindow.webContents.session.webRequest.onHeadersReceived(
(details, callback) => {
details.responseHeaders["Cross-Origin-Opener-Policy"] = ["same-origin"];
details.responseHeaders["Cross-Origin-Embedder-Policy"] = [
"require-corp",
];
callback({ responseHeaders: details.responseHeaders });
}
);
// and load the index.html of the app. // and load the index.html of the app.
mainWindow.loadFile(path.join(__dirname, "../renderer/index.html")); mainWindow.loadFile(path.join(__dirname, "../renderer/index.html"));

View File

@ -1,43 +1,63 @@
const { videoModeBufferView } = require("./video"); const { videoModeBufferView } = require("./video");
const { audioContext } = require("./audio"); const BITS = 4;
const SCREEN_BUFFER_SIZE = 800 * 600 * BITS; // 32bpp;
const SCREEN_WIDTH = 800;
const SCREEN_HEIGHT = 600;
const SCREEN_BUFFER_SIZE = SCREEN_WIDTH * SCREEN_HEIGHT * 4; // 32bpp;
const screenBuffer = new SharedArrayBuffer(SCREEN_BUFFER_SIZE); const screenBuffer = new SharedArrayBuffer(SCREEN_BUFFER_SIZE);
const screenBufferView = new Uint8Array(screenBuffer); const screenBufferView = new Uint8Array(screenBuffer);
canvas.width = SCREEN_WIDTH; let screenWidth = 800;
canvas.height = SCREEN_HEIGHT; let screenHeight = 600;
canvas.width = screenWidth;
canvas.height = screenHeight;
const canvasCtx = canvas.getContext("2d"); const canvasCtx = canvas.getContext("2d");
const imageData = canvasCtx.createImageData(SCREEN_WIDTH, SCREEN_HEIGHT); let imageData = canvasCtx.createImageData(screenWidth, screenHeight);
window.addEventListener("resize", () => {
screenHeight = window.innerHeight - 35;
screenWidth = Math.floor(screenHeight * (4 / 3));
if (window.innerWidth < screenWidth) {
screenWidth = window.innerWidth;
screenHeight = Math.floor(screenWidth * 0.75);
}
canvas.width = screenWidth;
canvas.height = screenHeight;
imageData = canvasCtx.createImageData(screenWidth, screenHeight);
});
let stopDrawing = false; let stopDrawing = false;
function drawScreen() { function drawScreen() {
if (stopDrawing) return; if (stopDrawing) return;
const pixelsRGBA = imageData.data; const pixelsRGBA = imageData.data;
const numPixels = SCREEN_WIDTH * SCREEN_HEIGHT; const numPixels = screenWidth * screenHeight;
const expandedFromPalettedMode = videoModeBufferView[3]; const expandedFromPalettedMode = videoModeBufferView[3];
const start = audioContext.currentTime;
if (expandedFromPalettedMode) { if (expandedFromPalettedMode) {
for (var i = 0; i < numPixels; i++) { for (let i = 0; i < numPixels; i++) {
// palette // palette
pixelsRGBA[i * 4 + 0] = screenBufferView[i * 4 + 0]; pixelsRGBA[i * BITS + 0] = screenBufferView[i * BITS + 0];
pixelsRGBA[i * 4 + 1] = screenBufferView[i * 4 + 1]; pixelsRGBA[i * BITS + 1] = screenBufferView[i * BITS + 1];
pixelsRGBA[i * 4 + 2] = screenBufferView[i * 4 + 2]; pixelsRGBA[i * BITS + 2] = screenBufferView[i * BITS + 2];
pixelsRGBA[i * 4 + 3] = 255; // full opacity pixelsRGBA[i * BITS + 3] = 255; // full opacity
} }
} else { } else {
for (var i = 0; i < numPixels; i++) { for (let i = 0; i < screenHeight; i++) {
// ARGB for (let j = 0; j < screenWidth; j++) {
pixelsRGBA[i * 4 + 0] = screenBufferView[i * 4 + 1]; // ARGB
pixelsRGBA[i * 4 + 1] = screenBufferView[i * 4 + 2]; const xRatio = 800 / screenWidth;
pixelsRGBA[i * 4 + 2] = screenBufferView[i * 4 + 3]; const yRatio = 600 / screenHeight;
pixelsRGBA[i * 4 + 3] = 255; // full opacity const px = Math.floor(j * xRatio);
const py = Math.floor(i * yRatio);
pixelsRGBA[(i * screenWidth + j) * 4 + 0] =
screenBufferView[(py * 800 + px) * 4 + 1]; //- lineMult];
pixelsRGBA[(i * screenWidth + j) * 4 + 1] =
screenBufferView[(py * 800 + px) * 4 + 2]; //- lineMult];
pixelsRGBA[(i * screenWidth + j) * 4 + 2] =
screenBufferView[(py * 800 + px) * 4 + 3]; //- lineMult];
pixelsRGBA[(i * screenWidth + j) * 4 + 3] = 255; // full opacity
}
} }
} }
@ -69,7 +89,7 @@ module.exports = {
screenBufferView, screenBufferView,
SCREEN_BUFFER_SIZE, SCREEN_BUFFER_SIZE,
drawScreen, drawScreen,
SCREEN_WIDTH, SCREEN_WIDTH: screenWidth,
SCREEN_HEIGHT, SCREEN_HEIGHT: screenHeight,
setCanvasBlank, setCanvasBlank,
}; };

2606
yarn.lock

File diff suppressed because it is too large Load Diff