From 412e9620744294aea8bf6ac751bf0b0b28562c74 Mon Sep 17 00:00:00 2001 From: avolkov Date: Mon, 7 Nov 2005 21:22:53 +0000 Subject: [PATCH] Gfx engine changes: always 32bpp internally (facilitates alpha channel usage), optimized and asm scaler code, only using alpha channel where needed (speed gain) git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1964 8092fc87-c524-0410-9efc-e669fe64eaf9 --- sc2/src/msvc++/UrQuanMasters.dsp | 153 +- sc2/src/sc2code/libs/gfxlib.h | 1 + sc2/src/sc2code/libs/graphics/drawable.c | 3 +- sc2/src/sc2code/libs/graphics/sdl/2xscalers.c | 3279 +---------------- sc2/src/sc2code/libs/graphics/sdl/2xscalers.h | 8 +- .../sc2code/libs/graphics/sdl/3do_getbody.c | 4 +- sc2/src/sc2code/libs/graphics/sdl/Makeinfo | 5 +- sc2/src/sc2code/libs/graphics/sdl/canvas.c | 32 +- sc2/src/sc2code/libs/graphics/sdl/opengl.c | 157 +- sc2/src/sc2code/libs/graphics/sdl/opengl.h | 1 - sc2/src/sc2code/libs/graphics/sdl/pure.c | 280 +- .../sc2code/libs/graphics/sdl/sdl_common.c | 34 +- .../sc2code/libs/graphics/sdl/sdl_common.h | 2 + sc2/src/sc2code/planets/plangen.c | 6 +- sc2/src/sc2code/uqmdebug.c | 3 + sc2/src/starcon2.c | 29 +- 16 files changed, 644 insertions(+), 3353 deletions(-) diff --git a/sc2/src/msvc++/UrQuanMasters.dsp b/sc2/src/msvc++/UrQuanMasters.dsp index 9b1926b53..85e2ea45a 100644 --- a/sc2/src/msvc++/UrQuanMasters.dsp +++ b/sc2/src/msvc++/UrQuanMasters.dsp @@ -4,7 +4,7 @@ # TARGTYPE "Win32 (x86) Console Application" 0x0103 -CFG=UrQuanMasters - Win32 Debug +CFG=URQUANMASTERS - WIN32 DEBUG !MESSAGE This is not a valid makefile. To build this project using NMAKE, !MESSAGE use the Export Makefile command and run !MESSAGE @@ -13,19 +13,20 @@ CFG=UrQuanMasters - Win32 Debug !MESSAGE You can specify a configuration when running NMAKE !MESSAGE by defining the macro CFG on the command line. For example: !MESSAGE -!MESSAGE NMAKE /f "UrQuanMasters.mak" CFG="UrQuanMasters - Win32 Debug" +!MESSAGE NMAKE /f "UrQuanMasters.mak" CFG="URQUANMASTERS - WIN32 DEBUG" !MESSAGE !MESSAGE Possible choices for configuration are: !MESSAGE !MESSAGE "UrQuanMasters - Win32 Release" (based on "Win32 (x86) Console Application") !MESSAGE "UrQuanMasters - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "UrQuanMasters - Win32 Release NoAL" (based on "Win32 (x86) Console Application") !MESSAGE # Begin Project # PROP AllowPerConfigDependencies 0 # PROP Scc_ProjName "" # PROP Scc_LocalPath "" -CPP=cl.exe +CPP=xicl6.exe RSC=rc.exe !IF "$(CFG)" == "UrQuanMasters - Win32 Release" @@ -42,14 +43,14 @@ RSC=rc.exe # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /I "..\regex" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "ZLIB_DLL" /FD /c +# ADD CPP /nologo /G6 /MD /W3 /GX /Zi /O2 /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /I "..\regex" /D "NDEBUG" /D "USE_PLATFORM_ACCEL" /D "USE_DEBUG_KEY" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "ZLIB_DLL" /FD /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "NDEBUG" # ADD RSC /l 0x409 /d "NDEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo -LINK32=link.exe +LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib zdll.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /out:"../../uqm.exe" # Begin Special Build Tool @@ -72,24 +73,57 @@ PostBuild_Cmds=rebase -b 0x400000 -x . "../../uqm.exe" # PROP Ignore_Export_Lib 0 # PROP Target_Dir "" # ADD BASE CPP /nologo /W3 /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /I "..\regex" /D "DEBUG" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "ZLIB_DLL" /FR /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /GX /Zi /Od /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /I "..\regex" /D "DEBUG" /D "_DEBUG" /D "DEBUG_TRACK_SEM" /D "USE_PLATFORM_ACCEL" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "ZLIB_DLL" /FR /FD /GZ /c # SUBTRACT CPP /YX # ADD BASE RSC /l 0x409 /d "_DEBUG" # ADD RSC /l 0x409 /d "_DEBUG" BSC32=bscmake.exe # ADD BASE BSC32 /nologo # ADD BSC32 /nologo /o"UrQuanMasters.bsc" -LINK32=link.exe +LINK32=xilink6.exe # ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept # ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib zdll.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"msvcrt.lib" /out:"../../uqmdebug.exe" /pdbtype:sept # SUBTRACT LINK32 /nodefaultlib +!ELSEIF "$(CFG)" == "UrQuanMasters - Win32 Release NoAL" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "UrQuanMasters___Win32_Release_NoAL" +# PROP BASE Intermediate_Dir "UrQuanMasters___Win32_Release_NoAL" +# PROP BASE Ignore_Export_Lib 0 +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release_NoAL" +# PROP Intermediate_Dir "Release_NoAL" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /MD /W3 /GX /Zi /O2 /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /I "..\regex" /D "NDEBUG" /D "USE_PLATFORM_ACCEL" /D "USE_DEBUG_KEY" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_OPENAL" /D "HAVE_ZIP" /D "ZLIB_DLL" /FD /c +# SUBTRACT BASE CPP /YX +# ADD CPP /nologo /MD /W3 /GX /Zi /O2 /I "." /I ".." /I "..\sc2code" /I "..\sc2code\libs" /I "..\sc2code\ships" /I "..\regex" /D "NDEBUG" /D "USE_PLATFORM_ACCEL" /D "USE_DEBUG_KEY" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D _VW=320 /D _VH=240 /D "HAVE_OPENGL" /D "GFXMODULE_SDL" /D "HAVE_ZIP" /D "ZLIB_DLL" /FD /c +# SUBTRACT CPP /YX +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=xilink6.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib zdll.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /out:"../../uqm.exe" +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib SDL.lib SDLmain.lib SDL_image.lib zdll.lib /nologo /subsystem:console /pdb:none /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /out:"../../uqm.exe" +# Begin Special Build Tool +SOURCE="$(InputPath)" +PostBuild_Desc=Stripping debug info... +PostBuild_Cmds=rebase -b 0x400000 -x . "../../uqm.exe" +# End Special Build Tool + !ENDIF # Begin Target # Name "UrQuanMasters - Win32 Release" # Name "UrQuanMasters - Win32 Debug" +# Name "UrQuanMasters - Win32 Release NoAL" # Begin Group "Source Files" # PROP Default_Filter "" @@ -186,10 +220,6 @@ SOURCE=..\sc2code\libs\file\temp.c # Begin Group "graphics" # PROP Default_Filter "" -# Begin Source File - -SOURCE=..\sc2code\libs\graphics\prim.h -# End Source File # Begin Group "sdl" # PROP Default_Filter "" @@ -203,6 +233,22 @@ SOURCE=..\sc2code\libs\graphics\sdl\2xscalers.h # End Source File # Begin Source File +SOURCE=..\sc2code\libs\graphics\sdl\2xscalers_3dnow.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\2xscalers_mmx.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\2xscalers_mmx.h +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\2xscalers_sse.c +# End Source File +# Begin Source File + SOURCE=..\sc2code\libs\graphics\sdl\3do_blt.c # End Source File # Begin Source File @@ -223,6 +269,14 @@ SOURCE=..\sc2code\libs\graphics\sdl\bbox.h # End Source File # Begin Source File +SOURCE=..\sc2code\libs\graphics\sdl\biadv2x.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\bilinear2x.c +# End Source File +# Begin Source File + SOURCE=..\sc2code\libs\graphics\sdl\canvas.c # End Source File # Begin Source File @@ -231,6 +285,14 @@ SOURCE=..\sc2code\libs\graphics\sdl\dcqueue.c # End Source File # Begin Source File +SOURCE=..\sc2code\libs\graphics\sdl\hq2x.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\nearest2x.c +# End Source File +# Begin Source File + SOURCE=..\sc2code\libs\graphics\sdl\opengl.c # End Source File # Begin Source File @@ -259,11 +321,27 @@ SOURCE=..\sc2code\libs\graphics\sdl\rndzoom.c # End Source File # Begin Source File +SOURCE=..\sc2code\libs\graphics\sdl\rotozoom.c +# End Source File +# Begin Source File + SOURCE=..\sc2code\libs\graphics\sdl\rotozoom.h # End Source File # Begin Source File -SOURCE=..\sc2code\libs\graphics\sdl\rotozoom.c +SOURCE=..\sc2code\libs\graphics\sdl\scaleint.h +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\scalemmx.h +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\scalers.c +# End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\scalers.h # End Source File # Begin Source File @@ -281,6 +359,10 @@ SOURCE=..\sc2code\libs\graphics\sdl\sdluio.c SOURCE=..\sc2code\libs\graphics\sdl\sdluio.h # End Source File +# Begin Source File + +SOURCE=..\sc2code\libs\graphics\sdl\triscan2x.c +# End Source File # End Group # Begin Source File @@ -368,6 +450,10 @@ SOURCE=..\sc2code\libs\graphics\pixmap.c # End Source File # Begin Source File +SOURCE=..\sc2code\libs\graphics\prim.h +# End Source File +# Begin Source File + SOURCE=..\sc2code\libs\graphics\resgfx.c # End Source File # Begin Source File @@ -952,6 +1038,11 @@ SOURCE=..\sc2code\libs\uio\debug.c !ELSEIF "$(CFG)" == "UrQuanMasters - Win32 Debug" +!ELSEIF "$(CFG)" == "UrQuanMasters - Win32 Release NoAL" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -1003,6 +1094,11 @@ SOURCE=..\sc2code\libs\uio\hashtable.c # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "UrQuanMasters - Win32 Release NoAL" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -1054,6 +1150,11 @@ SOURCE=..\sc2code\libs\uio\memdebug.c # PROP Exclude_From_Build 1 +!ELSEIF "$(CFG)" == "UrQuanMasters - Win32 Release NoAL" + +# PROP BASE Exclude_From_Build 1 +# PROP Exclude_From_Build 1 + !ENDIF # End Source File @@ -1160,6 +1261,10 @@ SOURCE=..\sc2code\libs\misc.h # End Source File # Begin Source File +SOURCE=..\sc2code\libs\platform.h +# End Source File +# Begin Source File + SOURCE=..\sc2code\libs\reslib.h # End Source File # Begin Source File @@ -1338,10 +1443,6 @@ SOURCE=..\sc2code\comm\comandr\restypes.h SOURCE=..\sc2code\comm\comandr\strings.h # End Source File # End Group -# Begin Source File - -SOURCE=..\sc2code\comm\commall.h -# End Source File # Begin Group "druuge.comm" # PROP Default_Filter "" @@ -2102,6 +2203,10 @@ SOURCE=..\sc2code\comm\zoqfot\strings.h SOURCE=..\sc2code\comm\zoqfot\zoqfotc.c # End Source File # End Group +# Begin Source File + +SOURCE=..\sc2code\comm\commall.h +# End Source File # End Group # Begin Group "planets" @@ -2306,10 +2411,6 @@ SOURCE=..\sc2code\planets\surface.c # Begin Group "ships" # PROP Default_Filter "" -# Begin Source File - -SOURCE=..\sc2code\ships\ship.h -# End Source File # Begin Group "androsyn" # PROP Default_Filter "" @@ -3314,6 +3415,10 @@ SOURCE=..\sc2code\ships\zoqfot\restypes.h SOURCE=..\sc2code\ships\zoqfot\zoqfot.c # End Source File # End Group +# Begin Source File + +SOURCE=..\sc2code\ships\ship.h +# End Source File # End Group # Begin Source File @@ -3709,10 +3814,6 @@ SOURCE=..\sc2code\starbase.c # End Source File # Begin Source File -SOURCE=..\sc2code\strtemp.h -# End Source File -# Begin Source File - SOURCE=..\sc2code\starbase.h # End Source File # Begin Source File @@ -3741,6 +3842,10 @@ SOURCE=..\sc2code\status.c # End Source File # Begin Source File +SOURCE=..\sc2code\strtemp.h +# End Source File +# Begin Source File + SOURCE=..\sc2code\tactrans.c # End Source File # Begin Source File diff --git a/sc2/src/sc2code/libs/gfxlib.h b/sc2/src/sc2code/libs/gfxlib.h index 9d7b99885..c9cd1309a 100644 --- a/sc2/src/sc2code/libs/gfxlib.h +++ b/sc2/src/sc2code/libs/gfxlib.h @@ -52,6 +52,7 @@ typedef BYTE CREATE_FLAGS; #define WANT_MASK (CREATE_FLAGS)(1 << 0) #define WANT_PIXMAP (CREATE_FLAGS)(1 << 1) #define MAPPED_TO_DISPLAY (CREATE_FLAGS)(1 << 2) +#define WANT_ALPHA (CREATE_FLAGS)(1 << 3) typedef struct extent { diff --git a/sc2/src/sc2code/libs/graphics/drawable.c b/sc2/src/sc2code/libs/graphics/drawable.c index fca4baa16..29d8ed36a 100644 --- a/sc2/src/sc2code/libs/graphics/drawable.c +++ b/sc2/src/sc2code/libs/graphics/drawable.c @@ -123,7 +123,8 @@ CreateDrawable (CREATE_FLAGS CreateFlags, SIZE width, SIZE height, COUNT Drawable = _request_drawable ( (COUNT)num_frames, (DRAWABLE_TYPE)RAM_DRAWABLE, - (CREATE_FLAGS)(CreateFlags & (WANT_MASK | WANT_PIXMAP | MAPPED_TO_DISPLAY)), + (CREATE_FLAGS)(CreateFlags & (WANT_MASK | WANT_PIXMAP + | WANT_ALPHA | MAPPED_TO_DISPLAY)), (SIZE)width, (SIZE)height ); if (Drawable) diff --git a/sc2/src/sc2code/libs/graphics/sdl/2xscalers.c b/sc2/src/sc2code/libs/graphics/sdl/2xscalers.c index f13785b53..84a86ae38 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/2xscalers.c +++ b/sc2/src/sc2code/libs/graphics/sdl/2xscalers.c @@ -1,4 +1,3 @@ -//Copyright Paul Reiche, Fred Ford. 1992-2002 /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,407 +17,35 @@ #ifdef GFXMODULE_SDL #include "libs/graphics/sdl/sdl_common.h" -#include "2xscalers.h" #include "types.h" +#include "scalers.h" +#include "scaleint.h" +#include "2xscalers.h" -static const Uint32 bilinear_table[4][4] = +// Scaler function lookup table +// +const Scale_FuncDef_t +Scale_C_Functions[] = { - { 9, 3, 3, 1 }, - { 3, 1, 9, 3 }, - { 3, 9, 1, 3 }, - { 1, 3, 3, 9 } + {TFB_GFXFLAGS_SCALE_BILINEAR, Scale_BilinearFilter}, + {TFB_GFXFLAGS_SCALE_BIADAPT, Scale_BiAdaptFilter}, + {TFB_GFXFLAGS_SCALE_BIADAPTADV, Scale_BiAdaptAdvFilter}, + {TFB_GFXFLAGS_SCALE_TRISCAN, Scale_TriScanFilter}, + {TFB_GFXFLAGS_SCALE_HQXX, Scale_HqFilter}, + // Default + {0, Scale_Nearest} }; -typedef union -{ - struct - { - Uint8 c1, c2, c3; - } bchan; - Uint8 channels[3]; -} PIXEL_24BIT; +// See +// nearest2x.c -- Nearest Neighboor scaling +// bilinear2x.c -- Bilinear scaling +// biadv2x.c -- Advanced Biadapt scaling +// triscan2x.c -- Triscan scaling -#if SDL_BYTEORDER == SDL_BIG_ENDIAN -// big endian cpu -// We avoid potential pagefaults based on the assumption -// that all buffers are allocated on *at least* 32bit boundary -// So if the pointer (p) is 32bit-aligned, we can read at -// least 32 bits at once; or if it is not aligned then we -// are not at the beginning of the buffer and can read 1 byte -// before (p) -// -// WARNING!! Do not call these macros like so: -// SET_PIX_24BIT (dst_p++, pixel) -// The pre-increment or post-increment will be done -// several times -// -# define GET_PIX_24BIT(p) \ - ( ((intptr_t)(p)) & 3 ? \ - (*(Uint32 *)((Uint8 *)(p) - 1) & 0x00ffffff) : \ - (*(Uint32 *)(p) >> 8) \ - ) - -# define SET_PIX_24BIT(p, c) \ - ( ((intptr_t)(p)) & 3 ? \ - ( *(Uint32 *)((Uint8 *)(p) - 1) = \ - (*(Uint32 *)((Uint8 *)(p) - 1) & 0xff000000) | \ - ((c) & 0x00ffffff) \ - ) : \ - ( *(Uint32 *)(p) = \ - (*(Uint32 *)(p) & 0x000000ff) | \ - ((c) << 8) \ - ) \ - ) -#else -// little endian cpu -// Same page-safety assumption applies as for big-endian -// -# define GET_PIX_24BIT(p) \ - ( ((intptr_t)(p)) & 3 ? \ - (*(Uint32 *)((Uint8 *)(p) - 1) >> 8) : \ - (*(Uint32 *)(p) & 0x00ffffff) \ - ) - -# define SET_PIX_24BIT(p, c) \ - ( ((intptr_t)(p)) & 3 ? \ - ( *(Uint32 *)((Uint8 *)(p) - 1) = \ - (*(Uint32 *)((Uint8 *)(p) - 1) & 0x000000ff) | \ - ((c) << 8) \ - ) : \ - ( *(Uint32 *)(p) = \ - (*(Uint32 *)(p) & 0xff000000) | \ - ((c) & 0x00ffffff) \ - ) \ - ) -#endif - -// RGB -> YUV transformation -// the RGB vector is multiplied by the transformation matrix -// to get the YUV vector -static const double YUV_matrix[3][3] = -{ - /* Y U V */ - /* R */ {0.2989, -0.1687, 0.5000}, - /* G */ {0.5867, -0.3312, -0.4183}, - /* B */ {0.1144, 0.5000, -0.0816} -}; - -typedef enum -{ - YUV_XFORM_R = 0, - YUV_XFORM_G = 1, - YUV_XFORM_B = 2, - YUV_XFORM_Y = 0, - YUV_XFORM_U = 1, - YUV_XFORM_V = 2 -} RGB_YUV_INDEX; - -// pre-computed transformations for 8 bits per channel -static int RGB_to_YUV[/*RGB*/ 3][/*YUV*/ 3][ /*mult-res*/ 256]; -// double to int rounding error correction -#define YUV_ERR_CORR 0.4999 - -// pre-compute the RGB->YUV transformations +// Biadapt scaling to 2x void -Scale_PrepYUV() -{ - int i1; - - for (i1 = 0; i1 < 3; i1++) // enum R,G,B - { - int i2; - for (i2 = 0; i2 < 3; i2++) // enum Y,U,V - { - int i3; - for (i3 = 0; i3 < 256; i3++) // enum possible channel vals - RGB_to_YUV[i1][i2][i3] = (int) - (YUV_matrix[i1][i2] * i3 + YUV_ERR_CORR); - } - } -} - -// expands the given rectangle in all directions by 'expansion' -// guarded by 'limits' -void -Scale_ExpandRect (SDL_Rect* rect, int expansion, SDL_Rect* limits) -{ - if (rect->x - expansion >= limits->x) - { - rect->w += expansion; - rect->x -= expansion; - } - else - { - rect->w += rect->x - limits->x; - rect->x = limits->x; - } - - if (rect->y - expansion >= limits->y) - { - rect->h += expansion; - rect->y -= expansion; - } - else - { - rect->h += rect->y - limits->y; - rect->y = limits->y; - } - - if (rect->x + rect->w + expansion <= limits->w) - rect->w += expansion; - else - rect->w = limits->w - rect->x; - - if (rect->y + rect->h + expansion <= limits->h) - rect->h += expansion; - else - rect->h = limits->h - rect->y; -} - -typedef struct _BLEND_PARAMS -{ - int shift_bits; - int pre_shift; - Uint32 low_mask; - Uint32 high_mask; -} BLEND_PARAMS; - -// blends two pixels with ratio 50% - 50% -__inline__ Uint32 -Scale_BlendPixels_2 (BLEND_PARAMS bp, Uint32 pix1, Uint32 pix2) -{ - return - /* lower bits can be safely ignored - the error is minimal - expression that calcs them is left for posterity - (pix1 & pix2 & bp.low_mask) + - */ - ((pix1 & bp.high_mask) >> 1) + ((pix2 & bp.high_mask) >> 1); -} - -// blends four pixels with equal weight -__inline__ Uint32 -Scale_BlendPixels_4 (BLEND_PARAMS bp, Uint32 pix1, Uint32 pix2, - Uint32 pix3, Uint32 pix4) -{ - return - /* lower bits can be safely ignored - the error is minimal - expression that calcs them is left for posterity - ((((pix1 & bp.low_mask) + (pix2 & bp.low_mask) + - (pix3 & bp.low_mask) + (pix4 & bp.low_mask) - ) >> 2) & bp.low_mask) + - */ - ((pix1 & bp.high_mask) >> 2) + ((pix2 & bp.high_mask) >> 2) + - ((pix3 & bp.high_mask) >> 2) + ((pix4 & bp.high_mask) >> 2); -} - -// compute optimized masks for N-pixel blending -// N must be a power of 2 and cannot be more than 2^(B/2), -// where B is the number of bits/channel -__inline__ void -Scale_CalcBlendMasks (SDL_PixelFormat* fmt, unsigned int npixels, - BLEND_PARAMS* pbp) -{ - // mask-on the bits used for the low-part - int mask = npixels - 1; - - // this just does an integer log-base-2(npixels) - for (pbp->shift_bits = 0, npixels >>= 1; npixels != 0; npixels >>= 1) - pbp->shift_bits++; - - pbp->low_mask = (mask << fmt->Rshift) | - (mask << fmt->Gshift) | - (mask << fmt->Bshift); - - pbp->high_mask = (fmt->Rmask | fmt->Gmask | fmt->Bmask) ^ pbp->low_mask; -} - -// compute channel masks for N-pixel blending -// N must be a power of 2 and generally should not be more than 2^(B/2), -// where B is the number of bits/channel -// although, blending weights may dictate other conditions -__inline__ void -Scale_CalcChannelMasks (SDL_PixelFormat* fmt, unsigned int npixels, - BLEND_PARAMS* pbp) -{ - Uint32 masks[3] = {fmt->Rmask, fmt->Gmask, fmt->Bmask}; - int i, swapped = 1; - - // this just does an integer log-base-2(npixels) - for (pbp->shift_bits = 0, npixels >>= 1; npixels != 0; npixels >>= 1) - pbp->shift_bits++; - - // buble-sort masks - while (swapped) - { - swapped = 0; - for (i = 0; i < 2; ++i) - { - if (masks[i] < masks[i + 1]) - { - Uint32 tval = masks[i]; - masks[i] = masks[i + 1]; - masks[i + 1] = tval; - swapped++; - } - } - } - - pbp->high_mask = masks[0] | masks[2]; - pbp->low_mask = masks[1]; - - pbp->pre_shift = pbp->high_mask >= (Uint32)1 << (32 - pbp->shift_bits); -} - -// compute the RGB distance between 2 pixels -__inline__ int -Scale_GetRGBDelta (SDL_PixelFormat* fmt, Uint32 pix1, Uint32 pix2) -{ - Uint32 c; - int delta; - - c = (((pix1 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss) - - (((pix2 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss); - delta = c * c; - - c = (((pix1 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss) - - (((pix2 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss); - delta += c * c; - - c = (((pix1 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss) - - (((pix2 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss); - delta += c * c; - - return delta; -} - -// compute the YUV distance between 2 pixels -__inline__ int -Scale_GetYUVDelta (SDL_PixelFormat* fmt, Uint32 pix1, Uint32 pix2) -{ - Uint32 r1, g1, b1, r2, g2, b2; - int compd, delta; - - r1 = ((pix1 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; - g1 = ((pix1 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; - b1 = ((pix1 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; - r2 = ((pix2 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; - g2 = ((pix2 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; - b2 = ((pix2 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; - - // compute Y delta - compd = RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_Y][r1] - + RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_Y][g1] - + RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_Y][b1] - - RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_Y][r2] - - RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_Y][g2] - - RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_Y][b2]; - if (compd < 0) - compd = -compd; - // Y is 2-4 times more important than U or V - delta = compd << 1; - - // compute U delta - compd = RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_U][r1] - + RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_U][g1] - + RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_U][b1] - - RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_U][r2] - - RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_U][g2] - - RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_U][b2]; - if (compd < 0) - compd = -compd; - delta += compd; - - // compute V delta - compd = RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_V][r1] - + RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_V][g1] - + RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_V][b1] - - RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_V][r2] - - RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_V][g2] - - RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_V][b2]; - if (compd < 0) - compd = -compd; - delta += compd; - - return delta; -} - -// retrieve the Y (intensity) component of pixel's YUV -__inline__ int -Scale_GetPixY (SDL_PixelFormat* fmt, Uint32 pix) -{ - Uint32 r, g, b; - - r = ((pix & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; - g = ((pix & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; - b = ((pix & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; - - // compare Ys - return RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_Y][r] - + RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_Y][g] - + RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_Y][b]; -} - -// compare 2 pixels with respect to their YUV representations -// tolerance set by toler arg -// returns true: close; false: distant (-gt toler) -__inline__ bool -Scale_CmpYUV (SDL_PixelFormat* fmt, Uint32 pix1, Uint32 pix2, int toler) -{ - Uint32 r1, g1, b1, r2, g2, b2; - int compd, delta; - - r1 = ((pix1 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; - g1 = ((pix1 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; - b1 = ((pix1 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; - r2 = ((pix2 & fmt->Rmask) >> fmt->Rshift) << fmt->Rloss; - g2 = ((pix2 & fmt->Gmask) >> fmt->Gshift) << fmt->Gloss; - b2 = ((pix2 & fmt->Bmask) >> fmt->Bshift) << fmt->Bloss; - - // compute Y delta - compd = RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_Y][r1] - + RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_Y][g1] - + RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_Y][b1] - - RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_Y][r2] - - RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_Y][g2] - - RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_Y][b2]; - if (compd < 0) - compd = -compd; - // Y is 2-4 times more important than U or V - delta = compd << 1; - if (delta > toler) - return false; - - // compute U delta - compd = RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_U][r1] - + RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_U][g1] - + RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_U][b1] - - RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_U][r2] - - RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_U][g2] - - RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_U][b2]; - if (compd < 0) - compd = -compd; - delta += compd; - if (delta > toler) - return false; - - // compute V delta - compd = RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_V][r1] - + RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_V][g1] - + RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_V][b1] - - RGB_to_YUV [YUV_XFORM_R][YUV_XFORM_V][r2] - - RGB_to_YUV [YUV_XFORM_G][YUV_XFORM_V][g2] - - RGB_to_YUV [YUV_XFORM_B][YUV_XFORM_V][b2]; - if (compd < 0) - compd = -compd; - delta += compd; - - return delta <= toler; -} - -// biadapt scaling to 2x -void -Scale_BiAdaptFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) +SCALE_(BiAdaptFilter) (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) { int x, y; const int w = src->w, h = src->h; @@ -427,10 +54,18 @@ Scale_BiAdaptFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) SDL_Rect *region = r; SDL_Rect limits; SDL_PixelFormat *fmt = dst->format; - BLEND_PARAMS blend2, blend4; - const int p = src->pitch, dp = dst->pitch; + const int sp = src->pitch, dp = dst->pitch; const int bpp = fmt->BytesPerPixel; - const int len = p / bpp, dlen = dp / bpp; + const int slen = sp / bpp, dlen = dp / bpp; + Uint32 *src_p = (Uint32 *)src->pixels; + Uint32 *dst_p = (Uint32 *)dst->pixels; + Uint32 pixval_tl, pixval_tr, pixval_bl, pixval_br; + + // these macros are for clarity; they make the current pixel (0,0) + // and allow to access pixels in all directions + #define SRC(x, y) (src_p + (x) + ((y) * slen)) + + SCALE_(PlatInit) (); // expand updated region if necessary // pixels neighbooring the updated region may @@ -443,2694 +78,186 @@ Scale_BiAdaptFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) xend = region->x + region->w; yend = region->y + region->h; - dsrc = len - region->w; + dsrc = slen - region->w; ddst = (dlen - region->w) * 2; - // precompute the blending masks and shifts - Scale_CalcBlendMasks (fmt, 2, &blend2); - Scale_CalcBlendMasks (fmt, 4, &blend4); + // move ptrs to the first updated pixel + src_p += slen * region->y + region->x; + dst_p += (dlen * region->y + region->x) * 2; - switch (fmt->BytesPerPixel) + for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) { - case 2: // 16bpp scaling - #define BIADAPT_GETPIX(p) ( *(Uint16 *)(p) ) - #define BIADAPT_SETPIX(p, c) ( *(Uint16 *)(p) = (c) ) - #define BIADAPT_BUF Uint16 - { - BIADAPT_BUF *src_p = (BIADAPT_BUF *)src->pixels; - BIADAPT_BUF *dst_p = (BIADAPT_BUF *)dst->pixels; - Uint32 pixval_tl, pixval_tr, pixval_bl, pixval_br; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) + for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) { - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - pixval_tl = BIADAPT_GETPIX (src_p); - - BIADAPT_SETPIX (dst_p, pixval_tl); - - if (y + 1 < h) - { - // check pixel below the current one - pixval_bl = BIADAPT_GETPIX (src_p + len); - - if (pixval_tl == pixval_bl) - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - else - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, pixval_tl, pixval_bl) - ); - } - else - { - // last pixel in column - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - } - dst_p++; - - - if (x + 1 >= w) - { - // last pixel in row - propagate - BIADAPT_SETPIX (dst_p, pixval_tl); - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // check pixel to the right from the current one - pixval_tr = BIADAPT_GETPIX (src_p + 1); - - if (pixval_tl == pixval_tr) - BIADAPT_SETPIX (dst_p, pixval_tr); - else - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, pixval_tl, pixval_tr) - ); - - if (y + 1 >= h) - { - // last pixel in column - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // check pixel to the bottom-right - pixval_br = BIADAPT_GETPIX (src_p + 1 + len); - - if (pixval_tl == pixval_br && pixval_tr == pixval_bl) - { - int cl, cr; - Uint32 clr; - - if (pixval_tl == pixval_tr) - { - // all 4 are equal - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // both pairs are equal, have to resolve the pixel - // race; we try detecting which color is - // the background by looking for a line or an edge - // examine 8 pixels surrounding the current quad - - cl = cr = 1; - - if (x > 0) - { - clr = BIADAPT_GETPIX (src_p - 1); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p - 1 + len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (y > 0) - { - clr = BIADAPT_GETPIX (src_p - len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 1 - len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (x + 2 < w) - { - clr = BIADAPT_GETPIX (src_p + 2); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 2 + len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (y + 2 < h) - { - clr = BIADAPT_GETPIX (src_p + 2 * len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 1 + 2 * len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - // least count wins - if (cl > cr) - BIADAPT_SETPIX (dst_p + dlen, pixval_tr); - else if (cr > cl) - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - else - BIADAPT_SETPIX (dst_p + dlen, - Scale_BlendPixels_2 (blend2, pixval_tl, - pixval_tr)); - } - else if (pixval_tl == pixval_br) - { - // main diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - } - else if (pixval_tr == pixval_bl) - { - // 2nd diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, pixval_tr); - } - else - { - // blend all 4 - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_4 ( - blend4, pixval_tl, pixval_bl, pixval_tr, pixval_br - )); - } - } - } - break; - } - #undef BIADAPT_GETPIX - #undef BIADAPT_SETPIX - #undef BIADAPT_BUF - - case 3: // 24bpp scaling - #define BIADAPT_GETPIX(p) GET_PIX_24BIT(p) - #define BIADAPT_SETPIX(p, c) SET_PIX_24BIT(p, c) - #define BIADAPT_BUF PIXEL_24BIT - { - BIADAPT_BUF *src_p = (BIADAPT_BUF *)src->pixels; - BIADAPT_BUF *dst_p = (BIADAPT_BUF *)dst->pixels; - Uint32 pixval_tl, pixval_tr, pixval_bl, pixval_br; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - pixval_tl = BIADAPT_GETPIX (src_p); - - BIADAPT_SETPIX (dst_p, pixval_tl); - - if (y + 1 < h) - { - // check pixel below the current one - pixval_bl = BIADAPT_GETPIX (src_p + len); - - if (pixval_tl == pixval_bl) - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - else - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, pixval_tl, pixval_bl) - ); - } - else - { - // last pixel in column - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - } - dst_p++; - - - if (x + 1 >= w) - { - // last pixel in row - propagate - BIADAPT_SETPIX (dst_p, pixval_tl); - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // check pixel to the right from the current one - pixval_tr = BIADAPT_GETPIX (src_p + 1); - - if (pixval_tl == pixval_tr) - BIADAPT_SETPIX (dst_p, pixval_tr); - else - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, pixval_tl, pixval_tr) - ); - - if (y + 1 >= h) - { - // last pixel in column - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // check pixel to the bottom-right - pixval_br = BIADAPT_GETPIX (src_p + 1 + len); - - if (pixval_tl == pixval_br && pixval_tr == pixval_bl) - { - int cl, cr; - Uint32 clr; - - if (pixval_tl == pixval_tr) - { - // all 4 are equal - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // both pairs are equal, have to resolve the pixel - // race; we try detecting which color is - // the background by looking for a line or an edge - // examine 8 pixels surrounding the current quad - - cl = cr = 1; - - if (x > 0) - { - clr = BIADAPT_GETPIX (src_p - 1); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p - 1 + len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (y > 0) - { - clr = BIADAPT_GETPIX (src_p - len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 1 - len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (x + 2 < w) - { - clr = BIADAPT_GETPIX (src_p + 2); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 2 + len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (y + 2 < h) - { - clr = BIADAPT_GETPIX (src_p + 2 * len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 1 + 2 * len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - // least count wins - if (cl > cr) - BIADAPT_SETPIX (dst_p + dlen, pixval_tr); - else if (cr > cl) - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - else - BIADAPT_SETPIX (dst_p + dlen, - Scale_BlendPixels_2 (blend2, pixval_tl, - pixval_tr)); - } - else if (pixval_tl == pixval_br) - { - // main diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - } - else if (pixval_tr == pixval_bl) - { - // 2nd diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, pixval_tr); - } - else - { - // blend all 4 - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_4 ( - blend4, pixval_tl, pixval_bl, pixval_tr, pixval_br - )); - } - } - } - break; - } - #undef BIADAPT_GETPIX - #undef BIADAPT_SETPIX - #undef BIADAPT_BUF - - case 4: // 32bpp scaling - #define BIADAPT_GETPIX(p) ( *(Uint32 *)(p) ) - #define BIADAPT_SETPIX(p, c) ( *(Uint32 *)(p) = (c) ) - #define BIADAPT_BUF Uint32 - { - BIADAPT_BUF *src_p = (BIADAPT_BUF *)src->pixels; - BIADAPT_BUF *dst_p = (BIADAPT_BUF *)dst->pixels; - Uint32 pixval_tl, pixval_tr, pixval_bl, pixval_br; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - pixval_tl = BIADAPT_GETPIX (src_p); - - BIADAPT_SETPIX (dst_p, pixval_tl); - - if (y + 1 < h) - { - // check pixel below the current one - pixval_bl = BIADAPT_GETPIX (src_p + len); - - if (pixval_tl == pixval_bl) - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - else - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, pixval_tl, pixval_bl) - ); - } - else - { - // last pixel in column - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - } - dst_p++; - - - if (x + 1 >= w) - { - // last pixel in row - propagate - BIADAPT_SETPIX (dst_p, pixval_tl); - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // check pixel to the right from the current one - pixval_tr = BIADAPT_GETPIX (src_p + 1); - - if (pixval_tl == pixval_tr) - BIADAPT_SETPIX (dst_p, pixval_tr); - else - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, pixval_tl, pixval_tr) - ); - - if (y + 1 >= h) - { - // last pixel in column - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // check pixel to the bottom-right - pixval_br = BIADAPT_GETPIX (src_p + 1 + len); - - if (pixval_tl == pixval_br && pixval_tr == pixval_bl) - { - int cl, cr; - Uint32 clr; - - if (pixval_tl == pixval_tr) - { - // all 4 are equal - propagate - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - continue; - } - - // both pairs are equal, have to resolve the pixel - // race; we try detecting which color is - // the background by looking for a line or an edge - // examine 8 pixels surrounding the current quad - - cl = cr = 1; - - if (x > 0) - { - clr = BIADAPT_GETPIX (src_p - 1); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p - 1 + len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (y > 0) - { - clr = BIADAPT_GETPIX (src_p - len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 1 - len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (x + 2 < w) - { - clr = BIADAPT_GETPIX (src_p + 2); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 2 + len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - if (y + 2 < h) - { - clr = BIADAPT_GETPIX (src_p + 2 * len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - - clr = BIADAPT_GETPIX (src_p + 1 + 2 * len); - if (clr == pixval_tl) - cl++; - else if (clr == pixval_tr) - cr++; - } - - // least count wins - if (cl > cr) - BIADAPT_SETPIX (dst_p + dlen, pixval_tr); - else if (cr > cl) - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - else - BIADAPT_SETPIX (dst_p + dlen, - Scale_BlendPixels_2 (blend2, pixval_tl, - pixval_tr)); - } - else if (pixval_tl == pixval_br) - { - // main diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, pixval_tl); - } - else if (pixval_tr == pixval_bl) - { - // 2nd diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, pixval_tr); - } - else - { - // blend all 4 - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_4 ( - blend4, pixval_tl, pixval_bl, pixval_tr, pixval_br - )); - } - } - } - break; - } - #undef BIADAPT_GETPIX - #undef BIADAPT_SETPIX - #undef BIADAPT_BUF - - } -} - -// advanced biadapt scaling to 2x -void -Scale_BiAdaptAdvFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) -{ - int x, y; - const int w = src->w, h = src->h; - int xend, yend; - int dsrc, ddst; - SDL_Rect *region = r; - SDL_Rect limits; - SDL_PixelFormat *fmt = dst->format; - BLEND_PARAMS blend2, blend4; - const int p = src->pitch, dp = dst->pitch; - const int bpp = fmt->BytesPerPixel; - const int len = p / bpp, dlen = dp / bpp; - // for clarity purposes, the 'pixels' array here is transposed - Uint32 pixels[4][4]; - static int resolve_coord[][2] = - { - {0, -1}, {1, -1}, { 2, 0}, { 2, 1}, - {1, 2}, {0, 2}, {-1, 1}, {-1, 0}, - {100, 100} // term - }; - - // these macros are for clarity; they make the current pixel (0,0) - // and allow to access pixels in all directions - #define PIX(x, y) (pixels[1 + (x)][1 + (y)]) - #define SRC(x, y) (src_p + (x) + ((y) * len)) - // commonly used operations, for clarity also - // others are defined at their respective bpp levels - #define BIADAPT_RGBHIGH 8000 - #define BIADAPT_YUVLOW 30 - #define BIADAPT_YUVMED 70 - #define BIADAPT_YUVHIGH 130 - - #define BIADAPT_CMPRGB(p1, p2) \ - Scale_GetRGBDelta (fmt, p1, p2) - // high tolerance pixel comparison - #define BIADAPT_CMPRGB_HIGH(p1, p2) \ - (p1 == p2 || BIADAPT_CMPRGB (p1, p2) <= BIADAPT_RGBHIGH) - - #define BIADAPT_CMPYUV(p1, p2) \ - Scale_GetYUVDelta (fmt, p1, p2) - // low tolerance pixel comparison - #define BIADAPT_CMPYUV_LOW(p1, p2) \ - (p1 == p2 || BIADAPT_CMPYUV (p1, p2) <= BIADAPT_YUVLOW) - // medium tolerance pixel comparison - #define BIADAPT_CMPYUV_MED(p1, p2) \ - (p1 == p2 || BIADAPT_CMPYUV (p1, p2) <= BIADAPT_YUVMED) - // high tolerance pixel comparison - #define BIADAPT_CMPYUV_HIGH(p1, p2) \ - (p1 == p2 || BIADAPT_CMPYUV (p1, p2) <= BIADAPT_YUVHIGH) - - // expand updated region if necessary - // pixels neighbooring the updated region may - // change as a result of updates - limits.x = 0; - limits.y = 0; - limits.w = src->w; - limits.h = src->h; - Scale_ExpandRect (region, 2, &limits); - - xend = region->x + region->w; - yend = region->y + region->h; - dsrc = len - region->w; - ddst = (dlen - region->w) * 2; - - // precompute the blending masks and shifts - Scale_CalcBlendMasks (fmt, 2, &blend2); - Scale_CalcBlendMasks (fmt, 4, &blend4); - - switch (fmt->BytesPerPixel) - { - case 2: // 16bpp scaling - #define BIADAPT_GETPIX(p) ( *(Uint16 *)(p) ) - #define BIADAPT_SETPIX(p, c) ( *(Uint16 *)(p) = (c) ) - #define BIADAPT_BUF Uint16 - { - BIADAPT_BUF *src_p = (BIADAPT_BUF *)src->pixels; - BIADAPT_BUF *dst_p = (BIADAPT_BUF *)dst->pixels; - - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - // pixel eqaulity counter - int cmatch; - - // most pixels will fall into 'all 4 equal' - // pattern, so we check it first - cmatch = 0; - - PIX (0, 0) = BIADAPT_GETPIX (SRC (0, 0)); - - BIADAPT_SETPIX (dst_p, PIX (0, 0)); - - if (y + 1 < h) - { - // check pixel below the current one - PIX (0, 1) = BIADAPT_GETPIX (SRC (0, 1)); - - if (PIX (0, 0) == PIX (0, 1)) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - cmatch |= 1; - } - } - else - { - // last pixel in column - propagate - PIX (0, 1) = PIX (0, 0); - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - cmatch |= 1; - - } - - if (x + 1 < w) - { - // check pixel to the right from the current one - PIX (1, 0) = BIADAPT_GETPIX (SRC (1, 0)); - - if (PIX (0, 0) == PIX (1, 0)) - { - BIADAPT_SETPIX (dst_p + 1, PIX (0, 0)); - cmatch |= 2; - } - } - else - { - // last pixel in row - propagate - PIX (1, 0) = PIX (0, 0); - BIADAPT_SETPIX (dst_p + 1, PIX (0, 0)); - cmatch |= 2; - } - - if (cmatch == 3) - { - if (y + 1 >= h || x + 1 >= w) - { - // last pixel in row/column and nearest - // neighboor is identical - dst_p++; - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - continue; - } - - // check pixel to the bottom-right - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - - if (PIX (0, 0) == PIX (1, 1)) - { - // all 4 are equal - propagate - dst_p++; - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - continue; - } - } - - // some neighnoors are different, lets check them - - if (x > 0) - PIX (-1, 0) = BIADAPT_GETPIX (SRC (-1, 0)); - else - PIX (-1, 0) = PIX (0, 0); - - if (x + 2 < w) - PIX (2, 0) = BIADAPT_GETPIX (SRC (2, 0)); - else - PIX (2, 0) = PIX (1, 0); - - if (y + 1 < h) - { - if (x > 0) - PIX (-1, 1) = BIADAPT_GETPIX (SRC (-1, 1)); - else - PIX (-1, 1) = PIX (0, 1); - - if (x + 2 < w) - { - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - PIX (2, 1) = BIADAPT_GETPIX (SRC (2, 1)); - } - else if (x + 1 < w) - { - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - PIX (2, 1) = PIX (1, 1); - } - else - { - PIX (1, 1) = PIX (0, 1); - PIX (2, 1) = PIX (0, 1); - } - } - else - { - // last pixel in column - PIX (-1, 1) = PIX (-1, 0); - PIX (1, 1) = PIX (1, 0); - PIX (2, 1) = PIX (2, 0); - } - - if (y + 2 < h) - { - PIX (0, 2) = BIADAPT_GETPIX (SRC (0, 2)); - - if (x > 0) - PIX (-1, 2) = BIADAPT_GETPIX (SRC (-1, 2)); - else - PIX (-1, 2) = PIX (0, 2); - - if (x + 2 < w) - { - PIX (1, 2) = BIADAPT_GETPIX (SRC (1, 2)); - PIX (2, 2) = BIADAPT_GETPIX (SRC (2, 2)); - } - else if (x + 1 < w) - { - PIX (1, 2) = BIADAPT_GETPIX (SRC (1, 2)); - PIX (2, 2) = PIX (1, 2); - } - else - { - PIX (1, 2) = PIX (0, 2); - PIX (2, 2) = PIX (0, 2); - } - } - else - { - // last pixel in column - PIX (-1, 2) = PIX (-1, 1); - PIX (0, 2) = PIX (0, 1); - PIX (1, 2) = PIX (1, 1); - PIX (2, 2) = PIX (2, 1); - } - - if (y > 0) - { - PIX (0, -1) = BIADAPT_GETPIX (SRC (0, -1)); - - if (x > 0) - PIX (-1, -1) = BIADAPT_GETPIX (SRC (-1, -1)); - else - PIX (-1, -1) = PIX (0, -1); - - if (x + 2 < w) - { - PIX (1, -1) = BIADAPT_GETPIX (SRC (1, -1)); - PIX (2, -1) = BIADAPT_GETPIX (SRC (2, -1)); - } - else if (x + 1 < w) - { - PIX (1, -1) = BIADAPT_GETPIX (SRC (1, -1)); - PIX (2, -1) = PIX (1, -1); - } - else - { - PIX (1, -1) = PIX (0, -1); - PIX (2, -1) = PIX (0, -1); - } - } - else - { - PIX (-1, -1) = PIX (-1, 0); - PIX (0, -1) = PIX (0, 0); - PIX (1, -1) = PIX (1, 0); - PIX (2, -1) = PIX (2, 0); - } - - // check pixel below the current one - if (!(cmatch & 1)) - { - if (BIADAPT_CMPYUV (PIX (0, 0), PIX (0, 1)) <= BIADAPT_YUVLOW) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (0, 1)) - ); - cmatch |= 1; - } - // detect a 2:1 line going across the current pixel - else if ( (PIX (0, 0) == PIX (-1, 0) - && PIX (0, 0) == PIX (1, 1) - && PIX (0, 0) == PIX (2, 1) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) || - - (PIX (0, 0) == PIX (1, 0) - && PIX (0, 0) == PIX (-1, 1) - && PIX (0, 0) == PIX (2, -1) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))))) ) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - } - // detect a 2:1 line going across the pixel below current - else if ( (PIX (0, 1) == PIX (-1, 0) - && PIX (0, 1) == PIX (1, 1) - && PIX (0, 1) == PIX (2, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 2))))) || - - (PIX (0, 1) == PIX (1, 0) - && PIX (0, 1) == PIX (-1, 1) - && PIX (0, 1) == PIX (2, 0) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, -1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))))) ) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 1)); - } - else - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (0, 1)) - ); - } - - dst_p++; - - // check pixel to the right from the current one - if (!(cmatch & 2)) - { - if (BIADAPT_CMPYUV (PIX (0, 0), PIX (1, 0)) <= BIADAPT_YUVLOW) - { - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 0)) - ); - cmatch |= 2; - } - // detect a 1:2 line going across the current pixel - else if ( (PIX (0, 0) == PIX (1, -1) - && PIX (0, 0) == PIX (0, 1) - && PIX (0, 0) == PIX (-1, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))))) || - - (PIX (0, 0) == PIX (0, -1) - && PIX (0, 0) == PIX (1, 1) - && PIX (0, 0) == PIX (1, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) ) - - { - BIADAPT_SETPIX (dst_p, PIX (0, 0)); - } - // detect a 1:2 line going across the pixel to the right - else if ( (PIX (1, 0) == PIX (1, -1) - && PIX (1, 0) == PIX (0, 1) - && PIX (1, 0) == PIX (0, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))))) || - - (PIX (1, 0) == PIX (0, -1) - && PIX (1, 0) == PIX (1, 1) - && PIX (1, 0) == PIX (2, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 1))))) ) - { - BIADAPT_SETPIX (dst_p, PIX (1, 0)); - } - else - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 0)) - ); - } - - if (PIX (0, 0) == PIX (1, 1) && PIX (1, 0) == PIX (0, 1)) - { - // diagonals are equal - int *coord; - int cl, cr; - Uint32 clr; - - // both pairs are equal, have to resolve the pixel - // race; we try detecting which color is - // the background by looking for a line or an edge - // examine 8 pixels surrounding the current quad - - cl = cr = 2; - for (coord = resolve_coord[0]; *coord < 100; coord += 2) - { - clr = PIX (coord[0], coord[1]); - - if (BIADAPT_CMPYUV_MED (clr, PIX (0, 0))) - cl++; - else if (BIADAPT_CMPYUV_MED (clr, PIX (1, 0))) - cr++; - } - - // least count wins - if (cl > cr) - clr = PIX (1, 0); - else if (cr > cl) - clr = PIX (0, 0); - else - clr = Scale_BlendPixels_2 (blend2, - PIX (0, 0), PIX (1, 0)); - - BIADAPT_SETPIX (dst_p + dlen, clr); - continue; - } - - if (cmatch == 3 - || (BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (0, 1)) - && BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (1, 1)))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 1), PIX (1, 0)) - ); - continue; - } - else if (cmatch && BIADAPT_CMPYUV_LOW (PIX (0, 0), PIX (1, 1))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - continue; - } - - // check pixel to the bottom-right - if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1)) - && BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1))) - { - if (Scale_GetPixY (fmt, PIX (0, 0)) - > Scale_GetPixY (fmt, PIX (1, 0))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - } - else - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - } - else if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1))) - { - // main diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - } - else if (BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1))) - { - // 2nd diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - else - { - // blend all 4 - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_4 ( - blend4, PIX (0, 0), PIX (0, 1), - PIX (1, 0), PIX (1, 1) - )); - } - } - } - break; - } - #undef BIADAPT_GETPIX - #undef BIADAPT_SETPIX - #undef BIADAPT_BUF - - case 3: // 24bpp scaling - #define BIADAPT_GETPIX(p) GET_PIX_24BIT(p) - #define BIADAPT_SETPIX(p, c) SET_PIX_24BIT(p, c) - #define BIADAPT_BUF PIXEL_24BIT - { - BIADAPT_BUF *src_p = (BIADAPT_BUF *)src->pixels; - BIADAPT_BUF *dst_p = (BIADAPT_BUF *)dst->pixels; - - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - // pixel eqaulity counter - int cmatch; - - // most pixels will fall into 'all 4 equal' - // pattern, so we check it first - cmatch = 0; - - PIX (0, 0) = BIADAPT_GETPIX (SRC (0, 0)); - - BIADAPT_SETPIX (dst_p, PIX (0, 0)); - - if (y + 1 < h) - { - // check pixel below the current one - PIX (0, 1) = BIADAPT_GETPIX (SRC (0, 1)); - - if (PIX (0, 0) == PIX (0, 1)) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - cmatch |= 1; - } - } - else - { - // last pixel in column - propagate - PIX (0, 1) = PIX (0, 0); - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - cmatch |= 1; - - } - - if (x + 1 < w) - { - // check pixel to the right from the current one - PIX (1, 0) = BIADAPT_GETPIX (SRC (1, 0)); - - if (PIX (0, 0) == PIX (1, 0)) - { - BIADAPT_SETPIX (dst_p + 1, PIX (0, 0)); - cmatch |= 2; - } - } - else - { - // last pixel in row - propagate - PIX (1, 0) = PIX (0, 0); - BIADAPT_SETPIX (dst_p + 1, PIX (0, 0)); - cmatch |= 2; - } - - if (cmatch == 3) - { - if (y + 1 >= h || x + 1 >= w) - { - // last pixel in row/column and nearest - // neighboor is identical - dst_p++; - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - continue; - } - - // check pixel to the bottom-right - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - - if (PIX (0, 0) == PIX (1, 1)) - { - // all 4 are equal - propagate - dst_p++; - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - continue; - } - } - - // some neighnoors are different, lets check them - - if (x > 0) - PIX (-1, 0) = BIADAPT_GETPIX (SRC (-1, 0)); - else - PIX (-1, 0) = PIX (0, 0); - - if (x + 2 < w) - PIX (2, 0) = BIADAPT_GETPIX (SRC (2, 0)); - else - PIX (2, 0) = PIX (1, 0); - - if (y + 1 < h) - { - if (x > 0) - PIX (-1, 1) = BIADAPT_GETPIX (SRC (-1, 1)); - else - PIX (-1, 1) = PIX (0, 1); - - if (x + 2 < w) - { - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - PIX (2, 1) = BIADAPT_GETPIX (SRC (2, 1)); - } - else if (x + 1 < w) - { - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - PIX (2, 1) = PIX (1, 1); - } - else - { - PIX (1, 1) = PIX (0, 1); - PIX (2, 1) = PIX (0, 1); - } - } - else - { - // last pixel in column - PIX (-1, 1) = PIX (-1, 0); - PIX (1, 1) = PIX (1, 0); - PIX (2, 1) = PIX (2, 0); - } - - if (y + 2 < h) - { - PIX (0, 2) = BIADAPT_GETPIX (SRC (0, 2)); - - if (x > 0) - PIX (-1, 2) = BIADAPT_GETPIX (SRC (-1, 2)); - else - PIX (-1, 2) = PIX (0, 2); - - if (x + 2 < w) - { - PIX (1, 2) = BIADAPT_GETPIX (SRC (1, 2)); - PIX (2, 2) = BIADAPT_GETPIX (SRC (2, 2)); - } - else if (x + 1 < w) - { - PIX (1, 2) = BIADAPT_GETPIX (SRC (1, 2)); - PIX (2, 2) = PIX (1, 2); - } - else - { - PIX (1, 2) = PIX (0, 2); - PIX (2, 2) = PIX (0, 2); - } - } - else - { - // last pixel in column - PIX (-1, 2) = PIX (-1, 1); - PIX (0, 2) = PIX (0, 1); - PIX (1, 2) = PIX (1, 1); - PIX (2, 2) = PIX (2, 1); - } - - if (y > 0) - { - PIX (0, -1) = BIADAPT_GETPIX (SRC (0, -1)); - - if (x > 0) - PIX (-1, -1) = BIADAPT_GETPIX (SRC (-1, -1)); - else - PIX (-1, -1) = PIX (0, -1); - - if (x + 2 < w) - { - PIX (1, -1) = BIADAPT_GETPIX (SRC (1, -1)); - PIX (2, -1) = BIADAPT_GETPIX (SRC (2, -1)); - } - else if (x + 1 < w) - { - PIX (1, -1) = BIADAPT_GETPIX (SRC (1, -1)); - PIX (2, -1) = PIX (1, -1); - } - else - { - PIX (1, -1) = PIX (0, -1); - PIX (2, -1) = PIX (0, -1); - } - } - else - { - PIX (-1, -1) = PIX (-1, 0); - PIX (0, -1) = PIX (0, 0); - PIX (1, -1) = PIX (1, 0); - PIX (2, -1) = PIX (2, 0); - } - - // check pixel below the current one - if (!(cmatch & 1)) - { - if (BIADAPT_CMPYUV (PIX (0, 0), PIX (0, 1)) <= BIADAPT_YUVLOW) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (0, 1)) - ); - cmatch |= 1; - } - // detect a 2:1 line going across the current pixel - else if ( (PIX (0, 0) == PIX (-1, 0) - && PIX (0, 0) == PIX (1, 1) - && PIX (0, 0) == PIX (2, 1) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) || - - (PIX (0, 0) == PIX (1, 0) - && PIX (0, 0) == PIX (-1, 1) - && PIX (0, 0) == PIX (2, -1) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))))) ) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - } - // detect a 2:1 line going across the pixel below current - else if ( (PIX (0, 1) == PIX (-1, 0) - && PIX (0, 1) == PIX (1, 1) - && PIX (0, 1) == PIX (2, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 2))))) || - - (PIX (0, 1) == PIX (1, 0) - && PIX (0, 1) == PIX (-1, 1) - && PIX (0, 1) == PIX (2, 0) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, -1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))))) ) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 1)); - } - else - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (0, 1)) - ); - } - - dst_p++; - - // check pixel to the right from the current one - if (!(cmatch & 2)) - { - if (BIADAPT_CMPYUV (PIX (0, 0), PIX (1, 0)) <= BIADAPT_YUVLOW) - { - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 0)) - ); - cmatch |= 2; - } - // detect a 1:2 line going across the current pixel - else if ( (PIX (0, 0) == PIX (1, -1) - && PIX (0, 0) == PIX (0, 1) - && PIX (0, 0) == PIX (-1, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))))) || - - (PIX (0, 0) == PIX (0, -1) - && PIX (0, 0) == PIX (1, 1) - && PIX (0, 0) == PIX (1, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) ) - - { - BIADAPT_SETPIX (dst_p, PIX (0, 0)); - } - // detect a 1:2 line going across the pixel to the right - else if ( (PIX (1, 0) == PIX (1, -1) - && PIX (1, 0) == PIX (0, 1) - && PIX (1, 0) == PIX (0, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))))) || - - (PIX (1, 0) == PIX (0, -1) - && PIX (1, 0) == PIX (1, 1) - && PIX (1, 0) == PIX (2, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 1))))) ) - { - BIADAPT_SETPIX (dst_p, PIX (1, 0)); - } - else - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 0)) - ); - } - - if (PIX (0, 0) == PIX (1, 1) && PIX (1, 0) == PIX (0, 1)) - { - // diagonals are equal - int *coord; - int cl, cr; - Uint32 clr; - - // both pairs are equal, have to resolve the pixel - // race; we try detecting which color is - // the background by looking for a line or an edge - // examine 8 pixels surrounding the current quad - - cl = cr = 2; - for (coord = resolve_coord[0]; *coord < 100; coord += 2) - { - clr = PIX (coord[0], coord[1]); - - if (BIADAPT_CMPYUV_MED (clr, PIX (0, 0))) - cl++; - else if (BIADAPT_CMPYUV_MED (clr, PIX (1, 0))) - cr++; - } - - // least count wins - if (cl > cr) - clr = PIX (1, 0); - else if (cr > cl) - clr = PIX (0, 0); - else - clr = Scale_BlendPixels_2 (blend2, - PIX (0, 0), PIX (1, 0)); - - BIADAPT_SETPIX (dst_p + dlen, clr); - continue; - } - - if (cmatch == 3 - || (BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (0, 1)) - && BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (1, 1)))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 1), PIX (1, 0)) - ); - continue; - } - else if (cmatch && BIADAPT_CMPYUV_LOW (PIX (0, 0), PIX (1, 1))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - continue; - } - - // check pixel to the bottom-right - if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1)) - && BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1))) - { - if (Scale_GetPixY (fmt, PIX (0, 0)) - > Scale_GetPixY (fmt, PIX (1, 0))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - } - else - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - } - else if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1))) - { - // main diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - } - else if (BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1))) - { - // 2nd diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - else - { - // blend all 4 - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_4 ( - blend4, PIX (0, 0), PIX (0, 1), - PIX (1, 0), PIX (1, 1) - )); - } - } - } - break; - } - #undef BIADAPT_GETPIX - #undef BIADAPT_SETPIX - #undef BIADAPT_BUF - - case 4: // 32bpp scaling - #define BIADAPT_GETPIX(p) ( *(Uint32 *)(p) ) - #define BIADAPT_SETPIX(p, c) ( *(Uint32 *)(p) = (c) ) - #define BIADAPT_BUF Uint32 - { - BIADAPT_BUF *src_p = (BIADAPT_BUF *)src->pixels; - BIADAPT_BUF *dst_p = (BIADAPT_BUF *)dst->pixels; - - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - // pixel eqaulity counter - int cmatch; - - // most pixels will fall into 'all 4 equal' - // pattern, so we check it first - cmatch = 0; - - PIX (0, 0) = BIADAPT_GETPIX (SRC (0, 0)); - - BIADAPT_SETPIX (dst_p, PIX (0, 0)); - - if (y + 1 < h) - { - // check pixel below the current one - PIX (0, 1) = BIADAPT_GETPIX (SRC (0, 1)); - - if (PIX (0, 0) == PIX (0, 1)) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - cmatch |= 1; - } - } - else - { - // last pixel in column - propagate - PIX (0, 1) = PIX (0, 0); - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - cmatch |= 1; - - } - - if (x + 1 < w) - { - // check pixel to the right from the current one - PIX (1, 0) = BIADAPT_GETPIX (SRC (1, 0)); - - if (PIX (0, 0) == PIX (1, 0)) - { - BIADAPT_SETPIX (dst_p + 1, PIX (0, 0)); - cmatch |= 2; - } - } - else - { - // last pixel in row - propagate - PIX (1, 0) = PIX (0, 0); - BIADAPT_SETPIX (dst_p + 1, PIX (0, 0)); - cmatch |= 2; - } - - if (cmatch == 3) - { - if (y + 1 >= h || x + 1 >= w) - { - // last pixel in row/column and nearest - // neighboor is identical - dst_p++; - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - continue; - } - - // check pixel to the bottom-right - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - - if (PIX (0, 0) == PIX (1, 1)) - { - // all 4 are equal - propagate - dst_p++; - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - continue; - } - } - - // some neighnoors are different, lets check them - - if (x > 0) - PIX (-1, 0) = BIADAPT_GETPIX (SRC (-1, 0)); - else - PIX (-1, 0) = PIX (0, 0); - - if (x + 2 < w) - PIX (2, 0) = BIADAPT_GETPIX (SRC (2, 0)); - else - PIX (2, 0) = PIX (1, 0); - - if (y + 1 < h) - { - if (x > 0) - PIX (-1, 1) = BIADAPT_GETPIX (SRC (-1, 1)); - else - PIX (-1, 1) = PIX (0, 1); - - if (x + 2 < w) - { - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - PIX (2, 1) = BIADAPT_GETPIX (SRC (2, 1)); - } - else if (x + 1 < w) - { - PIX (1, 1) = BIADAPT_GETPIX (SRC (1, 1)); - PIX (2, 1) = PIX (1, 1); - } - else - { - PIX (1, 1) = PIX (0, 1); - PIX (2, 1) = PIX (0, 1); - } - } - else - { - // last pixel in column - PIX (-1, 1) = PIX (-1, 0); - PIX (1, 1) = PIX (1, 0); - PIX (2, 1) = PIX (2, 0); - } - - if (y + 2 < h) - { - PIX (0, 2) = BIADAPT_GETPIX (SRC (0, 2)); - - if (x > 0) - PIX (-1, 2) = BIADAPT_GETPIX (SRC (-1, 2)); - else - PIX (-1, 2) = PIX (0, 2); - - if (x + 2 < w) - { - PIX (1, 2) = BIADAPT_GETPIX (SRC (1, 2)); - PIX (2, 2) = BIADAPT_GETPIX (SRC (2, 2)); - } - else if (x + 1 < w) - { - PIX (1, 2) = BIADAPT_GETPIX (SRC (1, 2)); - PIX (2, 2) = PIX (1, 2); - } - else - { - PIX (1, 2) = PIX (0, 2); - PIX (2, 2) = PIX (0, 2); - } - } - else - { - // last pixel in column - PIX (-1, 2) = PIX (-1, 1); - PIX (0, 2) = PIX (0, 1); - PIX (1, 2) = PIX (1, 1); - PIX (2, 2) = PIX (2, 1); - } - - if (y > 0) - { - PIX (0, -1) = BIADAPT_GETPIX (SRC (0, -1)); - - if (x > 0) - PIX (-1, -1) = BIADAPT_GETPIX (SRC (-1, -1)); - else - PIX (-1, -1) = PIX (0, -1); - - if (x + 2 < w) - { - PIX (1, -1) = BIADAPT_GETPIX (SRC (1, -1)); - PIX (2, -1) = BIADAPT_GETPIX (SRC (2, -1)); - } - else if (x + 1 < w) - { - PIX (1, -1) = BIADAPT_GETPIX (SRC (1, -1)); - PIX (2, -1) = PIX (1, -1); - } - else - { - PIX (1, -1) = PIX (0, -1); - PIX (2, -1) = PIX (0, -1); - } - } - else - { - PIX (-1, -1) = PIX (-1, 0); - PIX (0, -1) = PIX (0, 0); - PIX (1, -1) = PIX (1, 0); - PIX (2, -1) = PIX (2, 0); - } - - // check pixel below the current one - if (!(cmatch & 1)) - { - if (BIADAPT_CMPYUV (PIX (0, 0), PIX (0, 1)) <= BIADAPT_YUVLOW) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (0, 1)) - ); - cmatch |= 1; - } - // detect a 2:1 line going across the current pixel - else if ( (PIX (0, 0) == PIX (-1, 0) - && PIX (0, 0) == PIX (1, 1) - && PIX (0, 0) == PIX (2, 1) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) || - - (PIX (0, 0) == PIX (1, 0) - && PIX (0, 0) == PIX (-1, 1) - && PIX (0, 0) == PIX (2, -1) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 0))))) ) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 0)); - } - // detect a 2:1 line going across the pixel below current - else if ( (PIX (0, 1) == PIX (-1, 0) - && PIX (0, 1) == PIX (1, 1) - && PIX (0, 1) == PIX (2, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 2))))) || - - (PIX (0, 1) == PIX (1, 0) - && PIX (0, 1) == PIX (-1, 1) - && PIX (0, 1) == PIX (2, 0) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, -1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (-1, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (0, 2)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 1), PIX (2, 1))))) ) - { - BIADAPT_SETPIX (dst_p + dlen, PIX (0, 1)); - } - else - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (0, 1)) - ); - } - - dst_p++; - - // check pixel to the right from the current one - if (!(cmatch & 2)) - { - if (BIADAPT_CMPYUV (PIX (0, 0), PIX (1, 0)) <= BIADAPT_YUVLOW) - { - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 0)) - ); - cmatch |= 2; - } - // detect a 1:2 line going across the current pixel - else if ( (PIX (0, 0) == PIX (1, -1) - && PIX (0, 0) == PIX (0, 1) - && PIX (0, 0) == PIX (-1, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 1))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))))) || - - (PIX (0, 0) == PIX (0, -1) - && PIX (0, 0) == PIX (1, 1) - && PIX (0, 0) == PIX (1, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (-1, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (0, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (0, 0), PIX (2, 2))))) ) - - { - BIADAPT_SETPIX (dst_p, PIX (0, 0)); - } - // detect a 1:2 line going across the pixel to the right - else if ( (PIX (1, 0) == PIX (1, -1) - && PIX (1, 0) == PIX (0, 1) - && PIX (1, 0) == PIX (0, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))))) || - - (PIX (1, 0) == PIX (0, -1) - && PIX (1, 0) == PIX (1, 1) - && PIX (1, 0) == PIX (2, 2) && - - ((!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (-1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (0, 1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, 2))) || - (!BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (1, -1)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 0)) - && !BIADAPT_CMPRGB_HIGH (PIX (1, 0), PIX (2, 1))))) ) - { - BIADAPT_SETPIX (dst_p, PIX (1, 0)); - } - else - BIADAPT_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 0)) - ); - } - - if (PIX (0, 0) == PIX (1, 1) && PIX (1, 0) == PIX (0, 1)) - { - // diagonals are equal - int *coord; - int cl, cr; - Uint32 clr; - - // both pairs are equal, have to resolve the pixel - // race; we try detecting which color is - // the background by looking for a line or an edge - // examine 8 pixels surrounding the current quad - - cl = cr = 2; - for (coord = resolve_coord[0]; *coord < 100; coord += 2) - { - clr = PIX (coord[0], coord[1]); - - if (BIADAPT_CMPYUV_MED (clr, PIX (0, 0))) - cl++; - else if (BIADAPT_CMPYUV_MED (clr, PIX (1, 0))) - cr++; - } - - // least count wins - if (cl > cr) - clr = PIX (1, 0); - else if (cr > cl) - clr = PIX (0, 0); - else - clr = Scale_BlendPixels_2 (blend2, - PIX (0, 0), PIX (1, 0)); - - BIADAPT_SETPIX (dst_p + dlen, clr); - continue; - } - - if (cmatch == 3 - || (BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (0, 1)) - && BIADAPT_CMPYUV_LOW (PIX (1, 0), PIX (1, 1)))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 1), PIX (1, 0)) - ); - continue; - } - else if (cmatch && BIADAPT_CMPYUV_LOW (PIX (0, 0), PIX (1, 1))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - continue; - } - - // check pixel to the bottom-right - if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1)) - && BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1))) - { - if (Scale_GetPixY (fmt, PIX (0, 0)) - > Scale_GetPixY (fmt, PIX (1, 0))) - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - } - else - { - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - } - else if (BIADAPT_CMPYUV_HIGH (PIX (0, 0), PIX (1, 1))) - { - // main diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (0, 0), PIX (1, 1)) - ); - } - else if (BIADAPT_CMPYUV_HIGH (PIX (1, 0), PIX (0, 1))) - { - // 2nd diagonal is same color - // use its value - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - else - { - // blend all 4 - BIADAPT_SETPIX (dst_p + dlen, Scale_BlendPixels_4 ( - blend4, PIX (0, 0), PIX (0, 1), - PIX (1, 0), PIX (1, 1) - )); - } - } - } - break; - } - #undef BIADAPT_GETPIX - #undef BIADAPT_SETPIX - #undef BIADAPT_BUF - } - - #undef BIADAPT_CMPRGB - #undef BIADAPT_CMPRGB_HIGH - #undef BIADAPT_CMPYUV - #undef BIADAPT_CMPYUV_LOW - #undef BIADAPT_CMPYUV_MED - #undef BIADAPT_CMPYUV_HIGH - - #undef PIX - #undef SRC -} - - -// triscan scaling to 2x -// derivative of scale2x -- scale2x.sf.net -void -Scale_TriScanFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) -{ - int x, y; - const int w = src->w, h = src->h; - int xend, yend; - int dsrc, ddst; - SDL_Rect *region = r; - SDL_Rect limits; - SDL_PixelFormat *fmt = dst->format; - BLEND_PARAMS blend2; - bool eqflag; - const int p = src->pitch, dp = dst->pitch; - const int bpp = fmt->BytesPerPixel; - const int len = p / bpp, dlen = dp / bpp; - // for clarity purposes, the 'pixels' array here is transposed - Uint32 pixels[3][3]; - - // these macros are for clarity; they make the current pixel (0,0) - // and allow to access pixels in all directions - #define PIX(x, y) (pixels[1 + (x)][1 + (y)]) - #define SRC(x, y) (src_p + (x) + ((y) * len)) - - #define TRISCAN_YUV_MED 100 - - #define TRISCAN_CMPYUV_T(p1, p2, toler) \ - Scale_CmpYUV (fmt, p1, p2, toler) - // medium tolerance pixel comparison - #define TRISCAN_CMPYUV(p1, p2) \ - (p1 == p2 || TRISCAN_CMPYUV_T (p1, p2, TRISCAN_YUV_MED)) - #define TRISCAN_CMPYUV_FLAG(p1, p2) \ - ((eqflag = true, p1 == p2) || \ - (eqflag = false, TRISCAN_CMPYUV_T (p1, p2, TRISCAN_YUV_MED))) - - // expand updated region if necessary - // pixels neighbooring the updated region may - // change as a result of updates - limits.x = 0; - limits.y = 0; - limits.w = src->w; - limits.h = src->h; - Scale_ExpandRect (region, 1, &limits); - - xend = region->x + region->w; - yend = region->y + region->h; - dsrc = len - region->w; - ddst = (dlen - region->w) * 2; - - // precompute the blending masks and shifts - Scale_CalcBlendMasks (fmt, 2, &blend2); - - switch (fmt->BytesPerPixel) - { - case 2: // 16bpp scaling - #define TRISCAN_GETPIX(p) ( *(Uint16 *)(p) ) - #define TRISCAN_SETPIX(p, c) ( *(Uint16 *)(p) = (c) ) - #define TRISCAN_BUF Uint16 - { - TRISCAN_BUF *src_p = (TRISCAN_BUF *)src->pixels; - TRISCAN_BUF *dst_p = (TRISCAN_BUF *)dst->pixels; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - PIX (0, 0) = PIX (1, 0) = TRISCAN_GETPIX (SRC (0, 0)); - - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - // copy already fetched pixels as we move across - PIX (-1, 0) = PIX (0, 0); - PIX ( 0, 0) = PIX (1, 0); - - PIX (0, -1) = y > 0 ? TRISCAN_GETPIX (SRC (0, -1)) - : PIX(0, 0); - PIX (0, 1) = y + 1 < h ? TRISCAN_GETPIX (SRC (0, 1)) - : PIX(0, 0); - PIX (1, 0) = x + 1 < w ? TRISCAN_GETPIX (SRC (1, 0)) - : PIX(0, 0); - - if (!TRISCAN_CMPYUV(PIX (0, -1), PIX (0, 1)) && - !TRISCAN_CMPYUV(PIX (-1, 0), PIX (1, 0))) - { - if (TRISCAN_CMPYUV_FLAG(PIX (-1, 0), PIX (0, -1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p, PIX (-1, 0)); - else - TRISCAN_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (-1, 0), PIX (0, -1)) - ); - } - else - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - - if (TRISCAN_CMPYUV_FLAG(PIX (-1, 0), PIX (0, 1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p + dlen, PIX (-1, 0)); - else - TRISCAN_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (-1, 0), PIX (0, 1)) - ); - } - else - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - - ++dst_p; - - if (TRISCAN_CMPYUV_FLAG(PIX (1, 0), PIX (0, -1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p, PIX (1, 0)); - else - TRISCAN_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, -1)) - ); - } - else - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - - if (TRISCAN_CMPYUV_FLAG(PIX (1, 0), PIX (0, 1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p + dlen, PIX (1, 0)); - else - TRISCAN_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - else - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - - } - else - { - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - ++dst_p; - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - } - } - } - break; - } - #undef TRISCAN_GETPIX - #undef TRISCAN_SETPIX - #undef TRISCAN_BUF - - case 3: // 24bpp scaling - #define TRISCAN_GETPIX(p) GET_PIX_24BIT(p) - #define TRISCAN_SETPIX(p, c) SET_PIX_24BIT(p, c) - #define TRISCAN_BUF PIXEL_24BIT - { - TRISCAN_BUF *src_p = (TRISCAN_BUF *)src->pixels; - TRISCAN_BUF *dst_p = (TRISCAN_BUF *)dst->pixels; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - PIX (0, 0) = PIX (1, 0) = TRISCAN_GETPIX (SRC (0, 0)); - - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - // copy already fetched pixels as we move across - PIX (-1, 0) = PIX (0, 0); - PIX ( 0, 0) = PIX (1, 0); - - PIX (0, -1) = y > 0 ? TRISCAN_GETPIX (SRC (0, -1)) - : PIX(0, 0); - PIX (0, 1) = y + 1 < h ? TRISCAN_GETPIX (SRC (0, 1)) - : PIX(0, 0); - PIX (1, 0) = x + 1 < w ? TRISCAN_GETPIX (SRC (1, 0)) - : PIX(0, 0); - - if (!TRISCAN_CMPYUV(PIX (0, -1), PIX (0, 1)) && - !TRISCAN_CMPYUV(PIX (-1, 0), PIX (1, 0))) - { - if (TRISCAN_CMPYUV_FLAG(PIX (-1, 0), PIX (0, -1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p, PIX (-1, 0)); - else - TRISCAN_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (-1, 0), PIX (0, -1)) - ); - } - else - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - - if (TRISCAN_CMPYUV_FLAG(PIX (-1, 0), PIX (0, 1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p + dlen, PIX (-1, 0)); - else - TRISCAN_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (-1, 0), PIX (0, 1)) - ); - } - else - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - - ++dst_p; - - if (TRISCAN_CMPYUV_FLAG(PIX (1, 0), PIX (0, -1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p, PIX (1, 0)); - else - TRISCAN_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, -1)) - ); - } - else - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - - if (TRISCAN_CMPYUV_FLAG(PIX (1, 0), PIX (0, 1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p + dlen, PIX (1, 0)); - else - TRISCAN_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - else - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - - } - else - { - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - ++dst_p; - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - } - } - } - break; - } - #undef TRISCAN_GETPIX - #undef TRISCAN_SETPIX - #undef TRISCAN_BUF - - case 4: // 32bpp scaling - #define TRISCAN_GETPIX(p) ( *(Uint32 *)(p) ) - #define TRISCAN_SETPIX(p, c) ( *(Uint32 *)(p) = (c) ) - #define TRISCAN_BUF Uint32 - { - TRISCAN_BUF *src_p = (TRISCAN_BUF *)src->pixels; - TRISCAN_BUF *dst_p = (TRISCAN_BUF *)dst->pixels; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - PIX (0, 0) = PIX (1, 0) = TRISCAN_GETPIX (SRC (0, 0)); - - for (x = region->x; x < xend; ++x, ++src_p, ++dst_p) - { - // copy already fetched pixels as we move across - PIX (-1, 0) = PIX (0, 0); - PIX ( 0, 0) = PIX (1, 0); - - PIX (0, -1) = y > 0 ? TRISCAN_GETPIX (SRC (0, -1)) - : PIX(0, 0); - PIX (0, 1) = y + 1 < h ? TRISCAN_GETPIX (SRC (0, 1)) - : PIX(0, 0); - PIX (1, 0) = x + 1 < w ? TRISCAN_GETPIX (SRC (1, 0)) - : PIX(0, 0); - - if (!TRISCAN_CMPYUV(PIX (0, -1), PIX (0, 1)) && - !TRISCAN_CMPYUV(PIX (-1, 0), PIX (1, 0))) - { - if (TRISCAN_CMPYUV_FLAG(PIX (-1, 0), PIX (0, -1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p, PIX (-1, 0)); - else - TRISCAN_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (-1, 0), PIX (0, -1)) - ); - } - else - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - - if (TRISCAN_CMPYUV_FLAG(PIX (-1, 0), PIX (0, 1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p + dlen, PIX (-1, 0)); - else - TRISCAN_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (-1, 0), PIX (0, 1)) - ); - } - else - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - - ++dst_p; - - if (TRISCAN_CMPYUV_FLAG(PIX (1, 0), PIX (0, -1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p, PIX (1, 0)); - else - TRISCAN_SETPIX (dst_p, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, -1)) - ); - } - else - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - - if (TRISCAN_CMPYUV_FLAG(PIX (1, 0), PIX (0, 1))) - { - if (eqflag) - TRISCAN_SETPIX (dst_p + dlen, PIX (1, 0)); - else - TRISCAN_SETPIX (dst_p + dlen, Scale_BlendPixels_2 ( - blend2, PIX (1, 0), PIX (0, 1)) - ); - } - else - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - - } - else - { - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - ++dst_p; - TRISCAN_SETPIX (dst_p, PIX (0, 0)); - TRISCAN_SETPIX (dst_p + dlen, PIX (0, 0)); - } - } - } - break; - } - #undef TRISCAN_GETPIX - #undef TRISCAN_SETPIX - #undef TRISCAN_BUF - } - #undef TRISCAN_CMPYUV_FLAG - #undef TRISCAN_CMPYUV - #undef TRISCAN_CMPYUV_T -} - - -// nearest neighbor scaling to 2x -void Scale_Nearest (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) -{ - int x, y; - const int x0 = r->x, y0 = r->y, rw = r->w, rh = r->h; - const int p = src->pitch, dp = dst->pitch; - const int bpp = dst->format->BytesPerPixel; - const int len = p / bpp, dlen = dp / bpp; - const int ds = len-rw, dd = (dlen-rw) * 2; - - switch (dst->format->BytesPerPixel) - { - case 2: - { - Uint16 *src_p = (Uint16 *)src->pixels, *dst_p = (Uint16 *)dst->pixels; - Uint16 pixval_16; - src_p += len*y0 + x0; - dst_p += (dlen*y0 + x0) * 2; - for (y = 0; y < rh; ++y) - { - for (x = 0; x < rw; ++x) - { - pixval_16 = *src_p++; - dst_p[dlen] = pixval_16; - *dst_p++ = pixval_16; - dst_p[dlen] = pixval_16; - *dst_p++ = pixval_16; - } - dst_p += dd; - src_p += ds; - } - break; - } - case 3: - { - PIXEL_24BIT *src_p = (PIXEL_24BIT *)src->pixels; - PIXEL_24BIT *dst_p = (PIXEL_24BIT *)dst->pixels; - Uint32 pixval_32; - src_p += len*y0 + x0; - dst_p += (dlen*y0 + x0) * 2; - for (y = 0; y < rh; ++y) - { - for (x = 0; x < rw; ++x, ++src_p) - { - pixval_32 = GET_PIX_24BIT (src_p); - SET_PIX_24BIT (dst_p, pixval_32); - SET_PIX_24BIT (dst_p + dlen, pixval_32); - dst_p++; - SET_PIX_24BIT (dst_p, pixval_32); - SET_PIX_24BIT (dst_p + dlen, pixval_32); - dst_p++; - } - dst_p += dd; - src_p += ds; - } - break; - } - case 4: - { - Uint32 *src_p = (Uint32 *)src->pixels, *dst_p = (Uint32 *)dst->pixels; - Uint32 pixval_32; - src_p += len*y0 + x0; - dst_p += (dlen*y0 + x0) * 2; - for (y = 0; y < rh; ++y) - { - for (x = 0; x < rw; ++x) - { - pixval_32 = *src_p++; - dst_p[dlen] = pixval_32; - *dst_p++ = pixval_32; - dst_p[dlen] = pixval_32; - *dst_p++ = pixval_32; - } - dst_p += dd; - src_p += ds; - } - break; - } - } -} - -// bilinear weighted blend of four pixels -__inline__ Uint32 -Scale_BlendPixels_bilinear (BLEND_PARAMS bp, Uint32* p, const Uint32* w) -{ - if (bp.pre_shift) - { // high pre-shifted version - return (((((p[0] & bp.high_mask) >> 4) * w[0]) + - (((p[1] & bp.high_mask) >> 4) * w[1]) + - (((p[2] & bp.high_mask) >> 4) * w[2]) + - (((p[3] & bp.high_mask) >> 4) * w[3])) - & bp.high_mask) | - (((((p[0] & bp.low_mask) * w[0]) + - ((p[1] & bp.low_mask) * w[1]) + - ((p[2] & bp.low_mask) * w[2]) + - ((p[3] & bp.low_mask) * w[3])) - >> 4) & bp.low_mask); - } - else - { // high post-shifted version - return (((((p[0] & bp.high_mask) * w[0]) + - ((p[1] & bp.high_mask) * w[1]) + - ((p[2] & bp.high_mask) * w[2]) + - ((p[3] & bp.high_mask) * w[3])) - >> 4) & bp.high_mask) | - (((((p[0] & bp.low_mask) * w[0]) + - ((p[1] & bp.low_mask) * w[1]) + - ((p[2] & bp.low_mask) * w[2]) + - ((p[3] & bp.low_mask) * w[3])) - >> 4) & bp.low_mask); - } -} - -// bilinear scaling to 2x -void Scale_BilinearFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r) -{ - int x, y; - const int w = src->w, h = src->h; - int xend, yend; - int dsrc, ddst; - SDL_Rect *region = r; - SDL_Rect limits; - SDL_PixelFormat *fmt = dst->format; - BLEND_PARAMS blend16; - const int pitch = src->pitch, dp = dst->pitch; - const int bpp = fmt->BytesPerPixel; - const int len = pitch / bpp, dlen = dp / bpp; - Uint32 p[4]; // influential pixels array - - - // expand updated region if necessary - // pixels neighbooring the updated region may - // change as a result of updates - limits.x = 0; - limits.y = 0; - limits.w = w; - limits.h = h; - Scale_ExpandRect (region, 1, &limits); - - xend = region->x + region->w; - yend = region->y + region->h; - dsrc = len - region->w; - ddst = (dlen - region->w) * 2; - - // precompute the blending masks and shifts - Scale_CalcChannelMasks (fmt, 16, &blend16); - - // TODO: expand weight matrix in the code - // so that compiler can optimize the mults? - - switch (dst->format->BytesPerPixel) - { - case 2: - { - Uint16 *src_p = (Uint16 *) src->pixels; - Uint16 *dst_p = (Uint16 *) dst->pixels; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - p[0] = src_p[0]; - if (y < h - 1) - p[2] = src_p[len]; - else - p[2] = 0; - - for (x = region->x; x < xend; ++x, ++src_p) - { - if (y < h - 1) - { - if (x < w - 1) - { - p[1] = src_p[1]; - p[3] = src_p[len + 1]; - } - else - { - p[1] = 0; - p[3] = 0; - } - } - else - { - if (x < w - 1) - p[1] = src_p[1]; - else - p[1] = 0; - p[3] = 0; - } - - *dst_p = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[0] - ); - - *(dst_p + dlen) = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[1] - ); - - ++dst_p; - - *dst_p = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[2] - ); - - *(dst_p + dlen) = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[3] - ); - - ++dst_p; - - p[0] = p[1]; - p[2] = p[3]; - } - } - - break; - } - case 3: - { - PIXEL_24BIT *src_p = (PIXEL_24BIT *) src->pixels; - PIXEL_24BIT *dst_p = (PIXEL_24BIT *) dst->pixels; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - p[0] = GET_PIX_24BIT (src_p); - if (y < h - 1) - p[2] = GET_PIX_24BIT (src_p + len); - else - p[2] = 0; - - for (x = region->x; x < xend; ++x, ++src_p) - { - if (y < h - 1) - { - if (x < w - 1) - { - p[1] = GET_PIX_24BIT (src_p + 1); - p[3] = GET_PIX_24BIT (src_p + len + 1); - } - else - { - p[1] = 0; - p[3] = 0; - } - } - else - { - if (x < w - 1) - p[1] = GET_PIX_24BIT (src_p + 1); - else - p[1] = 0; - p[3] = 0; - } - - SET_PIX_24BIT (dst_p, Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[0] - )); - - SET_PIX_24BIT (dst_p + dlen, Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[1] - )); - - ++dst_p; - - SET_PIX_24BIT (dst_p, Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[2] - )); - - SET_PIX_24BIT (dst_p + dlen, Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[3] - )); - - ++dst_p; - - p[0] = p[1]; - p[2] = p[3]; - } - } - - break; - } - case 4: - { - Uint32 *src_p = (Uint32 *) src->pixels; - Uint32 *dst_p = (Uint32 *) dst->pixels; - - // move ptrs to the first updated pixel - src_p += len * region->y + region->x; - dst_p += (dlen * region->y + region->x) * 2; - - for (y = region->y; y < yend; ++y, dst_p += ddst, src_p += dsrc) - { - p[0] = src_p[0]; - if (y < h - 1) - p[2] = src_p[len]; - else - p[2] = 0; - - for (x = region->x; x < xend; ++x, ++src_p) - { - if (y < h - 1) - { - if (x < w - 1) - { - p[1] = src_p[1]; - p[3] = src_p[len + 1]; - } - else - { - p[1] = 0; - p[3] = 0; - } - } - else - { - if (x < w - 1) - p[1] = src_p[1]; - else - p[1] = 0; - p[3] = 0; - } - - *dst_p = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[0] - ); - - *(dst_p + dlen) = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[1] - ); - - ++dst_p; - - *dst_p = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[2] - ); - - *(dst_p + dlen) = Scale_BlendPixels_bilinear ( - blend16, p, bilinear_table[3] - ); + pixval_tl = SCALE_GETPIX (SRC (0, 0)); - ++dst_p; + SCALE_SETPIX (dst_p, pixval_tl); + + if (y + 1 < h) + { + // check pixel below the current one + pixval_bl = SCALE_GETPIX (SRC (0, 1)); + + if (pixval_tl == pixval_bl) + SCALE_SETPIX (dst_p + dlen, pixval_tl); + else + SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 ( + pixval_tl, pixval_bl) + ); + } + else + { + // last pixel in column - propagate + SCALE_SETPIX (dst_p + dlen, pixval_tl); + pixval_bl = pixval_tl; + } + ++dst_p; + + if (x + 1 >= w) + { + // last pixel in row - propagate + SCALE_SETPIX (dst_p, pixval_tl); + + if (pixval_tl == pixval_bl) + SCALE_SETPIX (dst_p + dlen, pixval_tl); + else + SCALE_SETPIX (dst_p + dlen, Scale_Blend_11 ( + pixval_tl, pixval_bl) + ); + continue; + } + + // check pixel to the right from the current one + pixval_tr = SCALE_GETPIX (SRC (1, 0)); + + if (pixval_tl == pixval_tr) + SCALE_SETPIX (dst_p, pixval_tr); + else + SCALE_SETPIX (dst_p, Scale_Blend_11 ( + pixval_tl, pixval_tr) + ); + + if (y + 1 >= h) + { + // last pixel in column - propagate + SCALE_SETPIX (dst_p + dlen, pixval_tl); + continue; + } + + // check pixel to the bottom-right + pixval_br = SCALE_GETPIX (SRC (1, 1)); + + if (pixval_tl == pixval_br && pixval_tr == pixval_bl) + { + int cl, cr; + Uint32 clr; + + if (pixval_tl == pixval_tr) + { + // all 4 are equal - propagate + SCALE_SETPIX (dst_p + dlen, pixval_tl); + continue; + } + + // both pairs are equal, have to resolve the pixel + // race; we try detecting which color is + // the background by looking for a line or an edge + // examine 8 pixels surrounding the current quad + + cl = cr = 1; + + if (x > 0) + { + clr = SCALE_GETPIX (SRC (-1, 0)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + + clr = SCALE_GETPIX (SRC (-1, 1)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + } + + if (y > 0) + { + clr = SCALE_GETPIX (SRC (0, -1)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + + clr = SCALE_GETPIX (SRC (1, -1)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + } + + if (x + 2 < w) + { + clr = SCALE_GETPIX (SRC (2, 0)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + + clr = SCALE_GETPIX (SRC (2, 1)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + } + + if (y + 2 < h) + { + clr = SCALE_GETPIX (SRC (0, 2)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + + clr = SCALE_GETPIX (SRC (1, 2)); + if (clr == pixval_tl) + cl++; + else if (clr == pixval_tr) + cr++; + } - p[0] = p[1]; - p[2] = p[3]; + // least count wins + if (cl > cr) + SCALE_SETPIX (dst_p + dlen, pixval_tr); + else if (cr > cl) + SCALE_SETPIX (dst_p + dlen, pixval_tl); + else + SCALE_SETPIX (dst_p + dlen, + Scale_Blend_11 (pixval_tl, pixval_tr)); + } + else if (pixval_tl == pixval_br) + { + // main diagonal is same color + // use its value + SCALE_SETPIX (dst_p + dlen, pixval_tl); + } + else if (pixval_tr == pixval_bl) + { + // 2nd diagonal is same color + // use its value + SCALE_SETPIX (dst_p + dlen, pixval_tr); + } + else + { + // blend all 4 + SCALE_SETPIX (dst_p + dlen, Scale_Blend_1111 ( + pixval_tl, pixval_bl, pixval_tr, pixval_br + )); } } + } - break; - } - } + SCALE_(PlatDone) (); } -#endif +#endif /* GFXMODULE_SDL */ diff --git a/sc2/src/sc2code/libs/graphics/sdl/2xscalers.h b/sc2/src/sc2code/libs/graphics/sdl/2xscalers.h index 68e19885b..4066366ec 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/2xscalers.h +++ b/sc2/src/sc2code/libs/graphics/sdl/2xscalers.h @@ -1,4 +1,3 @@ -//Copyright Paul Reiche, Fred Ford. 1992-2002 /* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -18,11 +17,14 @@ #ifndef _2XSCALERS_H_ #define _2XSCALERS_H_ -void Scale_PrepYUV (void); void Scale_Nearest (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r); void Scale_BilinearFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r); void Scale_BiAdaptFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r); void Scale_BiAdaptAdvFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r); void Scale_TriScanFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r); +void Scale_HqFilter (SDL_Surface *src, SDL_Surface *dst, SDL_Rect *r); -#endif +extern const Scale_FuncDef_t Scale_C_Functions[]; + + +#endif /* _2XSCALERS_H_ */ diff --git a/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c b/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c index e4285417c..4290c45dd 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c +++ b/sc2/src/sc2code/libs/graphics/sdl/3do_getbody.c @@ -388,6 +388,7 @@ FRAMEPTR Build_Font_Effect (FRAMEPTR FramePtr, Uint32 from, Uint32 to, BYTE type to_a = to & 0xFF; clear = SDL_MapRGBA (img->format, 0, 0, 0, 0); + TFB_DrawCanvas_SetTransparentColor (img, 0, 0, 0, FALSE); for (y = 0; y < 2; y++) for (x = 0; x < width; x++) putpix (img, x, y, clear); @@ -842,7 +843,8 @@ _request_drawable (COUNT NumFrames, DRAWABLE_TYPE DrawableType, TFB_Image *Image; if (DrawableType == RAM_DRAWABLE && imgw > 0 && imgh > 0 - && (Image = TFB_DrawImage_New (TFB_DrawCanvas_New_TrueColor (imgw, imgh, FALSE)))) + && (Image = TFB_DrawImage_New (TFB_DrawCanvas_New_TrueColor ( + imgw, imgh, (flags & WANT_ALPHA) ? TRUE : FALSE)))) { FramePtr->image = Image; } diff --git a/sc2/src/sc2code/libs/graphics/sdl/Makeinfo b/sc2/src/sc2code/libs/graphics/sdl/Makeinfo index 96490b1f6..cad9c0037 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/Makeinfo +++ b/sc2/src/sc2code/libs/graphics/sdl/Makeinfo @@ -1,3 +1,6 @@ uqm_CFILES="3do_blt.c 3do_funcs.c 3do_getbody.c dcqueue.c opengl.c primitives.c pure.c rndzoom.c sdl_common.c - canvas.c bbox.c 2xscalers.c sdluio.c rotozoom.c" + scalers.c 2xscalers.c + 2xscalers_mmx.c 2xscalers_sse.c 2xscalers_3dnow.c + nearest2x.c bilinear2x.c biadv2x.c triscan2x.c hq2x.c + canvas.c bbox.c sdluio.c rotozoom.c" diff --git a/sc2/src/sc2code/libs/graphics/sdl/canvas.c b/sc2/src/sc2code/libs/graphics/sdl/canvas.c index e739e63e9..09a596590 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/canvas.c +++ b/sc2/src/sc2code/libs/graphics/sdl/canvas.c @@ -154,7 +154,11 @@ TFB_Canvas TFB_DrawCanvas_New_TrueColor (int w, int h, BOOLEAN hasalpha) { SDL_Surface *new_surf; - new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, hasalpha ? 0xff000000 : 0); + SDL_PixelFormat* fmt = format_conv_surf->format; + + new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, + fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, + hasalpha ? fmt->Amask : 0); if (!new_surf) { fprintf(stderr, "INTERNAL PANIC: Failed to create TFB_Canvas: %s", SDL_GetError()); exit(-1); @@ -173,12 +177,13 @@ TFB_DrawCanvas_New_ForScreen (int w, int h, BOOLEAN withalpha) fprintf(stderr, "TFB_DrawCanvas_New_ForScreen() WARNING:" "Paletted display format will be slow"); - new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, - 32, 0x000000ff, 0x0000ff00, 0x00ff0000, - withalpha ? 0xff000000 : 0); + new_surf = TFB_DrawCanvas_New_TrueColor (w, h, withalpha); } else { + if (withalpha && fmt->Amask == 0) + fmt = format_conv_surf->format; // Screen has no alpha and we need it + new_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, w, h, fmt->BitsPerPixel, fmt->Rmask, fmt->Gmask, fmt->Bmask, withalpha ? fmt->Amask : 0); @@ -259,8 +264,10 @@ TFB_DrawCanvas_New_ScaleTarget (TFB_Canvas canvas, TFB_Canvas oldcanvas, int typ } if (!old) { - newsurf = SDL_CreateRGBSurface (SDL_SWSURFACE, src->w, src->h, 32, - 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000); + if (SDL_Screen->format->BitsPerPixel == 32) + newsurf = TFB_DrawCanvas_New_ForScreen (src->w, src->h, TRUE); + else + newsurf = TFB_DrawCanvas_New_TrueColor (src->w, src->h, TRUE); } } @@ -348,8 +355,12 @@ TFB_DrawCanvas_ToScreenFormat (TFB_Canvas canvas) fprintf (stderr, "WARNING: Could not convert sprite-canvas to display format.\n"); return canvas; } + else if (result == canvas) + { // no conversion was necessary + return canvas; + } else - { + { // converted TFB_DrawCanvas_Delete (canvas); return result; } @@ -590,7 +601,8 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, SDL_Surface *dst = (SDL_Surface *)dest_canvas; SDL_Surface *mipmap = (SDL_Surface *)src_mipmap; SDL_PixelFormat *dstfmt = dst->format; - const int dstopaque = 0xff << dstfmt->Ashift; + const int dstopaque = dstfmt->Amask; + const int dsttransparent = (dst->flags & SDL_SRCCOLORKEY) ? dstfmt->colorkey : 0; const int w = size.width, h = size.height; const int ALPHA_THRESHOLD = 128; @@ -785,7 +797,7 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, } else { - *dst_p++ = 0; + *dst_p++ = dsttransparent; } sx0 += fsx0; @@ -985,7 +997,7 @@ TFB_DrawCanvas_Rescale_Trilinear (TFB_Canvas src_canvas, TFB_Canvas dest_canvas, } else { - *dst_p++ = 0; + *dst_p++ = dsttransparent; } sx0 += fsx0; diff --git a/sc2/src/sc2code/libs/graphics/sdl/opengl.c b/sc2/src/sc2code/libs/graphics/sdl/opengl.c index f221afbae..4b4064200 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/opengl.c +++ b/sc2/src/sc2code/libs/graphics/sdl/opengl.c @@ -20,18 +20,18 @@ #include "libs/graphics/sdl/opengl.h" #include "bbox.h" -#include "2xscalers.h" +#include "scalers.h" -static SDL_Surface *format_conv_surf = NULL; static SDL_Surface *scaled_display = NULL; static SDL_Surface *scaled_transition = NULL; static int ScreenFilterMode; static GLuint DisplayTexture; static GLuint TransitionTexture; -static BOOLEAN scanlines; static BOOLEAN upload_transitiontexture = FALSE; +static TFB_ScaleFunc scaler = NULL; + #if SDL_BYTEORDER == SDL_BIG_ENDIAN #define R_MASK 0xff000000 #define G_MASK 0x00ff0000 @@ -46,16 +46,26 @@ static BOOLEAN upload_transitiontexture = FALSE; static SDL_Surface * -Create_Screen (void) +Create_Screen (SDL_Surface *template, int w, int h) { - SDL_Surface *result = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth, ScreenHeight, 32, - R_MASK, G_MASK, B_MASK, 0x00000000); - if (result == NULL) - { - fprintf (stderr, "Couldn't create screen buffer: %s\n", SDL_GetError()); - exit (-1); + SDL_Surface *newsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, + template->format->BitsPerPixel, + template->format->Rmask, template->format->Gmask, + template->format->Bmask, 0); + if (newsurf == 0) { + fprintf (stderr, "Couldn't create screen buffers: %s\n", SDL_GetError()); } - return result; + return newsurf; +} + +static int +ReInit_Screen (SDL_Surface **screen, SDL_Surface *template, int w, int h) +{ + if (*screen) + SDL_FreeSurface (*screen); + *screen = Create_Screen (template, w, h); + + return *screen == 0 ? -1 : 0; } int @@ -122,48 +132,9 @@ TFB_GL_ConfigureVideo (int driver, int flags, int width, int height, int bpp) glGetString (GL_RENDERER), glGetString (GL_VERSION)); } - if (GfxFlags & TFB_GFXFLAGS_SCALE_SOFT_ONLY) - { - if (scaled_display) - { - SDL_FreeSurface (scaled_display); - scaled_display = NULL; - } - scaled_display = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth * 2, - ScreenHeight * 2, 32, R_MASK, G_MASK, B_MASK, 0x00000000); - if (scaled_display == NULL) - { - fprintf (stderr, "Couldn't create scaled_display: %s\n", SDL_GetError()); - return -1; - } - if (scaled_transition) - { - SDL_FreeSurface (scaled_transition); - scaled_transition = NULL; - } - scaled_transition = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth * 2, - ScreenHeight * 2, 32, R_MASK, G_MASK, B_MASK, 0x00000000); - if (scaled_transition == NULL) - { - fprintf (stderr, "Couldn't create scaled_transition: %s\n", SDL_GetError()); - return -1; - } - - texture_width = 1024; - texture_height = 512; - } - else - { - texture_width = 512; - texture_height = 256; - } - if (format_conv_surf) - { SDL_FreeSurface (format_conv_surf); - format_conv_surf = NULL; - } - format_conv_surf = SDL_CreateRGBSurface(SDL_SWSURFACE, 0, 0, 32, + format_conv_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0, 32, R_MASK, G_MASK, B_MASK, A_MASK); if (format_conv_surf == NULL) { @@ -171,25 +142,44 @@ TFB_GL_ConfigureVideo (int driver, int flags, int width, int height, int bpp) return -1; } - if (GfxFlags & TFB_GFXFLAGS_SCALE_ANY) - ScreenFilterMode = GL_LINEAR; - else - ScreenFilterMode = GL_NEAREST; - - if (flags & TFB_GFXFLAGS_SCANLINES) - scanlines = TRUE; - else - scanlines = FALSE; - - /* TODO: This leaks */ for (i = 0; i < TFB_GFX_NUMSCREENS; i++) { - SDL_Screens[i] = Create_Screen (); + if (0 != ReInit_Screen (&SDL_Screens[i], format_conv_surf, + ScreenWidth, ScreenHeight)) + return -1; } SDL_Screen = SDL_Screens[0]; TransitionScreen = SDL_Screens[2]; + if (GfxFlags & TFB_GFXFLAGS_SCALE_SOFT_ONLY) + { + if (0 != ReInit_Screen (&scaled_display, format_conv_surf, + ScreenWidth * 2, ScreenHeight * 2)) + return -1; + + if (0 != ReInit_Screen (&scaled_transition, format_conv_surf, + ScreenWidth * 2, ScreenHeight * 2)) + return -1; + + texture_width = 1024; + texture_height = 512; + + scaler = Scale_PrepPlatform (flags, SDL_Screen->format); + } + else + { + texture_width = 512; + texture_height = 256; + + scaler = NULL; + } + + if (GfxFlags & TFB_GFXFLAGS_SCALE_ANY) + ScreenFilterMode = GL_LINEAR; + else + ScreenFilterMode = GL_NEAREST; + glViewport (0, 0, ScreenWidthActual, ScreenHeightActual); glClearColor (0,0,0,0); glClear (GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); @@ -236,8 +226,8 @@ TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp) exit (-1); } - // pre-compute the RGB->YUV transformations - Scale_PrepYUV(); + // Initialize scalers (let them precompute whatever) + Scale_Init (); return 0; } @@ -290,7 +280,7 @@ TFB_GL_DrawQuad (void) glEnd (); } -void +void TFB_GL_SwapBuffers (int force_full_redraw) { int fade_amount = FadeAmount; @@ -322,14 +312,9 @@ TFB_GL_SwapBuffers (int force_full_redraw) updated.w = TFB_BBox.region.extent.width; updated.h = TFB_BBox.region.extent.height; - if (GfxFlags & TFB_GFXFLAGS_SCALE_SOFT_ONLY) + if (scaler) { - if (GfxFlags & TFB_GFXFLAGS_SCALE_BIADAPT) - Scale_BiAdaptFilter (SDL_Screen, scaled_display, &updated); - else if (GfxFlags & TFB_GFXFLAGS_SCALE_BIADAPTADV) - Scale_BiAdaptAdvFilter (SDL_Screen, scaled_display, &updated); - else if (GfxFlags & TFB_GFXFLAGS_SCALE_TRISCAN) - Scale_TriScanFilter (SDL_Screen, scaled_display, &updated); + scaler (SDL_Screen, scaled_display, &updated); glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth * 2); glPixelStorei (GL_UNPACK_SKIP_ROWS, updated.y * 2); @@ -362,18 +347,14 @@ TFB_GL_SwapBuffers (int force_full_redraw) if (upload_transitiontexture) { - if (GfxFlags & TFB_GFXFLAGS_SCALE_SOFT_ONLY) + if (scaler) { SDL_Rect r; r.x = r.y = 0; r.w = ScreenWidth; r.h = ScreenHeight; - if (GfxFlags & TFB_GFXFLAGS_SCALE_BIADAPT) - Scale_BiAdaptFilter (TransitionScreen, scaled_transition, &r); - else if (GfxFlags & TFB_GFXFLAGS_SCALE_BIADAPTADV) - Scale_BiAdaptAdvFilter (TransitionScreen, scaled_transition, &r); - else if (GfxFlags & TFB_GFXFLAGS_SCALE_TRISCAN) - Scale_TriScanFilter (TransitionScreen, scaled_transition, &r); + + scaler (TransitionScreen, scaled_transition, &r); glPixelStorei (GL_UNPACK_ROW_LENGTH, ScreenWidth * 2); glPixelStorei (GL_UNPACK_SKIP_ROWS, 0); @@ -441,20 +422,4 @@ TFB_GL_SwapBuffers (int force_full_redraw) SDL_GL_SwapBuffers (); } -SDL_Surface* -TFB_GL_DisplayFormatAlpha (SDL_Surface *surface) -{ - SDL_Surface* newsurf; - - newsurf = SDL_ConvertSurface (surface, format_conv_surf->format, surface->flags); - // SDL_SRCCOLORKEY and SDL_SRCALPHA cannot work at the same time, - // so we need to disable one of them - if ((surface->flags & SDL_SRCCOLORKEY) && newsurf - && (newsurf->flags & SDL_SRCCOLORKEY) - && (newsurf->flags & SDL_SRCALPHA)) - SDL_SetAlpha (newsurf, 0, 255); - - return newsurf; -} - #endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/opengl.h b/sc2/src/sc2code/libs/graphics/sdl/opengl.h index d1c224e0f..395a85925 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/opengl.h +++ b/sc2/src/sc2code/libs/graphics/sdl/opengl.h @@ -25,7 +25,6 @@ int TFB_GL_InitGraphics (int driver, int flags, int width, int height, int bpp); int TFB_GL_ConfigureVideo (int driver, int flags, int width, int height, int bpp); void TFB_GL_UploadTransitionScreen (void); void TFB_GL_SwapBuffers (int force_full_redraw); -SDL_Surface* TFB_GL_DisplayFormatAlpha (SDL_Surface *surface); #ifdef HAVE_OPENGL diff --git a/sc2/src/sc2code/libs/graphics/sdl/pure.c b/sc2/src/sc2code/libs/graphics/sdl/pure.c index bd5677e0d..c5dd1bedd 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/pure.c +++ b/sc2/src/sc2code/libs/graphics/sdl/pure.c @@ -19,29 +19,44 @@ #include "pure.h" #include "bbox.h" -#include "2xscalers.h" +#include "scalers.h" static SDL_Surface *fade_black = NULL; static SDL_Surface *fade_white = NULL; static SDL_Surface *fade_temp = NULL; +static SDL_Surface *scaled_display = NULL; + +static TFB_ScaleFunc scaler = NULL; static SDL_Surface * -Create_Screen (SDL_Surface *template) +Create_Screen (SDL_Surface *template, int w, int h) { - SDL_Surface *newsurf = SDL_DisplayFormat (template); + SDL_Surface *newsurf = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, + template->format->BitsPerPixel, + template->format->Rmask, template->format->Gmask, + template->format->Bmask, 0); if (newsurf == 0) { fprintf (stderr, "Couldn't create screen buffers: %s\n", SDL_GetError()); - exit(-1); } return newsurf; } +static int +ReInit_Screen (SDL_Surface **screen, SDL_Surface *template, int w, int h) +{ + if (*screen) + SDL_FreeSurface (*screen); + *screen = Create_Screen (template, w, h); + + return *screen == 0 ? -1 : 0; +} + int TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height, int bpp) { int i, videomode_flags; - SDL_Surface *test_extra; - + SDL_Surface *temp_surf; + GraphicsDriver = driver; ScreenColorDepth = bpp; @@ -83,51 +98,67 @@ TFB_Pure_ConfigureVideo (int driver, int flags, int width, int height, int bpp) SDL_GetVideoSurface()->format->BitsPerPixel); } - test_extra = SDL_CreateRGBSurface(SDL_SWSURFACE, ScreenWidth, ScreenHeight, 32, - 0x000000ff, 0x0000ff00, 0x00ff0000, 0x00000000); - - if (test_extra == NULL) + // Create a 32bpp surface in a compatible format which will supply + // the format information to all other surfaces used in the game + if (format_conv_surf) { - fprintf (stderr, "Couldn't create back buffer: %s\n", SDL_GetError()); + SDL_FreeSurface (format_conv_surf); + format_conv_surf = NULL; + } + temp_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0, 32, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0x00000000); + if (temp_surf) + { // acquire a fast compatible format from SDL + format_conv_surf = SDL_DisplayFormatAlpha (temp_surf); + if (!format_conv_surf || format_conv_surf->format->BitsPerPixel != 32) + { // absolute fallback case + format_conv_surf = SDL_CreateRGBSurface (SDL_SWSURFACE, 0, 0, 32, + 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000); + } + SDL_FreeSurface (temp_surf); + } + if (!format_conv_surf) + { + fprintf (stderr, "Couldn't create format_conv_surf: %s\n", SDL_GetError()); return -1; } - + + for (i = 0; i < TFB_GFX_NUMSCREENS; i++) { - SDL_Screens[i] = Create_Screen (test_extra); + if (0 != ReInit_Screen (&SDL_Screens[i], format_conv_surf, + ScreenWidth, ScreenHeight)) + return -1; } SDL_Screen = SDL_Screens[0]; TransitionScreen = SDL_Screens[2]; - if (fade_white) - { - SDL_FreeSurface (fade_white); - fade_white = NULL; - } - fade_white = Create_Screen(test_extra); - SDL_FillRect (fade_white, NULL, SDL_MapRGB (fade_white->format, 255, 255, 255)); - if (fade_black) - { - SDL_FreeSurface (fade_black); - fade_black = NULL; - } - fade_black = Create_Screen(test_extra); - SDL_FillRect (fade_black, NULL, SDL_MapRGB (fade_black->format, 0, 0, 0)); - if (fade_temp) - { - SDL_FreeSurface (fade_temp); - fade_temp = NULL; - } - fade_temp = Create_Screen(test_extra); - - SDL_FreeSurface (test_extra); - - if (SDL_Video->format->BytesPerPixel != SDL_Screen->format->BytesPerPixel) - { - fprintf (stderr, "Fatal error: SDL_Video and SDL_Screen bpp doesn't match (%d vs. %d)\n", - SDL_Video->format->BytesPerPixel,SDL_Screen->format->BytesPerPixel); + if (0 != ReInit_Screen (&fade_white, format_conv_surf, + ScreenWidth, ScreenHeight)) return -1; + SDL_FillRect (fade_white, NULL, SDL_MapRGB (fade_white->format, 255, 255, 255)); + + if (0 != ReInit_Screen (&fade_black, format_conv_surf, + ScreenWidth, ScreenHeight)) + return -1; + SDL_FillRect (fade_black, NULL, SDL_MapRGB (fade_black->format, 0, 0, 0)); + + if (0 != ReInit_Screen (&fade_temp, format_conv_surf, + ScreenWidth, ScreenHeight)) + return -1; + + if (ScreenWidthActual > ScreenWidth || ScreenHeightActual > ScreenHeight) + { + if (0 != ReInit_Screen (&scaled_display, format_conv_surf, + ScreenWidthActual, ScreenHeightActual)) + return -1; + + scaler = Scale_PrepPlatform (flags, SDL_Screen->format); + } + else + { // no need to scale + scaler = NULL; } return 0; @@ -160,88 +191,35 @@ TFB_Pure_InitGraphics (int driver, int flags, int width, int height, int bpp) exit (-1); } - // pre-compute the RGB->YUV transformations - Scale_PrepYUV(); + // Initialize scalers (let them precompute whatever) + Scale_Init (); return 0; } -static void ScanLines (SDL_Surface *dst, SDL_Rect *r) +static void +ScanLines (SDL_Surface *dst, SDL_Rect *r) { - const int rx = r->x * 2; const int rw = r->w * 2; - const int ry1 = r->y * 2; - const int ry2 = ry1 + r->h * 2; - Uint8 *pixels = (Uint8 *) dst->pixels; + const int rh = r->h * 2; SDL_PixelFormat *fmt = dst->format; + const int pitch = dst->pitch; + const int len = pitch / fmt->BytesPerPixel; + int ddst; + Uint32 *p = (Uint32 *) dst->pixels; int x, y; - switch (dst->format->BytesPerPixel) + p += len * (r->y * 2) + (r->x * 2); + ddst = len + len - rw; + + for (y = rh; y; y -= 2, p += ddst) { - case 2: - { - for (y = ry1; y < ry2; y += 2) + for (x = rw; x; --x, ++p) { - Uint16 *p = (Uint16 *) &pixels[y * dst->pitch + (rx << 1)]; - for (x = 0; x < rw; ++x) - { - *p = ((((*p & fmt->Rmask) * 3) >> 2) & fmt->Rmask) | - ((((*p & fmt->Gmask) * 3) >> 2) & fmt->Gmask) | - ((((*p & fmt->Bmask) * 3) >> 2) & fmt->Bmask); - ++p; - } + // we ignore the lower bits as the difference + // of 1 in 255 is negligible + *p = ((*p >> 1) & 0x7f7f7f7f) + ((*p >> 2) & 0x3f3f3f3f); } - break; - } - case 3: - { - for (y = ry1; y < ry2; y += 2) - { - Uint8 *p = (Uint8 *) &pixels[y * dst->pitch + rx * 3]; - Uint32 pixval; -#if SDL_BYTEORDER == SDL_BIG_ENDIAN - for (x = 0; x < rw; ++x) - { - pixval = p[0] << 16 | p[1] << 8 | p[2]; - pixval = ((((pixval & fmt->Rmask) * 3) >> 2) & fmt->Rmask) | - ((((pixval & fmt->Gmask) * 3) >> 2) & fmt->Gmask) | - ((((pixval & fmt->Bmask) * 3) >> 2) & fmt->Bmask); - p[0] = (pixval >> 16) & 0xff; - p[1] = (pixval >> 8) & 0xff; - p[2] = pixval & 0xff; - p += 3; - } -#else - for (x = 0; x < rw; ++x) - { - pixval = p[0] | p[1] << 8 | p[2] << 16; - pixval = ((((pixval & fmt->Rmask) * 3) >> 2) & fmt->Rmask) | - ((((pixval & fmt->Gmask) * 3) >> 2) & fmt->Gmask) | - ((((pixval & fmt->Bmask) * 3) >> 2) & fmt->Bmask); - p[0] = pixval & 0xff; - p[1] = (pixval >> 8) & 0xff; - p[2] = (pixval >> 16) & 0xff; - p += 3; - } -#endif - } - break; - } - case 4: - { - for (y = ry1; y < ry2; y += 2) - { - Uint32 *p = (Uint32 *) &pixels[y * dst->pitch + (rx << 2)]; - for (x = 0; x < rw; ++x) - { - *p = ((((*p & fmt->Rmask) * 3) >> 2) & fmt->Rmask) | - ((((*p & fmt->Gmask) * 3) >> 2) & fmt->Gmask) | - ((((*p & fmt->Bmask) * 3) >> 2) & fmt->Bmask); - ++p; - } - } - break; - } } } @@ -274,12 +252,17 @@ TFB_Pure_SwapBuffers (int force_full_redraw) last_fade_amount = fade_amount; last_transition_amount = transition_amount; - if (ScreenWidth == 320 && ScreenHeight == 240 && - ScreenWidthActual == 640 && ScreenHeightActual == 480) + if (ScreenWidthActual == ScreenWidth * 2 && + ScreenHeightActual == ScreenHeight * 2) { // scales 320x240 backbuffer to 640x480 SDL_Surface *backbuffer = SDL_Screen; + SDL_Surface *scalebuffer = scaled_display; + + // we can scale directly onto SDL_Video if video is compatible + if (SDL_Video->format->BitsPerPixel == SDL_Screen->format->BitsPerPixel) + scalebuffer = SDL_Video; if (transition_amount != 255) { @@ -310,27 +293,26 @@ TFB_Pure_SwapBuffers (int force_full_redraw) } } - SDL_LockSurface (SDL_Video); + SDL_LockSurface (scalebuffer); SDL_LockSurface (backbuffer); - if (GfxFlags & TFB_GFXFLAGS_SCALE_BILINEAR) - Scale_BilinearFilter (backbuffer, SDL_Video, &updated); - else if (GfxFlags & TFB_GFXFLAGS_SCALE_BIADAPT) - Scale_BiAdaptFilter (backbuffer, SDL_Video, &updated); - else if (GfxFlags & TFB_GFXFLAGS_SCALE_BIADAPTADV) - Scale_BiAdaptAdvFilter (backbuffer, SDL_Video, &updated); - else if (GfxFlags & TFB_GFXFLAGS_SCALE_TRISCAN) - Scale_TriScanFilter (backbuffer, SDL_Video, &updated); - else - Scale_Nearest (backbuffer, SDL_Video, &updated); + if (scaler) + scaler (backbuffer, scalebuffer, &updated); if (GfxFlags & TFB_GFXFLAGS_SCANLINES) - ScanLines (SDL_Video, &updated); + ScanLines (scalebuffer, &updated); SDL_UnlockSurface (backbuffer); - SDL_UnlockSurface (SDL_Video); + SDL_UnlockSurface (scalebuffer); - SDL_UpdateRect (SDL_Video, updated.x * 2, updated.y * 2, updated.w * 2, updated.h * 2); + updated.x *= 2; + updated.y *= 2; + updated.w *= 2; + updated.h *= 2; + if (scalebuffer != SDL_Video) + SDL_BlitSurface (scalebuffer, &updated, SDL_Video, &updated); + + SDL_UpdateRects (SDL_Video, 1, &updated); } else { @@ -362,4 +344,50 @@ TFB_Pure_SwapBuffers (int force_full_redraw) } } +void +Scale_PerfTest (void) +{ + int fps = 0; + DWORD TimeStart, TimeIn, Now; + SDL_Rect updated = {0, 0, ScreenWidth, ScreenHeight}; + int i; + + if (!scaler) + { + fprintf (stderr, "No scaler configured! Run with larger resolution, please\n"); + return; + } + if (!scaled_display) + { + fprintf (stderr, "Run scaler performance tests in Pure mode, please\n"); + return; + } + + SDL_LockSurface (SDL_Screen); + SDL_LockSurface (scaled_display); + + TimeStart = TimeIn = SDL_GetTicks (); + + for (i = 1; i < 1001; ++i) // run for 1000 frames + { + scaler (SDL_Screen, scaled_display, &updated); + + if (GfxFlags & TFB_GFXFLAGS_SCANLINES) + ScanLines (scaled_display, &updated); + + if (i % 100 == 0) + { + Now = SDL_GetTicks (); + fprintf(stderr, "%03d(%04d) ", 100*1000 / (Now - TimeIn), Now - TimeIn); + TimeIn = Now; + } + } + + fprintf (stderr, "Full frames scaled: %d; over %d ms; %d fps\n", + (i - 1), Now - TimeStart, i * 1000 / (Now - TimeStart)); + + SDL_UnlockSurface (scaled_display); + SDL_UnlockSurface (SDL_Screen); +} + #endif diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c index a094e021c..18c294f2c 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.c @@ -41,6 +41,8 @@ SDL_Surface *TransitionScreen; SDL_Surface *SDL_Screens[TFB_GFX_NUMSCREENS]; +SDL_Surface *format_conv_surf = NULL; + volatile int TransitionAmount = 255; SDL_Rect TransitionClipRect; static volatile BOOLEAN abortFlag = FALSE; @@ -223,14 +225,32 @@ TFB_SwapBuffers (int force_full_redraw) SDL_Surface* TFB_DisplayFormatAlpha (SDL_Surface *surface) { -#ifdef HAVE_OPENGL - if (GraphicsDriver == TFB_GFXDRIVER_SDL_OPENGL) - { - return TFB_GL_DisplayFormatAlpha (surface); - } -#endif + SDL_Surface* newsurf; + SDL_PixelFormat* dstfmt; + const SDL_PixelFormat* srcfmt = surface->format; + + // figure out what format to use (alpha/no alpha) + if (surface->format->Amask) + dstfmt = format_conv_surf->format; + else + dstfmt = SDL_Screen->format; - return SDL_DisplayFormatAlpha (surface); + if (srcfmt->BytesPerPixel == dstfmt->BytesPerPixel && + srcfmt->Rmask == dstfmt->Rmask && + srcfmt->Gmask == dstfmt->Gmask && + srcfmt->Bmask == dstfmt->Bmask && + srcfmt->Amask == dstfmt->Amask) + return surface; // no conversion needed + + newsurf = SDL_ConvertSurface (surface, dstfmt, surface->flags); + // SDL_SRCCOLORKEY and SDL_SRCALPHA cannot work at the same time, + // so we need to disable one of them + if ((surface->flags & SDL_SRCCOLORKEY) && newsurf + && (newsurf->flags & SDL_SRCCOLORKEY) + && (newsurf->flags & SDL_SRCALPHA)) + SDL_SetAlpha (newsurf, 0, 255); + + return newsurf; } void TFB_BlitSurface (SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst, diff --git a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h index c4260cb0e..947c97824 100644 --- a/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h +++ b/sc2/src/sc2code/libs/graphics/sdl/sdl_common.h @@ -39,6 +39,8 @@ extern SDL_Surface *TransitionScreen; extern SDL_Surface *SDL_Screens[TFB_GFX_NUMSCREENS]; +extern SDL_Surface *format_conv_surf; + extern volatile int TransitionAmount; extern SDL_Rect TransitionClipRect; diff --git a/sc2/src/sc2code/planets/plangen.c b/sc2/src/sc2code/planets/plangen.c index 8d86a28fd..bf2395fd2 100644 --- a/sc2/src/sc2code/planets/plangen.c +++ b/sc2/src/sc2code/planets/plangen.c @@ -1214,13 +1214,13 @@ void planet_orbit_init () Orbit->isPFADefined = (BYTE *)HCalloc (sizeof(BYTE) * MAP_WIDTH); Orbit->PlanetFrameArray = CaptureDrawable ( - CreateDrawable (WANT_PIXMAP, DIAMETER, DIAMETER, + CreateDrawable (WANT_PIXMAP | WANT_ALPHA, DIAMETER, DIAMETER, (COUNT)MAP_WIDTH)); Orbit->TintFrame = CaptureDrawable ( - CreateDrawable (WANT_PIXMAP, (SWORD)MAP_WIDTH, + CreateDrawable (WANT_PIXMAP | WANT_ALPHA, (SWORD)MAP_WIDTH, (SWORD)MAP_HEIGHT, 2)); Orbit->ShieldFrame = CaptureDrawable ( - CreateDrawable (WANT_PIXMAP, SHIELD_DIAM, + CreateDrawable (WANT_PIXMAP | WANT_ALPHA, SHIELD_DIAM, SHIELD_DIAM, 1)); Orbit->lpTopoData = HMalloc (MAP_WIDTH * MAP_HEIGHT); diff --git a/sc2/src/sc2code/uqmdebug.c b/sc2/src/sc2code/uqmdebug.c index 453b12c06..55e63bd0e 100644 --- a/sc2/src/sc2code/uqmdebug.c +++ b/sc2/src/sc2code/uqmdebug.c @@ -67,6 +67,9 @@ debugKeyPressed (void) showSpheres (); // forwardToNextEvent (TRUE); + // Tests + //Scale_PerfTest (); + // Informational: // dumpEvents (stderr); // dumpPlanetTypes(stderr); diff --git a/sc2/src/starcon2.c b/sc2/src/starcon2.c index a5ddb7d65..5db7247cd 100644 --- a/sc2/src/starcon2.c +++ b/sc2/src/starcon2.c @@ -32,6 +32,7 @@ #include "libs/tasklib.h" #include "file.h" #include "port.h" +#include "libs/platform.h" #include "options.h" #include "uqmversion.h" #include "comm.h" @@ -108,7 +109,7 @@ main (int argc, char *argv[]) /* .soundFlags = */ audio_QUALITY_MEDIUM, /* .width = */ 640, /* .height = */ 480, - /* .bpp = */ 16, + /* .bpp = */ 32, /* .configDir = */ NULL, /* .contentDir = */ NULL, /* .addons = */ NULL, @@ -313,7 +314,8 @@ enum SCROLL_OPT, SOUND_OPT, STEREOSFX_OPT, - ADDON_OPT + ADDON_OPT, + ACCEL_OPT, }; static const char *optString = "+r:d:foc:b:spC:n:?hM:S:T:m:q:ug:l:i:v"; @@ -349,6 +351,7 @@ static struct option longOptions[] = {"sound", 1, NULL, SOUND_OPT}, {"stereosfx", 0, NULL, STEREOSFX_OPT}, {"addon", 1, NULL, ADDON_OPT}, + {"accel", 1, NULL, ACCEL_OPT}, {0, 0, 0, 0} }; @@ -466,6 +469,8 @@ parseOptions(int argc, char *argv[], struct options_struct *options) options->gfxFlags |= TFB_GFXFLAGS_SCALE_BIADAPTADV; else if (!strcmp (optarg, "triscan")) options->gfxFlags |= TFB_GFXFLAGS_SCALE_TRISCAN; + else if (!strcmp (optarg, "hq")) + options->gfxFlags |= TFB_GFXFLAGS_SCALE_HQXX; else if (strcmp (optarg, "none") != 0) { InvalidArgument(optarg, "--scale or -c"); @@ -625,6 +630,22 @@ parseOptions(int argc, char *argv[], struct options_struct *options) options->addons[options->numAddons - 1] = optarg; options->addons[options->numAddons] = NULL; break; + case ACCEL_OPT: + force_platform = PLATFORM_NULL; + if (!strcmp (optarg, "mmx")) + force_platform = PLATFORM_MMX; + else if (!strcmp (optarg, "sse")) + force_platform = PLATFORM_SSE; + else if (!strcmp (optarg, "3dnow")) + force_platform = PLATFORM_3DNOW; + else if (!strcmp (optarg, "none")) + force_platform = PLATFORM_C; + else if (strcmp (optarg, "detect") != 0) + { + InvalidArgument (optarg, "--accel"); + badArg = TRUE; + } + break; default: fprintf (stderr, "Error: Invalid option '%s' not found.\n", longOptions[optionIndex].name); @@ -740,8 +761,8 @@ usage (FILE *out, const struct options_struct *defaultOptions) fprintf (out, " -d, --bpp=BITSPERPIXEL (default 16)\n"); fprintf (out, " -f, --fullscreen (default off)\n"); fprintf (out, " -o, --opengl (default off)\n"); - fprintf (out, " -c, --scale=MODE (bilinear, biadapt, biadv, triscan " - "or none (default) )\n"); + fprintf (out, " -c, --scale=MODE (bilinear, biadapt, biadv, triscan, " + "hq or none (default) )\n"); fprintf (out, " -b, --meleezoom=MODE (step, aka pc, or smooth, aka 3do; " "default is 3do)\n"); fprintf (out, " -s, --scanlines (default off)\n");