[Source] Need help restoring low detail modes (r_detail)

Archive of the old editing forum
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. This forum is archived - please use this set of forums to ask new questions.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

[Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

This is for ZDoom LE (Legacy Edition, a fork of the ZDoom 2.8.1 maintenance branch for Windows 9x and old machines created at vogons (http://www.vogons.org) by blue-green-frog and continued (for now) by me.

Well, this is kind of embarrassing, I did some changes and everything went well but restoring the low detail modes wasn't as easy as i expected. The engine has seen a good amount of changes in 9 years. So now it compiles and links but crashes as soon as i start a new game with a divide by zero error. Actually i expected that. I've been trying to debug this with some breakpoints but crashes earlier, i really don't know where to start.
It's mostly done but I don't understand this code very well partly due to the lack of comments and i've been guessing here and there, i'm not familiar with global variables either.
There has been some remodularization (r_utility) and important changes to the status bar code. I think the use of realviewwidth/realviewheight and viewwidth/viewheight as well as detailxshift/detailyshift is a problem.
So i'm afraid i need help to fix this, a hand from one of the developers would be greatly appreciated but obviously i know i cannot count on it. Any experienced programmer with some knowledge of the ZDoom/Doom engine could be of help. I know some c++ but sadly i think i'm not up to the task.

I've uploaded the thing to GitHub and i'm attaching a diff patch with the latest changes to be applied with gnu32 patch, as i've mentioned i think this is mostly done and would be great if someone could have a look at this patch and give some hints of finish the job. I've added a preliminary quad horiz and double vert mode (i don't expect it to work) to allow the original low detail mode from higher resolutions and would be playable @320 for a somewhat cool retro look.
May be i could/should create a branch with the detail changes, i still don't know very well how git works. Thanks in advance.
https://github.com/drfrag666/ZDoom-LE

Code: Select all

diff -rupN zdoom-le/src/am_map.cpp zdoom-maint/src/am_map.cpp
--- zdoom-le/src/am_map.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/am_map.cpp	2017-02-26 12:25:33.148416900 +0100
@@ -3030,8 +3030,8 @@ void AM_Drawer ()
 	{
 		f_x = viewwindowx;
 		f_y = viewwindowy;
-		f_w = viewwidth;
-		f_h = viewheight;
+		f_w = realviewwidth;
+		f_h = realviewheight;
 		f_p = screen->GetPitch ();
 	}
 	AM_activateNewScale();
diff -rupN zdoom-le/src/asm_ia32/misc.asm zdoom-maint/src/asm_ia32/misc.asm
--- zdoom-le/src/asm_ia32/misc.asm	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/asm_ia32/misc.asm	2017-02-28 12:51:59.968971400 +0100
@@ -37,6 +37,9 @@ BITS 32
 
 %define DoBlending_MMX	_DoBlending_MMX
 %define BestColor_MMX	_BestColor_MMX
+%define DoubleHoriz_MMX _DoubleHoriz_MMX
+%define DoubleHorizVert_MMX _DoubleHorizVert_MMX
+%define DoubleVert_ASM	_DoubleVert_ASM
 
 %endif
 
@@ -198,3 +201,182 @@ BestColor_MMX:
 		pop		ebx
 		emms
 		ret
+
+;-----------------------------------------------------------
+;
+; DoubleHoriz_MMX
+;
+; Stretches an image horizontally using MMX instructions.
+; The source image is assumed to occupy the right half
+; of the destination image.
+;
+;	height of source
+;	width of source
+;	dest pointer (at end of row)
+;	pitch
+;
+;-----------------------------------------------------------
+
+GLOBAL	DoubleHoriz_MMX
+
+DoubleHoriz_MMX:
+	mov	edx,[esp+8]	; edx = width
+	push	edi
+
+	neg	edx		; make edx negative so we can count up
+	mov	edi,[esp+16]	; edi = dest pointer
+
+	sar	edx,2		; and make edx count groups of 4 pixels
+	push	ebp
+
+	mov	ebp,edx		; ebp = # of columns remaining in this row
+	push	ebx
+
+	mov	ebx,[esp+28]	; ebx = pitch
+	mov	ecx,[esp+16]	; ecx = # of rows remaining
+
+.loop	movq		mm0,[edi+ebp*4]
+
+.loop2	movq		mm1,mm0
+	punpcklbw	mm0,mm0			; double left 4 pixels
+
+	movq		mm2,[edi+ebp*4+8]
+	punpckhbw	mm1,mm1			; double right 4 pixels
+
+	movq		[edi+ebp*8],mm0		; write left pixels
+	movq		mm0,mm2
+
+	movq		[edi+ebp*8+8],mm1	; write right pixels
+
+	add		ebp,2			; increment counter
+	jnz		.loop2			; repeat until done with this row
+
+
+	add	edi,ebx		; move edi to next row
+	dec	ecx		; decrease row counter
+
+	mov	ebp,edx		; prep ebp for next row
+	jnz	.loop		; repeat until every row is done
+
+	emms
+	pop	ebx
+	pop	ebp
+	pop	edi
+	ret
+
+;-----------------------------------------------------------
+;
+; DoubleHorizVert_MMX
+;
+; Stretches an image horizontally and vertically using
+; MMX instructions. The source image is assumed to occupy
+; the right half of the destination image and to leave
+; every other line unused for expansion.
+;
+;	height of source
+;	width of source
+;	dest pointer (at end of row)
+;	pitch
+;
+;-----------------------------------------------------------
+
+GLOBAL	DoubleHorizVert_MMX
+
+DoubleHorizVert_MMX:
+	mov	edx,[esp+8]	; edx = width
+	push	edi
+
+	neg	edx		; make edx negative so we can count up
+	mov	edi,[esp+16]	; edi = dest pointer
+
+	sar	edx,2		; and make edx count groups of 4 pixels
+	push	ebp
+
+	mov	ebp,edx		; ebp = # of columns remaining in this row
+	push	ebx
+
+	mov	ebx,[esp+28]	; ebx = pitch
+	mov	ecx,[esp+16]	; ecx = # of rows remaining
+
+	push	esi
+	lea	esi,[edi+ebx]
+
+.loop	movq		mm0,[edi+ebp*4]		; get 8 pixels
+
+	movq		mm1,mm0
+	punpcklbw	mm0,mm0			; double left 4
+
+	punpckhbw	mm1,mm1			; double right 4
+	add		ebp,2			; increment counter
+
+	movq		[edi+ebp*8-16],mm0	; write them back out
+
+	movq		[edi+ebp*8-8],mm1
+
+	movq		[esi+ebp*8-16],mm0
+
+	movq		[esi+ebp*8-8],mm1
+
+	jnz		.loop			; repeat until done with this row
+
+	lea	edi,[edi+ebx*2]	; move edi and esi to next row
+	lea	esi,[esi+ebx*2]
+
+	dec	ecx		; decrease row counter
+	mov	ebp,edx		; prep ebp for next row
+
+	jnz	.loop		; repeat until every row is done
+
+	emms
+	pop	esi
+	pop	ebx
+	pop	ebp
+	pop	edi
+	ret
+
+;-----------------------------------------------------------
+;
+; DoubleVert_ASM
+;
+; Stretches an image vertically using regular x86
+; instructions. The source image should be interleaved.
+;
+;	height of source
+;	width of source
+;	source/dest pointer
+;	pitch
+;
+;-----------------------------------------------------------
+
+GLOBAL	DoubleVert_ASM
+
+DoubleVert_ASM:
+	mov	edx,[esp+16]	; edx = pitch
+	mov	eax,[esp+4]	; eax = # of rows left
+
+	push	esi
+	mov	esi,[esp+16]
+
+	push	edi
+	lea	edi,[esi+edx]
+
+	shl	edx,1		; edx = pitch*2
+	mov	ecx,[esp+16]
+
+	sub	edx,ecx		; edx = dist from end of one line to start of next
+	shr	ecx,2
+
+.loop	rep movsd
+	
+	mov	ecx,[esp+16]
+	add	esi,edx
+
+	add	edi,edx
+	shr	ecx,2
+
+	dec	eax
+	jnz	.loop
+
+	pop	edi
+	pop	esi
+	ret
diff -rupN zdoom-le/src/asm_ia32/tmap.asm zdoom-maint/src/asm_ia32/tmap.asm
--- zdoom-le/src/asm_ia32/tmap.asm	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/asm_ia32/tmap.asm	2017-02-26 12:25:34.910517700 +0100
@@ -51,7 +51,7 @@ FUZZTABLE	equ	50
 %define fuzzpos			_fuzzpos
 %define fuzzoffset		_fuzzoffset
 %define NormalLight		_NormalLight
-%define viewheight		_viewheight
+%define realviewheight		_realviewheight
 %define fuzzviewheight	_fuzzviewheight
 %define CPU				_CPU
 
@@ -103,7 +103,7 @@ EXTERN centery
 EXTERN fuzzpos
 EXTERN fuzzoffset
 EXTERN NormalLight
-EXTERN viewheight
+EXTERN realviewheight
 EXTERN fuzzviewheight
 EXTERN CPU
 
diff -rupN zdoom-le/src/ct_chat.cpp zdoom-maint/src/ct_chat.cpp
--- zdoom-le/src/ct_chat.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/ct_chat.cpp	2017-02-26 12:25:36.960634900 +0100
@@ -238,7 +238,7 @@ void CT_Drawer (void)
 		int screen_height = con_scaletext > 1? SCREENHEIGHT/2 : SCREENHEIGHT;
 		int st_y = con_scaletext > 1?  ST_Y/2 : ST_Y;
 
-		y += ((SCREENHEIGHT == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
+		y += ((SCREENHEIGHT == realviewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
 
 		promptwidth = SmallFont->StringWidth (prompt) * scalex;
 		x = SmallFont->GetCharWidth ('_') * scalex * 2 + promptwidth;
diff -rupN zdoom-le/src/d_main.cpp zdoom-maint/src/d_main.cpp
--- zdoom-le/src/d_main.cpp	2017-02-24 21:45:43.962225500 +0100
+++ zdoom-maint/src/d_main.cpp	2017-03-05 00:28:00.701817800 +0100
@@ -762,7 +762,7 @@ void D_Display ()
 				StatusBar->BlendView (blend);
 			}
 			screen->SetBlendingRect(viewwindowx, viewwindowy,
-				viewwindowx + viewwidth, viewwindowy + viewheight);
+				viewwindowx + realviewwidth, viewwindowy + realviewheight);
 
 			Renderer->RenderView(&players[consoleplayer]);
 
@@ -777,9 +777,9 @@ void D_Display ()
 			if (automapactive)
 			{
 				int saved_ST_Y = ST_Y;
-				if (hud_althud && viewheight == SCREENHEIGHT)
+				if (hud_althud && realviewheight == SCREENHEIGHT)
 				{
-					ST_Y = viewheight;
+					ST_Y = realviewheight;
 				}
 				AM_Drawer ();
 				ST_Y = saved_ST_Y;
@@ -789,7 +789,7 @@ void D_Display ()
 				V_RefreshViewBorder ();
 			}
 
-			if (hud_althud && viewheight == SCREENHEIGHT && screenblocks > 10)
+			if (hud_althud && realviewheight == SCREENHEIGHT && screenblocks > 10)
 			{
 				StatusBar->DrawBottomStuff (HUD_AltHud);
 				if (DrawFSHUD || automapactive) DrawHUD();
@@ -797,7 +797,7 @@ void D_Display ()
 				StatusBar->DrawTopStuff (HUD_AltHud);
 			}
 			else 
-			if (viewheight == SCREENHEIGHT && viewactive && screenblocks > 10)
+			if (realviewheight == SCREENHEIGHT && viewactive && screenblocks > 10)
 			{
 				EHudState state = DrawFSHUD ? HUD_Fullscreen : HUD_None;
 				StatusBar->DrawBottomStuff (state);
diff -rupN zdoom-le/src/doomstat.h zdoom-maint/src/doomstat.h
--- zdoom-le/src/doomstat.h	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/doomstat.h	2017-02-26 12:30:44.021197800 +0100
@@ -122,7 +122,10 @@ extern	int 			viewwindowy;
 extern	"C" int 		viewheight;
 extern	"C" int 		viewwidth;
 extern	"C"	int			halfviewwidth;		// [RH] Half view width, for plane drawing
-
+extern	"C" int			realviewwidth;		// [RH] Physical width of view window
+extern	"C" int			realviewheight;		// [RH] Physical height of view window
+extern	"C" int			detailxshift;		// [RH] X shift for horizontal detail level
+extern	"C" int			detailyshift;		// [RH] Y shift for vertical detail level
 
 
 
diff -rupN zdoom-le/src/g_shared/shared_sbar.cpp zdoom-maint/src/g_shared/shared_sbar.cpp
--- zdoom-le/src/g_shared/shared_sbar.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/g_shared/shared_sbar.cpp	2017-02-26 12:47:49.952877700 +0100
@@ -1185,8 +1185,8 @@ void DBaseStatusBar::DrawCrosshair ()
 	}
 
 	screen->DrawTexture (CrosshairImage,
-		viewwidth / 2 + viewwindowx,
-		viewheight / 2 + viewwindowy,
+		realviewwidth / 2 + viewwindowx,
+		realviewheight / 2 + viewwindowy,
 		DTA_DestWidth, w,
 		DTA_DestHeight, h,
 		DTA_AlphaChannel, true,
diff -rupN zdoom-le/src/menu/menu.cpp zdoom-maint/src/menu/menu.cpp
--- zdoom-le/src/menu/menu.cpp	2017-02-23 15:03:12.575603700 +0100
+++ zdoom-maint/src/menu/menu.cpp	2017-03-07 10:16:44.881858300 +0100
@@ -715,7 +715,11 @@ void M_Drawer (void) 
 
 	if (DMenu::CurrentMenu != NULL && menuactive != MENU_Off) 
 	{
-		if (DMenu::CurrentMenu->DimAllowed()) screen->Dim(fade);
+		if (DMenu::CurrentMenu->DimAllowed())
+		{
+			screen->Dim(fade);
+			V_SetBorderNeedRefresh();
+		}
 		DMenu::CurrentMenu->Drawer();
 	}
 }
diff -rupN zdoom-le/src/r_draw.cpp zdoom-maint/src/r_draw.cpp
--- zdoom-le/src/r_draw.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_draw.cpp	2017-03-08 11:12:00.240263800 +0100
@@ -52,7 +52,7 @@ extern	int		ST_Y;
 
 //
 // All drawing to the view buffer is accomplished in this file.
-// The other refresh files only know about ccordinates,
+// The other refresh files only know about coordinates,
 //	not the architecture of the frame buffer.
 // Conveniently, the frame buffer is a linear one,
 //	and we need only the base address,
@@ -67,6 +67,19 @@ BYTE			*dc_destorg;
 }
 int 			scaledviewwidth;
 
+extern "C" {
+int				realviewwidth;		// [RH] Physical width of view window
+int				realviewheight;		// [RH] Physical height of view window
+int				detailxshift;		// [RH] X shift for horizontal detail level
+int				detailyshift;		// [RH] Y shift for vertical detail level
+}
+
+#ifdef X86_ASM
+extern "C" void STACK_ARGS DoubleHoriz_MMX (int height, int width, BYTE *dest, int pitch);
+extern "C" void STACK_ARGS DoubleHorizVert_MMX (int height, int width, BYTE *dest, int pitch);
+extern "C" void STACK_ARGS DoubleVert_ASM (int height, int width, BYTE *dest, int pitch);
+#endif
+
 // [RH] Pointers to the different column drawers.
 //		These get changed depending on the current
 //		screen depth and asm/no asm.
@@ -117,6 +130,8 @@ const BYTE*		bufplce[4];
 int 			dccount;
 }
 
+cycle_t			DetailDoubleCycles;
+
 int dc_fillcolor;
 BYTE *dc_translation;
 BYTE shadetables[NUMCOLORMAPS*16*256];
@@ -2165,6 +2180,132 @@ const BYTE *R_GetColumn (FTexture *tex, 
 }
 
 
+// [RH] Double pixels in the view window horizontally
+//		and/or vertically (or not at all).
+void R_DetailDouble ()
+{
+	if (!viewactive) return;
+	DetailDoubleCycles.Reset();
+	DetailDoubleCycles.Clock();
+
+	switch ((detailxshift << 1) | detailyshift)
+	{
+	case 1:		// y-double
+#ifdef X86_ASM
+		DoubleVert_ASM (viewheight, viewwidth, dc_destorg, RenderTarget->GetPitch());
+#else
+		{
+			int rowsize = realviewwidth;
+			int pitch = RenderTarget->GetPitch();
+			int y;
+			BYTE *line;
+
+			line = dc_destorg;
+			for (y = viewheight; y != 0; --y, line += pitch<<1)
+			{
+				memcpy (line+pitch, line, rowsize);
+			}
+		}
+#endif
+		break;
+
+	case 2:		// x-double
+#ifdef X86_ASM
+		if (CPU.bMMX && (viewwidth&15)==0)
+		{
+			DoubleHoriz_MMX (viewheight, viewwidth, dc_destorg+viewwidth, RenderTarget->GetPitch());
+		}
+		else
+#endif
+		{
+			int rowsize = viewwidth;
+			int pitch = RenderTarget->GetPitch();
+			int y,x;
+			BYTE *linefrom, *lineto;
+
+			linefrom = dc_destorg;
+			for (y = viewheight; y != 0; --y, linefrom += pitch)
+			{
+				lineto = linefrom - viewwidth;
+				for (x = 0; x < rowsize; ++x)
+				{
+					BYTE c = linefrom[x];
+					lineto[x*2] = c;
+					lineto[x*2+1] = c;
+				}
+			}
+		}
+		break;
+
+	case 3:		// x- and y-double
+#ifdef X86_ASM
+		if (CPU.bMMX && (viewwidth&15)==0 && 0)
+		{
+			DoubleHorizVert_MMX (viewheight, viewwidth, dc_destorg+viewwidth, RenderTarget->GetPitch());
+		}
+		else
+#endif
+		{
+			int rowsize = viewwidth;
+			int realpitch = RenderTarget->GetPitch();
+			int pitch = realpitch << 1;
+			int y,x;
+			BYTE *linefrom, *lineto;
+
+			linefrom = dc_destorg;
+			for (y = viewheight; y != 0; --y, linefrom += pitch)
+			{
+				lineto = linefrom - viewwidth;
+				for (x = 0; x < rowsize; ++x)
+				{
+					BYTE c = linefrom[x];
+					lineto[x*2] = c;
+					lineto[x*2+1] = c;
+					lineto[x*2+realpitch] = c;
+					lineto[x*2+realpitch+1] = c;
+				}
+			}
+		}
+		break;
+
+	case 5:		// x-quad and y-double placeholder
+		{
+			int rowsize = viewwidth;
+			int realpitch = RenderTarget->GetPitch();
+			int pitch = realpitch << 1;
+			int y,x;
+			BYTE *linefrom, *lineto;
+
+			linefrom = dc_destorg;
+			for (y = viewheight; y != 0; --y, linefrom += pitch)
+			{
+				lineto = linefrom - viewwidth;
+				for (x = 0; x < rowsize; ++x)
+				{
+					BYTE c = linefrom[x];
+					lineto[x*4] = c;
+					lineto[x*4+1] = c;
+					lineto[x*4+2] = c;
+					lineto[x*4+3] = c;
+					lineto[x*4+realpitch] = c;
+					lineto[x*4+realpitch+1] = c;
+					lineto[x*4+realpitch+2] = c;
+					lineto[x*4+realpitch+3] = c;
+				}
+			}
+		}
+		break;
+	}	
+	DetailDoubleCycles.Unclock();
+}
+
+ADD_STAT(detail)
+{
+	FString out;
+	out.Format ("doubling = %04.1f ms", DetailDoubleCycles.TimeMS());
+	return out;
+}
+
 // [RH] Initialize the column drawer pointers
 void R_InitColumnDrawers ()
 {
diff -rupN zdoom-le/src/r_draw.h zdoom-maint/src/r_draw.h
--- zdoom-le/src/r_draw.h	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_draw.h	2017-02-26 20:13:57.297240700 +0100
@@ -257,6 +257,9 @@ extern FDynamicColormap ShadeFakeColorma
 extern BYTE identitymap[256];
 extern BYTE *dc_translation;
 
+// [RH] Double view pixels by detail mode
+void R_DetailDouble (void);
+
 // [RH] Added for muliresolution support
 void R_InitShadeMaps();
 void R_InitFuzzTable (int fuzzoff);
diff -rupN zdoom-le/src/r_main.cpp zdoom-maint/src/r_main.cpp
--- zdoom-le/src/r_main.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_main.cpp	2017-03-08 10:09:06.784608100 +0100
@@ -146,6 +146,8 @@ angle_t 		xtoviewangle[MAXWIDTH+1];
 bool			foggy;			// [RH] ignore extralight and fullbright?
 int				r_actualextralight;
 
+extern int setdetail; // Defined in r_utility.cpp
+
 void (*colfunc) (void);
 void (*basecolfunc) (void);
 void (*fuzzcolfunc) (void);
@@ -275,8 +277,8 @@ void R_SetVisibility (float vis)
 	else
 		r_WallVisibility = r_BaseVisibility;
 
-	r_WallVisibility = FixedMul (Scale (InvZtoScale, SCREENWIDTH*BaseRatioSizes[WidescreenRatio][1],
-		viewwidth*SCREENHEIGHT*3), FixedMul (r_WallVisibility, FocalTangent));
+	r_WallVisibility = FixedMul (Scale (InvZtoScale, SCREENWIDTH*(BaseRatioSizes[WidescreenRatio][1]<<detailyshift),
+		(viewwidth<<detailxshift)*SCREENHEIGHT*3), FixedMul (r_WallVisibility, FocalTangent));
 
 	// Prevent overflow on floors/ceilings. Note that the calculation of
 	// MaxVisForFloor means that planes less than two units from the player's
@@ -334,6 +336,38 @@ CCMD (r_visibility)
 
 //==========================================================================
 //
+// CVAR r_detail
+//
+// Selects a pixel doubling mode
+//
+//==========================================================================
+
+CUSTOM_CVAR (Int, r_detail, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
+{
+	static bool badrecovery = false;
+
+	if (badrecovery)
+	{
+		badrecovery = false;
+		return;
+	}
+
+	if (self < 0 || self > 5 || self == 4)
+	{
+		Printf ("Bad detail mode. (Use 0-3)\n");
+		badrecovery = true;
+		self = (detailyshift << 1) | detailxshift;
+		return;
+	}
+
+	setdetail = self;
+	setsizeneeded = true;
+}
+
+void R_SetDetail (int detail);
+
+//==========================================================================
+//
 // R_SetWindow
 //
 //==========================================================================
@@ -342,6 +376,12 @@ void R_SWRSetWindow(int windowSize, int 
 {
 	int virtheight, virtwidth, virtwidth2, virtheight2;
 
+	viewwidth = realviewwidth >> detailxshift;
+	viewheight = realviewheight >> detailyshift;
+	fuzzviewheight = viewheight - 2;	// Maximum row the fuzzer can draw to
+	freelookviewheight >>= detailyshift;
+	halfviewwidth = (viewwidth >> 1) - 1;
+
 	if (!bRenderingToCanvas)
 	{ // Set r_viewsize cvar to reflect the current view size
 		UCVarValue value;
@@ -352,15 +392,14 @@ void R_SWRSetWindow(int windowSize, int 
 		r_viewsize.ForceSet (value, CVAR_String);
 	}
 
-	fuzzviewheight = viewheight - 2;	// Maximum row the fuzzer can draw to
-	halfviewwidth = (viewwidth >> 1) - 1;
-
 	lastcenteryfrac = 1<<30;
+	centery = viewheight/2;
+	centerx = viewwidth/2;
 	centerxfrac = centerx<<FRACBITS;
 	centeryfrac = centery<<FRACBITS;
 
-	virtwidth = virtwidth2 = fullWidth;
-	virtheight = virtheight2 = fullHeight;
+	virtwidth = virtwidth2 = fullWidth >> detailxshift;
+	virtheight = virtheight2 = fullHeight >> detailyshift;
 
 	if (Is54Aspect(trueratio))
 	{
@@ -397,8 +436,8 @@ void R_SWRSetWindow(int windowSize, int 
 
 	R_InitTextureMapping ();
 
-	MaxVisForWall = FixedMul (Scale (InvZtoScale, SCREENWIDTH*r_Yaspect,
-		viewwidth*SCREENHEIGHT), FocalTangent);
+	MaxVisForWall = FixedMul (Scale (InvZtoScale, SCREENWIDTH*(r_Yaspect<<detailyshift),
+		(viewwidth<<detailxshift)*SCREENHEIGHT), FocalTangent);
 	MaxVisForWall = FixedDiv (0x7fff0000, MaxVisForWall);
 	MaxVisForFloor = Scale (FixedDiv (0x7fff0000, viewheight<<(FRACBITS-2)), FocalLengthY, 160*FRACUNIT);
 
@@ -422,6 +461,7 @@ CUSTOM_CVAR (Int, r_columnmethod, 1, CVA
 	}
 	else
 	{ // Trigger the change
+		r_detail.Callback ();
 		setsizeneeded = true;
 	}
 }
@@ -706,13 +746,22 @@ void R_EnterMirror (drawseg_t *ds, int d
 //
 //==========================================================================
 
-void R_SetupBuffer ()
+void R_SetupBuffer (bool inview)
 {
 	static BYTE *lastbuff = NULL;
 
 	int pitch = RenderTarget->GetPitch();
 	BYTE *lineptr = RenderTarget->GetBuffer() + viewwindowy*pitch + viewwindowx;
 
+	if (inview)
+	{
+		pitch <<= detailyshift;
+	}
+	if (detailxshift)
+	{
+		lineptr += viewwidth;
+	}
+	
 	if (dc_pitch != pitch || lineptr != lastbuff)
 	{
 		if (dc_pitch != pitch)
@@ -747,7 +796,7 @@ void R_RenderActorView (AActor *actor, b
 	fakeActive = 0; // kg3D - reset fake floor indicator
 	R_3D_ResetClip(); // reset clips (floor/ceiling)
 
-	R_SetupBuffer ();
+	R_SetupBuffer (true);
 	R_SetupFrame (actor);
 
 	// Clear buffers.
@@ -829,7 +878,15 @@ void R_RenderActorView (AActor *actor, b
 	}
 	WallMirrors.Clear ();
 	interpolator.RestoreInterpolations ();
-	R_SetupBuffer ();
+
+	// If there is vertical doubling, and the view window is not an even height,
+	// draw a black line at the bottom of the view window.
+	if (detailyshift && viewwindowy == 0 && (realviewheight & 1))
+	{
+		screen->Clear (0, realviewheight-1, realviewwidth, realviewheight, 0, 0);
+	}
+
+	R_SetupBuffer (false);
 
 	// If we don't want shadered colormaps, NULL it now so that the
 	// copy to the screen does not use a special colormap shader.
@@ -850,12 +907,15 @@ void R_RenderActorView (AActor *actor, b
 void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas,
 	int x, int y, int width, int height, bool dontmaplines)
 {
+	const int saveddetail = detailxshift | (detailyshift << 1);
 	const bool savedviewactive = viewactive;
 
-	viewwidth = width;
+	detailxshift = detailyshift = 0;
+	realviewwidth = viewwidth = width;
 	RenderTarget = canvas;
 	bRenderingToCanvas = true;
 
+	R_SetDetail (0);
 	R_SetWindow (12, width, height, height);
 	viewwindowx = x;
 	viewwindowy = y;
@@ -865,9 +925,10 @@ void R_RenderViewToCanvas (AActor *actor
 
 	RenderTarget = screen;
 	bRenderingToCanvas = false;
+	R_SetDetail (saveddetail);
 	R_ExecuteSetViewSize ();
 	screen->Lock (true);
-	R_SetupBuffer ();
+	R_SetupBuffer (false);
 	screen->Unlock ();
 	viewactive = savedviewactive;
 }
diff -rupN zdoom-le/src/r_main.h zdoom-maint/src/r_main.h
--- zdoom-le/src/r_main.h	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_main.h	2017-02-27 00:51:36.702162700 +0100
@@ -129,7 +129,7 @@ void R_InitTextureMapping ();
 
 // Called by G_Drawer.
 void R_RenderActorView (AActor *actor, bool dontmaplines = false);
-void R_SetupBuffer ();
+void R_SetupBuffer (bool inview);
 
 void R_RenderViewToCanvas (AActor *actor, DCanvas *canvas, int x, int y, int width, int height, bool dontmaplines = false);
 
diff -rupN zdoom-le/src/r_plane.cpp zdoom-maint/src/r_plane.cpp
--- zdoom-le/src/r_plane.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_plane.cpp	2017-02-27 00:57:05.190951200 +0100
@@ -536,7 +536,7 @@ void R_ClearPlanes (bool fullclear)
 		// [RH] clip ceiling to console bottom
 		clearbufshort (ceilingclip, viewwidth,
 			!screen->Accel2D && ConBottom > viewwindowy && !bRenderingToCanvas
-			? (ConBottom - viewwindowy) : 0);
+			? ((ConBottom - viewwindowy) >> detailyshift) : 0);
 
 		lastopening = 0;
 	}
diff -rupN zdoom-le/src/r_sky.cpp zdoom-maint/src/r_sky.cpp
--- zdoom-le/src/r_sky.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_sky.cpp	2017-02-27 11:33:40.865297200 +0100
@@ -54,6 +54,7 @@ CUSTOM_CVAR (Bool, r_stretchsky, true, C
 	R_InitSkyMap ();
 }
 
+extern "C" int detailxshift, detailyshift;
 fixed_t			freelookviewheight;
 
 //==========================================================================
@@ -112,8 +113,8 @@ void R_InitSkyMap ()
 
 	if (viewwidth != 0 && viewheight != 0)
 	{
-		skyiscale = (r_Yaspect*FRACUNIT) / ((freelookviewheight * viewwidth) / viewwidth);
-		skyscale = (((freelookviewheight * viewwidth) / viewwidth) << FRACBITS) /
+		skyiscale = (r_Yaspect*FRACUNIT) / (((freelookviewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift));
+		skyscale = ((((freelookviewheight<<detailxshift) * viewwidth) / (viewwidth<<detailxshift)) << FRACBITS) /
 					(r_Yaspect);
 
 		skyiscale = Scale (skyiscale, FieldOfView, 2048);
diff -rupN zdoom-le/src/r_state.h zdoom-maint/src/r_state.h
--- zdoom-le/src/r_state.h	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_state.h	2017-02-27 11:35:14.220636800 +0100
@@ -34,7 +34,9 @@
 //
 
 extern "C" int			viewwidth;
+extern "C" int			realviewwidth;
 extern "C" int			viewheight;
+extern "C" int			realviewheight;
 
 //
 // Lookup tables for map data.
diff -rupN zdoom-le/src/r_swrenderer.cpp zdoom-maint/src/r_swrenderer.cpp
--- zdoom-le/src/r_swrenderer.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_swrenderer.cpp	2017-03-04 19:02:27.687892100 +0100
@@ -109,6 +109,7 @@ void FSoftwareRenderer::PrecacheTexture(
 void FSoftwareRenderer::RenderView(player_t *player)
 {
 	R_RenderActorView (player->mo);
+	R_DetailDouble ();		// [RH] Apply detail mode expansion
 	// [RH] Let cameras draw onto textures that were visible this frame.
 	FCanvasTextureInfo::UpdateAll ();
 }
@@ -188,7 +189,7 @@ void FSoftwareRenderer::OnModeSet ()
 
 	RenderTarget = screen;
 	screen->Lock (true);
-	R_SetupBuffer ();
+	R_SetupBuffer (false);
 	screen->Unlock ();
 }
 
diff -rupN zdoom-le/src/r_things.cpp zdoom-maint/src/r_things.cpp
--- zdoom-le/src/r_things.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_things.cpp	2017-03-06 18:31:25.842789900 +0100
@@ -124,6 +124,7 @@ short			screenheightarray[MAXWIDTH];
 
 EXTERN_CVAR (Bool, r_drawplayersprites)
 EXTERN_CVAR (Bool, r_drawvoxels)
+EXTERN_CVAR (Int, r_detail)
 
 //
 // INITIALIZATION FUNCTIONS
@@ -1224,15 +1225,21 @@ void R_DrawPSprite (pspdef_t* psp, int p
 	// calculate edges of the shape
 	tx = sx-((320/2)<<FRACBITS);
 
-	tx -= tex->GetScaledLeftOffset() << FRACBITS;
-	x1 = (centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS;
+	tx -= tex->GetScaledLeftOffset() << FRACBITS;	
+	if (r_detail == 0 || r_detail == 2)
+		x1 = (centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS;
+	else
+		x1 = (centerxfrac + FixedMul (tx, pspritexscale/2)) >>FRACBITS;
 
 	// off the right side
 	if (x1 > viewwidth)
 		return; 
 
 	tx += tex->GetScaledWidth() << FRACBITS;
-	x2 = ((centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS);
+	if (r_detail == 0 || r_detail == 2)
+		x2 = (centerxfrac + FixedMul (tx, pspritexscale)) >>FRACBITS;
+	else
+		x2 = (centerxfrac + FixedMul (tx, pspritexscale/2)) >>FRACBITS;
 
 	// off the left side
 	if (x2 <= 0)
@@ -1246,7 +1253,7 @@ void R_DrawPSprite (pspdef_t* psp, int p
 	vis->texturemid = MulScale16((BASEYCENTER<<FRACBITS) - sy, tex->yScale) + (tex->TopOffset << FRACBITS);
 
 	if (camera->player && (RenderTarget != screen ||
-		viewheight == RenderTarget->GetHeight() ||
+		realviewheight == RenderTarget->GetHeight() ||
 		(RenderTarget->GetWidth() > 320 && !st_scale)))
 	{	// Adjust PSprite for fullscreen views
 		AWeapon *weapon = NULL;
@@ -1256,7 +1263,7 @@ void R_DrawPSprite (pspdef_t* psp, int p
 		}
 		if (pspnum <= ps_flash && weapon != NULL && weapon->YAdjust != 0)
 		{
-			if (RenderTarget != screen || viewheight == RenderTarget->GetHeight())
+			if (RenderTarget != screen || realviewheight == RenderTarget->GetHeight())
 			{
 				vis->texturemid -= weapon->YAdjust;
 			}
@@ -1274,19 +1281,28 @@ void R_DrawPSprite (pspdef_t* psp, int p
 	vis->x1 = x1 < 0 ? 0 : x1;
 	vis->x2 = x2 >= viewwidth ? viewwidth : x2;
 	vis->xscale = DivScale16(pspritexscale, tex->xScale);
-	vis->yscale = DivScale16(pspriteyscale, tex->yScale);
+	if (r_detail == 0 || r_detail == 2)
+		vis->yscale = DivScale16(pspriteyscale, tex->yScale);
+	else
+		vis->yscale = DivScale16(pspriteyscale/2, tex->yScale);
 	vis->Translation = 0;		// [RH] Use default colors
 	vis->pic = tex;
 	vis->ColormapNum = 0;
 
 	if (flip)
 	{
-		vis->xiscale = -MulScale16(pspritexiscale, tex->xScale);
+		if (r_detail == 0 || r_detail == 2)
+			vis->xiscale = -MulScale16(pspritexiscale, tex->xScale);
+		else
+			vis->xiscale = -MulScale16(pspritexiscale*2, tex->xScale);
 		vis->startfrac = (tex->GetWidth() << FRACBITS) - 1;
 	}
 	else
 	{
-		vis->xiscale = MulScale16(pspritexiscale, tex->xScale);
+		if (r_detail == 0 || r_detail == 2)
+			vis->xiscale = MulScale16(pspritexiscale, tex->xScale);
+		else
+			vis->xiscale = MulScale16(pspritexiscale*2, tex->xScale);
 		vis->startfrac = 0;
 	}
 
@@ -2514,7 +2530,7 @@ void R_DrawParticle (vissprite_t *vis)
 		fg = fg2rgb[color];
 	}
 
-	spacing = RenderTarget->GetPitch() - countbase;
+	spacing = (RenderTarget->GetPitch()<<detailyshift) - countbase;
 	dest = ylookup[yl] + x1 + dc_destorg;
 
 	do
diff -rupN zdoom-le/src/r_utility.cpp zdoom-maint/src/r_utility.cpp
--- zdoom-le/src/r_utility.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_utility.cpp	2017-03-07 18:47:05.783755200 +0100
@@ -132,7 +132,7 @@ bool			LocalKeyboardTurner;
 
 float			LastFOV;
 int				WidescreenRatio;
-int				setblocks;
+int				setblocks, setdetail = -1;
 int				extralight;
 bool			setsizeneeded;
 fixed_t			FocalTangent;
@@ -395,6 +395,24 @@ void R_SetViewSize (int blocks)
 
 //==========================================================================
 //
+// R_SetDetail
+//
+//==========================================================================
+
+void R_SetDetail (int detail)
+{
+	if (detail != 5) {
+		detailxshift = detail & 1;
+		detailyshift = (detail >> 1) & 1;
+	}
+	else {
+		detailxshift = 2;
+		detailyshift = 1;
+	}
+}
+
+//==========================================================================
+//
 // R_SetWindow
 //
 //==========================================================================
@@ -405,19 +423,19 @@ void R_SetWindow (int windowSize, int fu
 
 	if (windowSize >= 11)
 	{
-		viewwidth = fullWidth;
-		freelookviewheight = viewheight = fullHeight;
+		realviewwidth = fullWidth;
+		freelookviewheight = realviewheight = fullHeight;
 	}
 	else if (windowSize == 10)
 	{
-		viewwidth = fullWidth;
-		viewheight = stHeight;
+		realviewwidth = fullWidth;
+		realviewheight = stHeight;
 		freelookviewheight = fullHeight;
 	}
 	else
 	{
-		viewwidth = ((setblocks*fullWidth)/10) & (~15);
-		viewheight = ((setblocks*stHeight)/10)&~7;
+		realviewwidth = ((setblocks*fullWidth)/10) & (~15);
+		realviewheight = ((setblocks*stHeight)/10)&~7;
 		freelookviewheight = ((setblocks*fullHeight)/10)&~7;
 	}
 
@@ -429,8 +447,8 @@ void R_SetWindow (int windowSize, int fu
 	// [RH] Sky height fix for screens not 200 (or 240) pixels tall
 	R_InitSkyMap ();
 
-	centery = viewheight/2;
-	centerx = viewwidth/2;
+	centery = realviewheight/2;
+	centerx = realviewwidth/2;
 	if (Is54Aspect(WidescreenRatio))
 	{
 		centerxwide = centerx;
@@ -467,13 +485,19 @@ void R_ExecuteSetViewSize ()
 	setsizeneeded = false;
 	V_SetBorderNeedRefresh();
 
+	if (setdetail >= 0)
+	{
+		R_SetDetail (setdetail);
+		setdetail = -1;
+	}
+
 	R_SetWindow (setblocks, SCREENWIDTH, SCREENHEIGHT, ST_Y);
 
 	// Handle resize, e.g. smaller view windows with border and/or status bar.
-	viewwindowx = (screen->GetWidth() - viewwidth) >> 1;
+	viewwindowx = (screen->GetWidth() - (viewwidth<<detailxshift)) >> 1;
 
 	// Same with base row offset.
-	viewwindowy = (viewwidth == screen->GetWidth()) ? 0 : (ST_Y - viewheight) >> 1;
+	viewwindowy = ((viewwidth<<detailxshift) == screen->GetWidth()) ? 0 : (ST_Y - (viewheight<<detailyshift)) >> 1;
 }
 
 //==========================================================================
diff -rupN zdoom-le/src/r_utility.h zdoom-maint/src/r_utility.h
--- zdoom-le/src/r_utility.h	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/r_utility.h	2017-02-27 00:50:51.467575500 +0100
@@ -19,6 +19,10 @@ extern int				viewpitch;
 extern "C" int			centerx, centerxwide;
 extern "C" int			centery;
 
+// [RH] New detail modes
+extern "C" int			detailxshift;
+extern "C" int			detailyshift;
+
 extern int				setblocks;
 
 extern fixed_t			viewtancos;
diff -rupN zdoom-le/src/s_sound.cpp zdoom-maint/src/s_sound.cpp
--- zdoom-le/src/s_sound.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/s_sound.cpp	2017-03-07 10:12:23.391399100 +0100
@@ -740,8 +740,8 @@ static void CalcPosVel(int type, const A
 		if (type == SOURCE_Actor && actor != NULL)
 		{
 			vel->X = FIXED2FLOAT(actor->velx) * TICRATE;
-			vel->Y = FIXED2FLOAT(actor->velz) * TICRATE;
-			vel->Z = FIXED2FLOAT(actor->vely) * TICRATE;
+			vel->Y = FIXED2FLOAT(actor->vely) * TICRATE;
+			vel->Z = FIXED2FLOAT(actor->velz) * TICRATE;
 		}
 		else
 		{
diff -rupN zdoom-le/src/v_draw.cpp zdoom-maint/src/v_draw.cpp
--- zdoom-le/src/v_draw.cpp	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/src/v_draw.cpp	2017-02-26 12:45:50.287033200 +0100
@@ -1499,17 +1499,17 @@ static void V_DrawViewBorder (void)
 		ST_SetNeedRefresh();
 	}
 
-	if (viewwidth == SCREENWIDTH)
+	if (realviewwidth == SCREENWIDTH)
 	{
 		return;
 	}
 
 	V_DrawBorder (0, 0, SCREENWIDTH, viewwindowy);
-	V_DrawBorder (0, viewwindowy, viewwindowx, viewheight + viewwindowy);
-	V_DrawBorder (viewwindowx + viewwidth, viewwindowy, SCREENWIDTH, viewheight + viewwindowy);
-	V_DrawBorder (0, viewwindowy + viewheight, SCREENWIDTH, ST_Y);
+	V_DrawBorder (0, viewwindowy, viewwindowx, realviewheight + viewwindowy);
+	V_DrawBorder (viewwindowx + realviewwidth, viewwindowy, SCREENWIDTH, realviewheight + viewwindowy);
+	V_DrawBorder (0, viewwindowy + realviewheight, SCREENWIDTH, ST_Y);
 
-	V_DrawFrame (viewwindowx, viewwindowy, viewwidth, viewheight);
+	V_DrawFrame (viewwindowx, viewwindowy, realviewwidth, realviewheight);
 	V_MarkRect (0, 0, SCREENWIDTH, ST_Y);
 }
 
@@ -1526,7 +1526,7 @@ static void V_DrawTopBorder ()
 	FTexture *p;
 	int offset;
 
-	if (viewwidth == SCREENWIDTH)
+	if (realviewwidth == SCREENWIDTH)
 		return;
 
 	offset = gameinfo.Border.offset;
@@ -1534,24 +1534,24 @@ static void V_DrawTopBorder ()
 	if (viewwindowy < 34)
 	{
 		V_DrawBorder (0, 0, viewwindowx, 34);
-		V_DrawBorder (viewwindowx, 0, viewwindowx + viewwidth, viewwindowy);
-		V_DrawBorder (viewwindowx + viewwidth, 0, SCREENWIDTH, 34);
+		V_DrawBorder (viewwindowx, 0, viewwindowx + realviewwidth, viewwindowy);
+		V_DrawBorder (viewwindowx + realviewwidth, 0, SCREENWIDTH, 34);
 		p = TexMan(gameinfo.Border.t);
 		screen->FlatFill(viewwindowx, viewwindowy - p->GetHeight(),
-						 viewwindowx + viewwidth, viewwindowy, p, true);
+						 viewwindowx + realviewwidth, viewwindowy, p, true);
 
 		p = TexMan(gameinfo.Border.l);
 		screen->FlatFill(viewwindowx - p->GetWidth(), viewwindowy,
 						 viewwindowx, 35, p, true);
 		p = TexMan(gameinfo.Border.r);
-		screen->FlatFill(viewwindowx + viewwidth, viewwindowy,
-						 viewwindowx + viewwidth + p->GetWidth(), 35, p, true);
+		screen->FlatFill(viewwindowx + realviewwidth, viewwindowy,
+						 viewwindowx + realviewwidth + p->GetWidth(), 35, p, true);
 
 		p = TexMan(gameinfo.Border.tl);
 		screen->DrawTexture (p, viewwindowx - offset, viewwindowy - offset, TAG_DONE);
 
 		p = TexMan(gameinfo.Border.tr);
-		screen->DrawTexture (p, viewwindowx + viewwidth, viewwindowy - offset, TAG_DONE);
+		screen->DrawTexture (p, viewwindowx + realviewwidth, viewwindowy - offset, TAG_DONE);
 	}
 	else
 	{
diff -rupN zdoom-le/wadsrc/static/menudef.txt zdoom-maint/wadsrc/static/menudef.txt
--- zdoom-le/wadsrc/static/menudef.txt	2016-04-18 10:59:02.000000000 +0200
+++ zdoom-maint/wadsrc/static/menudef.txt	2017-03-06 21:29:42.384634700 +0100
@@ -594,6 +594,15 @@ OptionMenu "JoystickConfigMenu"
 //
 //-------------------------------------------------------------------------------------------
 
+OptionValue DetailModes 
+{
+	0.0, "High"
+	1.0, "Double Horizontally"
+	2.0, "Double Vertically"
+	3.0, "Double Horiz and Vert"
+	5.0, "Quad Horiz and Double Vert"
+}
+
 OptionValue ColumnMethods 
 {
 	0.0, "Original"
@@ -661,7 +670,8 @@ OptionMenu "VideoOptions"
 	Option "Vertical Sync",				"vid_vsync", "OnOff"
 	Option "Rendering Interpolation",	"cl_capfps", "OffOn"
 	Option "Column render mode",		"r_columnmethod", "ColumnMethods"
-
+    Option "Detail mode",				"r_detail",		  "DetailModes"
+	
 	StaticText " "
 	Option "Screen wipe style",			"wipetype", "Wipes"
 

Last edited by drfrag on Wed Mar 08, 2017 3:14 pm, edited 6 times in total.
dpJudas
 
 
Posts: 3109
Joined: Sat May 28, 2016 1:01 pm

Re: [Source] Need help restoring low detail modes (r_detail)

Post by dpJudas »

Sorry, I don't really know anything about r_detail. I don't think I have ever seen any realviewwidth or realviewheight variables in the part of the codebase I've touched either.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

Thanks anyway, i was trying ro revert the commit from 8 years ago at https://github.com/rheit/zdoom/commit/d ... 18aca44aa3.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

I've managed to get the engine running, i did a backtrace with gdb and it crashed with an aritmetic exception in r_plane.cpp. I tracked it down to changing view for realview in 'centery = realviewheight/2 'and 'centerx = realviewwidth/2' in r_utility.cpp. I've updated the patch accordingly. By the way apparently breakpoints still don't work if your path contains special characters.
Now everything seems to work well in normal detail mode. Unfortunately doubling horizontally now results in a zoomed view with the weapon centered in the rightmost side of the screen. Clearly the view is double the size it should be, i know for sure the problem is not in R_DetailDouble (). Doubling vertically works well so may be i've used somewhere realviewwidth instead of viewwidth. I guess for one of the devs finding the problem would take a few minutes but i've been looking at this for hours now and still don't see it. Any suggestions?

Edit: the quad mode doesn't do anything, i wonder how i could give detailxshift the right value in R_SetDetail.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

Well, it's working now! After debugging with gdb (and that was a pain) viewwidth was right but centerx and centery were not, i think they were moved and reused when the sky fix was introduced. But there's a problem left, when doubling horizontally the weapon is big and partly sunk below the bottom of the screen. I don't know why, i've tried several changes in r_things.cpp without success. I've updated the patch again.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

@Graf Zahl : I really don't want to bother you but i'm afraid i'm in need of your expertise here. As i've mentioned in doubled horizontally modes the weapon has now double the size, i guess that's becouse it's not part of the 3d world view anymore and now is drawn as a texture. I think the weapon is rendered twice now and the second time is bigger due to the view width being smaller. Or am i completely wrong here? I can't think of a possible fix for this. Besides that and quad mode the patch works well. Thanks in advance.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49143
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [Source] Need help restoring low detail modes (r_detail)

Post by Graf Zahl »

Sorry, I cannot help you here. I always said that the software renderer's innards are off limits for me - and this is really old to begin with.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

That's unfortunate. If i'm not wrong i only need to know how to render a scaled down weapon (half size) for those modes in r_things.cpp. May be dpJudas could help.
dpJudas
 
 
Posts: 3109
Joined: Sat May 28, 2016 1:01 pm

Re: [Source] Need help restoring low detail modes (r_detail)

Post by dpJudas »

I'm afraid the developer you're looking for is Randi. I refactored the software renderer because I could not make heads and tails of which functions did what and how it transferred data between them. One example of why I did this was because that one file, r_things.cpp, could be expanded to no less than 8 different classes and 16 files.

All I can really help you with is that R_DrawPSprite is responsible for drawing the weapon. The code there decides if it can use hardware acceleration or not (vid_hw2d, don't know if that's available on windows 98) and then either postpones the drawing to R_DrawRemainingPlayerSprites if it can be drawn by a shader, or calls R_DrawPlayerSprites if it cannot.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

Yes but unfortunately she's not longer around. Thanks, i was already looking into R_DrawPSprite. Anyway it's fixed now after toying with x1, x2, vis->yscale and vis->xiscale (xscale is always ignored) thru trial and error. :) Next thing is trying to finish quad mode.

As a side note this works on win95 but it's much slower on pentiums than 2.2 and i wonder why, you get pretty much half the performance. With rendering interpolation enabled it's extremely slow on such machines and there was a race condition when setting the default video mode, should be fixed now. May be low detail modes will help since openal is much faster than fmodex and even faster than fmod.
On a pentium 2 it's slower than 2.2 on high resolutions but you get the same performance at low resolutions.
I think the floating point rewrite didn't make it into the maint branch, may be some micro-optimization was removed or it's just some overhead from the new features i don't know. I still need to try compiling with i586 optimizations.
Edit: i was wrong and the weapon is actually affected by pixel doubling.
Last edited by drfrag on Tue Mar 07, 2017 4:14 am, edited 1 time in total.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49143
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [Source] Need help restoring low detail modes (r_detail)

Post by Graf Zahl »

drfrag wrote:Yes but unfortunately she's not longer around. Thanks, i was already looking into R_DrawPSprite. Anyway it's fixed now after toying with x1, x2, vis->yscale and vis->xiscale (xscale is always ignored) thru trial and error. :) As expected the weapon now it's not affected by detail modes. Next thing is trying to finish quad mode.

As a side note this works on win95 but it's much slower on pentiums than 2.2 and i wonder why
What compiler are you using? And are you actually using the assembly drawers? The heavy speed loss you see may well be caused by using C drawers.

Aside from that, why are you working with the 2.8.1 maint branch and not something more recent? 2.8.1 was working with Win98 after all, so this offers relatively little value for potential users. Wouldn't something roughly corresponding to GZDoom 2.2 be more useful?
User avatar
Rachael
Posts: 13736
Joined: Tue Jan 13, 2004 1:31 pm
Preferred Pronouns: She/Her

Re: [Source] Need help restoring low detail modes (r_detail)

Post by Rachael »

Unfortunately 2.2 (GZDoom) has the broken software renderer, as that was released after the floating point rewrites and before or just barely after dpJudas started tweaking things.

I don't think it ever really got "stable" until about a month or so before 2.3 came out.
User avatar
Graf Zahl
Lead GZDoom+Raze Developer
Lead GZDoom+Raze Developer
Posts: 49143
Joined: Sat Jul 19, 2003 10:19 am
Location: Germany

Re: [Source] Need help restoring low detail modes (r_detail)

Post by Graf Zahl »

Right. But that still doesn't change much about the maint branch. It got a handful of bugfixes before the code bases started to deviate too much.
But even so, a better place might be the master branch before the ill-fated renderer floatification.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

I'm compiling with CodeBlocks (TDM-GCC 4.9.2) and NASM 2.10.09. Blue-green-frog already tested that, actually first he "forked" from the end of the openal branch around 2.7.1 and the official 2.7.1 gave pretty much the same performance on a pentium 2, ZDoom 2.2 was faster but the massive performance difference is there only on pentiums. On a fast pentium 2 the difference is not important anymore.

Blzut3 suggested forking from the maint branch and i think the floatification came roughly at the same time. Anyway it's a classic version for old machines and we wanted a stable codebase.

Lately i've been trying even older versions of ZDoom, such as 1.14a, and that one had a different cool startup console and a highcolor mode which was not working very well.
User avatar
drfrag
Vintage GZDoom Developer
Posts: 3147
Joined: Fri Apr 23, 2004 3:51 am
Location: Spain

Re: [Source] Need help restoring low detail modes (r_detail)

Post by drfrag »

Looks like i'm in trouble again, the quad mode doesn't work but i think the algorithm is right, i don't know what's going on.
I can see only one third of the screen and the rest is junk, as if the buffer is too small but that's not the case. When i change "BYTE c = linefrom[x]" to "BYTE c = linefrom[x*2]" (half the data to copy) i get the full view but on half of the screen (squished horizontally) and when i put there "BYTE c = linefrom[x*2]" i get the screen stretched vertically as well but repeated four times so clearly the buffer is there since it doesn't crash. Any ideas guys?

The algorithm just copies an array of bytes, it's like dog->ddddoooogggg. The pitch stuff is for doubling vertically, viewwidth is e.g. 160 and realviewwidth 640, this is based on the x and y double one of course. I don't know why i can only see one third of the screen.

Code: Select all

	case 5:		// x-quad and y-double placeholder
		{
			int rowsize = viewwidth;
			int realpitch = RenderTarget->GetPitch();
			int pitch = realpitch << 1;
			int y,x;
			BYTE *linefrom, *lineto;

			linefrom = dc_destorg;
			for (y = viewheight; y != 0; --y, linefrom += pitch)
			{
				lineto = linefrom - viewwidth;
				for (x = 0; x < rowsize; ++x)
				{
					BYTE c = linefrom[x];
					lineto[x*4] = c;
					lineto[x*4+1] = c;
					lineto[x*4+2] = c;
					lineto[x*4+3] = c;
					lineto[x*4+realpitch] = c;
					lineto[x*4+realpitch+1] = c;
					lineto[x*4+realpitch+2] = c;
					lineto[x*4+realpitch+3] = c;
				}
			}
		}
		break;

Return to “Editing (Archive)”