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
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
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
);
52 unsigned char * start
= tex
+ (mask_width
);
55 mov edi
,dword ptr
[start
]
57 mov ecx
,dword ptr
[height
]
62 mov esi
,dword ptr
[tex
]
63 mov ebx
,dword ptr
[mask_width
]
65 and ebx
,dword ptr
[mask_width
]
69 and eax
,dword ptr
[mask_mask
]
76 add esi
,dword ptr
[mask_mask
]
78 and eax
,dword ptr
[mask_mask
]
86 cmp edx
,dword ptr
[count
]
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
98 //printf("Mirror8bS\n");
99 intptr_t fake_esi
,fake_eax
;
103 "xor %%edx, %%edx \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"
114 "mov (%[S]), %%al \n"
115 "mov %%al, (%[start]) \n"
117 "jmp end_mirror_check2 \n"
119 "add %[mask_mask], %[S] \n"
120 "mov %%edx, %%eax \n"
121 "and %[mask_mask], %[a] \n"
123 "mov (%[S]), %%al \n"
124 "mov %%al, (%[start]) \n"
126 "end_mirror_check2: \n"
129 "cmp %[count], %%edx \n"
132 "add %[line], %[start] \n"
133 "add %[line_full], %[tex] \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"
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
++)
163 memcpy ((void*)dst
, (void*)(tex
+ (mask_mask
- (y
& mask_mask
)) * line_full
), line_full
);
168 memcpy ((void*)dst
, (void*)(tex
+ (y
& mask_mask
) * line_full
), 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
);
193 mov edi
,dword ptr
[start
]
195 mov ecx
,dword ptr
[height
]
201 mov esi
,dword ptr
[tex
]
203 and eax
,dword ptr
[mask_mask
]
206 mov eax
,dword ptr
[esi
]
207 mov dword ptr
[edi
],eax
211 cmp edx
,dword ptr
[count
]
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
223 //printf("wrap8bS\n");
224 intptr_t fake_esi
,fake_eax
;
228 "xor %%edx, %%edx \n"
231 "mov %[tex], %[S] \n"
232 "mov %%edx, %%eax \n"
233 "and %[mask_mask], %%eax \n"
236 "mov (%[S]), %%eax \n"
237 "mov %%eax, (%[start]) \n"
238 "add $4, %[start] \n"
241 "cmp %[count], %%edx \n"
244 "add %[line], %[start] \n"
245 "add %[line_full], %[tex] \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"
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
++)
273 memcpy ((void*)dst
, (void*)(tex
+ (y
& mask_mask
) * line_full
), 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
;
294 mov esi
,dword ptr
[constant
]
295 mov edi
,dword ptr
[dest
]
300 mov al
,byte ptr
[esi
]
302 mov edx
,dword ptr
[count
]
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)
311 add esi
,dword ptr
[line_full
]
312 add edi
,dword ptr
[line
]
318 //printf("clamp8bs\n");
322 "mov (%[constant]), %%al \n"
324 "mov %[count], %%edx \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)
333 "add %[line_full], %[constant] \n"
334 "add %[line], %[dest] \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"
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
);