Melee scaling is now trilinear by default, but it's still possible to
choose nearest neighbour with --meleescale; fixes #34 git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@885 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -1,4 +1,6 @@
|
||||
Changes towards version 0.3:
|
||||
- Melee scaling is now trilinear by default, but it's still possible to
|
||||
choose nearest neighbour with --meleescale; fixes #34 -Mika
|
||||
- Minimum scaling extent is now 1,1; fixes mostly small-objects-disappearing
|
||||
problem in melee, from chmmravatar
|
||||
- Fixed a long standing memory leak relating to planet surface -PhracturedBlue
|
||||
|
||||
@@ -41,6 +41,12 @@ faster as well -- but it also may not work on older cards.
|
||||
Graphics scaling mode (bilinear, biadapt or biadv). Default is none.
|
||||
Try these to get smoother graphics with cost on performance.
|
||||
|
||||
-b (or --meleescale=mode)
|
||||
|
||||
Melee scaling mode (nearest or trilinear). Default is trilinear.
|
||||
Slower machine owners can set it to nearest to get better performance
|
||||
in melee but degraded visual quality.
|
||||
|
||||
-s (or --scanlines)
|
||||
|
||||
Simulates interlaced displays.
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "compiler.h"
|
||||
#include "options.h"
|
||||
#include "file.h"
|
||||
@@ -32,6 +33,7 @@ int optWhichCoarseScan = OPT_3DO;
|
||||
int optWhichMenu = OPT_3DO;
|
||||
int optWhichFonts = OPT_PC;
|
||||
int optSmoothScroll = OPT_PC;
|
||||
int optMeleeScale = TFB_SCALE_TRILINEAR;
|
||||
|
||||
char *configDir, *saveDir, *meleeDir;
|
||||
BOOLEAN optSubtitles = TRUE;
|
||||
|
||||
@@ -31,6 +31,7 @@ extern int optWhichCoarseScan;
|
||||
extern int optWhichMenu;
|
||||
extern int optWhichFonts;
|
||||
extern int optSmoothScroll;
|
||||
extern int optMeleeScale;
|
||||
|
||||
extern BOOLEAN optSubtitles;
|
||||
|
||||
|
||||
@@ -150,7 +150,7 @@ FRAMEPTR stretch_frame (FRAMEPTR FramePtr, int neww, int newh, int destroy)
|
||||
dst = NewFrame->image->NormalImg;
|
||||
ext.width = neww;
|
||||
ext.height = newh;
|
||||
TFB_DrawCanvas_Rescale (src, dst, ext);
|
||||
TFB_DrawCanvas_Rescale_Nearest (src, dst, ext);
|
||||
UnlockMutex (tfbImg->mutex);
|
||||
if (destroy)
|
||||
DestroyDrawable (ReleaseDrawable (FramePtr));
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/graphics/sdl/primitives.h"
|
||||
#include "libs/graphics/tfb_draw.h"
|
||||
#include "options.h"
|
||||
|
||||
typedef SDL_Surface *NativeCanvas;
|
||||
|
||||
@@ -50,7 +51,24 @@ TFB_DrawCanvas_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *pale
|
||||
|
||||
if (scale != 0 && scale != GSCALE_IDENTITY)
|
||||
{
|
||||
TFB_DrawImage_FixScaling (img, scale);
|
||||
int type;
|
||||
if (optMeleeScale == TFB_SCALE_TRILINEAR && img->MipmapImg)
|
||||
{
|
||||
type = TFB_SCALE_TRILINEAR;
|
||||
if (palette)
|
||||
{
|
||||
if (((SDL_Surface *)img->NormalImg)->format->palette)
|
||||
SDL_SetColors (img->NormalImg, (SDL_Color*)palette, 0, 256);
|
||||
if (((SDL_Surface *)img->MipmapImg)->format->palette)
|
||||
SDL_SetColors (img->MipmapImg, (SDL_Color*)palette, 0, 256);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
type = TFB_SCALE_NEAREST;
|
||||
}
|
||||
|
||||
TFB_DrawImage_FixScaling (img, scale, type);
|
||||
surf = img->ScaledImg;
|
||||
srcRect.x = 0;
|
||||
srcRect.y = 0;
|
||||
@@ -101,7 +119,7 @@ TFB_DrawCanvas_FilledImage (TFB_Image *img, int x, int y, int scale, int r, int
|
||||
|
||||
if (scale != 0 && scale != GSCALE_IDENTITY)
|
||||
{
|
||||
TFB_DrawImage_FixScaling (img, scale);
|
||||
TFB_DrawImage_FixScaling (img, scale, TFB_SCALE_NEAREST);
|
||||
surf = img->ScaledImg;
|
||||
srcRect.x = 0;
|
||||
srcRect.y = 0;
|
||||
@@ -163,20 +181,46 @@ TFB_DrawCanvas_New_Paletted (int w, int h, TFB_Palette *palette, int transparent
|
||||
}
|
||||
|
||||
TFB_Canvas
|
||||
TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas)
|
||||
TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int type, int last_type)
|
||||
{
|
||||
SDL_Surface *src = (SDL_Surface *)canvas;
|
||||
SDL_Surface *newsurf = SDL_CreateRGBSurface (SDL_SWSURFACE, src->w,
|
||||
src->h,
|
||||
src->format->BitsPerPixel,
|
||||
src->format->Rmask,
|
||||
src->format->Gmask,
|
||||
src->format->Bmask,
|
||||
src->format->Amask);
|
||||
if (src->format->palette)
|
||||
SDL_Surface *old = (SDL_Surface *)oldcanvas;
|
||||
SDL_Surface *newsurf = old;
|
||||
|
||||
if (type == TFB_SCALE_NEAREST)
|
||||
{
|
||||
TFB_DrawCanvas_SetTransparentIndex (newsurf, TFB_DrawCanvas_GetTransparentIndex (src));
|
||||
if (old && type != last_type)
|
||||
{
|
||||
TFB_DrawCanvas_Delete (old);
|
||||
old = NULL;
|
||||
}
|
||||
if (!old)
|
||||
{
|
||||
newsurf = SDL_CreateRGBSurface (SDL_SWSURFACE, src->w,
|
||||
src->h,
|
||||
src->format->BitsPerPixel,
|
||||
src->format->Rmask,
|
||||
src->format->Gmask,
|
||||
src->format->Bmask,
|
||||
src->format->Amask);
|
||||
if (src->format->palette)
|
||||
TFB_DrawCanvas_SetTransparentIndex (newsurf, TFB_DrawCanvas_GetTransparentIndex (src));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (old && type != last_type)
|
||||
{
|
||||
TFB_DrawCanvas_Delete (old);
|
||||
old = NULL;
|
||||
}
|
||||
if (!old)
|
||||
{
|
||||
newsurf = SDL_CreateRGBSurface (SDL_SWSURFACE, src->w, src->h, 32,
|
||||
0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
}
|
||||
}
|
||||
|
||||
return newsurf;
|
||||
}
|
||||
|
||||
@@ -268,11 +312,31 @@ TFB_DrawCanvas_SetTransparentIndex (TFB_Canvas canvas, int index)
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, int scale, PEXTENT size)
|
||||
TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, int scale, PEXTENT size)
|
||||
{
|
||||
SDL_Surface *src = (SDL_Surface *)src_canvas;
|
||||
size->width = (int) (src->w * scale / (float)GSCALE_IDENTITY);
|
||||
size->height = (int) (src->h * scale / (float)GSCALE_IDENTITY);
|
||||
|
||||
if (!src_mipmap)
|
||||
{
|
||||
size->width = (int) (src->w * scale / (float)GSCALE_IDENTITY);
|
||||
size->height = (int) (src->h * scale / (float)GSCALE_IDENTITY);
|
||||
}
|
||||
else
|
||||
{
|
||||
// interpolates extents between src and mipmap to get smoother
|
||||
// transition when surface changes
|
||||
|
||||
SDL_Surface *mipmap = (SDL_Surface *)src_mipmap;
|
||||
float ratio = (scale / (float)GSCALE_IDENTITY) * 2.0f - 1.0f;
|
||||
if (ratio < 0.0f)
|
||||
ratio = 0.0f;
|
||||
else if (ratio > 1.0f)
|
||||
ratio = 1.0f;
|
||||
|
||||
size->width = (int)((src->w - mipmap->w) * ratio + mipmap->w);
|
||||
size->height = (int)((src->h - mipmap->h) * ratio + mipmap->h);
|
||||
}
|
||||
|
||||
if (!size->width && src->w)
|
||||
size->width = 1;
|
||||
if (!size->height && src->h)
|
||||
@@ -280,7 +344,7 @@ TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, int scale, PEXTENT size)
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawCanvas_Rescale (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, EXTENT size)
|
||||
TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, EXTENT size)
|
||||
{
|
||||
SDL_Surface *src = (SDL_Surface *)src_canvas;
|
||||
SDL_Surface *dst = (SDL_Surface *)dest_canvas;
|
||||
@@ -382,3 +446,377 @@ TFB_DrawCanvas_Rescale (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, EXTENT si
|
||||
SDL_UnlockSurface (dst);
|
||||
SDL_UnlockSurface (src);
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, TFB_Canvas src_mipmap, EXTENT size)
|
||||
{
|
||||
// TODO: this can be optimized a lot..
|
||||
// - make everything integer-only, use lookup tables, read/modify
|
||||
// pixels directly instead of SDL_GetRGB(), etc.
|
||||
|
||||
SDL_Surface *src = (SDL_Surface *)src_canvas;
|
||||
SDL_Surface *dst = (SDL_Surface *)dest_canvas;
|
||||
SDL_Surface *mipmap = (SDL_Surface *)src_mipmap;
|
||||
const int w = size.width, h = size.height;
|
||||
const int ALPHA_THRESHOLD = 128;
|
||||
|
||||
float ratio = ((float)w / src->w) * 2.0f - 1.0f;
|
||||
float om_ratio;
|
||||
if (ratio < 0.0f)
|
||||
ratio = 0.0f;
|
||||
if (ratio > 1.0f)
|
||||
ratio = 1.0f;
|
||||
om_ratio = 1.0f - ratio;
|
||||
|
||||
if (size.width > dst->w || size.height > dst->h)
|
||||
{
|
||||
fprintf (stderr, "TFB_DrawCanvas_Rescale_Trilinear: Tried to scale image to size %d %d when dest_canvas has only dimensions of %d %d! Failing.\n",
|
||||
size.width, size.height, dst->w, dst->h);
|
||||
return;
|
||||
}
|
||||
|
||||
if (src->format->BytesPerPixel == 1 && dst->format->BytesPerPixel == 4 &&
|
||||
mipmap->format->BytesPerPixel == 1)
|
||||
{
|
||||
float fsx0 = (float)src->w / w;
|
||||
float fsy0 = (float)src->h / h;
|
||||
float fsx1 = (float)mipmap->w / w;
|
||||
float fsy1 = (float)mipmap->h / h;
|
||||
float v0 = 0.0f;
|
||||
float v1 = 0.0f;
|
||||
Uint32 ck0 = src->format->colorkey;
|
||||
Uint32 ck1 = mipmap->format->colorkey;
|
||||
int x, y;
|
||||
|
||||
SDL_LockSurface(src);
|
||||
SDL_LockSurface(dst);
|
||||
SDL_LockSurface(mipmap);
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
float u0 = 0.0f;
|
||||
float u1 = 0.0f;
|
||||
int iv0 = (int)v0;
|
||||
int iv1 = (int)v1;
|
||||
float decy0 = v0 - iv0;
|
||||
float decy1 = v1 - iv1;
|
||||
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
int iu0 = (int)u0;
|
||||
int iu1 = (int)u1;
|
||||
float decx0 = u0 - iu0;
|
||||
float decx1 = u1 - iu1;
|
||||
float ul0 = (1.0f - decx0) * (1.0f - decy0);
|
||||
float ul1 = (1.0f - decx1) * (1.0f - decy1);
|
||||
float ur0 = decx0 * (1.0f - decy0);
|
||||
float ur1 = decx1 * (1.0f - decy1);
|
||||
float ll0 = (1.0f - decx0) * decy0;
|
||||
float ll1 = (1.0f - decx1) * decy1;
|
||||
float lr0 = decx0 * decy0;
|
||||
float lr1 = decx1 * decy1;
|
||||
|
||||
Uint8 r0[5], r1[5], g0[5], g1[5], b0[5], b1[5], a0[5], a1[5];
|
||||
Uint8 c;
|
||||
|
||||
Uint8 *src_p0 = (Uint8 *)src->pixels + iv0 * src->pitch + iu0;
|
||||
Uint8 *src_p1 = (Uint8 *)mipmap->pixels + iv1 * mipmap->pitch + iu1;
|
||||
Uint32 *dst_p = (Uint32 *)dst->pixels + y * dst->w + x;
|
||||
|
||||
if (iu0 <= src->w - 2)
|
||||
{
|
||||
a0[0] = ((c = *src_p0) == ck0) ? 0 : 255;
|
||||
SDL_GetRGB (c, src->format, &r0[0], &g0[0], &b0[0]);
|
||||
a0[1] = ((c = *(src_p0 + 1)) == ck0) ? 0 : 255;
|
||||
SDL_GetRGB (c, src->format, &r0[1], &g0[1], &b0[1]);
|
||||
if (iv0 <= src->h - 2)
|
||||
{
|
||||
a0[2] = ((c = *(src_p0 + src->pitch)) == ck0) ? 0 : 255;
|
||||
SDL_GetRGB (c, src->format, &r0[2], &g0[2], &b0[2]);
|
||||
a0[3] = ((c = *(src_p0 + src->pitch + 1)) == ck0) ? 0 : 255;
|
||||
SDL_GetRGB (c, src->format, &r0[3], &g0[3], &b0[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
r0[2] = r0[0];
|
||||
g0[2] = g0[0];
|
||||
b0[2] = b0[0];
|
||||
a0[2] = a0[0];
|
||||
r0[3] = r0[1];
|
||||
g0[3] = g0[1];
|
||||
b0[3] = b0[1];
|
||||
a0[3] = a0[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a0[0] = ((c = *src_p0) == ck0) ? 0 : 255;
|
||||
SDL_GetRGB (c, src->format, &r0[0], &g0[0], &b0[0]);
|
||||
r0[1] = r0[0];
|
||||
g0[1] = g0[0];
|
||||
b0[1] = b0[0];
|
||||
a0[1] = a0[0];
|
||||
if (iv0 <= src->h - 2)
|
||||
{
|
||||
a0[2] = ((c = *(src_p0 + src->pitch)) == ck0) ? 0 : 255;
|
||||
SDL_GetRGB (c, src->format, &r0[2], &g0[2], &b0[2]);
|
||||
r0[3] = r0[2];
|
||||
g0[3] = g0[2];
|
||||
b0[3] = b0[2];
|
||||
a0[3] = a0[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
r0[2] = r0[3] = r0[0];
|
||||
g0[2] = g0[3] = g0[0];
|
||||
b0[2] = b0[3] = b0[0];
|
||||
a0[2] = a0[3] = a0[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (iu1 <= mipmap->w - 2)
|
||||
{
|
||||
a1[0] = ((c = *src_p1) == ck1) ? 0 : 255;
|
||||
SDL_GetRGB (c, mipmap->format, &r1[0], &g1[0], &b1[0]);
|
||||
a1[1] = ((c = *(src_p1 + 1)) == ck1) ? 0 : 255;
|
||||
SDL_GetRGB (c, mipmap->format, &r1[1], &g1[1], &b1[1]);
|
||||
if (iv1 <= mipmap->h - 2)
|
||||
{
|
||||
a1[2] = ((c = *(src_p1 + mipmap->pitch)) == ck1) ? 0 : 255;
|
||||
SDL_GetRGB (c, mipmap->format, &r1[2], &g1[2], &b1[2]);
|
||||
a1[3] = ((c = *(src_p1 + mipmap->pitch + 1)) == ck1) ? 0 : 255;
|
||||
SDL_GetRGB (c, mipmap->format, &r1[3], &g1[3], &b1[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
r1[2] = r1[0];
|
||||
g1[2] = g1[0];
|
||||
b1[2] = b1[0];
|
||||
a1[2] = a1[0];
|
||||
r1[3] = r1[1];
|
||||
g1[3] = g1[1];
|
||||
b1[3] = b1[1];
|
||||
a1[3] = a1[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
a1[0] = ((c = *src_p1) == ck1) ? 0 : 255;
|
||||
SDL_GetRGB (c, mipmap->format, &r1[0], &g1[0], &b1[0]);
|
||||
r1[1] = r1[0];
|
||||
g1[1] = g1[0];
|
||||
b1[1] = b1[0];
|
||||
a1[1] = a1[0];
|
||||
if (iv1 <= mipmap->h - 2)
|
||||
{
|
||||
a1[2] = ((c = *(src_p1 + mipmap->pitch)) == ck1) ? 0 : 255;
|
||||
SDL_GetRGB (c, mipmap->format, &r1[2], &g1[2], &b1[2]);
|
||||
r1[3] = r1[2];
|
||||
g1[3] = g1[2];
|
||||
b1[3] = b1[2];
|
||||
a1[3] = a1[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
r1[2] = r1[3] = r1[0];
|
||||
g1[2] = g1[3] = g1[0];
|
||||
b1[2] = b1[3] = b1[0];
|
||||
a1[2] = a1[3] = a1[0];
|
||||
}
|
||||
}
|
||||
|
||||
r0[4] = (Uint8)(ul0 * r0[0] + ur0 * r0[1] + ll0 * r0[2] + lr0 * r0[3]);
|
||||
g0[4] = (Uint8)(ul0 * g0[0] + ur0 * g0[1] + ll0 * g0[2] + lr0 * g0[3]);
|
||||
b0[4] = (Uint8)(ul0 * b0[0] + ur0 * b0[1] + ll0 * b0[2] + lr0 * b0[3]);
|
||||
a0[4] = (Uint8)(ul0 * a0[0] + ur0 * a0[1] + ll0 * a0[2] + lr0 * a0[3]);
|
||||
|
||||
r1[4] = (Uint8)(ul1 * r1[0] + ur1 * r1[1] + ll1 * r1[2] + lr1 * r1[3]);
|
||||
g1[4] = (Uint8)(ul1 * g1[0] + ur1 * g1[1] + ll1 * g1[2] + lr1 * g1[3]);
|
||||
b1[4] = (Uint8)(ul1 * b1[0] + ur1 * b1[1] + ll1 * b1[2] + lr1 * b1[3]);
|
||||
a1[4] = (Uint8)(ul1 * a1[0] + ur1 * a1[1] + ll1 * a1[2] + lr1 * a1[3]);
|
||||
|
||||
*dst_p = SDL_MapRGBA(dst->format,
|
||||
(Uint8)(ratio * r0[4] + om_ratio * r1[4]),
|
||||
(Uint8)(ratio * g0[4] + om_ratio * g1[4]),
|
||||
(Uint8)(ratio * b0[4] + om_ratio * b1[4]),
|
||||
(Uint8)((ratio * a0[4] + om_ratio * a1[4]) > ALPHA_THRESHOLD ? 255 : 0));
|
||||
|
||||
u0 += fsx0;
|
||||
u1 += fsx1;
|
||||
}
|
||||
v0 += fsy0;
|
||||
v1 += fsy1;
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(mipmap);
|
||||
SDL_UnlockSurface(dst);
|
||||
SDL_UnlockSurface(src);
|
||||
}
|
||||
else if (src->format->BytesPerPixel == 4 && dst->format->BytesPerPixel == 4 &&
|
||||
mipmap->format->BytesPerPixel == 4)
|
||||
{
|
||||
float fsx0 = (float)src->w / w;
|
||||
float fsy0 = (float)src->h / h;
|
||||
float fsx1 = (float)mipmap->w / w;
|
||||
float fsy1 = (float)mipmap->h / h;
|
||||
float v0 = 0.0f;
|
||||
float v1 = 0.0f;
|
||||
int x, y;
|
||||
|
||||
SDL_LockSurface(src);
|
||||
SDL_LockSurface(dst);
|
||||
SDL_LockSurface(mipmap);
|
||||
|
||||
for (y = 0; y < h; ++y)
|
||||
{
|
||||
float u0 = 0.0f;
|
||||
float u1 = 0.0f;
|
||||
int iv0 = (int)v0;
|
||||
int iv1 = (int)v1;
|
||||
float decy0 = v0 - iv0;
|
||||
float decy1 = v1 - iv1;
|
||||
|
||||
for (x = 0; x < w; ++x)
|
||||
{
|
||||
int iu0 = (int)u0;
|
||||
int iu1 = (int)u1;
|
||||
float decx0 = u0 - iu0;
|
||||
float decx1 = u1 - iu1;
|
||||
float ul0 = (1.0f - decx0) * (1.0f - decy0);
|
||||
float ul1 = (1.0f - decx1) * (1.0f - decy1);
|
||||
float ur0 = decx0 * (1.0f - decy0);
|
||||
float ur1 = decx1 * (1.0f - decy1);
|
||||
float ll0 = (1.0f - decx0) * decy0;
|
||||
float ll1 = (1.0f - decx1) * decy1;
|
||||
float lr0 = decx0 * decy0;
|
||||
float lr1 = decx1 * decy1;
|
||||
|
||||
Uint8 r0[5], r1[5], g0[5], g1[5], b0[5], b1[5], a0[5], a1[5];
|
||||
|
||||
Uint32 *src_p0 = (Uint32 *)src->pixels + iv0 * src->w + iu0;
|
||||
Uint32 *src_p1 = (Uint32 *)mipmap->pixels + iv1 * mipmap->w + iu1;
|
||||
Uint32 *dst_p = (Uint32 *)dst->pixels + y * dst->w + x;
|
||||
|
||||
if (iu0 <= src->w - 2)
|
||||
{
|
||||
SDL_GetRGBA (*src_p0, src->format, &r0[0], &g0[0], &b0[0], &a0[0]);
|
||||
SDL_GetRGBA (*(src_p0 + 1), src->format, &r0[1], &g0[1], &b0[1], &a0[1]);
|
||||
if (iv0 <= src->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p0 + src->w), src->format, &r0[2], &g0[2], &b0[2], &a0[2]);
|
||||
SDL_GetRGBA (*(src_p0 + src->w + 1), src->format, &r0[3], &g0[3], &b0[3], &a0[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
r0[2] = r0[0];
|
||||
g0[2] = g0[0];
|
||||
b0[2] = b0[0];
|
||||
a0[2] = a0[0];
|
||||
r0[3] = r0[1];
|
||||
g0[3] = g0[1];
|
||||
b0[3] = b0[1];
|
||||
a0[3] = a0[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_GetRGBA (*src_p0, src->format, &r0[0], &g0[0], &b0[0], &a0[0]);
|
||||
r0[1] = r0[0];
|
||||
g0[1] = g0[0];
|
||||
b0[1] = b0[0];
|
||||
a0[1] = a0[0];
|
||||
if (iv0 <= src->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p0 + src->w), src->format, &r0[2], &g0[2], &b0[2], &a0[2]);
|
||||
r0[3] = r0[2];
|
||||
g0[3] = g0[2];
|
||||
b0[3] = b0[2];
|
||||
a0[3] = a0[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
r0[2] = r0[3] = r0[0];
|
||||
g0[2] = g0[3] = g0[0];
|
||||
b0[2] = b0[3] = b0[0];
|
||||
a0[2] = a0[3] = a0[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (iu1 <= mipmap->w - 2)
|
||||
{
|
||||
SDL_GetRGBA (*src_p1, mipmap->format, &r1[0], &g1[0], &b1[0], &a1[0]);
|
||||
SDL_GetRGBA (*(src_p1 + 1), mipmap->format, &r1[1], &g1[1], &b1[1], &a1[1]);
|
||||
if (iv1 <= mipmap->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p1 + mipmap->w) , mipmap->format, &r1[2], &g1[2], &b1[2], &a1[2]);
|
||||
SDL_GetRGBA (*(src_p1 + mipmap->w + 1), mipmap->format, &r1[3], &g1[3], &b1[3], &a1[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
r1[2] = r1[0];
|
||||
g1[2] = g1[0];
|
||||
b1[2] = b1[0];
|
||||
a1[2] = a1[0];
|
||||
r1[3] = r1[1];
|
||||
g1[3] = g1[1];
|
||||
b1[3] = b1[1];
|
||||
a1[3] = a1[1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
SDL_GetRGBA (*src_p1, mipmap->format, &r1[0], &g1[0], &b1[0], &a1[0]);
|
||||
r1[1] = r1[0];
|
||||
g1[1] = g1[0];
|
||||
b1[1] = b1[0];
|
||||
a1[1] = a1[0];
|
||||
if (iv1 <= mipmap->h - 2)
|
||||
{
|
||||
SDL_GetRGBA (*(src_p1 + mipmap->w), mipmap->format, &r1[2], &g1[2], &b1[2], &a1[2]);
|
||||
r1[3] = r1[2];
|
||||
g1[3] = g1[2];
|
||||
b1[3] = b1[2];
|
||||
a1[3] = a1[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
r1[2] = r1[3] = r1[0];
|
||||
g1[2] = g1[3] = g1[0];
|
||||
b1[2] = b1[3] = b1[0];
|
||||
a1[2] = a1[3] = a1[0];
|
||||
}
|
||||
}
|
||||
|
||||
r0[4] = (Uint8)(ul0 * r0[0] + ur0 * r0[1] + ll0 * r0[2] + lr0 * r0[3]);
|
||||
g0[4] = (Uint8)(ul0 * g0[0] + ur0 * g0[1] + ll0 * g0[2] + lr0 * g0[3]);
|
||||
b0[4] = (Uint8)(ul0 * b0[0] + ur0 * b0[1] + ll0 * b0[2] + lr0 * b0[3]);
|
||||
a0[4] = (Uint8)(ul0 * a0[0] + ur0 * a0[1] + ll0 * a0[2] + lr0 * a0[3]);
|
||||
|
||||
r1[4] = (Uint8)(ul1 * r1[0] + ur1 * r1[1] + ll1 * r1[2] + lr1 * r1[3]);
|
||||
g1[4] = (Uint8)(ul1 * g1[0] + ur1 * g1[1] + ll1 * g1[2] + lr1 * g1[3]);
|
||||
b1[4] = (Uint8)(ul1 * b1[0] + ur1 * b1[1] + ll1 * b1[2] + lr1 * b1[3]);
|
||||
a1[4] = (Uint8)(ul1 * a1[0] + ur1 * a1[1] + ll1 * a1[2] + lr1 * a1[3]);
|
||||
|
||||
*dst_p = SDL_MapRGBA(dst->format,
|
||||
(Uint8)(ratio * r0[4] + om_ratio * r1[4]),
|
||||
(Uint8)(ratio * g0[4] + om_ratio * g1[4]),
|
||||
(Uint8)(ratio * b0[4] + om_ratio * b1[4]),
|
||||
(Uint8)((ratio * a0[4] + om_ratio * a1[4]) > ALPHA_THRESHOLD ? 255 : 0));
|
||||
|
||||
u0 += fsx0;
|
||||
u1 += fsx1;
|
||||
}
|
||||
v0 += fsy0;
|
||||
v1 += fsy1;
|
||||
}
|
||||
|
||||
SDL_UnlockSurface(mipmap);
|
||||
SDL_UnlockSurface(dst);
|
||||
SDL_UnlockSurface(src);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, "Tried to deal with unknown BPP: %d -> %d, mipmap %d\n",
|
||||
src->format->BitsPerPixel, dst->format->BitsPerPixel, mipmap->format->BitsPerPixel);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +86,6 @@ TFB_DrawScreen_Image (TFB_Image *img, int x, int y, int scale, TFB_Palette *pale
|
||||
DC.data.image.y = y;
|
||||
DC.data.image.scale = (scale == GSCALE_IDENTITY) ? 0 : scale;
|
||||
|
||||
|
||||
if (palette != NULL)
|
||||
{
|
||||
int i, changed;
|
||||
@@ -250,7 +249,9 @@ TFB_DrawImage_New (TFB_Canvas canvas)
|
||||
TFB_Image *img = HMalloc (sizeof (TFB_Image));
|
||||
img->mutex = CreateMutex ();
|
||||
img->ScaledImg = NULL;
|
||||
img->MipmapImg = NULL;
|
||||
img->colormap_index = -1;
|
||||
img->last_scale_type = -1;
|
||||
|
||||
img->Palette = TFB_DrawCanvas_ExtractPalette (canvas);
|
||||
|
||||
@@ -293,29 +294,24 @@ TFB_DrawImage_Delete (TFB_Image *image)
|
||||
}
|
||||
|
||||
void
|
||||
TFB_DrawImage_FixScaling (TFB_Image *image, int target)
|
||||
TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type)
|
||||
{
|
||||
EXTENT old = image->extent;
|
||||
TFB_DrawCanvas_GetScaledExtent (image->NormalImg, target, &image->extent);
|
||||
|
||||
TFB_DrawCanvas_GetScaledExtent (image->NormalImg, image->MipmapImg, target, &image->extent);
|
||||
|
||||
if ((old.width != image->extent.width) || (old.height != image->extent.height) ||
|
||||
image->dirty || !image->ScaledImg)
|
||||
image->dirty || !image->ScaledImg || type != image->last_scale_type)
|
||||
{
|
||||
image->dirty = FALSE;
|
||||
if (!image->ScaledImg)
|
||||
image->ScaledImg = TFB_DrawCanvas_New_ScaleTarget (image->NormalImg);
|
||||
TFB_DrawCanvas_Rescale (image->NormalImg, image->ScaledImg, image->extent);
|
||||
}
|
||||
/*
|
||||
if (TFB_DrawCanvas_IsPaletted (image->ScaledImg))
|
||||
{
|
||||
int colorkey = TFB_DrawCanvas_GetTransparentIndex (image->NormalImg);
|
||||
image->ScaledImg = TFB_DrawCanvas_New_ScaleTarget (image->NormalImg,
|
||||
image->ScaledImg, type, image->last_scale_type);
|
||||
image->last_scale_type = type;
|
||||
|
||||
TFB_DrawCanvas_SetPalette (image->ScaledImg, image->Palette);
|
||||
if (colorkey != -1)
|
||||
{
|
||||
TFB_DrawCanvas_SetTransparentIndex (image->ScaledImg, colorkey);
|
||||
}
|
||||
if (type == TFB_SCALE_NEAREST)
|
||||
TFB_DrawCanvas_Rescale_Nearest (image->NormalImg, image->ScaledImg,
|
||||
image->extent);
|
||||
else
|
||||
TFB_DrawCanvas_Rescale_Trilinear (image->NormalImg, image->ScaledImg,
|
||||
image->MipmapImg, image->extent);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ typedef enum {
|
||||
TFB_GFX_NUMSCREENS
|
||||
} SCREEN;
|
||||
|
||||
typedef enum {
|
||||
TFB_SCALE_NEAREST,
|
||||
TFB_SCALE_TRILINEAR
|
||||
} SCALE;
|
||||
|
||||
typedef struct tfb_palette
|
||||
{
|
||||
UBYTE r;
|
||||
@@ -43,8 +48,10 @@ typedef struct tfb_image
|
||||
{
|
||||
TFB_Canvas NormalImg;
|
||||
TFB_Canvas ScaledImg;
|
||||
TFB_Canvas MipmapImg;
|
||||
TFB_Palette *Palette;
|
||||
int colormap_index;
|
||||
int last_scale_type;
|
||||
EXTENT extent;
|
||||
Mutex mutex;
|
||||
BOOLEAN dirty;
|
||||
@@ -66,7 +73,7 @@ void TFB_FlushPaletteCache (void);
|
||||
|
||||
TFB_Image *TFB_DrawImage_New (TFB_Canvas canvas);
|
||||
void TFB_DrawImage_Delete (TFB_Image *image);
|
||||
void TFB_DrawImage_FixScaling (TFB_Image *image, int target);
|
||||
void TFB_DrawImage_FixScaling (TFB_Image *image, int target, int type);
|
||||
|
||||
void TFB_DrawImage_Line (int x1, int y1, int x2, int y2, int r, int g, int b, TFB_Image *dest);
|
||||
void TFB_DrawImage_Rect (PRECT rect, int r, int g, int b, TFB_Image *image);
|
||||
@@ -75,13 +82,12 @@ void TFB_DrawImage_FilledImage (TFB_Image *img, int x, int y, int scale, int r,
|
||||
|
||||
TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN hasalpha);
|
||||
TFB_Canvas TFB_DrawCanvas_New_Paletted (int w, int h, TFB_Palette *palette, int transparent_index);
|
||||
TFB_Canvas TFB_DrawCanvas_New_Scaled (TFB_Canvas src, int scale);
|
||||
TFB_Canvas TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas);
|
||||
TFB_Canvas TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int type, int last_type);
|
||||
TFB_Canvas TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas);
|
||||
BOOLEAN TFB_DrawCanvas_IsPaletted (TFB_Canvas canvas);
|
||||
void TFB_DrawCanvas_Rescale (TFB_Canvas src, TFB_Canvas dst, EXTENT size);
|
||||
void TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, int scale, PEXTENT size);
|
||||
|
||||
void TFB_DrawCanvas_Rescale_Nearest (TFB_Canvas src, TFB_Canvas dst, EXTENT size);
|
||||
void TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src, TFB_Canvas dst, TFB_Canvas mipmap, EXTENT size);
|
||||
void TFB_DrawCanvas_GetScaledExtent (TFB_Canvas src_canvas, TFB_Canvas src_mipmap, int scale, PEXTENT size);
|
||||
|
||||
void TFB_DrawCanvas_Delete (TFB_Canvas canvas);
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "starcon.h"
|
||||
#include "libs/graphics/gfx_common.h"
|
||||
#include "libs/graphics/drawable.h"
|
||||
|
||||
COUNT DisplayFreeList;
|
||||
PRIMITIVE DisplayArray[MAX_DISPLAY_PRIMS];
|
||||
@@ -980,6 +981,20 @@ PostProcessQueue (register VIEW_STATE view_state, register SIZE scroll_x,
|
||||
[index],
|
||||
ElementPtr->next.image.frame);
|
||||
#endif /* SAFE */
|
||||
|
||||
if (index < 2 && scale != 256)
|
||||
{
|
||||
// assigns next (smaller) zoom level image as mipmap, needed for trilinear scaling
|
||||
((PFRAME_DESC)ElementPtr->next.image.frame)->image->MipmapImg =
|
||||
((PFRAME_DESC)SetEquFrameIndex (
|
||||
ElementPtr->next.image.farray
|
||||
[index + 1],
|
||||
ElementPtr->next.image.frame))->image->NormalImg;
|
||||
}
|
||||
else
|
||||
{
|
||||
((PFRAME_DESC)ElementPtr->next.image.frame)->image->MipmapImg = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
DisplayArray[ElementPtr->PrimIndex].Object.Stamp.frame =
|
||||
|
||||
+11
-3
@@ -108,6 +108,7 @@ main (int argc, char *argv[])
|
||||
{"fullscreen", 0, NULL, 'f'},
|
||||
{"opengl", 0, NULL, 'o'},
|
||||
{"scale", 1, NULL, 'c'},
|
||||
{"meleescale", 1, NULL, 'b'},
|
||||
{"scanlines", 0, NULL, 's'},
|
||||
{"fps", 0, NULL, 'p'},
|
||||
{"contentdir", 1, NULL, 'n'},
|
||||
@@ -140,7 +141,7 @@ main (int argc, char *argv[])
|
||||
strcpy (contentdir, "content");
|
||||
#endif
|
||||
|
||||
while ((c = getopt_long(argc, argv, "r:d:foc:spn:?hM:S:T:m:q:ug:", long_options, &option_index)) != -1)
|
||||
while ((c = getopt_long(argc, argv, "r:d:foc:b:spn:?hM:S:T:m:q:ug:", long_options, &option_index)) != -1)
|
||||
{
|
||||
switch (c) {
|
||||
case 'r':
|
||||
@@ -169,6 +170,12 @@ main (int argc, char *argv[])
|
||||
gfxflags |= TFB_GFXFLAGS_SCALE_BIADAPTADV;
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
if (!strcmp (optarg, "nearest"))
|
||||
optMeleeScale = TFB_SCALE_NEAREST;
|
||||
else if (!strcmp (optarg, "trilinear"))
|
||||
optMeleeScale = TFB_SCALE_TRILINEAR;
|
||||
break;
|
||||
case 's':
|
||||
gfxflags |= TFB_GFXFLAGS_SCANLINES;
|
||||
break;
|
||||
@@ -279,7 +286,8 @@ main (int argc, char *argv[])
|
||||
printf(" -d, --bpp=BITSPERPIXEL (default 16)\n");
|
||||
printf(" -f, --fullscreen (default off)\n");
|
||||
printf(" -o, --opengl (default off)\n");
|
||||
printf(" -c, --scale=mode (bilinear, biadapt or biadv, default is none)\n");
|
||||
printf(" -c, --scale=MODE (bilinear, biadapt or biadv, default is none)\n");
|
||||
printf(" -b, --meleescale=MODE (nearest or trilinear, default is trilinear)\n");
|
||||
printf(" -s, --scanlines (default off)\n");
|
||||
printf(" -p, --fps (default off)\n");
|
||||
printf(" -g, --gamma=CORRECTIONVALUE (default 1.0, which causes no change)\n");
|
||||
@@ -288,8 +296,8 @@ main (int argc, char *argv[])
|
||||
printf(" -S, --sfxvol=VOLUME (0-100, default 100)\n");
|
||||
printf(" -T, --speechvol=VOLUME (0-100, default 100)\n");
|
||||
printf(" -q, --audioquality=QUALITY (high, medium or low, default medium)\n");
|
||||
printf(" --sound=DRIVER (openal, mixsdl, none; default mixsdl)\n");
|
||||
printf(" -u, --nosubtitles\n");
|
||||
printf(" --sound=DRIVER (openal, mixsdl, none; default mixsdl)\n");
|
||||
printf("The following options can take either '3do' or 'pc' as an option:\n");
|
||||
printf(" -m, --music : Music version (default 3do)\n");
|
||||
printf(" --cscan : coarse-scan display, pc=text, 3do=hieroglyphs (default 3do)\n");
|
||||
|
||||
Reference in New Issue
Block a user