Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alexbevi
GitHub Repository: alexbevi/BizHawk
Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/MiClWr16b.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
// 16-bit Horizontal Mirror
40
41
void Mirror16bS (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) << 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 short * start = (unsigned short *)(tex) + mask_width;
54
55
unsigned short * edi = start;
56
for(unsigned int ecx = height; ecx; --ecx)
57
{
58
for (int edx = 0; edx != count; ++edx)
59
{
60
unsigned short * esi = (unsigned short *)(tex);
61
if ((mask_width + edx) & mask_width)
62
{
63
esi += (mask_mask - ((edx >> 1) & mask_mask)) / 2;
64
}
65
else
66
{
67
esi += ((edx >> 1) & mask_mask) / 2;
68
}
69
*edi = *esi;
70
++edi;
71
}
72
edi += line;
73
tex += line_full * 2;
74
}
75
}
76
77
//****************************************************************
78
// 16-bit Vertical Mirror
79
80
void Mirror16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
81
{
82
if (mask == 0) return;
83
84
DWORD mask_height = (1 << mask);
85
DWORD mask_mask = mask_height-1;
86
if (max_height <= mask_height) return;
87
int line_full = real_width << 1;
88
89
unsigned char * dst = tex + mask_height * line_full;
90
91
for (DWORD y=mask_height; y<max_height; y++)
92
{
93
if (y & mask_height)
94
{
95
// mirrored
96
memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);
97
}
98
else
99
{
100
// not mirrored
101
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
102
}
103
104
dst += line_full;
105
}
106
}
107
108
//****************************************************************
109
// 16-bit Horizontal Wrap (like mirror)
110
111
void Wrap16bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)
112
{
113
if (mask == 0) return;
114
115
DWORD mask_width = (1 << mask);
116
DWORD mask_mask = (mask_width-1) >> 1;
117
if (mask_width >= max_width) return;
118
int count = (max_width - mask_width) >> 1;
119
if (count <= 0) return;
120
int line_full = real_width << 1;
121
int line = line_full - (count << 2);
122
if (line < 0) return;
123
unsigned char * start = tex + (mask_width << 1);
124
#if !defined(__GNUC__) && !defined(NO_ASM)
125
__asm {
126
mov edi,dword ptr [start]
127
128
mov ecx,dword ptr [height]
129
loop_y:
130
131
xor edx,edx
132
loop_x:
133
134
mov esi,dword ptr [tex]
135
mov eax,edx
136
and eax,dword ptr [mask_mask]
137
shl eax,2
138
add esi,eax
139
mov eax,dword ptr [esi]
140
mov dword ptr [edi],eax
141
add edi,4
142
143
inc edx
144
cmp edx,dword ptr [count]
145
jne loop_x
146
147
add edi,dword ptr [line]
148
mov eax,dword ptr [tex]
149
add eax,dword ptr [line_full]
150
mov dword ptr [tex],eax
151
152
dec ecx
153
jnz loop_y
154
}
155
#elif !defined(NO_ASM)
156
//printf("wrap16bS\n");
157
intptr_t fake_esi, fake_eax;
158
asm volatile (
159
"0: \n"
160
161
"xor %%edx, %%edx \n"
162
"1: \n"
163
164
"mov %[tex], %[S] \n"
165
"mov %%edx, %%eax \n"
166
"and %[mask_mask], %%eax \n"
167
"shl $2, %%eax \n"
168
"add %[a], %[S] \n"
169
"mov (%[S]), %%eax \n"
170
"mov %%eax, (%[start]) \n"
171
"add $4, %[start] \n"
172
173
"inc %%edx \n"
174
"cmp %[count], %%edx \n"
175
"jne 1b \n"
176
177
"add %[line], %[start] \n"
178
"add %[line_full], %[tex] \n"
179
180
"dec %%ecx \n"
181
"jnz 0b \n"
182
: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r"(tex)
183
: [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
184
: "memory", "cc", "edx"
185
);
186
#endif // _WIN32
187
}
188
189
//****************************************************************
190
// 16-bit Vertical Wrap
191
192
void Wrap16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)
193
{
194
if (mask == 0) return;
195
196
DWORD mask_height = (1 << mask);
197
DWORD mask_mask = mask_height-1;
198
if (max_height <= mask_height) return;
199
int line_full = real_width << 1;
200
201
unsigned char * dst = tex + mask_height * line_full;
202
203
for (DWORD y=mask_height; y<max_height; y++)
204
{
205
// not mirrored
206
memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);
207
208
dst += line_full;
209
}
210
}
211
212
//****************************************************************
213
// 16-bit Horizontal Clamp
214
215
void Clamp16bS (unsigned char * tex, DWORD width, DWORD clamp_to, DWORD real_width, DWORD real_height)
216
{
217
if (real_width <= width) return;
218
219
unsigned char * dest = tex + (width << 1);
220
unsigned char * constant = dest-2;
221
int count = clamp_to - width;
222
223
int line_full = real_width << 1;
224
int line = width << 1;
225
226
#if !defined(__GNUC__) && !defined(NO_ASM)
227
__asm {
228
mov esi,dword ptr [constant]
229
mov edi,dword ptr [dest]
230
231
mov ecx,real_height
232
y_loop:
233
234
mov ax,word ptr [esi]
235
236
mov edx,dword ptr [count]
237
x_loop:
238
239
mov word ptr [edi],ax // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
240
add edi,2
241
242
dec edx
243
jnz x_loop
244
245
add esi,dword ptr [line_full]
246
add edi,dword ptr [line]
247
248
dec ecx
249
jnz y_loop
250
}
251
#elif !defined(NO_ASM)
252
//printf("clamp16bS\n");
253
asm volatile (
254
//"y_loop10: \n"
255
"0: \n"
256
257
"mov (%[constant]), %%ax \n"
258
259
"mov %[count], %%edx \n"
260
//"x_loop10: \n"
261
"1: \n"
262
263
"mov %%ax, (%[dest]) \n" // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)
264
"add $2, %[dest] \n"
265
266
"dec %%edx \n"
267
//"jnz x_loop10 \n"
268
"jnz 1b \n"
269
270
"add %[line_full], %[constant] \n"
271
"add %[line], %[dest] \n"
272
273
"dec %%ecx \n"
274
//"jnz y_loop10 \n"
275
"jnz 0b \n"
276
: "+c"(real_height), [constant]"+S"(constant), [dest]"+D"(dest)
277
: [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)
278
: "memory", "cc", "eax", "edx"
279
);
280
#endif
281
}
282
283
//****************************************************************
284
// 16-bit Vertical Clamp
285
286
void Clamp16bT (unsigned char * tex, DWORD height, DWORD real_width, DWORD clamp_to)
287
{
288
int line_full = real_width << 1;
289
unsigned char * dst = tex + height * line_full;
290
unsigned char * const_line = dst - line_full;
291
292
for (DWORD y=height; y<clamp_to; y++)
293
{
294
memcpy ((void*)dst, (void*)const_line, line_full);
295
dst += line_full;
296
}
297
}
298
299
300