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:
gewlitys
2003-03-15 21:40:09 +00:00
parent f9e2747507
commit e6a8d4fe7c
10 changed files with 519 additions and 45 deletions
+2
View File
@@ -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
+6
View File
@@ -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.
+2
View File
@@ -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;
+1
View File
@@ -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));
+454 -16
View File
@@ -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);
}
}
+14 -18
View File
@@ -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);
}
*/
}
+12 -6
View File
@@ -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);
+15
View File
@@ -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
View File
@@ -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");