ref: b492d42e2545b8c414c917f7544bdd4b92e406e8
dir: /view.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <thread.h>
#include <mouse.h>
#include <cursor.h>
#include <keyboard.h>
#include <ctype.h>
#include "gen3dat.h"
#include "colodat.h"
#include "pse.h"
Save save;
int currentbox = 0;
void *currentpk = nil;
Point spwd;
Image *background, *light;
Image *spritecache[1024];
extern char *dexfiletab[];
extern char *movenametab[];
static void
chbox(int x)
{
int max;
switch(save.type){
default:
case GG3:
max = 13;
break;
case GCOLO:
max = 2;
break;
}
currentbox += x;
if(currentbox < 0)
currentbox = max;
else if(currentbox > max)
currentbox = 0;
}
static int
screenprint(Point p, char *s)
{
char *y, *dot;
Point op;
op = p;
for(y = s; (dot = strchr(y, '\n')) != nil; y = dot+1){
*dot = 0;
string(screen, p, display->black, ZP, display->defaultfont, y);
p.y += display->defaultfont->height;
}
return p.y - op.y;
}
static void
redraw(void)
{
char path[128];
char buf[512];
Image *image;
Rectangle r, r2;
int i;
int fd;
int dex;
void *p;
draw(screen, screen->r, background, nil, ZP);
r = screen->r;
r2 = r;
spwd = Pt(68*2, 56*2);
save.view->hdr(buf, buf + sizeof buf, &save.gen3, currentbox);
r.min.y += screenprint(r.min, buf);
if(currentpk == nil)
currentpk = save.view->box(0, 0, &save.gen3);
for(i = 0; i < 30; i++){
r2.min.x = r.min.x + (i%6) * spwd.x;
r2.min.y = r.min.y + (i/6) * spwd.y;
r2.max.x = r2.min.x + spwd.x;
r2.max.y = r2.min.y + spwd.y;
p = save.view->box(currentbox, i, &save.gen3);
if(p == currentpk)
draw(screen, r2, light, nil, ZP);
dex = save.view->dex(p);
if(dex > 411 || dex == -1)
continue;
snprint(path, sizeof path, "/sys/games/lib/pokesprite/regular/%s.png", dexfiletab[dex]);
image = spritecache[dex];
if(image == nil){
fd = open(path, OREAD);
if(fd < 0){
fprint(2, "could not open %s\n", path);
continue;
}
image = readimage(display, fd, 0);
close(fd);
if(image == nil)
continue;
}
draw(screen, r2, image, nil, ZP);
spritecache[dex] = image;
}
r = screen->r;
r.min.x += 6*spwd.x;
save.view->body(buf, buf + sizeof buf, currentpk);
r.min.y += screenprint(r.min, buf);
flushimage(display, 1);
}
static int
click(Mouse *m)
{
Point p;
if((m->buttons&(1<<3)) != 0){
chbox(-1);
return 1;
} else if((m->buttons&(1<<4)) != 0){
chbox(1);
return 1;
}
if((m->buttons&1) == 0)
return 0;
p = m->xy;
p.y -= screen->r.min.y;
p.x -= screen->r.min.x;
/* FIXME */
p.y -= display->defaultfont->height*3;
p.x /= spwd.x;
p.y /= spwd.y;
if(p.x + (p.y*6) > 30)
return 0;
currentpk = save.view->box(currentbox, (p.x + (p.y*6)), &save.gen3);
return 1;
}
enum{
Ckey,
Cmouse,
Cresize,
Numchan,
};
void
usage(void)
{
fprint(2, "usage: %s [-3c] file\n", argv0);
threadexitsall("usage");
}
mainstacksize = 8192*16;
void
threadmain(int argc, char **argv)
{
Mousectl *mctl;
Keyboardctl *kctl;
Rune r;
Mouse m;
int fd;
Alt a[Numchan+1] = {
[Ckey] = {nil, &r, CHANRCV},
[Cmouse] = {nil, &m, CHANRCV },
[Cresize] = {nil, nil, CHANRCV},
{nil, nil, CHANEND},
};
save.type = GNONE;
ARGBEGIN{
case '3':
save.view = &vgen3;
save.type = GG3;
break;
case 'c':
save.view = &vcolo;
save.type = GCOLO;
break;
default:
usage();
}ARGEND;
if(argc < 1 || save.type == GNONE)
usage();
fd = open(argv[0], OREAD);
if(fd < 0)
sysfatal("open: %r");
save.view->init();
switch(save.type){
case GG3:
getgen3(fd, &save.gen3);
break;
case GCOLO:
getcolo(fd, &save.colo);
break;
}
if(initdraw(nil, nil, "pse") < 0)
sysfatal("initdraw: %r");
if((kctl = initkeyboard(nil)) == nil)
sysfatal("initkeyboard: %r");
a[Ckey].c = kctl->c;
if((mctl = initmouse(nil, screen)) == nil)
sysfatal("initmouse: %r");
a[Cmouse].c = mctl->c;
a[Cresize].c = mctl->resizec;
light = allocimagemix(display, DMedblue, DWhite);
background = allocimagemix(display, DPaleyellow, DWhite);
redraw();
for(;;){
switch(alt(a)){
case -1:
goto end;
case Ckey:
switch (r) {
case 'w':
chbox(-1);
redraw();
break;
case 'e':
chbox(1);
redraw();
break;
case Kdel:
case 'q':
goto end;
break;
}
break;
case Cmouse:
if(click(&m))
redraw();
break;
case Cresize:
getwindow(display, Refnone);
redraw();
break;
}
}
end:
threadexitsall(nil);
}