Add native Durak, poker, blackjack, roulette, Buckshot and billiards scenes with animation assets and regression tests. Improve arrival, city, hall, profiles, shops, audio and exit handling; remove the portable C game core and refresh shipping executables.
56 lines
2.1 KiB
Python
56 lines
2.1 KiB
Python
"""Small original PCM effects for UI, dice and skill checks; offline only."""
|
|
import math
|
|
from pathlib import Path
|
|
import random
|
|
import struct
|
|
import wave
|
|
|
|
RATE = 44100
|
|
TARGET = Path(__file__).resolve().parents[2] / "assets/audio/generated"
|
|
|
|
|
|
def save(name, samples):
|
|
with wave.open(str(TARGET / name), "wb") as output:
|
|
output.setparams((1, 2, RATE, 0, "NONE", "not compressed"))
|
|
output.writeframes(b"".join(struct.pack("<h", round(max(-1, min(1, v)) * 28000)) for v in samples))
|
|
|
|
|
|
def tones(name, notes, spacing, duration, gain=0.2):
|
|
samples = [0.0] * round(duration * RATE)
|
|
for step, frequency in enumerate(notes):
|
|
start = round(step * spacing * RATE)
|
|
for index in range(start, len(samples)):
|
|
t = (index - start) / RATE
|
|
envelope = min(1, t / 0.003) * math.exp(-t * 26)
|
|
samples[index] += gain * envelope * math.sin(2 * math.pi * frequency * t)
|
|
save(name, samples)
|
|
|
|
|
|
def main():
|
|
TARGET.mkdir(parents=True, exist_ok=True)
|
|
tones("ui-tick.wav", [1300], 0, 0.075, 0.07)
|
|
tones("round-win.wav", [523, 659, 784], 0.09, 0.5)
|
|
tones("round-loss.wav", [392, 311], 0.10, 0.35, 0.14)
|
|
tones("skill-hit.wav", [740, 988], 0.04, 0.20, 0.12)
|
|
tones("skill-perfect.wav", [880, 1175, 1568], 0.04, 0.26, 0.15)
|
|
tones("skill-miss.wav", [185, 147], 0.04, 0.20, 0.13)
|
|
rng = random.Random(4619)
|
|
samples = [0.0] * round(1.6 * RATE)
|
|
for hit, start in enumerate([0.03, 0.18, 0.48, 0.51, 0.73, 0.94, 0.97, 1.11, 1.29, 1.32]):
|
|
amplitude = 0.24 * (1 - start / 2)
|
|
offset = round(start * RATE)
|
|
pitch = rng.randrange(850, 1600)
|
|
for index in range(round(0.16 * RATE)):
|
|
if offset + index >= len(samples):
|
|
break
|
|
t = index / RATE
|
|
attack = min(1, t / 0.0007)
|
|
click = rng.uniform(-1, 1) * math.exp(-t * 130)
|
|
knock = math.sin(2 * math.pi * pitch * t) * math.exp(-t * 60)
|
|
samples[offset + index] += amplitude * attack * (click + 0.4 * knock)
|
|
save("dice-roll.wav", samples)
|
|
print("Generated 7 short game effects; original recordings unchanged.")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|