From 137145cc85c43a2d939edeb72320bc64abb6e211 Mon Sep 17 00:00:00 2001 From: boxgaming <75969133+boxgaming@users.noreply.github.com> Date: Wed, 30 Mar 2022 17:37:36 -0500 Subject: [PATCH] v0.3.0-beta updates --- codemirror/qb-lang.js | 22 +- dialog/dialog-polyfill.js | 105 --- dialog/dialog-simple.css | 18 - dialog/dialog.css | 81 -- dialog/dialog.js | 435 ---------- gx/gx.js | 7 +- index.html | 225 +++-- play.png | Bin 0 -> 533 bytes qb.js | 251 +++++- qb2js.js | 1727 +++++++++++++++++++------------------ tools/qb2js.bas | 79 +- 11 files changed, 1402 insertions(+), 1548 deletions(-) delete mode 100644 dialog/dialog-polyfill.js delete mode 100644 dialog/dialog-simple.css delete mode 100644 dialog/dialog.css delete mode 100644 dialog/dialog.js create mode 100644 play.png diff --git a/codemirror/qb-lang.js b/codemirror/qb-lang.js index 1804cdc..1cb61f1 100644 --- a/codemirror/qb-lang.js +++ b/codemirror/qb-lang.js @@ -35,13 +35,18 @@ CodeMirror.defineMode("qbjs", function(conf, parserConf) { // TODO: adjust for QB var atomWords = ['true', 'false', 'nothing', 'empty', 'null']; - var builtinFuncsWords = ['_alpha', '_alpha32', '_atan2', '_autodisplay', '_blue', '_blue32', '_copyimage', '_delay', '_dest', '_dest', '_display', '_fontwidth', - '_freeimage', '_green', '_green32', '_height', '_instrrev', '_limit', '_keyclear', '_keydown', '_keyhit', '_loadimage', - '_mousebutton', '_mouseinput', '_mousex', '_mousey', '_newimage', '_pi', '_printstring', '_printwidth', '_putimage', - '_red', '_red32', '_rgb', '_rgba', '_rgb32', '_rgba32', '_round', '_screenexists', '_title', '_trim', '_width', 'abs', - 'asc', 'atn', 'chr', 'circle', 'cls', 'color', 'command', 'cos', 'exp', 'fix', 'input', 'inkey', 'instr', 'int', - 'lbound', 'left', 'lcase', 'len', 'line', 'locate', 'log', 'ltrim', 'mid', 'print', 'pset', 'right', 'rtrim', 'rnd', - 'screen', 'sgn', 'sin', 'sleep', 'sqr', 'str', 'swap', 'tan', 'timer', 'ubound', 'ucase', 'val']; + var builtinFuncsWords = ['_alpha', '_alpha32', '_atan2', '_autodisplay', '_blue', '_blue32', '_continue', '_copyimage', '_delay', '_dest', '_dest', + '_display', '_fontwidth', '_freeimage', '_green', '_green32', '_height', '_instrrev', '_limit', '_keyclear', '_keydown', + '_keyhit', '_loadimage', '_mousebutton', '_mouseinput', '_mousex', '_mousey', '_newimage', '_pi', '_printstring', '_printwidth', + '_putimage', '_red', '_red32', '_resize', '_resizewidth', '_resizeheight', '_rgb', '_rgba', '_rgb32', '_rgba32', '_round', + '_screenexists', '_sndclose', '_sndopen', '_sndplay', '_sndloop', '_sndpause', '_sndstop', '_sndvol', + '_title', '_trim', '_width', 'abs', 'asc', 'atn', 'chr', 'circle', 'cls', 'color', 'command', 'cos', 'cvi', 'cvl', 'exp', + 'fix', 'input', 'inkey', 'instr', 'int', 'lbound', 'left', 'lcase', 'len', 'line', 'locate', 'log', 'ltrim', 'mid', 'mki', 'mkl', + 'print', 'pset', 'right', 'rtrim', 'rnd', 'screen', 'shared', 'sgn', 'sin', 'sleep', 'space', 'sqr', 'str', 'swap', 'tan', + 'timer', 'ubound', 'ucase', 'val', + // QBJS-specific + 'alert', 'confirm', 'domadd', 'domcontainer', 'domcreate', 'domevent','domget', 'domgetimage', 'domremove', 'prompt', + 'storageclear', 'storageget', 'storagekey', 'storagelength', 'storageset', 'storageremove']; var builtinConsts = ['gx_true', 'gx_false', 'gxevent_init', 'gxevent_update', 'gxevent_drawbg', 'gxevent_drawmap', 'gxevent_drawscreen', 'gxevent_mouseinput', 'gxevent_paintbefore', 'gxevent_paintafter', 'gxevent_collision_tile', 'gxevent_collision_entity', @@ -64,7 +69,8 @@ CodeMirror.defineMode("qbjs", function(conf, parserConf) { 'gxscene_follow_entity_center_x', 'gxscene_follow_entity_center_y', 'gxscene_follow_entity_center_x_pos', 'gxscene_follow_entity_center_x_neg', 'gxscene_constrain_none', 'gxscene_constrain_to_map', 'gxfont_default', 'gxfont_default_black', 'gxdevice_keyboard', 'gxdevice_mouse', 'gxdevice_controller', 'gxdevice_button', - 'gxdevice_axis', 'gxdevice_wheel', 'gxtype_entity', 'gxtype_font', 'gx_cr', 'gx_lf', 'gx_crlf']; + 'gxdevice_axis', 'gxdevice_wheel', 'gxtype_entity', 'gxtype_font', 'gx_cr', 'gx_lf', 'gx_crlf', + 'local', 'session']; var builtinObjsWords = ['\\$if', '\\$end if']; diff --git a/dialog/dialog-polyfill.js b/dialog/dialog-polyfill.js deleted file mode 100644 index 527c44c..0000000 --- a/dialog/dialog-polyfill.js +++ /dev/null @@ -1,105 +0,0 @@ -'use strict'; -/** - * Polyfill of dialog - * for Firefox - * - * author Nemo - * - * v1.1 - * Supports: - * show - * hide - * showModal - * cancel(ESC) - */ -{ - -const UA = window.navigator.userAgent; -const browser = { - isFirefox: UA.includes('Firefox'), -}; - -const dlg = document.createElement('dialog'); -let mask = undefined; - -const initMask = () => { - if (mask != undefined) - return; - - mask = document.createElement('div'); - mask.style.display = 'none'; - mask.style.position = 'absolute'; - mask.style.zIndex = 999998; - mask.style.top = 0; - mask.style.left = 0; - mask.style.right = 0; - mask.style.bottom = 0; - mask.style.backgroundColor = 'rgba(0, 0, 0, 0.1)'; - document.body.appendChild(mask); -}; - -// show support -if (!dlg.__proto__.show) { - dlg.__proto__.open = false; - - dlg.__proto__.show = function() { - this.open = true; - - this.style.backgroundColor = 'white'; - this.style.position = 'absolute'; - this.style.zIndex = 999999; - this.style.display = 'table'; - this.style.top = '50%'; - this.style.transform = 'translate(0, -50%)'; - - return this; - }; -} - -// showModal support -if (!dlg.__proto__.showModal) { - initMask(); - - dlg.__proto__.showModal = function() { - mask.style.display = 'block'; - this.show(); - - return this; - }; -} - -// hide support -if (!dlg.__proto__.close) { - initMask(); - - dlg.__proto__.close = function() { - this.open = false; - - mask.style.display = 'none'; - this.style.display = 'none'; - - return this; - } -} - -// cancel(ESC) support -if (dlg.oncancel === void 0) { - const dialogClass = 'dlg-dialog'; - document.addEventListener('keypress', (e) => { - if (e.code !== 'Escape') - return; - - let dlgs = document.querySelectorAll(`.${dialogClass}`); - for (let i = 0; i < dlgs.length; i++) { - let d = dlgs[i]; - if (d.style.display === 'none') - continue; - - if (d.wrapper.cancelable) { - d.close(); - } - } - }); -} - -} diff --git a/dialog/dialog-simple.css b/dialog/dialog-simple.css deleted file mode 100644 index 2fae759..0000000 --- a/dialog/dialog-simple.css +++ /dev/null @@ -1,18 +0,0 @@ -.dlg-dialog { - border: none; - box-shadow: 10px 10px 20px gray; -} - -.dlg-header { - background-color: #555; - color: white; -} - -.dlg-caption { - height: 1.17em; - text-shadow: 1px 1px 1px black; -} -.dlg-close-button::before, -.dlg-close-button::after { - background-color: white; -} diff --git a/dialog/dialog.css b/dialog/dialog.css deleted file mode 100644 index 2f12fd6..0000000 --- a/dialog/dialog.css +++ /dev/null @@ -1,81 +0,0 @@ -.dlg-dialog { - position: fixed; - top: 0; - bottom: 0; - box-sizing: border-box; - min-width: 300px; - max-width: 100%; - padding: 0; - overflow: hidden; - background-color: #ccc; -} - -.dlg-dialog textarea { - background-color: #ccc; - font-family: dosvga; - font-size: 1em; - padding: .25em; - border: 2px solid #333; -} - -.dlg-header { - padding: .5em; - background-color: #999; - border-bottom: 1px solid #333; -} - -.dlg-caption { - font-size: 1em; - margin: 0; - padding-right: 2em; - font-weight: normal; -} - -.dlg-close-button { - position: absolute; - right: .5em; - top: .5em; - width: 1.17em; - height: 1.17em; - cursor: pointer; -} - -.dlg-close-button::before { - transform: rotate(45deg); -} - -.dlg-close-button::after{ - transform: rotate(-45deg); -} - -.dlg-close-button::before, -.dlg-close-button::after { - content: ''; - position: absolute; - height: 1px; - width: 100%; - top: 50%; - left:0; - background-color: black; -} - -.dlg-body { - padding: .5em; -} - -.dlg-content { - padding: .5em; - overflow: auto; -} - -.dlg-button-area { - padding: 0 .5em; - text-align: right; -} - -.dlg-button-area button { - padding: .3em .4em; - margin-left: 1em; - width: 5em; - text-align: center; -} diff --git a/dialog/dialog.js b/dialog/dialog.js deleted file mode 100644 index 42d1830..0000000 --- a/dialog/dialog.js +++ /dev/null @@ -1,435 +0,0 @@ -/** - * class Dialog { - * - * author: nemo - * date: 2017-06-20 - * v: 1.1 - * } - */ -{ -'use strict'; - -class Dialog { - - constructor(opt) { - Object.assign(this.option = { - caption: '', - message: '', - content: undefined, - buttons: Dialog.buttons.NONE, - - resize: 'none', - - cancelable: true, - - showHeader: true, - showClose: true, - showFooter: false, - - // handler - abortHandler: undefined, - cancelHandler: () => { this.close(); }, - ignoreHandler: undefined, - noHandler: undefined, - okHandler: () => { this.close(); }, - retryHandler: undefined, - yesHandler: undefined, - - // events - beforeClosing: () => { return true; }, // set to false to prevent close - closed: undefined, - }, opt); - this.init(); - } - - /** - * START init - */ - init() { - return this - .initLayout() - .initAttributes() - .initContent() - .initEvents(); - } - - initLayout() { - this.dialog = create('dialog', 'dialog'); - this.dialog.style.resize = this.option.resize, - appendTo(this.dialog, document.body); - this.show(); - - this.container = this.dialog; - - this.header = create('header', 'header'); - this.caption = create('h3', 'caption'); - this.closeButton = create('em', 'close-button'); - - this.body = create('div', 'body'); - this.content = create('section', 'content'); - this.buttonArea = create('div', 'button-area'); - - this.footer = create('footer', 'footer'); - - // assembly dom - this.header.appendChild(this.caption); - if (this.option.showClose) - this.header.appendChild(this.closeButton); - if (this.option.showHeader) - this.dialog.appendChild(this.header); - - this.body.appendChild(this.content); - this.body.appendChild(this.buttonArea); - this.assemblyButtons(); - this.dialog.appendChild(this.body); - - if (this.option.showFooter) - this.dialog.appendChild(this.footer); - - return this; - } - - initAttributes() { - this.dialog.wrapper = this; - - this.cancelable = this.option.cancelable; - - return this; - } - - assemblyButtons() { - switch (this.option.buttons) { - case Dialog.buttons.ABORT_RETRY_IGNORE: - new DialogButton(this, Dialog.button.ABORT).assembly(); - new DialogButton(this, Dialog.button.RETRY).assembly().focus(); - new DialogButton(this, Dialog.button.IGNORE).assembly(); - break; - case Dialog.buttons.OK: - new DialogButton(this, Dialog.button.OK).assembly().focus(); - break; - case Dialog.buttons.OK_CANCEL: - new DialogButton(this, Dialog.button.OK).assembly(); - new DialogButton(this, Dialog.button.CANCEL).assembly().focus(); - break; - case Dialog.buttons.RETRY_CANCEL: - new DialogButton(this, Dialog.button.RETRY).assembly().focus(); - new DialogButton(this, Dialog.button.CANCEL).assembly(); - break; - case Dialog.buttons.YES_NO: - new DialogButton(this, Dialog.button.YES).assembly(); - new DialogButton(this, Dialog.button.NO).assembly().focus(); - break; - case Dialog.buttons.YES_NO_CANCEL: - new DialogButton(this, Dialog.button.YES).assembly(); - new DialogButton(this, Dialog.button.NO).assembly(); - new DialogButton(this, Dialog.button.CANCEL).assembly().focus(); - break; - default: - // no button - break; - } - - return this; - } - - appendButton(btn) { - this.buttonArea.appendChild(btn.button); - return this; - } - - removeButton(btn) { - this.buttonArea.removeChild(btn.button); - return this; - } - - initContent() { - this.caption.innerText = this.option.caption; - if (this.option.content == undefined) { - this.content.innerText = this.option.message; - } else { - this.content.innerHTML = this.option.content; - } - - return this; - } - - initEvents() { - this.closeButton.addEventListener('click', () => { - this.close(); - }); - - // prevent esc - this.dialog.addEventListener('cancel', (e) => { - !this.cancelable && e.preventDefault(); - }); - - return this; - } - /** - * END init - */ - - //:~ - - trigger(type) { - switch (type) { - case Dialog.button.ABORT: - callHandler(this.option.abortHandler, this); - break; - case Dialog.button.CANCEL: - callHandler(this.option.cancelHandler, this); - break; - case Dialog.button.IGNORE: - callHandler(this.option.ignoreHandler, this); - break; - case Dialog.button.NO: - callHandler(this.option.noHandler, this); - break; - case Dialog.button.OK: - callHandler(this.option.okHandler, this); - break; - case Dialog.button.RETRY: - callHandler(this.option.retryHandler, this); - break; - case Dialog.button.YES: - callHandler(this.option.yesHandler, this); - break; - default: - console.log(`Unknown type:${type}`); - break; - } - - return this; - } - - beforeClosing(func) { - this.option.beforeClosing = func; - - return this; - } - - closed(func) { - this.dialog.addEventListener('close', func); - - return this; - } - - get cancelable() { - return this.option.cancelable; - } - - set cancelable(value) { - this.option.cancelable = !!value; - } - - show() { - if (this.dialog.open) - return this; - - try { - this.dialog.showModal(); - } catch (e) { - appendTo(this.dialog, document.body); - this.dialog.showModal(); - } - - return this; - } - - hide(dispose = true) { - if (!this.dialog.open) - return this; - - if (typeof this.option.beforeClosing != 'function' || - !!this.option.beforeClosing()) { - this.dialog.close(); - - try { - dispose && document.body.removeChild(this.dialog); - } finally { } - } - - return this; - } - - close(dispose = true) { - return this.hide(dispose); - } - - addClass(className) { - addClass(this.dialog, className); - } - - //:~ - - /** - * START static helper - */ - static alert(message, caption = '') { - return new Dialog({ - caption: `${caption}`, - message: `${message}`, - buttons: Dialog.buttons.OK, - }); - } - - static confirm(message, caption = '', ok, cancel) { - return new Dialog({ - caption: `${caption}`, - message: `${message}`, - buttons: Dialog.buttons.OK_CANCEL, - okHandler: ok, - cancelHandler: cancel, - }); - } - - static template(dom, caption = '') { - return new Dialog({ - caption: `${caption}`, - content: dom.innerHTML, - }); - } - - static templet(dom, caption) { - return template(dom, caption); - } - - static iframe(src, caption = '', width = 'auto', height = 'auto') { - let dlg = new Dialog({ - caption: `${caption}`, - content: ``, - }); - let iframe = dlg.content.childNodes[0]; - iframe.style.width = width; - iframe.style.height = height; - } - /** - * END static helper - */ -} - -class DialogButton { - constructor(dialog, type) { - this.dialog = dialog; - this.type = type; - - this.button = create('button', `btn-${type}`); - this.button.type = 'button'; - this.button.innerText = Dialog.buttonText[type]; - - this.click(() => { - this.dialog.trigger(this.type); - }); - } - - assembly() { - this.dialog.appendButton(this); - - return this; - } - - click(func) { - this.button.addEventListener('click', func); - - return this; - } - - focus() { - window.setTimeout(() => { - this.button.focus(); - }, 1); - - return this; - } -} - -Object.assign(Dialog, { - - buttons: { - ABORT_RETRY_IGNORE: 1, - OK: 2, - OK_CANCEL: 3, - RETRY_CANCEL: 4, - YES_NO: 5, - YES_NO_CANCEL: 6, - }, - - button: { - NONE: 0, - ABORT: 1, - CANCEL: 2, - IGNORE: 3, - NO: 4, - OK: 5, - RETRY: 6, - YES: 7, - }, - - buttonText: [ - undefined, - 'Abort', - 'Cancel', - 'Ignore', - 'NO', - 'OK', - 'Retry', - 'Yes', - ], -}); - -let callHandler = (func, dlg) => { - return typeof func == 'function' ? - func(dlg) : undefined; -} - -let cls = (cls) => { - return `dlg-${cls}`; -} - -let addClass = (dom, className) => { - let c = dom.className; - let add = cls(className); - if (c == '') { - return add; - } else { - return c + ' ' + add; - } -} - -let prependTo = (sub, base) => { - if (base.hasChildNodes()) { - base.insertBefore(sub, base.firstChild); - } else { - base.appendChild(sub); - } -} - -let appendTo = (sub, base) => { - base.appendChild(sub); -} - -let show = (dom, display = 'block') => { - visible(dom, true, display); -} - -let hide = (dom) => { - visible(dom, true); -} - -let visible = (dom, v, display) => { - if (dom == undefined || dom.style == undefined) - return; - else - dom.style.display = v ? display : 'none'; -} - -let create = (name, className) => { - let e = document.createElement(name); - if (typeof className == 'string') - e.className = cls(className); - return e; -} - -// export { Dialog } // ES6 -window['Dialog'] = Dialog; -} diff --git a/gx/gx.js b/gx/gx.js index c26a808..04d6df0 100644 --- a/gx/gx.js +++ b/gx/gx.js @@ -572,6 +572,11 @@ var GX = new function() { // Sound Methods // ---------------------------------------------------------------------------- + function _soundClose (sid) { + _sounds[sid-1].pause(); + _sounds[sid-1] = undefined; + } + function _soundLoad (filename) { var a = new Audio(filename); _sounds.push(a); @@ -613,7 +618,6 @@ var GX = new function() { return _sound_muted; } - // Entity Functions // ----------------------------------------------------------------------------- function _entityCreate (imageFilename, ewidth, height, seqFrames, uid) { @@ -2299,6 +2303,7 @@ var GX = new function() { this.backgroundHeight = _backgroundHeight; this.backgroundClear = _backgroundClear; + this.soundClose = _soundClose; this.soundLoad = _soundLoad; this.soundPlay = _soundPlay; this.soundRepeat = _soundRepeat; diff --git a/index.html b/index.html index 3fb857c..2b72273 100644 --- a/index.html +++ b/index.html @@ -116,16 +116,60 @@ background-color: transparent; color: #ccc; } + #gx-load-screen { + display: none; + text-align: center; + margin: auto; + width: 600px; + height: 360px; + font-size: 24px; + color: #ccc; + border: 1px solid #000; + text-decoration: none; + background-position: center center; + background-image: url('play.png'); + background-repeat: no-repeat; + background-color: #444; + } + #gx-load-screen:hover { + background-color: #555; + } + #gx-load-screen:before { content: ""; } + #gx-load-screen:after { content: ""; } + + #gx-container a, #gx-container a:link, #gx-container a:visited { + color: rgb(69, 118, 147); + } + #gx-container a:hover { + color: rgb(69, 118, 147); + text-decoration: underline; + } + #gx-container a:before { content: ""; } + #gx-container a:after { content: ""; } + + #gx-container, #gx-container table { + font-family: arial, helvetica, sans-serif; + font-size: 14px; + } + + #share-dialog { + background-color:#ddd; + } + #share-dialog textarea { + font-family: dosvga; + font-size: 1em; + background-color: #efefef; + } + #share-dialog a { color: #333; } + #share-dialog a:hover { color: #000; } + - - -