shithub: libgraphics

Download patch

ref: 5f10c82aad318fc9091c9bd612e89fda1a77009f
parent: 78bf838d0c45fbe6e282450e127446de5888fa11
author: rodri <rgl@antares-labs.eu>
date: Sun Jul 14 17:49:43 EDT 2024

initial viewport upscaling support.

--- a/fb.c
+++ b/fb.c
@@ -20,6 +20,30 @@
 }
 
 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)
 {
 	Framebuf *fb;
@@ -31,6 +55,30 @@
 }
 
 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)
 {
 	Framebuf *fb;
@@ -106,7 +154,9 @@
 	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;
--- a/graphics.h
+++ b/graphics.h
@@ -255,7 +255,9 @@
 	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*);
--- 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 *