Browse Source

Add PNG renderer

June 2 months ago
parent
commit
fcc9bee663
Signed by: Curtis McEnroe <june@causal.agency> GPG Key ID: CEA2F97ADCFCD77C
5 changed files with 248 additions and 14 deletions
  1. 5
    2
      Makefile
  2. 19
    12
      README
  3. BIN
      default8x16.psfu
  4. 167
    0
      image.c
  5. 57
    0
      torus.7

+ 5
- 2
Makefile View File

@@ -3,8 +3,8 @@ CHROOT_GROUP = $(CHROOT_USER)
3 3
 
4 4
 CFLAGS += -Wall -Wextra -Wpedantic
5 5
 LDFLAGS += -static
6
-LDLIBS = -lcursesw
7
-BINS = server client meta merge
6
+LDLIBS = -lcursesw -lz
7
+BINS = server client image meta merge
8 8
 OBJS = $(BINS:%=%.o)
9 9
 
10 10
 all: tags $(BINS)
@@ -43,3 +43,6 @@ chroot.tar: server client
43 43
 
44 44
 clean:
45 45
 	rm -f tags $(OBJS) $(BINS) chroot.tar
46
+
47
+README: torus.7
48
+	mandoc torus.7 | col -b -x > README

+ 19
- 12
README View File

@@ -1,15 +1,22 @@
1
-Welcome to ascii.town!
1
+TORUS(7)           FreeBSD Miscellaneous Information Manual           TORUS(7)
2 2
 
3
-This software targets FreeBSD and Darwin.
3
+NAME
4
+     torus – welcome to ascii.town!
4 5
 
5
-	torus.h        Shared structures and message protocol.
6
-	server.c       Maps torus.dat and listens on torus.sock.
7
-	client.c       Curses client.
8
-	help.c         Automated client which redraws a helpful banner.
9
-	meta.c         Exports metadata from data file to CSV.
10
-	merge.c        Interactively merges two data files.
11
-	snapshot.sh    Snapshots data file, appropriate for cron.
6
+DESCRIPTION
7
+     This software targets FreeBSD and Darwin.
12 8
 
13
-	sshd_config    Anonymous login to chrooted client.
14
-	termcap.diff   Patch for bright colors in xterm and rxvt.
15
-	index.html     Friendly directions.
9
+     torus.h      Shared structures and message protocol.
10
+     server.c     Maps torus.dat and listens on torus.sock.
11
+     client.c     curses(3) client.
12
+     help.h       Tile data for help page.
13
+     image.c      Renders PNGs of tiles.
14
+     meta.c       Exports metadata from data file to CSV.
15
+     merge.c      Interactively merges two data files.
16
+     snapshot.sh  Snapshots data file, appropriate for cron.
17
+
18
+     sshd_config       Anonymous login to chroot(8)'d client.
19
+     index.html        Friendly directions.
20
+     default8x16.psfu  Bitmap font from kbd: http://kbd-project.org.
21
+
22
+Causal Agency                  October 10, 2018                  Causal Agency

BIN
default8x16.psfu View File


+ 167
- 0
image.c View File

@@ -0,0 +1,167 @@
1
+/* Copyright (C) 2018  Curtis McEnroe <june@causal.agency>
2
+ *
3
+ * This program is free software: you can redistribute it and/or modify
4
+ * it under the terms of the GNU Affero General Public License as published by
5
+ * the Free Software Foundation, either version 3 of the License, or
6
+ * (at your option) any later version.
7
+ *
8
+ * This program is distributed in the hope that it will be useful,
9
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
+ * GNU Affero General Public License for more details.
12
+ *
13
+ * You should have received a copy of the GNU Affero General Public License
14
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
15
+ */
16
+
17
+#include <arpa/inet.h>
18
+#include <err.h>
19
+#include <fcntl.h>
20
+#include <stdint.h>
21
+#include <stdio.h>
22
+#include <stdlib.h>
23
+#include <string.h>
24
+#include <sys/mman.h>
25
+#include <sysexits.h>
26
+#include <unistd.h>
27
+#include <zlib.h>
28
+
29
+#include "torus.h"
30
+
31
+static const uint8_t Palette[16][3] = {
32
+	{ 0x00, 0x00, 0x00 },
33
+	{ 0xAA, 0x00, 0x00 },
34
+	{ 0x00, 0xAA, 0x00 },
35
+	{ 0xAA, 0x55, 0x00 },
36
+	{ 0x00, 0x00, 0xAA },
37
+	{ 0xAA, 0x00, 0xAA },
38
+	{ 0x00, 0xAA, 0xAA },
39
+	{ 0xAA, 0xAA, 0xAA },
40
+	{ 0x55, 0x55, 0x55 },
41
+	{ 0xFF, 0x55, 0x55 },
42
+	{ 0x55, 0xFF, 0x55 },
43
+	{ 0xFF, 0xFF, 0x55 },
44
+	{ 0x55, 0x55, 0xFF },
45
+	{ 0xFF, 0x55, 0xFF },
46
+	{ 0x55, 0xFF, 0xFF },
47
+	{ 0xFF, 0xFF, 0xFF },
48
+};
49
+
50
+static uint32_t crc;
51
+static void pngWrite(const void *ptr, size_t size) {
52
+	fwrite(ptr, size, 1, stdout);
53
+	if (ferror(stdout)) err(EX_IOERR, "(stdout)");
54
+	crc = crc32(crc, ptr, size);
55
+}
56
+static void pngInt(uint32_t host) {
57
+	uint32_t net = htonl(host);
58
+	pngWrite(&net, 4);
59
+}
60
+static void pngChunk(char type[static 4], uint32_t size) {
61
+	pngInt(size);
62
+	crc = crc32(0, Z_NULL, 0);
63
+	pngWrite(type, 4);
64
+}
65
+
66
+int main(int argc, char *argv[]) {
67
+	const char *fontPath = "default8x16.psfu";
68
+	const char *dataPath = "torus.dat";
69
+	uint32_t tileX = TileInitX;
70
+	uint32_t tileY = TileInitY;
71
+
72
+	int opt;
73
+	while (0 < (opt = getopt(argc, argv, "d:f:x:y:"))) {
74
+		switch (opt) {
75
+			break; case 'd': dataPath = optarg;
76
+			break; case 'f': fontPath = optarg;
77
+			break; case 'x': tileX = strtoul(optarg, NULL, 0) % TileCols;
78
+			break; case 'y': tileY = strtoul(optarg, NULL, 0) % TileRows;
79
+			break; default:  return EX_USAGE;
80
+		}
81
+	}
82
+
83
+	FILE *file = fopen(fontPath, "r");
84
+	if (!file) err(EX_NOINPUT, "%s", fontPath);
85
+
86
+	struct {
87
+		uint32_t magic;
88
+		uint32_t version;
89
+		uint32_t size;
90
+		uint32_t flags;
91
+		struct {
92
+			uint32_t len;
93
+			uint32_t size;
94
+			uint32_t height;
95
+			uint32_t width;
96
+		} glyph;
97
+	} psf;
98
+	size_t len = fread(&psf, sizeof(psf), 1, file);
99
+	if (ferror(file)) err(EX_IOERR, "%s", fontPath);
100
+	if (len < 1) errx(EX_DATAERR, "%s: truncated header", fontPath);
101
+
102
+	uint8_t glyphs[psf.glyph.len][psf.glyph.height][(psf.glyph.width + 7) / 8];
103
+	len = fread(glyphs, psf.glyph.size, psf.glyph.len, file);
104
+	if (ferror(file)) err(EX_IOERR, "%s", fontPath);
105
+	if (len < 1) errx(EX_DATAERR, "%s: truncated glyphs", fontPath);
106
+	fclose(file);
107
+
108
+	int fd = open(dataPath, O_RDONLY);
109
+	if (fd < 0) err(EX_NOINPUT, "%s", dataPath);
110
+
111
+	struct Tile *tile = mmap(
112
+		NULL, sizeof(struct Tile),
113
+		PROT_READ, MAP_SHARED,
114
+		fd, sizeof(struct Tile) * (TileRows * tileY + tileX)
115
+	);
116
+	if (tile == MAP_FAILED) err(EX_IOERR, "mmap");
117
+	close(fd);
118
+
119
+	pngWrite("\x89PNG\r\n\x1A\n", 8);
120
+
121
+	uint32_t width = CellCols * psf.glyph.width;
122
+	uint32_t height = CellRows * psf.glyph.height;
123
+
124
+	pngChunk("IHDR", 13);
125
+	pngInt(width);
126
+	pngInt(height);
127
+	pngWrite("\x08\x03\x00\x00\x00", 5);
128
+	pngInt(crc);
129
+
130
+	pngChunk("PLTE", sizeof(Palette));
131
+	pngWrite(Palette, sizeof(Palette));
132
+	pngInt(crc);
133
+
134
+	uint8_t data[height][1 + width];
135
+	memset(data, 0, sizeof(data));
136
+
137
+	for (uint32_t y = 0; y < CellRows; ++y) {
138
+		for (uint32_t x = 0; x < CellCols; ++x) {
139
+			uint8_t cell = tile->cells[y][x];
140
+			uint8_t fg = tile->colors[y][x] & 0x0F;
141
+			uint8_t bg = tile->colors[y][x] >> 4;
142
+
143
+			uint32_t row = psf.glyph.height * y;
144
+			uint32_t col = psf.glyph.width * x;
145
+			for (uint8_t gy = 0; gy < psf.glyph.height; ++gy) {
146
+				for (uint8_t gx = 0; gx < psf.glyph.width; ++gx) {
147
+					uint8_t bit = glyphs[cell][gy][gx / 8] >> (7 - gx % 8) & 1;
148
+					data[row + gy][1 + col + gx] = (bit ? fg : bg);
149
+				}
150
+			}
151
+		}
152
+	}
153
+
154
+	uLong size = compressBound(sizeof(data));
155
+	uint8_t deflate[size];
156
+	int error = compress(deflate, &size, (Byte *)data, sizeof(data));
157
+	if (error != Z_OK) errx(EX_SOFTWARE, "compress: %d", error);
158
+
159
+	pngChunk("IDAT", size);
160
+	pngWrite(deflate, size);
161
+	pngInt(crc);
162
+
163
+	pngChunk("IEND", 0);
164
+	pngInt(crc);
165
+
166
+	return EX_OK;
167
+}

+ 57
- 0
torus.7 View File

@@ -0,0 +1,57 @@
1
+.Dd October 10, 2018
2
+.Dt TORUS 7
3
+.Os "Causal Agency"
4
+.
5
+.Sh NAME
6
+.Nm torus
7
+.Nd welcome to ascii.town!
8
+.
9
+.Sh DESCRIPTION
10
+This software targets
11
+.Fx
12
+and Darwin.
13
+.
14
+.Pp
15
+.Bl -tag -width "snapshot.sh" -compact
16
+.It Pa torus.h
17
+Shared structures and message protocol.
18
+.
19
+.It Pa server.c
20
+Maps
21
+.Pa torus.dat
22
+and listens on
23
+.Pa torus.sock .
24
+.
25
+.It Pa client.c
26
+.Xr curses 3
27
+client.
28
+.
29
+.It Pa help.h
30
+Tile data for help page.
31
+.
32
+.It Pa image.c
33
+Renders PNGs of tiles.
34
+.
35
+.It Pa meta.c
36
+Exports metadata from data file to CSV.
37
+.
38
+.It Pa merge.c
39
+Interactively merges two data files.
40
+.
41
+.It Pa snapshot.sh
42
+Snapshots data file, appropriate for cron.
43
+.El
44
+.
45
+.Pp
46
+.Bl -tag -width "default8x16.psfu" -compact
47
+.It Pa sshd_config
48
+Anonymous login to
49
+.Xr chroot 8 Ap d client.
50
+.
51
+.It Pa index.html
52
+Friendly directions.
53
+.
54
+.It Pa default8x16.psfu
55
+Bitmap font from
56
+.Lk http://kbd-project.org kbd .
57
+.El

Loading…
Cancel
Save