Replace Tmem_nasm.asm with C++ code. Patch by pyro.
[Glide64.git] / MiClWr8b.h
blobf2492378d0ca86279162c5635e75a7305ca66f14
1 /*
2 * Glide64 - Glide video plugin for Nintendo 64 emulators.
3 * Copyright (c) 2002 Dave2001
4 * Copyright (c) 2008 Günther <guenther.emu@freenet.de>
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.
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.
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
21 //****************************************************************
23 // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
24 // Project started on December 29th, 2001
26 // To modify Glide64:
27 // * 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.
28 // * 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.
30 // Official Glide64 development channel: #Glide64 on EFnet
32 // Original author: Dave2001 (Dave2999@hotmail.com)
33 // Other authors: Gonetz, Gugaman
35 //****************************************************************
37 //****************************************************************
38 // 8-bit Horizontal Mirror
40 void Mirror8bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
42 if (mask == 0) return;
44 DWORD mask_width = (1 << mask);
45 DWORD mask_mask = (mask_width-1);
46 if (mask_width >= max_width) return;
47 int count = max_width - mask_width;
48 if (count <= 0) return;
49 int line_full = real_width;
50 int line = line_full - (count);
51 if (line < 0) return;
52 unsigned char * start = tex + (mask_width);
53 #ifndef GCC
54 __asm {
55 mov edi,dword ptr [start]
57 mov ecx,dword ptr [height]
58 loop_y:
60 xor edx,edx
61 loop_x:
62 mov esi,dword ptr [tex]
63 mov ebx,dword ptr [mask_width]
64 add ebx,edx
65 and ebx,dword ptr [mask_width]
66 jnz is_mirrored
68 mov eax,edx
69 and eax,dword ptr [mask_mask]
70 add esi,eax
71 mov al,byte ptr [esi]
72 mov byte ptr [edi],al
73 inc edi
74 jmp end_mirror_check
75 is_mirrored:
76 add esi,dword ptr [mask_mask]
77 mov eax,edx
78 and eax,dword ptr [mask_mask]
79 sub esi,eax
80 mov al,byte ptr [esi]
81 mov byte ptr [edi],al
82 inc edi
83 end_mirror_check:
85 inc edx
86 cmp edx,dword ptr [count]
87 jne loop_x
89 add edi,dword ptr [line]
90 mov eax,dword ptr [tex]
91 add eax,dword ptr [line_full]
92 mov dword ptr [tex],eax
94 dec ecx
95 jnz loop_y
97 #else // _WIN32
98 //printf("Mirror8bS\n");
99 intptr_t fake_esi,fake_eax;
100 asm volatile (
101 "loop_y3: \n"
103 "xor %%edx, %%edx \n"
104 "loop_x3: \n"
105 "mov %[tex], %[S] \n"
106 "mov %[mask_width], %%eax \n"
107 "add %%edx, %%eax \n"
108 "and %[mask_width], %%eax \n"
109 "jnz is_mirrored2 \n"
111 "mov %%edx, %%eax \n"
112 "and %[mask_mask], %[a] \n"
113 "add %[a], %[S] \n"
114 "mov (%[S]), %%al \n"
115 "mov %%al, (%[start]) \n"
116 "inc %[start] \n"
117 "jmp end_mirror_check2 \n"
118 "is_mirrored2: \n"
119 "add %[mask_mask], %[S] \n"
120 "mov %%edx, %%eax \n"
121 "and %[mask_mask], %[a] \n"
122 "sub %[a], %[S] \n"
123 "mov (%[S]), %%al \n"
124 "mov %%al, (%[start]) \n"
125 "inc %[start] \n"
126 "end_mirror_check2: \n"
128 "inc %%edx \n"
129 "cmp %[count], %%edx \n"
130 "jne loop_x3 \n"
132 "add %[line], %[start] \n"
133 "add %[line_full], %[tex] \n"
135 "dec %%ecx \n"
136 "jnz loop_y3 \n"
137 : [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r" (tex)
138 : [mask_width] "g" (mask_width), [mask_mask] "g" ((intptr_t)mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
139 : "memory", "cc", "edx"
141 #endif // _WIN32
144 //****************************************************************
145 // 8-bit Vertical Mirror
147 void Mirror8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
149 if (mask == 0) return;
151 DWORD mask_height = (1 << mask);
152 DWORD mask_mask = mask_height-1;
153 if (max_height <= mask_height) return;
154 int line_full = real_width;
156 unsigned char * dst = tex + mask_height * line_full;
158 for (DWORD y=mask_height; y<max_height; y++)
160 if (y & mask_height)
162 // mirrored
163 memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);
165 else
167 // not mirrored
168 memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
171 dst += line_full;
175 //****************************************************************
176 // 8-bit Horizontal Wrap (like mirror) ** UNTESTED **
178 void Wrap8bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
180 if (mask == 0) return;
182 DWORD mask_width = (1 << mask);
183 DWORD mask_mask = (mask_width-1) >> 2;
184 if (mask_width >= max_width) return;
185 int count = (max_width - mask_width) >> 2;
186 if (count <= 0) return;
187 int line_full = real_width;
188 int line = line_full - (count << 2);
189 if (line < 0) return;
190 unsigned char * start = tex + (mask_width);
191 #ifndef GCC
192 __asm {
193 mov edi,dword ptr [start]
195 mov ecx,dword ptr [height]
196 loop_y:
198 xor edx,edx
199 loop_x:
201 mov esi,dword ptr [tex]
202 mov eax,edx
203 and eax,dword ptr [mask_mask]
204 shl eax,2
205 add esi,eax
206 mov eax,dword ptr [esi]
207 mov dword ptr [edi],eax
208 add edi,4
210 inc edx
211 cmp edx,dword ptr [count]
212 jne loop_x
214 add edi,dword ptr [line]
215 mov eax,dword ptr [tex]
216 add eax,dword ptr [line_full]
217 mov dword ptr [tex],eax
219 dec ecx
220 jnz loop_y
222 #else // _WIN32
223 //printf("wrap8bS\n");
224 intptr_t fake_esi,fake_eax;
225 asm volatile (
226 "loop_y4: \n"
228 "xor %%edx, %%edx \n"
229 "loop_x4: \n"
231 "mov %[tex], %[S] \n"
232 "mov %%edx, %%eax \n"
233 "and %[mask_mask], %%eax \n"
234 "shl $2, %%eax \n"
235 "add %[a], %[S] \n"
236 "mov (%[S]), %%eax \n"
237 "mov %%eax, (%[start]) \n"
238 "add $4, %[start] \n"
240 "inc %%edx \n"
241 "cmp %[count], %%edx \n"
242 "jne loop_x4 \n"
244 "add %[line], %[start] \n"
245 "add %[line_full], %[tex] \n"
247 "dec %%ecx \n"
248 "jnz loop_y4 \n"
249 : [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), [tex] "+r" (tex), "+c"(height)
250 : [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
251 : "memory", "cc", "edx"
253 #endif // _WIN32
256 //****************************************************************
257 // 8-bit Vertical Wrap
259 void Wrap8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
261 if (mask == 0) return;
263 DWORD mask_height = (1 << mask);
264 DWORD mask_mask = mask_height-1;
265 if (max_height <= mask_height) return;
266 int line_full = real_width;
268 unsigned char * dst = tex + mask_height * line_full;
270 for (DWORD y=mask_height; y<max_height; y++)
272 // not mirrored
273 memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
275 dst += line_full;
279 //****************************************************************
280 // 8-bit Horizontal Clamp
282 void Clamp8bS (unsigned char * tex, DWORD width, DWORD clamp_to, DWORD real_width, DWORD real_height)
284 if (real_width <= width) return;
286 unsigned char * dest = tex + (width);
287 unsigned char * constant = dest-1;
288 int count = clamp_to - width;
290 int line_full = real_width;
291 int line = width;
292 #ifndef GCC
293 __asm {
294 mov esi,dword ptr [constant]
295 mov edi,dword ptr [dest]
297 mov ecx,real_height
298 y_loop:
300 mov al,byte ptr [esi]
302 mov edx,dword ptr [count]
303 x_loop:
305 mov byte ptr [edi],al // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
306 inc edi
308 dec edx
309 jnz x_loop
311 add esi,dword ptr [line_full]
312 add edi,dword ptr [line]
314 dec ecx
315 jnz y_loop
317 #else // _WIN32
318 //printf("clamp8bs\n");
319 asm volatile (
320 "0: \n"
322 "mov (%[constant]), %%al \n"
324 "mov %[count], %%edx \n"
325 "1: \n"
327 "mov %%al, (%[dest]) \n" // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
328 "inc %[dest] \n"
330 "dec %%edx \n"
331 "jnz 1b \n"
333 "add %[line_full], %[constant] \n"
334 "add %[line], %[dest] \n"
336 "dec %%ecx \n"
337 "jnz 0b \n"
338 : [constant]"+S"(constant), [dest]"+D"(dest), "+c"(real_height)
339 : [count] "g" (count), [line] "g" ((uintptr_t)line), [line_full] "g" ((intptr_t)line_full)
340 : "memory", "cc", "eax", "edx"
342 #endif // _WIN32
345 //****************************************************************
346 // 8-bit Vertical Clamp
348 void Clamp8bT (unsigned char * tex, DWORD height, DWORD real_width, DWORD clamp_to)
350 int line_full = real_width;
351 unsigned char * dst = tex + height * line_full;
352 unsigned char * const_line = dst - line_full;
354 for (DWORD y=height; y<clamp_to; y++)
356 memcpy ((void*)dst, (void*)const_line, line_full);
357 dst += line_full;