From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from pizarro.uberspace.de ([185.26.156.189]) by ewsd; Mon May 11 06:47:09 EDT 2020 Received: (qmail 2496 invoked from network); 11 May 2020 10:46:54 -0000 Received: from unknown (HELO ninebox.fritz.box) (84.56.166.18) by pizarro.uberspace.de with SMTP; 11 May 2020 10:46:54 -0000 Message-ID: <8EFC32D745A5C353120FBC00E63719B8@pizarro.uberspace.de> To: 9front@9front.org Subject: sprat, sprite cat Date: Mon, 11 May 2020 12:46:52 +0200 From: sirjofri@sirjofri.de MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: template-based lifecycle-based persistence-scale backend 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 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 +#include +#include +#include +#include + +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); +}