The white flashing was the top fade: the live raisers were not repainting it
Oliver: "what is this white flashing while applause in the upper right corner of the crowd". With the photographers switched off entirely it was still there, so it was never them — it was mine, from this morning. The top fade is baked into the cached stand, and drawRaisers was painting a spectator's box straight over it with only the dim applied. Every time that spectator stood up his box lost the fade and lit up; every time he sat down it came back. Measured on the canvas: a 146-luminance jump, twice a second, in exactly the two places raisers sit near the top of the picture. Both stand treatments now come from one function each and are applied in both places. The gradient is built in user space, so filling a raiser's sub-rect with it picks up the right alpha for free. Probed again after the fix: zero bright pops during applause and during the wave, against the four hot spots before. While chasing it, two real detector faults turned up and are fixed too: a blob may not be a pale block (a re-rolled cream shirt is "new material" by the stand-turned-person test but nothing rises), and it may not cover something already bright (a genuine arm drawn over a white shirt deletes a white block, which flashes just as hard). 94 raisers survive both rules. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
93c4a21be5
commit
ca3e72d0a9
8 files changed
+81
-47
No files matched your search
+12
@@ -378,6 +378,11 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
|
|||||||
(`HUD`, in portrait logical px — landscape has a shorter band, so the rule is conservative
|
(`HUD`, in portrait logical px — landscape has a shorter band, so the rule is conservative
|
||||||
there rather than over-eager).
|
there rather than over-eager).
|
||||||
Result: 92 of 101 raisers below the board's bottom edge, against 103 of 134 before.
|
Result: 92 of 101 raisers below the board's bottom edge, against 103 of 134 before.
|
||||||
|
- **A raise must be ARMS OVER STAND, and `_crowdpass.py` tests all three words.** The rolls
|
||||||
|
repaint clothing as well as posing people, so "was stand, is now person" also catches a
|
||||||
|
cream shirt that came back a shade brighter (`PALE_MAX`) and a genuine arm drawn over
|
||||||
|
something already bright, where raising him DELETES a white block (`COVER_MAX`). Both flash
|
||||||
|
exactly as hard as a real error would.
|
||||||
- **A raiser is ~8x6 logical px, so a pose that appears and holds is invisible.** What reads as
|
- **A raiser is ~8x6 logical px, so a pose that appears and holds is invisible.** What reads as
|
||||||
applause is the CYCLE — arms high, hands together, up, down, at about 3.5 Hz — and how many people
|
applause is the CYCLE — arms high, hands together, up, down, at about 3.5 Hz — and how many people
|
||||||
are doing it at once (`crowd.pop`). Oliver on the first per-person cut: "when clapping I barely see
|
are doing it at once (`crowd.pop`). Oliver on the first per-person cut: "when clapping I barely see
|
||||||
@@ -401,6 +406,13 @@ zombie (now an occasional opponent, `TUNE.racketEvery`, not the every-game fixtu
|
|||||||
`assets/_sheet_crowd1.png` is the pre-brightening original of the FIRST crowd, kept for history.
|
`assets/_sheet_crowd1.png` is the pre-brightening original of the FIRST crowd, kept for history.
|
||||||
|
|
||||||
## Settled feel decisions — do not regress silently
|
## Settled feel decisions — do not regress silently
|
||||||
|
- **ANYTHING DRAWN OVER THE CACHED STAND MUST CARRY THE STAND'S OWN TREATMENTS.** There are two —
|
||||||
|
`standDim` and `topFade` — and a raiser box drawn with one of them missing lights up as a bright
|
||||||
|
rectangle every time that spectator stands. That is what the "white flashing in the upper right
|
||||||
|
corner of the crowd" was (2026-08-21): the top fade was baked into the backdrop and the live
|
||||||
|
raisers were not repainting it. Both now come from one function each, called from `paintBackdrop`
|
||||||
|
and from `drawRaisers`. The gradient is built in USER space, so filling any sub-rect with it picks
|
||||||
|
up the right alpha for free. Two copies of either number is the same bug waiting again.
|
||||||
- **The frame is dark at BOTH ends.** The run-off apron already took the bottom of the screen down
|
- **The frame is dark at BOTH ends.** The run-off apron already took the bottom of the screen down
|
||||||
to near-black below the near baseline; `TUNE.standTop` does the same at the top, so the stand fades
|
to near-black below the near baseline; `TUNE.standTop` does the same at the top, so the stand fades
|
||||||
UP out of the dark instead of being cut off at y = 0. Oliver, 2026-08-21: "the bottom of the screen
|
UP out of the dark instead of being cut off at y = 0. Oliver, 2026-08-21: "the bottom of the screen
|
||||||
|
|||||||
@@ -76,6 +76,19 @@ HUD = [(6, 6, 156, 62), # scoreboard + the GAME/SETS panel under it
|
|||||||
(170, 6, 264, 30)] # the BLOOD panel, clear of the quit chip
|
(170, 6, 264, 30)] # the BLOOD panel, clear of the quit chip
|
||||||
|
|
||||||
MIN_AREA, MAX_AREA = 150, 3000 # an arm blob: one pair of raised arms, or one arm
|
MIN_AREA, MAX_AREA = 150, 3000 # an arm blob: one pair of raised arms, or one arm
|
||||||
|
# ...AND IT HAS TO BE ARMS GOING UP OVER STAND. Oliver: "what is this white flashing while applause
|
||||||
|
# in the upper right corner of the crowd" — and with the photographers switched off entirely it was
|
||||||
|
# still there, so it was never them. Two different blobs were doing it, and neither is a raise:
|
||||||
|
# PALE SWAPS — the roll repainted somebody's cream shirt, and `stand()` (which only asks whether a
|
||||||
|
# pixel matches its row's modal colour) called the old one stand. Nothing rises; a white block
|
||||||
|
# just changes pattern at 3.5 Hz.
|
||||||
|
# BRIGHT COVER-UPS — a genuine arm, but drawn over something ALREADY BRIGHT (a white shirt in the
|
||||||
|
# row behind, lum 239). Raising him deletes a white block and sitting him down brings it back,
|
||||||
|
# which flashes exactly as hard as adding one would.
|
||||||
|
# So a blob must be warm-ish, must not be a pale block, and must ADD light to something dark.
|
||||||
|
PALE_MAX = 0.35 # of the blob may be bright-and-colourless (a cream shirt)
|
||||||
|
COVER_MAX = 150 # ...and what it covers in the seated frame must be darker than this
|
||||||
|
LIFT_MIN = 12 # ...by at least this much: arms over wall, never over a white shirt
|
||||||
ARM_H, ARM_W = (10, 70), (8, 90) # ...and its shape, in px of the 1408x768 sheet
|
ARM_H, ARM_W = (10, 70), (8, 90) # ...and its shape, in px of the 1408x768 sheet
|
||||||
BAND = 8 # rows the background colour is sampled over
|
BAND = 8 # rows the background colour is sampled over
|
||||||
PAD = 3 # px of margin around a raiser's box
|
PAD = 3 # px of margin around a raiser's box
|
||||||
@@ -127,6 +140,13 @@ def raisers(A, B):
|
|||||||
# sheet; arms that rise out of empty stand belong to nobody and read as floating hands.
|
# sheet; arms that rise out of empty stand belong to nobody and read as floating hands.
|
||||||
if bgA[sl[0].stop:min(A.shape[0], sl[0].stop + 6), sl[1]].mean() > 0.55:
|
if bgA[sl[0].stop:min(A.shape[0], sl[0].stop + 6), sl[1]].mean() > 0.55:
|
||||||
continue
|
continue
|
||||||
|
# ...AND IT HAS TO BE A RAISE (see PALE_MAX / COVER_MAX / LIFT_MIN above).
|
||||||
|
m = lab[sl] == i + 1
|
||||||
|
px, was = B[sl][m].astype(int), A[sl][m].astype(int)
|
||||||
|
if ((abs(px[:, 0] - px[:, 2]) < 26) & (px[:, 0] > 140)).mean() > PALE_MAX:
|
||||||
|
continue
|
||||||
|
if was.mean() > COVER_MAX or px.mean() - was.mean() < LIFT_MIN:
|
||||||
|
continue
|
||||||
out.append([sl[0].start, sl[1].start, sl[0].stop, sl[1].stop, i + 1])
|
out.append([sl[0].start, sl[1].start, sl[0].stop, sl[1].stop, i + 1])
|
||||||
return out, lab
|
return out, lab
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
+1
-1
@@ -664,6 +664,6 @@ if (location.hostname !== 'splatter-tennis.wuwi.one' && !window.Capacitor?.isNat
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<script type="module" src="src/main.js?v=303"></script>
|
<script type="module" src="src/main.js?v=304"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
+29
-36
@@ -12,101 +12,94 @@ export const RAISERS = [
|
|||||||
[-0.0014, 0.6458, 0.0327, 0.0560, 2],
|
[-0.0014, 0.6458, 0.0327, 0.0560, 2],
|
||||||
[-0.0014, 0.7682, 0.0419, 0.0221, 2],
|
[-0.0014, 0.7682, 0.0419, 0.0221, 2],
|
||||||
[-0.0014, 0.8451, 0.0327, 0.0521, 3],
|
[-0.0014, 0.8451, 0.0327, 0.0521, 3],
|
||||||
[0.0028, 0.7878, 0.0369, 0.0286, 2],
|
[0.0064, 0.3190, 0.0206, 0.0286, 2],
|
||||||
[0.0064, 0.3190, 0.0206, 0.0286, 3],
|
|
||||||
[0.0071, 0.9128, 0.0369, 0.0286, 3],
|
[0.0071, 0.9128, 0.0369, 0.0286, 3],
|
||||||
[0.0234, 0.5521, 0.0163, 0.0456, 1],
|
|
||||||
[0.0234, 0.9440, 0.0206, 0.0286, 2],
|
[0.0234, 0.9440, 0.0206, 0.0286, 2],
|
||||||
[0.0355, 0.6419, 0.0753, 0.0677, 3],
|
[0.0355, 0.6419, 0.0753, 0.0677, 3],
|
||||||
[0.0568, 0.8503, 0.0412, 0.0273, 1],
|
[0.0568, 0.8503, 0.0412, 0.0273, 1],
|
||||||
[0.0689, 0.3190, 0.0334, 0.0286, 2],
|
[0.0689, 0.3190, 0.0334, 0.0286, 2],
|
||||||
[0.0859, 0.7669, 0.0249, 0.0247, 2],
|
[0.0859, 0.7669, 0.0249, 0.0247, 2],
|
||||||
[0.0952, 0.5586, 0.0320, 0.0690, 3],
|
[0.0952, 0.5755, 0.0284, 0.0521, 2],
|
||||||
[0.0980, 0.9544, 0.0419, 0.0286, 2],
|
|
||||||
[0.1065, 0.8086, 0.0206, 0.0273, 3],
|
|
||||||
[0.1278, 0.6719, 0.0284, 0.0299, 2],
|
[0.1278, 0.6719, 0.0284, 0.0299, 2],
|
||||||
[0.1293, 0.5000, 0.0511, 0.0755, 1],
|
|
||||||
[0.1357, 0.7930, 0.1037, 0.0547, 3],
|
|
||||||
[0.1392, 0.9362, 0.0213, 0.0234, 2],
|
[0.1392, 0.9362, 0.0213, 0.0234, 2],
|
||||||
[0.1399, 0.3190, 0.0249, 0.0286, 2],
|
[0.1399, 0.3190, 0.0249, 0.0286, 2],
|
||||||
[0.1562, 0.6732, 0.0206, 0.0286, 2],
|
[0.1562, 0.6732, 0.0206, 0.0286, 2],
|
||||||
[0.1598, 0.9518, 0.0213, 0.0234, 2],
|
[0.1598, 0.9518, 0.0213, 0.0234, 2],
|
||||||
[0.1619, 0.6003, 0.0199, 0.0286, 2],
|
|
||||||
[0.1641, 0.8672, 0.0298, 0.0430, 2],
|
[0.1641, 0.8672, 0.0298, 0.0430, 2],
|
||||||
[0.1690, 0.9753, 0.0291, 0.0221, 2],
|
|
||||||
[0.1768, 0.7305, 0.0376, 0.0299, 1],
|
[0.1768, 0.7305, 0.0376, 0.0299, 1],
|
||||||
[0.1854, 0.5052, 0.0170, 0.0469, 1],
|
[0.1854, 0.7982, 0.0540, 0.0495, 2],
|
||||||
[0.1918, 0.5964, 0.0526, 0.0326, 2],
|
[0.1918, 0.5964, 0.0526, 0.0326, 2],
|
||||||
[0.2259, 0.4857, 0.0732, 0.0911, 3],
|
|
||||||
[0.2393, 0.8594, 0.0298, 0.0299, 2],
|
[0.2393, 0.8594, 0.0298, 0.0299, 2],
|
||||||
[0.2401, 0.7669, 0.0241, 0.0247, 3],
|
|
||||||
[0.2528, 0.9336, 0.0284, 0.0391, 3],
|
[0.2528, 0.9336, 0.0284, 0.0391, 3],
|
||||||
[0.2557, 0.7305, 0.0213, 0.0299, 1],
|
[0.2557, 0.7305, 0.0213, 0.0299, 1],
|
||||||
[0.2599, 0.5924, 0.0384, 0.0365, 2],
|
[0.2599, 0.5924, 0.0384, 0.0365, 2],
|
||||||
[0.2734, 0.6458, 0.0199, 0.0221, 2],
|
[0.2734, 0.6458, 0.0199, 0.0221, 2],
|
||||||
[0.2891, 0.8398, 0.2088, 0.1419, 3],
|
[0.2891, 0.9440, 0.0213, 0.0378, 2],
|
||||||
|
[0.2898, 0.8503, 0.1371, 0.0859, 3],
|
||||||
[0.2976, 0.6732, 0.0170, 0.0326, 2],
|
[0.2976, 0.6732, 0.0170, 0.0326, 2],
|
||||||
[0.2976, 0.8086, 0.0384, 0.0286, 3],
|
|
||||||
[0.3026, 0.7682, 0.0419, 0.0273, 3],
|
[0.3026, 0.7682, 0.0419, 0.0273, 3],
|
||||||
[0.3359, 0.4844, 0.0724, 0.0911, 3],
|
[0.3359, 0.4922, 0.0575, 0.0833, 2],
|
||||||
|
[0.3565, 0.9440, 0.0206, 0.0378, 2],
|
||||||
[0.3729, 0.6602, 0.0206, 0.0312, 2],
|
[0.3729, 0.6602, 0.0206, 0.0312, 2],
|
||||||
[0.3899, 0.6003, 0.0447, 0.0391, 2],
|
[0.3899, 0.6003, 0.0241, 0.0286, 2],
|
||||||
|
[0.3899, 0.9440, 0.0206, 0.0286, 2],
|
||||||
[0.3977, 0.6523, 0.0831, 0.0638, 3],
|
[0.3977, 0.6523, 0.0831, 0.0638, 3],
|
||||||
[0.4055, 0.7669, 0.0724, 0.0690, 3],
|
[0.4055, 0.8008, 0.0213, 0.0352, 1],
|
||||||
[0.4062, 0.4857, 0.0376, 0.1133, 3],
|
[0.4233, 0.7669, 0.0504, 0.0247, 2],
|
||||||
|
[0.4354, 0.8438, 0.0291, 0.0534, 3],
|
||||||
|
[0.4389, 0.9362, 0.0220, 0.0234, 2],
|
||||||
|
[0.4602, 0.9427, 0.0170, 0.0299, 2],
|
||||||
[0.4730, 0.5534, 0.0291, 0.0508, 3],
|
[0.4730, 0.5534, 0.0291, 0.0508, 3],
|
||||||
|
[0.4730, 0.8672, 0.0249, 0.0221, 2],
|
||||||
[0.4901, 0.6458, 0.0533, 0.0560, 2],
|
[0.4901, 0.6458, 0.0533, 0.0560, 2],
|
||||||
[0.4936, 0.7044, 0.0298, 0.0247, 2],
|
[0.4936, 0.7044, 0.0298, 0.0247, 2],
|
||||||
[0.4936, 0.7669, 0.0497, 0.0247, 2],
|
[0.4936, 0.7669, 0.0497, 0.0247, 2],
|
||||||
[0.5021, 0.8503, 0.0291, 0.0312, 3],
|
[0.5021, 0.8503, 0.0291, 0.0312, 3],
|
||||||
[0.5064, 0.3190, 0.0206, 0.0286, 2],
|
[0.5064, 0.3190, 0.0206, 0.0286, 2],
|
||||||
[0.5064, 0.5755, 0.0206, 0.0234, 1],
|
[0.5064, 0.5755, 0.0206, 0.0234, 1],
|
||||||
[0.5064, 0.9049, 0.0241, 0.0260, 3],
|
|
||||||
[0.5312, 0.9141, 0.0831, 0.0690, 3],
|
|
||||||
[0.5355, 0.8086, 0.0249, 0.0286, 3],
|
|
||||||
[0.5398, 0.4922, 0.1300, 0.1367, 3],
|
|
||||||
[0.5611, 0.6719, 0.0291, 0.0299, 2],
|
[0.5611, 0.6719, 0.0291, 0.0299, 2],
|
||||||
[0.5646, 0.7878, 0.0668, 0.0391, 3],
|
|
||||||
[0.5682, 0.1562, 0.0334, 0.0247, 1],
|
|
||||||
[0.5682, 0.8776, 0.0298, 0.0221, 2],
|
[0.5682, 0.8776, 0.0298, 0.0221, 2],
|
||||||
[0.5689, 0.3190, 0.0334, 0.0286, 2],
|
[0.5689, 0.3190, 0.0334, 0.0286, 2],
|
||||||
|
[0.5724, 0.9362, 0.0220, 0.0234, 2],
|
||||||
[0.5895, 0.6732, 0.0192, 0.0286, 2],
|
[0.5895, 0.6732, 0.0192, 0.0286, 2],
|
||||||
[0.5938, 0.1107, 0.0462, 0.0312, 2],
|
[0.5938, 0.1107, 0.0462, 0.0312, 2],
|
||||||
|
[0.5938, 0.5534, 0.0334, 0.0299, 3],
|
||||||
|
[0.5959, 0.5846, 0.0149, 0.0443, 3],
|
||||||
[0.6023, 0.2643, 0.0249, 0.0208, 2],
|
[0.6023, 0.2643, 0.0249, 0.0208, 2],
|
||||||
|
[0.6186, 0.5911, 0.0213, 0.0378, 2],
|
||||||
[0.6186, 0.9362, 0.0249, 0.0365, 3],
|
[0.6186, 0.9362, 0.0249, 0.0365, 3],
|
||||||
[0.6357, 0.7227, 0.0284, 0.0208, 2],
|
[0.6357, 0.7227, 0.0284, 0.0208, 2],
|
||||||
[0.6357, 0.8516, 0.0284, 0.0273, 3],
|
[0.6357, 0.8516, 0.0284, 0.0273, 3],
|
||||||
[0.6371, 0.6458, 0.1271, 0.0703, 3],
|
[0.6371, 0.6458, 0.1271, 0.0703, 3],
|
||||||
[0.6399, 0.3190, 0.0249, 0.0286, 2],
|
[0.6399, 0.3190, 0.0249, 0.0286, 2],
|
||||||
[0.6776, 0.6003, 0.0249, 0.0286, 2],
|
[0.6776, 0.6003, 0.0249, 0.0286, 2],
|
||||||
[0.6925, 0.4870, 0.1016, 0.1146, 3],
|
[0.7053, 0.9297, 0.0419, 0.0430, 2],
|
||||||
[0.6974, 0.9271, 0.0497, 0.0456, 3],
|
|
||||||
[0.7230, 0.7669, 0.0412, 0.0312, 2],
|
[0.7230, 0.7669, 0.0412, 0.0312, 2],
|
||||||
[0.7393, 0.8672, 0.0213, 0.0234, 2],
|
[0.7393, 0.8672, 0.0213, 0.0234, 2],
|
||||||
[0.7401, 0.5990, 0.0327, 0.0299, 2],
|
[0.7401, 0.5990, 0.0327, 0.0299, 2],
|
||||||
[0.7401, 0.8398, 0.0327, 0.0273, 1],
|
[0.7401, 0.8398, 0.0327, 0.0273, 1],
|
||||||
[0.7727, 0.8086, 0.0923, 0.0729, 3],
|
[0.7692, 0.5755, 0.0249, 0.0234, 1],
|
||||||
[0.7940, 0.8828, 0.0788, 0.0586, 3],
|
[0.7727, 0.8503, 0.0916, 0.0312, 3],
|
||||||
[0.7940, 0.9440, 0.0163, 0.0286, 2],
|
[0.7940, 0.9440, 0.0163, 0.0286, 2],
|
||||||
[0.7983, 0.6732, 0.0163, 0.0326, 2],
|
[0.7983, 0.6732, 0.0163, 0.0326, 2],
|
||||||
[0.8026, 0.2253, 0.0241, 0.0247, 2],
|
|
||||||
[0.8068, 0.7695, 0.0419, 0.0260, 3],
|
[0.8068, 0.7695, 0.0419, 0.0260, 3],
|
||||||
|
[0.8182, 0.9023, 0.0547, 0.0391, 3],
|
||||||
[0.8565, 0.9440, 0.0206, 0.0378, 2],
|
[0.8565, 0.9440, 0.0206, 0.0378, 2],
|
||||||
[0.8622, 0.4844, 0.0817, 0.1549, 3],
|
[0.8622, 0.4922, 0.0312, 0.0742, 2],
|
||||||
[0.8686, 0.8503, 0.0291, 0.0326, 3],
|
[0.8686, 0.8503, 0.0291, 0.0326, 3],
|
||||||
[0.8693, 0.2878, 0.0327, 0.0260, 2],
|
[0.8899, 0.6003, 0.0241, 0.0286, 2],
|
||||||
[0.8771, 0.2253, 0.0206, 0.0365, 3],
|
|
||||||
[0.8899, 0.9440, 0.0206, 0.0378, 2],
|
[0.8899, 0.9440, 0.0206, 0.0378, 2],
|
||||||
[0.8977, 0.6732, 0.0249, 0.0286, 2],
|
[0.8977, 0.6732, 0.0249, 0.0286, 2],
|
||||||
[0.8984, 0.8503, 0.0284, 0.0234, 1],
|
[0.8984, 0.8503, 0.0284, 0.0234, 1],
|
||||||
[0.9048, 0.2604, 0.0220, 0.0247, 1],
|
[0.9062, 0.5755, 0.0206, 0.0234, 1],
|
||||||
[0.9062, 0.7982, 0.0249, 0.0378, 3],
|
[0.9062, 0.8008, 0.0206, 0.0352, 1],
|
||||||
[0.9062, 0.8776, 0.0206, 0.0326, 3],
|
[0.9062, 0.8776, 0.0206, 0.0326, 3],
|
||||||
[0.9233, 0.6523, 0.0582, 0.0599, 3],
|
[0.9233, 0.6523, 0.0582, 0.0599, 3],
|
||||||
[0.9240, 0.7669, 0.0533, 0.0247, 2],
|
[0.9240, 0.7669, 0.0533, 0.0247, 2],
|
||||||
[0.9240, 0.9271, 0.0533, 0.0456, 3],
|
|
||||||
[0.9354, 0.2461, 0.0291, 0.0286, 2],
|
[0.9354, 0.2461, 0.0291, 0.0286, 2],
|
||||||
[0.9354, 0.8438, 0.0291, 0.0534, 3],
|
[0.9354, 0.8438, 0.0291, 0.0534, 3],
|
||||||
|
[0.9389, 0.9362, 0.0220, 0.0234, 2],
|
||||||
|
[0.9602, 0.9440, 0.0170, 0.0286, 2],
|
||||||
[0.9730, 0.5586, 0.0284, 0.0456, 3],
|
[0.9730, 0.5586, 0.0284, 0.0456, 3],
|
||||||
[0.9730, 0.8672, 0.0249, 0.0234, 2],
|
[0.9730, 0.8672, 0.0249, 0.0234, 2],
|
||||||
];
|
];
|
||||||
+19
-10
@@ -235,7 +235,7 @@ function farB(z) {
|
|||||||
// Asset cache-buster — bump with main.js?v=N (see the img.src note below). EXPORTED because the
|
// Asset cache-buster — bump with main.js?v=N (see the img.src note below). EXPORTED because the
|
||||||
// menu screens hang <img> tags on the same files, and two copies of this number is one copy too
|
// menu screens hang <img> tags on the same files, and two copies of this number is one copy too
|
||||||
// many: the one that does not get bumped is the one that serves a cached 404.
|
// many: the one that does not get bumped is the one that serves a cached 404.
|
||||||
export const SPRV = 147;
|
export const SPRV = 148;
|
||||||
// The boot bar in main.js watches this. Nothing here CHANGES when things load — every sprite was
|
// The boot bar in main.js watches this. Nothing here CHANGES when things load — every sprite was
|
||||||
// already requested at import — it just makes the wait visible and holds the menu back until the
|
// already requested at import — it just makes the wait visible and holds the menu back until the
|
||||||
// last sheet has landed. See the onerror note below for the other half of "sometimes missing".
|
// last sheet has landed. See the onerror note below for the other half of "sometimes missing".
|
||||||
@@ -443,11 +443,25 @@ const standDim = pt => Math.min(0.88, (court.dim ?? TUNE.standBack) + 0.26 * pt)
|
|||||||
// looks pretty artificial").
|
// looks pretty artificial").
|
||||||
// The sub-rect is drawn at EXACTLY the scale paintBackdrop used for the whole sheet (kx/ky below),
|
// The sub-rect is drawn at EXACTLY the scale paintBackdrop used for the whole sheet (kx/ky below),
|
||||||
// which is what guarantees the raised arms land on the same pixel grid as the body under them.
|
// which is what guarantees the raised arms land on the same pixel grid as the body under them.
|
||||||
|
// THE TOP FADE, in ONE place. It is baked into the cached stand, and the live raisers have to paint
|
||||||
|
// it over themselves as well — a spectator whose box was redrawn without it lit up as a bright
|
||||||
|
// rectangle every time he stood, which is what Oliver saw: "what is this white flashing while
|
||||||
|
// applause in the upper right corner of the crowd". Same class of bug as two copies of standDim.
|
||||||
|
// A gradient in user space, so filling ANY sub-rect with it picks up the right alpha for free.
|
||||||
|
function topFade(c, standsBottom) {
|
||||||
|
if (!(TUNE.standTop > 0)) return null;
|
||||||
|
const g = c.createLinearGradient(0, -8, 0, standsBottom * 0.42);
|
||||||
|
g.addColorStop(0, `rgba(6,10,6,${TUNE.standTop})`);
|
||||||
|
g.addColorStop(1, 'rgba(6,10,6,0)');
|
||||||
|
return g;
|
||||||
|
}
|
||||||
|
|
||||||
const rnd = i => ((i * 9301 + 49297) % 233280) / 233280; // one stable pseudo-random per spectator
|
const rnd = i => ((i * 9301 + 49297) % 233280) / 233280; // one stable pseudo-random per spectator
|
||||||
function drawRaisers(img, standsBottom, pt, frameOf) {
|
function drawRaisers(img, standsBottom, pt, frameOf) {
|
||||||
const fh = img.height / FRAMES, crowdH = standsBottom - AD_H + 2;
|
const fh = img.height / FRAMES, crowdH = standsBottom - AD_H + 2;
|
||||||
const kx = W / img.width, ky = (crowdH + 2) / fh;
|
const kx = W / img.width, ky = (crowdH + 2) / fh;
|
||||||
const d = standDim(pt), tint = d > 0 ? `rgba(12,8,20,${d})` : null;
|
const d = standDim(pt), tint = d > 0 ? `rgba(12,8,20,${d})` : null;
|
||||||
|
const fade = topFade(ctx, standsBottom);
|
||||||
let open = false;
|
let open = false;
|
||||||
for (let i = 0; i < RAISERS.length; i++) {
|
for (let i = 0; i < RAISERS.length; i++) {
|
||||||
const r = RAISERS[i], f = frameOf(i, r[0], r[4]);
|
const r = RAISERS[i], f = frameOf(i, r[0], r[4]);
|
||||||
@@ -458,8 +472,9 @@ function drawRaisers(img, standsBottom, pt, frameOf) {
|
|||||||
}
|
}
|
||||||
const sx = r[0] * img.width, sy = r[1] * fh, sw = r[2] * img.width, sh = r[3] * fh;
|
const sx = r[0] * img.width, sy = r[1] * fh, sw = r[2] * img.width, sh = r[3] * fh;
|
||||||
ctx.drawImage(img, sx, sy + f * fh, sw, sh, sx * kx, sy * ky, sw * kx + 0.5, sh * ky + 0.5);
|
ctx.drawImage(img, sx, sy + f * fh, sw, sh, sx * kx, sy * ky, sw * kx + 0.5, sh * ky + 0.5);
|
||||||
// re-tinted like the cached stand, so a raised pair of arms cannot pop brighter than the rot
|
// re-tinted AND re-faded exactly like the cached stand underneath, or the box lights up
|
||||||
if (tint) { ctx.fillStyle = tint; ctx.fillRect(sx * kx, sy * ky, sw * kx + 0.5, sh * ky + 0.5); }
|
if (tint) { ctx.fillStyle = tint; ctx.fillRect(sx * kx, sy * ky, sw * kx + 0.5, sh * ky + 0.5); }
|
||||||
|
if (fade) { ctx.fillStyle = fade; ctx.fillRect(sx * kx, sy * ky, sw * kx + 0.5, sh * ky + 0.5); }
|
||||||
}
|
}
|
||||||
if (open) ctx.restore();
|
if (open) ctx.restore();
|
||||||
}
|
}
|
||||||
@@ -514,14 +529,8 @@ function paintBackdrop(c, pal, pt) {
|
|||||||
// function): the stand is the far edge of the frame, and a hard cut at y = 0 reads as a
|
// function): the stand is the far edge of the frame, and a hard cut at y = 0 reads as a
|
||||||
// photograph that has been cropped rather than as a stadium with a roof somewhere above it.
|
// photograph that has been cropped rather than as a stadium with a roof somewhere above it.
|
||||||
// It also happens to be where the scoreboard sits, which is the second reason it earns its keep.
|
// It also happens to be where the scoreboard sits, which is the second reason it earns its keep.
|
||||||
if (TUNE.standTop > 0) {
|
const fade = topFade(c, standsBottom);
|
||||||
const deep = standsBottom * 0.42;
|
if (fade) { c.fillStyle = fade; c.fillRect(-8, -8, W + 16, standsBottom * 0.42 + 8); }
|
||||||
const g = c.createLinearGradient(0, -8, 0, deep);
|
|
||||||
g.addColorStop(0, `rgba(6,10,6,${TUNE.standTop})`);
|
|
||||||
g.addColorStop(1, 'rgba(6,10,6,0)');
|
|
||||||
c.fillStyle = g;
|
|
||||||
c.fillRect(-8, -8, W + 16, deep + 8);
|
|
||||||
}
|
|
||||||
// ground + court (Super Tennis lawn); everything outside the doubles court is OUT
|
// ground + court (Super Tennis lawn); everything outside the doubles court is OUT
|
||||||
const dw = COURT.dblW / 2;
|
const dw = COURT.dblW / 2;
|
||||||
quadXZ(-14, -6, 14, 30, pal.out); // out area. NEVER let z approach
|
quadXZ(-14, -6, 14, 30, pal.out); // out area. NEVER let z approach
|
||||||
|
|||||||
Reference in new issue
Block a user