mirror of
https://github.com/felixrieseberg/macintosh.js.git
synced 2024-12-26 19:29:28 +00:00
fix: A whole bunch of cleaning up
This commit is contained in:
parent
118703356d
commit
bf1f043bc4
15
CREDITS.md
Normal file
15
CREDITS.md
Normal file
@ -0,0 +1,15 @@
|
||||
# macintosh.js Credits
|
||||
|
||||
This app by <a href="https://www.felixrieseberg.com">Felix Rieseberg</a>. The real work was done by the people below:
|
||||
|
||||
**Emulator**: Basilisk II, a 68k Macintosh emulator, by [Christian Bauer et al](http://basilisk.cebix.net), modified and compiled [with Emscripten](https://jamesfriend.com.au/basilisk-ii-classic-mac-emulator-in-the-browser) by [James Friend](https://jamesfriend.com.au).
|
||||
|
||||
**Installed software** from vintage computing archives: [WinWorldPC](https://winworldpc.com), [Macintosh Garden](https://macintoshgarden.org), and [Macintosh Repository](https://www.macintoshrepository.org/).
|
||||
|
||||
This software is not affiliated with nor authorized by Apple. It is provided for educational purposes only. This is an unstable toy and should not be expected to work properly.
|
||||
|
||||
# Licenses
|
||||
|
||||
The [source code for this app can be found on GitHub](https://github.com/felixrieseberg/macintosh).
|
||||
|
||||
Basilisk II and its components are released under the GNU GPL. See [LICENSE](src/basilisk/LICENSE.txt) for details.
|
35
README.md
Normal file
35
README.md
Normal file
@ -0,0 +1,35 @@
|
||||
# macintosh.js
|
||||
|
||||
This is Mac OS 8, running in an [Electron](https://electronjs.org/) app. Yes, it's the full thing. I'm sorry.
|
||||
|
||||
## Downloads
|
||||
| | Windows | macOS | Linux |
|
||||
|---------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Standalone Download | 📦[Standalone, 32-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-win32-standalone-ia32.zip) <br /> 📦[Standalone, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-win32-standalone-x64.zip) | 📦[Standalone](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-macos-2.2.1.zip) | |
|
||||
| Installer | 💽[Setup, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-setup-win32-x64.exe) <br /> 💽[Setup, 32-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-2.2.1-setup-win32-ia32.exe) | | 💽[deb, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-linux-2.2.1_amd64.deb) <br /> 💽[rpm, 64-bit](https://github.com/felixrieseberg/macintosh.js/releases/download/v2.2.1/macintosh.js-linux-2.2.1.x86_64.rpm) |
|
||||
|
||||
![Screenshot]()
|
||||
|
||||
## Does it work?
|
||||
Yes! Quite well, actually - on macOS, Windows, and Linux. Bear in mind that this is written entirely in JavaScript, so please adjust your expectations. The virtual machine is emulating a Motorola CPU, which Apple used before switching to IBM's PowerPC architecture in the late 1990s.
|
||||
|
||||
## Should this have been a native app?
|
||||
Absolutely.
|
||||
|
||||
## Does it run my favorite game or app?
|
||||
You'll likely be better off with an actual virtualization app, but the short answer is yes. In fact, you'll find various games and demos preinstalled, thanks to an old MacWorld Demo CD from 1997. Namely, Oregon Trail, Duke Nukem 3D, Civilization II, Alley 19 Bowling, Damage Incorporated, and Dungeons & Dragons.
|
||||
|
||||
There are also various apps and trials preinstalled, including Photoshop 3, Premiere 4, Illustrator 5.5, StuffIt Expander, the Apple Web Page Construction Kit, and more.
|
||||
|
||||
## Can I transfer files from and to the machine?
|
||||
|
||||
Yes, you can. Click on the "Help" button at the bottom of the running app to see instructions.
|
||||
|
||||
## Can I connect to the Internet?
|
||||
|
||||
No. For what it's worth, the web was quite different 30 years ago - and you wouldn't be able to open even Google. However, Internet Explorer and Netscape are installed, as is the "Web Sharing Server", if you want to play around a bit.
|
||||
|
||||
## License
|
||||
|
||||
This project is provided for educational purposes only. It is not affiliated with and has
|
||||
not been approved by Apple.
|
BIN
assets/icon.icns
Normal file
BIN
assets/icon.icns
Normal file
Binary file not shown.
BIN
assets/icon.ico
Normal file
BIN
assets/icon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.2 KiB |
BIN
assets/icon.png
Normal file
BIN
assets/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
80
forge.config.js
Normal file
80
forge.config.js
Normal file
@ -0,0 +1,80 @@
|
||||
const path = require('path');
|
||||
const package = require('./package.json');
|
||||
|
||||
module.exports = {
|
||||
hooks: {
|
||||
postPackage: require('./tools/notarize')
|
||||
},
|
||||
packagerConfig: {
|
||||
asar: false,
|
||||
icon: path.resolve(__dirname, 'assets', 'icon'),
|
||||
appBundleId: 'com.felixrieseberg.macintoshjs',
|
||||
appCategoryType: 'public.app-category.developer-tools',
|
||||
win32metadata: {
|
||||
CompanyName: 'Felix Rieseberg',
|
||||
OriginalFilename: 'macintosh.js'
|
||||
},
|
||||
osxSign: {
|
||||
identity: 'Developer ID Application: Felix Rieseberg (LT94ZKYDCJ)',
|
||||
'hardened-runtime': true,
|
||||
'gatekeeper-assess': false,
|
||||
'entitlements': 'static/entitlements.plist',
|
||||
'entitlements-inherit': 'static/entitlements.plist',
|
||||
'signature-flags': 'library'
|
||||
},
|
||||
ignore: [
|
||||
/\/assets(\/?)/,
|
||||
/\/docs(\/?)/,
|
||||
/\/tools(\/?)/,
|
||||
/package-lock\.json/,
|
||||
/README\.md/,
|
||||
/CREDITS\.md/,
|
||||
/issue_template\.md/,
|
||||
/HELP\.md/,
|
||||
]
|
||||
},
|
||||
makers: [
|
||||
{
|
||||
name: '@electron-forge/maker-squirrel',
|
||||
platforms: ['win32'],
|
||||
config: (arch) => {
|
||||
return {
|
||||
name: 'macintosh.js',
|
||||
authors: 'Felix Rieseberg',
|
||||
exe: 'macintoshjs.exe',
|
||||
noMsi: true,
|
||||
remoteReleases: '',
|
||||
setupExe: `macintoshjs-${package.version}-setup-${arch}.exe`,
|
||||
setupIcon: path.resolve(__dirname, 'assets', 'icon.ico'),
|
||||
certificateFile: process.env.WINDOWS_CERTIFICATE_FILE,
|
||||
certificatePassword: process.env.WINDOWS_CERTIFICATE_PASSWORD
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
name: '@electron-forge/maker-zip',
|
||||
platforms: ['darwin', 'win32']
|
||||
},
|
||||
{
|
||||
name: '@electron-forge/maker-deb',
|
||||
platforms: ['linux']
|
||||
},
|
||||
{
|
||||
name: '@electron-forge/maker-rpm',
|
||||
platforms: ['linux']
|
||||
}
|
||||
],
|
||||
publishers: [
|
||||
{
|
||||
name: '@electron-forge/publisher-github',
|
||||
config: {
|
||||
repository: {
|
||||
owner: 'felixrieseberg',
|
||||
name: 'macintosh.js'
|
||||
},
|
||||
draft: true,
|
||||
prerelease: true
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
29
package.json
29
package.json
@ -19,34 +19,11 @@
|
||||
},
|
||||
"license": "MIT",
|
||||
"config": {
|
||||
"forge": {
|
||||
"packagerConfig": {},
|
||||
"makers": [
|
||||
{
|
||||
"name": "@electron-forge/maker-squirrel",
|
||||
"config": {
|
||||
"name": "macintosh"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-zip",
|
||||
"platforms": [
|
||||
"darwin"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-deb",
|
||||
"config": {}
|
||||
},
|
||||
{
|
||||
"name": "@electron-forge/maker-rpm",
|
||||
"config": {}
|
||||
}
|
||||
]
|
||||
}
|
||||
"forge": "./forge.config.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"electron-squirrel-startup": "^1.0.0"
|
||||
"electron-squirrel-startup": "^1.0.0",
|
||||
"update-electron-app": "^1.5.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@electron-forge/cli": "6.0.0-beta.52",
|
||||
|
@ -62,10 +62,22 @@ function addAutoloader(module) {
|
||||
true
|
||||
);
|
||||
} catch (error) {
|
||||
postMessage("showMessageBoxSync", {
|
||||
type: 'error',
|
||||
title: 'Could not transfer file',
|
||||
message: `We tried to transfer ${fileName} to the virtual machine, but failed. The error was: ${error}`
|
||||
});
|
||||
|
||||
console.error(`loadDatafiles: Failed to preload ${fileName}`, error);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
postMessage("showMessageBoxSync", {
|
||||
type: 'error',
|
||||
title: 'Could not transfer files',
|
||||
message: `We tried to transfer files to the virtual machine, but failed. The error was: ${error}`
|
||||
});
|
||||
|
||||
console.error(`loadDatafiles: Failed to copyFilesAtPath`, error);
|
||||
}
|
||||
}
|
||||
@ -115,6 +127,12 @@ function writeSafely(filePath, fileData) {
|
||||
return new Promise((resolve) => {
|
||||
fs.writeFile(filePath, fileData, (error) => {
|
||||
if (error) {
|
||||
postMessage("showMessageBoxSync", {
|
||||
type: 'error',
|
||||
title: 'Could not save files',
|
||||
message: `We tried to save files from the virtual machine, but failed. The error was: ${error}`
|
||||
});
|
||||
|
||||
console.error(`Disk save: Encountered error for ${filePath}`, error);
|
||||
} else {
|
||||
console.log(`Disk save: Finished writing ${filePath}`);
|
||||
@ -158,6 +176,12 @@ async function saveFilesInPath(folderPath) {
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
postMessage("showMessageBoxSync", {
|
||||
type: 'error',
|
||||
title: 'Could not safe file',
|
||||
message: `We tried to save the file "${file}" from the virtual machine, but failed. The error was: ${error}`
|
||||
});
|
||||
|
||||
console.error(`Disk save: Could not write ${file}`, error);
|
||||
}
|
||||
}
|
||||
|
@ -1,23 +1,26 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const { app } = require('electron');
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const { app } = require("electron");
|
||||
|
||||
const appDataPath = app.getPath('userData');
|
||||
const devFilePath = path.join(appDataPath, 'developer');
|
||||
const appDataPath = app.getPath("userData");
|
||||
const devFilePath = path.join(appDataPath, "developer");
|
||||
|
||||
let isDevMode = true;
|
||||
let isDevMode;
|
||||
|
||||
function getIsDevMode() {
|
||||
if (isDevMode !== undefined) {
|
||||
return isDevMode;
|
||||
}
|
||||
|
||||
return isDevMode = fs.existsSync(devFilePath);
|
||||
return (isDevMode = !app.isPackaged || fs.existsSync(devFilePath));
|
||||
}
|
||||
|
||||
function setIsDevMode(set) {
|
||||
if (set && !getIsDevMode()) {
|
||||
fs.writeFileSync(devFilePath, `So you're a developer, huh? Neat! Welcome aboard!`);
|
||||
fs.writeFileSync(
|
||||
devFilePath,
|
||||
`So you're a developer, huh? Neat! Welcome aboard!`
|
||||
);
|
||||
} else if (!set && getIsDevMode()) {
|
||||
fs.unlinkSync(devFilePath);
|
||||
}
|
||||
@ -27,5 +30,5 @@ function setIsDevMode(set) {
|
||||
|
||||
module.exports = {
|
||||
getIsDevMode,
|
||||
setIsDevMode
|
||||
setIsDevMode,
|
||||
};
|
||||
|
@ -1,39 +1,54 @@
|
||||
const { app, BrowserWindow } = require("electron");
|
||||
const path = require("path");
|
||||
|
||||
const { registerIpcHandlers } = require("./ipc");
|
||||
const { createWindow } = require("./windows");
|
||||
const { getIsDevMode } = require("./devmode");
|
||||
const { shouldQuit } = require("./squirrel");
|
||||
const { setupUpdates } = require("./update");
|
||||
|
||||
// Handle creating/removing shortcuts on Windows when installing/uninstalling.
|
||||
if (require("electron-squirrel-startup")) {
|
||||
// eslint-disable-line global-require
|
||||
app.quit();
|
||||
}
|
||||
async function onReady() {
|
||||
if (!getIsDevMode()) process.env.NODE_ENV = "production";
|
||||
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.on("ready", () => {
|
||||
registerIpcHandlers();
|
||||
createWindow();
|
||||
});
|
||||
setupUpdates();
|
||||
}
|
||||
|
||||
// Quit when all windows are closed, except on macOS. There, it's common
|
||||
// for applications and their menu bar to stay active until the user quits
|
||||
// explicitly with Cmd + Q.
|
||||
app.on("window-all-closed", () => {
|
||||
/**
|
||||
* All windows have been closed, quit on anything but
|
||||
* macOS.
|
||||
*/
|
||||
function onWindowsAllClosed() {
|
||||
// On OS X it is common for applications and their menu bar
|
||||
// to stay active until the user quits explicitly with Cmd + Q
|
||||
if (process.platform !== "darwin") {
|
||||
app.quit();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
app.on("activate", () => {
|
||||
function onActivate() {
|
||||
// On OS X it's common to re-create a window in the app when the
|
||||
// dock icon is clicked and there are no other windows open.
|
||||
if (BrowserWindow.getAllWindows().length === 0) {
|
||||
createWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// In this file you can include the rest of your app's specific main process
|
||||
// code. You can also put them in separate files and import them here.
|
||||
function main() {
|
||||
// Handle creating/removing shortcuts on Windows when
|
||||
// installing/uninstalling.
|
||||
if (shouldQuit()) {
|
||||
app.quit();
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the app's name
|
||||
app.setName("macintosh.js");
|
||||
|
||||
// Launch
|
||||
app.on("ready", onReady);
|
||||
app.on("activate", onActivate);
|
||||
app.on("window-all-closed", onWindowsAllClosed);
|
||||
}
|
||||
|
||||
main();
|
||||
|
@ -1,5 +1,6 @@
|
||||
const { ipcMain, app, BrowserWindow } = require("electron");
|
||||
const { ipcMain, app, BrowserWindow, dialog } = require("electron");
|
||||
const { setIsDevMode, getIsDevMode } = require("./devmode");
|
||||
const { getMainWindow } = require("./windows");
|
||||
|
||||
function registerIpcHandlers() {
|
||||
ipcMain.handle("quit", () => app.quit());
|
||||
@ -12,9 +13,23 @@ function registerIpcHandlers() {
|
||||
|
||||
ipcMain.handle("getIsDevMode", () => getIsDevMode());
|
||||
|
||||
ipcMain.handle("setIsDevMode", (event, set) => {
|
||||
ipcMain.handle("setIsDevMode", (_event, set) => {
|
||||
setIsDevMode(set);
|
||||
});
|
||||
|
||||
ipcMain.handle("showMessageBox", (_event, options) => {
|
||||
const mainWindow = getMainWindow();
|
||||
return dialog.showMessageBox(mainWindow, options);
|
||||
});
|
||||
|
||||
ipcMain.handle("showMessageBoxSync", (_event, options) => {
|
||||
const mainWindow = getMainWindow();
|
||||
return dialog.showMessageBoxSync(mainWindow, options);
|
||||
});
|
||||
|
||||
ipcMain.handle("getAppVersion", () => {
|
||||
return app.getVersion();
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
7
src/main/squirrel.js
Normal file
7
src/main/squirrel.js
Normal file
@ -0,0 +1,7 @@
|
||||
function shouldQuit() {
|
||||
return require("electron-squirrel-startup");
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
shouldQuit,
|
||||
};
|
14
src/main/update.js
Normal file
14
src/main/update.js
Normal file
@ -0,0 +1,14 @@
|
||||
const { app } = require("electron");
|
||||
|
||||
function setupUpdates() {
|
||||
if (app.isPackaged) {
|
||||
require("update-electron-app")({
|
||||
repo: "felixrieseberg/macintosh.js",
|
||||
updateInterval: "1 hour",
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
setupUpdates,
|
||||
};
|
@ -6,6 +6,10 @@ const { getIsDevMode } = require("./devmode");
|
||||
const windowList = {};
|
||||
let mainWindow;
|
||||
|
||||
function getMainWindow() {
|
||||
return mainWindow;
|
||||
}
|
||||
|
||||
function handleNewWindow(event, url, frameName, disposition, options) {
|
||||
// open window as modal
|
||||
event.preventDefault();
|
||||
@ -85,4 +89,5 @@ function createWindow() {
|
||||
|
||||
module.exports = {
|
||||
createWindow,
|
||||
getMainWindow,
|
||||
};
|
||||
|
@ -4,9 +4,7 @@ var audio = {
|
||||
channels: 1,
|
||||
bytesPerSample: 2,
|
||||
samples: 4096,
|
||||
// freq: 11025,
|
||||
freq: 22050,
|
||||
// freq: 44100,
|
||||
format: 0x8010,
|
||||
paused: false,
|
||||
timer: null,
|
||||
@ -41,12 +39,6 @@ var audioDataBuffer = new SharedArrayBuffer(AUDIO_DATA_BUFFER_SIZE);
|
||||
var audioDataBufferView = new Uint8Array(audioDataBuffer);
|
||||
|
||||
var audioContext = new AudioContext();
|
||||
// document.querySelector('#enableAudio').addEventListener('click', function() {
|
||||
// audioContext.resume().then(() => {
|
||||
// document.querySelector('#enableAudio').remove();
|
||||
// });
|
||||
// });
|
||||
|
||||
var gainNode = audioContext.createGain();
|
||||
|
||||
gainNode.gain.value = 1;
|
||||
@ -120,11 +112,6 @@ function openAudio() {
|
||||
audio.gotFirstBlock &&
|
||||
Date.now() - getBlockBufferLastWarningTime > 5000
|
||||
) {
|
||||
// console.warn(
|
||||
// `UI thread tried to read audio data from worker-locked chunk ${getBlockBufferWarningCount} times`
|
||||
// );
|
||||
//console.log("curChunkIndex", curChunkIndex);
|
||||
// debugger
|
||||
getBlockBufferLastWarningTime = Date.now();
|
||||
getBlockBufferWarningCount = 0;
|
||||
}
|
||||
@ -139,10 +126,7 @@ function openAudio() {
|
||||
curChunkAddr + 2 + audio.bufferSize
|
||||
);
|
||||
audio.nextChunkIndex = audioDataBufferView[curChunkAddr + 1];
|
||||
// console.assert(audio.nextChunkIndex != curChunkIndex, `curChunkIndex=${curChunkIndex} == nextChunkIndex=${audio.nextChunkIndex}`)
|
||||
audioDataBufferView[curChunkAddr] = LockStates.EMUL_THREAD_LOCK;
|
||||
// debugger
|
||||
// console.log(`got buffer=${curChunkIndex}, next=${audio.nextChunkIndex}`)
|
||||
return blockBuffer;
|
||||
};
|
||||
|
||||
@ -196,7 +180,6 @@ function openAudio() {
|
||||
// And queue it to be played after the currently playing audio stream.
|
||||
audio.pushAudio(blockBuffer, audio.bufferSize);
|
||||
}
|
||||
// console.log(`queued ${i} buffers of audio`);
|
||||
};
|
||||
|
||||
// Create a callback function that will be routinely called to ask more audio data from the user application.
|
||||
|
7
src/renderer/controls.js
vendored
7
src/renderer/controls.js
vendored
@ -1,8 +1,9 @@
|
||||
const { quit, devtools } = require("./ipc");
|
||||
const { getIsWorkerRunning, getIsWorkerSaving } = require("./worker");
|
||||
const { showCloseWarning } = require("./dialogs");
|
||||
const { getIsDevMode } = require("./ipc");
|
||||
|
||||
function registerControls() {
|
||||
async function registerControls() {
|
||||
document.querySelector("#close").addEventListener("click", () => {
|
||||
if (!getIsWorkerRunning()) {
|
||||
quit();
|
||||
@ -16,6 +17,10 @@ function registerControls() {
|
||||
document.querySelector("#devtools").addEventListener("click", () => {
|
||||
devtools();
|
||||
});
|
||||
|
||||
if (await getIsDevMode()) {
|
||||
document.querySelector("#devtools").classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
registerControls();
|
||||
|
@ -8,6 +8,9 @@
|
||||
</head>
|
||||
<body>
|
||||
<h1>Credits</h1>
|
||||
|
||||
<small id="versions"></small>
|
||||
|
||||
<p>
|
||||
This app by <a href="https://www.felixrieseberg.com">Felix Rieseberg</a>. The real work was done by the people below:
|
||||
</p>
|
||||
@ -29,14 +32,6 @@
|
||||
|
||||
<p>Basilisk II and its components are released under the GNU GPL. See <a href="#" id="license">LICENSE</a> for details.</p>
|
||||
|
||||
<script>
|
||||
license.onclick = () => {
|
||||
const { shell } = require('electron');
|
||||
const path = require('path');
|
||||
|
||||
const licensePath = path.join(__dirname, '../basilisk/LICENSE.txt');
|
||||
shell.openPath(licensePath);
|
||||
}
|
||||
</script>
|
||||
<script src="./credits.js"></script>
|
||||
</body>
|
||||
</html>
|
19
src/renderer/credits.js
Normal file
19
src/renderer/credits.js
Normal file
@ -0,0 +1,19 @@
|
||||
const { shell, ipcRenderer } = require("electron");
|
||||
const path = require("path");
|
||||
const { versions } = require("process");
|
||||
|
||||
const { getAppVersion } = require("./ipc.js");
|
||||
|
||||
async function credits() {
|
||||
license.onclick = () => {
|
||||
const licensePath = path.join(__dirname, "../basilisk/LICENSE.txt");
|
||||
shell.openPath(licensePath);
|
||||
};
|
||||
|
||||
const version = await getAppVersion();
|
||||
document.querySelector(
|
||||
"#versions"
|
||||
).innerHTML = `macintosh.js v${version} with Electron v${process.versions.electron}`;
|
||||
}
|
||||
|
||||
credits();
|
@ -9,21 +9,24 @@
|
||||
<body>
|
||||
<h1>Help</h1>
|
||||
|
||||
<h2>Passing files into the machine</h2>
|
||||
<h2>How can I get files into the machine?</h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
<li>Open the folder "macintosh.js" in your <a href="#_" id="user_dir">user directory</a>.</li>
|
||||
<li>Put any files you want to use in your VM (virtual machine) into that folder.</li>
|
||||
<li>Restart the app.</li>
|
||||
<li>On the VM's (virtual machine) desktop, find the "Unix" volume and double-click to open it.</li>
|
||||
<li>On the VM's desktop, find the "Unix" volume and double-click to open it.</li>
|
||||
<li>Find the "macintosh.js" folder, which now contains all your files.</li>
|
||||
</ul>
|
||||
|
||||
Files will be copied over when you start your VM (virtual machine). They are not synchronized while the VM is running. However, any changes made to the "macintosh.js" folder in your VM will be saved to the corresponding folder in your home directory once you shut the VM down.
|
||||
Files will be copied over when you start your VM. They are not synchronized while the VM is running. However, any changes made to the "macintosh.js" folder in your VM will be saved to the corresponding folder in your home directory once you shut the VM down.
|
||||
|
||||
Be chill about it: The more files you put into that folder,
|
||||
the more memory macintosh.js will consume.
|
||||
</p>
|
||||
|
||||
<h2>Getting files out of machine</h2>
|
||||
<h2>How can I get files out of the machine?</h2>
|
||||
|
||||
<p>
|
||||
<ul>
|
||||
@ -43,8 +46,6 @@
|
||||
<button id="devtools">Enable developer tools</button>
|
||||
</p>
|
||||
|
||||
<script>
|
||||
require('./help.js')
|
||||
</script>
|
||||
<script src="./help.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -1,35 +1,47 @@
|
||||
const { shell, ipcRenderer } = require('electron');
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const homedir = require('os').homedir();
|
||||
const macDir = path.join(homedir, 'macintosh.js');
|
||||
const { shell, ipcRenderer } = require("electron");
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
const homedir = require("os").homedir();
|
||||
const macDir = path.join(homedir, "macintosh.js");
|
||||
|
||||
let isDevTools;
|
||||
|
||||
// Setup dev mode
|
||||
function fetchIsDevTools() {
|
||||
ipcRenderer.invoke('getIsDevMode').then((result) => {
|
||||
ipcRenderer.invoke("getIsDevMode").then((result) => {
|
||||
isDevTools = result;
|
||||
|
||||
if (result) {
|
||||
devtools.innerHTML = 'Disable developer tools';
|
||||
devtools.innerHTML = "Disable developer tools";
|
||||
} else {
|
||||
devtools.innerHTML = 'Enable developer tools';
|
||||
devtools.innerHTML = "Enable developer tools";
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
user_dir.onclick = user_dir2.onclick = () => {
|
||||
if (!fs.existsSync(macDir)) {
|
||||
fs.mkdirSync(macDir);
|
||||
}
|
||||
async function help() {
|
||||
user_dir.onclick = user_dir2.onclick = () => {
|
||||
try {
|
||||
if (!fs.existsSync(macDir)) {
|
||||
fs.mkdirSync(macDir);
|
||||
}
|
||||
|
||||
shell.showItemInFolder(macDir);
|
||||
}
|
||||
shell.showItemInFolder(macDir);
|
||||
} catch (error) {
|
||||
ipcRenderer.invoke("showMessageBox", {
|
||||
type: "error",
|
||||
title: "Could not open folder",
|
||||
message: `We tried to open the macintosh.js directory, but failed. The error was: ${error}`,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
devtools.onclick = async () => {
|
||||
await ipcRenderer.invoke("setIsDevMode", !isDevTools);
|
||||
fetchIsDevTools();
|
||||
};
|
||||
|
||||
devtools.onclick = async () => {
|
||||
await ipcRenderer.invoke('setIsDevMode', !isDevTools);
|
||||
fetchIsDevTools();
|
||||
}
|
||||
|
||||
fetchIsDevTools();
|
||||
help();
|
||||
|
@ -21,7 +21,7 @@
|
||||
<a id="close" href="#">Quit</a>
|
||||
<a id="credits" href="#" onclick="window.open('credits.html')">Credits</a>
|
||||
<a id="help" href="#" onclick="window.open('help.html')">Help</a>
|
||||
<a id="devtools" href="#">Dev</a>
|
||||
<a id="devtools" href="#" class="hidden">Toggle DevTools</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="warning" class="dialog hidden absolute_center">
|
||||
|
@ -8,4 +8,16 @@ module.exports = {
|
||||
devtools() {
|
||||
ipcRenderer.invoke("devtools");
|
||||
},
|
||||
|
||||
getIsDevMode() {
|
||||
return ipcRenderer.invoke("getIsDevMode");
|
||||
},
|
||||
|
||||
setIsDevMode() {
|
||||
return ipcRenderer.invoke("setIsDevMode");
|
||||
},
|
||||
|
||||
getAppVersion() {
|
||||
return ipcRenderer.invoke("getAppVersion");
|
||||
},
|
||||
};
|
||||
|
@ -49,6 +49,21 @@
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.controls > .clear > a:before {
|
||||
content: "• ";
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.controls > .clear > a:before:hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.controls > .clear > a:nth-of-type(1):before {
|
||||
content: "";
|
||||
}
|
||||
|
||||
#progress {
|
||||
display: none;
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ function registerWorker() {
|
||||
worker.onmessage = function (e) {
|
||||
if (e.data.type === "emulator_loading") {
|
||||
const progressElement = document.querySelector("#progressbar");
|
||||
const progressDialog = document.querySelector("#progress p")
|
||||
const progressDialog = document.querySelector("#progress p");
|
||||
|
||||
if (progressElement && e.data.type === "emulator_loading") {
|
||||
const val = Math.max(10, e.data.completion * 100);
|
||||
@ -102,7 +102,7 @@ function registerWorker() {
|
||||
// If we're ready, Basilisk II will send
|
||||
// video_open()
|
||||
if (e.data.data === "video_open()") {
|
||||
document.body.classList.remove('emulator_loading');
|
||||
document.body.classList.remove("emulator_loading");
|
||||
document.body.classList.add("emulator_running");
|
||||
}
|
||||
} else if (e.data.type === "disk_saved") {
|
||||
|
30
tools/notarize.js
Normal file
30
tools/notarize.js
Normal file
@ -0,0 +1,30 @@
|
||||
const { notarize } = require('electron-notarize');
|
||||
const path = require('path');
|
||||
|
||||
const buildOutput = path.resolve(
|
||||
__dirname,
|
||||
'..',
|
||||
'out',
|
||||
'macintosh.js-darwin-x64',
|
||||
'macintosh.js.app'
|
||||
);
|
||||
|
||||
module.exports = function () {
|
||||
if (process.platform !== 'darwin') {
|
||||
console.log('Not a Mac; skipping notarization');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log('Notarizing...');
|
||||
|
||||
return notarize({
|
||||
appBundleId: 'com.felixrieseberg.macintoshjs',
|
||||
appPath: buildOutput,
|
||||
appleId: process.env.APPLE_ID,
|
||||
appleIdPassword: process.env.APPLE_ID_PASSWORD,
|
||||
ascProvider: 'LT94ZKYDCJ'
|
||||
}).catch((e) => {
|
||||
console.error(e);
|
||||
throw e;
|
||||
});
|
||||
}
|
29
yarn.lock
29
yarn.lock
@ -933,6 +933,11 @@ electron-installer-redhat@^3.0.0:
|
||||
word-wrap "^1.2.3"
|
||||
yargs "^15.1.0"
|
||||
|
||||
electron-is-dev@^0.3.0:
|
||||
version "0.3.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-is-dev/-/electron-is-dev-0.3.0.tgz#14e6fda5c68e9e4ecbeff9ccf037cbd7c05c5afe"
|
||||
integrity sha1-FOb9pcaOnk7L7/nM8DfL18BcWv4=
|
||||
|
||||
electron-notarize@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/electron-notarize/-/electron-notarize-1.0.0.tgz#bc925b1ccc3f79e58e029e8c4706572b01a9fd8f"
|
||||
@ -1009,7 +1014,7 @@ electron-winstaller@^4.0.0:
|
||||
lodash.template "^4.2.2"
|
||||
temp "^0.9.0"
|
||||
|
||||
electron@10.0.0-beta.13:
|
||||
electron@10.0.0-beta.12:
|
||||
version "10.0.0-beta.12"
|
||||
resolved "https://registry.yarnpkg.com/electron/-/electron-10.0.0-beta.12.tgz#93db286f96de03104a39fc693c25d0d4c0784813"
|
||||
integrity sha512-cUYFrtGDD96aes4W+jCD1CwyC17HE4/wbok3yphL66z08ZQ+MIqgEe/pChujcSiMoK9SjvxTPPYGtszyXOrZKg==
|
||||
@ -1355,6 +1360,13 @@ getpass@^0.1.1:
|
||||
dependencies:
|
||||
assert-plus "^1.0.0"
|
||||
|
||||
github-url-to-object@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/github-url-to-object/-/github-url-to-object-4.0.4.tgz#a9797b7026e18d53b50b07f45b7e169b55fd90ee"
|
||||
integrity sha512-1Ri1pR8XTfzLpbtPz5MlW/amGNdNReuExPsbF9rxLsBfO1GH9RtDBamhJikd0knMWq3RTTQDbTtw0GGvvEAJEA==
|
||||
dependencies:
|
||||
is-url "^1.1.0"
|
||||
|
||||
glob@^7.1.3, glob@^7.1.4, glob@^7.1.5, glob@^7.1.6:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
@ -1591,6 +1603,11 @@ is-typedarray@~1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
|
||||
integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
|
||||
|
||||
is-url@^1.1.0, is-url@^1.2.4:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
|
||||
integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
|
||||
|
||||
is-utf8@^0.2.0:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72"
|
||||
@ -3036,6 +3053,16 @@ universalify@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/universalify/-/universalify-1.0.0.tgz#b61a1da173e8435b2fe3c67d29b9adf8594bd16d"
|
||||
integrity sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==
|
||||
|
||||
update-electron-app@^1.5.0:
|
||||
version "1.5.0"
|
||||
resolved "https://registry.yarnpkg.com/update-electron-app/-/update-electron-app-1.5.0.tgz#492cb904db07a0b28dbd83fb52e0fe500bbe3463"
|
||||
integrity sha512-g7noW9JfQ8Hwq6zw9lmZei+R/ikOIBcaZ04TbmIcU5zNfv23HkN80QLLAyiR/47KvfS4sjnh2/wuDq5nh8+0mQ==
|
||||
dependencies:
|
||||
electron-is-dev "^0.3.0"
|
||||
github-url-to-object "^4.0.4"
|
||||
is-url "^1.2.4"
|
||||
ms "^2.1.1"
|
||||
|
||||
uri-js@^4.2.2:
|
||||
version "4.2.2"
|
||||
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0"
|
||||
|
Loading…
Reference in New Issue
Block a user