ref: 0cc2ad38090b1b286ded01321afc0e199b37372c
parent: de979570b694ba56b7196a4fe339ff7292fe8fe5
author: Simon Howard <[email protected]>
date: Mon Dec 18 13:15:47 EST 2006
x3, x4 aspect ratio corrected scale functions. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 786
--- a/TODO
+++ b/TODO
@@ -5,7 +5,6 @@
- Debian/Ubuntu .deb packages, Fedora .rpm packages.
- Windows NSIS installer.
- MacOS X .dmg packages (should be universal binaries!)
-* Aspect ratio correction - stretch 320x200 to 320x240, 640x480, etc.
* Smarter setup program - detect IWADs automatically and make them
selectable from a list.
* Free version of the Chocolate Doom logo (from scratch, not using the
--- a/src/i_scale.c
+++ b/src/i_scale.c
@@ -402,3 +402,285 @@
}
}
+static void WriteLine3x(byte *dest, byte *src)
+{
+ int x;
+
+ for (x=0; x<SCREENWIDTH; ++x)
+ {
+ dest[0] = *src;
+ dest[1] = *src;
+ dest[2] = *src;
+ dest += 3;
+ ++src;
+ }
+}
+
+static void WriteBlendedLine3x(byte *dest, byte *src1, byte *src2,
+ byte *stretch_table)
+{
+ int x;
+ int val;
+
+ for (x=0; x<SCREENWIDTH; ++x)
+ {
+ val = stretch_table[*src1 * 256 + *src2];
+ dest[0] = val;
+ dest[1] = val;
+ dest[2] = val;
+ dest += 3;
+ ++src1;
+ ++src2;
+ }
+}
+
+void I_Stretch3x(int x1, int y1, int x2, int y2)
+{
+ byte *bufp, *screenp;
+ int y;
+
+ // Only works with full screen update
+
+ if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT)
+ {
+ return;
+ }
+
+ // Need to byte-copy from buffer into the screen buffer
+
+ bufp = src_buffer + y1 * SCREENWIDTH + x1;
+ screenp = (byte *) dest_buffer + y1 * dest_pitch + x1;
+
+ // For every 5 lines of src_buffer, 18 lines are written to dest_buffer.
+ // (200 -> 720)
+
+ for (y=0; y<SCREENHEIGHT; y += 5)
+ {
+ // 100% line 0
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 0
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 0
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 60% line 0, 40% line 1
+ WriteBlendedLine3x(screenp, bufp + SCREENWIDTH, bufp, stretch_tables[1]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 1
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 1
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 1
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 20% line 1, 80% line 2
+ WriteBlendedLine3x(screenp, bufp, bufp + SCREENWIDTH, stretch_tables[0]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 2
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 2
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 80% line 2, 20% line 3
+ WriteBlendedLine3x(screenp, bufp + SCREENWIDTH, bufp, stretch_tables[0]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 3
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 3
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 3
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 40% line 3, 60% line 4
+ WriteBlendedLine3x(screenp, bufp, bufp + SCREENWIDTH, stretch_tables[1]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 4
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 4
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 4
+ WriteLine3x(screenp, bufp);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+ }
+}
+
+static void WriteLine4x(byte *dest, byte *src)
+{
+ int x;
+
+ for (x=0; x<SCREENWIDTH; ++x)
+ {
+ dest[0] = *src;
+ dest[1] = *src;
+ dest[2] = *src;
+ dest[3] = *src;
+ dest += 4;
+ ++src;
+ }
+}
+
+static void WriteBlendedLine4x(byte *dest, byte *src1, byte *src2,
+ byte *stretch_table)
+{
+ int x;
+ int val;
+
+ for (x=0; x<SCREENWIDTH; ++x)
+ {
+ val = stretch_table[*src1 * 256 + *src2];
+ dest[0] = val;
+ dest[1] = val;
+ dest[2] = val;
+ dest[3] = val;
+ dest += 4;
+ ++src1;
+ ++src2;
+ }
+}
+
+void I_Stretch4x(int x1, int y1, int x2, int y2)
+{
+ byte *bufp, *screenp;
+ int y;
+
+ // Only works with full screen update
+
+ if (x1 != 0 || y1 != 0 || x2 != SCREENWIDTH || y2 != SCREENHEIGHT)
+ {
+ return;
+ }
+
+ // Need to byte-copy from buffer into the screen buffer
+
+ bufp = src_buffer + y1 * SCREENWIDTH + x1;
+ screenp = (byte *) dest_buffer + y1 * dest_pitch + x1;
+
+ // For every 5 lines of src_buffer, 24 lines are written to dest_buffer.
+ // (200 -> 960)
+
+ for (y=0; y<SCREENHEIGHT; y += 5)
+ {
+ // 100% line 0
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 0
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 0
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 0
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 90% line 0, 20% line 1
+ WriteBlendedLine4x(screenp, bufp + SCREENWIDTH, bufp, stretch_tables[0]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 1
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 1
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 1
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 1
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 60% line 1, 40% line 2
+ WriteBlendedLine4x(screenp, bufp + SCREENWIDTH, bufp, stretch_tables[1]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 2
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 2
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 2
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 2
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 40% line 2, 60% line 3
+ WriteBlendedLine4x(screenp, bufp, bufp + SCREENWIDTH, stretch_tables[1]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 3
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 3
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 3
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 3
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 20% line 3, 80% line 4
+ WriteBlendedLine4x(screenp, bufp, bufp + SCREENWIDTH, stretch_tables[0]);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+
+ // 100% line 4
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 4
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 4
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch;
+
+ // 100% line 4
+ WriteLine4x(screenp, bufp);
+ screenp += dest_pitch; bufp += SCREENWIDTH;
+ }
+}
+
--- a/src/i_scale.h
+++ b/src/i_scale.h
@@ -37,6 +37,8 @@
void I_Scale4x(int x1, int y1, int x2, int y2);
void I_Stretch1x(int x1, int y1, int x2, int y2);
void I_Stretch2x(int x1, int y1, int x2, int y2);
+void I_Stretch3x(int x1, int y1, int x2, int y2);
+void I_Stretch4x(int x1, int y1, int x2, int y2);
void I_InitStretchTables(byte *palette);
#endif /* #ifndef __I_SCALE__ */
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -591,6 +591,14 @@
{
scale_function = I_Stretch2x;
}
+ else if (screenmultiply == 3)
+ {
+ scale_function = I_Stretch3x;
+ }
+ else if (screenmultiply == 4)
+ {
+ scale_function = I_Stretch4x;
+ }
else
{
I_Error("No aspect ratio stretching function for screenmultiply=%i",