9front - general discussion about 9front
 help / color / mirror / Atom feed
* sprat, sprite cat
@ 2020-05-11 10:46 sirjofri
  0 siblings, 0 replies; only message in thread
From: sirjofri @ 2020-05-11 10:46 UTC (permalink / raw)
  To: 9front

Hello all,

I created a small tool that puts together sprites (see spred(1)).
more information below in the patch.

Feel free to comment on this.


changeset:   7758:37e62cb8f2dc
tag:         tip
user:        sirjofri <sirjofri@sirjofri.de>
date:        Mon May 11 12:18:19 2020 +0200
files:       sys/man/1/sprat sys/src/cmd/sprat.c
description:
adds sprat, sprite cat

sprat is an additional tool for spred(1). It puts multiple sprite
files together and outputs a matrix/tileset of these as standard
plan9 image.

example usage:
* create sprites and palette with spred(1). Save them as X.spr
* cat *.spr | sprat > sprites.bit
* or: cat *.spr | sprat | page

see the manpage for more information


diff -r 965e0f59464d -r 37e62cb8f2dc sys/man/1/sprat
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/man/1/sprat	Mon May 11 12:18:19 2020 +0200
@@ -0,0 +1,38 @@
+.TH SPRAT 1
+.SH NAME
+sprat \- sprite cat
+.SH SYNOPSIS
+.B sprat
+[
+.B -c
+. I cols
+]
+.SH DESCRIPTION
+.I Sprat
+creates tilesets from small images created with
+.IR spred (1).
+.PP
+It receives a stream of sprite images on standard input and outputs the resulting tileset plan 9 image (see
+.IR image (6)).
+The channel is hardcoded as RGB24 (see
+.IR color (6)).
+.PP
+The input data stream contains information about the palette file. This file is
+.I not
+part of the stream; it will be opened separately by sprat.
+.PP
+The
+.B cols
+parameter determines how many sprite images will be part of a row.
+The rows are filled with
+.B cols
+(default: 8) sprites, then a new row is started.
+.PP
+Free space is filled with black color.
+.PP
+If the dimensions of the sprite images are not the same, a warning is printed to stderr.
+The program will continue, but the output might not be the expected result.
+.SH SOURCE
+.B /sys/src/cmd/sprat
+.SH SEE ALSO
+.IR spred (1)
diff -r 965e0f59464d -r 37e62cb8f2dc sys/src/cmd/sprat.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/src/cmd/sprat.c	Mon May 11 12:18:19 2020 +0200
@@ -0,0 +1,183 @@
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#include <draw.h>
+#include <memdraw.h>
+
+int cols = 8;
+int ncols, nrows;
+int count = 0;
+
+char palfile[BUFSIZ];
+char buf[BUFSIZ];
+
+Point dimen;
+int palsize;
+Memimage *img;
+Memimage *color;
+Memimage **palette;
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [ -c cols ]\n", argv0);
+	exits("usage");
+}
+
+int
+loadpalette(void)
+{
+	FILE *fd;
+	int i, c;
+	int r, g, b;
+	
+	if (palette) {
+		for (i = 0; i < palsize; i++) {
+			freememimage(palette[i]);
+		}
+		free(palette);
+	}
+	
+	if ((fd = fopen(palfile, "r")) == nil) {
+		werrstr("cannot open file for read: %s", palfile);
+		return 0;
+	}
+	
+	if (fscanf(fd, "pal %d\n", &palsize) != 1) {
+		werrstr("invalid palette file Format");
+		return 0;
+	}
+	
+	palette = malloc(palsize * sizeof(Memimage*));
+	
+	for (i = 0; i < palsize; i++) {
+		if (fscanf(fd, "0x%2x%2x%2x\n", &r, &g, &b) != 3) {
+			werrstr("invalid palette file format");
+			return 0;
+		}
+		palette[i] = allocmemimage(Rect(0, 0, 1, 1), RGB24);
+		c  = r<<8*3;
+		c += g<<8*2;
+		c += b<<8*1;
+		memfillcolor(palette[i], c);
+	}
+	
+	fclose(fd);
+	return 1;
+}
+
+int
+shiftimage(Memimage *i)
+{
+	Memimage *tmp;
+	Rectangle r;
+	Point p;
+	
+	if (ncols + nrows <= 0) {
+		img = allocmemimage(Rect(0, 0, dimen.x, dimen.y), RGB24);
+		if (!img) {
+			werrstr("cannot allocate img");
+			return 0;
+		}
+	}
+	if ((count/cols) + 1 > nrows)
+		nrows = (count/cols) + 1;
+	ncols = (count < cols-1 ? count : cols-1) + 1;
+	tmp = allocmemimage(Rect(0, 0, ncols*dimen.x, nrows*dimen.y), RGB24);
+	memfillcolor(tmp, 0);
+	
+	memimagedraw(tmp, img->r, img, ZP, nil, ZP, S);
+	
+	p = Pt((count%cols)*dimen.x, count/cols*dimen.y);
+	r = rectaddpt(Rect(0, 0, dimen.x, dimen.y), p);
+	memimagedraw(tmp, r, i, ZP, nil, ZP, S);
+	
+	count++;
+	
+	freememimage(img);
+	img = tmp;
+	
+	return 1;
+}
+
+int
+limage(void)
+{
+	Memimage *rimage;
+	int x, y, c;
+	
+	rimage = allocmemimage(Rect(0, 0, dimen.x, dimen.y), RGB24);
+	if (rimage == nil) {
+		werrstr("cannot allocate memimage for sprite");
+		return 0;
+	}
+	
+	for (y = 0; y < dimen.y; y++) {
+		for (x = 0; x < dimen.x; x++) {
+			if (scanf("%d", &c) != 1) {
+				werrstr("bad image data");
+				return 0;
+			}
+			memimagedraw(rimage, rectaddpt(Rect(0, 0, 1, 1), Pt(x, y)),
+				palette[c], ZP, nil, ZP, S);
+		}
+	}
+	
+	if (!shiftimage(rimage)) {
+		freememimage(rimage);
+		return 0;
+	}
+	freememimage(rimage);
+	
+	return 1;
+}
+
+void
+main(int argc, char **argv)
+{
+	char streammagic[7];
+	Point readp;
+	
+	ARGBEGIN {
+	case 'c':
+		cols = atoi(EARGF(usage()));
+		break;
+	} ARGEND;
+	
+	if (memimageinit())
+		sysfatal("memimageinit failed: %r");
+	
+	color = allocmemimage(Rect(0, 0, 1, 1), RGB24);
+	if (!color)
+		sysfatal("cannot allocate memimage");
+	
+	readp = Pt(0, 0);
+	
+	while (1) {
+		if (read(0, streammagic, 6) != 6)
+			break;
+		
+		if (strcmp(streammagic, "sprite") != 0)
+			sysfatal("bad data Format");
+		
+		if (scanf("%d %d %s", &readp.x, &readp.y, palfile) != 3)
+			sysfatal("bad data stream");
+		
+		if (dimen.x + dimen.y != 0) {
+			if (readp.x != dimen.x || readp.y != dimen.y) {
+				fprint(2, "inconsistent dimensions. continuing, but check output!\n");
+			}
+		}
+		dimen = readp;
+		
+		if (!loadpalette())
+			sysfatal("error loading palette file: %r");
+		
+		if (!limage())
+			sysfatal("error loading sprite data: %r");
+	}
+	
+	if (writememimage(1, img))
+		sysfatal("error writing image: %r");
+	freememimage(img);
+}



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2020-05-11 10:46 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-05-11 10:46 sprat, sprite cat sirjofri

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).