/* * Glide64 - Glide video plugin for Nintendo 64 emulators. * Copyright (c) 2002 Dave2001 * Copyright (c) 2008 Günther * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public * Licence along with this program; if not, write to the Free * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA */ //**************************************************************** // // Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64) // Project started on December 29th, 2001 // // To modify Glide64: // * 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. // * 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. // // Official Glide64 development channel: #Glide64 on EFnet // // Original author: Dave2001 (Dave2999@hotmail.com) // Other authors: Gonetz, Gugaman // //**************************************************************** //**************************************************************** // 16-bit Horizontal Mirror void Mirror16bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height) { if (mask == 0) return; DWORD mask_width = (1 << mask); DWORD mask_mask = (mask_width-1) << 1; if (mask_width >= max_width) return; int count = max_width - mask_width; if (count <= 0) return; int line_full = real_width; int line = line_full - count; if (line < 0) return; unsigned short * start = (unsigned short *)(tex) + mask_width; unsigned short * edi = start; for(unsigned int ecx = height; ecx; --ecx) { for (int edx = 0; edx != count; ++edx) { unsigned short * esi = (unsigned short *)(tex); if ((mask_width + edx) & mask_width) { esi += (mask_mask - ((edx >> 1) & mask_mask)) / 2; } else { esi += ((edx >> 1) & mask_mask) / 2; } *edi = *esi; ++edi; } edi += line; tex += line_full * 2; } } //**************************************************************** // 16-bit Vertical Mirror void Mirror16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width) { if (mask == 0) return; DWORD mask_height = (1 << mask); DWORD mask_mask = mask_height-1; if (max_height <= mask_height) return; int line_full = real_width << 1; unsigned char * dst = tex + mask_height * line_full; for (DWORD y=mask_height; y> 1; if (mask_width >= max_width) return; int count = (max_width - mask_width) >> 1; if (count <= 0) return; int line_full = real_width << 1; int line = line_full - (count << 2); if (line < 0) return; unsigned char * start = tex + (mask_width << 1); #if !defined(__GNUC__) && !defined(NO_ASM) __asm { mov edi,dword ptr [start] mov ecx,dword ptr [height] loop_y: xor edx,edx loop_x: mov esi,dword ptr [tex] mov eax,edx and eax,dword ptr [mask_mask] shl eax,2 add esi,eax mov eax,dword ptr [esi] mov dword ptr [edi],eax add edi,4 inc edx cmp edx,dword ptr [count] jne loop_x add edi,dword ptr [line] mov eax,dword ptr [tex] add eax,dword ptr [line_full] mov dword ptr [tex],eax dec ecx jnz loop_y } #elif !defined(NO_ASM) //printf("wrap16bS\n"); intptr_t fake_esi, fake_eax; asm volatile ( "0: \n" "xor %%edx, %%edx \n" "1: \n" "mov %[tex], %[S] \n" "mov %%edx, %%eax \n" "and %[mask_mask], %%eax \n" "shl $2, %%eax \n" "add %[a], %[S] \n" "mov (%[S]), %%eax \n" "mov %%eax, (%[start]) \n" "add $4, %[start] \n" "inc %%edx \n" "cmp %[count], %%edx \n" "jne 1b \n" "add %[line], %[start] \n" "add %[line_full], %[tex] \n" "dec %%ecx \n" "jnz 0b \n" : [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r"(tex) : [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full) : "memory", "cc", "edx" ); #endif // _WIN32 } //**************************************************************** // 16-bit Vertical Wrap void Wrap16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width) { if (mask == 0) return; DWORD mask_height = (1 << mask); DWORD mask_mask = mask_height-1; if (max_height <= mask_height) return; int line_full = real_width << 1; unsigned char * dst = tex + mask_height * line_full; for (DWORD y=mask_height; y