diff --git a/Makefile b/Makefile index abc4796c..c602cd48 100644 --- a/Makefile +++ b/Makefile @@ -1,11 +1,26 @@ TSC=./node_modules/typescript/bin/tsc --build +TMP=./tmp/dist all: cp nanoasm/src/assembler.ts src/worker/ $(TSC) -v $(TSC) cd jsnes && npm i + patch -i electron.diff -o electron.html + +dist: + rm -fr $(TMP) && mkdir -p $(TMP) + git archive HEAD | tar x -C $(TMP) + cp -rp gen $(TMP) + rm -r $(TMP)/doc $(TMP)/romsrc $(TMP)/scripts $(TMP)/test* $(TMP)/tools $(TMP)/electron.diff $(TMP)/.[a-z]* $(TMP)/ts*.json + rm -f $(TMP)/javatari && mkdir -p $(TMP)/javatari && cp javatari.js/release/javatari/* $(TMP)/javatari/ + tar cf - `cat electron.html | egrep "^<(script|link)" | egrep -o '"([^"]+).(js|css)"' | cut -d '"' -f2` | tar x -C $(TMP) + +%.dist: + ./node_modules/.bin/electron-packager $(TMP) --icon images/8bitworkshop-icon-1024.icns --out ./release --overwrite --platform $* + +package: dist darwin.dist win32.dist linux.dist z80: src/cpu/z80fast.js @@ -21,7 +36,6 @@ check: lint: gjslint -r src - web: (ip addr || ifconfig) | grep inet python3 scripts/serveit.py 2>> /dev/null #http.out diff --git a/README.md b/README.md index f7289b2d..14a5b968 100644 --- a/README.md +++ b/README.md @@ -65,13 +65,14 @@ The IDE uses custom forks for many of these, found at https://github.com/sehugg? * http://mcpp.sourceforge.net/ * http://www.ifarchive.org/indexes/if-archiveXinfocomXcompilersXinform6.html * https://github.com/dmsc/fastbasic -* https://github.com/apple2accumulator/merlin32 ### Assemblers/Linkers * https://dasm-assembler.github.io/ * http://atjs.mbnet.fi/mc6809/Assembler/xasm-990104.tar.gz * http://48k.ca/zmac.html +* https://github.com/apple2accumulator/merlin32 +* https://github.com/camsaul/nesasm ### Dev Kits / Libraries diff --git a/_config.yml b/_config.yml deleted file mode 100644 index c4192631..00000000 --- a/_config.yml +++ /dev/null @@ -1 +0,0 @@ -theme: jekyll-theme-cayman \ No newline at end of file diff --git a/electron-preload.js b/electron-preload.js new file mode 100644 index 00000000..103c1500 --- /dev/null +++ b/electron-preload.js @@ -0,0 +1,18 @@ +// preload.js for Electron app +const { ipcRenderer } = require('electron'); + +process.once('loaded', () => { + ipcRenderer.on('updateFile', (event, data) => { + console.log('updateFile', data); + data.cmd = 'updateFile'; + postMessage(data); + }); + window.addEventListener('message', event => { + const message = event.data; + console.log('MESSAGE', event, message); + //if (message.myTypeField === 'my-custom-message') { + //ipcRenderer.send('custom-message', message); + //} + }); + //ipcRenderer.send('hello', true); +}); diff --git a/electron.diff b/electron.diff new file mode 100644 index 00000000..80f94111 --- /dev/null +++ b/electron.diff @@ -0,0 +1,266 @@ +*** index.html 2020-07-30 21:15:48.000000000 -0500 +--- electron.html 2020-07-30 21:16:00.000000000 -0500 +*************** +*** 3,18 **** + + + 8bitworkshop IDE +- +- +- +- +- +- +- +- +- +- + + + +- +- +- +- +- +- +- +- +- +- +- +- +- +- + + + +--- 11,16 ---- +*************** if (window.location.host.endsWith('8bitw +*** 83,108 **** +
+
  • Add Include File...
  • +
  • Add Linked File...
  • +-
    +- +-
  • Request Local Storage Permissions
  • +- +- +- +
  • Break Expression...
  • + + +- +-
    +- +- + + + +--- 63,68 ---- +*************** if (window.location.host.endsWith('8bitw +*** 252,290 **** + evals/clk + + +- +- +- +- +- + + + +--- 157,162 ---- +*************** if (window.location.host.endsWith('8bitw +*** 471,543 **** + + + +- +- +- + + + +--- 343,348 ---- +*************** $( ".dropdown-submenu" ).click(function( +*** 629,640 **** + startUI(); + + +- +- + + +--- 434,438 ---- diff --git a/electron.html b/electron.html new file mode 100644 index 00000000..9ce918f9 --- /dev/null +++ b/electron.html @@ -0,0 +1,438 @@ + + + + +8bitworkshop IDE + + + + + + + + + +
    + +
    + +
    + +
    +
    +
    + + + +
    +
    + + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/electron.js b/electron.js new file mode 100644 index 00000000..a02a394d --- /dev/null +++ b/electron.js @@ -0,0 +1,252 @@ +const { app, ipcMain, ipcRenderer, Menu, BrowserWindow } = require('electron') +const modpath = require('path') +const fs = require('fs') +const {URLSearchParams} = require('url') +const isMac = process.platform === 'darwin' +const chokidar = require('chokidar') + +// file watcher +class Workspace { + constructor(directory, mainfile, wnd) { + this.directory = directory; + this.mainfile = mainfile; + this.watcher = chokidar.watch(modpath.join(directory, mainfile)); + this.watcher.on('all', (event, path) => { + console.log(event, path); + switch (event) { + case 'add': + /* + wnd.webContents.send('updateFile', { + main: modpath.relative(mainDirectoryPath, mainFilePath), + path: modpath.relative(mainDirectoryPath, path), + data: data, + }); + */ + break; + } + }); + } +} + +function openFile(path) { + var data = new Uint8Array(fs.readFileSync(path)); + var dirname = modpath.dirname(path); + var filename = modpath.basename(path); + //var platform_id = 'vcs'; // TODO: which platform? + //var wnd = createWindow({repo_id:dirname, file:filename, platform_id:platform_id}); + var wnd = BrowserWindow.getFocusedWindow(); + var ws = new Workspace(dirname, filename, wnd); + wnd.workspace = ws; + var qs = new URLSearchParams(); + qs.set('ws', dirname); + qs.set('file', filename); + wnd.loadURL(`file://${__dirname}/electron.html?${qs}`); +} + +function openFileDialog() { + const { dialog } = require('electron') + dialog.showOpenDialog({ + title: "Open File", + properties: ['openFile','promptToCreate'], + }).then((rtn) => { + if (!rtn.canceled && rtn.filePaths && rtn.filePaths.length > 0) { + var path = rtn.filePaths[0]; + openFile(path); + } + }); +} + +function openWorkspace() { + const { dialog } = require('electron') + console.log(dialog.showOpenDialog({ + title: "Open Workspace", + properties: ['openDirectory','createDirectory','promptToCreate'], + message: "Choose a directory that holds your source files.", + })) +} + +function openURL(url) { + return async () => { + const { shell } = require('electron') + await shell.openExternal(url); + } +} + +function buildMenu() { + + const template = [ + // { role: 'appMenu' } + ...(isMac ? [{ + label: app.name, + submenu: [ + { role: 'about' }, + { type: 'separator' }, + { role: 'services' }, + { type: 'separator' }, + { role: 'hide' }, + { role: 'hideothers' }, + { role: 'unhide' }, + { type: 'separator' }, + { role: 'quit' } + ] + }] : []), + // { role: 'fileMenu' } + { + label: 'File', + submenu: [ + /* + { + label: 'Open File...', + click: openFileDialog, + accelerator: 'CmdOrCtrl+O', + }, + */ + { type: 'separator' }, + isMac ? { role: 'close' } : { role: 'quit' } + ] + }, + // { role: 'editMenu' } + { + label: 'Edit', + submenu: [ + { role: 'undo' }, + { role: 'redo' }, + { type: 'separator' }, + { role: 'cut' }, + { role: 'copy' }, + { role: 'paste' }, + ...(isMac ? [ + { role: 'pasteAndMatchStyle' }, + { role: 'delete' }, + { role: 'selectAll' }, + { type: 'separator' }, + { + label: 'Speech', + submenu: [ + { role: 'startspeaking' }, + { role: 'stopspeaking' } + ] + } + ] : [ + { role: 'delete' }, + { type: 'separator' }, + { role: 'selectAll' } + ]) + ] + }, + // { role: 'viewMenu' } + { + label: 'View', + submenu: [ + { role: 'reload' }, + { role: 'forcereload' }, + { role: 'toggledevtools' }, + { type: 'separator' }, + { role: 'resetzoom' }, + { role: 'zoomin' }, + { role: 'zoomout' }, + { type: 'separator' }, + { role: 'togglefullscreen' } + ] + }, + // { role: 'windowMenu' } + { + label: 'Window', + submenu: [ + { role: 'minimize' }, + { role: 'zoom' }, + ...(isMac ? [ + { type: 'separator' }, + { role: 'front' }, + { type: 'separator' }, + { role: 'window' } + ] : [ + { role: 'close' } + ]) + ] + }, + { + role: 'help', + submenu: [ + { + label: 'IDE Help', + click: openURL('https://8bitworkshop.com/blog/docs/ide.md.html') + }, + { + label: 'Latest News', + click: openURL('https://8bitworkshop.com/blog/') + }, + { + label: 'Follow @8bitworkshop on Twitter', + click: openURL('https://twitter.com/8bitworkshop') + }, + { + label: 'Report an Issue', + click: openURL('https://github.com/sehugg/8bitworkshop/issues/new') + }, + ] + } + ] + + const menu = Menu.buildFromTemplate(template) + Menu.setApplicationMenu(menu) +} + +function createWindow () { + // Create the browser window. + const win = new BrowserWindow({ + width: 1024, + height: 768, + backgroundColor: '#fff', + webPreferences: { + preload: modpath.join(__dirname, './electron-preload.js'), + nodeIntegration: false, + enableRemoteModule: false, + contextIsolation: true, + sandbox: true, + } + }) + + // and load the index.html of the app. + win.loadFile('electron.html') + + // Open the DevTools. + //win.webContents.openDevTools() + + // Maximize + win.maximize(); + return win; +} + +// 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.whenReady().then(buildMenu).then(createWindow) + +// 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', () => { + if (process.platform !== 'darwin') { + app.quit() + } +}) + +app.on('activate', () => { + // On macOS 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 require them here. + +// Register IPC messages +// https://stackoverflow.com/questions/52236641/electron-ipc-and-nodeintegration +/* +ipcMain.on('hello', (event, message) => { + console.log(event); +}); +*/ diff --git a/images/8bitworkshop-icon-1024.icns b/images/8bitworkshop-icon-1024.icns new file mode 100644 index 00000000..e53b162e Binary files /dev/null and b/images/8bitworkshop-icon-1024.icns differ diff --git a/images/8bitworkshop-icon-1024.ico b/images/8bitworkshop-icon-1024.ico new file mode 100644 index 00000000..ad9102fe Binary files /dev/null and b/images/8bitworkshop-icon-1024.ico differ diff --git a/images/8bitworkshop-icon-1024.png b/images/8bitworkshop-icon-1024.png new file mode 100644 index 00000000..dcd7a058 Binary files /dev/null and b/images/8bitworkshop-icon-1024.png differ diff --git a/index.html b/index.html index 0bc39f45..e7bdeb00 100644 --- a/index.html +++ b/index.html @@ -131,8 +131,8 @@ if (window.location.host.endsWith('8bitworkshop.com')) {