shithub: wl3d

ref: 3b2f4d3df58368ce53243dd992612b9fcb7f0d1a
dir: /drw.c/

View raw version
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"

Fnt fnts[2], *fnt;
Pic *pics;
uchar **exts, **dems, **epis;
Dat *wals, *sprs;

int scale, npx;
uchar *px, pxb[Va], fzb[Vw*Vhud];
View vw;

static Col *fcol;
static u32int *fref;
static int fi, fo, fdt;
static uchar *fzd;
static int fzc, fzdx, fzdy, fzdn, fzn, fzout;

static uchar wl6ceil[] = {
	0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0xbf,
	0x4e, 0x4e, 0x4e, 0x1d, 0x8d, 0x4e, 0x1d, 0x2d, 0x1d, 0x8d,
	0x1d, 0x1d, 0x1d, 0x1d, 0x1d, 0x2d, 0xdd, 0x1d, 0x1d, 0x98,
	0x1d, 0x9d, 0x2d, 0xdd, 0xdd, 0x9d, 0x2d, 0x4d, 0x1d, 0xdd,
	0x7d, 0x1d, 0x2d, 0x2d, 0xdd, 0xd7, 0x1d, 0x1d, 0x1d, 0x2d,
	0x1d, 0x1d, 0x1d, 0x1d, 0xdd, 0xdd, 0x7d, 0xdd, 0xdd, 0xdd,
};
static uchar sodceil[] = {
	0x6f, 0x4f, 0x1d, 0xde, 0xdf, 0x2e, 0x7f, 0x9e, 0xae, 0x7f,
	0x1d, 0xde, 0xdf, 0xde, 0xdf, 0xde, 0xe1, 0xdc, 0x2e, 0x1d, 0xdc
};

static void
hudnp(int x, int y, int dx, int n)
{
	char s[20], *p;

	memset(s, 0, sizeof s);
	p = s;
	if(n == 0)
		p++;
	while(n > 0 && p < s + sizeof s)
		*p++ = n % 10, n /= 10;
	n = dx - (p - s);
	if(n > 0)
		memset(p, -1, n);	/* Pblank == Pn0 - 1, always */
	p += n - 1;
	while(p >= s){
		pic(x, y, pict[Pn0] + *p--);
		x += 8;
	}
}

void
fizz(void)
{
	int i, x, y, ofs;

	for(i=0; i<fzdn*Δtc; i++){
		y = fzn - 1 & 0xff;
		x = fzn >> 8;
		fzn = fzn >> 1 ^ (fzn & 1 ? 0x12000 : 0);
		if(x >= fzdx || y >= fzdy)
			continue;
		ofs = y * Vw + x;
		fzd[ofs] = fzout ? fzc : fzb[ofs];
		if(fzn == 1){
			fzdn = 0;
			break;
		}
	}
	out();
}

void
fizzop(int c, int save)
{
	if(save)
		memcpy(fzb, pxb + vw.ofs, (vw.dy-1) * Vw + vw.dx-1);
	if(c < 0){
		fzd = pxb + vw.ofs;
		fzdx = vw.dx;
		fzdy = vw.dy;
		fzdn = Va / 20;
		fzout = 0;
	}else{
		fzd = pxb;
		fzdx = Vw;
		fzdy = Vhud;
		fzdn = Va / 70;
		fzout = 1;
		fzc = c;
	}
	fzn = 1;
}

void
fadeout(void)
{
	int i, u, v, w;
	u32int p, *s, *d;

	i = fo + Δtc;
	if(i > fdt)
		i = fdt;
	fo = i;
	s = fref;
	d = pal;
	while(d < pal + nelem(pals[0])){
		p = *s++;
		u = p & 0xff;
		v = p>>8 & 0xff;
		w = p>>16 & 0xff;
		u = u + (fcol->b-u) * i/fdt;
		v = v + (fcol->g-v) * i/fdt;
		w = w + (fcol->r-w) * i/fdt;
		*d++ = w<<16 | v<<8 | u;
	}
	out();
}

void
fadein(void)
{
	int i, u, v, w;
	u32int p, *s, *d;

	i = fi + Δtc;
	if(i > fdt)
		i = fdt;
	fi = i;
	s = fref;
	d = pal;
	while(d < pal + nelem(pals[0])){
		p = *s++;
		u = p & 0xff;
		v = p>>8 & 0xff;
		w = p>>16 & 0xff;
		u = fcol->b + (u-fcol->b) * i/fdt;
		v = fcol->g + (v-fcol->g) * i/fdt;
		w = fcol->r + (w-fcol->r) * i/fdt;
		*d++ = w<<16 | v<<8 | u;
	}
	out();
}

void
fadeop(Col *c, int dt)
{
	fi = 0;
	fo = 0;
	fdt = dt;
	fcol = c;
	fref = pal;
	pal = pals[Cfad];
}

void
palpic(uchar *s)
{
	u32int *p;

	p = pal = pals[Csod];
	while(p < pals[Csod] + nelem(pals[0])){
		*p++ = s[0]*255/63<<16 | s[1]*255/63<<8 | s[2]*255/63;
		s += 3;
	}
}

void
out(void)
{
	int n;
	u32int c;
	uchar *s, *d, *w;

	d = px;
	s = pxb;
	n = scale * 3;
	while(s < pxb + sizeof pxb){
		c = pal[*s++];
		w = d + n;
		while(d < w){
			*d++ = c;
			*d++ = c>>8;
			*d++ = c>>16;
		}
	}
	flush();
}

void
pput(int x, int y, int dx, int dy, uchar *s)
{
	uchar *d;

	d = pxb + x + y*Vw;
	while(dy-- > 0){
		memcpy(d, s, dx);
		s += dx;
		d += Vw;
	}	
}

void
put(int x, int y, int dx, int dy, int c)
{
	uchar *d;

	d = pxb + x + y*Vw;
	while(dy-- > 0){
		memset(d, c, dx);
		d += Vw;
	}	
}

int
txt(int x, int y, char *t, int col)
{
	int h, w;
	uchar c, *d, *s, *p, *e, *q;

	h = fnt->h;
	p = fnt->p;
	c = *t++;
	d = pxb + x + y*Vw;
	x = 0;
	while(c != 0){
		w = fnt->w[c];
		s = p + fnt->ofs[c];
		e = s + w*h;
		while(s < e){
			q = s + w;
			while(s < q){
				c = *s++;
				if(c != 0)
					*d = col;
				d++;
			}
			d += Vw-w;
		}
		d -= Vw*h - w;
		x += w;
		c = *t++;
	}
	return x;
}

int
txtnl(int x, int y, char *t, int col)
{
	int n;
	char *s, *m;

	n = 0;
	m = strdup(t);
	if(m == nil)
		sysfatal("txtnl: %r");
	s = strtok(m, "\n");
	while(s != nil){
		n += txt(x, y, s, col);
		s = strtok(nil, "\n");
		y += fnt->h;
	}
	free(m);
	return n;
}

int
txth(char *t)
{
	int h, n;

	h = fnt->h;
	n = h;
	while(*t != 0)
		if(*t++ == '\n')
			n += h;
	return n;
}

int
txtw(char *t)
{
	int n, m;

	n = m = 0;
	while(*t != 0){
		if(*t == '\n'){
			if(n > m)
				m = n;
			n = 0;
		}else
			n += fnt->w[(uchar)*t];
		t++;
	}
	return n > m ? n : m;
}

void
fill(int c)
{
	memset(pxb, c, sizeof pxb);
}

void
pic(int x, int y, int n)
{
	Pic *p;

	p = pics+n;
	pput(x, y, p->x, p->y, p->p);
}

void
pictxt(int x0, int y, char *t)
{
	int p, x, n;
	char c;

	x = x0;
	for(;;){
		c = *t++;
		n = 16;
		switch(c){
		case 0: return;
		case '\n': y += 16; x = x0 - 16; goto skip;
		case ' ': goto skip;
		case '!': p = pict[Pexcl]; n = 8; break;
		case '\'': p = pict[Papo]; n = 8; break;
		case ':': p = pict[Pcolon]; n = 8; break;
		case '%': p = pict[Ppercent]; break;
		default: p = pict[P0] + c - (c >= 'A' ? 'A'-11 : '0'); break;
		}
		pic(x, y, p);
skip:
		x += n;
	}
}

void
hudf(void)
{
	int p;

	if(gm.hp > 0){
		p = god ? pict[Pgod] : pict[Pface1] + 3 * (100 - gm.hp >> 4);
		p += gm.facefrm;
	}else
		p = gm.mut ? pict[Pmut] : pict[Pface8];
	pic(136, 164, p);
}

void
hudh(void)
{
	hudnp(168, 176, 3, gm.hp);
}

void
hudl(void)
{
	hudnp(112, 176, 1, gm.lives);
}

void
hudm(void)
{
	hudnp(16, 176, 2, ver == SOD && gm.map == 20 ? 18 : gm.map+1);
}

void
huda(void)
{
	hudnp(216, 176, 2, gm.ammo);
}

void
hudk(void)
{
	pic(240, 164, pict[gm.keys & 1 ? Pgkey : Pnokey]);
	pic(240, 180, pict[gm.keys & 2 ? Pskey : Pnokey]);
}

void
hudw(void)
{
	pic(256, 168, pict[Pknife]+gm.w);
}

void
hudp(void)
{
	hudnp(48, 176, 6, gm.pt);
}

void
clear(void)
{
	int n;
	uchar c, *p;

	c = ver < SDM ? wl6ceil[gm.map] : sodceil[gm.map];
	p = pxb + vw.ofs;
	n = 0;
	while(n++ < vw.dy){
		memset(p, c, vw.dx);
		p += Vw;
		if(n == vw.dy/2)
			c = 0x19;
	}
}