SMOLNET PORTAL home about changes
iAdd vtv-viewer. - vtv-tools - virtual terminal video tools	Err	bitreich.org	70
1Log	/scm/vtv-tools/log.gph	bitreich.org	70
1Files	/scm/vtv-tools/files.gph	bitreich.org	70
1Refs	/scm/vtv-tools/refs.gph	bitreich.org	70
1Tags	/scm/vtv-tools/tag	bitreich.org	70
1README	/scm/vtv-tools/file/README.md.gph	bitreich.org	70
1LICENSE	/scm/vtv-tools/file/LICENSE.gph	bitreich.org	70
i---	Err	bitreich.org	70
1commit 991a6f94bb058979f28763ecd33b5920cad034d5	/scm/vtv-tools/commit/991a6f94bb058979f28763ecd33b5920cad034d5.gph	bitreich.org	70
1parent 121db131a875338f494bb1ab98e6dd7245cea1f6	/scm/vtv-tools/commit/121db131a875338f494bb1ab98e6dd7245cea1f6.gph	bitreich.org	70
hAuthor: Troels Henriksen <athas@sigkill.dk>	URL:mailto:athas@sigkill.dk	bitreich.org	70
iDate:   Tue, 22 Aug 2023 18:30:18 +0200	Err	bitreich.org	70
i	Err	bitreich.org	70
iAdd vtv-viewer.	Err	bitreich.org	70
i	Err	bitreich.org	70
iDiffstat:	Err	bitreich.org	70
i  M .gitignore                          |       1 +	Err	bitreich.org	70
i  M Makefile                            |       2 +-	Err	bitreich.org	70
i  M man/vtv-player.1                    |       2 +-	Err	bitreich.org	70
i  A man/vtv-viewer.1                    |      41 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i  A src/vtv-viewer.c                    |     147 +++++++++++++++++++++++++++++++	Err	bitreich.org	70
i	Err	bitreich.org	70
i5 files changed, 191 insertions(+), 2 deletions(-)	Err	bitreich.org	70
i---	Err	bitreich.org	70
1diff --git a/.gitignore b/.gitignore	/scm/vtv-tools/file/.gitignore.gph	bitreich.org	70
i@@ -1 +1,2 @@	Err	bitreich.org	70
i bin/vtv-from-ff	Err	bitreich.org	70
i+bin/vtv-viewer	Err	bitreich.org	70
1diff --git a/Makefile b/Makefile	/scm/vtv-tools/file/Makefile.gph	bitreich.org	70
i@@ -4,7 +4,7 @@ MANPREFIX ?= ${PREFIX}/share/man	Err	bitreich.org	70
i CFLAGS?=-O -Wall -Wextra -pedantic	Err	bitreich.org	70
i CC?=cc	Err	bitreich.org	70
i 	Err	bitreich.org	70
i-all: bin/vtv-from-ff	Err	bitreich.org	70
i+all: bin/vtv-from-ff bin/vtv-viewer	Err	bitreich.org	70
i 	Err	bitreich.org	70
i bin/%: src/%.c	Err	bitreich.org	70
i         $(CC) -o $@ $< $(CFLAGS)	Err	bitreich.org	70
1diff --git a/man/vtv-player.1 b/man/vtv-player.1	/scm/vtv-tools/file/man/vtv-player.1.gph	bitreich.org	70
i@@ -16,7 +16,7 @@	Err	bitreich.org	70
i .Sh DESCRIPTION	Err	bitreich.org	70
i .Bd -filled	Err	bitreich.org	70
i .Nm	Err	bitreich.org	70
i-plays a VTV file in the terminal.  Loops until manually terminated.	Err	bitreich.org	70
i+Plays a VTV file in the terminal.  Loops until manually terminated.	Err	bitreich.org	70
i .	Err	bitreich.org	70
i .Sh OPTIONS	Err	bitreich.org	70
i .Bl -tag -width Ds	Err	bitreich.org	70
1diff --git a/man/vtv-viewer.1 b/man/vtv-viewer.1	/scm/vtv-tools/file/man/vtv-viewer.1.gph	bitreich.org	70
i@@ -0,0 +1,41 @@	Err	bitreich.org	70
i+.Dd August 22, 2023	Err	bitreich.org	70
i+.Dt VTV-VIEWER 1	Err	bitreich.org	70
i+.OS	Err	bitreich.org	70
i+.	Err	bitreich.org	70
i+.sh NAME	Err	bitreich.org	70
i+.Nm vtv-viewer	Err	bitreich.org	70
i+.Nd Interactively view frames of VTV file.	Err	bitreich.org	70
i+.	Err	bitreich.org	70
i+.Sh SYNOPSIS	Err	bitreich.org	70
i+.Nm	Err	bitreich.org	70
i+.Bk	Err	bitreich.org	70
i+.Ar FILE	Err	bitreich.org	70
i+.Ek	Err	bitreich.org	70
i+.	Err	bitreich.org	70
i+.Sh DESCRIPTION	Err	bitreich.org	70
i+.Bd -filled	Err	bitreich.org	70
i+.Nm	Err	bitreich.org	70
i+Interactively shows frames of a VTV file in the terminal.  This can be	Err	bitreich.org	70
i+useful for trying to figure out the intended frame size of a VTV.	Err	bitreich.org	70
i+.	Err	bitreich.org	70
i+.Sh COMMANDS	Err	bitreich.org	70
i+.	Err	bitreich.org	70
i+The following keyboard commands are supported.	Err	bitreich.org	70
i+.Bl -tag -width Ds	Err	bitreich.org	70
i+.It h	Err	bitreich.org	70
i+Go to previous frame.	Err	bitreich.org	70
i+.It l	Err	bitreich.org	70
i+Go to next frame.	Err	bitreich.org	70
i+.It j	Err	bitreich.org	70
i+Decrease frame size by one line.	Err	bitreich.org	70
i+.It k	Err	bitreich.org	70
i+Increase frame size by one line.	Err	bitreich.org	70
i+.El	Err	bitreich.org	70
i+.	Err	bitreich.org	70
i+.Sh BUGS	Err	bitreich.org	70
i+The VTV frame is emitted directly to the terminal, which can cause	Err	bitreich.org	70
i+user interface corruption if it writes to the parts of the screen used	Err	bitreich.org	70
i+by vtv-viewer itself.	Err	bitreich.org	70
i+.	Err	bitreich.org	70
i+.Sh LICENSE	Err	bitreich.org	70
i+The vtv-tools are released under the GPLv3 or later.	Err	bitreich.org	70
1diff --git a/src/vtv-viewer.c b/src/vtv-viewer.c	/scm/vtv-tools/file/src/vtv-viewer.c.gph	bitreich.org	70
i@@ -0,0 +1,147 @@	Err	bitreich.org	70
i+#include <assert.h>	Err	bitreich.org	70
i+#include <stdint.h>	Err	bitreich.org	70
i+#include <stdio.h>	Err	bitreich.org	70
i+#include <stdlib.h>	Err	bitreich.org	70
i+#include <string.h>	Err	bitreich.org	70
i+#include <sys/ioctl.h>	Err	bitreich.org	70
i+#include <termios.h>	Err	bitreich.org	70
i+#include <unistd.h>	Err	bitreich.org	70
i+#include <errno.h>	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+struct termios orig_termios;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void cooked_mode() {	Err	bitreich.org	70
i+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &orig_termios);	Err	bitreich.org	70
i+  printf("\033[?25h");	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void raw_mode() {	Err	bitreich.org	70
i+  printf("\033[?25l");	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  tcgetattr(STDIN_FILENO, &orig_termios);	Err	bitreich.org	70
i+  atexit(cooked_mode);	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  struct termios raw = orig_termios;	Err	bitreich.org	70
i+  raw.c_iflag &= ~(IXON);	Err	bitreich.org	70
i+  raw.c_lflag &= ~(ECHO | ICANON);	Err	bitreich.org	70
i+  raw.c_cc[VMIN] = 1;	Err	bitreich.org	70
i+  raw.c_cc[VTIME] = 0;	Err	bitreich.org	70
i+  tcsetattr(STDIN_FILENO, TCSAFLUSH, &raw);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void move(int x, int y) { printf("\033[%d;%dH", y, x); }	Err	bitreich.org	70
i+void home() { printf("\033[;H"); }	Err	bitreich.org	70
i+void clear_screen() { printf("\033[2J"); }	Err	bitreich.org	70
i+void clear_line() { printf("\033[2K"); }	Err	bitreich.org	70
i+void def() { printf("\033[0m"); }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void fg_rgb(uint8_t r, uint8_t g, uint8_t b) {	Err	bitreich.org	70
i+  printf("\033[38;2;%d;%d;%dm", r, g, b);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void bg_rgb(uint8_t r, uint8_t g, uint8_t b) {	Err	bitreich.org	70
i+  printf("\033[48;2;%d;%d;%dm", r, g, b);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int read_lines(FILE* f, char*** lines_out, size_t *num_lines_out) {	Err	bitreich.org	70
i+  size_t n, num_lines = 0, capacity = 10;	Err	bitreich.org	70
i+  char** lines = calloc(capacity, sizeof(char*));	Err	bitreich.org	70
i+  ssize_t len;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  while ((len = getline(&lines[num_lines], &n, f)) > 0) {	Err	bitreich.org	70
i+    lines[num_lines][len-1] = 0; // Strip newline.	Err	bitreich.org	70
i+    if (++num_lines == capacity) {	Err	bitreich.org	70
i+      capacity *= 2;	Err	bitreich.org	70
i+      lines = reallocarray(lines, capacity, sizeof(char*));	Err	bitreich.org	70
i+      for (unsigned int i = num_lines; i < capacity; i++) {	Err	bitreich.org	70
i+        lines[i] = NULL;	Err	bitreich.org	70
i+      }	Err	bitreich.org	70
i+    }	Err	bitreich.org	70
i+  }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  *lines_out = lines;	Err	bitreich.org	70
i+  *num_lines_out = num_lines;	Err	bitreich.org	70
i+  return 0;	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+struct {	Err	bitreich.org	70
i+  int frame;	Err	bitreich.org	70
i+  int lines_per_frame;	Err	bitreich.org	70
i+  char** lines;	Err	bitreich.org	70
i+  int num_lines;	Err	bitreich.org	70
i+} state;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void show_status() {	Err	bitreich.org	70
i+  printf("Frame (h/l): %5d    Framesize (j/k): %5d\n",	Err	bitreich.org	70
i+         state.frame, state.lines_per_frame);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+void show_frame() {	Err	bitreich.org	70
i+  for (int i = 0; i < state.lines_per_frame; i++) {	Err	bitreich.org	70
i+    int j = state.frame*state.lines_per_frame + i;	Err	bitreich.org	70
i+    if (j < state.num_lines) {	Err	bitreich.org	70
i+      puts(state.lines[j]);	Err	bitreich.org	70
i+    } else {	Err	bitreich.org	70
i+      puts("   MISSING LINE");	Err	bitreich.org	70
i+    }	Err	bitreich.org	70
i+  }	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int view(char** lines, size_t num_lines) {	Err	bitreich.org	70
i+  raw_mode();	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  state.frame = 0;	Err	bitreich.org	70
i+  state.lines_per_frame = 25;	Err	bitreich.org	70
i+  state.lines = lines;	Err	bitreich.org	70
i+  state.num_lines = num_lines;	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  while (1) {	Err	bitreich.org	70
i+    home();	Err	bitreich.org	70
i+    def();	Err	bitreich.org	70
i+    clear_screen();	Err	bitreich.org	70
i+    show_frame();	Err	bitreich.org	70
i+    move(0, state.lines_per_frame+1);	Err	bitreich.org	70
i+    def();	Err	bitreich.org	70
i+    // It is intentional that the status is at the bottom, as VTV	Err	bitreich.org	70
i+    // files may assume that they are drawn from line 0.	Err	bitreich.org	70
i+    show_status();	Err	bitreich.org	70
i+    switch(getchar()) {	Err	bitreich.org	70
i+    case 'q':	Err	bitreich.org	70
i+      return 0;	Err	bitreich.org	70
i+    case 'h':	Err	bitreich.org	70
i+      if (state.frame != 0) { state.frame--; }	Err	bitreich.org	70
i+      break;	Err	bitreich.org	70
i+    case 'l':	Err	bitreich.org	70
i+      state.frame = (state.frame+1);	Err	bitreich.org	70
i+      break;	Err	bitreich.org	70
i+    case 'j':	Err	bitreich.org	70
i+      if (state.lines_per_frame != 0) {state.lines_per_frame--; }	Err	bitreich.org	70
i+      break;	Err	bitreich.org	70
i+    case 'k':	Err	bitreich.org	70
i+      state.lines_per_frame++;	Err	bitreich.org	70
i+      break;	Err	bitreich.org	70
i+    }	Err	bitreich.org	70
i+  }	Err	bitreich.org	70
i+}	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+int main(int argc, char** argv) {	Err	bitreich.org	70
i+  if (argc != 2) {	Err	bitreich.org	70
i+    fprintf(stderr, "Usage: %s FILE\n", argv[0]);	Err	bitreich.org	70
i+    return 1;	Err	bitreich.org	70
i+  }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  FILE* f = fopen(argv[1], "r");	Err	bitreich.org	70
i+  if (f == NULL) {	Err	bitreich.org	70
i+    fprintf(stderr, "%s: cannot open %s: %s\n",	Err	bitreich.org	70
i+            argv[0], argv[1], strerror(errno));	Err	bitreich.org	70
i+  }	Err	bitreich.org	70
i+	Err	bitreich.org	70
i+  char** lines;	Err	bitreich.org	70
i+  size_t num_lines;	Err	bitreich.org	70
i+  if (read_lines(f, &lines, &num_lines) != 0) {	Err	bitreich.org	70
i+    fprintf(stderr, "%s: failed to read from %s: %s\n",	Err	bitreich.org	70
i+            argv[0], argv[1], strerror(errno));	Err	bitreich.org	70
i+    exit(1);	Err	bitreich.org	70
i+  }	Err	bitreich.org	70
i+  return view(lines, num_lines);	Err	bitreich.org	70
i+}	Err	bitreich.org	70
.
Response: text/plain
Original URLgopher://bitreich.org/0/scm/vtv-tools/commit/991a6f94bb05...
Content-Typetext/plain; charset=utf-8