First post, by Elamaton
This is going to sound a bit outlandish, but bear with me.
Earlier today at work I posted this thread: Scaling, aspect ratios and Normal4x revisited.
While driving home, I thought about my statement of "it can't be that hard", concerning implementing Normal4x. I have no C/C++ experience whatsoever (just PHP, Python, and some Java years ago), certainly nothing graphics-related, but just for the hell of it, I checked out the source from CVS and started looking at it.
Well, a hour and a half of grepping and copypasting later, I thought I'd download SDL to my Mac and try compiling DOSBox with my changes.
To my surprise, it compiled just fine.
To my even greater surprise, it ran just fine.
To my complete jaw-dropping amazement, the 4x scaling actually. Fucking. Worked.
This wasn't supposed to happen. The compilation was supposed to die at some point, or at least the software should have crashed violently. But no.
I verified the functionality with Tyrian with its 320x200 resolution, having this in the config file:
windowresolution=original
output=opengl
aspect=true
scaler=normal4x
And what do you know, I got a 1280x960 resolution. For fun, I set windowresolution=1280x960 and tried the various normal scalers, and yes, the 4x image was easily the sharpest. This is exactly what I was saying in the original thread. And I have screenshots of this experiment:
http://elamaton.no-ip.com:8080/dosbox/Normal3x.png
http://elamaton.no-ip.com:8080/dosbox/Normal4x.png
The difference should be quite obvious at least on a proper LCD screen. Flip back and forth those two, the difference is particularly visible in the text, especially the brighter-colored "Data".
Now, while I'm completely giddy at actually pulling this off and feeling good about myself, I must admit that the changes were not that hard. I'm not that smart. But if even I could manage them in an hour and a half, never having done any C++ and certainly never having looked at DOSBox's codebase before, I must express my amazement: why hasn't someone done this a long time ago? I mean, the feature request isn't actually new. And the changes were positively trivial. This is something a dev could have done during a coffee break.
I'm mostly being rhetorical. I'm sure there are valid reasons.
Anyway. Here's the output of cvs diff. The changes are naive and unassuming, and minimally tested, but tested anyway. You'll want to review them and clean them up. But after they've gone through whatever process you have for these sort of things, I would REALLY like to see Normal4x in the next release. Don't let their humble copy-pasted origins or their simian author put you off. I know people want this feature, and that's why I started the whole thing.
Cheers, and all the best to you.
Index: src/dosbox.cpp
===================================================================
RCS file: /cvsroot/dosbox/dosbox/src/dosbox.cpp,v
retrieving revision 1.137
diff -r1.137 dosbox.cpp
372c372
< "none", "normal2x", "normal3x",
---
> "none", "normal2x", "normal3x", "normal4x",
Index: src/gui/render.cpp
===================================================================
RCS file: /cvsroot/dosbox/dosbox/src/gui/render.cpp,v
retrieving revision 1.56
diff -r1.56 render.cpp
290a291,292
> else if (render.scale.size == 4)
> simpleBlock = &ScaleNormal4x;
553c555
< if(++render.scale.size > 3)
---
> if(++render.scale.size > 4)
591a594
> else if (scaler == "normal4x") { render.scale.op = scalerOpNormal;render.scale.size = 4; }
Index: src/gui/render_loops.h
===================================================================
RCS file: /cvsroot/dosbox/dosbox/src/gui/render_loops.h,v
retrieving revision 1.5
diff -r1.5 render_loops.h
53a54,56
> #if (SCALERHEIGHT > 3)
> PTYPE * line3;
> #endif
68a72,74
> #if (SCALERHEIGHT > 3)
> line3 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 3);
> #endif
79a86,88
> #if (SCALERHEIGHT > 3)
> line3 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 3);
> #endif
87a97,99
> #if (SCALERHEIGHT > 3)
> line3 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 3);
> #endif
94a107,109
> #if (SCALERHEIGHT > 3)
> line3 += SCALERWIDTH * (SCALER_BLOCKSIZE -1);
> #endif
107a123,125
> #if (SCALERHEIGHT > 3)
> line3 = WC[2];
> #endif
114a133,135
> #if (SCALERHEIGHT > 3)
> line3 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 3);
> #endif
124a146,148
> #if (SCALERHEIGHT > 3)
> line3 += SCALERWIDTH;
> #endif
133a158,160
> #if (SCALERHEIGHT > 3)
> BituMove((Bit8u*)(&line0[-SCALER_BLOCKSIZE*SCALERWIDTH])+render.scale.outPitch*3,WC[2], SCALER_BLOCKSIZE *SCALERWIDTH*PSIZE);
> #endif
Index: src/gui/render_scalers.cpp
===================================================================
RCS file: /cvsroot/dosbox/dosbox/src/gui/render_scalers.cpp,v
retrieving revision 1.14
diff -r1.14 render_scalers.cpp
258a259,275
> ScalerSimpleBlock_t ScaleNormal4x = {
> "Normal4x",
> GFX_CAN_8|GFX_CAN_15|GFX_CAN_16|GFX_CAN_32,
> 4,4,{
> { Normal4x_8_8_L, Normal4x_8_15_L , Normal4x_8_16_L , Normal4x_8_32_L },
> { 0, Normal4x_15_15_L, Normal4x_15_16_L, Normal4x_15_32_L},
> { 0, Normal4x_16_15_L, Normal4x_16_16_L, Normal4x_16_32_L},
> { 0, Normal4x_32_15_L, Normal4x_32_16_L, Normal4x_32_32_L},
> { Normal4x_8_8_L, Normal4x_9_15_L , Normal4x_9_16_L , Normal4x_9_32_L }
> },{
> { Normal4x_8_8_R, Normal4x_8_15_R , Normal4x_8_16_R , Normal4x_8_32_R },
> { 0, Normal4x_15_15_R, Normal4x_15_16_R, Normal4x_15_32_R},
> { 0, Normal4x_16_15_R, Normal4x_16_16_R, Normal4x_16_32_R},
> { 0, Normal4x_32_15_R, Normal4x_32_16_R, Normal4x_32_32_R},
> { Normal4x_8_8_R, Normal4x_9_15_R , Normal4x_9_16_R , Normal4x_9_32_R }
> }};
>
Index: src/gui/render_scalers.h
===================================================================
RCS file: /cvsroot/dosbox/dosbox/src/gui/render_scalers.h,v
retrieving revision 1.13
diff -r1.13 render_scalers.h
115a116
> extern ScalerSimpleBlock_t ScaleNormal4x;
Index: src/gui/render_simple.h
===================================================================
RCS file: /cvsroot/dosbox/dosbox/src/gui/render_simple.h,v
retrieving revision 1.5
diff -r1.5 render_simple.h
68a69,71
> #if (SCALERHEIGHT > 3)
> PTYPE *line3 = WC[2];
> #endif
75a79,81
> #if (SCALERHEIGHT > 3)
> PTYPE *line3 = (PTYPE *)(((Bit8u*)line0)+ render.scale.outPitch * 3);
> #endif
90a97,99
> #if (SCALERHEIGHT > 3)
> line3 += SCALERWIDTH;
> #endif
99a109,111
> #if (SCALERHEIGHT > 3)
> BituMove(((Bit8u*)line0)-copyLen+render.scale.outPitch*3,WC[2], copyLen );
> #endif
Index: src/gui/render_templates.h
===================================================================
RCS file: /cvsroot/dosbox/dosbox/src/gui/render_templates.h,v
retrieving revision 1.14
diff -r1.14 render_templates.h
259a260,285
> #define SCALERNAME Normal4x
> #define SCALERWIDTH 4
> #define SCALERHEIGHT 4
> #define SCALERFUNC \
> line0[0] = P; \
> line0[1] = P; \
> line0[2] = P; \
> line0[3] = P; \
> line1[0] = P; \
> line1[1] = P; \
> line1[2] = P; \
> line1[3] = P; \
> line2[0] = P; \
> line2[1] = P; \
> line2[2] = P; \
> line2[3] = P; \
> line3[0] = P; \
> line3[1] = P; \
> line3[2] = P; \
> line3[3] = P;
> #include "render_simple.h"
> #undef SCALERNAME
> #undef SCALERWIDTH
> #undef SCALERHEIGHT
> #undef SCALERFUNC
>