Arachnoid GLESv1.1 plugin. Compile and run (a bit glitchy and no frameskip) on the...
[mupen64plus-pandora.git] / source / mupen64plus-video-arachnoid / src / texture / ImageFormatSelector.cpp
CommitLineData
22726e4d 1/******************************************************************************
2 * Arachnoid Graphics Plugin for Mupen64Plus
3 * http://bitbucket.org/wahrhaft/mupen64plus-video-arachnoid/
4 *
5 * Copyright (C) 2007 Kristofer Karlsson, Rickard Niklasson
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 *****************************************************************************/
21
22//*****************************************************************************
23//
24// NOTE THAT THIS FILE IS BASED ON MATERIAL FROM glN64.
25// http://gln64.emulation64.com/
26//
27//*****************************************************************************
28
29#include "ImageFormatSelector.h"
30#include "CachedTexture.h"
31#include "assembler.h"
32#include "GBIDefs.h"
33#include "m64p.h"
34#include "OpenGL.h"
35#include "Memory.h"
36
37#ifndef GL_EXT_packed_pixels
38#define GL_EXT_packed_pixels 1
39 #define GL_UNSIGNED_BYTE_3_3_2_EXT 0x8032
40 #define GL_UNSIGNED_SHORT_4_4_4_4_EXT 0x8033
41 #define GL_UNSIGNED_SHORT_5_5_5_1_EXT 0x8034
42 #define GL_UNSIGNED_INT_8_8_8_8_EXT 0x8035
43 #define GL_UNSIGNED_INT_10_10_10_2_EXT 0x8036
44#endif /* GL_EXT_packed_pixels */
45
46unsigned long long* TMEM = Memory::getTextureMemory();
47
48
49inline unsigned int GetNone( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
50{
51 return 0x00000000;
52}
53
54inline unsigned int GetCI4IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
55{
56 unsigned char color4B;
57
58 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
59
60 if (x & 1)
61 return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
62 else
63 return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
64}
65
66inline unsigned int GetCI4IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
67{
68 unsigned char color4B;
69
70 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
71
72 if (x & 1)
73 return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
74 else
75 return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
76}
77
78inline unsigned int GetCI4RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
79{
80 unsigned char color4B;
81
82 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
83
84 if (x & 1)
85 return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
86 else
87 return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
88}
89
90inline unsigned int GetCI4RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
91{
92 unsigned char color4B;
93
94 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
95
96 if (x & 1)
97 return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B & 0x0F)] );
98 else
99 return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + (palette << 4) + (color4B >> 4)] );
100}
101
102inline unsigned int GetIA31_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
103{
104 unsigned char color4B;
105
106 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
107
108 return IA31_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
109}
110
111inline unsigned int GetIA31_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
112{
113 unsigned char color4B;
114
115 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
116
117 return IA31_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
118}
119
120inline unsigned int GetI4_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
121{
122 unsigned char color4B;
123
124 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
125
126 return I4_RGBA8888( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
127}
128
129inline unsigned int GetI4_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
130{
131 unsigned char color4B;
132
133 color4B = ((unsigned char*)src)[(x>>1)^(i<<1)];
134
135 return I4_RGBA4444( (x & 1) ? (color4B & 0x0F) : (color4B >> 4) );
136}
137
138inline unsigned int GetCI8IA_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
139{
140 return IA88_RGBA4444( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
141}
142
143inline unsigned int GetCI8IA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
144{
145 return IA88_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
146}
147
148inline unsigned int GetCI8RGBA_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
149{
150 return RGBA5551_RGBA5551( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
151}
152
153inline unsigned int GetCI8RGBA_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
154{
155 return RGBA5551_RGBA8888( *(unsigned short*)&TMEM[256 + ((unsigned char*)src)[x^(i<<1)]] );
156}
157
158inline unsigned int GetIA44_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
159{
160 return IA44_RGBA8888(((unsigned char*)src)[x^(i<<1)]);
161}
162
163inline unsigned int GetIA44_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
164{
165 return IA44_RGBA4444(((unsigned char*)src)[x^(i<<1)]);
166}
167
168inline unsigned int GetI8_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
169{
170 return I8_RGBA8888(((unsigned char*)src)[x^(i<<1)]);
171}
172
173inline unsigned int GetI8_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
174{
175 return I8_RGBA4444(((unsigned char*)src)[x^(i<<1)]);
176}
177
178inline unsigned int GetRGBA5551_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
179{
180 return RGBA5551_RGBA8888( ((unsigned short*)src)[x^i] );
181}
182
183inline unsigned int GetRGBA5551_RGBA5551( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
184{
185 return RGBA5551_RGBA5551( ((unsigned short*)src)[x^i] );
186}
187
188inline unsigned int GetIA88_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
189{
190 return IA88_RGBA8888(((unsigned short*)src)[x^i]);
191}
192
193inline unsigned int GetIA88_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
194{
195 return IA88_RGBA4444(((unsigned short*)src)[x^i]);
196}
197
198inline unsigned int GetRGBA8888_RGBA8888( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
199{
200 return ((unsigned int*)src)[x^i];
201}
202
203inline unsigned int GetRGBA8888_RGBA4444( unsigned long long *src, unsigned short x, unsigned short i, unsigned char palette )
204{
205 return RGBA8888_RGBA4444(((unsigned int*)src)[x^i]);
206}
207
208/*
209const struct
210{
211 GetTexelFunc Get16;
212 unsigned int glType16;
213 int glInternalFormat16;
214 GetTexelFunc Get32;
215 unsigned int glType32;
216 int glInternalFormat32;
217 unsigned int autoFormat, lineShift, maxTexels;
218}
219*/
220ImageFormat ImageFormatSelector::imageFormats[4][5] =
221{ // Get16 glType16 glInternalFormat16 Get32 glType32 glInternalFormat32 autoFormat
222 { // 4-bit
223 { 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...)
224 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // YUV
225 { 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
226 { GetIA31_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA31_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // IA
227 { GetI4_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetI4_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 4, 8192 }, // I
228 },
229 { // 8-bit
230 { 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
231 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 4096 }, // YUV
232 { 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
233 { GetIA44_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA44_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 3, 4096 }, // IA
234 { GetI8_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetI8_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 3, 4096 }, // I
235 },
236 { // 16-bit
237 { 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
238 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 2, 2048 }, // YUV
239 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 2048 }, // CI
240 { GetIA88_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetIA88_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 2, 2048 }, // IA
241 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 2048 }, // I
242 },
243 { // 32-bit
244 { GetRGBA8888_RGBA4444, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetRGBA8888_RGBA8888, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA8, 2, 1024 }, // RGBA
245 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // YUV
246 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // CI
247 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // IA
248 { GetNone, GL_UNSIGNED_SHORT_4_4_4_4_EXT, GL_RGBA4, GetNone, GL_UNSIGNED_BYTE, GL_RGBA8, GL_RGBA4, 0, 1024 }, // I
249 }
250};
251
252//-----------------------------------------------------------------------------
253//! Constructor
254//-----------------------------------------------------------------------------
255ImageFormatSelector::ImageFormatSelector()
256{
257}
258
259//-----------------------------------------------------------------------------
260//! Destructor
261//-----------------------------------------------------------------------------
262ImageFormatSelector::~ImageFormatSelector()
263{
264
265}
266
267//-----------------------------------------------------------------------------
268// Detect Image Format
269//-----------------------------------------------------------------------------
270void ImageFormatSelector::detectImageFormat(CachedTexture* texture, unsigned int textureBitDepth, GetTexelFunc& getTexelFunc, unsigned int& internalFormat, int& imageType, unsigned int textureLUT)
271{
272 if (((imageFormats[texture->size][texture->format].autoFormat == GL_RGBA8) ||
273 ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16)) ||
274 (textureBitDepth == 2)) && (textureBitDepth != 0))
275 {
276 texture->m_textureSize = (texture->realWidth * texture->realHeight) << 2;
277 if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16))
278 {
279 if (texture->size == G_IM_SIZ_4b)
280 getTexelFunc = GetCI4IA_RGBA8888;
281 else
282 getTexelFunc = GetCI8IA_RGBA8888;
283
284 internalFormat = GL_RGBA8;
285 imageType = GL_UNSIGNED_BYTE;
286 }
287 else
288 {
289 getTexelFunc = imageFormats[texture->size][texture->format].Get32;
290 internalFormat = imageFormats[texture->size][texture->format].glInternalFormat32;
291 imageType = imageFormats[texture->size][texture->format].glType32;
292 }
293 }
294 else
295 {
296 texture->m_textureSize = (texture->realWidth * texture->realHeight) << 1;
297 if ((texture->format == G_IM_FMT_CI) && (textureLUT == G_TT_IA16))
298 {
299 if (texture->size == G_IM_SIZ_4b)
300 getTexelFunc = GetCI4IA_RGBA4444;
301 else
302 getTexelFunc = GetCI8IA_RGBA4444;
303
304 internalFormat = GL_RGBA4;
305 imageType = GL_UNSIGNED_SHORT_4_4_4_4_EXT;
306 }
307 else
308 {
309 getTexelFunc = imageFormats[texture->size][texture->format].Get16;
310 internalFormat = imageFormats[texture->size][texture->format].glInternalFormat16;
311 imageType = imageFormats[texture->size][texture->format].glType16;
312 }
313 }
314}