Word Unperfect
public
Read
Owner: themaster
Branch: main
Commits: 0
Git CLI clone URL
git clone https://www.xt-emporium.com/git/word-unperfect.git
Fullscreen desktop URL
Code
Commits
History
Branches
Bug Reports
Discussions
Compare
Settings
word-unperfect
/
rev
/
wp_display_buffer.c
File editor
#include "wp_display_buffer.h" #include "wp_control_codes.h" #include "wp_fixed_codes.h" #include "wp_layout_shared.h" #include "wp_record_parser.h" #include "wp_variable_codes.h" #include <stdio.h> #include <stdlib.h> #include <string.h> void wp_display_init(WpDisplayBuffer *db) { if (db == NULL) { return; } memset(db, 0, sizeof(WpDisplayBuffer)); db->reveal_codes_split_row = 12; /* Default split */ } void wp_display_clear(WpDisplayBuffer *db) { int y; int x; if (db == NULL) { return; } for (y = 0; y < WP_SCREEN_HEIGHT; y++) { for (x = 0; x < WP_SCREEN_WIDTH; x++) { db->cells[y][x].ch = ' '; db->cells[y][x].attr = 0x07; /* Light gray on black */ db->cells[y][x].is_dirty = true; } } } void wp_display_putc(WpDisplayBuffer *db, int x, int y, uint8_t ch, uint8_t attr) { if (db != NULL && x >= 0 && x < WP_SCREEN_WIDTH && y >= 0 && y < WP_SCREEN_HEIGHT) { if (db->cells[y][x].ch != ch || db->cells[y][x].attr != attr) { db->cells[y][x].ch = ch; db->cells[y][x].attr = attr; db->cells[y][x].is_dirty = true; } } } /* Helper to get a short visible name for a WP code. */ static const char* wp_get_code_name(uint8_t code, uint8_t sub_code) { const char *marker; if (code < 0xC0U) { marker = wp_control_code_marker(code); if (marker != NULL) { return marker; } } if (code < 0xD0U) { return wp_fixed_code_name(code); } return wp_variable_code_name(code, sub_code); } static void wp_display_write_text(WpDisplayBuffer *db, int *col, int *row, const char *text, uint8_t attr) { while (text != NULL && *text != '\0' && *row < WP_SCREEN_HEIGHT) { wp_display_putc(db, *col, *row, (uint8_t)*text, attr); *col += 1; if (*col >= WP_SCREEN_WIDTH) { *col = 0; *row += 1; } ++text; } } static void wp_display_write_record(WpDisplayBuffer *db, int *col, int *row, const WpRecord *rec) { char label[320]; char detail[192]; if (rec->type == WP_CODE_CHAR) { char ch[2]; ch[0] = (rec->code >= 0x20 && rec->code < 0x7f) ? (char)rec->code : '.'; ch[1] = '\0'; wp_display_write_text(db, col, row, ch, 0x07); return; } if (rec->type == WP_CODE_SINGLE_BYTE) { wp_display_write_text(db, col, row, wp_get_code_name(rec->code, rec->sub_code), 0x03); return; } if (rec->type == WP_CODE_FIXED_LENGTH) { detail[0] = '\0'; if (wp_fixed_code_describe_payload(rec->code, rec->data, rec->data_length, detail, sizeof(detail))) { snprintf(label, sizeof(label), "[%02X %s %s%s]", (unsigned)rec->code, wp_get_code_name(rec->code, rec->sub_code), detail, rec->is_complete ? "" : " incomplete"); } else { snprintf(label, sizeof(label), "[%02X %s%s]", (unsigned)rec->code, wp_get_code_name(rec->code, rec->sub_code), rec->is_complete ? "" : " incomplete"); } wp_display_write_text(db, col, row, label, 0x03); return; } if (rec->type == WP_CODE_VARIABLE_LENGTH) { const char *name = wp_get_code_name(rec->code, rec->sub_code); detail[0] = '\0'; if (wp_variable_describe_payload(rec, detail, sizeof(detail))) { snprintf(label, sizeof(label), "[%02X:%02X %s %s%s%s]", (unsigned)rec->code, (unsigned)rec->sub_code, name, detail, rec->is_complete ? "" : " incomplete", (rec->trailer_present && !rec->trailer_matches) ? " bad-trailer" : ""); } else { snprintf(label, sizeof(label), "[%02X:%02X %s%s%s]", (unsigned)rec->code, (unsigned)rec->sub_code, name, rec->is_complete ? "" : " incomplete", (rec->trailer_present && !rec->trailer_matches) ? " bad-trailer" : ""); } wp_display_write_text(db, col, row, label, 0x03); return; } wp_display_write_text(db, col, row, "[?]", 0x03); } void wp_reveal_codes_sync_view(WpLayoutGlobals *wl, WpDisplayBuffer *db) { int x; int row; int col = 0; WpLayoutGlobals snapshot; static const char separator[] = "--------------------------------------------------------------------------------"; if (wl == NULL || db == NULL || !db->reveal_codes_active) { return; } row = db->reveal_codes_split_row; if (row < 0 || row >= WP_SCREEN_HEIGHT) { row = WP_SCREEN_HEIGHT / 2; db->reveal_codes_split_row = row; } for (x = 0; x < WP_SCREEN_WIDTH; x++) { wp_display_putc(db, x, row, (uint8_t)separator[x], 0x70); /* Inverse divider */ } row++; snapshot = *wl; while (row < WP_SCREEN_HEIGHT && snapshot.record_used_bytes > 0) { WpRecord rec; wp_parser_consume_record(&snapshot, &rec); if (rec.length == 0) { wp_record_free(&rec); break; } wp_display_write_record(db, &col, &row, &rec); wp_record_free(&rec); } } void wp_display_render(WpDisplayBuffer *db) { int y; int x; if (db == NULL) { return; } /* For the host scaffold, rendering only clears the dirty flags. Front-ends * can translate the same buffer into ANSI, SDL, curses, etc. */ for (y = 0; y < WP_SCREEN_HEIGHT; y++) { for (x = 0; x < WP_SCREEN_WIDTH; x++) { db->cells[y][x].is_dirty = false; } } }
Commit message
This repository is read-only for this account.
Repository snapshot
Current branch
main
Visibility
public
Your access
Read
Remote
None
File activity
View file history