Merge branch 'cpp'
This commit is contained in:
		@@ -1,7 +1,3 @@
 | 
			
		||||
//% shim=foo::bar
 | 
			
		||||
function test() {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
basic.plotLeds(`
 | 
			
		||||
# # . # #
 | 
			
		||||
. . # . .
 | 
			
		||||
@@ -10,4 +6,5 @@ basic.plotLeds(`
 | 
			
		||||
. # # # .
 | 
			
		||||
`);
 | 
			
		||||
basic.pause(300);
 | 
			
		||||
test();
 | 
			
		||||
basic.showString("Hello");
 | 
			
		||||
// foo.bar();
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,10 @@
 | 
			
		||||
#include "BitVM.h"
 | 
			
		||||
#include "MicroBitTouchDevelop.h"
 | 
			
		||||
 | 
			
		||||
namespace foo {
 | 
			
		||||
  GLUE void bar()
 | 
			
		||||
  //%
 | 
			
		||||
  void bar()
 | 
			
		||||
  {
 | 
			
		||||
    micro_bit::scrollNumber(108108, 50);
 | 
			
		||||
    touch_develop::micro_bit::scrollNumber(108108, 50);
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -6,6 +6,6 @@
 | 
			
		||||
    ],
 | 
			
		||||
    "public": true,
 | 
			
		||||
    "dependencies": {
 | 
			
		||||
        "core": "file:../microbit"
 | 
			
		||||
        "microbit": "file:../microbit"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,6 @@
 | 
			
		||||
#include "BitVM.h"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Provides access to basic micro:bit functionality.
 | 
			
		||||
 */
 | 
			
		||||
@@ -10,10 +13,19 @@ namespace basic {
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/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 { }
 | 
			
		||||
    void showNumber(int value, int interval = 150) { 
 | 
			
		||||
      if (interval < 0)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
      ManagedString t(value);
 | 
			
		||||
      if (value < 0 || value >= 10) {
 | 
			
		||||
        uBit.display.scroll(t, interval);
 | 
			
		||||
      } else {
 | 
			
		||||
        uBit.display.print(t.charAt(0), interval * 5);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Draws an image on the LED screen.
 | 
			
		||||
@@ -22,11 +34,12 @@ namespace basic {
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/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 { }
 | 
			
		||||
    void showLeds(ImageLiteral leds, int interval = 400) {
 | 
			
		||||
      uBit.display.print(MicroBitImage(getbytes(leds)), 0, 0, 0, interval);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 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.
 | 
			
		||||
@@ -35,19 +48,32 @@ namespace basic {
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/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 { }
 | 
			
		||||
    void showString(StringData *text, int interval = 150) {
 | 
			
		||||
      if (interval < 0)
 | 
			
		||||
        return;
 | 
			
		||||
      ManagedString s(text);
 | 
			
		||||
      int l = s.length();
 | 
			
		||||
      if (l == 0) {
 | 
			
		||||
        uBit.display.clear();
 | 
			
		||||
        uBit.sleep(interval * 5);
 | 
			
		||||
      } else if (l > 1) {
 | 
			
		||||
        uBit.display.scroll(s, interval);
 | 
			
		||||
      } else {
 | 
			
		||||
        uBit.display.print(s.charAt(0), interval * 5);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Turn off all LEDs
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/clear-screen weight=79
 | 
			
		||||
    //% shim=micro_bit::clearScreen
 | 
			
		||||
    //% blockId=device_clear_display block="clear screen" icon="\uf12d"
 | 
			
		||||
    export function clearScreen(): void { }
 | 
			
		||||
    void clearScreen() {
 | 
			
		||||
      uBit.display.image.clear();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Shows a sequence of LED screens as an animation.
 | 
			
		||||
@@ -55,29 +81,48 @@ namespace basic {
 | 
			
		||||
     * @param interval TODO
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/show-animation shim=micro_bit::showAnimation imageLiteral=1 async
 | 
			
		||||
    export function showAnimation(leds: string, interval: number = 400): void { }
 | 
			
		||||
    void showAnimation(ImageLiteral leds, int interval = 400) {
 | 
			
		||||
      uBit.display.animate(MicroBitImage(getbytes(leds)), interval, 5, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Draws an image on the LED screen.
 | 
			
		||||
     * @param leds TODO
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/plot-leds weight=80 shim=micro_bit::plotLeds imageLiteral=1
 | 
			
		||||
    export function plotLeds(leds: string): void { }
 | 
			
		||||
    //% help=basic/plot-leds weight=80 shim=micro_bit::plotLeds
 | 
			
		||||
    void plotLeds(ImageLiteral leds) {
 | 
			
		||||
      MicroBitImage i(getbytes(leds));
 | 
			
		||||
      uBit.display.print(i, 0, 0, 0, 0);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void forever_stub(void *a) {
 | 
			
		||||
      while (true) {
 | 
			
		||||
        action::run((Action)a);
 | 
			
		||||
        uBit.sleep(20);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Repeats the code forever in the background. On each iteration, allows other codes to run.
 | 
			
		||||
     * @param body TODO
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/forever weight=55 blockGap=8
 | 
			
		||||
    //% blockId=device_forever block="forever" icon="\uf01e" shim=micro_bit::forever
 | 
			
		||||
    export function forever(body: () => void): void { }
 | 
			
		||||
    //% blockId=device_forever block="forever" icon="\uf01e"
 | 
			
		||||
    void forever(Action a) {
 | 
			
		||||
      if (a != 0) {
 | 
			
		||||
        incr(a);
 | 
			
		||||
        create_fiber(forever_stub, (void*)a);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Pause for the specified time in milliseconds
 | 
			
		||||
     * @param ms how long to pause for, eg: 100, 200, 500, 1000, 2000
 | 
			
		||||
     */
 | 
			
		||||
    //% help=basic/pause weight=54
 | 
			
		||||
    //% shim=micro_bit::pause async block="pause (ms) %pause"
 | 
			
		||||
    //% async block="pause (ms) %pause"
 | 
			
		||||
    //% blockId=device_pause icon="\uf110"
 | 
			
		||||
    export function pause(ms: number): void { }
 | 
			
		||||
    void pause(int ms) {
 | 
			
		||||
      uBit.sleep(ms);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										30
									
								
								libs/microbit/control.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								libs/microbit/control.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,30 @@
 | 
			
		||||
#include "BitVM.h"
 | 
			
		||||
 | 
			
		||||
namespace control {
 | 
			
		||||
    void fiberDone(void *a)
 | 
			
		||||
    {
 | 
			
		||||
      decr((Action)a);
 | 
			
		||||
      release_fiber();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Schedules code that run in the background.
 | 
			
		||||
     */
 | 
			
		||||
    //% help=control/in-background
 | 
			
		||||
    //% blockId="control_in_background" block="run in background" blockGap=8
 | 
			
		||||
    void inBackground(Action a) {
 | 
			
		||||
      if (a != 0) {
 | 
			
		||||
        incr(a);
 | 
			
		||||
        create_fiber((void(*)(void*))action::run, (void*)a, fiberDone);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Resets the BBC micro:bit.
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=30 async help=control/reset
 | 
			
		||||
    //% blockId="control_reset" block="reset"
 | 
			
		||||
    void reset() { 
 | 
			
		||||
      uBit.reset(); 
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@@ -192,25 +192,27 @@ enum EventBusValue {
 | 
			
		||||
 | 
			
		||||
//% weight=1 color="#333333"
 | 
			
		||||
namespace control {
 | 
			
		||||
    /**
 | 
			
		||||
     * Schedules code that run in the background.
 | 
			
		||||
     */
 | 
			
		||||
    //% help=control/in-background shim=micro_bit::runInBackground
 | 
			
		||||
    //% blockId="control_in_background" block="run in background" blockGap=8
 | 
			
		||||
    export function inBackground(body: Action): void { }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Resets the BBC micro:bit.
 | 
			
		||||
     * Returns the value of a C++ runtime constant
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=30 shim=uBit.reset async help=control/reset
 | 
			
		||||
    //% blockId="control_reset" block="reset"
 | 
			
		||||
    export function reset(): void { }
 | 
			
		||||
    //% weight=19 weight=19 blockId="control_event_source" block="%id"
 | 
			
		||||
    export function eventSource(id: EventBusSource) : number {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the value of a C++ runtime constant
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=19 weight=19 blockId="control_event_value" block="%id"
 | 
			
		||||
    export function eventValue(id: EventBusValue) : number {
 | 
			
		||||
        return id;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Raises an event in the event bus.
 | 
			
		||||
     @param src ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.
 | 
			
		||||
     @param value Component specific code indicating the cause of the event.
 | 
			
		||||
     @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_QUEUE).
 | 
			
		||||
     * @param src ID of the MicroBit Component that generated the event e.g. MICROBIT_ID_BUTTON_A.
 | 
			
		||||
     * @param value Component specific code indicating the cause of the event.
 | 
			
		||||
     * @param mode optional definition of how the event should be processed after construction (default is CREATE_AND_QUEUE).
 | 
			
		||||
     */
 | 
			
		||||
    // shim=micro_bit::busRaiseEvent
 | 
			
		||||
    //% weight=21 blockGap=12 blockId="control_raise_event" block="raise event|from source %src=control_event_source|with value %value=control_event_value" blockExternalInputs=1
 | 
			
		||||
@@ -223,19 +225,4 @@ namespace control {
 | 
			
		||||
    //% weight=20 blockGap=8 blockId="control_on_event" block="on event|from %src=control_event_source|with value %value=control_event_value" 
 | 
			
		||||
    //% blockExternalInputs=1 blockStatement=1
 | 
			
		||||
    export function onEvent(src: number, value: number, handler: Action): void { }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the value of a C++ runtime constant
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=19 shimw=TD_ID weight=19 blockId="control_event_source" block="%id"
 | 
			
		||||
    export function eventSource(id: EventBusSource) : number {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
    /**
 | 
			
		||||
     * Returns the value of a C++ runtime constant
 | 
			
		||||
     */
 | 
			
		||||
    //% weight=19 shimw=TD_ID weight=19 blockId="control_event_value" block="%id"
 | 
			
		||||
    export function eventValue(id: EventBusValue) : number {
 | 
			
		||||
        return 0;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,9 +7,10 @@
 | 
			
		||||
        "core.d.ts",
 | 
			
		||||
        "mbit.ts",
 | 
			
		||||
        "images.ts",
 | 
			
		||||
        "basic.ts",
 | 
			
		||||
        "basic.cpp",
 | 
			
		||||
        "input.ts",
 | 
			
		||||
        "control.ts",
 | 
			
		||||
        "control.cpp",
 | 
			
		||||
        "game.ts",
 | 
			
		||||
        "led.ts",
 | 
			
		||||
        "music.ts",
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										201
									
								
								sim/libmbit.ts
									
									
									
									
									
								
							
							
						
						
									
										201
									
								
								sim/libmbit.ts
									
									
									
									
									
								
							@@ -88,78 +88,6 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
        throw new Error("PANIC " + code)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* basic */
 | 
			
		||||
    export function showDigit(v: number) {
 | 
			
		||||
        if (!quiet)
 | 
			
		||||
            console.log("DIGIT:", v)
 | 
			
		||||
        plotLeds(createImageFromString(v.toString()[0]));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function clearScreen() {
 | 
			
		||||
        board().image.clear();
 | 
			
		||||
        runtime.queueDisplayUpdate()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function showLeds(leds: micro_bit.Image, delay: number): void {
 | 
			
		||||
        showAnimation(leds, delay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function scrollImage(leds: micro_bit.Image, interval: number, stride: number): void {
 | 
			
		||||
        let cb = getResume()
 | 
			
		||||
        let off = stride > 0 ? 0 : leds.width - 1;
 | 
			
		||||
        let display = board().image;
 | 
			
		||||
 | 
			
		||||
        board().animationQ.enqueue({
 | 
			
		||||
            interval: interval,
 | 
			
		||||
            frame: () => {
 | 
			
		||||
                if (off >= leds.width || off < 0) return false;
 | 
			
		||||
                stride > 0 ? display.shiftLeft(stride) : display.shiftRight(-stride);
 | 
			
		||||
                let c = Math.min(stride, leds.width - off);
 | 
			
		||||
                leds.copyTo(off, c, display, 5 - stride)
 | 
			
		||||
                off += stride;
 | 
			
		||||
                return true;
 | 
			
		||||
            },
 | 
			
		||||
            whenDone: cb
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function showAnimation(leds: micro_bit.Image, interval: number = 400): void {
 | 
			
		||||
        scrollImage(leds, interval, 5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function scrollNumber(x: number, interval: number) {
 | 
			
		||||
        if (interval < 0) return;
 | 
			
		||||
 | 
			
		||||
        let leds = createImageFromString(x.toString());
 | 
			
		||||
        if (x < 0 || x >= 10) scrollImage(leds, interval, 1);
 | 
			
		||||
        else showLeds(leds, interval * 5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function scrollString(s: string, interval: number) {
 | 
			
		||||
        if (interval < 0) return;
 | 
			
		||||
        if (s.length == 0) {
 | 
			
		||||
            clearScreen();
 | 
			
		||||
            pause(interval * 5);
 | 
			
		||||
        } else {
 | 
			
		||||
            let leds = createImageFromString(s);
 | 
			
		||||
            if (s.length == 1) showLeds(leds, interval * 5)
 | 
			
		||||
            else scrollImage(leds, interval, 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function forever(a: RefAction) {
 | 
			
		||||
        function loop() {
 | 
			
		||||
            runtime.runFiberAsync(a)
 | 
			
		||||
                .then(() => Promise.delay(20))
 | 
			
		||||
                .then(loop)
 | 
			
		||||
                .done()
 | 
			
		||||
        }
 | 
			
		||||
        incr(a)
 | 
			
		||||
        loop()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export var pause = thread.pause;
 | 
			
		||||
 | 
			
		||||
    /* leds */
 | 
			
		||||
    export function plot(x: number, y: number) {
 | 
			
		||||
        board().image.set(x, y, 255);
 | 
			
		||||
@@ -198,20 +126,17 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
        runtime.queueDisplayUpdate()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* control */
 | 
			
		||||
    export var runInBackground = thread.runInBackground;
 | 
			
		||||
 | 
			
		||||
    /* serial */
 | 
			
		||||
    export function serialSendString(s: string) {
 | 
			
		||||
        board().writeSerial(s);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function serialReadString() : string {
 | 
			
		||||
    export function serialReadString(): string {
 | 
			
		||||
        return board().readSerial();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* input */
 | 
			
		||||
    export function onButtonPressed(button : number, handler: RefAction) : void {
 | 
			
		||||
    export function onButtonPressed(button: number, handler: RefAction): void {
 | 
			
		||||
        let ens = enums();
 | 
			
		||||
        let b = board();
 | 
			
		||||
        if (button == ens.MICROBIT_ID_BUTTON_AB && !board().usesButtonAB) {
 | 
			
		||||
@@ -305,7 +230,7 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function setAccelerometerRange(range : number) {
 | 
			
		||||
    export function setAccelerometerRange(range: number) {
 | 
			
		||||
        let b = board();
 | 
			
		||||
        b.accelerometer.setSampleRange(range);
 | 
			
		||||
    }
 | 
			
		||||
@@ -329,29 +254,29 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* pins */
 | 
			
		||||
    export function digitalReadPin(pin : Pin) : number {
 | 
			
		||||
    export function digitalReadPin(pin: Pin): number {
 | 
			
		||||
        pin.mode = PinMode.Digital | PinMode.Input;
 | 
			
		||||
        return pin.value > 100 ? 1 : 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function digitalWritePin(pin : Pin, value: number) {
 | 
			
		||||
    export function digitalWritePin(pin: Pin, value: number) {
 | 
			
		||||
        pin.mode = PinMode.Digital | PinMode.Output;
 | 
			
		||||
        pin.value = value > 0 ? 1023 : 0;
 | 
			
		||||
        runtime.queueDisplayUpdate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function analogReadPin(pin : Pin) : number {
 | 
			
		||||
    export function analogReadPin(pin: Pin): number {
 | 
			
		||||
        pin.mode = PinMode.Analog | PinMode.Input;
 | 
			
		||||
        return pin.value || 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function analogWritePin(pin : Pin, value: number) {
 | 
			
		||||
    export function analogWritePin(pin: Pin, value: number) {
 | 
			
		||||
        pin.mode = PinMode.Analog | PinMode.Output;
 | 
			
		||||
        pin.value = value ? 1 : 0;
 | 
			
		||||
        runtime.queueDisplayUpdate();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function setAnalogPeriodUs(pin: Pin, micros:number) {
 | 
			
		||||
    export function setAnalogPeriodUs(pin: Pin, micros: number) {
 | 
			
		||||
        pin.mode = PinMode.Analog | PinMode.Output;
 | 
			
		||||
        pin.period = micros;
 | 
			
		||||
        runtime.queueDisplayUpdate();
 | 
			
		||||
@@ -362,27 +287,27 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
        // TODO
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function servoSetPulse(pin: Pin, micros:number) {        
 | 
			
		||||
    export function servoSetPulse(pin: Pin, micros: number) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    module AudioContextManager {
 | 
			
		||||
        var _context : any; // AudioContext
 | 
			
		||||
        var _vco : any; //OscillatorNode;
 | 
			
		||||
        var _context: any; // AudioContext
 | 
			
		||||
        var _vco: any; //OscillatorNode;
 | 
			
		||||
        var _vca: any; // GainNode;
 | 
			
		||||
 | 
			
		||||
        function context() : any {
 | 
			
		||||
        function context(): any {
 | 
			
		||||
            if (!_context) _context = freshContext();
 | 
			
		||||
            return _context;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        function freshContext() : any {
 | 
			
		||||
        function freshContext(): any {
 | 
			
		||||
            (<any>window).AudioContext = (<any>window).AudioContext || (<any>window).webkitAudioContext;
 | 
			
		||||
            if ((<any>window).AudioContext) {
 | 
			
		||||
                try {
 | 
			
		||||
                    // this call my crash.
 | 
			
		||||
                    // SyntaxError: audio resources unavailable for AudioContext construction
 | 
			
		||||
                    return new (<any>window).AudioContext();
 | 
			
		||||
                } catch(e) {}
 | 
			
		||||
                } catch (e) { }
 | 
			
		||||
            }
 | 
			
		||||
            return undefined;
 | 
			
		||||
        }
 | 
			
		||||
@@ -405,7 +330,7 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
                    _vca.connect(ctx.destination);
 | 
			
		||||
                    _vca.gain.value = gain;
 | 
			
		||||
                    _vco.start(0);
 | 
			
		||||
                } catch(e) {
 | 
			
		||||
                } catch (e) {
 | 
			
		||||
                    _vco = undefined;
 | 
			
		||||
                    _vca = undefined;
 | 
			
		||||
                    return;
 | 
			
		||||
@@ -431,7 +356,7 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
            pin.period = 0;
 | 
			
		||||
        } else {
 | 
			
		||||
            pin.value = 512;
 | 
			
		||||
            pin.period = 1000000/frequency;        
 | 
			
		||||
            pin.period = 1000000 / frequency;
 | 
			
		||||
        }
 | 
			
		||||
        runtime.queueDisplayUpdate();
 | 
			
		||||
 | 
			
		||||
@@ -452,42 +377,118 @@ namespace ks.rt.micro_bit {
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /* radio */
 | 
			
		||||
    export function broadcastMessage(msg: number) : void {
 | 
			
		||||
    export function broadcastMessage(msg: number): void {
 | 
			
		||||
        board().radio.broadcast(msg);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function onBroadcastMessageReceived(msg: number, handler: RefAction) : void {
 | 
			
		||||
    export function onBroadcastMessageReceived(msg: number, handler: RefAction): void {
 | 
			
		||||
        let ens = enums()
 | 
			
		||||
        board().bus.listen(ens.MES_BROADCAST_GENERAL_ID, msg, handler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function setGroup(id : number) : void {
 | 
			
		||||
    export function setGroup(id: number): void {
 | 
			
		||||
        board().radio.setGroup(id);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function setTransmitPower(power: number) : void {
 | 
			
		||||
    export function setTransmitPower(power: number): void {
 | 
			
		||||
        board().radio.setTransmitPower(power);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function datagramSendNumbers(value0 : number, value1: number, value2: number, value3: number) : void {
 | 
			
		||||
    export function datagramSendNumbers(value0: number, value1: number, value2: number, value3: number): void {
 | 
			
		||||
        board().radio.datagram.send([value0, value1, value2, value3]);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function datagramReceiveNumber() : number {
 | 
			
		||||
    export function datagramReceiveNumber(): number {
 | 
			
		||||
        return board().radio.datagram.recv().data[0];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function datagramGetNumber(index : number) : number {
 | 
			
		||||
    export function datagramGetNumber(index: number): number {
 | 
			
		||||
        return board().radio.datagram.lastReceived.data[index] || 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function datagramGetRSSI() : number {
 | 
			
		||||
    export function datagramGetRSSI(): number {
 | 
			
		||||
        return board().radio.datagram.lastReceived.rssi;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function onDatagramReceived(handler: RefAction) : void {
 | 
			
		||||
    export function onDatagramReceived(handler: RefAction): void {
 | 
			
		||||
        let ens = enums();
 | 
			
		||||
        board().bus.listen(ens.MICROBIT_ID_RADIO, ens.MICROBIT_RADIO_EVT_DATAGRAM, handler);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace ks.rt.basic {
 | 
			
		||||
    var board = micro_bit.board;
 | 
			
		||||
 | 
			
		||||
    export var pause = thread.pause;
 | 
			
		||||
 | 
			
		||||
    export function showNumber(x: number, interval: number) {
 | 
			
		||||
        if (interval < 0) return;
 | 
			
		||||
 | 
			
		||||
        let leds = micro_bit.createImageFromString(x.toString());
 | 
			
		||||
        if (x < 0 || x >= 10) scrollImage(leds, interval, 1);
 | 
			
		||||
        else showLeds(leds, interval * 5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function showString(s: string, interval: number) {
 | 
			
		||||
        if (interval < 0) return;
 | 
			
		||||
        if (s.length == 0) {
 | 
			
		||||
            clearScreen();
 | 
			
		||||
            pause(interval * 5);
 | 
			
		||||
        } else {
 | 
			
		||||
            let leds = micro_bit.createImageFromString(s);
 | 
			
		||||
            if (s.length == 1) showLeds(leds, interval * 5)
 | 
			
		||||
            else scrollImage(leds, interval, 1);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function showLeds(leds: micro_bit.Image, delay: number): void {
 | 
			
		||||
        showAnimation(leds, delay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function clearScreen() {
 | 
			
		||||
        board().image.clear();
 | 
			
		||||
        runtime.queueDisplayUpdate()
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function scrollImage(leds: micro_bit.Image, interval: number, stride: number): void {
 | 
			
		||||
        let cb = getResume()
 | 
			
		||||
        let off = stride > 0 ? 0 : leds.width - 1;
 | 
			
		||||
        let display = board().image;
 | 
			
		||||
 | 
			
		||||
        board().animationQ.enqueue({
 | 
			
		||||
            interval: interval,
 | 
			
		||||
            frame: () => {
 | 
			
		||||
                if (off >= leds.width || off < 0) return false;
 | 
			
		||||
                stride > 0 ? display.shiftLeft(stride) : display.shiftRight(-stride);
 | 
			
		||||
                let c = Math.min(stride, leds.width - off);
 | 
			
		||||
                leds.copyTo(off, c, display, 5 - stride)
 | 
			
		||||
                off += stride;
 | 
			
		||||
                return true;
 | 
			
		||||
            },
 | 
			
		||||
            whenDone: cb
 | 
			
		||||
        })
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function showAnimation(leds: micro_bit.Image, interval: number = 400): void {
 | 
			
		||||
        scrollImage(leds, interval, 5);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    export function forever(a: RefAction) {
 | 
			
		||||
        function loop() {
 | 
			
		||||
            runtime.runFiberAsync(a)
 | 
			
		||||
                .then(() => Promise.delay(20))
 | 
			
		||||
                .then(loop)
 | 
			
		||||
                .done()
 | 
			
		||||
        }
 | 
			
		||||
        incr(a)
 | 
			
		||||
        loop()
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
namespace ks.rt.control {
 | 
			
		||||
    export var inBackground = thread.runInBackground;
 | 
			
		||||
 | 
			
		||||
    export function reset() {
 | 
			
		||||
        U.userError("reset not implemented in simulator yet")
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user