shithub: cstory

Download patch

ref: a47b7adde380c7479ec053e1982800da12579114
parent: 7a84cdf9b107510f765bcc8dee496b9ba800b8fe
author: Jacob Moody <moody@posixcafe.org>
date: Tue Dec 19 19:13:17 EST 2023

first pass at scaling implementation

--- a/src/Backends/Rendering/9front.cpp
+++ b/src/Backends/Rendering/9front.cpp
@@ -36,9 +36,13 @@
 static RenderBackend_GlyphAtlas *glyph_atlas;
 static RenderBackend_Surface *glyph_destination_surface;
 
+enum {
+	scale = 2,
+};
+
 RenderBackend_Surface* RenderBackend_Init(const char *window_title, size_t width, size_t height, int fullscreen)
 {
-	framebuffer.i = allocimage(display, Rect(0, 0, width, height), screen->chan, 0, DBlue);
+	framebuffer.i = allocimage(display, Rect(0, 0, width*scale, height*scale), screen->chan, 0, DBlue);
 	if(framebuffer.i == nil)
 		sysfatal("could not alloc screen");
 
@@ -65,7 +69,7 @@
 	if (surface == NULL)
 		return NULL;
 
-	surface->i = allocimage(display, Rect(0, 0, width, height), screen->chan, 0, DGreen);
+	surface->i = allocimage(display, Rect(0, 0, width*scale, height*scale), screen->chan, 0, DGreen);
 
 	return surface;
 }
@@ -89,11 +93,48 @@
 	(void)surface;
 }
 
+void RenderBackend_UploadSurfaceScale(RenderBackend_Surface *surface, const unsigned char *pixels, size_t width, size_t height)
+{
+	Image *row;
+	Rectangle r, r2;
+	int i, j, k, l;
+	uchar *buf, *d;
+
+	r = Rect(0, 0, width*scale, 1);
+	r2 = Rect(0, 0, width*scale, scale);
+	row = allocimage(display, r, BGR24, 1, DYellow);
+	buf = malloc(width*scale*3);
+
+	for(i = 0; i < height; i++){
+		d = buf;
+		for(j = 0; j < width; j++)
+		for(k = 0; k < scale; k++){
+			*d++ = pixels[(i*width*3) + j*3 + 0];
+			*d++ = pixels[(i*width*3) + j*3 + 1];
+			*d++ = pixels[(i*width*3) + j*3 + 2];
+		}
+
+		loadimage(row, r, buf, width*scale*3);
+		draw(surface->i, r2, row, nil, ZP);
+		r2.min.y += scale;
+		r2.max.y += scale;
+	}
+
+	freeimage(row);
+	free(buf);
+	surface->dirty = 1;
+}
+
 void RenderBackend_UploadSurface(RenderBackend_Surface *surface, const unsigned char *pixels, size_t width, size_t height)
 {
 	Image *i;
 	Rectangle r;
 
+	if(scale != 1){
+		RenderBackend_UploadSurfaceScale(surface, pixels, width, height);
+		return;
+	}
+
 	r = Rect(0, 0, width, height);
 	i = allocimage(display, r, BGR24, 0, DYellow);
 	loadimage(i, r, pixels, width*height*3);
@@ -148,47 +189,10 @@
 void RenderBackend_Blit(RenderBackend_Surface *source_surface, const RenderBackend_Rect *rect, RenderBackend_Surface *destination_surface, long x, long y, int colour_key)
 {
 	Rectangle r, r2;
-	RenderBackend_Rect rect_clamped;
 
-	rect_clamped.left = rect->left;
-	rect_clamped.top = rect->top;
-	rect_clamped.right = rect->right;
-	rect_clamped.bottom = rect->bottom;
+	r = Rect(rect->left*scale, rect->top*scale, rect->right*scale, rect->bottom*scale);
+	r2 = Rect(x*scale, y*scale, (x*scale+Dx(r)), (y*scale+Dy(r)));
 
-	// Clamp the rect and coordinates so we don't write outside the pixel buffer
-	long overflow;
-
-	overflow = 0 - x;
-	if (overflow > 0)
-	{
-		rect_clamped.left += overflow;
-		x += overflow;
-	}
-
-	overflow = 0 - y;
-	if (overflow > 0)
-	{
-		rect_clamped.top += overflow;
-		y += overflow;
-	}
-
-	overflow = (x + (rect_clamped.right - rect_clamped.left)) - destination_surface->i->r.max.x;
-	if (overflow > 0)
-		rect_clamped.right -= overflow;
-
-	overflow = (y + (rect_clamped.bottom - rect_clamped.top)) - destination_surface->i->r.max.y;
-	if (overflow > 0)
-		rect_clamped.bottom -= overflow;
-
-	if (rect_clamped.bottom - rect_clamped.top <= 0)
-		return;
-
-	if (rect_clamped.right - rect_clamped.left <= 0)
-		return;
-
-	r = Rect(rect_clamped.left, rect_clamped.top, rect_clamped.right, rect_clamped.bottom);
-	r2 = Rect(x, y, x+Dx(r), y+Dy(r));
-
 	if(colour_key && source_surface->dirty)
 		RenderBackend_CalcMask(source_surface);
 
@@ -200,39 +204,8 @@
 {
 	Rectangle r;
 	Image *color;
-	RenderBackend_Rect rect_clamped;
 
-	rect_clamped.left = rect->left;
-	rect_clamped.top = rect->top;
-	rect_clamped.right = rect->right;
-	rect_clamped.bottom = rect->bottom;
-
-	// Clamp the rect so it doesn't write outside the pixel buffer
-	long overflow;
-
-	overflow = 0 - rect_clamped.left;
-	if (overflow > 0)
-		rect_clamped.left += overflow;
-
-	overflow = 0 - rect_clamped.top;
-	if (overflow > 0)
-		rect_clamped.top += overflow;
-
-	overflow = rect_clamped.right - surface->i->r.max.x;
-	if (overflow > 0)
-		rect_clamped.right -= overflow;
-
-	overflow = rect_clamped.bottom - surface->i->r.max.y;
-	if (overflow > 0)
-		rect_clamped.bottom -= overflow;
-
-	if (rect_clamped.bottom - rect_clamped.top <= 0)
-		return;
-
-	if (rect_clamped.right - rect_clamped.left <= 0)
-		return;
-
-	r = Rect(rect_clamped.left, rect_clamped.top, rect_clamped.right, rect_clamped.bottom);
+	r = Rect(rect->left*scale, rect->top*scale, rect->right*scale, rect->bottom*scale);
 	color = allocimage(display, Rect(0, 0, 1, 1), BGR24, 1, (red<<24)|(green<<16)|(blue<<8)|0xFF);
 	draw(surface->i, r, color, nil, ZP);
 	freeimage(color);
@@ -242,7 +215,7 @@
 RenderBackend_GlyphAtlas* RenderBackend_CreateGlyphAtlas(size_t width, size_t height)
 {
 	RenderBackend_GlyphAtlas *atlas = mallocz(sizeof(RenderBackend_GlyphAtlas), 1);
-	atlas->m = allocmemimage(Rect(0, 0, width, height), screen->chan);
+	atlas->m = allocmemimage(Rect(0, 0, width*scale, height*scale), screen->chan);
 	atlas->dirty = 1;
 	return atlas;
 }
@@ -256,23 +229,25 @@
 
 void RenderBackend_UploadGlyph(RenderBackend_GlyphAtlas *atlas, size_t x, size_t y, const unsigned char *pixels, size_t width, size_t height, size_t pitch)
 {
-	uchar *s, *d;
-	ulong dw, max;
-	int ix, iy;
+	uchar *s, *d, *od;
+	ulong dw;
+	int ix, iy, k;
 
 	dw = Dx(atlas->m->r);
-	max = height * pitch;
-	for (iy = 0; iy < max; iy += pitch, y++){
-		s = pixels + iy;
-		d = atlas->m->data->bdata + (y * dw + x) * 4;
+	for(iy = 0; iy < height; iy++, y++){
+		s = pixels + iy*pitch;
+		od = d = byteaddr(atlas->m, Pt(x*scale, y*scale));
 
-		for (ix = 0; ix < width; ix++){
+		for(ix = 0; ix < width; ix++, s++)
+		for(k = 0; k < scale; k++){
 			*d++ = *s;
 			*d++ = *s;
 			*d++ = *s;
 			*d++ = 0xFF;
-			s++;
 		}
+
+		for(k = 1; k < scale; k++)
+			memcpy(byteaddr(atlas->m, Pt(x*scale, y*scale+k)), od, d - od);
 	}
 	atlas->dirty = 1;
 }
@@ -293,8 +268,8 @@
 	Rectangle r, cr;
 	Point p;
 
-	r = Rect(x, y, x+glyph_width, y+glyph_height);
-	p = Pt(glyph_x, glyph_y);
+	r = Rect(x*scale, y*scale, x*scale+glyph_width*scale, y*scale+glyph_height*scale);
+	p = Pt(glyph_x*scale, glyph_y*scale);
 	if(glyph_atlas->dirty){
 		cr = glyph_atlas->m->r;
 		freeimage(glyph_atlas->cache);