X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=source%2Fmupen64plus-video-arachnoid%2Fsrc%2Ftexture%2FImageFormatSelector.cpp;fp=source%2Fmupen64plus-video-arachnoid%2Fsrc%2Ftexture%2FImageFormatSelector.cpp;h=c834712cb4dee0032a4a19efd8256474cb025fc7;hb=22726e4d55be26faa48b57b22689cbedde27ae44;hp=0000000000000000000000000000000000000000;hpb=fc5d46b49a19d41f9f2da5a9336daec452900475;p=mupen64plus-pandora.git diff --git a/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp new file mode 100755 index 0000000..c834712 --- /dev/null +++ b/source/mupen64plus-video-arachnoid/src/texture/ImageFormatSelector.cpp @@ -0,0 +1,314 @@ +/****************************************************************************** + * Arachnoid Graphics Plugin for Mupen64Plus + * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/ + * + * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson + * + * 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 the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + *****************************************************************************/ + +//***************************************************************************** +// +// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64. +// http://gln64.emulation64.com/ +// +//***************************************************************************** + +#include "ImageFormatSelector.h" +#include "CachedTexture.h" +#include "assembler.h" +#include "GBIDefs.h" +#include "m64p.h" +#include "OpenGL.h" +#include "Memory.h" + +#ifndef GL_EXT_packed_pixels +#define GL_EXT_packed_pixels 1 + #define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032 + #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033 + #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034 + #define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035 + #define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036 +#endif /* GL_EXT_packed_pixels */ + +unsigned long long* TMEM = Memory::getTextureMemory(); + + +inline unsigned int GetNone( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return 0x00000000; +} + +inline unsigned int GetCI4IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetCI4IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetCI4RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetCI4RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + if (x & 1) + return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] ); + else + return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] ); +} + +inline unsigned int GetIA31_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetIA31_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetI4_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetI4_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + unsigned char color4B; + + color4B = ((unsigned char*)src)[(x>>1)^(i<<1)]; + + return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) ); +} + +inline unsigned int GetCI8IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetCI8IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetCI8RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetCI8RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] ); +} + +inline unsigned int GetIA44_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA44_RGBA8888(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetIA44_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA44_RGBA4444(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetI8_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return I8_RGBA8888(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetI8_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return I8_RGBA4444(((unsigned char*)src)[x^(i<<1)]); +} + +inline unsigned int GetRGBA5551_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA8888( ((unsigned short*)src)[x^i] ); +} + +inline unsigned int GetRGBA5551_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA5551_RGBA5551( ((unsigned short*)src)[x^i] ); +} + +inline unsigned int GetIA88_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA8888(((unsigned short*)src)[x^i]); +} + +inline unsigned int GetIA88_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return IA88_RGBA4444(((unsigned short*)src)[x^i]); +} + +inline unsigned int GetRGBA8888_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return ((unsigned int*)src)[x^i]; +} + +inline unsigned int GetRGBA8888_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette ) +{ + return RGBA8888_RGBA4444(((unsigned int*)src)[x^i]); +} + +/* +const struct +{ + GetTexelFunc Get16; + unsigned int glType16; + int glInternalFormat16; + GetTexelFunc Get32; + unsigned int glType32; + int glInternalFormat32; + unsigned int autoFormat, lineShift, maxTexels; +} +*/ +ImageFormat ImageFormatSelector::imageFormats[4][5] = +{ // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat + { // 4-bit + { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 4, 4096 }, // CI (Banjo-Kazooie uses this, doesn't make sense, but it works...) + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // YUV + { GetCI4RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI4RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 4, 4096 }, // CI + { GetIA31_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA31_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // IA + { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // I + }, + { // 8-bit + { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 3, 2048 }, // RGBA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 4096 }, // YUV + { GetCI8RGBA_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetCI8RGBA_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 3, 2048 }, // CI + { GetIA44_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA44_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 3, 4096 }, // IA + { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 3, 4096 }, // I + }, + { // 16-bit + { GetRGBA5551_RGBA5551, GL_UNSIGNED_SHORT_5_5_5_1_EXT, GL_RGB5_A1, GetRGBA5551_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGB5_A1, 2, 2048 }, // RGBA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 2, 2048 }, // YUV + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 2048 }, // CI + { GetIA88_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA88_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 2, 2048 }, // IA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 2048 }, // I + }, + { // 32-bit + { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 2, 1024 }, // RGBA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // YUV + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // CI + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // IA + { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // I + } +}; + +//----------------------------------------------------------------------------- +//! Constructor +//----------------------------------------------------------------------------- +ImageFormatSelector::ImageFormatSelector() +{ +} + +//----------------------------------------------------------------------------- +//! Destructor +//----------------------------------------------------------------------------- +ImageFormatSelector::~ImageFormatSelector() +{ + +} + +//----------------------------------------------------------------------------- +// Detect Image Format +//----------------------------------------------------------------------------- +void ImageFormatSelector::detectImageFormat(CachedTexture* texture, unsigned int textureBitDepth, GetTexelFunc& getTexelFunc, unsigned int& internalFormat, int& imageType, unsigned int textureLUT) +{ + if (((imageFormats[texture->size][texture->format].autoFormat == GL_RGBA8) || + ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) || + (textureBitDepth == 2)) && (textureBitDepth != 0)) + { + texture->m_textureSize = (texture->realWidth * texture->realHeight) << 2; + if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) + { + if (texture->size == G_IM_SIZ_4b) + getTexelFunc = GetCI4IA_RGBA8888; + else + getTexelFunc = GetCI8IA_RGBA8888; + + internalFormat = GL_RGBA8; + imageType = GL_UNSIGNED_BYTE; + } + else + { + getTexelFunc = imageFormats[texture->size][texture->format].Get32; + internalFormat = imageFormats[texture->size][texture->format].glInternalFormat32; + imageType = imageFormats[texture->size][texture->format].glType32; + } + } + else + { + texture->m_textureSize = (texture->realWidth * texture->realHeight) << 1; + if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) + { + if (texture->size == G_IM_SIZ_4b) + getTexelFunc = GetCI4IA_RGBA4444; + else + getTexelFunc = GetCI8IA_RGBA4444; + + internalFormat = GL_RGBA4; + imageType = GL_UNSIGNED_SHORT_4_4_4_4_EXT; + } + else + { + getTexelFunc = imageFormats[texture->size][texture->format].Get16; + internalFormat = imageFormats[texture->size][texture->format].glInternalFormat16; + imageType = imageFormats[texture->size][texture->format].glType16; + } + } +}