DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 /* 00020 * The HQ3x high quality 3x graphics filter. 00021 * Original author Maxim Stepin (see http://www.hiend3d.com/hq3x.html). 00022 * Adapted for DOSBox from ScummVM and HiEnd3D code by Kronuz. 00023 */ 00024 00025 #include <stdlib.h> 00026 00027 #ifndef RENDER_TEMPLATES_HQNX_TABLE_H 00028 #define RENDER_TEMPLATES_HQNX_TABLE_H 00029 00030 static Bit32u *_RGBtoYUV = 0; 00031 static inline bool diffYUV(Bit32u yuv1, Bit32u yuv2) 00032 { 00033 static const Bit32u Ymask = 0x00FF0000; 00034 static const Bit32u Umask = 0x0000FF00; 00035 static const Bit32u Vmask = 0x000000FF; 00036 static const Bit32u trY = 0x00300000; 00037 static const Bit32u trU = 0x00000700; 00038 static const Bit32u trV = 0x00000006; 00039 00040 Bit32u diff; 00041 Bit32u mask; 00042 00043 diff = ((yuv1 & Ymask) - (yuv2 & Ymask)); 00044 mask = (Bit32u)(((Bit32s)diff) >> 31); // ~1/-1 if value < 0, 0 otherwise 00045 diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value 00046 if (diff > trY) return true; 00047 00048 diff = ((yuv1 & Umask) - (yuv2 & Umask)); 00049 mask = (Bit32u)(((Bit32s)diff) >> 31); // ~1/-1 if value < 0, 0 otherwise 00050 diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value 00051 if (diff > trU) return true; 00052 00053 diff = ((yuv1 & Vmask) - (yuv2 & Vmask)); 00054 mask = (Bit32u)(((Bit32s)diff) >> 31); // ~1/-1 if value < 0, 0 otherwise 00055 diff = (diff ^ mask) - mask; //-1: ~value + 1; 0: value 00056 if (diff > trV) return true; 00057 00058 return false; 00059 } 00060 00061 #endif 00062 00063 static inline void conc2d(InitLUTs,SBPP)(void) 00064 { 00065 # if !defined(_MSC_VER) /* Microsoft C++ thinks this is a failed attempt at a function call---it's not */ 00066 (void)conc2d(InitLUTs,SBPP); 00067 # endif 00068 00069 _RGBtoYUV = (Bit32u *)malloc(65536 * sizeof(Bit32u)); 00070 00071 for (int color = 0; color < 65536; ++color) { 00072 int r, g, b; 00073 #if SBPP == 32 00074 r = ((color & 0xF800) >> 11) << (8 - 5); 00075 g = ((color & 0x07E0) >> 5) << (8 - 6); 00076 b = ((color & 0x001F) >> 0) << (8 - 5); 00077 #else 00078 r = ((color & redMask) >> redShift) << (8 - redBits); 00079 g = ((color & greenMask) >> greenShift) << (8 - greenBits); 00080 b = ((color & blueMask) >> blueShift) << (8 - blueBits); 00081 #endif 00082 int Y = (r + g + b) >> 2; 00083 int u = 128 + ((r - b) >> 2); 00084 int v = 128 + ((-r + 2 * g - b) >> 3); 00085 if (_RGBtoYUV != NULL) 00086 _RGBtoYUV[color] = (Bit32u)((Y << 16) | (u << 8) | v); 00087 else 00088 E_Exit("Memory allocation failed in conc2d"); 00089 } 00090 }