Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glide64 / TexLoad16b.h
1 /*
2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002  Dave2001
4 * Copyright (c) 2003-2009  Sergey 'Gonetz' Lipski
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 */
20
21 //****************************************************************
22 //
23 // Glide64 - Glide Plugin for Nintendo 64 emulators
24 // Project started on December 29th, 2001
25 //
26 // Authors:
27 // Dave2001, original author, founded the project in 2001, left it in 2002
28 // Gugaman, joined the project in 2002, left it in 2002
29 // Sergey 'Gonetz' Lipski, joined the project in 2002, main author since fall of 2002
30 // Hiroshi 'KoolSmoky' Morii, joined the project in 2007
31 //
32 //****************************************************************
33 //
34 // To modify Glide64:
35 // * Write your name and (optional)email, commented by your work, so I know who did it, and so that you can find which parts you modified when it comes time to send it to me.
36 // * Do NOT send me the whole project or file that you modified.  Take out your modified code sections, and tell me where to put them.  If people sent the whole thing, I would have many different versions, but no idea how to combine them all.
37 //
38 //****************************************************************
39
40 static inline void load16bRGBA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
41 {
42   uint32_t *v6;
43   uint32_t *v7;
44   int v8;
45   int v9;
46   uint32_t v10;
47   uint32_t v11;
48   uint32_t *v12;
49   uint32_t *v13;
50   int v14;
51   uint32_t v15;
52   uint32_t v16;
53   int v17;
54   int v18;
55
56   v6 = (uint32_t *)src;
57   v7 = (uint32_t *)dst;
58   v8 = height;
59   do
60   {
61     v17 = v8;
62     v9 = wid_64;
63     do
64     {
65       v10 = bswap32(*v6);
66       v11 = bswap32(v6[1]);
67       ALOWORD(v10) = __ROR__((uint16_t)v10, 1);
68       ALOWORD(v11) = __ROR__((uint16_t)v11, 1);
69       v10 = __ROR__(v10, 16);
70       v11 = __ROR__(v11, 16);
71       ALOWORD(v10) = __ROR__((uint16_t)v10, 1);
72       ALOWORD(v11) = __ROR__((uint16_t)v11, 1);
73       *v7 = v10;
74       v7[1] = v11;
75       v6 += 2;
76       v7 += 2;
77       --v9;
78     }
79     while ( v9 );
80     if ( v17 == 1 )
81       break;
82     v18 = v17 - 1;
83     v12 = (uint32_t *)&src[(line + (uintptr_t)v6 - (uintptr_t)src) & 0xFFF];
84     v13 = (uint32_t *)((char *)v7 + ext);
85     v14 = wid_64;
86     do
87     {
88       v15 = bswap32(v12[1]);
89       v16 = bswap32(*v12);
90       ALOWORD(v15) = __ROR__((uint16_t)v15, 1);
91       ALOWORD(v16) = __ROR__((uint16_t)v16, 1);
92       v15 = __ROR__(v15, 16);
93       v16 = __ROR__(v16, 16);
94       ALOWORD(v15) = __ROR__((uint16_t)v15, 1);
95       ALOWORD(v16) = __ROR__((uint16_t)v16, 1);
96       *v13 = v15;
97       v13[1] = v16;
98       v12 += 2;
99       v13 += 2;
100       --v14;
101     }
102     while ( v14 );
103     v6 = (uint32_t *)&src[(line + (uintptr_t)v12 - (uintptr_t)src) & 0xFFF];
104     v7 = (uint32_t *)((char *)v13 + ext);
105     v8 = v18 - 1;
106   }
107   while ( v18 != 1 );
108 }
109
110 static inline void load16bIA(uint8_t *src, uint8_t *dst, int wid_64, int height, int line, int ext)
111 {
112   uint32_t *v6;
113   uint32_t *v7;
114   int v8;
115   int v9;
116   uint32_t v10;
117   uint32_t *v11;
118   uint32_t *v12;
119   int v13;
120   uint32_t v14;
121   int v15;
122   int v16;
123
124   v6 = (uint32_t *)src;
125   v7 = (uint32_t *)dst;
126   v8 = height;
127   do
128   {
129     v15 = v8;
130     v9 = wid_64;
131     do
132     {
133       v10 = v6[1];
134       *v7 = *v6;
135       v7[1] = v10;
136       v6 += 2;
137       v7 += 2;
138       --v9;
139     }
140     while ( v9 );
141     if ( v15 == 1 )
142       break;
143     v16 = v15 - 1;
144     v11 = (uint32_t *)((char *)v6 + line);
145     v12 = (uint32_t *)((char *)v7 + ext);
146     v13 = wid_64;
147     do
148     {
149       v14 = *v11;
150       *v12 = v11[1];
151       v12[1] = v14;
152       v11 += 2;
153       v12 += 2;
154       --v13;
155     }
156     while ( v13 );
157     v6 = (uint32_t *)((char *)v11 + line);
158     v7 = (uint32_t *)((char *)v12 + ext);
159     v8 = v16 - 1;
160   }
161   while ( v16 != 1 );
162 }
163
164
165 //****************************************************************
166 // Size: 2, Format: 0
167 //
168
169 wxUint32 Load16bRGBA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
170 {
171   if (wid_64 < 1) wid_64 = 1;
172   if (height < 1) height = 1;
173   int ext = (real_width - (wid_64 << 2)) << 1;
174
175   load16bRGBA((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
176
177   return (1 << 16) | GR_TEXFMT_ARGB_1555;
178 }
179
180 //****************************************************************
181 // Size: 2, Format: 3
182 //
183 // ** by Gugaman/Dave2001 **
184
185 wxUint32 Load16bIA (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
186 {
187   if (wid_64 < 1) wid_64 = 1;
188   if (height < 1) height = 1;
189   int ext = (real_width - (wid_64 << 2)) << 1;
190
191   load16bIA((uint8_t *)src, (uint8_t *)dst, wid_64, height, line, ext);
192
193   return (1 << 16) | GR_TEXFMT_ALPHA_INTENSITY_88;
194 }
195
196 //****************************************************************
197 // Size: 2, Format: 1
198 //
199
200 wxUint16 yuv_to_rgb565(wxUint8 y, wxUint8 u, wxUint8 v)
201 {
202   //*
203   float r = y + (1.370705f * (v-128));
204   float g = y - (0.698001f * (v-128)) - (0.337633f * (u-128));
205   float b = y + (1.732446f * (u-128));
206   r *= 0.125f;
207   g *= 0.25f;
208   b *= 0.125f;
209   //clipping the result
210   if (r > 31) r = 31;
211   if (g > 63) g = 63;
212   if (b > 31) b = 31;
213   if (r < 0) r = 0;
214   if (g < 0) g = 0;
215   if (b < 0) b = 0;
216   wxUint16 c = (wxUint16)(((wxUint16)(r) << 11) |
217     ((wxUint16)(g) << 5) |
218     (wxUint16)(b) );
219   return c;
220   //*/
221   /*
222   const wxUint32 c = y - 16;
223   const wxUint32 d = u - 128;
224   const wxUint32 e = v - 128;
225
226   wxUint32 r =  (298 * c           + 409 * e + 128) & 0xf800;
227   wxUint32 g = ((298 * c - 100 * d - 208 * e + 128) >> 5) & 0x7e0;
228   wxUint32 b = ((298 * c + 516 * d           + 128) >> 11) & 0x1f;
229
230   WORD texel = (WORD)(r | g | b);
231
232   return texel;
233   */
234 }
235
236 //****************************************************************
237 // Size: 2, Format: 1
238 //
239
240 wxUint32 Load16bYUV (wxUIntPtr dst, wxUIntPtr src, int wid_64, int height, int line, int real_width, int tile)
241 {
242   wxUint32 * mb = (wxUint32*)(gfx.RDRAM+rdp.addr[rdp.tiles[tile].t_mem]); //pointer to the macro block
243   wxUint16 * tex = (wxUint16*)dst;
244   wxUint16 i;
245   for (i = 0; i < 128; i++)
246   {
247     wxUint32 t = mb[i]; //each wxUint32 contains 2 pixels
248     wxUint8 y1 = (wxUint8)t&0xFF;
249     wxUint8 v  = (wxUint8)(t>>8)&0xFF;
250     wxUint8 y0 = (wxUint8)(t>>16)&0xFF;
251     wxUint8 u  = (wxUint8)(t>>24)&0xFF;
252     wxUint16 c = yuv_to_rgb565(y0, u, v);
253     *(tex++) = c;
254     c = yuv_to_rgb565(y1, u, v);
255     *(tex++) = c;
256   }
257   return (1 << 16) | GR_TEXFMT_RGB_565;
258 }