ref: 902ca370394b608c685eb79ca61386a530bc9a85
dir: /main.c/
#include <u.h>
#include <libc.h>
#include <draw.h>
#include <memdraw.h>
#include <mouse.h>
#include <keyboard.h>
#include <thread.h>
#include "frame.h"
#include "misc.h"
#include "stream.h"
#include "decoder.h"
int mainstacksize = 128*1024;
static Image *curim;
static uvlong lastframe;
static void
drawframe(Frame *f)
{
uvlong x, end, left;
static uvlong delay;
Rectangle r;
lockdisplay(display);
if(curim != nil && (Dx(curim->r) != f->w || Dy(curim->r) != f->h)){
freeimage(curim);
curim = nil;
}
r = Rect(0,0,f->w,f->h);
if(curim == nil)
curim = allocimage(display, r, RGB24, 0, DNofill);
loadimage(curim, r, f->rgb, f->w*f->h*3);
if(lastframe == 0)
lastframe = nanosec();
end = lastframe + f->dt - delay;
while(1){
x = nanosec();
if(x >= end)
break;
left = end - x;
if(left > 750000000ULL)
sleep(70);
else if(left > 250000000ULL)
sleep(20);
else if(left > 100000000ULL)
sleep(1);
}
x = nanosec();
if(Dx(r) < Dx(screen->r) && Dy(r) < Dy(screen->r))
r = rectsubpt(screen->r, divpt(Pt(Dx(r)-Dx(screen->r), Dy(r)-Dy(screen->r)), 2));
else
r = screen->r;
draw(screen, r, curim, nil, ZP);
flushimage(display, 1);
unlockdisplay(display);
delay = nanosec() - x;
lastframe += f->dt;
free(f);
}
void
threadmain(int argc, char **argv)
{
enum {
Cframe,
Cplayerdone,
Cmouse,
Ckeyboard,
Cresize,
Cnum,
};
Frame *frame;
Mousectl *mctl;
Keyboardctl *kctl;
Rune key;
Mouse m;
char *s;
Stream *stream;
Streaminfo info;
Decoder *d;
int i, end, done, res;
Alt a[Cnum+1] =
{
[Cframe] = { nil, &frame, CHANRCV },
[Cplayerdone] = { nil, nil, CHANRCV },
[Cmouse] = { nil, &m, CHANRCV },
[Ckeyboard] = { nil, &key, CHANRCV },
[Cresize] = { nil, nil, CHANRCV },
[Cnum] = { nil, nil, CHANEND },
};
ARGBEGIN{
}ARGEND
if(argc < 1)
sysfatal("usage");
nproc = atoi((s = getenv("NPROC")) != nil ? s : "1");
srand(nanosec());
if(initdraw(nil, nil, "treason") < 0)
sysfatal("initdraw: %r");
flushimage(display, 1);
display->locking = 1;
unlockdisplay(display);
if((mctl = initmouse(nil, screen)) == nil)
sysfatal("initmouse: %r");
if((kctl = initkeyboard(nil)) == nil)
sysfatal("initkeyboard: %r");
a[Cmouse].c = mctl->c;
a[Cresize].c = mctl->resizec;
a[Ckeyboard].c = kctl->c;
for(end = i = 0; !end && i < argc; i++){
draw(screen, screen->r, display->black, nil, ZP);
if((stream = Sopen(argv[i], &info)) == nil)
sysfatal("%r");
if((d = Dopen(stream, &info)) == nil)
sysfatal("%r");
a[Cframe].c = d->frames;
a[Cplayerdone].c = d->finished;
lastframe = 0;
for(done = 0; !done && !end;){
res = alt(a);
switch(res){
case Cframe:
drawframe(frame);
break;
case Cplayerdone:
done = 1;
break;
case Cmouse:
break;
case Ckeyboard:
end = key == 'q' || key == Kdel;
done = key == '\n';
break;
case Cresize:
lockdisplay(display);
if(getwindow(display, Refnone) < 0)
sysfatal("getwindow: %r");
freeimage(curim);
curim = nil;
draw(screen, screen->r, display->black, nil, ZP);
flushimage(display, 1);
unlockdisplay(display);
break;
}
}
Dclose(d);
Sclose(stream);
}
threadexitsall(nil);
}