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

Discuss all aspects of editing for ZDoom.
Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.

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

Postby drfrag » Wed Mar 01, 2017 8:23 am

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 allExpand view
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 4:14 pm, edited 6 times in total.
User avatar
drfrag
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby dpJudas » Wed Mar 01, 2017 12:43 pm

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.
dpJudas
 
 
 
Joined: 28 May 2016

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

Postby drfrag » Wed Mar 01, 2017 1:13 pm

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
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby drfrag » Fri Mar 03, 2017 3:33 pm

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
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby drfrag » Sat Mar 04, 2017 3:48 pm

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
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby drfrag » Sun Mar 05, 2017 7:03 am

@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
drfrag
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby Graf Zahl » Sun Mar 05, 2017 7:41 am

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
Graf Zahl
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

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

Postby drfrag » Sun Mar 05, 2017 11:49 am

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.
User avatar
drfrag
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby dpJudas » Sun Mar 05, 2017 5:15 pm

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.
dpJudas
 
 
 
Joined: 28 May 2016

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

Postby drfrag » Mon Mar 06, 2017 1:11 pm

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 5:14 am, edited 1 time in total.
User avatar
drfrag
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby Graf Zahl » Mon Mar 06, 2017 1:25 pm

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
Graf Zahl
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

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

Postby Rachael » Mon Mar 06, 2017 1:31 pm

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
Rachael
Webmaster
 
Joined: 13 Jan 2004
Discord: Rachael#3767
Twitch ID: madamerachelle
Github ID: madame-rachelle

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

Postby Graf Zahl » Mon Mar 06, 2017 1:32 pm

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
Graf Zahl
Lead GZDoom Developer
 
Joined: 19 Jul 2003
Location: Germany

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

Postby drfrag » Tue Mar 07, 2017 5:20 am

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
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

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

Postby drfrag » Wed Mar 08, 2017 6:13 am

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 allExpand view
   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;

User avatar
drfrag
I.R developer, I.R smart
Vintage GZDoom Developer
 
Joined: 23 Apr 2004
Location: Spain

Next

Return to Editing (Archive)

Who is online

Users browsing this forum: Google [Bot] and 1 guest