diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..af5e14eb --- /dev/null +++ b/.gitattributes @@ -0,0 +1,22 @@ +# enforce unix style line endings +*.ts text eol=lf +*.tsx text eol=lf +*.md text eol=lf +*.txt text eol=lf +*.js text eol=lf +*.json text eol=lf +*.xml text eol=lf +*.svg text eol=lf +*.yaml text eol=lf +*.css text eol=lf +*.html text eol=lf +*.py text eol=lf +*.exp text eol=lf + +# do not enforce text for everything - it causes issues with random binary files + +*.sln text eol=crlf + +*.png binary +*.jpg binary +*.jpeg binary diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..07bbeed6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +node_modules +*.sw? +built +typings/ +tmp/ +*.ts.new +temp/ diff --git a/kindtarget.json b/kindtarget.json new file mode 100644 index 00000000..853a1687 --- /dev/null +++ b/kindtarget.json @@ -0,0 +1,72 @@ +{ + "id": "microbit", + "name": "microbit", + "cloud": true, + "bundleddirs": [ + "libs/microbit", + "libs/microbit-led", + "libs/microbit-music", + "libs/microbit-radio", + "libs/microbit-game", + "libs/microbit-pins", + "libs/microbit-serial" + ], + + "blocksprj": { + "id": "blocksprj", + "config": { + "name": "{0} block", + "dependencies": { + "microbit": "*", + "microbit-led": "*", + "microbit-music": "*", + "microbit-radio": "*", + "microbit-game": "*", + "microbit-pins": "*", + "microbit-serial": "*" + }, + "description": "", + "files": [ + "main.blocks", + "main.blocks.ts", + "README.md" + ] + }, + "files": { + "main.blocks": "\n\n", + "main.blocks.ts": "\n", + "README.md": "Describe your project here!" + } + }, + + "tsprj": { + "id": "tsprj", + "config": { + "name": "{0} bit", + "dependencies": { + "microbit": "*", + "microbit-led": "*", + "microbit-music": "*", + "microbit-radio": "*", + "microbit-game": "*", + "microbit-pins": "*", + "microbit-serial": "*" + }, + "description": "", + "files": [ + "main.ts", + "README.md" + ] + }, + "files": { + "main.ts": "basic.showString('Hi!')\n", + "README.md": "Describe your project here!" + } + }, + "koduvscode": true, + + "compile": { + "isNative": false, + "hasHex": true + } +} diff --git a/libs/cpp-test/hello.ts b/libs/cpp-test/hello.ts new file mode 100644 index 00000000..6f4776d1 --- /dev/null +++ b/libs/cpp-test/hello.ts @@ -0,0 +1,13 @@ +//% shim=foo::bar +function test() { +} + +basic.plotLeds(` +# # . # # +. . # . . +. . # . . +# . . . # +. # # # . +`); +basic.pause(300); +test(); diff --git a/libs/cpp-test/support.cpp b/libs/cpp-test/support.cpp new file mode 100644 index 00000000..1474159a --- /dev/null +++ b/libs/cpp-test/support.cpp @@ -0,0 +1,6 @@ +namespace foo { + GLUE void bar() + { + micro_bit::scrollNumber(108108, 50); + } +} diff --git a/libs/cpp-test/yelm.json b/libs/cpp-test/yelm.json new file mode 100644 index 00000000..3c660dab --- /dev/null +++ b/libs/cpp-test/yelm.json @@ -0,0 +1,17 @@ +{ + "name": "cpp-test", + "description": "Testing C++", + "files": [ + "support.cpp", + "hello.ts" + ], + "public": true, + "microbit": { + "config": { + "MICROBIT_BLE_ENABLED": "0" + } + }, + "dependencies": { + "core": "file:../microbit" + } +} diff --git a/libs/hello/hello.ts b/libs/hello/hello.ts new file mode 100644 index 00000000..a1c168a9 --- /dev/null +++ b/libs/hello/hello.ts @@ -0,0 +1,7 @@ +basic.plotLeds(` +# # . # # +. . # . . +. . # . . +# . . . # +. # # # . +`); diff --git a/libs/hello/yelm.json b/libs/hello/yelm.json new file mode 100644 index 00000000..d7f7e7c1 --- /dev/null +++ b/libs/hello/yelm.json @@ -0,0 +1,11 @@ +{ + "name": "hello", + "description": "Hello world", + "files": [ + "hello.ts" + ], + "public": true, + "dependencies": { + "core": "file:../microbit" + } +} diff --git a/libs/microbit-devices/README.md b/libs/microbit-devices/README.md new file mode 100644 index 00000000..8bba447d --- /dev/null +++ b/libs/microbit-devices/README.md @@ -0,0 +1 @@ +# devices diff --git a/libs/microbit-devices/devices.ts b/libs/microbit-devices/devices.ts new file mode 100644 index 00000000..665a7ed3 --- /dev/null +++ b/libs/microbit-devices/devices.ts @@ -0,0 +1,181 @@ +enum MesCameraEvent { + //% enumval=MES_CAMERA_EVT_TAKE_PHOTO blockId="take photo" + TakePhoto, + //% enumval=MES_CAMERA_EVT_START_VIDEO_CAPTURE blockId="start video capture" + StartVideoCapture, + //% enumval=MES_CAMERA_EVT_STOP_VIDEO_CAPTURE blockId="stop video capture" + StopVideoCapture, + //% enumval=MES_CAMERA_EVT_TOGGLE_FRONT_REAR blockId="toggle front-rear" + ToggleFrontRear, + //% enumval=MES_CAMERA_EVT_LAUNCH_PHOTO_MODE blockId="launch photo mode" + LaunchPhotoMode, + //% enumval=MES_CAMERA_EVT_LAUNCH_VIDEO_MODE blockId="launch video mode" + LaunchVideoMode, + //% enumval=MES_CAMERA_EVT_STOP_PHOTO_MODE blockId="stop photo mode" + StopPhotoMode, + //% enumval=MES_CAMERA_EVT_STOP_VIDEO_MODE blockId="stop video mode" + StopVideoMode, +} + +enum MesAlertEvent { + //% enumval=MES_ALERT_EVT_DISPLAY_TOAST blockId="display toast" + DisplayToast, + //% enumval=MES_ALERT_EVT_VIBRATE blockId="vibrate" + Vibrate, + //% enumval=MES_ALERT_EVT_PLAY_SOUND blockId="play sound" + PlaySound, + //% enumval=MES_ALERT_EVT_PLAY_RINGTONE blockId="play ring tone" + PlayRingtone, + //% enumval=MES_ALERT_EVT_FIND_MY_PHONE blockId="find my phone" + FindMyPhone, + //% enumval=MES_ALERT_EVT_ALARM1 blockId="ring alarm" + RingAlarm, + //% enumval=MES_ALERT_EVT_ALARM2 blockId="ring alarm 2" + RingAlarm2, + //% enumval=MES_ALERT_EVT_ALARM3 blockId="ring alarm 3" + RingAlarm3, + //% enumval=MES_ALERT_EVT_ALARM4 blockId="ring alarm 4" + RingAlarm4, + //% enumval=MES_ALERT_EVT_ALARM5 blockId="ring alarm 5" + RingAlarm5, + //% enumval=MES_ALERT_EVT_ALARM6 blockId="ring alarm 6" + RingAlarm6, +} + +enum MesDeviceInfo { + //% enumval=MES_DEVICE_INCOMING_CALL blockId="incoming call" + IncomingCall, + //% enumval=MES_DEVICE_INCOMING_MESSAGE blockId="incoming message" + IncomingMessage, + //% enumval=MES_DEVICE_ORIENTATION_LANDSCAPE blockId="orientation landscape" + OrientationLandscape, + //% enumval=MES_DEVICE_ORIENTATION_PORTRAIT blockId="orientation portrait" + OrientationPortrait, + //% enumval=MES_DEVICE_GESTURE_DEVICE_SHAKEN blockId="shaken" + Shaken, + //% enumval=MES_DEVICE_DISPLAY_OFF blockId="display off" + DisplayOff, + //% enumval=MES_DEVICE_DISPLAY_ON blockId="display on" + DisplayOn, +} + +enum MesRemoteControlEvent { + //% enumval=MES_REMOTE_CONTROL_EVT_PLAY blockId="play" + play, + //% enumval=MES_REMOTE_CONTROL_EVT_PAUSE blockId="pause" + pause, + //% enumval=MES_REMOTE_CONTROL_EVT_STOP blockId="stop" + stop, + //% enumval=MES_REMOTE_CONTROL_EVT_NEXTTRACK blockId="next track" + nextTrack, + //% enumval=MES_REMOTE_CONTROL_EVT_PREVTRACK blockId="previous track" + previousTrack, + //% enumval=MES_REMOTE_CONTROL_EVT_FORWARD blockId="forward" + forward, + //% enumval=MES_REMOTE_CONTROL_EVT_REWIND blockId="rewind" + rewind, + //% enumval=MES_REMOTE_CONTROL_EVT_VOLUMEUP blockId="volume up" + volumeUp, + //% enumval=MES_REMOTE_CONTROL_EVT_VOLUMEDOWN blockId="volume down" + volumeDown, +} + +enum MesDpadButtonInfo { + //% enumval=MES_DPAD_BUTTON_A_DOWN blockId="A down" + ADown, + //% enumval=MES_DPAD_BUTTON_A_UP blockId="A up" + AUp, + //% enumval=MES_DPAD_BUTTON_B_DOWN blockId="B down" + BDown, + //% enumval=MES_DPAD_BUTTON_B_UP blockId="B up" + BUp, + //% enumval=MES_DPAD_BUTTON_C_DOWN blockId="C down" + CDown, + //% enumval=MES_DPAD_BUTTON_C_UP blockId="C up" + CUp, + //% enumval=MES_DPAD_BUTTON_D_DOWN blockId="D down" + DDown, + //% enumval=MES_DPAD_BUTTON_D_UP blockId="D up" + DUp, + //% enumval=MES_DPAD_BUTTON_1_UP blockId="1 down" + _1Down, + //% enumval=MES_DPAD_BUTTON_1_DOWN blockId="1 up" + _1Up, + //% enumval=MES_DPAD_BUTTON_2_DOWN blockId="2 down" + _2Down, + //% enumval=MES_DPAD_BUTTON_2_UP blockId="2 up" + _2Up, + //% enumval=MES_DPAD_BUTTON_3_DOWN blockId="3 down" + _3Down, + //% enumval=MES_DPAD_BUTTON_3_UP blockId="3 up" + _3Up, + //% enumval=MES_DPAD_BUTTON_4_DOWN blockId="4 down" + _4Down, + //% enumval=MES_DPAD_BUTTON_4_UP blockId="4 up" + _4Up, +} + +//% color=156 weight=80 +namespace devices { + /** + * Sends a ``camera`` command to the parent device. + * @param event TODO + */ + //% weight=30 help=functions/tell-camera-to shim=micro_bit::devices::camera + //% blockId=devices_camera icon="\uf030" block="tell camera to|%property" blockGap=8 + export function tellCameraTo(event: MesCameraEvent): void { } + + /** + * Sends a ``remote control`` command to the parent device. + * @param event TODO + */ + //% weight=29 help=functions/tell-remote-control-to shim=micro_bit::devices::remote_control + //% blockId=devices_remote_control block="tell remote control to|%property" blockGap=14 icon="\uf144" + export function tellRemoteControlTo(event: MesRemoteControlEvent): void { } + + /** + * Sends an ``alert`` command to the parent device. + * @param event TODO + */ + //% weight=27 help=functions/raise-alert-to shim=micro_bit::devices::alert + //% blockId=devices_alert block="raise alert to|%property" icon="\uf0f3" + export function raiseAlertTo(event: MesAlertEvent): void { } + + /** + * Registers code to run when the device notifies about a particular event. + * @param event TODO + * @param body TODO + */ + //% shim=micro_bit::onDeviceInfo help=functions/on-notified + //% weight=26 + //% blockId=devices_device_info_event block="on notified" icon="\uf10a" + export function onNotified(event: MesDeviceInfo, body: Action): void { } + + /** + * Register code to run when the micro:bit receives a command from the paired gamepad. + * @param name TODO + * @param body TODO + */ + //% help=functions/on-gamepad-button weight=40 shim=micro_bit::onGamepadButton + //% weight=25 + //% blockId=devices_gamepad_event block="on gamepad button|%NAME" icon="\uf11b" + export function onGamepadButton(name: MesDpadButtonInfo, body: Action): void { } + + /** + * Returns the last signal strength reported by the paired device. + */ + //% help=functions/signal-strength weight=24 shim=micro_bit::signalStrength + //% blockId=devices_signal_strength block="signal strength" blockGap=14 icon="\uf012" blockGap=14 + export function signalStrength(): number { + return 0; + } + + /** + * Registers code to run when the device notifies about a change of signal strength. + * @param body TODO + */ + //% shim=micro_bit::onSignalStrengthChanged weight=23 help=functions/on-signal-strength-changed + //% blockId=devices_signal_strength_changed_event block="on signal strength changed" icon="\uf012" + export function onSignalStrengthChanged(body: Action): void { } +} + diff --git a/libs/microbit-devices/yelm.json b/libs/microbit-devices/yelm.json new file mode 100644 index 00000000..fc9dfa5e --- /dev/null +++ b/libs/microbit-devices/yelm.json @@ -0,0 +1,13 @@ +{ + "name": "microbit-devices", + "description": "The BLE specific services", + "files": [ + "README.md", + "devices.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit" + }, + "installedVersion": "zakvul" +} diff --git a/libs/microbit-game/README.md b/libs/microbit-game/README.md new file mode 100644 index 00000000..0ed2bde3 --- /dev/null +++ b/libs/microbit-game/README.md @@ -0,0 +1,4 @@ +# game + +The game library. + diff --git a/libs/microbit-game/game.ts b/libs/microbit-game/game.ts new file mode 100644 index 00000000..c00345fd --- /dev/null +++ b/libs/microbit-game/game.ts @@ -0,0 +1,723 @@ +enum Direction { + //% blockId=right + Right, + //% blockId=left + Left +} + +enum LedSpriteProperty { + //% blockId=x + X, + //% blockId=y + Y, + //% blockId=direction + Direction, + //% blockId=brightness + Brightness, + //% blockId=blink + Blink +} + +//% color=176 weight=32 +namespace game { + var _score: number = 0; + var _life: number = 3; + var _startTime: number = 0; + var _endTime: number = 0; + var _isGameOver: boolean = false; + var _countdownPause: number = 0; + var _level: number = 1; + var _gameId: number = 0; + var img: images.Image; + var sprites: LedSprite[]; + + /** + * Creates a new LED sprite pointing to the right. + * @param x sprite horizontal coordinate, eg: 2 + * @param y sprite vertical coordinate, eg: 2 + */ + //% weight=60 + //% blockId=game_create_sprite block="create sprite at|x: %x|y: %y" + export function createSprite(x: number, y: number): LedSprite { + init(); + let p = new LedSprite(x, y); + sprites.push(p); + plot(); + return p; + } + + /** + * Gets the current score + */ + //% weight=9 help=td/game-library + //% blockId=game_score block="score" blockGap=8 + export function score(): number { + return _score; + } + + /** + * Adds points to the current score + * @param points amount of points to change, eg: 1 + */ + //% weight=10 help=td/game-library + //% blockId=game_add_score block="change score by|%points" blockGap=8 + export function addScore(points: number): void { + setScore(_score + points); + 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 +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 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); + }); + } + + /** + * Starts a game countdown timer + * @param ms countdown duration in milliseconds, eg: 10000 + */ + //% weight=9 help=td/game-library + //% blockId=game_start_countdown block="start countdown|(ms) %duration" blockGap=8 + export function startCountdown(ms: number): void { + if (checkStart()) { + basic.showAnimation(`1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 +0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 +1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 +0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 +1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0`, 400); + _countdownPause = Math.max(500, ms); + _startTime = -1; + _endTime = input.runningTime() + _countdownPause; + control.inBackground(() => { + basic.pause(_countdownPause); + gameOver(); + }); + } + } + + /** + * Displays a game over animation. + */ + //% weight=8 help=td/game-library + //% blockId=game_game_over block="game over" + export function gameOver(): void { + if (!_isGameOver) { + _isGameOver = true; + unplugEvents(); + led.stopAnimation(); + led.setBrightness(255); + led.setDisplayMode(DisplayMode.BackAndWhite); + while (true) { + for (let i = 0; i < 8; i++) { + basic.clearScreen(); + basic.pause(100); + basic.showLeds(`1 1 1 1 1 +1 1 1 1 1 +1 1 1 1 1 +1 1 1 1 1 +1 1 1 1 1`, 300); + } + basic.showAnimation(`1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 0 0 1 1 0 0 0 1 0 0 0 0 1 0 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 0 0 0 0 0 0 0 0 +1 1 0 1 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 1 1 0 0 0 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 0 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 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 0 0 0 0 0 0 0 0 0 0 0 0 +1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 1 1 0 0 0 0 1 0 0 0 0 0`, 100); + for (let j = 0; j < 3; j++) { + basic.showString(" GAMEOVER ", 100); + showScore(); + } + } + } else { + // already in game over mode in another fiber + while (true) { + basic.pause(10000); + } + } + } + + /** + * Sets the current score value + * @param value TODO + */ + //% weight=10 help=td/game-library + export function setScore(value: number): void { + _score = Math.max(0, value); + } + + /** + * Gets the current life + */ + //% weight=10 help=td/game-library + export function life(): number { + return _life; + } + + /** + * Sets the current life value + * @param value TODO + */ + //% weight=10 help=td/game-library + export function setLife(value: number): void { + _life = Math.max(0, value); + if (_life <= 0) { + gameOver(); + } + } + + /** + * Adds life points to the current life + * @param lives TODO + */ + //% weight=10 help=td/game-library + export function addLife(lives: number): void { + setLife(_life + lives); + } + + /** + * Gets the remaining time (since `start countdown`) or current time (since the device started or `start stopwatch`) in milliseconds. + */ + //% weight=10 help=td/game-library + export function currentTime(): number { + if (_endTime > 0) { + return Math.max(0, _endTime - input.runningTime()); + } else { + return input.runningTime() - _startTime; + } + } + + /** + * Removes some life + * @param life TODO + */ + //% weight=10 help=td/game-library + export function removeLife(life: number): void { + setLife(_life - life); + control.inBackground(() => { + led.stopAnimation(); + basic.showAnimation(`1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0 +0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 +0 0 1 0 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 +0 1 0 1 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 +1 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 0 0 0`, 40); + }); + } + + /** + * Increments the level and display a message. + */ + //% weight=10 help=td/game-library + export function levelUp(): void { + _level = _level + 1; + basic.showString("LEVEL:", 150); + basic.showNumber(_level, 150); + } + + /** + * Gets the current level + */ + //% weight=10 help=td/game-library + export function level(): number { + return _level; + } + + /** + * Starts a stopwatch timer. `current time` will return the elapsed time. + */ + //% weight=10 help=td/game-library + export function startStopwatch(): void { + _startTime = input.runningTime(); + _endTime = -1; + } + + /** + * Gets a value indicating if the game is still running. Returns `false` if game over. + */ + //% weight=10 help=td/game-library + export function isRunning(): boolean { + let running: boolean; + return !_isGameOver; + } + + /** + * Displays the score on the screen. + */ + //% help=td/game-library weight=60 + export function showScore(): void { + basic.showString(" SCORE ", 100); + basic.showNumber(_score, 150); + basic.showString(" ", 150); + } + + /** + * Indicates if the game is display the game over sequence. + */ + //% help=/functions/game-library + export function isGameOver(): boolean { + let over: boolean; + return _isGameOver; + } + + /** + * returns false if game can't start + */ + function checkStart(): boolean { + if (_countdownPause > 0 || _startTime > 0) { + return false; + } else { + return true; + } + } + + function unplugEvents(): void { + input.onButtonPressed(Button.A, () => { }); + input.onButtonPressed(Button.B, () => { }); + input.onButtonPressed(Button.AB, () => { + control.reset(); + }); + } + + export class LedSprite { + private _x: number; + private _y: number; + private _dir: number; + private _brightness: number; + private _blink: number; + + constructor(x: number, y: number) { + this._x = math.clamp(0, 4, x); + this._y = math.clamp(0, 4, y); + this._dir = 90; + this._brightness = 255; + init(); + sprites.push(this); + plot(); + } + + /** + * Move a certain number of LEDs + * @param this the sprite to move + * @param leds number of leds to move, eg: 1, -1 + */ + //% weight=50 + //% blockId=game_move_sprite block="%sprite|move by %leds" blockGap=8 + public move(leds: number): void { + if (this._dir == 0) { + this._y = this._y - leds; + } else if (this._dir == 45) { + this._x = this._x + leds; + this._y = this._y - leds; + } else if (this._dir == 90) { + this._x = this._x + leds; + } else if (this._dir == 135) { + this._x = this._x + leds; + this._y = this._y + leds; + } else if (this._dir == 180) { + this._y = this._y + leds; + } else if (this._dir == -45) { + this._x = this._x - leds; + this._y = this._y - leds; + } else if (this._dir == -90) { + this._x = this._x - leds; + } else { + this._x = this._x - leds; + this._y = this._y + leds; + } + this._x = math.clamp(0, 4, this._x); + this._y = math.clamp(0, 4, this._y); + plot(); + } + + /** + * Go to this position on the screen + * @param this TODO + * @param x TODO + * @param y TODO + */ + public goTo(x: number, y: number): void { + this._x = x; + this._y = y; + this._x = math.clamp(0, 4, this._x); + this._y = math.clamp(0, 4, this._y); + plot(); + } + + /** + * If touching the edge of the stage, then bounce away. + * @param this TODO + */ + //% weight=18 + //% blockId=game_sprite_bounce block="%sprite|if on edge, bounce" + public ifOnEdgeBounce(): void { + if (this._dir == 0 && this._y == 0) { + this._dir = 180; + } else if (this._dir == 45 && (this._x == 4 || this._y == 0)) { + if (this._x == 0 && this._y == 0) { + this._dir = -135; + } else if (this._y == 0) { + this._dir = 135; + } else { + this._dir = -45; + } + } else if (this._dir == 90 && this._x == 4) { + this._dir = -90; + } else if (this._dir == 135 && (this._x == 4 || this._y == 4)) { + if (this.x() == 4 && this.y() == 4) { + this._dir = -45; + } else if (this._y == 4) { + this._dir = 45; + } else { + this._dir = -135; + } + } else if (this._dir == 180 && this._y == 4) { + this._dir = 0; + } else if (this._dir == -45 && (this._x == 0 || this._y == 0)) { + if (this.x() == 0 && this.y() == 0) { + this._dir = 135; + } else if (this._y == 0) { + this._dir = -135; + } else { + this._dir = 45; + } + } else if (this._dir == -90 && this._x == 0) { + this._dir = 90; + } else if (this._dir == -135 && (this._x == 0 || this._y == 4)) { + if (this._x == 0 && this._y == 4) { + this._dir = 45; + } else if (this._y == 4) { + this._dir = -45; + } else { + this._dir = 135; + } + } + plot(); + } + + /** + * Turn the sprite + * @param this TODO + * @param direction left or right + * @param degrees angle in degrees to turn, eg: 45, 90, 180, 135 + */ + //% weight=49 + //% blockId=game_turn_sprite block="%sprite|turn %direction|by (°) %degrees" + public turn(direction : Direction, degrees: number) { + if (direction == Direction.Right) + this.setDirection(this._dir + degrees); + else + this.setDirection(this._dir - degrees); + } + + /** + * Turn to the right (clockwise) + * @param this TODO + * @param degrees TODO + */ + public turnRight(degrees: number): void { + this.turn(Direction.Right, degrees); + } + + /** + * Turn to the left (counter-clockwise) + * @param this TODO + * @param degrees TODO + */ + public turnLeft(degrees: number): void { + this.turn(Direction.Left, degrees); + } + + /** + * Sets a property of the sprite + * @param property the name of the property to change + * @param the updated value + */ + //% weight=29 + //% blockId=game_sprite_set_property block="%sprite|set %property|to %value" blockGap=8 + public set(property : LedSpriteProperty, value:number) { + switch(property) { + case LedSpriteProperty.X: this.setX(value); break; + case LedSpriteProperty.Y: this.setY(value); break; + case LedSpriteProperty.Direction: this.setDirection(value); break; + case LedSpriteProperty.Brightness: this.setBrightness(value); break; + case LedSpriteProperty.Blink: this.setBlink(value); break; + } + } + + /** + * Changes a property of the sprite + * @param property the name of the property to change + * @param value amount of change, eg: 1 + */ + //% weight=30 + //% blockId=game_sprite_change_xy block="%sprite|change %property|by %value" blockGap=8 + public change(property : LedSpriteProperty, value:number) { + switch(property) { + case LedSpriteProperty.X: this.changeXBy(value); break; + case LedSpriteProperty.Y: this.changeYBy(value); break; + case LedSpriteProperty.Direction: this.changeDirectionBy(value); break; + case LedSpriteProperty.Brightness: this.changeBrightnessBy(value); break; + case LedSpriteProperty.Blink: this.changeBlinkBy(value); break; + } + } + + /** + * Gets a property of the sprite + * @param property the name of the property to change + */ + //% weight=28 + //% blockId=game_sprite_property block="%sprite|%property" + public get(property : LedSpriteProperty) { + switch(property) { + case LedSpriteProperty.X: return this.x(); + case LedSpriteProperty.Y: return this.y(); + case LedSpriteProperty.Direction: return this.direction() + case LedSpriteProperty.Brightness: return this.brightness(); + case LedSpriteProperty.Blink: return this.blink(); + default: return 0; + } + } + + /** + * Set the direction of the current sprite, rounded to the nearest multiple of 45 + * @param this TODO + * @param degrees TODO + */ + public setDirection(degrees: number): void { + this._dir = ((degrees / 45) % 8) * 45; + if (this._dir <= -180) { + this._dir = this._dir + 360; + } else if (this._dir > 180) { + this._dir = this._dir - 360; + } + plot(); + } + + /** + * Reports the ``x`` position of a sprite on the LED screen + * @param this TODO + */ + public x(): number { + return this._x; + } + + /** + * Reports the ``y`` position of a sprite on the LED screen + * @param this TODO + */ + public y(): number { + return this._y; + } + + /** + * Reports the current direction of a sprite + * @param this TODO + */ + public direction(): number { + return this._dir; + } + + /** + * Set the ``x`` position of a sprite + * @param this TODO + * @param x TODO + */ + public setX(x: number): void { + this.goTo(x, this._y); + } + + /** + * Set the ``y`` position of a sprite + * @param this TODO + * @param y TODO + */ + public setY(y: number): void { + this.goTo(this._x, y); + } + + /** + * Changes the ``y`` position by the given amount + * @param this TODO + * @param y TODO + */ + public changeYBy(y: number): void { + this.goTo(this._x, this._y + y); + } + + /** + * Changes the ``x`` position by the given amount + * @param this TODO + * @param x TODO + */ + public changeXBy(x: number): void { + this.goTo(this._x + x, this._y); + } + + /** + * Reports true if sprite is touching specified sprite + * @param this TODO + * @param other TODO + */ + //% weight=20 + //% blockId=game_sprite_touching_sprite block="%sprite|touching %other|?" blockGap=8 + public isTouching(other: LedSprite): boolean { + return this._x == other._x && this._y == other._y; + } + + /** + * Reports true if sprite is touching an edge + * @param this TODO + */ + //% weight=19 + //% blockId=game_sprite_touching_edge block="%sprite|touching edge?" blockGap=8 + public isTouchingEdge(): boolean { + return this._x == 0 || this._x == 4 || this._y == 0 || this._y == 4; + } + + /** + * Turns on the sprite (on by default) + * @param this TODO + */ + public on(): void { + this.setBrightness(255); + } + + /** + * Turns off the sprite (on by default) + * @param this TODO + */ + public off(): void { + this.setBrightness(0); + } + + /** + * Set the ``brightness`` of a sprite + * @param this TODO + * @param brightness TODO + */ + public setBrightness(brightness: number): void { + this._brightness = math.clamp(0, 255, brightness); + plot(); + } + + /** + * Reports the ``brightness` of a sprite on the LED screen + * @param this TODO + */ + public brightness(): number { + let r: number; + return this._brightness; + } + + /** + * Changes the ``y`` position by the given amount + * @param this TODO + * @param value TODO + */ + public changeBrightnessBy(value: number): void { + this.setBrightness(this._brightness + value); + } + + /** + * Changes the ``direction`` position by the given amount by turning right + * @param this TODO + * @param angle TODO + */ + public changeDirectionBy(angle: number): void { + this.turnRight(angle); + } + + /** + * Deletes the sprite from the game engine. All further operation of the sprite will not have any effect. + * @param sprite TODO + */ + public delete(sprite: LedSprite): void { + sprites.removeElement(sprite); + } + + /** + * Sets the blink duration interval in millisecond. + * @param sprite TODO + * @param ms TODO + */ + public setBlink(ms: number): void { + this._blink = math.clamp(0, 10000, ms); + } + + /** + * Changes the ``blink`` duration by the given amount of millisecons + * @param this TODO + * @param ms TODO + */ + public changeBlinkBy(ms: number): void { + this.setBlink(this._blink + ms); + } + + /** + * Reports the ``blink`` duration of a sprite + * @param this TODO + */ + public blink(): number { + let r: number; + return this._blink; + } + + //% weight=-1 + public _plot(now: number) { + let ps = this + if (ps._brightness > 0) { + let r = 0; + if (ps._blink > 0) { + r = (now / ps._blink) % 2; + } + if (r == 0) { + img.setPixelBrightness(ps._x, ps._y, img.pixelBrightness(ps._x, ps._y) + ps._brightness); + } + } + } + } + + function init(): void { + if (img == null) { + 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 = ([]); + led.setDisplayMode(DisplayMode.Greyscale); + basic.forever(() => { + basic.pause(30); + plot(); + if (game.isGameOver()) { + basic.pause(600); + } + }); + } + } + + /** + * Plots the current sprites on the screen + */ + function plot(): void { + if (game.isGameOver()) { + return; + } + let now = input.runningTime(); + img.clear(); + for (let i = 0; i < sprites.length; i++) { + sprites[i]._plot(now); + } + img.plotImage(0); + } + + /** + * Gets an invalid sprite; used to initialize locals. + */ + //% weight=0 + export function invalidSprite(): LedSprite { + return null; + } + +} + diff --git a/libs/microbit-game/yelm.json b/libs/microbit-game/yelm.json new file mode 100644 index 00000000..09020b09 --- /dev/null +++ b/libs/microbit-game/yelm.json @@ -0,0 +1,14 @@ +{ + "name": "microbit-game", + "description": "The game services", + "files": [ + "README.md", + "game.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit", + "microbit-led": "file:../microbit-led" + }, + "installedVersion": "zxxhqa" +} diff --git a/libs/microbit-led/README.md b/libs/microbit-led/README.md new file mode 100644 index 00000000..535d3d54 --- /dev/null +++ b/libs/microbit-led/README.md @@ -0,0 +1,4 @@ +# led + +The led library. + diff --git a/libs/microbit-led/led.ts b/libs/microbit-led/led.ts new file mode 100644 index 00000000..c4ecc8a0 --- /dev/null +++ b/libs/microbit-led/led.ts @@ -0,0 +1,208 @@ +enum DisplayMode { + //% enumval=0 blockId="black and white" + BackAndWhite, + //% enumval=1 blockId="greyscale" + Greyscale, +} + +//% color=3 weight=35 +namespace led { + /** + * Turn on the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left. + * @param x TODO + * @param y TODO + */ + //% help=functions/plot weight=78 shim=micro_bit::plot + //% blockId=device_plot block="plot|x %x|y %y" icon="\uf205" blockGap=8 + export function plot(x: number, y: number): void { } + + /** + * Turn off the specified LED using x, y coordinates (x is horizontal, y is vertical). (0,0) is upper left. + * @param x TODO + * @param y TODO + */ + //% help=functions/unplot weight=77 shim=micro_bit::unPlot + //% blockId=device_unplot block="unplot|x %x|y %y" icon="\uf204" blockGap=8 + export function unplot(x: number, y: number): void { } + + /** + * Get the on/off state of the specified LED using x, y coordinates. (0,0) is upper left. + * @param x TODO + * @param y TODO + */ + //% help=functions/point weight=76 shim=micro_bit::point + //% blockId=device_point block="point|x %x|y %y" icon="\uf10c" + export function point(x: number, y: number): boolean { + return false; + } + + /** + * Get the screen brightness from 0 (off) to 255 (full bright). + */ + //% help=functions/brightness weight=60 shim=micro_bit::getBrightness + //% blockId=device_get_brightness block="brightness" icon="\uf042" blockGap=8 + export function brightness(): number { + return 0; + } + + /** + * Set the screen brightness from 0 (off) to 255 (full bright). + * @param value the brightness value, eg:255, 127, 0 + */ + //% help=functions/set-brightness weight=59 shim=micro_bit::setBrightness + //% blockId=device_set_brightness block="set brightness %value" icon="\uf042" + export function setBrightness(value: number): void { } + + /** + * Cancels the current animation and clears other pending animations. + */ + //% weight=50 shim=uBit.display.stopAnimation help=functions/stop-animation + //% blockId=device_stop_animation block="stop animation" icon="\uf04d" + export function stopAnimation(): void { } + + /** + * Displays a vertical bar graph based on the ``value`` and ``high`` value. + * @param value current value to plot + * @param high maximum value, eg: 1023, 255 + */ + //% help=/functions/plot-bar-graph weight=20 + //% blockId=device_plot_bar_graph block="plot bar graph of %value |up to %high" icon="\uf080" blockExternalInputs=true + export function plotBarGraph(value: number, high: number = 1023): void { + + writeString("v: "); + writeString(value.toString()); + writeString("\n"); + + let v = Math.abs((value * 15) / high); + let k = 0; + for(let y = 4; y >= 0; --y) { + for (let x = 0; x < 3; ++x) { + if (k > v) { + unplot(2-x,y); + unplot(2+x,y); + } else { + plot(2-x, y); + plot(2+x, y); + } + ++k; + } + } + } + + /** + * Writes a string to serial + */ + //% shim=micro_bit::serialSendString + function writeString(text: string): void { } + + /** + * Sets the display mode between black and white and greyscale for rendering LEDs. + * @param mode TODO + */ + //% shim=micro_bit::setDisplayMode weight=1 help=/functions/set-display-mode + export function setDisplayMode(mode: DisplayMode): void { } + + /** + * Toggles a particular pixel + * @param x TODO + * @param y TODO + */ + //% help=functions/toggle + export function toggle(x: number, y: number): void { + if (led.point(x, y)) { + led.unplot(x, y); + } else { + led.plot(x, y); + } + } + + /** + * Turns all LEDS on + */ + //% help=functions/plot-all + export function plotAll(): void { + for (let i = 0; i < 5; i++) { + for (let j = 0; j < 5; j++) { + led.plot(i, j); + } + } + } + + /** + * Inverts the current LED display + */ + //% help=functions/toggle-all + export function toggleAll(): void { + for (let i = 0; i < 5; i++) { + for (let j = 0; j < 5; j++) { + led.toggle(i, j); + } + } + } + + /** + * Fades in the screen display. + * @param ms TODO + */ + //% help=functions/fade-in + export function fadeIn(ms: number = 700): void { + if (ms < 20) { + led.setBrightness(255); + return; + } + let dt = 50; + let brightness = led.brightness(); + let start = input.runningTime(); + let elapsed = 0; + while (elapsed < ms) { + led.setBrightness(brightness + ((255 - brightness) * elapsed) / ms); + basic.pause(dt); + elapsed = input.runningTime() - start; + } + led.setBrightness(255); + } + + /** + * Fades out the screen brightness. + * @param ms TODO + */ + //% help=functions/fade-out + export function fadeOut(ms: number = 700): void { + if (ms < 20) { + led.setBrightness(0); + return; + } + let brightness = led.brightness(); + let dt = 50; + let start = input.runningTime(); + let elapsed = 0; + while (elapsed < ms) { + led.setBrightness(brightness - (brightness * elapsed) / ms); + basic.pause(dt); + elapsed = input.runningTime() - start; + } + led.setBrightness(0); + } + + /** + * Takes a screenshot of the LED screen and returns an image. + */ + //% shim=uBit.display.screenShot help=functions/screenshot + export function screenshot(): images.Image { + /* + let img: Image; + img = image.createImage(""); + for (let i = 0; i < 5; i++) { + for (let j = 0; j < 5; j++) { + if (led.point(i, j)) { + img.setPixel(i, j, true); + } + } + } + return img; + */ + return null; + } + + +} diff --git a/libs/microbit-led/yelm.json b/libs/microbit-led/yelm.json new file mode 100644 index 00000000..5a4630bc --- /dev/null +++ b/libs/microbit-led/yelm.json @@ -0,0 +1,13 @@ +{ + "name": "microbit-led", + "description": "The led services", + "files": [ + "README.md", + "led.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit" + }, + "installedVersion": "pjryly" +} diff --git a/libs/microbit-music/README.md b/libs/microbit-music/README.md new file mode 100644 index 00000000..e659935f --- /dev/null +++ b/libs/microbit-music/README.md @@ -0,0 +1,2 @@ +# music + diff --git a/libs/microbit-music/music.ts b/libs/microbit-music/music.ts new file mode 100644 index 00000000..ca737e0d --- /dev/null +++ b/libs/microbit-music/music.ts @@ -0,0 +1,201 @@ +enum Notes { + //% enumval=262 + C, + //% enumval=277 blockId=C# + CSharp, + //% enumval=294 + D, + //% enumval=311 + Eb, + //% enumval=330 + E, + //% enumval=349 + F, + //% enumval=370 blockId=F# + FSharp, + //% enumval=392 + G, + //% enumval=415 blockId=G# + GSharp, + //% enumval=440 + A, + //% enumval=466 + Bb, + //% enumval=494 + B, + //% enumval=131 + C3, + //% enumval=139 blockId=C#3 + CSharp3, + //% enumval=147 + D3, + //% enumval=156 + Eb3, + //% enumval=165 + E3, + //% enumval=175 + F3, + //% enumval=185 blockId=F#3 + FSharp3, + //% enumval=196 + G3, + //% enumval=208 blockId=G#3 + GSharp3, + //% enumval=220 + A3, + //% enumval=233 + Bb3, + //% enumval=247 + B3, + //% enumval=262 + C4, + //% enumval=277 blockId=C#4 + CSharp4, + //% enumval=294 + D4, + //% enumval=311 + Eb4, + //% enumval=330 + E4, + //% enumval=349 + F4, + //% enumval=370 blockId=F#3 + FSharp4, + //% enumval=392 + G4, + //% enumval=415 blockId=G#3 + GSharp4, + //% enumval=440 + A4, + //% enumval=466 + Bb4, + //% enumval=494 + B4, + //% enumval=523 + C5, + //% enumval=555 blockId=C#5 + CSharp5, + //% enumval=587 + D5, + //% enumval=622 + Eb5, + //% enumval=659 + E5, + //% enumval=698 + F5, + //% enumval=740 blockId=F#5 + FSharp5, + //% enumval=784 + G5, + //% enumval=831 blockId=G#5 + GSharp5, + //% enumval=880 + A5, + //% enumval=932 + Bb5, + //% enumval=989 + B5, +} + +enum BeatFraction { + //% enumVal=1 blockId=1 + Whole = 1, + //% enumVal=2 blockId="1/2" + Half = 2, + //% enumVal=4 blockId="1/4" + Quater = 4, + //% enumVal=8 blockId="1/8" + Heighth = 8, + //% enumVal=16 blockId="1/16" + Sixteenth = 16 +} + +//% color=52 weight=33 +namespace music { + var beatsPerMinute: number = 120; + + /** + * Plays a tone through pin ``P0`` for the given duration. + * @param frequency TODO + * @param ms TODO + */ + //% help=functions/play-tone weight=90 + //% blockId=device_play_note block="play|tone (Hz) %note=device_note|for (ms) %duration=device_beat" icon="\uf025" blockGap=8 + export function playTone(frequency: number, ms: number): void { + pins.analogSetPitchPin(AnalogPins.P0); + pins.analogPitch(frequency, ms); + } + + /** + * Plays a tone through pin ``P0``. + * @param frequency TODO + */ + //% help=functions/ring-tone weight=80 + //% blockId=device_ring block="ring tone (Hz)|%note=device_note" icon="\uf025" blockGap=8 + export function ringTone(frequency: number): void { + pins.analogSetPitchPin(AnalogPins.P0); + pins.analogPitch(frequency, 0); + } + + /** + * Rests (plays nothing) for a specified time through pin ``P0``. + * @param ms TODO + */ + //% help=functions/rest weight=79 + //% blockId=device_rest block="rest(ms)|%duration=device_beat" + export function rest(ms: number): void { + playTone(0, ms); + } + + + /** + * Gets the frequency of a note. + * @param name TODO + */ + //% shim=TD_ID weight=50 help=functions/note-frequency + //% blockId=device_note block="%note" + export function noteFrequency(name: Notes): number { + return name; + } + + /** + * Returns the duration of a beat in milli-seconds + */ + //% help=/functions/beat weight=49 + //% blockId=device_beat block="%fraction|beat" + export function beat(fraction : BeatFraction = BeatFraction.Whole): number { + let ms: number; + return 60000 / fraction / beatsPerMinute; + } + + /** + * 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. + */ + //% help=/functions/tempo weight=40 + //% blockId=device_tempo block="tempo (bpm)" blockGap=8 + export function tempo(): number { + return beatsPerMinute; + } + + /** + * Change the tempo by the specified amount + * @param bpm The change in beats per minute to the tempo, eg: 20 + */ + //% help=/functions/tempo weight=39 + //% blockId=device_change_tempo block="change tempo by (bpm)|%value" blockGap=8 + export function changeTempoBy(bpm: number): void { + setTempo(beatsPerMinute + bpm); + } + + /** + * Sets the tempo to the specified amount + * @param bpm The new tempo in beats per minute, eg: 120 + */ + //% help=/functions/tempo weight=38 + //% blockId=device_set_tempo block="set tempo to (bpm)|%value" + export function setTempo(bpm: number): void { + if (bpm > 0) { + beatsPerMinute = Math.max(1, bpm); + } + } +} diff --git a/libs/microbit-music/yelm.json b/libs/microbit-music/yelm.json new file mode 100644 index 00000000..b79cb106 --- /dev/null +++ b/libs/microbit-music/yelm.json @@ -0,0 +1,13 @@ +{ + "name": "microbit-music", + "description": "The music library", + "files": [ + "README.md", + "music.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit" + }, + "installedVersion": "vlwlid" +} diff --git a/libs/microbit-pins/README.md b/libs/microbit-pins/README.md new file mode 100644 index 00000000..1ffdf2b7 --- /dev/null +++ b/libs/microbit-pins/README.md @@ -0,0 +1,4 @@ +# radio + +The radio library. + diff --git a/libs/microbit-pins/pins.ts b/libs/microbit-pins/pins.ts new file mode 100644 index 00000000..13f8dacc --- /dev/null +++ b/libs/microbit-pins/pins.ts @@ -0,0 +1,155 @@ +enum DigitalPins { + //% enumval=uBit.io.P0 + P0, + //% enumval=uBit.io.P1 + P1, + //% enumval=uBit.io.P2 + P2, + //% enumval=uBit.io.P3 + P3, + //% enumval=uBit.io.P4 + P4, + //% enumval=uBit.io.P5 + P5, + //% enumval=uBit.io.P6 + P6, + //% enumval=uBit.io.P7 + P7, + //% enumval=uBit.io.P8 + P8, + //% enumval=uBit.io.P9 + P9, + //% enumval=uBit.io.P10 + P10, + //% enumval=uBit.io.P11 + P11, + //% enumval=uBit.io.P12 + P12, + //% enumval=uBit.io.P13 + P13, + //% enumval=uBit.io.P14 + P14, + //% enumval=uBit.io.P15 + P15, + //% enumval=uBit.io.P16 + P16, + //% enumval=uBit.io.P19 + P19, + //% enumval=uBit.io.P20 + P20, +} + +enum AnalogPins { + //% enumval=uBit.io.P0 + P0, + //% enumval=uBit.io.P1 + P1, + //% enumval=uBit.io.P2 + P2, + //% enumval=uBit.io.P3 + P3, + //% enumval=uBit.io.P4 + P4, + //% enumval=uBit.io.P10 + P10, +} + + +//% color=351 weight=30 +namespace pins { + /** + * Read the specified pin or connector as either 0 or 1 + * @param name pin to read from + */ + //% help=functions/digital-read-pin weight=30 shim=micro_bit::digitalReadPin + //% blockId=device_get_digital_pin block="digital read|pin %name" blockGap=8 + export function digitalReadPin(name: DigitalPins): number { + + return 0; + } + + /** + * Set a pin or connector value to either 0 or 1. + * @param name pin to write to + * @param value value to set on the pin, eg: 1,0 + */ + //% help=functions/digital-write-pin weight=29 shim=micro_bit::digitalWritePin + //% blockId=device_set_digital_pin block="digital write|pin %name|to %value" + export function digitalWritePin(name: DigitalPins, value: number): void { } + + /** + * Read the connector value as analog, that is, as a value comprised between 0 and 1023. + * @param name pin to write to + */ + //% help=functions/analog-read-pin weight=25 shim=micro_bit::analogReadPin + //% blockId=device_get_analog_pin block="analog read|pin %name" blockGap="8" + export function analogReadPin(name: AnalogPins): number { + return 0; + } + + /** + * Set the connector value as analog. Value must be comprised between 0 and 1023. + * @param name pin name to write to + * @param value value to write to the pin between ``0`` and ``1023``. eg:1023,0 + */ + //% help=functions/analog-write-pin weight=24 shim=micro_bit::analogWritePin + //% blockId=device_set_analog_pin block="analog write|pin %name|to %value" blockGap=8 + export function analogWritePin(name: AnalogPins, value: number): void { } + + /** + * Configures the Pulse-width modulation (PWM) of the analog output to the given value in **microseconds** or `1/1000` milliseconds. + * If this pin is not configured as an analog output (using `analog write pin`), the operation has no effect. + * @param pin analog pin to set period to + * @param micros period in micro seconds. eg:20000 + */ + //% shim=micro_bit::setAnalogPeriodUs help=functions/analog-set-period weight=23 + //% blockId=device_set_analog_period block="analog set period|pin %pin|to (µs)%micros" + export function analogSetPeriod(pin: AnalogPins, micros: number): void { } + + /** + * Writes a value to the servo, controlling the shaft accordingly. On a standard servo, this will set the angle of the shaft (in degrees), moving the shaft to that orientation. On a continuous rotation servo, this will set the speed of the servo (with ``0`` being full-speed in one direction, ``180`` being full speed in the other, and a value near ``90`` being no movement). + * @param name pin to write to + * @param value angle or rotation speed, eg:180,90,0 + */ + //% help=functions/servo-write-pin weight=20 shim=micro_bit::servoWritePin + //% blockId=device_set_servo_pin block="servo write|pin %name|to %value" blockGap=8 + export function servoWritePin(name: AnalogPins, value: number): void { } + + /** + * Configures this IO pin as an analog/pwm output, configures the period to be 20 ms, and sets the pulse width, based on the value it is given **microseconds** or `1/1000` milliseconds. + * @param pin pin name + * @param micros pulse duration in micro seconds, eg:1500 + */ + //% shim=micro_bit::setServoPulseUs help=functions/serial-set-pulse weight=19 + //% blockId=device_set_servo_pulse block="servo set pulse|pin %value|to (µs) %micros" + export function servoSetPulse(pin: AnalogPins, micros: number): void { } + + /** + * Re-maps a number from one range to another. That is, a value of ``from low`` would get mapped to ``to low``, a value of ``from high`` to ``to high``, values in-between to values in-between, etc. + * @param value value to map in ranges + * @param fromLow the lower bound of the value's current range + * @param fromHigh the upper bound of the value's current range, eg: 1023 + * @param toLow the lower bound of the value's target range + * @param toHigh the upper bound of the value's target range, eg: 4 + */ + //% help=functions/map weight=15 + //% blockId=math_map block="map %value|from low %fromLow|from high %fromHigh|to low %toLow|to high %toHigh" + export function map(value: number, fromLow: number, fromHigh: number, toLow: number, toHigh: number): number { + return ((value - fromLow) * (toHigh - toLow)) / (fromHigh - fromLow) + toLow; + } + + /** + * Sets the pin used when using `pins->analog pitch`. + * @param name TODO + */ + //% shim=micro_bit::enablePitch help=functions/analog-set-pitch weight=12 + export function analogSetPitchPin(name: AnalogPins): void { } + + /** + * Emits a Pulse-width modulation (PWM) signal to the current pitch pin. Use `analog set pitch pin` to define the pitch pin. + * @param frequency TODO + * @param ms TODO + */ + //% shim=micro_bit::pitch help=functions/analog-pitch weight=14 async + export function analogPitch(frequency: number, ms: number): void { } +} diff --git a/libs/microbit-pins/yelm.json b/libs/microbit-pins/yelm.json new file mode 100644 index 00000000..d803ef02 --- /dev/null +++ b/libs/microbit-pins/yelm.json @@ -0,0 +1,13 @@ +{ + "name": "microbit-pins", + "description": "The pins services", + "files": [ + "README.md", + "pins.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit" + }, + "installedVersion": "bornqs" +} diff --git a/libs/microbit-radio/README.md b/libs/microbit-radio/README.md new file mode 100644 index 00000000..1ffdf2b7 --- /dev/null +++ b/libs/microbit-radio/README.md @@ -0,0 +1,4 @@ +# radio + +The radio library. + diff --git a/libs/microbit-radio/radio.ts b/libs/microbit-radio/radio.ts new file mode 100644 index 00000000..7c763a53 --- /dev/null +++ b/libs/microbit-radio/radio.ts @@ -0,0 +1,85 @@ +//% color=270 weight=34 +namespace radio { + /** + * Broadcasts a number over radio to any connected micro:bit in the group. + */ + //% help=/functions/send-number + //% weight=60 + //% blockId=radio_datagram_send block="send number %MESSAGE" blockGap=8 + export function sendNumber(value: number) : void { + sendNumbers(value, 0, 0, 0); + } + + /** + * Broadcasts 4 numbers over radio to any connected micro:bit in the group. + */ + //% help=/functions/send-numbers + //% shim=micro_bit::datagramSendNumbers + //% weight=59 + //% blockId=radio_datagram_send_numbers block="send numbers|0: %VALUE0|1: %VALUE1|2: %VALUE2|3: %VALUE3" + export function sendNumbers(value_0: number, value_1: number, value_2: number, value_3: number) : void { + // noBleWarning(); + } + + /** + * Registers code to run when a packet is received over radio. + */ + //% help=/functions/on-data-received + //% shim=micro_bit::onDatagramReceived + //% weight=50 + //% blockId=radio_datagram_received_event block="on data received" blockGap=8 + export function onDataReceived(body:Action) : void { + // noBleWarning(); + } + + /** + * Reads the next packet as a number from the radio queue. + */ + //% help=/functions/receive-number + //% shim=micro_bit::datagramReceiveNumber + //% weight=46 + //% blockId=radio_datagram_receive block="receive number" blockGap=8 + export function receiveNumber() : number + { + //noBleWarning(); + return 0; + } + + /** + * Reads a number at a given index, between ``0`` and ``3``, from the packet received by ``receive number``. Not supported in simulator. + * @param index index of the number to read from 0 to 3. eg: 1 + */ + //% help=/functions/received-number-at + //% shim=micro_bit::datagramGetNumber + //% weight=45 + //% blockId=radio_datagram_received_number_at block="receive number|at %VALUE" blockGap=8 + export function receivedNumberAt(index: number) : number { + /* if (index < 0 || index >= 4) { + TD.simulator.warning("index should be between ``0`` and ``3``."); + }*/ + return 0; + } + + /** + * Gets the received signal strength indicator (RSSI) from the packet received by ``receive number``. Not supported in simulator. + * namespace=radio + */ + //% help=/functions/received-signal-strength + //% shim=micro_bit::datagramGetRSSI + //% weight=40 + //% blockId=radio_datagram_rssi block="received signal strength" + export function receivedSignalStrength() : number { + return 0; + } + + /** + * Sets the group id for radio communications. A micro:bit can only listen to one group ID at any time. + * @ param id the group id between ``0`` and ``255``, eg: 1 + */ + //% help=/functions/set-group + //% shim=micro_bit::setGroup + //% weight=10 + //% blockId=radio_set_group block="set group %ID" + export function setGroup(id: number) : void { + } +} diff --git a/libs/microbit-radio/yelm.json b/libs/microbit-radio/yelm.json new file mode 100644 index 00000000..03b28324 --- /dev/null +++ b/libs/microbit-radio/yelm.json @@ -0,0 +1,13 @@ +{ + "name": "microbit-radio", + "description": "The radio services", + "files": [ + "README.md", + "radio.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit" + }, + "installedVersion": "phykjp" +} diff --git a/libs/microbit-serial/README.md b/libs/microbit-serial/README.md new file mode 100644 index 00000000..7907b1b9 --- /dev/null +++ b/libs/microbit-serial/README.md @@ -0,0 +1,4 @@ +# serial + +The serial library. + diff --git a/libs/microbit-serial/serial.ts b/libs/microbit-serial/serial.ts new file mode 100644 index 00000000..038457e8 --- /dev/null +++ b/libs/microbit-serial/serial.ts @@ -0,0 +1,59 @@ +//% weight=1 +namespace serial { + /** + * Prints a line of text to the serial + * @param value to send over serial + */ + //% blockId=serial_writeline block="serial|write %text" + export function writeLine(text: string): void { + writeString(text); + writeString("\r\n"); + } + + /** + * Prints a numeric value to the serial + */ + export function writeNumber(value: number): void { + writeString(value.toString()); + } + + /** + * Reads a line of text from the serial port. + */ + //% shim=micro_bit::serialReadString + export function readString(): string { + return "" + } + + /** + * Sends a piece of text through Serial connection. + */ + //% shim=micro_bit::serialSendString + export function writeString(text: string): void { } + + /** + * Sends the current pixel values, byte-per-pixel, over serial. + */ + //% shim=micro_bit::serialSendDisplayState + export function writeScreen(): void { } + + /** + * Reads the screen from serial. + */ + //% shim=micro_bit::serialReadDisplayState + export function readScreen(): void { } + + /** + * Writes a ``name: value`` pair line to the serial. + * @param name name of the value stream, eg: x + * @param value to write + */ + //% weight=80 + //% blockId=serial_writevalue block="serial|write %name|= %value" + export function writeValue(name: string, value: number): void { + writeString(name); + writeString(": "); + writeNumber(value); + writeLine(""); + } +} diff --git a/libs/microbit-serial/yelm.json b/libs/microbit-serial/yelm.json new file mode 100644 index 00000000..2e020ace --- /dev/null +++ b/libs/microbit-serial/yelm.json @@ -0,0 +1,13 @@ +{ + "name": "microbit-serial", + "description": "The serial services", + "files": [ + "README.md", + "serial.ts" + ], + "public": true, + "dependencies": { + "microbit": "file:../microbit" + }, + "installedVersion": "vykmvx" +} diff --git a/libs/microbit/README.md b/libs/microbit/README.md new file mode 100644 index 00000000..3abad658 --- /dev/null +++ b/libs/microbit/README.md @@ -0,0 +1,4 @@ +# core + +The core library. + diff --git a/libs/microbit/basic.ts b/libs/microbit/basic.ts new file mode 100644 index 00000000..f6393955 --- /dev/null +++ b/libs/microbit/basic.ts @@ -0,0 +1,83 @@ +/** + * Provides access to basic micro:bit functionality. + */ +//% color=190 weight=100 +namespace basic { + + /** + * Scroll a number on the screen. If the number fits on the screen (i.e. is a single digit), do not scroll. + * @param interval speed of scroll; eg: 150, 100, 200, -100 + */ + //% help=functions/show-number + //% weight=96 + //% shim=micro_bit::scrollNumber + //% blockId=device_show_number block="show|number %number" blockGap=8 icon="\uf1ec" + //% async + export function showNumber(value: number, interval: number = 150): void { } + + /** + * Draws an image on the LED screen. + * @param leds TODO + * @param interval TODO + */ + //% help=functions/show-leds + //% weight=95 blockGap=8 + //% shim=micro_bit::showLeds + //% imageLiteral=1 async + //% blockId=device_show_leds + //% block="show leds" icon="\uf00a" + export function showLeds(leds: string, interval: number = 400): void { } + + /** + * Display text on the display, one character at a time. If the string fits on the screen (i.e. is one letter), does not scroll. + * @param text the text to scroll on the screen, eg: "Hello!" + * @param interval how fast to shift characters; eg: 150, 100, 200, -100 + */ + //% help=functions/show-string + //% weight=87 blockGap=8 + //% shim=micro_bit::scrollString async + //% block="show|string %text" icon="\uf031" + //% async + //% blockId=device_print_message + export function showString(text: string, interval: number = 150): void { } + + /** + * Turn off all LEDs + */ + //% help=functions/clear-screen weight=79 + //% shim=micro_bit::clearScreen + //% blockId=device_clear_display block="clear screen" icon="\uf12d" + export function clearScreen(): void { } + + /** + * Shows a sequence of LED screens as an animation. + * @param leds TODO + * @param interval TODO + */ + //% help=functions/show-animation shim=micro_bit::showAnimation imageLiteral=1 async + export function showAnimation(leds: string, interval: number = 400): void { } + + /** + * Draws an image on the LED screen. + * @param leds TODO + */ + //% help=functions/plot-leds weight=80 shim=micro_bit::plotLeds imageLiteral=1 + export function plotLeds(leds: string): void { } + + /** + * Repeats the code forever in the background. On each iteration, allows other codes to run. + * @param body TODO + */ + //% help=functions/forever weight=55 blockGap=8 + //% blockId=device_forever block="forever" icon="\uf01e" shim=micro_bit::forever + export function forever(body: () => void): void { } + + /** + * Pause for the specified time in milliseconds + * @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000 + */ + //% help=functions/pause weight=54 + //% shim=micro_bit::pause async block="pause (ms) %pause" + //% blockId=device_pause icon="\uf110" + export function pause(ms: number): void { } +} diff --git a/libs/microbit/control.ts b/libs/microbit/control.ts new file mode 100644 index 00000000..02c04cd9 --- /dev/null +++ b/libs/microbit/control.ts @@ -0,0 +1,13 @@ +namespace control { + /** + * Schedules code that run in the background. + //% help=functions/in-background shim=micro_bit::runInBackground + */ + export function inBackground(body: Action): void { } + + /** + * Resets the BBC micro:bit. + */ + //% weight=1 shim=uBit.reset async help=functions/reset + export function reset() : void { } +} diff --git a/libs/microbit/core.d.ts b/libs/microbit/core.d.ts new file mode 100644 index 00000000..e81b586d --- /dev/null +++ b/libs/microbit/core.d.ts @@ -0,0 +1,236 @@ +/// + +interface Array { + /** + * Gets or sets the length of the array. This is a number one higher than the highest element defined in an array. + */ + //% shim=collection::count + length: number; + + /** + * Appends new elements to an array. + * @param items New elements of the Array. + */ + //% shim=collection::add + push(item: T): void; + + /** + * Removes the last element from an array and returns it. + */ + //% helper=arrayPop + pop(): T; + + /** + * Reverses the elements in an Array. + */ + //% helper=arrayReverse + reverse(): void; + + /** + * Removes the first element from an array and returns it. + */ + //% helper=arrayShift + shift(): T; + + /** + * Returns a section of an array. + * @param start The beginning of the specified portion of the array. + * @param end The end of the specified portion of the array. + */ + //% helper=arraySlice + slice(start: number, end: number): T[]; + + /** Removes the first occurence of an object. Returns true if removed. */ + //% shim=collection::remove + removeElement(element:T) : boolean; + + /** Removes the object at position index. */ + //% shim=collection::remove_at + removeAt(idx:number) : void; + + + /** + * Removes elements from an array. + * @param start The zero-based location in the array from which to start removing elements. + * @param deleteCount The number of elements to remove. + */ + //% helper=arraySplice + splice(start: number, deleteCount: number): void; + + /** + * Inserts new elements at the start of an array. + * @param items Elements to insert at the start of the Array. + */ + //% helper=arrayUnshift + unshift(item:T): void; + + /** + * Returns the index of the first occurrence of a value in an array. + * @param searchElement The value to locate in the array. + * @param fromIndex The array index at which to begin the search. If fromIndex is omitted, the search starts at index 0. + */ + //% shim=collection::index_of + indexOf(searchElement: T, fromIndex?: number): number; + + + [n: number]: T; +} + + +interface String { + + /** + * Returns the character at the specified index. + * @param pos The zero-based index of the desired character. + */ + //% shim=string::at + charAt(pos: number): string; + + /** + * Returns the Unicode value of the character at the specified location. + * @param index The zero-based index of the desired character. If there is no character at the specified index, NaN is returned. + */ + //% shim=string::code_at + charCodeAt(index: number): number; + + /** + * Returns a string that contains the concatenation of two or more strings. + * @param strings The strings to append to the end of the string. + */ + //% shim=string::concat + concat(other: string): string; + + /** + * Returns the position of the first occurrence of a substring. + * @param searchString The substring to search for in the string + * @param position The index at which to begin searching the String object. If omitted, search starts at the beginning of the string. + */ + indexOf(searchString: string, position?: number): number; + + /** + * Returns the last occurrence of a substring in the string. + * @param searchString The substring to search for. + * @param position The index at which to begin searching. If omitted, the search begins at the end of the string. + */ + lastIndexOf(searchString: string, position?: number): number; + + /** + * Determines whether two strings are equivalent in the current locale. + * @param that String to compare to target string + */ + localeCompare(that: string): number; + + /** + * Returns a section of a string. + * @param start The index to the beginning of the specified portion of stringObj. + * @param end The index to the end of the specified portion of stringObj. The substring includes the characters up to, but not including, the character indicated by end. + * If this value is not specified, the substring continues to the end of stringObj. + */ + slice(start?: number, end?: number): string; + + /** + * Returns the substring at the specified location within a String object. + * @param start The zero-based index number indicating the beginning of the substring. + * @param end Zero-based index number indicating the end of the substring. The substring includes the characters up to, but not including, the character indicated by end. + * If end is omitted, the characters from start through the end of the original string are returned. + */ + substring(start: number, end?: number): string; + + /** Converts all the alphabetic characters in a string to lowercase. */ + toLowerCase(): string; + + /** Converts all the alphabetic characters in a string to uppercase. */ + toUpperCase(): string; + + /** Returns the length of a String object. */ + //% shim=string::count + length: number; + + //% shim=string::at + [index: number]: string; +} + + +/** + * Converts A string to an integer. + * @param s A string to convert into a number. + */ + //% shim=string::to_number +declare function parseInt(s: string): number; + +interface Object {} +interface Function {} +interface IArguments {} +interface RegExp {} + +interface Boolean { + /** + * Returns a string representation of an object. + */ + //% shim=boolean::to_string + toString(): string; +} + +declare namespace String { + /** + * Make a string from the given ASCII character code. + */ + //% shim=number::to_character + export function fromCharCode(code:number): string; +} + +interface Number { + /** + * Returns a string representation of an object. + */ + //% shim=number::to_string + toString(): string; +} + +declare namespace Math { + /** + * Returns the absolute value of a number (the value without regard to whether it is positive or negative). + * For example, the absolute value of -5 is the same as the absolute value of 5. + * @param x A numeric expression for which the absolute value is needed. + */ + //% shim=math::abs + export function abs(x: number): number; + + /** + * Returns the sign of the x, indicating whether x is positive, negative or zero. + * @param x The numeric expression to test + */ + //% shim=math::sign + export function sign(x: number): number; + + /** + * Returns the larger of two supplied numeric expressions. + */ + //% shim=math::max + export function max(a:number, b:number): number; + + /** + * Returns the smaller of two supplied numeric expressions. + */ + //% shim=math::min + export function min(a:number, b:number): number; + + /** + * Returns the value of a base expression taken to a specified power. + * @param x The base value of the expression. + * @param y The exponent value of the expression. + */ + //% shim=math::pow + export function pow(x: number, y: number): number; + + /** Returns a pseudorandom number between 0 and `max`. */ + //% shim=math::random + export function random(max:number): number; + + /** + * Returns the square root of a number. + * @param x A numeric expression. + */ + //% shim=math::sqrt + export function sqrt(x: number): number; +} diff --git a/libs/microbit/images.ts b/libs/microbit/images.ts new file mode 100644 index 00000000..62a01d47 --- /dev/null +++ b/libs/microbit/images.ts @@ -0,0 +1,50 @@ +//% color=45 weight=31 +namespace images { + /** + * Creates an image that fits on the LED screen. + */ + //% weight=75 + //% blockId=device_build_image block="create image" imageLiteral=1 + export function createImage(leds: string): Image { + return null; + } + + /** + * Creates an image with 2 frames. + */ + //% weight=74 + //% blockId=device_build_big_image block="create big image" imageLiteral=2 + export function createBigImage(leds: string): Image { + return null; + } + + export class Image { + /** + * Shows an frame from the image at offset ``x offset``. + * @param xOffset TODO + */ + //% help=functions/show-image weight=80 shim=micro_bit::showImage + //% blockId=device_show_image_offset block="show image %sprite|at offset %offset" blockGap=8 + public showImage(xOffset: number): void {} + + /** + * Scrolls an image . + * @param frameOffset x offset moved on each animation step, eg: 5, 1, -1 + * @param interval time between each animation step in milli seconds, eg: 200 + */ + //% help=functions/show-image weight=79 shim=micro_bit::showImage async + //% blockId=device_scroll_image block="scroll image %sprite|with offset %frameoffset|and interval (ms) %delay" blockGap=8 + public scrollImage(frameOffset: number, interval : number = 200) { + } + + public plotImage(xOffset: number): void {} + + public clear(): void {} + + public setPixelBrightness(x: number, y: number, v: number): void {} + + public pixelBrightness(x: number, y: number): number { + return 0; + } + } +} \ No newline at end of file diff --git a/libs/microbit/input.ts b/libs/microbit/input.ts new file mode 100644 index 00000000..b6b6b335 --- /dev/null +++ b/libs/microbit/input.ts @@ -0,0 +1,226 @@ +enum Button { + //% enumval=MICROBIT_ID_BUTTON_A + A, + //% enumval=MICROBIT_ID_BUTTON_B + B, + //% enumval=MICROBIT_ID_BUTTON_AB + //% blockId="A+B" + AB, +} + +enum Dimension { + //% enumval=0 blockId=x + X, + //% enumval=1 blockId=y + Y, + //% enumval=2 blockId=z + Z, + //% enumval=3 blockId=strength + Strength, +} + +enum Rotation { + //% enumval=0 blockId=pitch + Pitch, + //% enumval=1 blockId=roll + Roll, +} + +enum TouchPins { + //% enumval=uBit.io.P0 + P0, + //% enumval=uBit.io.P1 + P1, + //% enumval=uBit.io.P2 + P2, +} + +enum Gestures { + //% blockId=shake enumval=MICROBIT_ACCELEROMETER_EVT_SHAKE + Shake, + //% blockId="logo up" enumval=MICROBIT_ACCELEROMETER_EVT_TILT_UP + LogoUp, + //% blockId="logo down" enumval=MICROBIT_ACCELEROMETER_EVT_TILT_DOWN + LogoDown, + //% blockId="screen up" enumval=MICROBIT_ACCELEROMETER_EVT_FACE_UP + ScreenUp, + //% blockId="screen down" enumval=MICROBIT_ACCELEROMETER_EVT_FACE_DOWN + ScreenDown +} + +//% color=300 weight=99 +namespace input { + /** + * Do something when a button (``A``, ``B`` or both ``A+B``) is pressed + * @param button TODO + * @param body TODO + */ + //% help=functions/on-button-pressed weight=85 + //% shim=micro_bit::onButtonPressed + //% blockId=device_button_event + //% block="on button|%NAME|pressed" + //% icon="\uf192" + export function onButtonPressed(button: Button, body: Action): void { } + + /** + * Attaches code to run when the screen is facing up. + * @param body TODO + */ + //% help=functions/on-gesture shim=micro_bit::on_event weight=84 + //% blockId=device_gesture_event block="on |%NAME" icon="\uf135" + export function onGesture(gesture: Gestures, body: Action): void { } + + /** + * Do something when a pin(``P0``, ``P1`` or both ``P2``) is pressed. + * @param name TODO + * @param body TODO + */ + //% help=functions/on-pin-pressed weight=83 shim=micro_bit::onPinPressed + //% blockId=device_pin_event block="on pin|%NAME|pressed" icon="\uf094" + export function onPinPressed(name: TouchPins, body: Action): void { } + + /** + * Get the button state (pressed or not) for ``A`` and ``B``. + */ + //% help=functions/button-is-pressed weight=57 + //% shim=micro_bit::isButtonPressed + //% block="button|%NAME|is pressed" + //% blockId=device_get_button2 + //% icon="\uf192" blockGap=8 + export function buttonIsPressed(button: Button): boolean { + return false; + } + + + /** + * Get the current compass compass heading in degrees. + */ + //% help=functions/compass-heading + //% weight=56 icon="\uf14e" + //% shim=micro_bit::compassHeading + //% blockId=device_heading block="compass heading (°)" blockGap=8 + export function compassHeading(): number { + return 0; + } + + + /** + * Gets the temperature in Celsius degrees (°C). + */ + //% weight=55 icon="\uf06d" + //% help=functions/temperature shim=uBit.thermometer.getTemperature + //% blockId=device_temperature block="temperature (°C)" blockGap=8 + export function temperature(): number { + return 0; + } + + /** + * Get the acceleration value in milli-gravitys (when the board is laying flat with the screen up, x=0, y=0 and z=-1024) + * @param dimension TODO + */ + //% help=functions/acceleration weight=54 icon="\uf135" + //% shim=micro_bit::getAcceleration + //% blockId=device_acceleration block="acceleration (mg)|%NAME" blockGap=8 + export function acceleration(dimension: Dimension): number { + return 0; + } + + + /** + * Reads the light level applied to the LED screen in a range from ``0`` (dark) to ``255`` bright. In the simulator, the ``acceleration y`` is used to emulate this value. + */ + //% help=functions/light-level weight=53 shim=micro_bit::lightLevel + //% blockId=device_get_light_level block="light level" blockGap=8 icon="\uf185" + export function lightLevel(): number { + return 0; + } + + /** + * The pitch of the device, rotation along the ``x-axis``, in degrees. + * @param kind TODO + */ + //% help=/functions/rotation weight=52 shim=micro_bit::getRotation + //% blockId=device_get_rotation block="rotation (°)|%NAME" blockGap=8 icon="\uf197" + export function rotation(kind: Rotation): number { + return 0; + } + + /** + * Get the magnetic force value in ``micro-Teslas`` (``µT``). This function is not supported in the simulator. + * @param dimension TODO + */ + //% help=functions/magnetic-force weight=51 shim=micro_bit::getMagneticForce + //% blockId=device_get_magnetic_force block="magnetic force (µT)|%NAME" blockGap=8 icon="\uf076" + export function magneticForce(dimension: Dimension): number { + return 0; + } + + /** + * Gets the number of milliseconds elapsed since power on. + */ + //% help=functions/running-time shim=micro_bit::getCurrentTime weight=50 + //% blockId=device_get_running_time block="running time (ms)" blockGap=8 icon="\uf017" + export function runningTime(): number { + return 0; + } + + /** + * Obsolete, compass calibration is automatic. + */ + //% help=functions/calibrate weight=0 shim=TD_NOOP + export function calibrate(): void { } + + /** + * Get the pin state (pressed or not). Requires to hold the ground to close the circuit. + * @param name TODO + */ + //% help=functions/pin-is-pressed weight=58 shim=micro_bit::isPinTouched block="pin|%NAME|is pressed" icon="\uf094" + export function pinIsPressed(name: TouchPins): boolean { + return false; + } + + /** + * Attaches code to run when the screen is facing up. + * @param body TODO + */ + //% help=functions/on-screen-up + export function onScreenUp(body: Action): void { + onGesture(Gestures.ScreenUp, body); + } + + /** + * Attaches code to run when the screen is facing down. + * @param body TODO + */ + //% help=functions/on-screen-down + export function onScreenDown(body: Action): void { + onGesture(Gestures.ScreenDown, body); + } + + /** + * Attaches code to run when the device is shaken. + * @param body TODO + */ + //% help=functions/on-shake + export function onShake(body: Action): void { + onGesture(Gestures.Shake, body); + } + + /** + * Attaches code to run when the logo is oriented upwards and the board is vertical. + * @param body TODO + */ + //% help=functions/on-logo-up + export function onLogoUp(body: Action): void { + onGesture(Gestures.LogoUp, body); + } + + /** + * Attaches code to run when the logo is oriented downwards and the board is vertical. + * @param body TODO + */ + //% help=functions/on-logo-down + export function onLogoDown(body: Action): void { + onGesture(Gestures.LogoDown, body); + } +} diff --git a/libs/microbit/mbit.ts b/libs/microbit/mbit.ts new file mode 100644 index 00000000..52f6b1c9 --- /dev/null +++ b/libs/microbit/mbit.ts @@ -0,0 +1,28 @@ +type Action = () => void; + +namespace helpers { + export function arraySplice(arr: T[], start: number, len: number) { + if (start < 0) { + return; + } + for (let i = 0; i < len; ++i) { + arr.removeAt(start) + } + } +} + +namespace console { + export function log(msg: string) { + writeString(msg); + writeString("\r\n"); + } + + //% shim=micro_bit::serialSendString + function writeString(text: string): void { } +} + +namespace math { + export function clamp(min: number, max:number, value:number): number { + return Math.min(max, Math.max(min, value)); + } +} diff --git a/libs/microbit/yelm.json b/libs/microbit/yelm.json new file mode 100644 index 00000000..c7e4c9a7 --- /dev/null +++ b/libs/microbit/yelm.json @@ -0,0 +1,76 @@ +{ + "name": "microbit", + "description": "The microbit core library", + "installedVersion": "xdvxev", + "files": [ + "README.md", + "core.d.ts", + "mbit.ts", + "images.ts", + "basic.ts", + "input.ts", + "control.ts" + ], + "public": true, + "dependencies": {}, + "target": { + "id": "microbit", + "name": "microbit", + "cloud": true, + "blocksprj": { + "id": "blocksprj", + "config": { + "name": "{0} block", + "dependencies": { + "microbit": "*", + "microbit-led": "*", + "microbit-music": "*", + "microbit-radio": "*", + "microbit-game": "*", + "microbit-pins": "*", + "microbit-serial": "*" + }, + "description": "", + "files": [ + "main.blocks", + "main.blocks.ts", + "README.md" + ] + }, + "files": { + "main.blocks": "\n\n", + "main.blocks.ts": "\n", + "README.md": "Describe your project here!" + } + }, + "tsprj": { + "id": "tsprj", + "config": { + "name": "{0} bit", + "dependencies": { + "microbit": "*", + "microbit-led": "*", + "microbit-music": "*", + "microbit-radio": "*", + "microbit-game": "*", + "microbit-pins": "*", + "microbit-serial": "*" + }, + "description": "", + "files": [ + "main.ts", + "README.md" + ] + }, + "files": { + "main.ts": "basic.showString('Hi!')\n", + "README.md": "Describe your project here!" + } + }, + "koduvscode": true, + "compile": { + "isNative": false, + "hasHex": true + } + } +} \ No newline at end of file diff --git a/libs/tsconfig.json b/libs/tsconfig.json new file mode 100644 index 00000000..4a1a04d5 --- /dev/null +++ b/libs/tsconfig.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "target": "es5", + "noImplicitAny": true, + "noImplicitReturns": true, + "outDir": "../built", + "rootDir": ".", + "newLine": "LF", + "sourceMap": true + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000..b90b5cfe --- /dev/null +++ b/package.json @@ -0,0 +1,24 @@ +{ + "name": "kindscript-microbit", + "version": "0.0.0", + "private": true, + "description": "microbit target for KindScript", + "keywords": [ + "JavaScript", + "education", + "microbit" + ], + "repository": { + "type": "git", + "url": "git+https://github.com/Microsoft/kindscript-microbit.git" + }, + "author": "", + "license": "MIT", + "homepage": "https://github.com/Microsoft/kindscript-microbit#readme", + "files": [ + "README.md" + ], + "dependencies": { + "kindscript": "*" + } +}