Skip to content

Commit

Permalink
only post screen when at end of render, incl palette in sim<->host me…
Browse files Browse the repository at this point in the history
…ssages (#1380)

* only post screen when at end of render, incl palette in sim<->host messages

* use throttledmsg

* don't send image message unless host

* pass around palette as 48b uint8array instead of 96b string

* do not export getOrigin / postImage

* bump pxt version
  • Loading branch information
jwunderl authored Oct 20, 2022
1 parent 4f14fec commit 851f8a1
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 27 deletions.
5 changes: 1 addition & 4 deletions libs/game/multiplayer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,15 @@

namespace multiplayer {
//%
void postImage(Image_ im, String goal) {
// no support >:(
void postImage(Image_ im) {
}

//%
void setOrigin(String origin) {
// no
}

//%
Image_ getCurrentImage() {
// nah
return NULL;
}

Expand Down
13 changes: 13 additions & 0 deletions libs/game/multiplayer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ namespace multiplayer {
//% shim=multiplayer::getCurrentImage
declare function getCurrentImage(): Image;

//% shim=multiplayer::postImage
declare function postImage(im: Image): void;

//% shim=multiplayer::setOrigin
declare function setOrigin(origin: string): void;

Expand All @@ -21,4 +24,14 @@ namespace multiplayer {
});
game.pushScene();
}

export function initServer() {
if (getOrigin() === "server") {
game.eventContext().registerFrameHandler(scene.MULTIPLAYER_POST_SCREEN_PRIORITY, () => {
if (getOrigin() === "server") {
postImage(screen);
}
})
}
}
}
2 changes: 2 additions & 0 deletions libs/game/scene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ namespace scene {
export const RENDER_DIAGNOSTICS_PRIORITY = 150;
export const MULTIPLAYER_SCREEN_PRIORITY = 190;
export const UPDATE_SCREEN_PRIORITY = 200;
export const MULTIPLAYER_POST_SCREEN_PRIORITY = 210;

// default rendering z indices
export const ON_PAINT_Z = -20;
Expand Down Expand Up @@ -179,6 +180,7 @@ namespace scene {
});
// update screen
this.eventContext.registerFrameHandler(UPDATE_SCREEN_PRIORITY, control.__screen.update);
multiplayer.initServer();
// register additional components
Scene.initializers.forEach(f => f(this));
}
Expand Down
35 changes: 18 additions & 17 deletions libs/game/sim/multiplayer.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,28 @@
namespace pxsim.multiplayer {
export function postImage(im: pxsim.RefImage, goal: string) {
const throttledImgPost = pxsim.U.throttle((msg: MultiplayerImageMessage) =>{
getMultiplayerState().send(msg);
}, 50, true);

export function postImage(im: pxsim.RefImage) {
if (getMultiplayerState().origin !== "server")
return;
const asBuf = pxsim.image.toBuffer(im);
getMultiplayerState().send(<MultiplayerImageMessage>{
const sb = board() as ScreenBoard;
throttledImgPost(<MultiplayerImageMessage>{
content: "Image",
image: asBuf,
goal
palette: sb?.screenState?.paletteToUint8Array(),
});
}


export function getCurrentImage(): pxsim.RefImage {
return getMultiplayerState().backgroundImage;
}

export function setOrigin(origin: "client" | "server" | undefined) {
getMultiplayerState().origin = origin;

}

export function getOrigin(): string {
Expand Down Expand Up @@ -41,8 +50,9 @@ namespace pxsim {

export interface MultiplayerImageMessage extends SimulatorMultiplayerMessage {
content: "Image";
goal: string; // goal of message; e.g. "broadcast-screen"
image: RefBuffer;
// 48bytes, [r0,g0,b0,r1,g1,b1,...]
palette: Uint8Array;
}

export interface MultiplayerButtonEvent extends SimulatorMultiplayerMessage {
Expand All @@ -51,13 +61,11 @@ namespace pxsim {
state: "Pressed" | "Released" | "Held";
}

let postScreenInterval: any;
export class MultiplayerState {
lastMessageId: number;
origin: string;
backgroundImage: RefImage;


constructor() {
this.lastMessageId = 0;
}
Expand All @@ -76,17 +84,6 @@ namespace pxsim {
init(origin: string) {
this.origin = origin;
runtime.board.addMessageListener(msg => this.messageHandler(msg));
if (postScreenInterval) {
clearInterval(postScreenInterval)
}
postScreenInterval = setInterval(() => {
if (this.origin === "server") {
const b = board() as ScreenBoard;
const screenState = b && b.screenState;
const lastImage = screenState && screenState.lastImage;
lastImage && pxsim.multiplayer.postImage(lastImage, "broadcast-screen");
}
}, 50);
}

setButton(key: number, isPressed: boolean) {
Expand All @@ -111,6 +108,10 @@ namespace pxsim {
msg.image.data = new Uint8Array(msg.image.data);
}
this.backgroundImage = pxsim.image.ofBuffer(msg.image);
if (msg.palette?.length === 48) {
const palBuffer = new pxsim.RefBuffer(msg.palette)
pxsim.pxtcore.setPalette(palBuffer);
}
}
} else if (isButtonMessage(msg)) {
if (this.origin === "server") {
Expand Down
32 changes: 27 additions & 5 deletions libs/screen/sim/state.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
namespace pxsim {
function htmlColorToUint32(hexColor: string) {
const ca = new Uint8ClampedArray(4)
const ui = new Uint32Array(ca.buffer)
const v = parseInt(hexColor.replace(/#/, ""), 16)
ca[0] = (v >> 16) & 0xff;
ca[1] = (v >> 8) & 0xff;
Expand All @@ -11,6 +10,13 @@ namespace pxsim {
return new Uint32Array(ca.buffer)[0]
}

function UInt32ToRGB(col: number): number[] {
const ui = new Uint32Array(1);
ui[0] = col;
const ca = new Uint8ClampedArray(ui.buffer);
return [ca[0], ca[1], ca[2]];
}

export class ScreenState {
width = 0
height = 0
Expand All @@ -25,10 +31,8 @@ namespace pxsim {

constructor(paletteSrc: string[], w = 0, h = 0) {
if (!paletteSrc) paletteSrc = ["#000000", "#ffffff"]
this.palette = new Uint32Array(paletteSrc.length)
for (let i = 0; i < this.palette.length; ++i) {
this.palette[i] = htmlColorToUint32(paletteSrc[i])
}
this.palette = new Uint32Array(paletteSrc.length);
this.setPaletteFromHtmlColors(paletteSrc);
if (w) {
this.width = w
this.height = h
Expand All @@ -41,6 +45,24 @@ namespace pxsim {
this.brightness = b | 0;
}

paletteToUint8Array() {
const out = new Uint8Array(this.palette.length * 3);
for (let i = 0; i < this.palette.length; ++i) {
const [r, g, b] = UInt32ToRGB(this.palette[i]);
const s = 3 * i;
out[s] = r;
out[s + 1] = g;
out[s + 2] = b;
}
return out;
}

setPaletteFromHtmlColors(src: string[]) {
for (let i = 0; i < this.palette.length; ++i) {
this.palette[i] = htmlColorToUint32(src[i])
}
}

setPalette(buf: RefBuffer) {
const ca = new Uint8ClampedArray(4)
const rd = new Uint32Array(ca.buffer)
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"libs/**/*"
],
"dependencies": {
"pxt-core": "8.2.4"
"pxt-core": "8.4.8"
},
"devDependencies": {
"typescript": "^4.2.3"
Expand Down

0 comments on commit 851f8a1

Please sign in to comment.