diff --git a/cnc-ddraw.vcxproj b/cnc-ddraw.vcxproj
index 4cde61e..db234cc 100644
--- a/cnc-ddraw.vcxproj
+++ b/cnc-ddraw.vcxproj
@@ -92,7 +92,6 @@
-
diff --git a/cnc-ddraw.vcxproj.filters b/cnc-ddraw.vcxproj.filters
index 6871a26..39187f8 100644
--- a/cnc-ddraw.vcxproj.filters
+++ b/cnc-ddraw.vcxproj.filters
@@ -176,9 +176,6 @@
Header Files
-
- Header Files
-
Header Files
diff --git a/inc/blt.h b/inc/blt.h
index 363139f..34bffa4 100644
--- a/inc/blt.h
+++ b/inc/blt.h
@@ -100,13 +100,13 @@ void blt_bgra8888_to_rgba8888(
int src_p);
void blt_stretch(
- unsigned char* dst_buf,
+ unsigned char* dst,
int dst_x,
int dst_y,
int dst_w,
int dst_h,
int dst_p,
- unsigned char* src_buf,
+ unsigned char* src,
int src_x,
int src_y,
int src_w,
diff --git a/inc/scale_pattern.h b/inc/scale_pattern.h
deleted file mode 100644
index a4027df..0000000
--- a/inc/scale_pattern.h
+++ /dev/null
@@ -1,18 +0,0 @@
-#ifndef _SCALE_PATTERN_H
-#define _SCALE_PATTERN_H
-
-typedef enum {
- REPEAT,
- SEQUENCE,
- ONCE,
- END
-} SCALE_PATTERN_TYPE;
-
-typedef struct {
- SCALE_PATTERN_TYPE type;
- int dst_index;
- int src_index;
- int count;
-} scale_pattern;
-
-#endif
diff --git a/src/blt.c b/src/blt.c
index 4193182..ef1bb47 100644
--- a/src/blt.c
+++ b/src/blt.c
@@ -522,13 +522,13 @@ void blt_bgra8888_to_rgba8888(
}
void blt_stretch(
- unsigned char* dst_buf,
+ unsigned char* dst,
int dst_x,
int dst_y,
int dst_w,
int dst_h,
int dst_p,
- unsigned char* src_buf,
+ unsigned char* src,
int src_x,
int src_y,
int src_w,
@@ -536,203 +536,101 @@ void blt_stretch(
int src_p,
int bpp)
{
- /* Linear scaling using integer math
- * Since the scaling pattern for x will aways be the same, the pattern itself gets pre-calculated
- * and stored in an array.
- * Y scaling pattern gets calculated during the blit loop
- */
- unsigned int x_ratio = (unsigned int)((src_w << 16) / dst_w) + 1;
- unsigned int y_ratio = (unsigned int)((src_h << 16) / dst_h) + 1;
+ int bytes_pp = bpp / 8;
- unsigned int s_src_x, s_src_y;
- unsigned int dest_base, source_base;
+ size_t size = dst_w * bytes_pp;
- scale_pattern* pattern = malloc((dst_w + 1) * (sizeof(scale_pattern)));
- int pattern_idx = 0;
- unsigned int last_src_x = 0;
+ int dst_surf_w = dst_p / bytes_pp;
+ int src_surf_w = src_p / bytes_pp;
- if (pattern != NULL)
+ float scale_w = (float)src_w / dst_w;
+ float scale_h = (float)src_h / dst_h;
+
+ int last_y = -1;
+ int last_row = -1;
+
+ if (bpp == 8)
{
- pattern[pattern_idx] = (scale_pattern){ ONCE, 0, 0, 1 };
+ for (int y = 0; y < dst_h; y++)
+ {
+ int scaled_y = (int)(y * scale_h);
+ int dst_row = dst_surf_w * (y + dst_y);
- /* Build the pattern! */
- int x;
- for (x = 1; x < dst_w; x++) {
- s_src_x = (x * x_ratio) >> 16;
- if (s_src_x == last_src_x)
+ if (scaled_y == last_y)
{
- if (pattern[pattern_idx].type == REPEAT || pattern[pattern_idx].type == ONCE)
- {
- pattern[pattern_idx].type = REPEAT;
- pattern[pattern_idx].count++;
- }
- else if (pattern[pattern_idx].type == SEQUENCE)
- {
- pattern_idx++;
- pattern[pattern_idx] = (scale_pattern){ REPEAT, x, s_src_x, 1 };
- }
+ memcpy(&dst[dst_x + dst_row], &dst[dst_x + last_row], size);
+ continue;
}
- else if (s_src_x == last_src_x + 1)
+
+ last_y = scaled_y;
+ last_row = dst_row;
+
+ int src_row = src_surf_w * (scaled_y + src_y);
+
+ for (int x = 0; x < dst_w; x++)
{
- if (pattern[pattern_idx].type == SEQUENCE || pattern[pattern_idx].type == ONCE)
- {
- pattern[pattern_idx].type = SEQUENCE;
- pattern[pattern_idx].count++;
- }
- else if (pattern[pattern_idx].type == REPEAT)
- {
- pattern_idx++;
- pattern[pattern_idx] = (scale_pattern){ ONCE, x, s_src_x, 1 };
- }
- }
- else
- {
- pattern_idx++;
- pattern[pattern_idx] = (scale_pattern){ ONCE, x, s_src_x, 1 };
- }
- last_src_x = s_src_x;
- }
- pattern[pattern_idx + 1] = (scale_pattern){ END, 0, 0, 0 };
+ int scaled_x = (int)(x * scale_w);
-
- /* Do the actual blitting */
- int bytes_pp = bpp / 8;
- int dst_surf_w = dst_p / bytes_pp;
- int src_surf_w = src_p / bytes_pp;
-
- int count = 0;
- int y;
-
- for (y = 0; y < dst_h; y++) {
-
- dest_base = dst_x + dst_surf_w * (y + dst_y);
-
- s_src_y = (y * y_ratio) >> 16;
-
- source_base = src_x + src_surf_w * (s_src_y + src_y);
-
- pattern_idx = 0;
- scale_pattern* current = &pattern[pattern_idx];
-
- if (bpp == 8)
- {
- unsigned char* d, * s, v;
- unsigned char* src = (unsigned char*)src_buf;
- unsigned char* dst = (unsigned char*)dst_buf;
-
- do {
- switch (current->type)
- {
- case ONCE:
- dst[dest_base + current->dst_index] =
- src[source_base + current->src_index];
- break;
-
- case REPEAT:
- d = (dst + dest_base + current->dst_index);
- v = src[source_base + current->src_index];
-
- count = current->count;
- while (count-- > 0)
- *d++ = v;
-
- break;
-
- case SEQUENCE:
- d = dst + dest_base + current->dst_index;
- s = src + source_base + current->src_index;
-
- memcpy((void*)d, (void*)s, current->count);
- break;
-
- case END:
- default:
- break;
- }
-
- current = &pattern[++pattern_idx];
- } while (current->type != END);
- }
- else if (bpp == 16)
- {
- unsigned short* d, * s, v;
- unsigned short* src = (unsigned short*)src_buf;
- unsigned short* dst = (unsigned short*)dst_buf;
-
- do {
- switch (current->type)
- {
- case ONCE:
- dst[dest_base + current->dst_index] =
- src[source_base + current->src_index];
- break;
-
- case REPEAT:
- d = (dst + dest_base + current->dst_index);
- v = src[source_base + current->src_index];
-
- count = current->count;
- while (count-- > 0)
- *d++ = v;
-
- break;
-
- case SEQUENCE:
- d = dst + dest_base + current->dst_index;
- s = src + source_base + current->src_index;
-
- memcpy((void*)d, (void*)s, current->count * bytes_pp);
- break;
-
- case END:
- default:
- break;
- }
-
- current = &pattern[++pattern_idx];
- } while (current->type != END);
- }
- else if (bpp == 32)
- {
- unsigned int* d, * s, v;
- unsigned int* src = (unsigned int*)src_buf;
- unsigned int* dst = (unsigned int*)dst_buf;
-
- do {
- switch (current->type)
- {
- case ONCE:
- dst[dest_base + current->dst_index] =
- src[source_base + current->src_index];
- break;
-
- case REPEAT:
- d = (dst + dest_base + current->dst_index);
- v = src[source_base + current->src_index];
-
- count = current->count;
- while (count-- > 0)
- *d++ = v;
-
- break;
-
- case SEQUENCE:
- d = dst + dest_base + current->dst_index;
- s = src + source_base + current->src_index;
-
- memcpy((void*)d, (void*)s, current->count * bytes_pp);
- break;
-
- case END:
- default:
- break;
- }
-
- current = &pattern[++pattern_idx];
- } while (current->type != END);
+ dst[x + dst_x + dst_row] = src[scaled_x + src_x + src_row];
}
}
- free(pattern);
}
+ else if (bpp == 16)
+ {
+ unsigned short* d = (unsigned short*)dst;
+ unsigned short* s = (unsigned short*)src;
+ for (int y = 0; y < dst_h; y++)
+ {
+ int scaled_y = (int)(y * scale_h);
+ int dst_row = dst_surf_w * (y + dst_y);
+
+ if (scaled_y == last_y)
+ {
+ memcpy(&d[dst_x + dst_row], &d[dst_x + last_row], size);
+ continue;
+ }
+
+ last_y = scaled_y;
+ last_row = dst_row;
+
+ int src_row = src_surf_w * (scaled_y + src_y);
+
+ for (int x = 0; x < dst_w; x++)
+ {
+ int scaled_x = (int)(x * scale_w);
+
+ d[x + dst_x + dst_row] = s[scaled_x + src_x + src_row];
+ }
+ }
+ }
+ else if (bpp == 32)
+ {
+ unsigned int* d = (unsigned int*)dst;
+ unsigned int* s = (unsigned int*)src;
+
+ for (int y = 0; y < dst_h; y++)
+ {
+ int scaled_y = (int)(y * scale_h);
+ int dst_row = dst_surf_w * (y + dst_y);
+
+ if (scaled_y == last_y)
+ {
+ memcpy(&d[dst_x + dst_row], &d[dst_x + last_row], size);
+ continue;
+ }
+
+ last_y = scaled_y;
+ last_row = dst_row;
+
+ int src_row = src_surf_w * (scaled_y + src_y);
+
+ for (int x = 0; x < dst_w; x++)
+ {
+ int scaled_x = (int)(x * scale_w);
+
+ d[x + dst_x + dst_row] = s[scaled_x + src_x + src_row];
+ }
+ }
+ }
}