1 /***********************************************************************************
2 Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
3
4 (c) Copyright 1996 - 2002 Gary Henderson (gary.henderson@ntlworld.com),
5 Jerremy Koot (jkoot@snes9x.com)
6
7 (c) Copyright 2002 - 2004 Matthew Kendora
8
9 (c) Copyright 2002 - 2005 Peter Bortas (peter@bortas.org)
10
11 (c) Copyright 2004 - 2005 Joel Yliluoma (http://iki.fi/bisqwit/)
12
13 (c) Copyright 2001 - 2006 John Weidman (jweidman@slip.net)
14
15 (c) Copyright 2002 - 2006 funkyass (funkyass@spam.shaw.ca),
16 Kris Bleakley (codeviolation@hotmail.com)
17
18 (c) Copyright 2002 - 2010 Brad Jorsch (anomie@users.sourceforge.net),
19 Nach (n-a-c-h@users.sourceforge.net),
20
21 (c) Copyright 2002 - 2011 zones (kasumitokoduck@yahoo.com)
22
23 (c) Copyright 2006 - 2007 nitsuja
24
25 (c) Copyright 2009 - 2016 BearOso,
26 OV2
27
28
29 BS-X C emulator code
30 (c) Copyright 2005 - 2006 Dreamer Nom,
31 zones
32
33 C4 x86 assembler and some C emulation code
34 (c) Copyright 2000 - 2003 _Demo_ (_demo_@zsnes.com),
35 Nach,
36 zsKnight (zsknight@zsnes.com)
37
38 C4 C++ code
39 (c) Copyright 2003 - 2006 Brad Jorsch,
40 Nach
41
42 DSP-1 emulator code
43 (c) Copyright 1998 - 2006 _Demo_,
44 Andreas Naive (andreasnaive@gmail.com),
45 Gary Henderson,
46 Ivar (ivar@snes9x.com),
47 John Weidman,
48 Kris Bleakley,
49 Matthew Kendora,
50 Nach,
51 neviksti (neviksti@hotmail.com)
52
53 DSP-2 emulator code
54 (c) Copyright 2003 John Weidman,
55 Kris Bleakley,
56 Lord Nightmare (lord_nightmare@users.sourceforge.net),
57 Matthew Kendora,
58 neviksti
59
60 DSP-3 emulator code
61 (c) Copyright 2003 - 2006 John Weidman,
62 Kris Bleakley,
63 Lancer,
64 z80 gaiden
65
66 DSP-4 emulator code
67 (c) Copyright 2004 - 2006 Dreamer Nom,
68 John Weidman,
69 Kris Bleakley,
70 Nach,
71 z80 gaiden
72
73 OBC1 emulator code
74 (c) Copyright 2001 - 2004 zsKnight,
75 pagefault (pagefault@zsnes.com),
76 Kris Bleakley
77 Ported from x86 assembler to C by sanmaiwashi
78
79 SPC7110 and RTC C++ emulator code used in 1.39-1.51
80 (c) Copyright 2002 Matthew Kendora with research by
81 zsKnight,
82 John Weidman,
83 Dark Force
84
85 SPC7110 and RTC C++ emulator code used in 1.52+
86 (c) Copyright 2009 byuu,
87 neviksti
88
89 S-DD1 C emulator code
90 (c) Copyright 2003 Brad Jorsch with research by
91 Andreas Naive,
92 John Weidman
93
94 S-RTC C emulator code
95 (c) Copyright 2001 - 2006 byuu,
96 John Weidman
97
98 ST010 C++ emulator code
99 (c) Copyright 2003 Feather,
100 John Weidman,
101 Kris Bleakley,
102 Matthew Kendora
103
104 Super FX x86 assembler emulator code
105 (c) Copyright 1998 - 2003 _Demo_,
106 pagefault,
107 zsKnight
108
109 Super FX C emulator code
110 (c) Copyright 1997 - 1999 Ivar,
111 Gary Henderson,
112 John Weidman
113
114 Sound emulator code used in 1.5-1.51
115 (c) Copyright 1998 - 2003 Brad Martin
116 (c) Copyright 1998 - 2006 Charles Bilyue'
117
118 Sound emulator code used in 1.52+
119 (c) Copyright 2004 - 2007 Shay Green (gblargg@gmail.com)
120
121 S-SMP emulator code used in 1.54+
122 (c) Copyright 2016 byuu
123
124 SH assembler code partly based on x86 assembler code
125 (c) Copyright 2002 - 2004 Marcus Comstedt (marcus@mc.pp.se)
126
127 2xSaI filter
128 (c) Copyright 1999 - 2001 Derek Liauw Kie Fa
129
130 HQ2x, HQ3x, HQ4x filters
131 (c) Copyright 2003 Maxim Stepin (maxim@hiend3d.com)
132
133 NTSC filter
134 (c) Copyright 2006 - 2007 Shay Green
135
136 GTK+ GUI code
137 (c) Copyright 2004 - 2016 BearOso
138
139 Win32 GUI code
140 (c) Copyright 2003 - 2006 blip,
141 funkyass,
142 Matthew Kendora,
143 Nach,
144 nitsuja
145 (c) Copyright 2009 - 2016 OV2
146
147 Mac OS GUI code
148 (c) Copyright 1998 - 2001 John Stiles
149 (c) Copyright 2001 - 2011 zones
150
151
152 Specific ports contains the works of other authors. See headers in
153 individual files.
154
155
156 Snes9x homepage: http://www.snes9x.com/
157
158 Permission to use, copy, modify and/or distribute Snes9x in both binary
159 and source form, for non-commercial purposes, is hereby granted without
160 fee, providing that this license information and copyright notice appear
161 with all copies and any derived work.
162
163 This software is provided 'as-is', without any express or implied
164 warranty. In no event shall the authors be held liable for any damages
165 arising from the use of this software or it's derivatives.
166
167 Snes9x is freeware for PERSONAL USE only. Commercial users should
168 seek permission of the copyright holders first. Commercial use includes,
169 but is not limited to, charging money for Snes9x or software derived from
170 Snes9x, including Snes9x or derivatives in commercial game bundles, and/or
171 using Snes9x as a promotion for your commercial product.
172
173 The copyright holders request that bug fixes and improvements to the code
174 should be forwarded to them so everyone can benefit from the modifications
175 in future versions.
176
177 Super NES and Super Nintendo Entertainment System are trademarks of
178 Nintendo Co., Limited and its subsidiary companies.
179 ***********************************************************************************/
180
181
182 #include "snes9x.h"
183 #include "epx.h"
184
185
EPX_16(uint8 * srcPtr,int srcRowBytes,uint8 * dstPtr,int dstRowBytes,int width,int height)186 void EPX_16 (uint8 *srcPtr, int srcRowBytes, uint8 *dstPtr, int dstRowBytes, int width, int height)
187 {
188 uint16 colorX, colorA, colorB, colorC, colorD;
189 uint16 *sP, *uP, *lP;
190 uint32 *dP1, *dP2;
191 int w;
192
193 height -= 2;
194
195 // D
196 // A X C
197 // B
198
199 // top edge
200
201 sP = (uint16 *) srcPtr;
202 lP = (uint16 *) (srcPtr + srcRowBytes);
203 dP1 = (uint32 *) dstPtr;
204 dP2 = (uint32 *) (dstPtr + dstRowBytes);
205
206 // left edge
207
208 colorX = *sP;
209 colorC = *++sP;
210 colorB = *lP++;
211
212 if ((colorX != colorC) && (colorB != colorX))
213 {
214 #ifdef MSB_FIRST
215 *dP1 = (colorX << 16) + colorX;
216 *dP2 = (colorX << 16) + ((colorB == colorC) ? colorB : colorX);
217 #else
218 *dP1 = colorX + (colorX << 16);
219 *dP2 = colorX + (((colorB == colorC) ? colorB : colorX) << 16);
220 #endif
221 }
222 else
223 *dP1 = *dP2 = (colorX << 16) + colorX;
224
225 dP1++;
226 dP2++;
227
228 //
229
230 for (w = width - 2; w; w--)
231 {
232 colorA = colorX;
233 colorX = colorC;
234 colorC = *++sP;
235 colorB = *lP++;
236
237 if ((colorA != colorC) && (colorB != colorX))
238 {
239 #ifdef MSB_FIRST
240 *dP1 = (colorX << 16) + colorX;
241 *dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
242 #else
243 *dP1 = colorX + (colorX << 16);
244 *dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
245 #endif
246 }
247 else
248 *dP1 = *dP2 = (colorX << 16) + colorX;
249
250 dP1++;
251 dP2++;
252 }
253
254 // right edge
255
256 colorA = colorX;
257 colorX = colorC;
258 colorB = *lP;
259
260 if ((colorA != colorX) && (colorB != colorX))
261 {
262 #ifdef MSB_FIRST
263 *dP1 = (colorX << 16) + colorX;
264 *dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + colorX;
265 #else
266 *dP1 = colorX + (colorX << 16);
267 *dP2 = ((colorA == colorB) ? colorA : colorX) + (colorX << 16);
268 #endif
269 }
270 else
271 *dP1 = *dP2 = (colorX << 16) + colorX;
272
273 srcPtr += srcRowBytes;
274 dstPtr += dstRowBytes << 1;
275
276 //
277
278 for (; height; height--)
279 {
280 sP = (uint16 *) srcPtr;
281 uP = (uint16 *) (srcPtr - srcRowBytes);
282 lP = (uint16 *) (srcPtr + srcRowBytes);
283 dP1 = (uint32 *) dstPtr;
284 dP2 = (uint32 *) (dstPtr + dstRowBytes);
285
286 // left edge
287
288 colorX = *sP;
289 colorC = *++sP;
290 colorB = *lP++;
291 colorD = *uP++;
292
293 if ((colorX != colorC) && (colorB != colorD))
294 {
295 #ifdef MSB_FIRST
296 *dP1 = (colorX << 16) + ((colorC == colorD) ? colorC : colorX);
297 *dP2 = (colorX << 16) + ((colorB == colorC) ? colorB : colorX);
298 #else
299 *dP1 = colorX + (((colorC == colorD) ? colorC : colorX) << 16);
300 *dP2 = colorX + (((colorB == colorC) ? colorB : colorX) << 16);
301 #endif
302 }
303 else
304 *dP1 = *dP2 = (colorX << 16) + colorX;
305
306 dP1++;
307 dP2++;
308
309 //
310
311 for (w = width - 2; w; w--)
312 {
313 colorA = colorX;
314 colorX = colorC;
315 colorC = *++sP;
316 colorB = *lP++;
317 colorD = *uP++;
318
319 if ((colorA != colorC) && (colorB != colorD))
320 {
321 #ifdef MSB_FIRST
322 *dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
323 *dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + ((colorB == colorC) ? colorB : colorX);
324 #else
325 *dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
326 *dP2 = ((colorA == colorB) ? colorA : colorX) + (((colorB == colorC) ? colorB : colorX) << 16);
327 #endif
328 }
329 else
330 *dP1 = *dP2 = (colorX << 16) + colorX;
331
332 dP1++;
333 dP2++;
334 }
335
336 // right edge
337
338 colorA = colorX;
339 colorX = colorC;
340 colorB = *lP;
341 colorD = *uP;
342
343 if ((colorA != colorX) && (colorB != colorD))
344 {
345 #ifdef MSB_FIRST
346 *dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + colorX;
347 *dP2 = (((colorA == colorB) ? colorA : colorX) << 16) + colorX;
348 #else
349 *dP1 = ((colorD == colorA) ? colorD : colorX) + (colorX << 16);
350 *dP2 = ((colorA == colorB) ? colorA : colorX) + (colorX << 16);
351 #endif
352 }
353 else
354 *dP1 = *dP2 = (colorX << 16) + colorX;
355
356 srcPtr += srcRowBytes;
357 dstPtr += dstRowBytes << 1;
358 }
359
360 // bottom edge
361
362 sP = (uint16 *) srcPtr;
363 uP = (uint16 *) (srcPtr - srcRowBytes);
364 dP1 = (uint32 *) dstPtr;
365 dP2 = (uint32 *) (dstPtr + dstRowBytes);
366
367 // left edge
368
369 colorX = *sP;
370 colorC = *++sP;
371 colorD = *uP++;
372
373 if ((colorX != colorC) && (colorX != colorD))
374 {
375 #ifdef MSB_FIRST
376 *dP1 = (colorX << 16) + ((colorC == colorD) ? colorC : colorX);
377 *dP2 = (colorX << 16) + colorX;
378 #else
379 *dP1 = colorX + (((colorC == colorD) ? colorC : colorX) << 16);
380 *dP2 = colorX + (colorX << 16);
381 #endif
382 }
383 else
384 *dP1 = *dP2 = (colorX << 16) + colorX;
385
386 dP1++;
387 dP2++;
388
389 //
390
391 for (w = width - 2; w; w--)
392 {
393 colorA = colorX;
394 colorX = colorC;
395 colorC = *++sP;
396 colorD = *uP++;
397
398 if ((colorA != colorC) && (colorX != colorD))
399 {
400 #ifdef MSB_FIRST
401 *dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + ((colorC == colorD) ? colorC : colorX);
402 *dP2 = (colorX << 16) + colorX;
403 #else
404 *dP1 = ((colorD == colorA) ? colorD : colorX) + (((colorC == colorD) ? colorC : colorX) << 16);
405 *dP2 = colorX + (colorX << 16);
406 #endif
407 }
408 else
409 *dP1 = *dP2 = (colorX << 16) + colorX;
410
411 dP1++;
412 dP2++;
413 }
414
415 // right edge
416
417 colorA = colorX;
418 colorX = colorC;
419 colorD = *uP;
420
421 if ((colorA != colorX) && (colorX != colorD))
422 {
423 #ifdef MSB_FIRST
424 *dP1 = (((colorD == colorA) ? colorD : colorX) << 16) + colorX;
425 *dP2 = (colorX << 16) + colorX;
426 #else
427 *dP1 = ((colorD == colorA) ? colorD : colorX) + (colorX << 16);
428 *dP2 = colorX + (colorX << 16);
429 #endif
430 }
431 else
432 *dP1 = *dP2 = (colorX << 16) + colorX;
433 }
434