diff options
author | qwx <devnull@localhost> | 2018-07-25 05:02:46 +0200 |
---|---|---|
committer | qwx <devnull@localhost> | 2018-07-25 05:02:46 +0200 |
commit | a8644d01c34febd6e709c8968fbb926c9115e6c1 (patch) | |
tree | 8d40c668ef833a8ae4d61196dedc25bc37689e72 /sys/src/games | |
parent | 416aed9b662ad9e7ffa9a0bd608b29a878676a7f (diff) |
add games/dpic and games/todpic
Diffstat (limited to 'sys/src/games')
-rw-r--r-- | sys/src/games/dpic.c | 132 | ||||
-rw-r--r-- | sys/src/games/mkfile | 2 | ||||
-rw-r--r-- | sys/src/games/todpic.c | 190 |
3 files changed, 324 insertions, 0 deletions
diff --git a/sys/src/games/dpic.c b/sys/src/games/dpic.c new file mode 100644 index 000000000..98c8170bc --- /dev/null +++ b/sys/src/games/dpic.c @@ -0,0 +1,132 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <bio.h> + +int dx = 64, dy = 64; +Biobuf *bi, *bo; +u32int pal[256]; + +u8int +get8(void) +{ + uchar v; + + if(Bread(bi, &v, 1) != 1) + sysfatal("get8: short read"); + return v; +} + +u16int +get16(void) +{ + u8int v; + + v = get8(); + return get8() << 8 | v; +} + +u32int +get32(void) +{ + u16int v; + + v = get16(); + return get16() << 16 | v; +} + +u32int* +unpic(void) +{ + int n, h; + u32int *p, *d, *cols, *buf; + + dx = get16(); + dy = get16(); + cols = mallocz(dx * sizeof *cols, 1); + buf = mallocz(dx * dy * sizeof *buf, 1); + if(cols == nil || buf == nil) + sysfatal("mallocz: %r"); + get32(); + for(p=cols; p<cols+dx; p++) + *p = get32(); + for(p=cols; p<cols+dx; p++){ + Bseek(bi, *p, 0); + for(;;){ + if((h = get8()) == 0xff) + break; + n = get8(); + get8(); + for(d=buf+(p-cols)+h*dx; n-->0; d+=dx) + *d = pal[get8()]; + get8(); + } + } + free(cols); + return buf; +} + +u32int* +unflat(void) +{ + u32int *p; + static u32int buf[4096]; + + for(p=buf; p<buf+nelem(buf); p++) + *p = pal[get8()]; + return buf; +} + +void +getpal(char *f) +{ + uchar u[3]; + u32int *p; + Biobuf *bp; + + if((bp = Bopen(f, OREAD)) == nil) + sysfatal("getpal: %r"); + for(p=pal; p<pal+nelem(pal); p++){ + if(Bread(bp, u, 3) != 3) + sysfatal("getpal: short read: %r"); + *p = u[2]<<16 | u[1]<<8 | u[0]; + } + Bterm(bp); +} + +void +usage(void) +{ + fprint(2, "usage: %s [-f] [-p palette] pic\n", argv0); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + int fd, flat; + char *p, c[9]; + u32int *buf; + + flat = 0; + p = "/mnt/wad/playpal"; + ARGBEGIN{ + case 'f': flat = 1; break; + case 'p': p = EARGF(usage()); break; + default: usage(); + }ARGEND + if(*argv == nil) + usage(); + if((fd = open(*argv, OREAD)) < 0) + sysfatal("open: %r"); + getpal(p); + bi = Bfdopen(fd, OREAD); + bo = Bfdopen(1, OWRITE); + if(bi == nil || bo == nil) + sysfatal("Bfdopen: %r"); + buf = flat ? unflat() : unpic(); + Bprint(bo, "%11s %11d %11d %11d %11d ", + chantostr(c, XBGR32), 0, 0, dx, dy); + Bwrite(bo, buf, dx * dy * sizeof *buf); + exits(nil); +} diff --git a/sys/src/games/mkfile b/sys/src/games/mkfile index a42eb89e4..824f422c7 100644 --- a/sys/src/games/mkfile +++ b/sys/src/games/mkfile @@ -17,6 +17,8 @@ TARG=4s\ midi\ wadfs\ dmid\ + dpic\ + todpic\ OFILES= HFILES= diff --git a/sys/src/games/todpic.c b/sys/src/games/todpic.c new file mode 100644 index 000000000..89e7aa390 --- /dev/null +++ b/sys/src/games/todpic.c @@ -0,0 +1,190 @@ +#include <u.h> +#include <libc.h> +#include <draw.h> +#include <memdraw.h> +#include <bio.h> + +int wofs; +u32int pal[256], bg = 0x00ffff; +Biobuf *bp; + +#define abs(x) ((x) < 0 ? -(x) : (x)) + +void +put8(u8int v) +{ + if(Bwrite(bp, &v, sizeof v) != sizeof v) + sysfatal("put8: short write"); +} + +void +put16(u16int v) +{ + put8(v); + put8(v >> 8); +} + +void +put32(u32int v) +{ + put16(v); + put16(v >> 16); +} + +int +pali(u32int v) +{ + int i, Δ, Δ´; + u32int *p; + + i = 0; + Δ = abs((char)v - (char)*pal) + + abs((char)(v >> 8) - (char)(*pal >> 8)) + + abs((char)(v >> 16) - (char)(*pal >> 16)); + for(p=pal; p<pal+nelem(pal); p++){ + Δ´ = abs((char)v - (char)*p) + + abs((char)(v >> 8) - (char)(*p >> 8)) + + abs((char)(v >> 16) - (char)(*p >> 16)); + if(Δ´ < Δ){ + Δ = Δ´; + i = p - pal; + if(Δ == 0) + break; + } + } + return i; +} + +void +topic(Memimage *i) +{ + int w, h, dx, dy; + uchar *np, *b, *buf, *p, *pp; + u32int v; + + p = i->data->bdata; + dx = Dx(i->r); + dy = Dy(i->r); + if(dy > 254) + sysfatal("topic: invalid pic height"); + put16(dx); + put16(dy); + put16(wofs ? dx / 2 - 1 : i->r.min.x); + put16(wofs ? dy - 5 : i->r.min.y); + if(i->r.min.x != 0) + dx = i->width; + buf = mallocz((5 * dy / 2 + 5) * dx, 1); + if(buf == nil) + sysfatal("mallocz: %r"); + for(w=dx, b=buf; w>0; w--, p+=3){ + put32(b - buf + 8 + dx * 4); + for(h=0, np=b+1, pp=p; h<dy; h++, pp+=dx*3){ + v = pp[2] << 16 | pp[1] << 8 | pp[0]; + if(v == bg){ + if(b - np - 2 > 0){ + *np = b - np - 2; + *b++ = 0; + np = b + 1; + } + continue; + } + if(b - np - 2 < 0){ + *b++ = h; + b++; + *b++ = 0; + } + *b++ = pali(v); + } + if(b - np - 2 >= 0){ + *np = b - np - 2; + *b++ = 0; + } + *b++ = 0xff; + } + Bwrite(bp, buf, b - buf); + free(buf); +} + +void +toflat(Memimage *i) +{ + int n; + uchar *p; + + if(Dx(i->r) != 64 || Dy(i->r) != 64) + sysfatal("toflat: invalid flatpic dimensions"); + p = i->data->bdata; + n = 64*64; + while(n-- > 0){ + put8(pali(p[2] << 16 | p[1] << 8 | p[0])); + p += 4; + } +} + +static Memimage* +iconv(Memimage *i) +{ + Memimage *ni; + + if(i->chan == RGB24) + return i; + if((ni = allocmemimage(i->r, RGB24)) == nil) + sysfatal("allocmemimage: %r"); + memimagedraw(ni, ni->r, i, i->r.min, nil, i->r.min, S); + freememimage(i); + return ni; +} + +void +getpal(char *f) +{ + uchar u[3]; + u32int *p; + Biobuf *bp; + + if((bp = Bopen(f, OREAD)) == nil) + sysfatal("getpal: %r"); + for(p=pal; p<pal+nelem(pal); p++){ + if(Bread(bp, u, 3) != 3) + sysfatal("getpal: short read: %r"); + *p = u[0]<<16 | u[1]<<8 | u[2]; + } + Bterm(bp); +} + +void +usage(void) +{ + fprint(2, "usage: %s [-fw] [-b bgcol] [-p palette] [image]\n", argv0); + exits("usage"); +} + +void +main(int argc, char **argv) +{ + int fd, flat; + char *p; + Memimage *i; + + fd = 0; + flat = 0; + p = "/mnt/wad/playpal"; + ARGBEGIN{ + case 'b': bg = strtoul(EARGF(usage()), nil, 0); break; + case 'f': flat = 1; break; + case 'p': p = EARGF(usage()); break; + case 'w': wofs = 1; break; + default: usage(); + }ARGEND + if(*argv != nil) + if((fd = open(*argv, OREAD)) < 0) + sysfatal("open: %r"); + getpal(p); + if((bp = Bfdopen(1, OWRITE)) == nil) + sysfatal("Bfdopen: %r"); + memimageinit(); + if((i = readmemimage(fd)) == nil) + sysfatal("readmemimage: %r"); + (flat ? toflat : topic)(iconv(i)); + exits(nil); +} |