Compare commits

2 Commits
Author SHA1 Message Date
adrien b3f576b000 music pause 2026-10-05 19:32:23 +02:00
adrien b9a5465207 stuff 2026-10-02 20:12:02 +02:00
2 changed files with 61 additions and 74 deletions
-36
View File
@@ -1,36 +0,0 @@
#!/bin/sh
C0=-f16; Db0=-f17; D0=-f18; Eb0=-f19; E0=-f20; F0=-f21; Gb0=-f23; G0=-f24; Ab0=-f25; A0=-f27; Bb0=-f29; B0=-f30
C1=-f32; Db1=-f34; D1=-f36; Eb1=-f38; E1=-f41; F1=-f43; Gb1=-f46; G1=-f49; Ab1=-f51; A1=-f55; Bb1=-f58; B1=-f61
C2=-f65; Db2=-f69; D2=-f73; Eb2=-f77; E2=-f82; F2=-f87; Gb2=-f92; G2=-f98; Ab2=-f103; A2=-f110; Bb2=-f116; B2=-f123
C3=-f130; Db3=-f138; D3=-f146; Eb3=-f155; E3=-f164; F3=-f174; Gb3=-f185; G3=-f196; Ab3=-f207; A3=-f220; Bb3=-f233; B3=-f246
C4=-f261; Db4=-f277; D4=-f293; Eb4=-f311; E4=-f329; F4=-f349; Gb4=-f369; G4=-f392; Ab4=-f415; A4=-f440; Bb4=-f466; B4=-f493
C5=-f523; Db5=-f554; D5=-f587; Eb5=-f622; E5=-f659; F5=-f698; Gb5=-f739; G5=-f783; Ab5=-f830; A5=-f880; Bb5=-f932; B5=-f987
C6=-f1046; Db6=-f1108; D6=-f1174; Eb6=-f1244; E6=-f1318; F6=-f1396; Gb6=-f1479; G6=-f1567; Ab6=-f1661; A6=-f1760; Bb6=-f1864; B6=-f1975
C7=-f2093; Db7=-f2217; D7=-f2349; Eb7=-f2489; E7=-f2637; F7=-f2793; Gb7=-f2959; G7=-f3135; Ab7=-f3322; A7=-f3520; Bb7=-f3729; B7=-f3951
C8=-f4186; Db8=-f4434; D8=-f4698; Eb8=-f4978; E8=-f5274; F8=-f5587; Gb8=-f5919; G8=-f6271; Ab8=-f6644; A8=-f7040; Bb8=-f7458; B8=-f7902
dc=-l100; dcp=-l150; c=-l200; cp=-l300; n=-l400; np=-l600; b=-l800; bp=-l1200; r=-l1600
if command -v beep > /dev/null; then
while [ $? -eq 0 ]; do
beep $n $E5 -n $c $B4 -n $c $C5 -n $c $D5 -n $dc $E5 -n $dc $D5 -n $c $C5 -n $c $B4 \
-n $n $A4 -n $c $A4 -n $c $C5 -n $n $E5 -n $c $D5 -n $c $C5 \
-n $c $B4 -n $c $E4 -n $c $Ab4 -n $c $C5 -n $n $D5 -n $n $E5 \
-n $n $C5 -n $n $A4 -n $n $A4 -n $c $B3 -n $c $C4 \
-n $np $D5 -n $c $F5 -n $c $A5 -n $dc $A5 -n $dc $A5 -n $c $G5 -n $c $F5 \
-n $n $E5 -n $c $E5 -n $c $C5 -n $c $E5 -n $dc $F5 -n $dc $E5 -n $c $D5 -n $c $C5 \
-n $c $B4 -n $c $E4 -n $c $Ab4 -n $c $C5 -n $n $D5 -n $n $E5 \
-n $n $C5 -n $n $A4 -n $b $A4 \
-n $n $E5 -n $c $B4 -n $c $C5 -n $c $D5 -n $dc $E5 -n $dc $D5 -n $c $C5 -n $c $B4 \
-n $n $A4 -n $c $A4 -n $c $C5 -n $n $E5 -n $c $D5 -n $c $C5 \
-n $c $B4 -n $c $E4 -n $c $Ab4 -n $c $C5 -n $n $D5 -n $n $E5 \
-n $n $C5 -n $n $A4 -n $n $A4 -n $c $B3 -n $c $C4 \
-n $np $D5 -n $c $F5 -n $c $A5 -n $dc $A5 -n $dc $A5 -n $c $G5 -n $c $F5 \
-n $n $E5 -n $c $E5 -n $c $C5 -n $c $E5 -n $dc $F5 -n $dc $E5 -n $c $D5 -n $c $C5 \
-n $c $B4 -n $c $E4 -n $c $Ab4 -n $c $C5 -n $n $D5 -n $n $E5 \
-n $n $C5 -n $n $A4 -n $b $A4 \
-n $b $E5 -n $b $C5 -n $b $D5 -n $b $B4 -n $b $C5 -n $b $A4 -n $b $Ab4 -n $c $B4 -n $c $E4 -n $c $Ab4 -n $c $B4 \
-n $b $E5 -n $b $C5 -n $b $D5 -n $b $B4 -n $n $C5 -n $n $E5 -n $n $A5 -n $n $A5 -n $r $Ab5 > /dev/null
done
fi
+54 -31
View File
@@ -1,9 +1,11 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys import sys
import os import os
import subprocess import subprocess
import psutil import signal
try: try:
import curses import curses
@@ -25,9 +27,11 @@ import subprocess
try: try:
from configparser import ConfigParser from configparser import ConfigParser
except ImportError:
try:
from configparser import SafeConfigParser as ConfigParser
except ImportError: # Python2 except ImportError: # Python2
from ConfigParser import SafeConfigParser as ConfigParser import ConfigParser
DIR_NAME = "Terminis" DIR_NAME = "Terminis"
HELP_MSG = """terminis [options] HELP_MSG = """terminis [options]
@@ -254,7 +258,8 @@ class Window:
def __init__(self, width, height, begin_x, begin_y): def __init__(self, width, height, begin_x, begin_y):
self.window = curses.newwin(height, width, begin_y, begin_x) self.window = curses.newwin(height, width, begin_y, begin_x)
if self.TITLE: if self.TITLE:
self.title_begin_x = (width-len(self.TITLE)) // 2 + 1 self.title = "[" + self.TITLE + "]"
self.title_begin_x = (width-len(self.title)) // 2 + 1
self.piece = None self.piece = None
self.refresh() self.refresh()
@@ -262,7 +267,7 @@ class Window:
self.window.erase() self.window.erase()
self.window.border() self.window.border()
if self.TITLE: if self.TITLE:
self.window.addstr(0, self.title_begin_x, self.TITLE, curses.A_BOLD) self.window.addstr(0, self.title_begin_x, self.title, curses.A_BOLD)
def draw_piece(self): def draw_piece(self):
if self.piece: if self.piece:
@@ -506,9 +511,9 @@ class ControlsParser(ConfigParser):
SECTION = "CONTROLS" SECTION = "CONTROLS"
COMMENT = """# You can change key below. COMMENT = """# You can change key below.
# Acceptable values are: # Acceptable values are:
# `SPACE`, `TAB`, `ENTER`, # - `SPACE`, `TAB`, `ENTER`,
# printable characters (`q`, `*`...) (case sensitive), # - printable characters (`q`, `*`...) (case sensitive),
# curses's constants name starting with `KEY_` # - curses's constants name starting with `KEY_`
# See https://docs.python.org/3/library/curses.html?highlight=curses#constants # See https://docs.python.org/3/library/curses.html?highlight=curses#constants
""" """
@@ -585,18 +590,38 @@ class ControlsWindow(Window, ControlsParser):
class Music: class Music:
PATH = os.path.join(os.path.dirname(__file__), "music.sh")
def __init__(self): def __init__(self):
self.process = None self.process = None
def play(self): def play(self):
self.process = subprocess.Popen(["sh", self.PATH]) try:
self.process = subprocess.Popen(["beep", "-l400", "-f659", "-n", "-l200", "-f493", "-n", "-l200", "-f523", "-n", "-l200", "-f587", "-n", "-l100", "-f659", "-n", "-l100", "-f587", "-n", "-l200", "-f523", "-n", "-l200", "-f493", "-n", "-l400", "-f440", "-n", "-l200", "-f440", "-n", "-l200", "-f523", "-n", "-l400", "-f659", "-n", "-l200", "-f587", "-n", "-l200", "-f523", "-n", "-l200", "-f493", "-n", "-l200", "-f329", "-n", "-l200", "-f415", "-n", "-l200", "-f523", "-n", "-l400", "-f587", "-n", "-l400", "-f659", "-n", "-l400", "-f523", "-n", "-l400", "-f440", "-n", "-l400", "-f440", "-n", "-l200", "-f246", "-n", "-l200", "-f261", "-n", "-l600", "-f587", "-n", "-l200", "-f698", "-n", "-l200", "-f880", "-n", "-l100", "-f880", "-n", "-l100", "-f880", "-n", "-l200", "-f783", "-n", "-l200", "-f698", "-n", "-l400", "-f659", "-n", "-l200", "-f659", "-n", "-l200", "-f523", "-n", "-l200", "-f659", "-n", "-l100", "-f698", "-n", "-l100", "-f659", "-n", "-l200", "-f587", "-n", "-l200", "-f523", "-n", "-l200", "-f493", "-n", "-l200", "-f329", "-n", "-l200", "-f415", "-n", "-l200", "-f523", "-n", "-l400", "-f587", "-n", "-l400", "-f659", "-n", "-l400", "-f523", "-n", "-l400", "-f440", "-n", "-l800", "-f440", "-n", "-l400", "-f659", "-n", "-l200", "-f493", "-n", "-l200", "-f523", "-n", "-l200", "-f587", "-n", "-l100", "-f659", "-n", "-l100", "-f587", "-n", "-l200", "-f523", "-n", "-l200", "-f493", "-n", "-l400", "-f440", "-n", "-l200", "-f440", "-n", "-l200", "-f523", "-n", "-l400", "-f659", "-n", "-l200", "-f587", "-n", "-l200", "-f523", "-n", "-l200", "-f493", "-n", "-l200", "-f329", "-n", "-l200", "-f415", "-n", "-l200", "-f523", "-n", "-l400", "-f587", "-n", "-l400", "-f659", "-n", "-l400", "-f523", "-n", "-l400", "-f440", "-n", "-l400", "-f440", "-n", "-l200", "-f246", "-n", "-l200", "-f261", "-n", "-l600", "-f587", "-n", "-l200", "-f698", "-n", "-l200", "-f880", "-n", "-l100", "-f880", "-n", "-l100", "-f880", "-n", "-l200", "-f783", "-n", "-l200", "-f698", "-n", "-l400", "-f659", "-n", "-l200", "-f659", "-n", "-l200", "-f523", "-n", "-l200", "-f659", "-n", "-l100", "-f698", "-n", "-l100", "-f659", "-n", "-l200", "-f587", "-n", "-l200", "-f523", "-n", "-l200", "-f493", "-n", "-l200", "-f329", "-n", "-l200", "-f415", "-n", "-l200", "-f523", "-n", "-l400", "-f587", "-n", "-l400", "-f659", "-n", "-l400", "-f523", "-n", "-l400", "-f440", "-n", "-l800", "-f440", "-n", "-l800", "-f329", "-n", "-l800", "-f261", "-n", "-l800", "-f293", "-n", "-l800", "-f246", "-n", "-l800", "-f261", "-n", "-l800", "-f220", "-n", "-l800", "-f207", "-n", "-l200", "-f246", "-n", "-l200", "-f164", "-n", "-l200", "-f207", "-n", "-l200", "-f246", "-n", "-l800", "-f329", "-n", "-l800", "-f261", "-n", "-l800", "-f293", "-n", "-l800", "-f246", "-n", "-l400", "-f261", "-n", "-l400", "-f329", "-n", "-l400", "-f440", "-n", "-l400", "-f440", "-n", "-l1600", "-f415"])
except FileNotFoundError:
pass
else:
scheduler.repeat("music", 0.02, self.repeat)
def repeat(self):
if self.process:
if self.process.poll() is not None:
self.play()
else:
scheduler.cancel("music")
def pause(self):
if self.process:
scheduler.cancel("music")
self.process.send_signal(signal.SIGSTOP)
subprocess.Popen(["beep", "-l1", "-f1"])
scheduler.repeat("music", 0.02, self.repeat)
def resume(self):
if self.process:
self.process.send_signal(signal.SIGCONT)
def stop(self): def stop(self):
if self.process: if self.process:
for proc in psutil.Process(self.process.pid).children(recursive=True): scheduler.cancel("music")
proc.terminate()
self.process.terminate() self.process.terminate()
self.process = None self.process = None
@@ -612,12 +637,12 @@ class Game:
curses.start_color() curses.start_color()
if curses.can_change_color(): if curses.can_change_color():
curses.init_color(curses.COLOR_YELLOW, 1000, 500, 0) curses.init_color(curses.COLOR_YELLOW, 1000, 500, 0)
for tetromino_class in self.TETROMINOES: for tetromino in self.TETROMINOES:
curses.init_pair(tetromino_class.COLOR, tetromino_class.COLOR, curses.COLOR_WHITE) curses.init_pair(tetromino.COLOR, tetromino.COLOR, curses.COLOR_WHITE)
if tetromino_class.COLOR == curses.COLOR_ORANGE: if tetromino.COLOR == curses.COLOR_ORANGE:
tetromino_class.color_pair = curses.color_pair(curses.COLOR_YELLOW) tetromino.color_pair = curses.color_pair(curses.COLOR_YELLOW)
else: else:
tetromino_class.color_pair = curses.color_pair(tetromino_class.COLOR)|curses.A_BOLD tetromino.color_pair = curses.color_pair(tetromino.COLOR) | curses.A_BOLD
try: try:
curses.curs_set(0) curses.curs_set(0)
except curses.error: except curses.error:
@@ -698,7 +723,7 @@ class Game:
self.matrix.refresh(paused=True) self.matrix.refresh(paused=True)
self.next.refresh(paused=True) self.next.refresh(paused=True)
self.scr.timeout(-1) self.scr.timeout(-1)
self.music.stop() self.music.pause()
while True: while True:
key = self.scr.getkey() key = self.scr.getkey()
@@ -713,7 +738,7 @@ class Game:
self.matrix.refresh() self.matrix.refresh()
self.next.refresh() self.next.refresh()
self.stats.time = time.time() - self.stats.time self.stats.time = time.time() - self.stats.time
self.music.play() self.music.resume()
def swap(self): def swap(self):
if self.matrix.piece.hold_enabled: if self.matrix.piece.hold_enabled:
@@ -728,30 +753,27 @@ class Game:
def over(self): def over(self):
self.stats.time = time.time() - self.stats.time self.stats.time = time.time() - self.stats.time
self.matrix.refresh()
if curses.has_colors(): if curses.has_colors():
for tetromino_class in self.TETROMINOES: for tetromino in self.TETROMINOES:
curses.init_pair(tetromino_class.COLOR, tetromino_class.COLOR, curses.COLOR_BLACK) curses.init_pair(tetromino.COLOR, tetromino.COLOR, curses.COLOR_BLACK if tetromino.COLOR == curses.COLOR_YELLOW else curses.COLOR_WHITE)
for y, word in enumerate((("GA", "ME") ,("OV", "ER")), start=Matrix.NB_LINES // 2): for y, word in enumerate((("GA", "ME") ,("OV", "ER")), start=Matrix.NB_LINES // 2):
for x, syllable in enumerate(word, start=Matrix.NB_COLS//2 - 1): for x, syllable in enumerate(word, start=Matrix.NB_COLS//2 - 1):
color = self.matrix.cells[y][x] color = self.matrix.cells[y][x]
if color is None: self.matrix.window.addstr(y, 2*x + 1, syllable, (color | curses.A_REVERSE) if color else curses.COLOR_BLACK)
color = curses.COLOR_BLACK
else:
color |= curses.A_REVERSE
self.matrix.window.addstr(y, x*2+1, syllable, color)
self.matrix.window.refresh() self.matrix.window.refresh()
curses.beep() curses.beep()
self.scr.timeout(-1) self.scr.timeout(-1)
self.music.stop()
while self.scr.getkey() != self.controls["QUIT"]: while self.scr.getkey() != self.controls["QUIT"]:
pass pass
self.stats.time = time.time() - self.stats.time
self.quit() self.quit()
def quit(self): def quit(self):
self.stats.save() self.stats.save()
t = time.localtime(time.time() - self.stats.time)
self.music.stop() self.music.stop()
t = time.localtime(time.time() - self.stats.time)
sys.exit( sys.exit(
"SCORE\t{:n}\n".format(self.stats.score) + "SCORE\t{:n}\n".format(self.stats.score) +
"HIGH\t{:n}\n".format(self.stats.high_score) + "HIGH\t{:n}\n".format(self.stats.high_score) +
@@ -765,7 +787,7 @@ def main():
if "--help" in sys.argv[1:] or "-h" in sys.argv[1:] or "/?" in sys.argv[1:]: if "--help" in sys.argv[1:] or "-h" in sys.argv[1:] or "/?" in sys.argv[1:]:
print(HELP_MSG) print(HELP_MSG)
else: else:
if "--reset" in sys.argv[1:] or "-r" in sys.argv[1:]: if "-reset" in sys.argv[1:] or "-r" in sys.argv[1:]:
controls = ControlsParser() controls = ControlsParser()
controls.reset() controls.reset()
controls.edit() controls.edit()
@@ -780,3 +802,4 @@ def main():
if __name__ == "__main__": if __name__ == "__main__":
main() main()