17 s = emalloc(sizeof(*s));
26 if(s->pal != nil && !decref(s->pal) && s->pal->change <= 0)
33 readspr(Spr *s, Biobuf *bp)
35 char *args0[8], *p, *ss, **args;
40 if(tline(bp, &ss, args0, nelem(args0)) != 4)
42 if(strcmp(args0[0], "sprite") != 0)
44 n = strtol(args0[1], &p, 0);
48 n = strtol(args0[2], &p, 0);
53 s->palfile = strdup(args0[3]);
58 s->data = emalloc(s->w * s->h * sizeof(u32int));
59 args = emalloc((s->w + 1) * sizeof(char *));
60 for(i = 0; i < s->h; i++){
61 if(tline(bp, &ss, args, s->w + 1) != s->w)
63 for(j = 0; j < s->w; j++){
64 n = strtol(args[j], &p, 0);
67 s->data[i * s->w + j] = n;
75 werrstr("invalid format");
84 writespr(Spr *s, char *file)
92 bp = Bopen(file, OWRITE);
97 rc = Bprint(bp, "sprite %d %d %q\n", s->w, s->h, s->palfile != nil ? s->palfile : "");
100 for(i = 0; i < s->h; i++)
101 for(j = 0; j < s->w; j++){
102 rc = Bprint(bp, "%d%c", s->data[s->w * i + j], j == s->w - 1 ? '\n' : ' ');
112 cmdprint("%s: #%d\n", file, n);
128 sprrect(Win *w, Rectangle s)
135 p = Pt(t->w * w->zoom, t->h * w->zoom);
136 q = addpt(divpt(addpt(s.min, s.max), 2), w->scr);
137 r.min = subpt(q, divpt(p, 2));
138 r.max = addpt(r.min, p);
149 if(rectinrect(w->sprr, w->inner))
152 dx = Dx(r) - SCRTSIZ;
153 dy = Dy(r) - SCRTSIZ;
154 if(dx <= 0 || dy <= 0)
157 if(!rectclip(&s, w->sprr))
159 draw(w->im, Rect(r.min.x, r.max.y - SCRBSIZ, r.max.x - SCRTSIZ, r.max.y), w->tab->cols[BORD], nil, ZP);
160 draw(w->im, Rect(r.max.x - SCRBSIZ, r.min.y, r.max.x, r.max.y - SCRTSIZ), w->tab->cols[BORD], nil, ZP);
161 t0 = (s.min.x - w->sprr.min.x) * dx / Dx(w->sprr) + r.min.x;
162 t1 = (s.max.x - w->sprr.min.x) * dx / Dx(w->sprr) + r.min.x;
163 draw(w->im, Rect(t0, r.max.y - SCRBSIZ + 1, t1, r.max.y), w->tab->cols[BACK], nil, ZP);
164 t0 = (s.min.y - w->sprr.min.y) * dy / Dy(w->sprr) + r.min.y;
165 t1 = (s.max.y - w->sprr.min.y) * dy / Dy(w->sprr) + r.min.y;
166 draw(w->im, Rect(r.max.x - SCRBSIZ, t0, r.max.x, t1), w->tab->cols[BACK], nil, ZP);
179 if(w->type != SPR || w->f == nil)
180 sysfatal("sprdraw: phase error");
183 draw(w->im, w->inner, w->tab->cols[BACK], nil, ZP);
184 r = sprrect(w, w->inner);
186 if(!rectinrect(r, w->inner)){
196 for(j = 0; j < s->h; j++)
197 for(i = 0; i < s->w; i++, d++){
198 t.min = addpt(w->sprr.min, Pt(i * w->zoom, j * w->zoom));
199 t.max = addpt(t.min, Pt(w->zoom, w->zoom));
202 if(p != nil && *d < p->ncol)
206 draw(w->im, t, im, nil, ZP);
211 sprbars(Win *w, Mousectl *mc)
215 if(rectinrect(w->sprr, w->inner))
217 if(mc->xy.x >= w->inner.max.x - SCRBSIZ){
218 d = Dy(w->inner) / 5;
220 case 1: w->scr.y += d; break;
221 case 4: w->scr.y -= d; break;
227 if(mc->xy.y >= w->inner.max.y - SCRBSIZ){
228 d = Dx(w->inner) / 5;
230 case 1: w->scr.x += d; break;
231 case 4: w->scr.x -= d; break;
241 sprclick(Win *w, Mousectl *mc)
248 sysfatal("sprclick: phase error");
249 if(sprbars(w, mc) >= 0)
253 if(p == nil || p->sel < 0 || p->sel >= p->ncol)
256 q = divpt(subpt(mc->xy, w->sprr.min), w->zoom);
257 if(q.x < 0 || q.y < 0 || q.x >= s->w || q.y >= s->h)
259 if(s->data[q.y * s->w + q.x] != p->sel){
260 s->data[q.y * s->w + q.x] = p->sel;
264 }while(readmouse(mc) >= 0 && (mc->buttons & 1) != 0);
268 sprsize(Spr *s, int n, int m, int ch)
274 if(s->w == n && s->h == m)
276 s->data = emalloc(n * m * sizeof(u32int));
277 w = n < s->w ? n : s->w;
278 h = m < s->h ? m : s->h;
279 for(j = 0; j < h; j++)
280 for(i = 0; i < w; i++)
281 s->data[j * n + i] = v[j * w + i];
290 palfile(char *, char *n)
296 sprmenu(Win *w, Mousectl *mc)
299 static char *menus[] = {
303 static Menu menu = {menus};
308 sysfatal("sprmenu: phase error");
310 switch(menuhit(2, mc, &menu, scr)){
313 if(wp == nil || wp->type != PAL)
316 sysfatal("sprmenu: pal phase error");
317 if(s->pal != (Pal *) wp->f){
318 if(s->pal != nil && decref(s->pal) == 0 && s->pal->change <= 0)
321 s->pal = (Pal *) wp->f;
323 s->palfile = palfile(s->name, s->pal->name);
324 cmdprint("palette set to %q\n", s->palfile);
333 sprzerox(Win *w, Win *v)
340 sprkey(Win *w, Rune r)
342 static char keys[] = "1234567890qwertyuiop";
348 sysfatal("sprkey: phase error");
349 if(r < 0x100 && (p = strchr(keys, r)) != nil){
350 if(s->pal == nil || p - keys >= s->pal->ncol)
352 s->pal->sel = p - keys;