summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon Howard2006-12-18 18:15:47 +0000
committerSimon Howard2006-12-18 18:15:47 +0000
commit0cc2ad38090b1b286ded01321afc0e199b37372c (patch)
tree9242ca6ffa13b2e0a49a0457f081d9a4012aca26
parentde979570b694ba56b7196a4fe339ff7292fe8fe5 (diff)
downloadchocolate-doom-0cc2ad38090b1b286ded01321afc0e199b37372c.tar.gz
chocolate-doom-0cc2ad38090b1b286ded01321afc0e199b37372c.tar.bz2
chocolate-doom-0cc2ad38090b1b286ded01321afc0e199b37372c.zip
x3, x4 aspect ratio corrected scale functions.
Subversion-branch: /trunk/chocolate-doom Subversion-revision: 786
-rw-r--r--TODO1
-rw-r--r--src/i_scale.c282
-rw-r--r--src/i_scale.h2
-rw-r--r--src/i_video.c8
4 files changed, 292 insertions, 1 deletions
diff --git a/TODO b/TODO
index 83b9ecdc..41971825 100644
--- a/TODO
+++ b/TODO
@@ -5,7 +5,6 @@ To do:
- 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
diff --git a/src/i_scale.c b/src/i_scale.c
index 29bc8731..deda0551 100644
--- a/src/i_scale.c
+++ b/src/i_scale.c
@@ -402,3 +402,285 @@ void I_Stretch2x(int x1, int y1, int x2, int y2)
}
}
+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;
+ }
+}
+
diff --git a/src/i_scale.h b/src/i_scale.h
index 6f523039..578b2b36 100644
--- a/src/i_scale.h
+++ b/src/i_scale.h
@@ -37,6 +37,8 @@ void I_Scale3x(int x1, int y1, int x2, int y2);
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__ */
diff --git a/src/i_video.c b/src/i_video.c
index 26f8ec16..e2b12ed4 100644
--- a/src/i_video.c
+++ b/src/i_video.c
@@ -591,6 +591,14 @@ static void BlitArea(int x1, int y1, int x2, int y2)
{
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",