From 8c393c8f9ef6454a453cb74626f196315aebfbeb Mon Sep 17 00:00:00 2001 From: Daniel Dybing Date: Sun, 11 Jan 2026 11:40:20 +0100 Subject: [PATCH] Fix language detection bit swap in T42 header parsing Correctly map C12 and C13 control bits to fix misidentification of Swedish/Finnish (010) and German (001). Also ensures Page model, Renderer, and UI properly propagate and display the detected language. --- src/teletext/io.py | 18 +++++++++++++++--- src/teletext/models.py | 1 + src/teletext/renderer.py | 6 ++++++ src/teletext/ui.py | 17 +++++++++++++++-- 4 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/teletext/io.py b/src/teletext/io.py index f2f6d81..77046a2 100644 --- a/src/teletext/io.py +++ b/src/teletext/io.py @@ -43,10 +43,10 @@ def load_t42(file_path: str, progress_callback: Optional[Callable[[int, int], No # or find the existing one if we want to support updates (but T42 usually is a stream capture). # If it's an editor file, it's likely sequential. - p_num, sub_code = parse_header(packet.data) + p_num, sub_code, language = parse_header(packet.data) # Create new page - new_page = Page(magazine=packet.magazine, page_number=p_num, sub_code=sub_code) + new_page = Page(magazine=packet.magazine, page_number=p_num, sub_code=sub_code, language=language) new_page.packets.append(packet) service.pages.append(new_page) else: @@ -209,4 +209,16 @@ def parse_header(data: bytearray): sub_code = s1 | (s2 << 4) | (s3 << 8) | (s4 << 12) - return page_num, sub_code + # Control bits C12, C13, C14 are in Byte 8 (index 8) + # They determine the National Option (Language) + c_bits_2 = decode_hamming_8_4(data[8]) + + # Fix for Language Detection: + # It seems C12 and C13 are swapped in the Hamming decoding or file format relative to expected values. + # C12 is bit 0, C13 is bit 1. + # We swap them so D1 maps to C13 (Swedish bit) and D2 maps to C12 (German bit). + # Original: language = c_bits_2 & 0b111 + + language = ((c_bits_2 & 1) << 1) | ((c_bits_2 & 2) >> 1) | (c_bits_2 & 4) + + return page_num, sub_code, language diff --git a/src/teletext/models.py b/src/teletext/models.py index 90273e6..6fa2639 100644 --- a/src/teletext/models.py +++ b/src/teletext/models.py @@ -76,6 +76,7 @@ class Page: magazine: int page_number: int # 00-99 sub_code: int = 0 # Subpage code (0000 to 3F7F hex usually, simplest is 0-99 equivalent) + language: int = 0 # National Option (0-7) packets: List[Packet] = field(default_factory=list) @property diff --git a/src/teletext/renderer.py b/src/teletext/renderer.py index f2888d1..96b1dfd 100755 --- a/src/teletext/renderer.py +++ b/src/teletext/renderer.py @@ -139,6 +139,12 @@ class TeletextCanvas(QWidget): def set_page(self, page: Page): self.page = page + # Set language from page header + if page: + self.subset_idx = page.language + else: + self.subset_idx = 0 + self.cursor_x = 0 self.cursor_y = 0 self.redraw() diff --git a/src/teletext/ui.py b/src/teletext/ui.py index 39efb94..904861e 100644 --- a/src/teletext/ui.py +++ b/src/teletext/ui.py @@ -127,10 +127,22 @@ class MainWindow(QMainWindow): self.status_label = QLabel("Ready") self.status_bar.addWidget(self.status_label) + + self.language_label = QLabel("Lang: English") + self.status_bar.addPermanentWidget(self.language_label) + + self.language_names = ["English", "German", "Swedish/Finnish", "Italian", "French", "Portuguese/Spanish", "Turkish", "Romania"] # Menus self.create_menus() + def update_language_label(self): + idx = self.canvas.subset_idx + if 0 <= idx < len(self.language_names): + self.language_label.setText(f"Lang: {self.language_names[idx]}") + else: + self.language_label.setText(f"Lang: Unknown ({idx})") + def set_modified(self, modified: bool): self.is_modified = modified title = "Teletext Editor" @@ -222,8 +234,7 @@ class MainWindow(QMainWindow): view_menu = menu_bar.addMenu("View") lang_menu = view_menu.addMenu("Language") - langs = ["English", "German", "Swedish/Finnish", "Italian", "French", "Portuguese/Spanish", "Turkish", "Romania"] - for i, lang in enumerate(langs): + for i, lang in enumerate(self.language_names): action = QAction(lang, self) action.setData(i) action.triggered.connect(self.set_language) @@ -236,6 +247,7 @@ class MainWindow(QMainWindow): self.canvas.subset_idx = idx self.canvas.redraw() self.canvas.update() + self.update_language_label() def prev_subpage(self): count = self.subpage_combo.count() @@ -516,6 +528,7 @@ class MainWindow(QMainWindow): if isinstance(page, Page): self.current_page = page self.canvas.set_page(page) + self.update_language_label() self.canvas.setFocus() def insert_char(self, char_code):