V4 updates for beta testing (#147)
* change simulator svg
* change radio image
* Remove google fonts cdn
* change color of 'advanced' button
* font fix
* font fix 2
* display fix
* change fullsceen simulator bg
* Continuous servo
* handle continuous state
* adding shims
* update rendering for continuous servos
* fixing sim
* fix sig
* typo
* fix sim
* bump pxt
* bump pxt
* rerun travis
* Input blocks revision
- add Button and Pin event types
- merge onPinPressed & onPinReleased in new onPinEvent function
- create new onButtonEvent function
* update input blocks in docs and tests
* remove device_pin_release block
* Hide DAL.x behind Enum
* bring back deprecated blocks, but hide them
* shims and locales files
* fix input.input. typing
* remove buildpr
* bump V3
* update simulator aspect ratio
* add Loudness Block
* revoke loudness block
* Adds soundLevel
To be replaced by pxt-common-packages when DAL is updated.
* Remove P0 & P3 from AnalogPin
* Fix Sound and replace AnalogPin.P0
* remove approved extensions
* V4 Updates from remote Repo
* locales
* add storage functions
* fix storage functions
* fix int/float values
* decrease decimal precision
* reorder blocks
* Update BLE Settings and Storage Blocks
* Fetch MicroBit changes up to v4.0.18
* Update timing for LED Matrix usage
* use 32kb ram (mini v2)
* resize gatt table
* Revert "use 32kb ram (mini v2)"
This reverts commit 4b15592f0f
.
* fix missleading indentation
* add support for 32kb and 16kb ram
* only MIT extensions in preferredRepos
* remove extensions without MIT License file
* add updated extensions
* add extensions with MIT license
Co-authored-by: Juri <gitkraken@juriwolf.de>
Co-authored-by: Juri <info@juriwolf.de>
This commit is contained in:
@ -1,4 +1,14 @@
|
||||
namespace pxsim.input {
|
||||
export function onButtonEvent(button: number, buttonEvent: number, handler: RefAction): void {
|
||||
let b = board().buttonPairState;
|
||||
if (button == b.props.ID_BUTTON_AB && !b.usesButtonAB) {
|
||||
b.usesButtonAB = true;
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
pxtcore.registerWithDal(button, buttonEvent, handler);
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
export function onButtonPressed(button: number, handler: RefAction): void {
|
||||
let b = board().buttonPairState;
|
||||
if (button == b.props.ID_BUTTON_AB && !b.usesButtonAB) {
|
||||
|
@ -8,8 +8,22 @@ namespace pxsim.input {
|
||||
return b.heading;
|
||||
}
|
||||
|
||||
export function assumeCalibrationCompass(){
|
||||
}
|
||||
|
||||
export function clearCalibrationCompass(){
|
||||
}
|
||||
|
||||
export function isCalibratedCompass(): boolean {
|
||||
// let b = board().compassState;
|
||||
// return b.isCalibrated;
|
||||
// TODO
|
||||
return true;
|
||||
}
|
||||
|
||||
export function magneticForce(): number {
|
||||
// TODO
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
@ -1,17 +1,27 @@
|
||||
namespace pxsim.input {
|
||||
export function onPinTouchEvent(pinId: number, pinEvent: number, handler: RefAction) {
|
||||
let pin = getPin(pinId);
|
||||
if (!pin) return;
|
||||
pin.isTouched();
|
||||
runtime.queueDisplayUpdate();
|
||||
pxtcore.registerWithDal(pin.id, pinEvent, handler);
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
export function onPinPressed(pinId: number, handler: RefAction) {
|
||||
let pin = getPin(pinId);
|
||||
if (!pin) return;
|
||||
pin.isTouched();
|
||||
runtime.queueDisplayUpdate();
|
||||
runtime.queueDisplayUpdate();
|
||||
pxtcore.registerWithDal(pin.id, DAL.MICROBIT_BUTTON_EVT_CLICK, handler);
|
||||
}
|
||||
|
||||
// Deprecated
|
||||
export function onPinReleased(pinId: number, handler: RefAction) {
|
||||
let pin = getPin(pinId);
|
||||
if (!pin) return;
|
||||
pin.isTouched();
|
||||
runtime.queueDisplayUpdate();
|
||||
runtime.queueDisplayUpdate();
|
||||
pxtcore.registerWithDal(pin.id, DAL.MICROBIT_BUTTON_EVT_UP, handler);
|
||||
}
|
||||
|
||||
@ -95,51 +105,68 @@ namespace pxsim.pins {
|
||||
}
|
||||
|
||||
export function analogSetPitchPin(pinId: number) {
|
||||
const b = board();
|
||||
if (!b) return;
|
||||
let pin = getPin(pinId);
|
||||
if (!pin) return;
|
||||
board().edgeConnectorState.pins.filter(p => !!p).forEach(p => p.pitch = false);
|
||||
const ec = b.edgeConnectorState
|
||||
ec.pins.filter(p => !!p).forEach(p => p.pitch = false);
|
||||
pin.pitch = true;
|
||||
}
|
||||
|
||||
export function setSoundOutputPinEnabled(enabled: boolean) {
|
||||
const b = board();
|
||||
if (!b) return;
|
||||
const ec = b.edgeConnectorState
|
||||
ec.pitchEnabled = !enabled;
|
||||
}
|
||||
|
||||
export function analogSetPitchVolume(volume: number) {
|
||||
const ec = board().edgeConnectorState;
|
||||
ec.pitchVolume = Math.max(0, Math.min(0xff, volume | 0));
|
||||
AudioContextManager.setCurrentToneGain((ec.pitchVolume / 0xff) / 10);
|
||||
}
|
||||
|
||||
export function analogPitchVolume() {
|
||||
const ec = board().edgeConnectorState;
|
||||
return ec.pitchVolume;
|
||||
}
|
||||
|
||||
|
||||
export function analogPitch(frequency: number, ms: number) {
|
||||
// update analog output
|
||||
const b = board();
|
||||
if (!b) return;
|
||||
const ec = b.edgeConnectorState;
|
||||
const pins = ec.pins;
|
||||
const pin = pins.filter(pin => !!pin && pin.pitch)[0] || pins[0];
|
||||
const pin = ec.pitchEnabled && (pins.filter(pin => !!pin && pin.pitch)[0] || pins[0]);
|
||||
const pitchVolume = ec.pitchVolume | 0;
|
||||
pin.mode = PinFlags.Analog | PinFlags.Output;
|
||||
if (frequency <= 0 || pitchVolume <= 0) {
|
||||
pin.value = 0;
|
||||
pin.period = 0;
|
||||
} else {
|
||||
const v = 1 << (pitchVolume >> 5);
|
||||
pin.value = v;
|
||||
pin.period = 1000000 / frequency;
|
||||
if (pin) {
|
||||
pin.mode = PinFlags.Analog | PinFlags.Output;
|
||||
if (frequency <= 0 || pitchVolume <= 0) {
|
||||
pin.value = 0;
|
||||
pin.period = 0;
|
||||
} else {
|
||||
const v = 1 << (pitchVolume >> 5);
|
||||
pin.value = v;
|
||||
pin.period = 1000000 / frequency;
|
||||
}
|
||||
runtime.queueDisplayUpdate();
|
||||
}
|
||||
runtime.queueDisplayUpdate();
|
||||
|
||||
let cb = getResume();
|
||||
const v = pitchVolume / 0xff;
|
||||
AudioContextManager.tone(frequency, v);
|
||||
if (pin) {
|
||||
const v = pitchVolume / 0xff;
|
||||
AudioContextManager.tone(frequency, v / 10);
|
||||
}
|
||||
if (ms <= 0) cb();
|
||||
else {
|
||||
setTimeout(() => {
|
||||
AudioContextManager.stop();
|
||||
pin.value = 0;
|
||||
pin.period = 0;
|
||||
pin.mode = PinFlags.Unused;
|
||||
if (pin) {
|
||||
pin.value = 0;
|
||||
pin.period = 0;
|
||||
pin.mode = PinFlags.Unused;
|
||||
}
|
||||
runtime.queueDisplayUpdate();
|
||||
cb()
|
||||
}, ms);
|
||||
@ -152,4 +179,18 @@ namespace pxsim.pins {
|
||||
const ec = b.edgeConnectorState;
|
||||
// TODO support buttons here
|
||||
}
|
||||
}
|
||||
namespace pxsim.music {
|
||||
export function setVolume(volume: number): void {
|
||||
pxsim.pins.analogSetPitchVolume(volume);
|
||||
}
|
||||
export function volume(): number {
|
||||
return pxsim.pins.analogPitchVolume();
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.pins {
|
||||
export function setAudioPin(pinId: number) {
|
||||
pxsim.pins.analogSetPitchPin(pinId);
|
||||
}
|
||||
}
|
@ -87,6 +87,7 @@ namespace pxsim {
|
||||
export class EdgeConnectorState {
|
||||
pins: Pin[];
|
||||
pitchVolume: number;
|
||||
pitchEnabled = true;
|
||||
|
||||
constructor(public props: EdgeConnectorProps) {
|
||||
this.pins = props.pins.map(id => id != undefined ? new Pin(id) : null);
|
||||
|
28
sim/state/microphone.ts
Normal file
28
sim/state/microphone.ts
Normal file
@ -0,0 +1,28 @@
|
||||
// move to common packages eventually
|
||||
namespace pxsim.input {
|
||||
|
||||
export function soundLevel(): number {
|
||||
const b = microphoneState();
|
||||
if (!b) return 0;
|
||||
b.setUsed();
|
||||
return b.getLevel();
|
||||
}
|
||||
|
||||
export function onSound(sound: number /* SoundThreshold */, body: RefAction) {
|
||||
const b = microphoneState();
|
||||
if (!b) return;
|
||||
b.setUsed();
|
||||
pxtcore.registerWithDal(b.id, sound, body);
|
||||
}
|
||||
|
||||
export function setSoundThreshold(sound: number, threshold: number){
|
||||
const b = microphoneState();
|
||||
if (!b) return;
|
||||
b.setUsed();
|
||||
if (sound === 2 /* SoundThreshold.Loud */)
|
||||
b.setHighThreshold(threshold);
|
||||
else
|
||||
b.setLowThreshold(threshold);
|
||||
}
|
||||
|
||||
}
|
@ -35,46 +35,6 @@ namespace pxsim.basic {
|
||||
namespace pxsim.control {
|
||||
export var inBackground = thread.runInBackground;
|
||||
|
||||
export function createBuffer(sz: number) {
|
||||
return pxsim.BufferMethods.createBuffer(sz)
|
||||
}
|
||||
|
||||
export function reset() {
|
||||
const cb = getResume();
|
||||
pxsim.runtime.restart();
|
||||
}
|
||||
|
||||
export function waitMicros(micros: number) {
|
||||
// TODO
|
||||
}
|
||||
export function waitForEvent(id: number, evid: number) {
|
||||
const cb = getResume();
|
||||
board().bus.wait(id, evid, cb);
|
||||
}
|
||||
|
||||
export function millis(): number {
|
||||
return runtime.runningTime();
|
||||
}
|
||||
|
||||
export function micros(): number {
|
||||
return runtime.runningTimeUs();
|
||||
}
|
||||
|
||||
|
||||
export function deviceName(): string {
|
||||
let b = board();
|
||||
return b && b.id
|
||||
? b.id.slice(0, 4)
|
||||
: "abcd";
|
||||
}
|
||||
|
||||
export function deviceSerialNumber(): number {
|
||||
let b = board();
|
||||
return parseInt(b && b.id
|
||||
? b.id.slice(1)
|
||||
: "42");
|
||||
}
|
||||
|
||||
export function onEvent(id: number, evid: number, handler: RefAction) {
|
||||
if (id == DAL.MICROBIT_ID_BUTTON_AB) {
|
||||
const b = board().buttonPairState;
|
||||
@ -86,11 +46,6 @@ namespace pxsim.control {
|
||||
pxtcore.registerWithDal(id, evid, handler)
|
||||
}
|
||||
|
||||
export function raiseEvent(id: number, evid: number, mode: number) {
|
||||
// TODO mode?
|
||||
board().bus.queue(id, evid)
|
||||
}
|
||||
|
||||
export function eventTimestamp() {
|
||||
return board().bus.getLastEventTime()
|
||||
}
|
||||
@ -100,12 +55,6 @@ namespace pxsim.control {
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.pxtcore {
|
||||
export function registerWithDal(id: number, evid: number, handler: RefAction) {
|
||||
board().bus.listen(id, evid, handler);
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.input {
|
||||
export function calibrateCompass() {
|
||||
// device calibrates...
|
||||
@ -168,6 +117,12 @@ namespace pxsim.pins {
|
||||
|
||||
export function setEvents(name: number, event: number) {
|
||||
}
|
||||
|
||||
export function setMatrixWidth(pin: number, width: number) {
|
||||
const lp = neopixelState(pin);
|
||||
if (!lp) return;
|
||||
lp.width = width;
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.devices {
|
||||
@ -246,13 +201,24 @@ namespace pxsim.bluetooth {
|
||||
}
|
||||
|
||||
namespace pxsim.light {
|
||||
|
||||
export function sendWS2812Buffer(buffer: RefBuffer, pin: number) {
|
||||
pxsim.sendBufferAsm(buffer, pin)
|
||||
}
|
||||
|
||||
export function sendWS2812BufferWithBrightness(buffer: RefBuffer, pin: number, brightness: number) {
|
||||
const clone = new RefBuffer(new Uint8Array(buffer.data))
|
||||
const data = clone.data;
|
||||
for(let i =0; i < data.length; ++i) {
|
||||
data[i] = (data[i] * brightness) >> 8;
|
||||
}
|
||||
pxsim.sendBufferAsm(clone, pin)
|
||||
}
|
||||
|
||||
export function setMode(pin: number, mode: number) {
|
||||
const lp = neopixelState(pin);
|
||||
if (!lp) return;
|
||||
lp.mode = mode & 0xff;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -3,6 +3,17 @@ namespace pxsim {
|
||||
export class SerialState {
|
||||
serialIn: string[] = [];
|
||||
|
||||
constructor(private readonly runtime: Runtime, private readonly board: BaseBoard) {
|
||||
this.board.addMessageListener(this.handleMessage.bind(this))
|
||||
}
|
||||
|
||||
private handleMessage(msg: SimulatorMessage) {
|
||||
if (msg.type === "serial") {
|
||||
const data = (<SimulatorSerialMessage>msg).data || "";
|
||||
this.receiveData(data);
|
||||
}
|
||||
}
|
||||
|
||||
public receiveData(data: string) {
|
||||
this.serialIn.push();
|
||||
}
|
||||
@ -28,12 +39,6 @@ namespace pxsim {
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.control {
|
||||
export function __log(s: string) {
|
||||
board().writeSerial(s + "\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
namespace pxsim.serial {
|
||||
export function writeString(s: string) {
|
||||
board().writeSerial(s);
|
||||
|
60
sim/state/soundexpression.ts
Normal file
60
sim/state/soundexpression.ts
Normal file
@ -0,0 +1,60 @@
|
||||
namespace pxsim.music {
|
||||
function loadWavAsync(path: string): Promise<Uint8Array> {
|
||||
return new Promise<Uint8Array>((resolve, reject) => {
|
||||
let httprequest = new XMLHttpRequest();
|
||||
httprequest.responseType = "arraybuffer";
|
||||
httprequest.onreadystatechange = function () {
|
||||
if (httprequest.readyState == XMLHttpRequest.DONE) {
|
||||
if (httprequest.status == 200) {
|
||||
const r = httprequest.response;
|
||||
resolve(new Uint8Array(httprequest.response));
|
||||
}
|
||||
else {
|
||||
reject(httprequest.status);
|
||||
}
|
||||
}
|
||||
};
|
||||
httprequest.open("GET", path, true);
|
||||
httprequest.send();
|
||||
})
|
||||
}
|
||||
const wavPromises: Map<Promise<Uint8Array>> = {}
|
||||
//%
|
||||
export function __playSoundExpression(notes: string, waitTillDone: boolean): void {
|
||||
const cb = getResume();
|
||||
const b = board();
|
||||
// v2 only...
|
||||
b.ensureHardwareVersion(2);
|
||||
|
||||
// load wav file
|
||||
let p: Promise<Uint8Array>;
|
||||
// defined in sim.html
|
||||
const path = (<any>pxsim).soundExpressionFiles[notes];
|
||||
if (path) {
|
||||
p = wavPromises[notes] || (wavPromises[notes] = loadWavAsync(path));
|
||||
} else
|
||||
p = Promise.resolve(undefined);
|
||||
|
||||
p.then(data => {
|
||||
// failed to load data
|
||||
if (data) {
|
||||
// finally play
|
||||
const buf = new RefBuffer(data);
|
||||
const pp = AudioContextManager.playBufferAsync(buf)
|
||||
if (waitTillDone)
|
||||
// wait until sound is done
|
||||
return pp;
|
||||
}
|
||||
// don't wait
|
||||
cb();
|
||||
return Promise.resolve();
|
||||
}).catch((e) => {
|
||||
console.log(e)
|
||||
cb();
|
||||
})
|
||||
}
|
||||
|
||||
export function __stopSoundExpressions() {
|
||||
AudioContextManager.stopAll();
|
||||
}
|
||||
}
|
36
sim/state/storage.ts
Normal file
36
sim/state/storage.ts
Normal file
@ -0,0 +1,36 @@
|
||||
|
||||
namespace pxsim.storage {
|
||||
|
||||
export function putValue(key: string, value: string) : void {
|
||||
sessionStorage.setItem('simulatorValue_'+key, value);
|
||||
}
|
||||
|
||||
export function putValueInt(key: string, value: number) : void {
|
||||
sessionStorage.setItem('simulatorValue_'+key, value+"");
|
||||
}
|
||||
|
||||
export function getValue(key: string) : string {
|
||||
if(sessionStorage.getItem('simulatorValue_'+key)) {
|
||||
return sessionStorage.getItem('simulatorValue_'+key);
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
export function getValueInt(key: string) : number {
|
||||
if(sessionStorage.getItem('simulatorValue_'+key)) {
|
||||
return parseFloat(sessionStorage.getItem('simulatorValue_'+key));
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
export function removeStr(key: string) : void {
|
||||
sessionStorage.removeItem('simulatorValue_'+key);
|
||||
}
|
||||
|
||||
export function removeInt(key: string) : void {
|
||||
sessionStorage.removeItem('simulatorValue_'+key);
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user