feat: show inverted/random fx states

This commit is contained in:
2026-11-02 16:58:58 +01:00
parent 3d50717dbe
commit c96133bfae
4 changed files with 179 additions and 39 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ state_3=14
seed_4=524
state_4=13
seed_5=251
state_5=10
state_5=15
seed_6=808
state_6=4
active_0=0
+27 -10
View File
@@ -17,21 +17,38 @@ BACKGROUND_IMG_PATH = RESOURCES_PATH / "background.png"
ESTIMATED_BOOT_TIME_SECONDS = 18.0
SELECTED_RECT_BOUNDS = [
(10, 14, 28, 32),
(10, 38, 28, 56),
(39, 14, 57, 32),
(39, 38, 57, 56),
(0, 0, 0, 0),
(97, 26, 115, 44),
(10, 14, 28, 32), # SRC A
(10, 38, 28, 56), # SRC B
(39, 14, 57, 32), # FX A
(39, 38, 57, 56), # FX B
(0, 0, 0, 0),
(97, 26, 115, 44), # MFX
]
ACTIVE_SRC_RECT_BOUNDS = [
(10, 32, 28, 32),
(10, 56, 28, 56),
(0, 0, 0, 0),
(10, 32, 28, 32), # SRC A
(10, 56, 28, 56), # SRC B
]
ACTIVE_FX_RECT_BOUNDS = [
(39, 32, 57, 32),
(39, 56, 57, 56),
(97, 44, 115, 44),
(0, 0, 0, 0),
(39, 32, 57, 32), # FX A
(39, 56, 57, 56), # FX B
(97, 44, 115, 44), # MFX
]
SRCA_FRAG = 1
SRCB_FRAG = 2
FXA_FRAG = 3
FXB_FRAG = 4
MIX_FRAG = 5
MFX_FRAG = 6
SRC_GROUP = 1
FX_GROUP = 2
EXTRA_GROUP = 3
GROUPS_DELTA = [0, 12, 33]
GROUPS_SIZE = [6, 7, 2]
+46 -10
View File
@@ -9,8 +9,15 @@ from .constants import (
ESTIMATED_BOOT_TIME_SECONDS,
FONT_1_PATH,
FONT_2_PATH,
FX_GROUP,
FXA_FRAG,
FXB_FRAG,
LOADING_IMG_PATH,
MFX_FRAG,
SELECTED_RECT_BOUNDS,
SRC_GROUP,
SRCA_FRAG,
SRCB_FRAG,
)
from .enums import ForgeState
from .forge_data import ForgeData
@@ -65,11 +72,11 @@ def __get_running_display(data: ForgeData) -> Image.Image:
draw.circle((55 + 8 * data.page, 61), 2, fill="white")
# selected
draw.rectangle(SELECTED_RECT_BOUNDS[data.selected], outline="white", fill=None)
draw.rectangle(SELECTED_RECT_BOUNDS[data.frag_selected], outline="white", fill=None)
# active
draw.rectangle(ACTIVE_SRC_RECT_BOUNDS[data.active(0)], fill="white")
draw.rectangle(ACTIVE_FX_RECT_BOUNDS[data.active(1)], fill="white")
draw.rectangle(ACTIVE_SRC_RECT_BOUNDS[data.group_active(SRC_GROUP)], fill="white")
draw.rectangle(ACTIVE_FX_RECT_BOUNDS[data.group_active(FX_GROUP)], fill="white")
# fx/mix values
draw.rectangle((41, 16 + round(14 * (1 - data.fxa_value)), 55, 30), fill="white")
@@ -78,16 +85,45 @@ def __get_running_display(data: ForgeData) -> Image.Image:
draw.rectangle((70, 28 + round(14 * (1 - data.mix_value)), 84, 42), fill="white")
# active shaders
draw2.text((16, 20), hex(data.frag_state(0))[2].upper(), fill="white", font=FONT_2)
draw2.text((16, 44), hex(data.frag_state(1))[2].upper(), fill="white", font=FONT_2)
draw2.text((45, 20), hex(data.frag_state(2))[2].upper(), fill="white", font=FONT_2)
draw2.text((45, 44), hex(data.frag_state(3))[2].upper(), fill="white", font=FONT_2)
draw2.text((103, 32), hex(data.frag_state(5))[2].upper(), fill="white", font=FONT_2)
# TODO print when random
# TODO print when inverted
draw2.text(
(16, 20), hex(data.frag_state(SRCA_FRAG))[2].upper(), fill="white", font=FONT_2
)
draw2.text(
(16, 44), hex(data.frag_state(SRCB_FRAG))[2].upper(), fill="white", font=FONT_2
)
draw2.text(
(45, 20), hex(data.frag_state(FXA_FRAG))[2].upper(), fill="white", font=FONT_2
)
draw2.text(
(45, 44), hex(data.frag_state(FXB_FRAG))[2].upper(), fill="white", font=FONT_2
)
draw2.text(
(103, 32), hex(data.frag_state(MFX_FRAG))[2].upper(), fill="white", font=FONT_2
)
# mix
draw2.text((74, 32), "K" if data.mix_mode_key else "M", fill="white", font=FONT_2)
# random states indicator
if data.frag_state_rand(SRCA_FRAG):
draw2.rectangle((23, 18, 24, 19), fill="white")
if data.frag_state_rand(SRCB_FRAG):
draw2.rectangle((23, 42, 24, 43), fill="white")
if data.frag_state_rand(FXA_FRAG):
draw2.rectangle((52, 18, 53, 19), fill="white")
if data.frag_state_rand(FXB_FRAG):
draw2.rectangle((52, 42, 53, 43), fill="white")
if data.frag_state_rand(MFX_FRAG):
draw2.rectangle((110, 30, 111, 31), fill="white")
# inverted fx
if data.fxa_inverted:
draw2.rectangle((43, 18, 53, 18), fill="white")
if data.fxb_inverted:
draw2.rectangle((43, 42, 53, 42), fill="white")
if data.mfx_inverted:
draw2.rectangle((101, 30, 111, 30), fill="white")
# TODO show feedback
# TODO show blank out
# TODO show inverted out
+105 -18
View File
@@ -2,9 +2,21 @@ import collections
import pathlib
import typing
from .constants import FORGE_SAVE_BACKUP_PATH, FORGE_SAVE_PATH, MOCK_SAVE_PATH
from .constants import (
EXTRA_GROUP,
FORGE_SAVE_BACKUP_PATH,
FORGE_SAVE_PATH,
FX_GROUP,
FXA_FRAG,
FXB_FRAG,
GROUPS_DELTA,
GROUPS_SIZE,
MFX_FRAG,
MIX_FRAG,
MOCK_SAVE_PATH,
)
from .enums import ForgeState
from .glsl_funcs import fract, magic, magic_trigger
from .glsl_funcs import fract, magic, magic_trigger, rand_time
class ForgeRawData:
@@ -65,21 +77,54 @@ class ForgeData:
return True
return False
def value(self, n: int) -> tuple[float, float, float]:
def __value(self, n: int) -> tuple[float, float, float]:
return (
self.__data[f"value_{n}_x"] / 127,
self.__data[f"value_{n}_y"] / 127,
self.__data[f"value_{n}_z"] / 127,
)
def frag_state(self, n: int) -> int:
return int(self.__data[f"state_{n}"])
def frag_state_rand(self, frag: int) -> bool:
return int(self.__data[f"state_{frag - 1}"]) >= 14
def active(self, n: int) -> int:
return int(self.__data[f"active_{n}"])
def frag_state(self, frag: int) -> int:
state = int(self.__data[f"state_{frag - 1}"])
if state >= 14:
return (
int(
rand_time(self.time, self.beats, self.frag_seed(frag) + 100.0)
* 14.0
)
+ 1
)
return state + 1
def seed(self, n: int) -> int:
return int(self.__data[f"seed_{n}"])
def frag_seed(self, frag: int) -> int:
return int(self.__data[f"seed_{frag - 1}"])
@property
def frag_selected(self) -> int:
return int(self.__data["selected"] + 1)
def group_active(self, group: int) -> int:
return int(self.__data[f"active_{group - 1}"] + 1)
def group_value(self, group: int, layer: int, n: int) -> tuple[float, float, float]:
return self.__value(
GROUPS_DELTA[group - 1] + GROUPS_SIZE[group - 1] * (layer - 1) + n
)
@property
def demo(self) -> bool:
return self.__data["demo"] > 0
@property
def auto_random(self) -> bool:
return self.__data["auto_random"] > 0
@property
def auto_random_cycle(self) -> int:
return int(self.__data["auto_random_cycle"])
@property
def time(self) -> float:
@@ -105,38 +150,80 @@ class ForgeData:
def page(self) -> int:
return int(self.__data["page"])
@property
def selected(self) -> int:
return int(self.__data["selected"])
@property
def fxa_value(self) -> float:
return magic(
self.time, self.beats, self.value(18), (1.0, 0.0, 0.0), self.seed(2)
self.time,
self.beats,
self.group_value(FX_GROUP, 1, 6),
(1.0, 0.0, 0.0),
self.frag_seed(FXA_FRAG),
)
@property
def fxa_inverted(self) -> bool:
return magic_trigger(
self.time,
self.beats,
(self.group_value(FX_GROUP, 1, 6)[2], 0.0, 0.0),
self.frag_seed(FXA_FRAG),
)
@property
def fxb_value(self) -> float:
return magic(
self.time, self.beats, self.value(25), (1.0, 0.0, 0.0), self.seed(3)
self.time,
self.beats,
self.group_value(FX_GROUP, 2, 6),
(1.0, 0.0, 0.0),
self.frag_seed(FXB_FRAG),
)
@property
def fxb_inverted(self) -> bool:
return magic_trigger(
self.time,
self.beats,
(self.group_value(FX_GROUP, 2, 6)[2], 0.0, 0.0),
self.frag_seed(FXB_FRAG),
)
@property
def mix_value(self) -> float:
return magic(
self.time, self.beats, self.value(34), (1.0, 0.0, 0.0), self.seed(4)
self.time,
self.beats,
self.group_value(EXTRA_GROUP, 1, 1),
(1.0, 0.0, 0.0),
self.frag_seed(MIX_FRAG),
)
@property
def mix_mode_key(self) -> bool:
return magic_trigger(
self.time, self.beats, (self.value(33)[0], 0.0, 0.0), self.seed(4) + 10.0
self.time,
self.beats,
(self.group_value(EXTRA_GROUP, 1, 0)[0], 0.0, 0.0),
self.frag_seed(MIX_FRAG) + 10.0,
)
@property
def mfx_value(self) -> float:
return magic(
self.time, self.beats, self.value(32), (1.0, 0.0, 0.0), self.seed(5)
self.time,
self.beats,
self.group_value(FX_GROUP, 3, 6),
(1.0, 0.0, 0.0),
self.frag_seed(MFX_FRAG),
)
@property
def mfx_inverted(self) -> bool:
return magic_trigger(
self.time,
self.beats,
(self.group_value(FX_GROUP, 3, 6)[2], 0.0, 0.0),
self.frag_seed(MFX_FRAG),
)
def mock(self) -> typing.Self: