98e75f2d |
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 | } |