Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/MiClWr8b.h
2 views
1
/*
2
* Glide64 - Glide video plugin for Nintendo 64 emulators.
3
* Copyright (c) 2002 Dave2001
4
* Copyright (c) 2008 Günther <[email protected]>
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
17
* Licence along with this program; if not, write to the Free
18
* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19
* Boston, MA 02110-1301, USA
20
*/
21
22
//****************************************************************
23
//
24
// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)
25
// Project started on December 29th, 2001
26
//
27
// To modify Glide64:
28
// * 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.
29
// * 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
//
31
// Official Glide64 development channel: #Glide64 on EFnet
32
//
33
// Original author: Dave2001 ([email protected])
34
// Other authors: Gonetz, Gugaman
35
//
36
//****************************************************************
37
38
//****************************************************************
39
// 8-bit Horizontal Mirror
40
41
void Mirror8bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
42
{
43
if (mask == 0) return;
44
45
DWORD mask_width = (1 << mask);
46
DWORD mask_mask = (mask_width-1);
47
if (mask_width >= max_width) return;
48
int count = max_width - mask_width;
49
if (count <= 0) return;
50
int line_full = real_width;
51
int line = line_full - (count);
52
if (line < 0) return;
53
unsigned char * start = tex + (mask_width);
54
#if !defined(__GNUC__) && !defined(NO_ASM)
55
__asm {
56
mov edi,dword ptr [start]
57
58
mov ecx,dword ptr [height]
59
loop_y:
60
61
xor edx,edx
62
loop_x:
63
mov esi,dword ptr [tex]
64
mov ebx,dword ptr [mask_width]
65
add ebx,edx
66
and ebx,dword ptr [mask_width]
67
jnz is_mirrored
68
69
mov eax,edx
70
and eax,dword ptr [mask_mask]
71
add esi,eax
72
mov al,byte ptr [esi]
73
mov byte ptr [edi],al
74
inc edi
75
jmp end_mirror_check
76
is_mirrored:
77
add esi,dword ptr [mask_mask]
78
mov eax,edx
79
and eax,dword ptr [mask_mask]
80
sub esi,eax
81
mov al,byte ptr [esi]
82
mov byte ptr [edi],al
83
inc edi
84
end_mirror_check:
85
86
inc edx
87
cmp edx,dword ptr [count]
88
jne loop_x
89
90
add edi,dword ptr [line]
91
mov eax,dword ptr [tex]
92
add eax,dword ptr [line_full]
93
mov dword ptr [tex],eax
94
95
dec ecx
96
jnz loop_y
97
}
98
#elif !defined(NO_ASM)
99
//printf("Mirror8bS\n");
100
intptr_t fake_esi,fake_eax;
101
asm volatile (
102
"1: \n" // loop_y3
103
104
"xor %%edx, %%edx \n"
105
"2: \n" // loop_x3
106
"mov %[tex], %[S] \n"
107
"mov %[mask_width], %%eax \n"
108
"add %%edx, %%eax \n"
109
"and %[mask_width], %%eax \n"
110
"jnz 3f \n" // is_mirrored2
111
112
"mov %%edx, %%eax \n"
113
"and %[mask_mask], %[a] \n"
114
"add %[a], %[S] \n"
115
"mov (%[S]), %%al \n"
116
"mov %%al, (%[start]) \n"
117
"inc %[start] \n"
118
"jmp 4f \n" // end_mirror_check2
119
"3: \n" // is_mirrored2
120
"add %[mask_mask], %[S] \n"
121
"mov %%edx, %%eax \n"
122
"and %[mask_mask], %[a] \n"
123
"sub %[a], %[S] \n"
124
"mov (%[S]), %%al \n"
125
"mov %%al, (%[start]) \n"
126
"inc %[start] \n"
127
"4: \n" // end_mirror_check2
128
129
"inc %%edx \n"
130
"cmp %[count], %%edx \n"
131
"jne 2b \n" // loop_x3
132
133
"add %[line], %[start] \n"
134
"add %[line_full], %[tex] \n"
135
136
"dec %%ecx \n"
137
"jnz 1b \n" // loop_y3
138
: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r" (tex)
139
: [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)
140
: "memory", "cc", "edx"
141
);
142
#endif // _WIN32
143
}
144
145
//****************************************************************
146
// 8-bit Vertical Mirror
147
148
void Mirror8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
149
{
150
if (mask == 0) return;
151
152
DWORD mask_height = (1 << mask);
153
DWORD mask_mask = mask_height-1;
154
if (max_height <= mask_height) return;
155
int line_full = real_width;
156
157
unsigned char * dst = tex + mask_height * line_full;
158
159
for (DWORD y=mask_height; y<max_height; y++)
160
{
161
if (y & mask_height)
162
{
163
// mirrored
164
memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);
165
}
166
else
167
{
168
// not mirrored
169
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
170
}
171
172
dst += line_full;
173
}
174
}
175
176
//****************************************************************
177
// 8-bit Horizontal Wrap (like mirror) ** UNTESTED **
178
179
void Wrap8bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
180
{
181
if (mask == 0) return;
182
183
DWORD mask_width = (1 << mask);
184
DWORD mask_mask = (mask_width-1) >> 2;
185
if (mask_width >= max_width) return;
186
int count = (max_width - mask_width) >> 2;
187
if (count <= 0) return;
188
int line_full = real_width;
189
int line = line_full - (count << 2);
190
if (line < 0) return;
191
unsigned char * start = tex + (mask_width);
192
#if !defined(__GNUC__) && !defined(NO_ASM)
193
__asm {
194
mov edi,dword ptr [start]
195
196
mov ecx,dword ptr [height]
197
loop_y:
198
199
xor edx,edx
200
loop_x:
201
202
mov esi,dword ptr [tex]
203
mov eax,edx
204
and eax,dword ptr [mask_mask]
205
shl eax,2
206
add esi,eax
207
mov eax,dword ptr [esi]
208
mov dword ptr [edi],eax
209
add edi,4
210
211
inc edx
212
cmp edx,dword ptr [count]
213
jne loop_x
214
215
add edi,dword ptr [line]
216
mov eax,dword ptr [tex]
217
add eax,dword ptr [line_full]
218
mov dword ptr [tex],eax
219
220
dec ecx
221
jnz loop_y
222
}
223
#elif !defined(NO_ASM)
224
//printf("wrap8bS\n");
225
intptr_t fake_esi,fake_eax;
226
asm volatile (
227
"1: \n" // loop_y4
228
229
"xor %%edx, %%edx \n"
230
"2: \n" // loop_x4
231
232
"mov %[tex], %[S] \n"
233
"mov %%edx, %%eax \n"
234
"and %[mask_mask], %%eax \n"
235
"shl $2, %%eax \n"
236
"add %[a], %[S] \n"
237
"mov (%[S]), %%eax \n"
238
"mov %%eax, (%[start]) \n"
239
"add $4, %[start] \n"
240
241
"inc %%edx \n"
242
"cmp %[count], %%edx \n"
243
"jne 2b \n" // loop_x4
244
245
"add %[line], %[start] \n"
246
"add %[line_full], %[tex] \n"
247
248
"dec %%ecx \n"
249
"jnz 1b \n" // loop_y4
250
: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), [tex] "+r" (tex), "+c"(height)
251
: [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
252
: "memory", "cc", "edx"
253
);
254
#endif
255
}
256
257
//****************************************************************
258
// 8-bit Vertical Wrap
259
260
void Wrap8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
261
{
262
if (mask == 0) return;
263
264
DWORD mask_height = (1 << mask);
265
DWORD mask_mask = mask_height-1;
266
if (max_height <= mask_height) return;
267
int line_full = real_width;
268
269
unsigned char * dst = tex + mask_height * line_full;
270
271
for (DWORD y=mask_height; y<max_height; y++)
272
{
273
// not mirrored
274
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
275
276
dst += line_full;
277
}
278
}
279
280
//****************************************************************
281
// 8-bit Horizontal Clamp
282
283
void Clamp8bS (unsigned char * tex, DWORD width, DWORD clamp_to, DWORD real_width, DWORD real_height)
284
{
285
if (real_width <= width) return;
286
287
unsigned char * dest = tex + (width);
288
unsigned char * constant = dest-1;
289
int count = clamp_to - width;
290
291
int line_full = real_width;
292
int line = width;
293
#if !defined(__GNUC__) && !defined(NO_ASM)
294
__asm {
295
mov esi,dword ptr [constant]
296
mov edi,dword ptr [dest]
297
298
mov ecx,real_height
299
y_loop:
300
301
mov al,byte ptr [esi]
302
303
mov edx,dword ptr [count]
304
x_loop:
305
306
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)
307
inc edi
308
309
dec edx
310
jnz x_loop
311
312
add esi,dword ptr [line_full]
313
add edi,dword ptr [line]
314
315
dec ecx
316
jnz y_loop
317
}
318
#elif !defined(NO_ASM)
319
//printf("clamp8bs\n");
320
asm volatile (
321
"0: \n"
322
323
"mov (%[constant]), %%al \n"
324
325
"mov %[count], %%edx \n"
326
"1: \n"
327
328
"mov %%al, (%[dest]) \n" // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
329
"inc %[dest] \n"
330
331
"dec %%edx \n"
332
"jnz 1b \n"
333
334
"add %[line_full], %[constant] \n"
335
"add %[line], %[dest] \n"
336
337
"dec %%ecx \n"
338
"jnz 0b \n"
339
: [constant]"+S"(constant), [dest]"+D"(dest), "+c"(real_height)
340
: [count] "g" (count), [line] "g" ((uintptr_t)line), [line_full] "g" ((intptr_t)line_full)
341
: "memory", "cc", "eax", "edx"
342
);
343
#endif
344
}
345
346
//****************************************************************
347
// 8-bit Vertical Clamp
348
349
void Clamp8bT (unsigned char * tex, DWORD height, DWORD real_width, DWORD clamp_to)
350
{
351
int line_full = real_width;
352
unsigned char * dst = tex + height * line_full;
353
unsigned char * const_line = dst - line_full;
354
355
for (DWORD y=height; y<clamp_to; y++)
356
{
357
memcpy ((void*)dst, (void*)const_line, line_full);
358
dst += line_full;
359
}
360
}
361
362
363