Skip to content

Commit

Permalink
Update 95
Browse files Browse the repository at this point in the history
  • Loading branch information
morgan3d committed Aug 29, 2023
1 parent d0ae452 commit 1a8f694
Show file tree
Hide file tree
Showing 11 changed files with 84 additions and 37 deletions.
20 changes: 13 additions & 7 deletions console/ace/ace.js
100755 → 100644

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion console/ace/ext-searchbox.js
100755 → 100644

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion console/lib/versions.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ qrcode.js Nov 25, 2015 https://github.com/davidshimjs/qrcodejs
js-yaml.min.js 4.1.0 https://github.com/nodeca/js-yaml
dagre.min.js
decomp.min.js
../ace/ace.js 1.15.0 https://github.com/ajaxorg/ace
../ace/ace.js 1.24.1 https://github.com/ajaxorg/ace-builds/
webmidi.js 3.1.5 https://cdn.jsdelivr.net/npm/webmidi@latest/dist/iife/webmidi.iife.js
12 changes: 8 additions & 4 deletions console/quadplay-edit-code.js
Original file line number Diff line number Diff line change
Expand Up @@ -830,22 +830,26 @@ function onNewModeCreate() {
// Name is OK, create the mode
const modeContents = `${name}
════════════════════════════════════════════════════════════════════════
// Put local state for the mode here. Declare variables with let, constants with const, and functions with def.
// Put local state for the mode here. Declare variables with let,
// constants with const, and functions with def.
enter
────────────────────────────────────────────────────────────────────────
// This event runs when the mode is entered via set_mode() or push_mode().
// This event runs when the mode is entered via set_mode() or
// push_mode().
frame
────────────────────────────────────────────────────────────────────────
// This event runs 60 times per second. Game logic, simulation, user input, and drawing all go here.
// This event runs 60 times per second. Game logic, simulation,
// user input, and drawing all go here.
leave
────────────────────────────────────────────────────────────────────────
// This event runs just before leaving for another mode by set_mode() or pop_mode().
// This event runs just before leaving for another mode by
// set_mode() or pop_mode().
`;
// Tell the server
Expand Down
22 changes: 11 additions & 11 deletions console/quadplay-ide.js
Original file line number Diff line number Diff line change
Expand Up @@ -505,13 +505,13 @@ function onBackgroundPauseClick(event) {
function onAutoSleepClick(event) {
event.stopPropagation();
autosleepEnabled = document.getElementById('autoSleepCheckbox').checked;
saveIDEState();
localStorage.setItem('autoSleepEnabled', autoSleepEnabled);
}

function setKeyboardMappingMode(type) {
keyboardMappingMode = type;
document.getElementById(type + 'KeyboardRadio').checked = '1';
saveIDEState();
localStorage.setItem('keyboardMappingMode', type);
}


Expand Down Expand Up @@ -1973,7 +1973,7 @@ if (useIDE) {
function saveIDEState() {
// Never save in kiosk mode
if (getQueryString('kiosk') === '1') { return; }

const options = {
'uiMode': uiMode,
'backgroundPauseEnabled': backgroundPauseEnabled,
Expand Down Expand Up @@ -2527,7 +2527,7 @@ function visualizeGame(gameEditor, url, game) {

s+= '<tr><td>&nbsp;</td></tr>\n';
if (editableProject) {
s += '<tr valign="top"><td>Start&nbsp;Mode</td><td colspan=3><select style="width:390px" onchange="onProjectInitialModeChange(this.value)">\n';
s += '<tr valign="top"><td>Start&nbsp;Mode</td><td colspan=3><select id="projectstartmodedropdown" style="width:390px" onchange="onProjectInitialModeChange(this.value)">\n';
for (let i = 0; i < gameSource.modes.length; ++i) {
const mode = gameSource.modes[i];
if (! mode.name.startsWith('quad://console/os/_') && ! mode.name.startsWith('$')) {
Expand All @@ -2537,7 +2537,7 @@ function visualizeGame(gameEditor, url, game) {
s += '</select></td></tr>\n';

const overrideInitialMode = gameSource.debug && gameSource.debug.json && gameSource.debug.json.start_mode_enabled && gameSource.debug.json.start_mode;
s += `<tr valign="top"><td></td><td><label><input type="checkbox" autocomplete="false" style="margin-left:0" ${overrideInitialMode ? 'checked' : ''} onchange="onDebugInitialModeOverrideChange(this)">Debug&nbsp;Override</label></td><td colspan=2"><select id="debugOverrideInitialMode" style="width:205px; top:-2px" ${overrideInitialMode ? '' : 'disabled'} onchange="onProjectDebugInitialModeChange(this.value)">\n`;
s += `<tr valign="top"><td></td><td><label><input id="projectdebugstartmodeoverridecheckbox" type="checkbox" autocomplete="false" style="margin-left:0" ${overrideInitialMode ? 'checked' : ''} onchange="onDebugInitialModeOverrideChange(this)">Debug&nbsp;Override</label></td><td colspan=2"><select id="debugOverrideInitialMode" style="width:205px; top:-2px" ${overrideInitialMode ? '' : 'disabled'} onchange="onProjectDebugInitialModeChange(this.value)">\n`;
for (let i = 0; i < gameSource.modes.length; ++i) {
const mode = gameSource.modes[i];
if (! mode.name.startsWith('quad://console/os/_') && ! mode.name.startsWith('$')) {
Expand All @@ -2546,7 +2546,7 @@ function visualizeGame(gameEditor, url, game) {
}
s += '</select></td></tr>\n';

s += `<tr valign="top"><td>Screen&nbsp;Size</td><td colspan=3><select style="width:390px" onchange="onProjectScreenSizeChange(this)">`;
s += `<tr valign="top"><td>Screen&nbsp;Size</td><td colspan=3><select id="projectscreensizedropdown" style="width:390px" onchange="onProjectScreenSizeChange(this)">`;
for (let i = 0; i < allowedScreenSizes.length; ++i) {
const W = allowedScreenSizes[i].x, H = allowedScreenSizes[i].y;
s += `<option value='{"x":${W},"y":${H}}' ${W === gameSource.extendedJSON.screen_size.x && H === gameSource.extendedJSON.screen_size.y ? "selected" : ""}>${W} × ${H}${W === 384 && H === 224 ? ' ✜' : ''}</option>`;
Expand All @@ -2561,12 +2561,12 @@ function visualizeGame(gameEditor, url, game) {
break;
}
}
s += `<tr valign="top"><td>Screen&nbsp;Size</td><td colspan=3><input type="text" autocomplete="false" style="width:384px" ${disabled} value="${gameSource.extendedJSON.screen_size.x} × ${gameSource.extendedJSON.screen_size.y}"></td></tr>\n`;
s += `<tr valign="top"><td>Screen&nbsp;Size</td><td colspan=3><input id="projectscreensizetextbox" type="text" autocomplete="false" style="width:384px" ${disabled} value="${gameSource.extendedJSON.screen_size.x} × ${gameSource.extendedJSON.screen_size.y}"></td></tr>\n`;
}
s += `<tr valign="top"><td></td><td colspan=3><label><input type="checkbox" autocomplete="false" style="margin-left:0" ${disabled} ${game.y_up ? 'checked' : ''} onchange="onProjectYUpChange(this)">Y-Axis = Up</label></td></tr>\n`;
s += `<tr valign="top"><td></td><td colspan=3><label><input id="projectyupcheckbox" type="checkbox" autocomplete="false" style="margin-left:0" ${disabled} ${game.y_up ? 'checked' : ''} onchange="onProjectYUpChange(this)">Y-Axis = Up</label></td></tr>\n`;

s += '<tr><td>&nbsp;</td></tr>\n';
s += `<tr valign="top"><td>I/O</td><td colspan=4><label><input type="checkbox" autocomplete="false" style="margin-left:0" ${disabled} ${game.dual_dpad ? 'checked' : ''} onchange="onProjectDualDPadChange(this)">Dual D-Pad</label> <label><input type="checkbox" autocomplete=false ${disabled} ${game.midi_sysex ? 'checked' : ''} onchange="onProjectMIDISysexChange(this)" style="margin-left: 50px" tooltip="Does this game send MIDI sysex messages?">MIDI Sysex Output</label></td></tr>\n`;
s += `<tr valign="top"><td>I/O</td><td colspan=4><label><input id="projectdualdpadcheckbox" type="checkbox" autocomplete="false" style="margin-left:0" ${disabled} ${game.dual_dpad ? 'checked' : ''} onchange="onProjectDualDPadChange(this)">Dual D-Pad</label> <label><input id="projectmidicheckbox" type="checkbox" autocomplete=false ${disabled} ${game.midi_sysex ? 'checked' : ''} onchange="onProjectMIDISysexChange(this)" style="margin-left: 50px" tooltip="Does this game send MIDI sysex messages?">MIDI Sysex Output</label></td></tr>\n`;
s += '<tr><td>&nbsp;</td></tr>\n';

s += `<tr valign="top"><td>Description<br><span id="projectDescriptionLength">(${(game.description || '').length}/100 chars)</span> </td><td colspan=3><textarea ${disabled} style="width:384px; padding: 3px; margin-bottom:-3px; font-family: Helvetica, Arial; font-size:12px" rows=2 id="projectDescription" onchange="onProjectMetadataChanged(this)" oninput="document.getElementById('projectDescriptionLength').innerHTML = '(' + this.value.length + '/100 chars)'">${game.description || ''}</textarea>`;
Expand All @@ -2584,7 +2584,7 @@ function visualizeGame(gameEditor, url, game) {
s += `<tr valign="top"><td>Screenshot&nbsp;Tag</td><td colspan=3><input type="text" autocomplete="false" style="width:384px" ${disabled} onchange="onProjectMetadataChanged()" id="screenshotTag" value="${game.screenshot_tag.replace(/"/g, '\\"')}"></td></tr>\n`;
if (editableProject) {
const overrideTag = gameSource.debug.json && gameSource.debug.json.screenshot_tag_enabled;
s += `<tr><td></td><td><label><input type="checkbox" autocomplete="false" style="margin-left:0" ${overrideTag ? 'checked' : ''} onchange="onDebugScreenshotTagOverrideChange(this)">Debug&nbsp;Override</label></td><td colspan=2><input type="text" autocomplete="false" style="width:198px" ${overrideTag ? '' : 'disabled'} ${disabled} onchange="onProjectMetadataChanged()" id="debugScreenshotTag" value="${(game.debug && game.debug.json && game.debug.json.screenshot_tag !== undefined) ? game.debug.json.screenshot_tag.replace(/"/g, '\\"') : ''}"></td></tr>`;
s += `<tr><td></td><td><label><input id="projectscreenshottag" type="checkbox" autocomplete="false" style="margin-left:0" ${overrideTag ? 'checked' : ''} onchange="onDebugScreenshotTagOverrideChange(this)">Debug&nbsp;Override</label></td><td colspan=2><input type="text" autocomplete="false" style="width:198px" ${overrideTag ? '' : 'disabled'} ${disabled} onchange="onProjectMetadataChanged()" id="debugScreenshotTag" value="${(game.debug && game.debug.json && game.debug.json.screenshot_tag !== undefined) ? game.debug.json.screenshot_tag.replace(/"/g, '\\"') : ''}"></td></tr>`;
}
s += '<tr><td>&nbsp;</td></tr>\n';

Expand Down Expand Up @@ -5046,7 +5046,7 @@ LoadManager.fetchOne({}, location.origin + getQuadPath() + 'console/_config.json
serverConfig = json;
});

// Make the browser aware that we want gamepads as early as possible
// As early as possible, make the browser aware that we want gamepads
navigator.getGamepads();

// Initialize MIDI without requiring sysex, which can prompt.
Expand Down
2 changes: 1 addition & 1 deletion console/quadplay.css
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ div.debugOverride.disabled {
-webkit-touch-callout: none;
}

.button label span.label {
.button label span.label, .button span.label {
margin: 0px;
background-color: #FFF;
background: linear-gradient(to bottom, rgba(255,255,255,1) 0%,rgba(242,242,242,1) 36%,rgba(242,242,242,1) 90%,rgba(224,224,224,1) 100%);
Expand Down
2 changes: 1 addition & 1 deletion console/quadplay.html
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
const isQuadserver = getQueryString('quadserver') === '1';

function makeButton(label, title, onclick, id) {
document.write('<div ' + (id ? 'id="' + id + 'Container" ' : '') + ' onmousedown="event.stopPropagation()" class="button" onclick="if (event.target.parentElement.parentElement.enabled !== false) ' + (onclick || '') + '(event)" title="' + (title || label) + '"><label><span class="label" ' + (id ? 'id="' + id + 'Label"' : '') + '>' + label + '</span></label></div>');
document.write('<div ' + (id ? 'id="' + id + 'Container" ' : '') + ' onmousedown="event.stopPropagation()" class="button" onclick="if (event.target.parentElement.parentElement.enabled !== false) ' + (onclick || '') + '(event)" title="' + (title || label) + '"><span class="label" ' + (id ? 'id="' + id + 'Label"' : '') + '>' + label + '</span></div>');
}

function makeRadio(labelHTML, id, selected, attribs, groupID, disabled) {
Expand Down
2 changes: 1 addition & 1 deletion console/version.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
const version = '2023.08.27.22';
const version = '2023.08.29.06';
2 changes: 1 addition & 1 deletion doc/assets.md.html
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@

document.write(`
<div style="display: inline-block; margin-right: 20px; margin-bottom: 10px">
<div class="font" style="background-image:url('../fonts/${font}.png')"></div>
<div class="font" style="background-image:url('../fonts/${font.replace(/-mono/, '')}.png')"></div>
\`quad://fonts/${font}.font.json\`
</div>`);
</script>
Expand Down
8 changes: 7 additions & 1 deletion doc/changelog.md.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,19 @@
Changes for both the specification and implementation in each release
of [<quadplay/>](manual.md.html).

2023 August TBD: Update 95
2023 August 29: Update 95
===================================

- Open Game now has a filter to search for text
- Added MAME mapping for arcade controllers that act as hardcoded keyboards
- Added Ultimarc Mini PAC mapping for arcade controllers that act as hardcoded keyboards
- Removed "ξ" from vim plugin syntax highlighting (crashes vim)
- Upgraded to ace.js 1.24.1
- Fixed `game_frames == -1` at top level and in the start mode `enter()`
- Fixed several warnings under Chrome
- Fixed visualization of monospace font assets in the documentation
- Fixed IDE options resetting on browser reload


2023 July 29: Update 94
===================================
Expand Down
47 changes: 39 additions & 8 deletions scripts/midi_8x8.pyxl
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ API:
- `device_get_pixel(pos)`
- `device_set_all(color)`
- `device_set_border(color)`
- `device_any_pressed()`
- `transform_ds_to_ws(pos)`
- `device_blit(sprite, lower_left_corner default xy(0, 0), write_to_border default false)`
*/

Expand Down Expand Up @@ -269,7 +271,7 @@ def device_visualize(font default nil)
if font:
const text_args = {
font: font,
color: #FFF, shadow: #000, outline: #000,
color: #888, shadow: #000, outline: #000,
x_align: "center", y_align: "bottom", z:2 }

draw_text({
Expand Down Expand Up @@ -319,6 +321,7 @@ def device_visualize(font default nil)
draw_corner_rect(pos + 2, PAD_SIZE - 4, ∅, #FFF)



// Call once per frame to discover new devices. Automatically
// called from device_send_output
def _device_discover(device):
Expand Down Expand Up @@ -677,7 +680,10 @@ def device_blit(sprite, corner default xy(0, 0), write_to_border default false):

// Allow passing a sprite sheet as a sprite
if is_array(sprite): sprite = sprite[0][0]


// Flip the sprite y axis
sprite = sprite.y_flipped

// Source
let sx0 = 0
let sy0 = 0
Expand All @@ -690,6 +696,8 @@ def device_blit(sprite, corner default xy(0, 0), write_to_border default false):
let dx1 = ADD(dx0, sx1)
let dy1 = ADD(dy0, sy1)

//debug_print(sy0, sy1, dy0, dy1)

// Off screen entirely
if (MAX(dx0, dy0) ≥ screenSize or
MIN(dx0 + sx1, dy0 + sy1) ≤ 0): return
Expand All @@ -699,16 +707,13 @@ def device_blit(sprite, corner default xy(0, 0), write_to_border default false):
if dy0 < 0: sy0 += -dy0; dy0 = 0
if dx1 ≥ screenSize: sx1 -= screenSize - dx1 + 1; dx1 = screenSize
if dy1 ≥ screenSize: sy1 -= screenSize - dy1 + 1; dy1 = screenSize

const s = xy(0, 0)
for dx0 ≤ dx < dx1:
s.x = sx0 + dx - dx0

// Flip the sprite y axis
s.y = sy1
s.y = sy0
const output_column = device.output[dx]
for dy0 ≤ dy < dy1:
--s.y
const src = get_sprite_pixel_color(sprite, s)
const dst = output_column[dy]
if src.a == 1:
Expand All @@ -717,6 +722,7 @@ def device_blit(sprite, corner default xy(0, 0), write_to_border default false):
else if src.a > 0:
// Blend
RGB_LERP(dst, src, src.a, dst)
++s.y



Expand All @@ -734,6 +740,31 @@ def device_set_all(color = #000):
for x < 8:
for y < 8:
device.output[x][y] = rgb(color)




def device_any_pressed():
for x < 8:
for y < 8:
if device.input[x][y].pressed:
return true
return false


/* Convert a device pixel center to the world space position
in the emulator visualization. Useful for aligning text
labels with visualizer buttons. */
def transform_ds_to_ws(pos):
// set_transform(∅, xy(1, -1))
const GRID_POS = ½ SCREEN_SIZE + xy(0, -8)

const PAD_SIZE = floor(xy(20, 20) * device.pad_aspect / max_component(device.pad_aspect))
const GUTTER_SIZE = max(device.gutter_scale * max_component(PAD_SIZE), if device.gutter_scale > 0 then 1 else 0)
const PAD_SPACING = floor(PAD_SIZE + GUTTER_SIZE)
const PAD_OFFSET = round(GRID_POS - 4 PAD_SPACING) + xy(2, 2)

return (round(pos) + 0.5) * PAD_SPACING + PAD_OFFSET


const device = _make_device()

0 comments on commit 1a8f694

Please sign in to comment.