shithub: qk1

Download patch

ref: affa540c607a2f2f5906e5897ab84643f430ff5a
parent: 96759afc0218a1147e6de661a598267e121fcb84
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sun Dec 31 20:05:32 EST 2023

bring framebuffer scaling back - change dynamically with v_scale cvar

--- a/in_plan9.c
+++ b/in_plan9.c
@@ -5,8 +5,6 @@
 #include <mouse.h>
 #include <keyboard.h>
 
-/* vid.c */
-extern int resized;
 extern Point center;
 extern Rectangle grabr;
 
@@ -269,7 +267,7 @@
 		nerr = 0;
 		switch(*buf){
 		case 'r':
-			resized = 1;
+			vid.resized = true;
 			/* fall through */
 		case 'm':
 			if(!mouseon)
--- a/in_sdl.c
+++ b/in_sdl.c
@@ -1,9 +1,6 @@
 #include "quakedef.h"
 #include <SDL.h>
 
-/* vid.c */
-extern int resized;
-
 static cvar_t m_windowed = {"m_windowed", "1", true};
 static cvar_t m_filter = {"m_filter", "0", true};
 static cvar_t m_raw = {"m_raw", "1", true};
@@ -42,7 +39,7 @@
 		case SDL_WINDOWEVENT:
 			switch(event.window.event){
 			case SDL_WINDOWEVENT_RESIZED:
-				resized = 1;
+				vid.resized = true;
 				break;
 			case SDL_WINDOWEVENT_CLOSE:
 				Cbuf_AddText("menu_quit\n");
--- a/vid.h
+++ b/vid.h
@@ -14,6 +14,7 @@
 typedef struct
 {
 	pixel_t			*buffer;		// invisible buffer
+	pixel_t			*conbuffer;
 	pixel_t			*colormap;		// 256 * VID_GRADES size
 	int				fullbright;		// index of first fullbright color
 	int				width;
@@ -20,8 +21,8 @@
 	int				height;
 	float			aspect;		// width / height -- < 0 is taller than wide
 	int				numpages;
-	int				recalc_refdef;	// if true, recalc vid-based stuff
-	pixel_t			*conbuffer;
+	bool			recalc_refdef;	// if true, recalc vid-based stuff
+	bool			resized;
 	unsigned		conwidth;
 	unsigned		conheight;
 	int				maxwarpwidth;
--- a/vid_plan9.c
+++ b/vid_plan9.c
@@ -3,12 +3,13 @@
 #include <thread.h>
 
 viddef_t vid;		/* global video state */
-int resized;
 Point center;		/* of window */
 Rectangle grabr;
 
 pixel_t q1pal[256];
 static Image *fbi;
+static u32int *scibuf;
+static int scifactor;
 static Rectangle fbr;
 static pixel_t *vidbuffers[2];
 static int bufi = 0;
@@ -28,11 +29,13 @@
 	 * but at least this prevents a crash, beyond that
 	 * it's your funeral */
 	vid.width = Dx(screen->r);
-	if(vid.width < 320)
-		vid.width = 320;
 	vid.height = Dy(screen->r);
-	if(vid.height < 160)
-		vid.height = 160;
+	scifactor = v_scale.value;
+	vid.width /= scifactor;
+	vid.height /= scifactor;
+	vid.width = clamp(vid.width, 320, MAXWIDTH);
+	vid.height = clamp(vid.height, 240, MAXHEIGHT);
+
 	if(dvars.zbuffer != nil)
 		D_FlushCaches();
 
@@ -60,30 +63,66 @@
 	r_warpbuffer = emalloc((vid.width*vid.height+16)*sizeof(pixel_t));
 	vid.maxwarpwidth = vid.width;
 	vid.maxwarpheight = vid.height;
-	freeimage(fbi);
-	fbi = allocimage(display, Rect(0, 0, vid.width, vid.height), XRGB32, 0, 0);
-	if(fbi == nil)
-		sysfatal("resetfb: %r (%d %d)", vid.width, vid.height);
 	vid.buffer = vidbuffers[bufi = 0];
 	vid.conbuffer = vid.buffer;
 	draw(screen, screen->r, display->black, nil, ZP);
+
+	freeimage(fbi);
+	if(scifactor != 1){
+		fbi = allocimage(display, Rect(0, 0, vid.width*scifactor, 1), XRGB32, 1, DNofill);
+		scibuf = realloc(scibuf, vid.width*scifactor*sizeof(*scibuf));
+	}else{
+		fbi = allocimage(display, Rect(0, 0, vid.width, vid.height), XRGB32, 0, 0);
+		free(scibuf);
+		scibuf = nil;
+	}
+	if(fbi == nil)
+		sysfatal("resetfb: %r (%d %d)", vid.width, vid.height);
 }
 
 static void
 loader(void *)
 {
-	byte *f;
+	u32int *in, *out;
+	int n, x, y, j;
+	Point center;
 	Rectangle r;
-	int n;
+	byte *f;
 
+	center = addpt(screen->r.min, Pt(Dx(screen->r)/2, Dy(screen->r)/2));
 	r = Rect(0, 0, vid.width, vid.height);
-	n = vid.width * vid.height;
+	if(scibuf == nil)
+		n = vid.width * vid.height;
+	else
+		n = vid.width * scifactor * sizeof(*scibuf);
+
 	for(;;){
 		if((f = recvp(frame)) == nil)
 			break;
-		if(loadimage(fbi, r, f, n*4) != n*4)
-			sysfatal("%r");
-		draw(screen, fbr, fbi, nil, ZP);
+		if(scibuf != nil){
+			in = (u32int*)f;
+
+			r = rectsubpt(
+				rectaddpt(Rect(0, 0, scifactor*vid.width, scifactor), center),
+				Pt(scifactor*vid.width/2, scifactor*vid.height/2)
+			);
+
+			for(y = 0; y < vid.height; y++){
+				for(x = 0, out = scibuf; x < vid.width; x++, in++){
+					for(j = 0; j < scifactor; j++, out++)
+						*out = *in;
+				}
+				if(loadimage(fbi, fbi->r, (byte*)scibuf, n) != n)
+					sysfatal("%r");
+				draw(screen, r, fbi, nil, ZP);
+				r.min.y += scifactor;
+				r.max.y += scifactor;
+			}
+		}else{
+			if(loadimage(fbi, r, f, n*4) != n*4)
+				sysfatal("%r");
+			draw(screen, fbr, fbi, nil, ZP);
+		}
 		if(flushimage(display, 1) < 0)
 			sysfatal("%r");
 	}
@@ -103,11 +142,11 @@
 void
 flipfb(void)
 {
-	if(resized){		/* skip this frame if window resize */
+	if(vid.resized){		/* skip this frame if window resize */
+		vid.resized = false;
 		stopfb();
 		if(getwindow(display, Refnone) < 0)
 			sysfatal("%r");
-		resized = 0;
 		resetfb();
 		vid.recalc_refdef = true;	/* force a surface cache flush */
 		Con_CheckResize();
--- a/vid_sdl.c
+++ b/vid_sdl.c
@@ -1,8 +1,6 @@
 #include "quakedef.h"
 #include <SDL.h>
 
-int resized;
-
 pixel_t q1pal[256];
 
 static SDL_Renderer *rend;
@@ -21,10 +19,10 @@
 	 * but at least this prevents a crash, beyond that
 	 * it's your funeral */
 	SDL_GetWindowSize(win, &vid.width, &vid.height);
-	if(vid.width < 320)
-		vid.width = 320;
-	if(vid.height < 160)
-		vid.height = 160;
+	vid.width /= v_scale.value;
+	vid.height /= v_scale.value;
+	vid.width = clamp(vid.width, 320, MAXWIDTH);
+	vid.height = clamp(vid.height, 240, MAXHEIGHT);
 
 	vid.aspect = (float)vid.height / (float)vid.width * (320.0/240.0);
 	vid.conwidth = vid.width;
@@ -48,16 +46,14 @@
 	vid.buffer = vidbuffer;
 	vid.conbuffer = vid.buffer;
 
-	if(dvars.zbuffer != nil){
+	if(dvars.zbuffer != nil)
 		D_FlushCaches();
-		free(dvars.zbuffer);
-	}
 
 	// alloc an extra line in case we want to wrap, and allocate the z-buffer
 	hunkvbuf = vid.width * vid.height * sizeof(*dvars.zbuffer);
 	scachesz = D_SurfaceCacheForRes(vid.width, vid.height);
 	hunkvbuf += scachesz;
-	dvars.zbuffer = emalloc(hunkvbuf);
+	dvars.zbuffer = realloc(dvars.zbuffer, hunkvbuf);
 	surfcache = (byte *)(dvars.zbuffer + vid.width * vid.height);
 	D_InitCaches(surfcache, scachesz);
 }
@@ -70,8 +66,8 @@
 void
 flipfb(void)
 {
-	if(resized){		/* skip this frame if window resize */
-		resized = 0;
+	if(vid.resized){		/* skip this frame if window resize */
+		vid.resized = false;
 		resetfb();
 		vid.recalc_refdef = true;	/* force a surface cache flush */
 		Con_CheckResize();
--- a/view.c
+++ b/view.c
@@ -11,6 +11,8 @@
 
 cvar_t lcd_x = {"lcd_x","0"};
 
+cvar_t v_scale = {"v_scale", "1", true};
+
 static cvar_t lcd_yaw = {"lcd_yaw","0"};
 
 static cvar_t scr_ofsx = {"scr_ofsx","0", false};
@@ -927,6 +929,18 @@
 	strcpy(opath, path);
 }
 
+static void
+v_scale_cb(cvar_t *var)
+{
+	static float scale = 1.0;
+
+	var->value = clamp(var->value, 1, 16);
+	if(scale != var->value){
+		scale = var->value;
+		vid.resized = true;
+	}
+}
+
 /*
 =============
 V_Init
@@ -938,6 +952,9 @@
 	Cmd_AddCommand("bf", V_BonusFlash_f);
 	Cmd_AddCommand("centerview", V_StartPitchDrift);
 	Cmd_AddCommand("screenshot", screenshot);
+
+	Cvar_RegisterVariable(&v_scale);
+	v_scale.cb = v_scale_cb;
 
 	Cvar_RegisterVariable (&lcd_x);
 	Cvar_RegisterVariable (&lcd_yaw);
--- a/view.h
+++ b/view.h
@@ -4,6 +4,7 @@
 extern float v_blend[4];
 
 extern cvar_t lcd_x;
+extern cvar_t v_scale;
 
 void V_Init (void);
 void V_RenderView (void);