Glide Plugin GLES2 port from mupen64plus-ae, but with special FrameSkip code
[mupen64plus-pandora.git] / source / gles2glide64 / src / Glide64 / MiClWr16b.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 mirror16bS(uint8_t *tex, uint8_t *start, int width, int height, int mask, int line, int full, int count)
41 {
42   uint16_t *v8;
43   int v9;
44   int v10;
45
46   v8 = (uint16_t *)start;
47   v9 = height;
48   do
49   {
50     v10 = 0;
51     do
52     {
53       if ( width & (v10 + width) )
54       {
55         *v8 = *(uint16_t *)(&tex[mask] - (mask & 2 * v10));
56         ++v8;
57       }
58       else
59       {
60         *v8 = *(uint16_t *)&tex[mask & 2 * v10];
61         ++v8;
62       }
63       ++v10;
64     }
65     while ( v10 != count );
66     v8 = (uint16_t *)((char *)v8 + line);
67     tex += full;
68     --v9;
69   }
70   while ( v9 );
71 }
72
73 static inline void wrap16bS(uint8_t *tex, uint8_t *start, int height, int mask, int line, int full, int count)
74 {
75   uint32_t *v7;
76   int v8;
77   int v9;
78
79   v7 = (uint32_t *)start;
80   v8 = height;
81   do
82   {
83     v9 = 0;
84     do
85     {
86       *v7 = *(uint32_t *)&tex[4 * (mask & v9)];
87       ++v7;
88       ++v9;
89     }
90     while ( v9 != count );
91     v7 = (uint32_t *)((char *)v7 + line);
92     tex += full;
93     --v8;
94   }
95   while ( v8 );
96 }
97
98 static inline void clamp16bS(uint8_t *tex, uint8_t *constant, int height, int line, int full, int count)
99 {
100   uint16_t *v6;
101   uint16_t *v7;
102   int v8;
103   uint16_t v9;
104   int v10;
105
106   v6 = (uint16_t *)constant;
107   v7 = (uint16_t *)tex;
108   v8 = height;
109   do
110   {
111     v9 = *v6;
112     v10 = count;
113     do
114     {
115       *v7 = v9;
116       ++v7;
117       --v10;
118     }
119     while ( v10 );
120     v6 = (uint16_t *)((char *)v6 + full);
121     v7 = (uint16_t *)((char *)v7 + line);
122     --v8;
123   }
124   while ( v8 );
125 }
126
127 //****************************************************************
128 // 16-bit Horizontal Mirror
129 #include <stdint.h>
130 #include <string.h>
131 typedef uint32_t wxUint32;
132
133 void Mirror16bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
134 {
135   if (mask == 0) return;
136
137   wxUint32 mask_width = (1 << mask);
138   wxUint32 mask_mask = (mask_width-1) << 1;
139   if (mask_width >= max_width) return;
140   int count = max_width - mask_width;
141   if (count <= 0) return;
142   int line_full = real_width << 1;
143   int line = line_full - (count << 1);
144   if (line < 0) return;
145   unsigned char *start = tex + (mask_width << 1);
146   mirror16bS (tex, start, mask_width, height, mask_mask, line, line_full, count);
147 }
148
149 //****************************************************************
150 // 16-bit Horizontal Wrap (like mirror)
151
152 void Wrap16bS (unsigned char * tex, wxUint32 mask, wxUint32 max_width, wxUint32 real_width, wxUint32 height)
153 {
154   if (mask == 0) return;
155
156   wxUint32 mask_width = (1 << mask);
157   wxUint32 mask_mask = (mask_width-1) >> 1;
158   if (mask_width >= max_width) return;
159   int count = (max_width - mask_width) >> 1;
160   if (count <= 0) return;
161   int line_full = real_width << 1;
162   int line = line_full - (count << 2);
163   if (line < 0) return;
164   unsigned char * start = tex + (mask_width << 1);
165   wrap16bS (tex, start, height, mask_mask, line, line_full, count);
166 }
167
168 //****************************************************************
169 // 16-bit Horizontal Clamp
170
171 void Clamp16bS (unsigned char * tex, wxUint32 width, wxUint32 clamp_to, wxUint32 real_width, wxUint32 real_height)
172 {
173   if (real_width <= width) return;
174
175   unsigned char * dest = tex + (width << 1);
176   unsigned char * constant = dest-2;
177   int count = clamp_to - width;
178
179   int line_full = real_width << 1;
180   int line = width << 1;
181
182   clamp16bS (dest, constant, real_height, line, line_full, count);
183 }
184
185 //****************************************************************
186 // 16-bit Vertical Mirror
187
188 void Mirror16bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
189 {
190   if (mask == 0) return;
191
192   wxUint32 mask_height = (1 << mask);
193   wxUint32 mask_mask = mask_height-1;
194   if (max_height <= mask_height) return;
195   int line_full = real_width << 1;
196
197   unsigned char * dst = tex + mask_height * line_full;
198
199   for (wxUint32 y=mask_height; y<max_height; y++)
200   {
201     if (y & mask_height)
202     {
203       // mirrored
204       memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);
205     }
206     else
207     {
208       // not mirrored
209       memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
210     }
211
212     dst += line_full;
213   }
214 }
215
216 //****************************************************************
217 // 16-bit Vertical Wrap
218
219 void Wrap16bT (unsigned char * tex, wxUint32 mask, wxUint32 max_height, wxUint32 real_width)
220 {
221   if (mask == 0) return;
222
223   wxUint32 mask_height = (1 << mask);
224   wxUint32 mask_mask = mask_height-1;
225   if (max_height <= mask_height) return;
226   int line_full = real_width << 1;
227
228   unsigned char * dst = tex + mask_height * line_full;
229
230   for (wxUint32 y=mask_height; y<max_height; y++)
231   {
232     // not mirrored
233     memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
234
235     dst += line_full;
236   }
237 }
238
239 //****************************************************************
240 // 16-bit Vertical Clamp
241
242 void Clamp16bT (unsigned char * tex, wxUint32 height, wxUint32 real_width, wxUint32 clamp_to)
243 {
244   int line_full = real_width << 1;
245   unsigned char * dst = tex + height * line_full;
246   unsigned char * const_line = dst - line_full;
247
248   for (wxUint32 y=height; y<clamp_to; y++)
249   {
250     memcpy ((void*)dst, (void*)const_line, line_full);
251     dst += line_full;
252   }
253 }