@bloopjs/web 0.0.56 → 0.0.57
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/App.d.ts.map +1 -1
- package/dist/debugui/DebugUi.d.ts.map +1 -1
- package/dist/debugui/components/BottomBar.d.ts +8 -0
- package/dist/debugui/components/BottomBar.d.ts.map +1 -0
- package/dist/debugui/components/DebugToggle.d.ts.map +1 -1
- package/dist/debugui/components/Root.d.ts.map +1 -1
- package/dist/debugui/components/TopBar.d.ts +7 -0
- package/dist/debugui/components/TopBar.d.ts.map +1 -0
- package/dist/debugui/components/VerticalBar.d.ts +9 -0
- package/dist/debugui/components/VerticalBar.d.ts.map +1 -0
- package/dist/debugui/state.d.ts +9 -1
- package/dist/debugui/state.d.ts.map +1 -1
- package/dist/debugui/styles.d.ts +1 -1
- package/dist/debugui/styles.d.ts.map +1 -1
- package/dist/mod.js +571 -26
- package/dist/mod.js.map +12 -9
- package/package.json +3 -3
- package/src/App.ts +32 -1
- package/src/debugui/DebugUi.ts +7 -7
- package/src/debugui/components/BottomBar.tsx +68 -0
- package/src/debugui/components/DebugToggle.tsx +2 -6
- package/src/debugui/components/Root.tsx +81 -17
- package/src/debugui/components/TopBar.tsx +36 -0
- package/src/debugui/components/VerticalBar.tsx +26 -0
- package/src/debugui/state.ts +42 -5
- package/src/debugui/styles.ts +232 -2
package/dist/mod.js
CHANGED
|
@@ -3440,6 +3440,7 @@ __export(exports_mod, {
|
|
|
3440
3440
|
resetState: () => resetState,
|
|
3441
3441
|
removePeer: () => removePeer,
|
|
3442
3442
|
debugState: () => debugState,
|
|
3443
|
+
cycleLayout: () => cycleLayout,
|
|
3443
3444
|
clearLogs: () => clearLogs,
|
|
3444
3445
|
addPeer: () => addPeer,
|
|
3445
3446
|
addLog: () => addLog,
|
|
@@ -4471,7 +4472,7 @@ function useSignalEffect(i4) {
|
|
|
4471
4472
|
}
|
|
4472
4473
|
|
|
4473
4474
|
// src/debugui/state.ts
|
|
4474
|
-
var
|
|
4475
|
+
var layoutMode = d2("off");
|
|
4475
4476
|
var netStatus = d2({
|
|
4476
4477
|
ourId: null,
|
|
4477
4478
|
remoteId: null,
|
|
@@ -4479,16 +4480,35 @@ var netStatus = d2({
|
|
|
4479
4480
|
peers: []
|
|
4480
4481
|
});
|
|
4481
4482
|
var logs = d2([]);
|
|
4483
|
+
var fps = d2(0);
|
|
4484
|
+
var frameTime = d2(0);
|
|
4485
|
+
var snapshotSize = d2(0);
|
|
4486
|
+
var frameNumber = d2(0);
|
|
4482
4487
|
var debugState = {
|
|
4483
|
-
|
|
4488
|
+
layoutMode,
|
|
4489
|
+
isVisible: w3(() => layoutMode.value !== "off"),
|
|
4484
4490
|
netStatus,
|
|
4485
4491
|
logs,
|
|
4486
4492
|
peer: w3(() => netStatus.value.peers[0] ?? null),
|
|
4487
4493
|
advantage: w3(() => {
|
|
4488
4494
|
const peer = netStatus.value.peers[0];
|
|
4489
4495
|
return peer ? peer.seq - peer.ack : null;
|
|
4490
|
-
})
|
|
4496
|
+
}),
|
|
4497
|
+
fps,
|
|
4498
|
+
frameTime,
|
|
4499
|
+
snapshotSize,
|
|
4500
|
+
frameNumber
|
|
4491
4501
|
};
|
|
4502
|
+
function cycleLayout() {
|
|
4503
|
+
const current = layoutMode.value;
|
|
4504
|
+
if (current === "off") {
|
|
4505
|
+
layoutMode.value = "letterboxed";
|
|
4506
|
+
} else if (current === "letterboxed") {
|
|
4507
|
+
layoutMode.value = "full";
|
|
4508
|
+
} else {
|
|
4509
|
+
layoutMode.value = "off";
|
|
4510
|
+
}
|
|
4511
|
+
}
|
|
4492
4512
|
function addLog(log) {
|
|
4493
4513
|
debugState.logs.value = [...debugState.logs.value, log];
|
|
4494
4514
|
}
|
|
@@ -4538,7 +4558,7 @@ function clearLogs() {
|
|
|
4538
4558
|
debugState.logs.value = [];
|
|
4539
4559
|
}
|
|
4540
4560
|
function resetState() {
|
|
4541
|
-
debugState.
|
|
4561
|
+
debugState.layoutMode.value = "off";
|
|
4542
4562
|
debugState.logs.value = [];
|
|
4543
4563
|
debugState.netStatus.value = {
|
|
4544
4564
|
ourId: null,
|
|
@@ -4546,6 +4566,10 @@ function resetState() {
|
|
|
4546
4566
|
rtt: null,
|
|
4547
4567
|
peers: []
|
|
4548
4568
|
};
|
|
4569
|
+
debugState.fps.value = 0;
|
|
4570
|
+
debugState.frameTime.value = 0;
|
|
4571
|
+
debugState.snapshotSize.value = 0;
|
|
4572
|
+
debugState.frameNumber.value = 0;
|
|
4549
4573
|
}
|
|
4550
4574
|
// ../../node_modules/preact/jsx-runtime/dist/jsxRuntime.module.js
|
|
4551
4575
|
var f4 = 0;
|
|
@@ -4808,26 +4832,257 @@ function LogEntry({ log }) {
|
|
|
4808
4832
|
|
|
4809
4833
|
// src/debugui/components/DebugToggle.tsx
|
|
4810
4834
|
function DebugToggle({ hotkey = "Escape" }) {
|
|
4811
|
-
const
|
|
4812
|
-
const toggle = () => {
|
|
4813
|
-
debugState.isVisible.value = !debugState.isVisible.value;
|
|
4814
|
-
};
|
|
4835
|
+
const isVisible = debugState.isVisible.value;
|
|
4815
4836
|
return /* @__PURE__ */ u4("button", {
|
|
4816
4837
|
className: "debug-toggle",
|
|
4817
|
-
onClick:
|
|
4838
|
+
onClick: cycleLayout,
|
|
4818
4839
|
onMouseDown: (e4) => e4.stopPropagation(),
|
|
4819
4840
|
onMouseUp: (e4) => e4.stopPropagation(),
|
|
4820
|
-
title:
|
|
4821
|
-
children:
|
|
4841
|
+
title: isVisible ? `Hide debug (${hotkey})` : `Show debug (${hotkey})`,
|
|
4842
|
+
children: isVisible ? "✕" : "⚙"
|
|
4843
|
+
}, undefined, false, undefined, this);
|
|
4844
|
+
}
|
|
4845
|
+
|
|
4846
|
+
// src/debugui/components/TopBar.tsx
|
|
4847
|
+
function TopBar({ leftLabel, rightLabel }) {
|
|
4848
|
+
const fps2 = debugState.fps.value;
|
|
4849
|
+
const frameNumber2 = debugState.frameNumber.value;
|
|
4850
|
+
const rtt = debugState.netStatus.value.rtt;
|
|
4851
|
+
const isOnline = debugState.netStatus.value.peers.length > 0;
|
|
4852
|
+
return /* @__PURE__ */ u4("div", {
|
|
4853
|
+
className: "top-bar",
|
|
4854
|
+
children: [
|
|
4855
|
+
/* @__PURE__ */ u4("span", {
|
|
4856
|
+
className: "top-bar-side-label",
|
|
4857
|
+
children: leftLabel
|
|
4858
|
+
}, undefined, false, undefined, this),
|
|
4859
|
+
/* @__PURE__ */ u4("div", {
|
|
4860
|
+
className: "top-bar-center",
|
|
4861
|
+
children: [
|
|
4862
|
+
/* @__PURE__ */ u4("div", {
|
|
4863
|
+
className: "top-bar-item",
|
|
4864
|
+
children: [
|
|
4865
|
+
/* @__PURE__ */ u4("span", {
|
|
4866
|
+
className: "top-bar-label",
|
|
4867
|
+
children: "FPS"
|
|
4868
|
+
}, undefined, false, undefined, this),
|
|
4869
|
+
/* @__PURE__ */ u4("span", {
|
|
4870
|
+
className: "top-bar-value",
|
|
4871
|
+
children: fps2
|
|
4872
|
+
}, undefined, false, undefined, this)
|
|
4873
|
+
]
|
|
4874
|
+
}, undefined, true, undefined, this),
|
|
4875
|
+
/* @__PURE__ */ u4("div", {
|
|
4876
|
+
className: "top-bar-item",
|
|
4877
|
+
children: [
|
|
4878
|
+
/* @__PURE__ */ u4("span", {
|
|
4879
|
+
className: "top-bar-label",
|
|
4880
|
+
children: "Frame"
|
|
4881
|
+
}, undefined, false, undefined, this),
|
|
4882
|
+
/* @__PURE__ */ u4("span", {
|
|
4883
|
+
className: "top-bar-value",
|
|
4884
|
+
children: frameNumber2
|
|
4885
|
+
}, undefined, false, undefined, this)
|
|
4886
|
+
]
|
|
4887
|
+
}, undefined, true, undefined, this),
|
|
4888
|
+
isOnline && rtt !== null && /* @__PURE__ */ u4("div", {
|
|
4889
|
+
className: "top-bar-item",
|
|
4890
|
+
children: [
|
|
4891
|
+
/* @__PURE__ */ u4("span", {
|
|
4892
|
+
className: "top-bar-label",
|
|
4893
|
+
children: "Ping"
|
|
4894
|
+
}, undefined, false, undefined, this),
|
|
4895
|
+
/* @__PURE__ */ u4("span", {
|
|
4896
|
+
className: "top-bar-value",
|
|
4897
|
+
children: [
|
|
4898
|
+
rtt,
|
|
4899
|
+
"ms"
|
|
4900
|
+
]
|
|
4901
|
+
}, undefined, true, undefined, this)
|
|
4902
|
+
]
|
|
4903
|
+
}, undefined, true, undefined, this)
|
|
4904
|
+
]
|
|
4905
|
+
}, undefined, true, undefined, this),
|
|
4906
|
+
/* @__PURE__ */ u4("span", {
|
|
4907
|
+
className: "top-bar-side-label",
|
|
4908
|
+
children: rightLabel
|
|
4909
|
+
}, undefined, false, undefined, this)
|
|
4910
|
+
]
|
|
4911
|
+
}, undefined, true, undefined, this);
|
|
4912
|
+
}
|
|
4913
|
+
|
|
4914
|
+
// src/debugui/components/VerticalBar.tsx
|
|
4915
|
+
function VerticalBar({
|
|
4916
|
+
value,
|
|
4917
|
+
max,
|
|
4918
|
+
side,
|
|
4919
|
+
color = "#4a9eff"
|
|
4920
|
+
}) {
|
|
4921
|
+
const percentage = max > 0 ? Math.min(100, value / max * 100) : 0;
|
|
4922
|
+
return /* @__PURE__ */ u4("div", {
|
|
4923
|
+
className: `${side}-bar`,
|
|
4924
|
+
children: /* @__PURE__ */ u4("div", {
|
|
4925
|
+
className: "vertical-bar",
|
|
4926
|
+
children: /* @__PURE__ */ u4("div", {
|
|
4927
|
+
className: "vertical-bar-fill",
|
|
4928
|
+
style: { height: `${percentage}%`, background: color }
|
|
4929
|
+
}, undefined, false, undefined, this)
|
|
4930
|
+
}, undefined, false, undefined, this)
|
|
4822
4931
|
}, undefined, false, undefined, this);
|
|
4823
4932
|
}
|
|
4824
4933
|
|
|
4934
|
+
// src/debugui/components/BottomBar.tsx
|
|
4935
|
+
function BottomBar({
|
|
4936
|
+
tapeUtilization = 0,
|
|
4937
|
+
playheadPosition = 0,
|
|
4938
|
+
isPlaying = true
|
|
4939
|
+
}) {
|
|
4940
|
+
const handleJumpBack = () => {};
|
|
4941
|
+
const handleStepBack = () => {};
|
|
4942
|
+
const handlePlayPause = () => {};
|
|
4943
|
+
const handleStepForward = () => {};
|
|
4944
|
+
const handleJumpForward = () => {};
|
|
4945
|
+
const handleSeek = () => {};
|
|
4946
|
+
return /* @__PURE__ */ u4("div", {
|
|
4947
|
+
className: "bottom-bar",
|
|
4948
|
+
children: [
|
|
4949
|
+
/* @__PURE__ */ u4("div", {
|
|
4950
|
+
className: "playbar-controls",
|
|
4951
|
+
children: [
|
|
4952
|
+
/* @__PURE__ */ u4("button", {
|
|
4953
|
+
className: "playbar-btn",
|
|
4954
|
+
onClick: handleJumpBack,
|
|
4955
|
+
children: [
|
|
4956
|
+
"<<",
|
|
4957
|
+
/* @__PURE__ */ u4("span", {
|
|
4958
|
+
className: "tooltip tooltip-left",
|
|
4959
|
+
children: [
|
|
4960
|
+
"Jump back ",
|
|
4961
|
+
/* @__PURE__ */ u4("kbd", {
|
|
4962
|
+
children: "4"
|
|
4963
|
+
}, undefined, false, undefined, this)
|
|
4964
|
+
]
|
|
4965
|
+
}, undefined, true, undefined, this)
|
|
4966
|
+
]
|
|
4967
|
+
}, undefined, true, undefined, this),
|
|
4968
|
+
/* @__PURE__ */ u4("button", {
|
|
4969
|
+
className: "playbar-btn",
|
|
4970
|
+
onClick: handleStepBack,
|
|
4971
|
+
children: [
|
|
4972
|
+
"<",
|
|
4973
|
+
/* @__PURE__ */ u4("span", {
|
|
4974
|
+
className: "tooltip",
|
|
4975
|
+
children: [
|
|
4976
|
+
"Step back ",
|
|
4977
|
+
/* @__PURE__ */ u4("kbd", {
|
|
4978
|
+
children: "5"
|
|
4979
|
+
}, undefined, false, undefined, this)
|
|
4980
|
+
]
|
|
4981
|
+
}, undefined, true, undefined, this)
|
|
4982
|
+
]
|
|
4983
|
+
}, undefined, true, undefined, this),
|
|
4984
|
+
/* @__PURE__ */ u4("button", {
|
|
4985
|
+
className: "playbar-btn",
|
|
4986
|
+
onClick: handlePlayPause,
|
|
4987
|
+
children: [
|
|
4988
|
+
isPlaying ? "||" : ">",
|
|
4989
|
+
/* @__PURE__ */ u4("span", {
|
|
4990
|
+
className: "tooltip",
|
|
4991
|
+
children: [
|
|
4992
|
+
isPlaying ? "Pause" : "Play",
|
|
4993
|
+
" ",
|
|
4994
|
+
/* @__PURE__ */ u4("kbd", {
|
|
4995
|
+
children: "6"
|
|
4996
|
+
}, undefined, false, undefined, this)
|
|
4997
|
+
]
|
|
4998
|
+
}, undefined, true, undefined, this)
|
|
4999
|
+
]
|
|
5000
|
+
}, undefined, true, undefined, this),
|
|
5001
|
+
/* @__PURE__ */ u4("button", {
|
|
5002
|
+
className: "playbar-btn",
|
|
5003
|
+
onClick: handleStepForward,
|
|
5004
|
+
children: [
|
|
5005
|
+
">",
|
|
5006
|
+
/* @__PURE__ */ u4("span", {
|
|
5007
|
+
className: "tooltip",
|
|
5008
|
+
children: [
|
|
5009
|
+
"Step forward ",
|
|
5010
|
+
/* @__PURE__ */ u4("kbd", {
|
|
5011
|
+
children: "7"
|
|
5012
|
+
}, undefined, false, undefined, this)
|
|
5013
|
+
]
|
|
5014
|
+
}, undefined, true, undefined, this)
|
|
5015
|
+
]
|
|
5016
|
+
}, undefined, true, undefined, this),
|
|
5017
|
+
/* @__PURE__ */ u4("button", {
|
|
5018
|
+
className: "playbar-btn",
|
|
5019
|
+
onClick: handleJumpForward,
|
|
5020
|
+
children: [
|
|
5021
|
+
">>",
|
|
5022
|
+
/* @__PURE__ */ u4("span", {
|
|
5023
|
+
className: "tooltip",
|
|
5024
|
+
children: [
|
|
5025
|
+
"Jump forward ",
|
|
5026
|
+
/* @__PURE__ */ u4("kbd", {
|
|
5027
|
+
children: "8"
|
|
5028
|
+
}, undefined, false, undefined, this)
|
|
5029
|
+
]
|
|
5030
|
+
}, undefined, true, undefined, this)
|
|
5031
|
+
]
|
|
5032
|
+
}, undefined, true, undefined, this)
|
|
5033
|
+
]
|
|
5034
|
+
}, undefined, true, undefined, this),
|
|
5035
|
+
/* @__PURE__ */ u4("div", {
|
|
5036
|
+
className: "seek-bar",
|
|
5037
|
+
onClick: handleSeek,
|
|
5038
|
+
children: [
|
|
5039
|
+
/* @__PURE__ */ u4("div", {
|
|
5040
|
+
className: "seek-bar-fill",
|
|
5041
|
+
style: { width: `${tapeUtilization * 100}%` }
|
|
5042
|
+
}, undefined, false, undefined, this),
|
|
5043
|
+
tapeUtilization > 0 && /* @__PURE__ */ u4("div", {
|
|
5044
|
+
className: "seek-bar-position",
|
|
5045
|
+
style: { left: `${playheadPosition * tapeUtilization * 100}%` }
|
|
5046
|
+
}, undefined, false, undefined, this)
|
|
5047
|
+
]
|
|
5048
|
+
}, undefined, true, undefined, this)
|
|
5049
|
+
]
|
|
5050
|
+
}, undefined, true, undefined, this);
|
|
5051
|
+
}
|
|
5052
|
+
|
|
4825
5053
|
// src/debugui/components/Root.tsx
|
|
4826
5054
|
function Root({ canvas, hotkey = "Escape" }) {
|
|
4827
|
-
const
|
|
5055
|
+
const layoutMode2 = debugState.layoutMode.value;
|
|
5056
|
+
if (layoutMode2 === "off") {
|
|
5057
|
+
return /* @__PURE__ */ u4(k, {
|
|
5058
|
+
children: [
|
|
5059
|
+
/* @__PURE__ */ u4("main", {
|
|
5060
|
+
className: "fullscreen",
|
|
5061
|
+
children: /* @__PURE__ */ u4(GameCanvas, {
|
|
5062
|
+
canvas
|
|
5063
|
+
}, undefined, false, undefined, this)
|
|
5064
|
+
}, undefined, false, undefined, this),
|
|
5065
|
+
/* @__PURE__ */ u4(DebugToggle, {
|
|
5066
|
+
hotkey
|
|
5067
|
+
}, undefined, false, undefined, this)
|
|
5068
|
+
]
|
|
5069
|
+
}, undefined, true, undefined, this);
|
|
5070
|
+
}
|
|
5071
|
+
if (layoutMode2 === "letterboxed") {
|
|
5072
|
+
return /* @__PURE__ */ u4(k, {
|
|
5073
|
+
children: [
|
|
5074
|
+
/* @__PURE__ */ u4(LetterboxedLayout, {
|
|
5075
|
+
canvas
|
|
5076
|
+
}, undefined, false, undefined, this),
|
|
5077
|
+
/* @__PURE__ */ u4(DebugToggle, {
|
|
5078
|
+
hotkey
|
|
5079
|
+
}, undefined, false, undefined, this)
|
|
5080
|
+
]
|
|
5081
|
+
}, undefined, true, undefined, this);
|
|
5082
|
+
}
|
|
4828
5083
|
return /* @__PURE__ */ u4(k, {
|
|
4829
5084
|
children: [
|
|
4830
|
-
|
|
5085
|
+
/* @__PURE__ */ u4("main", {
|
|
4831
5086
|
className: "layout",
|
|
4832
5087
|
children: [
|
|
4833
5088
|
/* @__PURE__ */ u4("section", {
|
|
@@ -4845,14 +5100,53 @@ function Root({ canvas, hotkey = "Escape" }) {
|
|
|
4845
5100
|
children: /* @__PURE__ */ u4(Logs, {}, undefined, false, undefined, this)
|
|
4846
5101
|
}, undefined, false, undefined, this)
|
|
4847
5102
|
]
|
|
4848
|
-
}, undefined, true, undefined, this)
|
|
4849
|
-
|
|
5103
|
+
}, undefined, true, undefined, this),
|
|
5104
|
+
/* @__PURE__ */ u4(DebugToggle, {
|
|
5105
|
+
hotkey
|
|
5106
|
+
}, undefined, false, undefined, this)
|
|
5107
|
+
]
|
|
5108
|
+
}, undefined, true, undefined, this);
|
|
5109
|
+
}
|
|
5110
|
+
function LetterboxedLayout({ canvas }) {
|
|
5111
|
+
const isOnline = debugState.netStatus.value.peers.length > 0;
|
|
5112
|
+
const advantage = debugState.advantage.value ?? 0;
|
|
5113
|
+
const frameTime2 = debugState.frameTime.value;
|
|
5114
|
+
const snapshotSize2 = debugState.snapshotSize.value;
|
|
5115
|
+
const leftValue = isOnline ? Math.abs(advantage) : frameTime2;
|
|
5116
|
+
const leftMax = isOnline ? 10 : 16.67;
|
|
5117
|
+
const leftLabel = isOnline ? "ADV" : "MS";
|
|
5118
|
+
const leftColor = isOnline ? advantage >= 0 ? "#4a9eff" : "#ff4a4a" : frameTime2 > 16.67 ? "#ff4a4a" : "#4aff4a";
|
|
5119
|
+
const rightValue = isOnline ? 0 : snapshotSize2;
|
|
5120
|
+
const rightMax = isOnline ? 10 : 1e4;
|
|
5121
|
+
const rightLabel = isOnline ? "RB" : "KB";
|
|
5122
|
+
return /* @__PURE__ */ u4("main", {
|
|
5123
|
+
className: "layout-letterboxed",
|
|
5124
|
+
children: [
|
|
5125
|
+
/* @__PURE__ */ u4(TopBar, {
|
|
5126
|
+
leftLabel,
|
|
5127
|
+
rightLabel
|
|
5128
|
+
}, undefined, false, undefined, this),
|
|
5129
|
+
/* @__PURE__ */ u4(VerticalBar, {
|
|
5130
|
+
value: leftValue,
|
|
5131
|
+
max: leftMax,
|
|
5132
|
+
side: "left",
|
|
5133
|
+
color: leftColor
|
|
5134
|
+
}, undefined, false, undefined, this),
|
|
5135
|
+
/* @__PURE__ */ u4("div", {
|
|
5136
|
+
className: "letterboxed-game",
|
|
4850
5137
|
children: /* @__PURE__ */ u4(GameCanvas, {
|
|
4851
5138
|
canvas
|
|
4852
5139
|
}, undefined, false, undefined, this)
|
|
4853
5140
|
}, undefined, false, undefined, this),
|
|
4854
|
-
/* @__PURE__ */ u4(
|
|
4855
|
-
|
|
5141
|
+
/* @__PURE__ */ u4(VerticalBar, {
|
|
5142
|
+
value: rightValue,
|
|
5143
|
+
max: rightMax,
|
|
5144
|
+
side: "right"
|
|
5145
|
+
}, undefined, false, undefined, this),
|
|
5146
|
+
/* @__PURE__ */ u4(BottomBar, {
|
|
5147
|
+
tapeUtilization: 0.67,
|
|
5148
|
+
playheadPosition: 0.8,
|
|
5149
|
+
isPlaying: true
|
|
4856
5150
|
}, undefined, false, undefined, this)
|
|
4857
5151
|
]
|
|
4858
5152
|
}, undefined, true, undefined, this);
|
|
@@ -4881,13 +5175,24 @@ var styles = `
|
|
|
4881
5175
|
|
|
4882
5176
|
/* Layout */
|
|
4883
5177
|
.fullscreen {
|
|
4884
|
-
width:
|
|
4885
|
-
height:
|
|
5178
|
+
width: 100vw;
|
|
5179
|
+
height: 100vh;
|
|
4886
5180
|
margin: 0;
|
|
4887
5181
|
padding: 0;
|
|
4888
5182
|
overflow: hidden;
|
|
4889
5183
|
}
|
|
4890
5184
|
|
|
5185
|
+
.fullscreen .canvas-container {
|
|
5186
|
+
width: 100%;
|
|
5187
|
+
height: 100%;
|
|
5188
|
+
}
|
|
5189
|
+
|
|
5190
|
+
.fullscreen canvas {
|
|
5191
|
+
width: 100%;
|
|
5192
|
+
height: 100%;
|
|
5193
|
+
display: block;
|
|
5194
|
+
}
|
|
5195
|
+
|
|
4891
5196
|
.layout {
|
|
4892
5197
|
display: grid;
|
|
4893
5198
|
grid-template-areas:
|
|
@@ -4901,6 +5206,225 @@ var styles = `
|
|
|
4901
5206
|
padding: 1rem;
|
|
4902
5207
|
}
|
|
4903
5208
|
|
|
5209
|
+
/* Letterboxed layout - using equal vw/vh percentages keeps game at viewport aspect ratio */
|
|
5210
|
+
.layout-letterboxed {
|
|
5211
|
+
display: grid;
|
|
5212
|
+
grid-template-areas:
|
|
5213
|
+
"top-bar top-bar top-bar"
|
|
5214
|
+
"left-bar game right-bar"
|
|
5215
|
+
"bottom-bar bottom-bar bottom-bar";
|
|
5216
|
+
grid-template-columns: 2vw 1fr 2vw;
|
|
5217
|
+
grid-template-rows: 2vh 1fr 2vh;
|
|
5218
|
+
width: 100vw;
|
|
5219
|
+
height: 100vh;
|
|
5220
|
+
background: #1a1a1a;
|
|
5221
|
+
overflow: hidden;
|
|
5222
|
+
overscroll-behavior: none;
|
|
5223
|
+
}
|
|
5224
|
+
|
|
5225
|
+
.top-bar {
|
|
5226
|
+
grid-area: top-bar;
|
|
5227
|
+
display: flex;
|
|
5228
|
+
align-items: center;
|
|
5229
|
+
justify-content: space-between;
|
|
5230
|
+
background: #111;
|
|
5231
|
+
color: #aaa;
|
|
5232
|
+
font-family: monospace;
|
|
5233
|
+
font-size: 12px;
|
|
5234
|
+
padding: 0;
|
|
5235
|
+
}
|
|
5236
|
+
|
|
5237
|
+
.top-bar-side-label {
|
|
5238
|
+
width: 2vw;
|
|
5239
|
+
text-align: center;
|
|
5240
|
+
font-size: 9px;
|
|
5241
|
+
text-transform: uppercase;
|
|
5242
|
+
letter-spacing: 0.5px;
|
|
5243
|
+
color: #666;
|
|
5244
|
+
}
|
|
5245
|
+
|
|
5246
|
+
.top-bar-center {
|
|
5247
|
+
display: flex;
|
|
5248
|
+
align-items: center;
|
|
5249
|
+
justify-content: center;
|
|
5250
|
+
gap: 24px;
|
|
5251
|
+
flex: 1;
|
|
5252
|
+
}
|
|
5253
|
+
|
|
5254
|
+
.top-bar-item {
|
|
5255
|
+
display: flex;
|
|
5256
|
+
align-items: center;
|
|
5257
|
+
gap: 6px;
|
|
5258
|
+
}
|
|
5259
|
+
|
|
5260
|
+
.top-bar-label {
|
|
5261
|
+
opacity: 0.6;
|
|
5262
|
+
}
|
|
5263
|
+
|
|
5264
|
+
.top-bar-value {
|
|
5265
|
+
color: #fff;
|
|
5266
|
+
font-weight: 500;
|
|
5267
|
+
}
|
|
5268
|
+
|
|
5269
|
+
.left-bar {
|
|
5270
|
+
grid-area: left-bar;
|
|
5271
|
+
display: flex;
|
|
5272
|
+
flex-direction: column;
|
|
5273
|
+
align-items: center;
|
|
5274
|
+
justify-content: flex-end;
|
|
5275
|
+
background: #111;
|
|
5276
|
+
padding: 4px 0;
|
|
5277
|
+
}
|
|
5278
|
+
|
|
5279
|
+
.right-bar {
|
|
5280
|
+
grid-area: right-bar;
|
|
5281
|
+
display: flex;
|
|
5282
|
+
flex-direction: column;
|
|
5283
|
+
align-items: center;
|
|
5284
|
+
justify-content: flex-end;
|
|
5285
|
+
background: #111;
|
|
5286
|
+
padding: 4px 0;
|
|
5287
|
+
}
|
|
5288
|
+
|
|
5289
|
+
.vertical-bar {
|
|
5290
|
+
width: 12px;
|
|
5291
|
+
flex: 1;
|
|
5292
|
+
background: #333;
|
|
5293
|
+
border-radius: 2px;
|
|
5294
|
+
position: relative;
|
|
5295
|
+
overflow: hidden;
|
|
5296
|
+
}
|
|
5297
|
+
|
|
5298
|
+
.vertical-bar-fill {
|
|
5299
|
+
position: absolute;
|
|
5300
|
+
bottom: 0;
|
|
5301
|
+
left: 0;
|
|
5302
|
+
right: 0;
|
|
5303
|
+
background: #4a9eff;
|
|
5304
|
+
border-radius: 2px;
|
|
5305
|
+
transition: height 0.1s ease-out;
|
|
5306
|
+
}
|
|
5307
|
+
|
|
5308
|
+
|
|
5309
|
+
.bottom-bar {
|
|
5310
|
+
grid-area: bottom-bar;
|
|
5311
|
+
display: flex;
|
|
5312
|
+
align-items: center;
|
|
5313
|
+
background: #111;
|
|
5314
|
+
padding: 0 8px;
|
|
5315
|
+
gap: 8px;
|
|
5316
|
+
}
|
|
5317
|
+
|
|
5318
|
+
.playbar-controls {
|
|
5319
|
+
display: flex;
|
|
5320
|
+
align-items: center;
|
|
5321
|
+
gap: 2px;
|
|
5322
|
+
flex-shrink: 0;
|
|
5323
|
+
}
|
|
5324
|
+
|
|
5325
|
+
.playbar-btn {
|
|
5326
|
+
width: 1.5vh;
|
|
5327
|
+
height: 1.5vh;
|
|
5328
|
+
min-width: 18px;
|
|
5329
|
+
min-height: 18px;
|
|
5330
|
+
border: none;
|
|
5331
|
+
background: transparent;
|
|
5332
|
+
color: #888;
|
|
5333
|
+
font-size: 10px;
|
|
5334
|
+
cursor: pointer;
|
|
5335
|
+
border-radius: 2px;
|
|
5336
|
+
display: flex;
|
|
5337
|
+
align-items: center;
|
|
5338
|
+
justify-content: center;
|
|
5339
|
+
transition: background 0.15s, color 0.15s;
|
|
5340
|
+
position: relative;
|
|
5341
|
+
}
|
|
5342
|
+
|
|
5343
|
+
.playbar-btn:hover {
|
|
5344
|
+
background: #333;
|
|
5345
|
+
color: #fff;
|
|
5346
|
+
}
|
|
5347
|
+
|
|
5348
|
+
.playbar-btn:hover .tooltip {
|
|
5349
|
+
opacity: 1;
|
|
5350
|
+
visibility: visible;
|
|
5351
|
+
}
|
|
5352
|
+
|
|
5353
|
+
.tooltip {
|
|
5354
|
+
position: absolute;
|
|
5355
|
+
bottom: calc(100% + 4px);
|
|
5356
|
+
left: 50%;
|
|
5357
|
+
transform: translateX(-50%);
|
|
5358
|
+
background: #222;
|
|
5359
|
+
color: #ccc;
|
|
5360
|
+
padding: 4px 8px;
|
|
5361
|
+
border-radius: 4px;
|
|
5362
|
+
font-size: 10px;
|
|
5363
|
+
white-space: nowrap;
|
|
5364
|
+
opacity: 0;
|
|
5365
|
+
visibility: hidden;
|
|
5366
|
+
transition: opacity 0.15s;
|
|
5367
|
+
pointer-events: none;
|
|
5368
|
+
z-index: 10;
|
|
5369
|
+
}
|
|
5370
|
+
|
|
5371
|
+
.tooltip-left {
|
|
5372
|
+
left: 0;
|
|
5373
|
+
transform: none;
|
|
5374
|
+
}
|
|
5375
|
+
|
|
5376
|
+
.tooltip kbd {
|
|
5377
|
+
background: #444;
|
|
5378
|
+
padding: 1px 4px;
|
|
5379
|
+
border-radius: 2px;
|
|
5380
|
+
margin-left: 4px;
|
|
5381
|
+
font-family: monospace;
|
|
5382
|
+
}
|
|
5383
|
+
|
|
5384
|
+
.seek-bar {
|
|
5385
|
+
flex: 1;
|
|
5386
|
+
height: 16px;
|
|
5387
|
+
background: #222;
|
|
5388
|
+
border-radius: 4px;
|
|
5389
|
+
position: relative;
|
|
5390
|
+
cursor: pointer;
|
|
5391
|
+
overflow: hidden;
|
|
5392
|
+
}
|
|
5393
|
+
|
|
5394
|
+
.seek-bar-fill {
|
|
5395
|
+
position: absolute;
|
|
5396
|
+
top: 0;
|
|
5397
|
+
left: 0;
|
|
5398
|
+
bottom: 0;
|
|
5399
|
+
background: linear-gradient(to right, #4a2070, #7b3fa0);
|
|
5400
|
+
border-radius: 4px;
|
|
5401
|
+
transition: width 0.1s ease-out;
|
|
5402
|
+
}
|
|
5403
|
+
|
|
5404
|
+
.seek-bar-position {
|
|
5405
|
+
position: absolute;
|
|
5406
|
+
top: 0;
|
|
5407
|
+
bottom: 0;
|
|
5408
|
+
width: 2px;
|
|
5409
|
+
background: #fff;
|
|
5410
|
+
}
|
|
5411
|
+
|
|
5412
|
+
.letterboxed-game {
|
|
5413
|
+
grid-area: game;
|
|
5414
|
+
overflow: hidden;
|
|
5415
|
+
}
|
|
5416
|
+
|
|
5417
|
+
.letterboxed-game .canvas-container {
|
|
5418
|
+
width: 100%;
|
|
5419
|
+
height: 100%;
|
|
5420
|
+
}
|
|
5421
|
+
|
|
5422
|
+
.letterboxed-game canvas {
|
|
5423
|
+
width: 100%;
|
|
5424
|
+
height: 100%;
|
|
5425
|
+
display: block;
|
|
5426
|
+
}
|
|
5427
|
+
|
|
4904
5428
|
.game {
|
|
4905
5429
|
grid-area: game;
|
|
4906
5430
|
border-radius: 8px;
|
|
@@ -5087,7 +5611,7 @@ class DebugUi {
|
|
|
5087
5611
|
const container = options.container ?? document.body;
|
|
5088
5612
|
const initiallyVisible = options.initiallyVisible ?? new URLSearchParams(window.location.search).has("debug");
|
|
5089
5613
|
this.#host = document.createElement("bloop-debug-ui");
|
|
5090
|
-
this.#host.style.cssText = "display:block;width:100%;height:100%;position:absolute;top:0;left:0;";
|
|
5614
|
+
this.#host.style.cssText = "display:block;width:100%;height:100%;position:absolute;top:0;left:0;overflow:hidden;overscroll-behavior:none;";
|
|
5091
5615
|
this.#shadow = this.#host.attachShadow({ mode: "open" });
|
|
5092
5616
|
const styleEl = document.createElement("style");
|
|
5093
5617
|
styleEl.textContent = styles;
|
|
@@ -5096,12 +5620,12 @@ class DebugUi {
|
|
|
5096
5620
|
this.#mountPoint.id = "debug-root";
|
|
5097
5621
|
this.#mountPoint.style.cssText = "width:100%;height:100%;";
|
|
5098
5622
|
this.#shadow.appendChild(this.#mountPoint);
|
|
5099
|
-
debugState.
|
|
5623
|
+
debugState.layoutMode.value = initiallyVisible ? "letterboxed" : "off";
|
|
5100
5624
|
this.#canvas = document.createElement("canvas");
|
|
5101
5625
|
this.#render();
|
|
5102
5626
|
container.appendChild(this.#host);
|
|
5103
5627
|
this.#cleanup = this.#setupHotkey();
|
|
5104
|
-
debugState.
|
|
5628
|
+
debugState.layoutMode.subscribe(() => {
|
|
5105
5629
|
this.#render();
|
|
5106
5630
|
});
|
|
5107
5631
|
}
|
|
@@ -5111,7 +5635,7 @@ class DebugUi {
|
|
|
5111
5635
|
#setupHotkey() {
|
|
5112
5636
|
const handler = (e4) => {
|
|
5113
5637
|
if (e4.key === this.#hotkey) {
|
|
5114
|
-
|
|
5638
|
+
cycleLayout();
|
|
5115
5639
|
}
|
|
5116
5640
|
};
|
|
5117
5641
|
window.addEventListener("keydown", handler);
|
|
@@ -5127,7 +5651,7 @@ class DebugUi {
|
|
|
5127
5651
|
return debugState.isVisible.value;
|
|
5128
5652
|
}
|
|
5129
5653
|
set isVisible(value) {
|
|
5130
|
-
debugState.
|
|
5654
|
+
debugState.layoutMode.value = value ? "letterboxed" : "off";
|
|
5131
5655
|
}
|
|
5132
5656
|
unmount() {
|
|
5133
5657
|
this.#cleanup?.();
|
|
@@ -5259,8 +5783,29 @@ class App {
|
|
|
5259
5783
|
}
|
|
5260
5784
|
};
|
|
5261
5785
|
window.addEventListener("keydown", playbarHotkeys);
|
|
5786
|
+
let fpsFrames = 0;
|
|
5787
|
+
let fpsLastTime = performance.now();
|
|
5262
5788
|
const frame = () => {
|
|
5263
|
-
|
|
5789
|
+
const stepStart = performance.now();
|
|
5790
|
+
const ticks = this.sim.step(stepStart - this.#now);
|
|
5791
|
+
if (ticks > 0) {
|
|
5792
|
+
const stepEnd = performance.now();
|
|
5793
|
+
debugState.frameTime.value = stepEnd - stepStart;
|
|
5794
|
+
debugState.frameNumber.value = this.sim.time.frame;
|
|
5795
|
+
if (debugState.layoutMode.value === "letterboxed") {
|
|
5796
|
+
const bag = this.game.bag;
|
|
5797
|
+
if (bag) {
|
|
5798
|
+
debugState.snapshotSize.value = JSON.stringify(bag).length;
|
|
5799
|
+
}
|
|
5800
|
+
}
|
|
5801
|
+
fpsFrames++;
|
|
5802
|
+
const elapsed = stepEnd - fpsLastTime;
|
|
5803
|
+
if (elapsed >= 1000) {
|
|
5804
|
+
debugState.fps.value = Math.round(fpsFrames * 1000 / elapsed);
|
|
5805
|
+
fpsFrames = 0;
|
|
5806
|
+
fpsLastTime = stepEnd;
|
|
5807
|
+
}
|
|
5808
|
+
}
|
|
5264
5809
|
if (!this.sim.isPaused) {
|
|
5265
5810
|
try {
|
|
5266
5811
|
this.afterFrame.notify(this.sim.time.frame);
|
|
@@ -5466,5 +6011,5 @@ export {
|
|
|
5466
6011
|
App
|
|
5467
6012
|
};
|
|
5468
6013
|
|
|
5469
|
-
//# debugId=
|
|
6014
|
+
//# debugId=97C22D9653CE8DB864756E2164756E21
|
|
5470
6015
|
//# sourceMappingURL=mod.js.map
|