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);