diff --git a/README.md b/README.md index 4f5d2a81..06163ea2 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,9 @@ # micro:bit target for PXT -This target allow to program a [BBC micro:bit](https://microbit.org/) using +This target allows you to program a [BBC micro:bit](https://microbit.org/) using PXT ([Microsoft Programming Experience Toolkit](https://github.com/Microsoft/pxt)). -* [Try it live](@homeurl@) +* [Try it live](https://makecode.microbit.org) [![Build Status](https://travis-ci.org/Microsoft/pxt-microbit.svg?branch=master)](https://travis-ci.org/Microsoft/pxt-microbit) @@ -13,11 +13,11 @@ All issue tracking for this repo happens at https://github.com/Microsoft/pxt, se ## Local server -The local server allows to run the editor and the documentation from your computer. +The local server lets you to run the editor and serve the documentation from your own computer. ### Setup -The following commands are a 1-time setup after synching the repo on your machine. +The following commands perform a one-time setup after synching the repo on your machine. * See requirements for [pxt](https://github.com/Microsoft/pxt) * [clone this repo](https://help.github.com/articles/cloning-a-repository/) to your computer and go in the project folder @@ -32,6 +32,7 @@ npm install -g pxt * install the dependencies ``` npm install + ``` ### Running @@ -50,16 +51,16 @@ pxt serve -yt ## Updates -To update your PXT version and make sure you're running the latest tools, run (add ``sudo`` for Mac/Linux shells) +To update your PXT version and make sure you're running the latest tools, run (add ``sudo`` for Mac/Linux shells): ``` pxt update ``` -More instructions at https://github.com/Microsoft/pxt#running-a-target-from-localhost +More instructions are at https://github.com/Microsoft/pxt#running-a-target-from-localhost ## Testing -The build automatically runs the following: +The build also automatically runs the following checks: * make sure the built-in packages compile * `pxt run` in `libs/lang-test*` - this will run the test in command line runner; @@ -76,7 +77,7 @@ The `lang-test0` source comes from the `pxt-core` package. It's also tested with ## Repos -There are a number of repos that pxt-microbit depends on. The main ones are: +The pxt-microbit target depends on several other repos. The main ones are: - https://github.com/Microsoft/pxt, the PXT framework - https://github.com/lancaster-university/microbit, basic wrapper around the DAL - https://github.com/lancaster-university/microbit-dal @@ -85,8 +86,10 @@ There are a number of repos that pxt-microbit depends on. The main ones are: Current serviced versions of pxt-microbit: -| pxt-microbit | v0.12.* | release | uses pxt/v0 v.0.12.* -| pxt-microbit | v0.13.* | accessibility | uses pxt/v0 v.0.13.* (with accessibility) +| Target | Version | Type | PXT | +|---|---|---|---| +| pxt-microbit | v0.13.\* | accessibility | uses pxt/v0 v.0.13.\* (with accessibility) | +| pxt-microbit | v0.12.\* | release | uses pxt/v0 v.0.12.\* | ## Code of Conduct diff --git a/docs/courses.md b/docs/courses.md index 74c576e0..37eb80a5 100644 --- a/docs/courses.md +++ b/docs/courses.md @@ -1,10 +1,9 @@ # Courses -A collection of courses built for the @boardname@. +A collection of courses and tutorials built for the @boardname@. ## Courses - ```codecard [{ "name": "Intro to CS", @@ -17,15 +16,20 @@ A collection of courses built for the @boardname@. "url":"https://microbit.org/en/2017-03-07-javascript-block-resources/", "imageUrl": "https://microbit.org/assets/posts/2017-03-07-rock%20paper%20scissors.png" }, { - "name": "Kitronik Inventory Kit", - "description": "11 experiments based on the Kitronik Inventor Kit", - "url": "https://www.kitronik.co.uk/blog/inventors-kit-experiment-1-help", - "imageUrl": "https://www.kitronik.co.uk/wp/wp-content/uploads/2016/10/inventors-kit-experiment-1-further-help-870.jpg" -},{ "name": "SparkFun Videos", "description": "YouTube video tutorials produced by the SparkFun team!", "url": "https://youtu.be/kaNtg1HGXbY?list=PLBcrWxTa5CS0mWJrytvii8aG5KUqMXvSk", "imageUrl": "https://i.ytimg.com/vi/kaNtg1HGXbY/hqdefault.jpg" +}, { + "name": "Kitronik University", + "description": "Kits, projects and tutorials", + "url": "https://www.kitronik.co.uk/blog/bbc-microbit-kitronik-university/", + "imageUrl": "https://www.kitronik.co.uk/wp/wp-content/uploads/2015/03/2150_KIT01_banner-kitronikuniversity_002_v1.png" +}, { + "name": "Kitronik Inventory Kit", + "description": "11 experiments based on the Kitronik Inventor Kit", + "url": "https://www.kitronik.co.uk/blog/inventors-kit-experiment-1-help", + "imageUrl": "https://www.kitronik.co.uk/wp/wp-content/uploads/2016/10/inventors-kit-experiment-1-further-help-870.jpg" }, { "name": "micro:bit of Things", @@ -37,6 +41,4 @@ A collection of courses built for the @boardname@. ## See Also -[Intro to CS](/courses/csintro), -[Start Coding](http://microbit.org/en/2017-03-07-javascript-block-resources/), -[micro:bit of Things](https://sites.google.com/view/microbitofthings) \ No newline at end of file +[Intro to CS](/courses/csintro) diff --git a/docs/courses/csintro.md b/docs/courses/csintro.md index 731fd46b..f12c185a 100644 --- a/docs/courses/csintro.md +++ b/docs/courses/csintro.md @@ -13,13 +13,12 @@ This course takes approximately 14 weeks to complete, spending about 1 week on e The entire course is also available as a download. Choose any of these formats: -* [**HTML** - The entire course in a single HTML page that you can print to PDF or paper.](/--docs#book:/courses/csintro/SUMMARY) - -[![](/static/courses/csintro/icons/microsoft-onenote-24x24.png) **OneNote** - Intro to CS with MakeCode for micro:bit](https://1drv.ms/o/s!AqsgsTyHBmRBgQvFaUaeANNHbxpC) - -[![](/static/courses/csintro/icons/adobe-pdf-file-icon-24x24.png) **PDF** - Intro to CS with MakeCode for micro:bit](https://1drv.ms/b/s!AqsgsTyHBmRBgQ1Fjzm5y5wKG75M) - -[![](/static/courses/csintro/icons/apple-itunes-ibook-24x24.png) **iBooks** - Making with micro:bit](https://itunes.apple.com/us/book/making-with-micro-bit/id1255260221?mt=11) +||| +|-|-| +| [![](/static/courses/csintro/icons/html-24x24.png)](/--docs#book:/courses/csintro/SUMMARY) | [- **HTML** - The entire course in a single HTML page that you can print to PDF or paper](/--docs#book:/courses/csintro/SUMMARY) | +| [![](/static/courses/csintro/icons/microsoft-onenote-24x24.png)](https://1drv.ms/o/s!AqsgsTyHBmRBgQvFaUaeANNHbxpC) | [- **OneNote** - Intro to CS with MakeCode for micro:bit](https://1drv.ms/o/s!AqsgsTyHBmRBgQvFaUaeANNHbxpC) | +| [![](/static/courses/csintro/icons/adobe-pdf-file-icon-24x24.png)](https://1drv.ms/b/s!AqsgsTyHBmRBgQ1Fjzm5y5wKG75M) | [- **PDF** - Intro to CS with MakeCode for micro:bit](https://1drv.ms/b/s!AqsgsTyHBmRBgQ1Fjzm5y5wKG75M) | +| [![](/static/courses/csintro/icons/apple-itunes-ibook-24x24.png)](https://itunes.apple.com/us/book/making-with-micro-bit/id1255260221?mt=11) | [- **iBooks** - Making with micro:bit](https://itunes.apple.com/us/book/making-with-micro-bit/id1255260221?mt=11) | ### ~ ### Lesson structure diff --git a/docs/courses/csintro/algorithms/overview.md b/docs/courses/csintro/algorithms/overview.md index 4422a99b..630a88ca 100644 --- a/docs/courses/csintro/algorithms/overview.md +++ b/docs/courses/csintro/algorithms/overview.md @@ -1,4 +1,4 @@ -`# Introduction +# Introduction What is a micro:bit? The micro:bit was created in 2015 in the UK by the BBC to teach computer science to students. The BBC gave away a micro:bit to every Year 7 student in the UK. You can think of a micro:bit as a mini computer. diff --git a/docs/courses/csintro/references.md b/docs/courses/csintro/references.md index b05da385..361c349a 100644 --- a/docs/courses/csintro/references.md +++ b/docs/courses/csintro/references.md @@ -30,7 +30,7 @@ by **Colleen Graves** Inspiring Makers to Experiment, Create, and Learn -![Makerspace Projects Book Cover](/static/courses/csintro/references/makerspace-projects.jpg) +[![Makerspace Projects Book Cover](/static/courses/csintro/references/makerspace-projects.jpg)](https://colleengraves.org/bigmakerbook/) ## Code and Computational Thinking diff --git a/docs/projects.md b/docs/projects.md index 0110ebe3..8bd4cdcd 100644 --- a/docs/projects.md +++ b/docs/projects.md @@ -30,8 +30,7 @@ Fun games to build with your @boardname@. }, { "name": "Rock Paper Scissors", "url":"/projects/rock-paper-scissors", - "imageUrl":"/static/mb/projects/a4-motion.png", - "cardType": "tutorial" + "imageUrl":"/static/mb/projects/a4-motion.png" }, { "name": "Magic Button Trick", "url":"/projects/magic-button-trick", diff --git a/docs/projects/coin-flipper.md b/docs/projects/coin-flipper.md index cbd60e66..bf451a67 100644 --- a/docs/projects/coin-flipper.md +++ b/docs/projects/coin-flipper.md @@ -1,13 +1,5 @@ # Coin Flipper -## ~avatar avatar - -Are you trying to choose whether to play soccer or go to the movies -instead, or which toppings to have on your pizza? Build a coin -flipping machine with the @boardname@ to choose for you! - -## ~ - ## Step 1 Place a ``||input:on button pressed||`` block to run code diff --git a/docs/projects/soil-moisture/make.md b/docs/projects/soil-moisture/make.md index 79aafead..f801da5c 100644 --- a/docs/projects/soil-moisture/make.md +++ b/docs/projects/soil-moisture/make.md @@ -2,7 +2,7 @@ https://youtu.be/S8NppVT_paw -* Connect a nail to the ``GND`` pin with a croc clip and insert it in the soil +* Connect a nail to the ``3V`` pin with a croc clip and insert it in the soil * Connect the other nail to the ``P0`` pin with a croc clip and insert it in the soil That's it! @@ -11,4 +11,4 @@ That's it! Code -## ~ \ No newline at end of file +## ~ diff --git a/docs/reference/input.md b/docs/reference/input.md index c3bc2337..cc067255 100644 --- a/docs/reference/input.md +++ b/docs/reference/input.md @@ -21,6 +21,7 @@ input.lightLevel(); input.rotation(Rotation.Pitch); input.magneticForce(Dimension.X); input.runningTime(); +input.runningTimeMicros(); input.setAccelerometerRange(AcceleratorRange.OneG); ``` diff --git a/docs/reference/input/calibrate-compass.md b/docs/reference/input/calibrate-compass.md index 8e0b4b04..2a644ea5 100644 --- a/docs/reference/input/calibrate-compass.md +++ b/docs/reference/input/calibrate-compass.md @@ -8,7 +8,7 @@ input.calibrateCompass(); ## Calibration -The calibration will ask you to draw a circle by tilting the +The calibration will ask you to draw a circle or fill the LED screen by tilting the @boardname@. If you are calibrating or using the compass near metal, it might diff --git a/docs/reference/input/running-time-micros.md b/docs/reference/input/running-time-micros.md new file mode 100644 index 00000000..413cf4ef --- /dev/null +++ b/docs/reference/input/running-time-micros.md @@ -0,0 +1,17 @@ +# Running Time Micros + +Find how long it has been since the program started in micro-seconds. + +```sig +input.runningTimeMicros(); +``` + +## Returns + +* the [Number](/types/number) of microseconds since the program started. +(One second is 1000000 microseconds.) + +## See also + +[show number](/reference/basic/show-number), [pause](/reference/basic/pause) + diff --git a/docs/reference/input/running-time.md b/docs/reference/input/running-time.md index db209d16..099fb640 100644 --- a/docs/reference/input/running-time.md +++ b/docs/reference/input/running-time.md @@ -1,6 +1,6 @@ # Running Time -Find how long it has been since the program started. +Find how long it has been since the program started in milli-seconds. ```sig input.runningTime(); diff --git a/docs/static/courses/csintro/icons/html-24x24.png b/docs/static/courses/csintro/icons/html-24x24.png new file mode 100644 index 00000000..742b46da Binary files /dev/null and b/docs/static/courses/csintro/icons/html-24x24.png differ diff --git a/editor/extension.ts b/editor/extension.ts index c18dfcdb..266d86d4 100644 --- a/editor/extension.ts +++ b/editor/extension.ts @@ -31,89 +31,87 @@ namespace pxt.editor { class DAPWrapper { cortexM: DapJS.CortexM + packetIo: HF2.PacketIO; constructor(h: HF2.PacketIO) { - let pbuf = new U.PromiseBuffer() + this.packetIo = h; + let pbuf = new U.PromiseBuffer(); let sendMany = (cmds: Uint8Array[]) => { - return h.talksAsync(cmds.map(c => ({ cmd: 0, data: c }))) + return h.talksAsync(cmds.map(c => ({ cmd: 0, data: c }))); } if (!h.talksAsync) - sendMany = null + sendMany = null; let dev = new DapJS.DAP({ write: writeAsync, - close: closeAsync, + close: this.disconnectAsync, read: readAsync, sendMany: sendMany - }) - this.cortexM = new DapJS.CortexM(dev) + }); + this.cortexM = new DapJS.CortexM(dev); h.onData = buf => { - pbuf.push(buf) + pbuf.push(buf); } function writeAsync(data: ArrayBuffer) { - h.sendPacketAsync(new Uint8Array(data)) - return Promise.resolve() + h.sendPacketAsync(new Uint8Array(data)); + return Promise.resolve(); } function readAsync() { - return pbuf.shiftAsync() - } - - function closeAsync() { - return h.disconnectAsync() + return pbuf.shiftAsync(); } } reconnectAsync(first: boolean) { - return this.cortexM.init() + return this.cortexM.init(); + } + + disconnectAsync() { + return this.packetIo.disconnectAsync(); } } + let previousDapWrapper: DAPWrapper; function dapAsync() { - return pxt.HF2.mkPacketIOAsync() + return Promise.resolve() + .then(() => { + if (previousDapWrapper) { + return previousDapWrapper.disconnectAsync() + .finally(() => { + previousDapWrapper = null; + }); + } + return Promise.resolve(); + }) + .then(() => pxt.HF2.mkPacketIOAsync()) .then(h => { let w = new DAPWrapper(h) + previousDapWrapper = w; return w.reconnectAsync(true) .then(() => w) }) } - let noHID = false - - let initPromise: Promise function initAsync() { - if (initPromise) - return initPromise - let canHID = false if (U.isNodeJS) { canHID = true } else { const forceHexDownload = /forceHexDownload/i.test(window.location.href); - if (Cloud.isLocalHost() && Cloud.localToken && !forceHexDownload) + const isUwp = !!(window as any).Windows; + if (Cloud.isLocalHost() && Cloud.localToken && !forceHexDownload || isUwp) canHID = true } - if (noHID) - canHID = false - if (canHID) { - initPromise = dapAsync() - .catch(err => { - initPromise = null - noHID = true - return Promise.reject(err) - }) + return dapAsync(); } else { - noHID = true - initPromise = Promise.reject(new Error("no HID")) + return Promise.reject(new Error("no HID")) } - - return initPromise } function pageAlignBlocks(blocks: UF2.Block[], pageSize: number) { @@ -234,13 +232,8 @@ namespace pxt.editor { } startTime = 0 - - if (noHID) return saveHexAsync() - let wrap: DAPWrapper - log("init") - let logV = (msg: string) => { } //let logV = log @@ -339,11 +332,7 @@ namespace pxt.editor { }) }) .catch(e => { - // if we failed to initalize, retry - if (noHID) - return saveHexAsync() - else - return Promise.reject(e) + return saveHexAsync(); }) } @@ -371,16 +360,16 @@ namespace pxt.editor { }, name: data.meta.name }) }, { - id: "td", - canImport: data => data.meta.cloudId == "microbit.co.uk" && data.meta.editor == "touchdevelop", - importAsync: (project, data) => - project.createProjectAsync({ - filesOverride: { "main.blocks": "", "main.ts": " " }, - name: data.meta.name - }) - .then(() => project.convertTouchDevelopToTypeScriptAsync(data.source)) - .then(text => project.overrideTypescriptFile(text)) - }] + id: "td", + canImport: data => data.meta.cloudId == "microbit.co.uk" && data.meta.editor == "touchdevelop", + importAsync: (project, data) => + project.createProjectAsync({ + filesOverride: { "main.blocks": "", "main.ts": " " }, + name: data.meta.name + }) + .then(() => project.convertTouchDevelopToTypeScriptAsync(data.source)) + .then(text => project.overrideTypescriptFile(text)) + }] }; pxt.commands.deployCoreAsync = deployCoreAsync; return Promise.resolve(res); diff --git a/libs/core/_locales/core-jsdoc-strings.json b/libs/core/_locales/core-jsdoc-strings.json index c1adf164..4a990d14 100644 --- a/libs/core/_locales/core-jsdoc-strings.json +++ b/libs/core/_locales/core-jsdoc-strings.json @@ -1,4 +1,8 @@ { + "AcceleratorRange.EightG": "The accelerator measures forces up to 8 gravity", + "AcceleratorRange.FourG": "The accelerator measures forces up to 4 gravity", + "AcceleratorRange.OneG": "The accelerator measures forces up to 1 gravity", + "AcceleratorRange.TwoG": "The accelerator measures forces up to 2 gravity", "Array": "Add, remove, and replace items in lists.\n\nAdd, remove, and replace items in lists.", "Array.filter": "Return the elements of an array that meet the condition specified in a callback function.", "Array.filter|param|callbackfn": "A function that accepts up to two arguments. The filter method calls the callbackfn function one time for each element in the array.", @@ -35,6 +39,57 @@ "Array.splice|param|start": "The zero-based location in the array from which to start removing elements. eg: 0", "Array.unshift": "Add one element to the beginning of an array and return the new length of the array.", "Array.unshift|param|value": "to insert at the start of the Array.", + "Boolean.toString": "Returns a string representation of an object.", + "Buffer.fill": "Fill (a fragment) of the buffer with given value.", + "Buffer.getNumber": "Read a number in specified format from the buffer.", + "Buffer.length": "Returns the length of a Buffer object.", + "Buffer.rotate": "Rotate buffer left in place.", + "Buffer.rotate|param|length": "number of elements in buffer. If negative, length is set as the buffer length minus start. eg: -1", + "Buffer.rotate|param|offset": "number of bytes to shift; use negative value to shift right", + "Buffer.rotate|param|start": "start offset in buffer. Default is 0.", + "Buffer.setNumber": "Write a number in specified format in the buffer.", + "Buffer.shift": "Shift buffer left in place, with zero padding.", + "Buffer.shift|param|length": "number of elements in buffer. If negative, length is set as the buffer length minus start. eg: -1", + "Buffer.shift|param|offset": "number of bytes to shift; use negative value to shift right", + "Buffer.shift|param|start": "start offset in buffer. Default is 0.", + "Buffer.slice": "Return a copy of a fragment of a buffer.", + "Buffer.write": "Write contents of `src` at `dstOffset` in current buffer.", + "EventCreationMode": "How to create the event.", + "EventCreationMode.CreateAndFire": "MicroBitEvent is initialised, and its event handlers are immediately fired (not suitable for use in interrupts!).", + "EventCreationMode.CreateOnly": "MicroBitEvent is initialised, and no further processing takes place.", + "Gesture.EightG": "Raised when a 8G shock is detected", + "Gesture.FreeFall": "Raised when the board is falling!", + "Gesture.LogoDown": "Raised when the logo is downward and the screen is vertical", + "Gesture.LogoUp": "Raised when the logo is upward and the screen is vertical", + "Gesture.ScreenDown": "Raised when the screen is pointing up and the board is horizontal", + "Gesture.ScreenUp": "Raised when the screen is pointing down and the board is horizontal", + "Gesture.Shake": "Raised when shaken", + "Gesture.SixG": "Raised when a 6G shock is detected", + "Gesture.ThreeG": "Raised when a 3G shock is detected", + "Gesture.TiltLeft": "Raised when the screen is pointing left", + "Gesture.TiltRight": "Raised when the screen is pointing right", + "Image.clear": "Sets all pixels off.", + "Image.height": "Gets the height in rows (always 5)", + "Image.pixel": "Get the pixel state at position ``(x,y)``", + "Image.pixelBrightness": "Gets the pixel brightness ([0..255]) at a given position", + "Image.pixel|param|x": "TODO", + "Image.pixel|param|y": "TODO", + "Image.plotFrame": "Draws the ``index``-th frame of the image on the screen.", + "Image.plotFrame|param|xOffset": "column index to start displaying the image", + "Image.plotImage": "Plots the image at a given column to the screen", + "Image.scrollImage": "Scrolls an image .", + "Image.scrollImage|param|frameOffset": "x offset moved on each animation step, eg: 1, 2, 5", + "Image.scrollImage|param|interval": "time between each animation step in milli seconds, eg: 200", + "Image.setPixel": "Set a pixel state at position ``(x,y)``", + "Image.setPixelBrightness": "Sets a specific pixel brightness at a given position", + "Image.setPixel|param|value": "TODO", + "Image.setPixel|param|x": "TODO", + "Image.setPixel|param|y": "TODO", + "Image.showFrame": "Shows a particular frame of the image strip.", + "Image.showFrame|param|frame": "TODO", + "Image.showImage": "Shows an frame from the image at offset ``x offset``.", + "Image.showImage|param|xOffset": "column index to start displaying the image", + "Image.width": "Gets the width in columns", "Math": "More complex operations with numbers.", "Math.abs": "Returns the absolute value of a number (the value without regard to whether it is positive or negative).\nFor example, the absolute value of -5 is the same as the absolute value of 5.", "Math.abs|param|x": "A numeric expression for which the absolute value is needed.", @@ -50,6 +105,7 @@ "Math.sign|param|x": "The numeric expression to test", "Math.sqrt": "Return the square root of a number.", "Math.sqrt|param|x": "A numeric expression.", + "Number.toString": "Return a string representation of a number.", "String": "Combine, split, and search text strings.\n\nCombine, split, and search text strings.", "String.charAt": "Return the character at the specified index.", "String.charAt|param|index": "The zero-based index of the desired character, eg: 0", @@ -109,6 +165,58 @@ "control.waitMicros": "Blocks the current fiber for the given microseconds", "control.waitMicros|param|micros": "number of micro-seconds to wait. eg: 4", "game": "A single-LED sprite game engine", + "game.LedSprite": "A game sprite rendered as a single LED", + "game.LedSprite.blink": "Reports the ``blink`` duration of a sprite", + "game.LedSprite.brightness": "Reports the ``brightness` of a sprite on the LED screen", + "game.LedSprite.change": "Changes a property of the sprite", + "game.LedSprite.changeBlinkBy": "Changes the ``blink`` duration by the given amount of millisecons", + "game.LedSprite.changeBlinkBy|param|ms": "TODO", + "game.LedSprite.changeBrightnessBy": "Changes the ``y`` position by the given amount", + "game.LedSprite.changeBrightnessBy|param|value": "the value to change brightness", + "game.LedSprite.changeDirectionBy": "Changes the ``direction`` position by the given amount by turning right", + "game.LedSprite.changeDirectionBy|param|angle": "TODO", + "game.LedSprite.changeXBy": "Changes the ``x`` position by the given amount", + "game.LedSprite.changeXBy|param|x": "TODO", + "game.LedSprite.changeYBy": "Changes the ``y`` position by the given amount", + "game.LedSprite.changeYBy|param|y": "TODO", + "game.LedSprite.change|param|property": "the name of the property to change", + "game.LedSprite.change|param|value": "amount of change, eg: 1", + "game.LedSprite.delete": "Deletes the sprite from the game engine. The sprite will no longer appear on the screen or interact with other sprites.", + "game.LedSprite.direction": "Reports the current direction of a sprite", + "game.LedSprite.get": "Gets a property of the sprite", + "game.LedSprite.get|param|property": "the name of the property to change", + "game.LedSprite.goTo": "Go to this position on the screen", + "game.LedSprite.goTo|param|x": "TODO", + "game.LedSprite.goTo|param|y": "TODO", + "game.LedSprite.ifOnEdgeBounce": "If touching the edge of the stage and facing towards it, then turn away.", + "game.LedSprite.isTouching": "Reports true if sprite has the same position as specified sprite", + "game.LedSprite.isTouchingEdge": "Reports true if sprite is touching an edge", + "game.LedSprite.isTouching|param|other": "TODO", + "game.LedSprite.move": "Move a certain number of LEDs in the current direction", + "game.LedSprite.move|param|leds": "number of leds to move, eg: 1, -1", + "game.LedSprite.off": "Turns off the sprite (on by default)", + "game.LedSprite.on": "Turns on the sprite (on by default)", + "game.LedSprite.set": "Sets a property of the sprite", + "game.LedSprite.setBlink": "Sets the blink duration interval in millisecond.", + "game.LedSprite.setBlink|param|ms": "TODO", + "game.LedSprite.setBrightness": "Set the ``brightness`` of a sprite", + "game.LedSprite.setBrightness|param|brightness": "the brightness from 0 (off) to 255 (on), eg: 255.", + "game.LedSprite.setDirection": "Set the direction of the current sprite, rounded to the nearest multiple of 45", + "game.LedSprite.setDirection|param|degrees": "TODO", + "game.LedSprite.setX": "Set the ``x`` position of a sprite", + "game.LedSprite.setX|param|x": "TODO", + "game.LedSprite.setY": "Set the ``y`` position of a sprite", + "game.LedSprite.setY|param|y": "TODO", + "game.LedSprite.set|param|property": "the name of the property to change", + "game.LedSprite.turn": "Turn the sprite", + "game.LedSprite.turnLeft": "Turn to the left (counter-clockwise)", + "game.LedSprite.turnLeft|param|degrees": "TODO", + "game.LedSprite.turnRight": "Turn to the right (clockwise)", + "game.LedSprite.turnRight|param|degrees": "TODO", + "game.LedSprite.turn|param|degrees": "angle in degrees to turn, eg: 45, 90, 180, 135", + "game.LedSprite.turn|param|direction": "left or right", + "game.LedSprite.x": "Reports the ``x`` position of a sprite on the LED screen", + "game.LedSprite.y": "Reports the ``y`` position of a sprite on the LED screen", "game.addLife": "Adds life points to the current life", "game.addLife|param|lives": "TODO", "game.addScore": "Adds points to the current score and shows an animation", @@ -179,6 +287,7 @@ "input.rotation": "The pitch or roll of the device, rotation along the ``x-axis`` or ``y-axis``, in degrees.", "input.rotation|param|kind": "TODO", "input.runningTime": "Gets the number of milliseconds elapsed since power on.", + "input.runningTimeMicros": "Gets the number of microseconds elapsed since power on.", "input.setAccelerometerRange": "Sets the accelerometer sample range in gravities.", "input.setAccelerometerRange|param|range": "a value describe the maximum strengh of acceleration measured", "input.temperature": "Gets the temperature in Celsius degrees (°C).", @@ -239,6 +348,7 @@ "music.setTempo": "Sets the tempo to the specified amount", "music.setTempo|param|bpm": "The new tempo in beats per minute, eg: 120", "music.tempo": "Returns the tempo in beats per minute. Tempo is the speed (bpm = beats per minute) at which notes play. The larger the tempo value, the faster the notes will play.", + "parseInt": "Convert A string to an integer.", "pins": "Control currents in Pins for analog/digital signals, servos, i2c, ...", "pins.analogPitch": "Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin.", "pins.analogPitch|param|frequency": "frequency to modulate in Hz.", diff --git a/libs/core/_locales/core-strings.json b/libs/core/_locales/core-strings.json index fb3f9dfe..252a1b59 100644 --- a/libs/core/_locales/core-strings.json +++ b/libs/core/_locales/core-strings.json @@ -136,6 +136,8 @@ "IconNames.Triangle|block": "triangle", "IconNames.Umbrella|block": "umbrella", "IconNames.Yes|block": "yes", + "Image.scrollImage|block": "scroll image %sprite|with offset %frameoffset|and interval (ms) %delay", + "Image.showImage|block": "show image %sprite|at offset %offset", "LedSpriteProperty.Blink|block": "blink", "LedSpriteProperty.Brightness|block": "brightness", "LedSpriteProperty.Direction|block": "direction", @@ -244,6 +246,15 @@ "control.reset|block": "reset", "control.waitMicros|block": "wait (µs)%micros", "control|block": "control", + "game.LedSprite.change|block": "%sprite|change %property|by %value", + "game.LedSprite.delete|block": "delete %this", + "game.LedSprite.get|block": "%sprite|%property", + "game.LedSprite.ifOnEdgeBounce|block": "%sprite|if on edge, bounce", + "game.LedSprite.isTouchingEdge|block": "%sprite|touching edge?", + "game.LedSprite.isTouching|block": "%sprite|touching %other|?", + "game.LedSprite.move|block": "%sprite|move by %leds", + "game.LedSprite.set|block": "%sprite|set %property|to %value", + "game.LedSprite.turn|block": "%sprite|turn %direction|by (°) %degrees", "game.addScore|block": "change score by|%points", "game.createSprite|block": "create sprite at|x: %x|y: %y", "game.gameOver|block": "game over", @@ -253,8 +264,11 @@ "game.setScore|block": "set score %points", "game.startCountdown|block": "start countdown|(ms) %duration", "game|block": "game", + "images.arrowImage|block": "arrow image %i=device_arrow", + "images.arrowNumber|block": "%arrow", "images.createBigImage|block": "create big image", "images.createImage|block": "create image", + "images.iconImage|block": "icon image %i", "images|block": "images", "input.acceleration|block": "acceleration (mg)|%NAME", "input.buttonIsPressed|block": "button|%NAME|is pressed", @@ -268,6 +282,7 @@ "input.onPinReleased|block": "on pin %NAME|released", "input.pinIsPressed|block": "pin %NAME|is pressed", "input.rotation|block": "rotation (°)|%NAME", + "input.runningTimeMicros|block": "running time (micros)", "input.runningTime|block": "running time (ms)", "input.setAccelerometerRange|block": "set accelerometer|range %range", "input.temperature|block": "temperature (°C)", @@ -295,6 +310,7 @@ "music.setTempo|block": "set tempo to (bpm)|%value", "music.tempo|block": "tempo (bpm)", "music|block": "music", + "parseInt|block": "parse to integer %text", "pins.analogPitch|block": "analog pitch %frequency|for (ms) %ms", "pins.analogReadPin|block": "analog read|pin %name", "pins.analogSetPeriod|block": "analog set period|pin %pin|to (µs)%micros", @@ -333,13 +349,19 @@ "{id:category}Array": "Array", "{id:category}Arrays": "Arrays", "{id:category}Basic": "Basic", + "{id:category}Boolean": "Boolean", + "{id:category}Buffer": "Buffer", + "{id:category}Console": "Console", "{id:category}Control": "Control", "{id:category}Game": "Game", + "{id:category}Helpers": "Helpers", + "{id:category}Image": "Image", "{id:category}Images": "Images", "{id:category}Input": "Input", "{id:category}Led": "Led", "{id:category}Math": "Math", "{id:category}Music": "Music", + "{id:category}Number": "Number", "{id:category}Pins": "Pins", "{id:category}Serial": "Serial", "{id:category}String": "String", diff --git a/libs/core/enums.d.ts b/libs/core/enums.d.ts index 116ffdda..9a7689c1 100644 --- a/libs/core/enums.d.ts +++ b/libs/core/enums.d.ts @@ -5,7 +5,7 @@ declare namespace basic { } - declare enum Button { + declare const enum Button { A = 1, // MICROBIT_ID_BUTTON_A B = 2, // MICROBIT_ID_BUTTON_B //% block="A+B" @@ -13,7 +13,7 @@ declare namespace basic { } - declare enum Dimension { + declare const enum Dimension { //% block=x X = 0, //% block=y @@ -25,7 +25,7 @@ declare namespace basic { } - declare enum Rotation { + declare const enum Rotation { //% block=pitch Pitch = 0, //% block=roll @@ -33,14 +33,14 @@ declare namespace basic { } - declare enum TouchPin { + declare const enum TouchPin { P0 = 7, // MICROBIT_ID_IO_P0 P1 = 8, // MICROBIT_ID_IO_P1 P2 = 9, // MICROBIT_ID_IO_P2 } - declare enum AcceleratorRange { + declare const enum AcceleratorRange { /** * The accelerator measures forces up to 1 gravity */ @@ -64,7 +64,7 @@ declare namespace basic { } - declare enum Gesture { + declare const enum Gesture { /** * Raised when shaken */ @@ -123,7 +123,7 @@ declare namespace basic { } - declare enum MesDpadButtonInfo { + declare const enum MesDpadButtonInfo { //% block="A down" ADown = 1, // MES_DPAD_BUTTON_A_DOWN //% block="A up" @@ -165,7 +165,7 @@ declare namespace input { * How to create the event. */ - declare enum EventCreationMode { + declare const enum EventCreationMode { /** * MicroBitEvent is initialised, and no further processing takes place. */ @@ -177,7 +177,7 @@ declare namespace input { } - declare enum EventBusSource { + declare const enum EventBusSource { //% blockIdentity="control.eventSourceId" MICROBIT_ID_BUTTON_A = 1, // MICROBIT_ID_BUTTON_A //% blockIdentity="control.eventSourceId" @@ -239,7 +239,7 @@ declare namespace input { } - declare enum EventBusValue { + declare const enum EventBusValue { //% blockIdentity="control.eventValueId" MICROBIT_EVT_ANY = 0, // MICROBIT_EVT_ANY //% blockIdentity="control.eventValueId" @@ -367,7 +367,7 @@ declare namespace control { } - declare enum DisplayMode { + declare const enum DisplayMode { //% block="black and white" BackAndWhite = 0, // DISPLAY_MODE_BLACK_AND_WHITE //% block="greyscale" @@ -378,7 +378,7 @@ declare namespace led { } - declare enum DigitalPin { + declare const enum DigitalPin { P0 = 7, // MICROBIT_ID_IO_P0 P1 = 8, // MICROBIT_ID_IO_P1 P2 = 9, // MICROBIT_ID_IO_P2 @@ -401,7 +401,7 @@ declare namespace led { } - declare enum AnalogPin { + declare const enum AnalogPin { P0 = 7, // MICROBIT_ID_IO_P0 P1 = 8, // MICROBIT_ID_IO_P1 P2 = 9, // MICROBIT_ID_IO_P2 @@ -437,7 +437,7 @@ declare namespace led { } - declare enum PulseValue { + declare const enum PulseValue { //% block=high High = 4, // MICROBIT_PIN_EVT_PULSE_HI //% block=low @@ -445,7 +445,7 @@ declare namespace led { } - declare enum PinPullMode { + declare const enum PinPullMode { //% block="down" PullDown = 0, //% block="up" @@ -455,7 +455,7 @@ declare namespace led { } - declare enum PinEventType { + declare const enum PinEventType { //% block="edge" Edge = 1, // MICROBIT_PIN_EVENT_ON_EDGE //% block="pulse" @@ -467,7 +467,7 @@ declare namespace led { } - declare enum SerialPin { + declare const enum SerialPin { P0 = 7, // MICROBIT_ID_IO_P0 P1 = 8, // MICROBIT_ID_IO_P1 P2 = 9, // MICROBIT_ID_IO_P2 @@ -480,7 +480,7 @@ declare namespace led { } - declare enum BaudRate { + declare const enum BaudRate { //% block=115200 BaudRate115200 = 115200, //% block=57600 @@ -508,7 +508,7 @@ declare namespace led { } - declare enum Delimiters { + declare const enum Delimiters { //% block="new line" NewLine = 1, //% block="," @@ -526,7 +526,7 @@ declare namespace serial { } - declare enum NumberFormat { + declare const enum NumberFormat { Int8LE = 1, UInt8LE = 2, Int16LE = 3, diff --git a/libs/core/game.ts b/libs/core/game.ts index 4a912459..2acdef58 100644 --- a/libs/core/game.ts +++ b/libs/core/game.ts @@ -35,6 +35,7 @@ namespace game { let _img: Image; let _sprites: LedSprite[]; let _paused: boolean = false; + let _backgroundAnimation = false; // indicates if an auxiliary animation (and fiber) is already running /** * Creates a new LED sprite pointing to the right. @@ -68,7 +69,8 @@ namespace game { //% parts="ledmatrix" export function addScore(points: number): void { setScore(_score + points); - if (!_paused) + if (!_paused && !_backgroundAnimation) { + _backgroundAnimation = true; control.inBackground(() => { led.stopAnimation(); basic.showAnimation(`0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 @@ -76,7 +78,9 @@ namespace game { 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 1 1 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 0 1 0 0 0 0 0`, 20); + _backgroundAnimation = false; }); + } } /** @@ -116,7 +120,6 @@ namespace game { unplugEvents(); led.stopAnimation(); led.setBrightness(255); - led.setDisplayMode(DisplayMode.BackAndWhite); while (true) { for (let i = 0; i < 8; i++) { basic.clearScreen(); @@ -318,6 +321,10 @@ namespace game { }); } + /** + * A game sprite rendered as a single LED + */ + //% export class LedSprite { private _x: number; private _y: number; @@ -731,22 +738,22 @@ namespace game { } function init(): void { - if (_img == null) { - _img = images.createImage( - `0 0 0 0 0 + if (_img) return; + const img = images.createImage( +`0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0`); - _sprites = ([]); - basic.forever(() => { - basic.pause(30); - plot(); - if (game.isGameOver()) { - basic.pause(600); - } - }); - } + _sprites = ([]); + basic.forever(() => { + basic.pause(30); + plot(); + if (game.isGameOver()) { + basic.pause(600); + } + }); + _img = img; } /** @@ -754,19 +761,23 @@ namespace game { */ //% parts="ledmatrix" function plot(): void { - if (game.isGameOver() || game.isPaused() || !_img) { + if (game.isGameOver() || game.isPaused() || !_img || _backgroundAnimation) { return; } // ensure greyscale mode - if (led.displayMode() != DisplayMode.Greyscale) + const dm = led.displayMode(); + if (dm != DisplayMode.Greyscale) led.setDisplayMode(DisplayMode.Greyscale); // render sprites - let now = input.runningTime(); + const now = input.runningTime(); _img.clear(); for (let i = 0; i < _sprites.length; i++) { _sprites[i]._plot(now); } _img.plotImage(0); + // restore previous display mode + if (dm != DisplayMode.Greyscale) + led.setDisplayMode(dm); } /** diff --git a/libs/core/icons.ts b/libs/core/icons.ts index ee64d25c..bc37a407 100644 --- a/libs/core/icons.ts +++ b/libs/core/icons.ts @@ -274,6 +274,9 @@ namespace images { //% weight=50 blockGap=8 //% help=images/icon-image //% blockId=builtin_image block="icon image %i" + //% i.fieldEditor="gridpicker" + //% i.fieldOptions.width="400" i.fieldOptions.columns="5" + //% i.fieldOptions.itemColour="black" i.fieldOptions.tooltips="true" export function iconImage(i: IconNames): Image { switch (i) { case IconNames.Heart: return images.createImage(` diff --git a/libs/core/input.cpp b/libs/core/input.cpp index d6932473..63dbccf9 100644 --- a/libs/core/input.cpp +++ b/libs/core/input.cpp @@ -339,13 +339,23 @@ namespace input { /** * Gets the number of milliseconds elapsed since power on. */ - //% help=input/running-time weight=50 + //% help=input/running-time weight=50 blockGap=8 //% blockId=device_get_running_time block="running time (ms)" //% advanced=true int runningTime() { return system_timer_current_time(); } + /** + * Gets the number of microseconds elapsed since power on. + */ + //% help=input/running-time-micros weight=49 + //% blockId=device_get_running_time_micros block="running time (micros)" + //% advanced=true + int runningTimeMicros() { + return system_timer_current_time_us(); + } + /** * Obsolete, compass calibration is automatic. */ diff --git a/libs/core/pins.cpp b/libs/core/pins.cpp index 48d18960..1ada7a94 100644 --- a/libs/core/pins.cpp +++ b/libs/core/pins.cpp @@ -429,6 +429,12 @@ namespace pins { */ //% help=pins/spi-pins weight=2 advanced=true //% blockId=spi_pins block="spi set pins|MOSI %mosi|MISO %miso|SCK %sck" + //% mosi.fieldEditor="gridpicker" mosi.fieldOptions.columns=4 + //% mosi.fieldOptions.tooltips="false" mosi.fieldOptions.width="300" + //% miso.fieldEditor="gridpicker" miso.fieldOptions.columns=4 + //% miso.fieldOptions.tooltips="false" miso.fieldOptions.width="300" + //% sck.fieldEditor="gridpicker" sck.fieldOptions.columns=4 + //% sck.fieldOptions.tooltips="false" sck.fieldOptions.width="300" void spiPins(DigitalPin mosi, DigitalPin miso, DigitalPin sck) { if (NULL != spi) { delete spi; diff --git a/libs/core/pxt.cpp b/libs/core/pxt.cpp index f297e90c..bdea3518 100644 --- a/libs/core/pxt.cpp +++ b/libs/core/pxt.cpp @@ -394,10 +394,7 @@ namespace pxt { uint32_t RefCollection::removeAt(int i) { - if (isRef()) - { - decr(head.get(i)); - } + // no decr() - we return the result return head.remove(i); } @@ -464,7 +461,8 @@ namespace pxt { { int idx = indexOf(x, 0); if (idx >= 0) { - removeAt(idx); + uint32_t elt = removeAt(idx); + if (isRef()) decr(elt); return 1; } return 0; diff --git a/libs/core/pxt.h b/libs/core/pxt.h index 95224382..39482b28 100644 --- a/libs/core/pxt.h +++ b/libs/core/pxt.h @@ -160,6 +160,7 @@ namespace pxt { inline void unref() { //printf("DECR "); this->print(); + check(refcnt > 0, ERR_REF_DELETED); refcnt -= 2; if (refcnt == 0) { destroy(); diff --git a/libs/core/serial.cpp b/libs/core/serial.cpp index 1b25242f..05da5f2c 100644 --- a/libs/core/serial.cpp +++ b/libs/core/serial.cpp @@ -148,6 +148,10 @@ namespace serial { //% help=serial/redirect-to //% blockId=serial_redirect block="serial|redirect to|TX %tx|RX %rx|at baud rate %rate" //% blockExternalInputs=1 + //% tx.fieldEditor="gridpicker" tx.fieldOptions.columns=3 + //% tx.fieldOptions.tooltips="false" + //% rx.fieldEditor="gridpicker" rx.fieldOptions.columns=3 + //% rx.fieldOptions.tooltips="false" void redirect(SerialPin tx, SerialPin rx, BaudRate rate) { MicroBitPin* txp = getPin(tx); if (!tx) return; MicroBitPin* rxp = getPin(rx); if (!rx) return; diff --git a/libs/core/shims.d.ts b/libs/core/shims.d.ts index f5fae3e3..9fc25673 100644 --- a/libs/core/shims.d.ts +++ b/libs/core/shims.d.ts @@ -332,11 +332,19 @@ declare namespace input { /** * Gets the number of milliseconds elapsed since power on. */ - //% help=input/running-time weight=50 + //% help=input/running-time weight=50 blockGap=8 //% blockId=device_get_running_time block="running time (ms)" //% advanced=true shim=input::runningTime function runningTime(): number; + /** + * Gets the number of microseconds elapsed since power on. + */ + //% help=input/running-time-micros weight=49 + //% blockId=device_get_running_time_micros block="running time (micros)" + //% advanced=true shim=input::runningTimeMicros + function runningTimeMicros(): number; + /** * Obsolete, compass calibration is automatic. */ @@ -747,7 +755,13 @@ declare namespace pins { * */ //% help=pins/spi-pins weight=2 advanced=true - //% blockId=spi_pins block="spi set pins|MOSI %mosi|MISO %miso|SCK %sck" shim=pins::spiPins + //% blockId=spi_pins block="spi set pins|MOSI %mosi|MISO %miso|SCK %sck" + //% mosi.fieldEditor="gridpicker" mosi.fieldOptions.columns=4 + //% mosi.fieldOptions.tooltips="false" mosi.fieldOptions.width="300" + //% miso.fieldEditor="gridpicker" miso.fieldOptions.columns=4 + //% miso.fieldOptions.tooltips="false" miso.fieldOptions.width="300" + //% sck.fieldEditor="gridpicker" sck.fieldOptions.columns=4 + //% sck.fieldOptions.tooltips="false" sck.fieldOptions.width="300" shim=pins::spiPins function spiPins(mosi: DigitalPin, miso: DigitalPin, sck: DigitalPin): void; } @@ -813,7 +827,11 @@ declare namespace serial { //% weight=10 //% help=serial/redirect-to //% blockId=serial_redirect block="serial|redirect to|TX %tx|RX %rx|at baud rate %rate" - //% blockExternalInputs=1 shim=serial::redirect + //% blockExternalInputs=1 + //% tx.fieldEditor="gridpicker" tx.fieldOptions.columns=3 + //% tx.fieldOptions.tooltips="false" + //% rx.fieldEditor="gridpicker" rx.fieldOptions.columns=3 + //% rx.fieldOptions.tooltips="false" shim=serial::redirect function redirect(tx: SerialPin, rx: SerialPin, rate: BaudRate): void; } diff --git a/libs/devices/enums.d.ts b/libs/devices/enums.d.ts index 2a3fe98c..9eeabbe1 100644 --- a/libs/devices/enums.d.ts +++ b/libs/devices/enums.d.ts @@ -1,7 +1,7 @@ // Auto-generated. Do not edit. - declare enum MesCameraEvent { + declare const enum MesCameraEvent { //% block="take photo" TakePhoto = 3, // MES_CAMERA_EVT_TAKE_PHOTO //% block="start video capture" @@ -21,7 +21,7 @@ } - declare enum MesAlertEvent { + declare const enum MesAlertEvent { //% block="display toast" DisplayToast = 1, // MES_ALERT_EVT_DISPLAY_TOAST //% block="vibrate" @@ -47,7 +47,7 @@ } - declare enum MesDeviceInfo { + declare const enum MesDeviceInfo { //% block="incoming call" IncomingCall = 7, // MES_DEVICE_INCOMING_CALL //% block="incoming message" @@ -65,7 +65,7 @@ } - declare enum MesRemoteControlEvent { + declare const enum MesRemoteControlEvent { //% block="play" play = 1, // MES_REMOTE_CONTROL_EVT_PLAY //% block="pause" diff --git a/libs/radio/_locales/radio-jsdoc-strings.json b/libs/radio/_locales/radio-jsdoc-strings.json index 34b37e9e..9f9068f7 100644 --- a/libs/radio/_locales/radio-jsdoc-strings.json +++ b/libs/radio/_locales/radio-jsdoc-strings.json @@ -1,5 +1,10 @@ { "radio": "Communicate data using radio packets", + "radio.Packet.receivedNumber": "The number payload if a number was sent in this packet (via ``sendNumber()`` or ``sendValue()``)\nor 0 if this packet did not contain a number.", + "radio.Packet.receivedString": "The string payload if a string was sent in this packet (via ``sendString()`` or ``sendValue()``)\nor the empty string if this packet did not contain a string.", + "radio.Packet.serial": "The serial number of the sender of the packet or 0 if the sender did not sent their serial number.", + "radio.Packet.signal": "The received signal strength indicator (RSSI) of the packet.", + "radio.Packet.time": "The system time of the sender of the packet at the time the packet was sent.", "radio.onDataPacketReceived": "Registers code to run when the radio receives a packet. Also takes the\nreceived packet from the radio queue.", "radio.onDataReceived": "Registers code to run when a packet is received over radio.", "radio.receiveNumber": "Reads the next packet from the radio queue and returns the packet's number\npayload or 0 if the packet did not contain a number.", diff --git a/package.json b/package.json index 86a62bc2..b2d9f7b3 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "pxt-microbit", - "version": "0.13.22", + "version": "0.13.30", "description": "micro:bit target for Microsoft MakeCode (PXT)", "keywords": [ "JavaScript", @@ -38,6 +38,6 @@ "semantic-ui-less": "^2.2.4" }, "dependencies": { - "pxt-core": "0.13.30" + "pxt-core": "0.14.5" } } diff --git a/pxtarget.json b/pxtarget.json index 4aae702e..54e39fa6 100644 --- a/pxtarget.json +++ b/pxtarget.json @@ -70,6 +70,14 @@ "device_print_message.message": "text" } } + ], + "hidSelectors": [ + { + "usagePage": "0xFF00", + "usageId": "0x0001", + "vid": "0x0d28", + "pid": "0x0204" + } ] }, "runtime": { diff --git a/pxtwapp/.gitignore b/pxtwapp/.gitignore new file mode 100644 index 00000000..7ade57d0 --- /dev/null +++ b/pxtwapp/.gitignore @@ -0,0 +1,295 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +bld/ +[Bb]in/ +[Oo]bj/ +[Ll]og/ + +# Visual Studio 2015 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ +**/Properties/launchSettings.json + +*_i.c +*_p.c +*_i.h +*.ilk +*.meta +*.obj +*.pch +*.pdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# JustCode is a .NET coding add-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# TODO: Comment the next line if you want to checkin your web deploy settings +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# The packages folder can be ignored because of Package Restore +**/packages/* +# except build/, which is used as an MSBuild target. +!**/packages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/packages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Typescript v1 declaration files +typings/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# JetBrains Rider +.idea/ +*.sln.iml + +# CodeRush +.cr/ + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs \ No newline at end of file diff --git a/pxtwapp/pxtwapp.sln b/pxtwapp/pxtwapp.sln new file mode 100644 index 00000000..a4f95a62 --- /dev/null +++ b/pxtwapp/pxtwapp.sln @@ -0,0 +1,48 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.26430.15 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{262852C6-CD72-467D-83FE-5EEB1973A190}") = "pxtwapp", "pxtwapp\pxtwapp.jsproj", "{34E8CDE2-3991-414E-BB19-BFF4BD5E031A}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Debug|ARM = Debug|ARM + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|Any CPU = Release|Any CPU + Release|ARM = Release|ARM + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|Any CPU.Deploy.0 = Debug|Any CPU + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|ARM.ActiveCfg = Debug|ARM + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|ARM.Build.0 = Debug|ARM + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|ARM.Deploy.0 = Debug|ARM + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x64.ActiveCfg = Debug|x64 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x64.Build.0 = Debug|x64 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x64.Deploy.0 = Debug|x64 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x86.ActiveCfg = Debug|x86 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x86.Build.0 = Debug|x86 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Debug|x86.Deploy.0 = Debug|x86 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|Any CPU.Build.0 = Release|Any CPU + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|Any CPU.Deploy.0 = Release|Any CPU + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|ARM.ActiveCfg = Release|ARM + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|ARM.Build.0 = Release|ARM + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|ARM.Deploy.0 = Release|ARM + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x64.ActiveCfg = Release|x64 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x64.Build.0 = Release|x64 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x64.Deploy.0 = Release|x64 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x86.ActiveCfg = Release|x86 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x86.Build.0 = Release|x86 + {34E8CDE2-3991-414E-BB19-BFF4BD5E031A}.Release|x86.Deploy.0 = Release|x86 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/pxtwapp/pxtwapp/images/SmallTile.scale-200.png b/pxtwapp/pxtwapp/images/SmallTile.scale-200.png new file mode 100644 index 00000000..ece0f13d Binary files /dev/null and b/pxtwapp/pxtwapp/images/SmallTile.scale-200.png differ diff --git a/pxtwapp/pxtwapp/images/SplashScreen.scale-200.png b/pxtwapp/pxtwapp/images/SplashScreen.scale-200.png new file mode 100644 index 00000000..04e2edea Binary files /dev/null and b/pxtwapp/pxtwapp/images/SplashScreen.scale-200.png differ diff --git a/pxtwapp/pxtwapp/images/Square150x150Logo.scale-200.png b/pxtwapp/pxtwapp/images/Square150x150Logo.scale-200.png new file mode 100644 index 00000000..ba7825e4 Binary files /dev/null and b/pxtwapp/pxtwapp/images/Square150x150Logo.scale-200.png differ diff --git a/pxtwapp/pxtwapp/images/Square44x44Logo.altform-unplated_targetsize-48.png b/pxtwapp/pxtwapp/images/Square44x44Logo.altform-unplated_targetsize-48.png new file mode 100644 index 00000000..95fbcbba Binary files /dev/null and b/pxtwapp/pxtwapp/images/Square44x44Logo.altform-unplated_targetsize-48.png differ diff --git a/pxtwapp/pxtwapp/images/Square44x44Logo.scale-200.png b/pxtwapp/pxtwapp/images/Square44x44Logo.scale-200.png new file mode 100644 index 00000000..9718ecf2 Binary files /dev/null and b/pxtwapp/pxtwapp/images/Square44x44Logo.scale-200.png differ diff --git a/pxtwapp/pxtwapp/images/Square44x44Logo.targetsize-48.png b/pxtwapp/pxtwapp/images/Square44x44Logo.targetsize-48.png new file mode 100644 index 00000000..9c282d89 Binary files /dev/null and b/pxtwapp/pxtwapp/images/Square44x44Logo.targetsize-48.png differ diff --git a/pxtwapp/pxtwapp/images/Wide310x150Logo.scale-200.png b/pxtwapp/pxtwapp/images/Wide310x150Logo.scale-200.png new file mode 100644 index 00000000..dbcd6e25 Binary files /dev/null and b/pxtwapp/pxtwapp/images/Wide310x150Logo.scale-200.png differ diff --git a/pxtwapp/pxtwapp/images/logo.png b/pxtwapp/pxtwapp/images/logo.png new file mode 100644 index 00000000..8b21b4a5 Binary files /dev/null and b/pxtwapp/pxtwapp/images/logo.png differ diff --git a/pxtwapp/pxtwapp/images/storelogo.scale-200.png b/pxtwapp/pxtwapp/images/storelogo.scale-200.png new file mode 100644 index 00000000..d576c75e Binary files /dev/null and b/pxtwapp/pxtwapp/images/storelogo.scale-200.png differ diff --git a/pxtwapp/pxtwapp/msapp-error.css b/pxtwapp/pxtwapp/msapp-error.css new file mode 100644 index 00000000..8b478344 --- /dev/null +++ b/pxtwapp/pxtwapp/msapp-error.css @@ -0,0 +1,40 @@ +body { + margin: 10px; + background-color: #4C4B4D; + color: #FFFFFF; + font-family: 'Open Sans', 'Helvetica Neue', Arial, Helvetica, sans-serif; +} + +.paramName { + font-size: 10px; + font-weight: bold; +} + +.paramValue { + font-size: 10px; + padding-left: 10px; +} + +.param { + margin-bottom: 8px; +} + +#retryButton { + box-shadow: 0px 0em 0px 0px rgba(34, 36, 38, 0.15) inset; + outline: none; + border: none; + vertical-align: baseline; + padding: 0.78571429em 1.5em 0.78571429em; + text-transform: none; + font-weight: bold; + font-style: normal; + text-align: center; + text-decoration: none; + border-radius: 0.28571429rem; + background-color: #FB48C7; + margin: 15px 10px 100px 10px; + width: 80px; + height: 35px; + font-size: 15px; + color: #FFFFFF; +} diff --git a/pxtwapp/pxtwapp/msapp-error.html b/pxtwapp/pxtwapp/msapp-error.html new file mode 100644 index 00000000..33303cf1 --- /dev/null +++ b/pxtwapp/pxtwapp/msapp-error.html @@ -0,0 +1,24 @@ + + + + Oops! + + + + +

Oops! Please connect to the Internet.

+ +
+ URL: + +
+
+ HTTP status: + +
+
+ Failure name: + +
+ + diff --git a/pxtwapp/pxtwapp/msapp-error.js b/pxtwapp/pxtwapp/msapp-error.js new file mode 100644 index 00000000..ef5e2bef --- /dev/null +++ b/pxtwapp/pxtwapp/msapp-error.js @@ -0,0 +1,47 @@ +(function () { + var validParameterNames = ["httpStatus", "failureName", "failureUrl"]; + + function parseQueryParameters() { + var query = location.search.slice(1); + return query.split("&").reduce(function (queryParameters, rawPair) { + var pair = rawPair.split("=").map(decodeURIComponent); + queryParameters[pair[0]] = pair[1]; + return queryParameters; + }, {}); + } + + function initialize() { + var queryParameters = parseQueryParameters(); + var url = queryParameters["failureUrl"]; + var retryButton = document.getElementById("retryButton"); + + if (url) { + retryButton.addEventListener("click", (e) => { + window.location.href = url; + }); + } else { + retryButton.style.display = none; + } + + validParameterNames.forEach(function (parameterName) { + var parameterValue = queryParameters[parameterName]; + + if (parameterValue) { + document.getElementById(parameterName + "Value").textContent = parameterValue; + } else { + document.getElementById(parameterName).remove(); + } + }); + } + + function updateOnlineStatus(e) { + var queryParameters = parseQueryParameters(); + var url = queryParameters["failureUrl"]; + if (url) { + window.location.href = url; + } + } + + window.addEventListener("online", updateOnlineStatus); + document.addEventListener("DOMContentLoaded", initialize); +}()); diff --git a/pxtwapp/pxtwapp/package.appxmanifest b/pxtwapp/pxtwapp/package.appxmanifest new file mode 100644 index 00000000..8551fb37 --- /dev/null +++ b/pxtwapp/pxtwapp/package.appxmanifest @@ -0,0 +1,60 @@ + + + + + + Microsoft MakeCode for micro:bit + micro:bit + images\storelogo.png + + + + + + + + + + + + + + + + + + + + + + + + + Microsoft MakeCode binary file + + .hex + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/pxtwapp/pxtwapp/pxtwapp.jsproj b/pxtwapp/pxtwapp/pxtwapp.jsproj new file mode 100644 index 00000000..075e1e95 --- /dev/null +++ b/pxtwapp/pxtwapp/pxtwapp.jsproj @@ -0,0 +1,87 @@ + + + + + Debug + AnyCPU + + + Debug + ARM + + + Debug + x64 + + + Debug + x86 + + + Release + AnyCPU + + + Release + ARM + true + + + Release + x64 + true + + + Release + x86 + true + + + + 34e8cde2-3991-414e-bb19-bff4bd5e031a + + + + 14.0 + + + + + UAP + 10.0.15063.0 + 10.0.10240.0 + $(VersionNumberMajor).$(VersionNumberMinor) + en-US + pxtwapp_TemporaryKey.pfx + + + + Designer + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sim/state/misc.ts b/sim/state/misc.ts index cc16ed92..de0beb9c 100644 --- a/sim/state/misc.ts +++ b/sim/state/misc.ts @@ -86,6 +86,10 @@ namespace pxsim.input { return runtime.runningTime(); } + export function runningTimeMicros(): number { + return runtime.runningTimeUs(); + } + export function calibrateCompass() { // device calibrates... } @@ -189,13 +193,13 @@ namespace pxsim.bluetooth { export function startUartService(): void { // TODO } - export function uartWrite(s: string): void { + export function uartWriteString(s: string): void { serial.writeString(s) } export function uartReadUntil(del: string): string { return serial.readUntil(del); } - export function onDataReceived(delimiters: string, handler: RefAction) { + export function onUartDataReceived(delimiters: string, handler: RefAction) { let b = board(); b.bus.listen(DAL.MICROBIT_ID_BLE_UART, DAL.MICROBIT_UART_S_EVT_DELIM_MATCH, handler); } diff --git a/targetconfig.json b/targetconfig.json index b8cceeba..21787abb 100644 --- a/targetconfig.json +++ b/targetconfig.json @@ -21,9 +21,11 @@ ] }, "languages": [ - "de", "en", + "de", "fr", + "ko", + "it", "ja", "nl", "no",