From 5f10c82aad318fc9091c9bd612e89fda1a77009f Mon Sep 17 00:00:00 2001 From: rodri Date: Sun, 14 Jul 2024 21:49:43 +0000 Subject: initial viewport upscaling support. --- fb.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ graphics.h | 2 ++ viewport.c | 26 ++++++++++++++++++++++++-- 3 files changed, 76 insertions(+), 2 deletions(-) diff --git a/fb.c b/fb.c index e0fa2cd..a23e305 100644 --- a/fb.c +++ b/fb.c @@ -19,6 +19,30 @@ framebufctl_draw(Framebufctl *ctl, Image *dst) qunlock(ctl); } +static void +framebufctl_upscaledraw(Framebufctl *ctl, Image *dst, Point scale) +{ + Framebuf *fb; + Rectangle blkr; + Point sp, dp; + ulong *blk; + int i; + + blk = emalloc(scale.x*scale.y*4); + blkr = Rect(0,0,scale.x,scale.y); + + qlock(ctl); + fb = ctl->getfb(ctl); + for(sp.y = fb->r.min.y, dp.y = dst->r.min.y; sp.y < fb->r.max.y; sp.y++, dp.y += scale.y) + for(sp.x = fb->r.min.x, dp.x = dst->r.min.x; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){ + for(i = 0; i < scale.x*scale.y; i++) + blk[i] = fb->cb[Dx(fb->r)*sp.y + sp.x]; + loadimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4); + } + qunlock(ctl); + free(blk); +} + static void framebufctl_memdraw(Framebufctl *ctl, Memimage *dst) { @@ -30,6 +54,30 @@ framebufctl_memdraw(Framebufctl *ctl, Memimage *dst) qunlock(ctl); } +static void +framebufctl_upscalememdraw(Framebufctl *ctl, Memimage *dst, Point scale) +{ + Framebuf *fb; + Rectangle blkr; + Point sp, dp; + ulong *blk; + int i; + + blk = emalloc(scale.x*scale.y*4); + blkr = Rect(0,0,scale.x,scale.y); + + qlock(ctl); + fb = ctl->getfb(ctl); + for(sp.y = fb->r.min.y, dp.y = dst->r.min.y; sp.y < fb->r.max.y; sp.y++, dp.y += scale.y) + for(sp.x = fb->r.min.x, dp.x = dst->r.min.x; sp.x < fb->r.max.x; sp.x++, dp.x += scale.x){ + for(i = 0; i < scale.x*scale.y; i++) + blk[i] = fb->cb[Dx(fb->r)*sp.y + sp.x]; + loadmemimage(dst, rectaddpt(blkr, dp), (uchar*)blk, scale.x*scale.y*4); + } + qunlock(ctl); + free(blk); +} + static void framebufctl_drawnormals(Framebufctl *ctl, Image *dst) { @@ -106,7 +154,9 @@ mkfbctl(Rectangle r) fc->fb[0] = mkfb(r); fc->fb[1] = mkfb(r); fc->draw = framebufctl_draw; + fc->upscaledraw = framebufctl_upscaledraw; fc->memdraw = framebufctl_memdraw; + fc->upscalememdraw = framebufctl_upscalememdraw; fc->drawnormals = framebufctl_drawnormals; fc->swap = framebufctl_swap; fc->reset = framebufctl_reset; diff --git a/graphics.h b/graphics.h index 3c170f7..511564e 100644 --- a/graphics.h +++ b/graphics.h @@ -255,7 +255,9 @@ struct Framebufctl uint idx; /* front buffer index */ void (*draw)(Framebufctl*, Image*); + void (*upscaledraw)(Framebufctl*, Image*, Point); void (*memdraw)(Framebufctl*, Memimage*); + void (*upscalememdraw)(Framebufctl*, Memimage*, Point); void (*drawnormals)(Framebufctl*, Image*); void (*swap)(Framebufctl*); void (*reset)(Framebufctl*); diff --git a/viewport.c b/viewport.c index 0336353..d37a12c 100644 --- a/viewport.c +++ b/viewport.c @@ -11,13 +11,35 @@ static void viewport_draw(Viewport *v, Image *dst) { - v->fbctl->draw(v->fbctl, dst); + Point scale; + + scale.x = Dx(dst->r)/Dx(v->r); + scale.y = Dy(dst->r)/Dy(v->r); + + /* no downsampling support yet */ + assert(scale.x > 0 && scale.y > 0); + + if(scale.x > 1 || scale.y > 1) + v->fbctl->upscaledraw(v->fbctl, dst, scale); + else + v->fbctl->draw(v->fbctl, dst); } static void viewport_memdraw(Viewport *v, Memimage *dst) { - v->fbctl->memdraw(v->fbctl, dst); + Point scale; + + scale.x = Dx(dst->r)/Dx(v->r); + scale.y = Dy(dst->r)/Dy(v->r); + + /* no downsampling support yet */ + assert(scale.x > 0 && scale.y > 0); + + if(scale.x > 1 || scale.y > 1) + v->fbctl->upscalememdraw(v->fbctl, dst, scale); + else + v->fbctl->memdraw(v->fbctl, dst); } static Framebuf * -- cgit v1.2.3