Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/MiClWr16b.h
2 views
/*1* Glide64 - Glide video plugin for Nintendo 64 emulators.2* Copyright (c) 2002 Dave20013* Copyright (c) 2008 Günther <[email protected]>4*5* This program is free software; you can redistribute it and/or modify6* it under the terms of the GNU General Public License as published by7* the Free Software Foundation; either version 2 of the License, or8* any later version.9*10* This program is distributed in the hope that it will be useful,11* but WITHOUT ANY WARRANTY; without even the implied warranty of12* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the13* GNU General Public License for more details.14*15* You should have received a copy of the GNU General Public16* Licence along with this program; if not, write to the Free17* Software Foundation, Inc., 51 Franklin Street, Fifth Floor,18* Boston, MA 02110-1301, USA19*/2021//****************************************************************22//23// Glide64 - Glide Plugin for Nintendo 64 emulators (tested mostly with Project64)24// Project started on December 29th, 200125//26// To modify Glide64: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.29//30// Official Glide64 development channel: #Glide64 on EFnet31//32// Original author: Dave2001 ([email protected])33// Other authors: Gonetz, Gugaman34//35//****************************************************************3637//****************************************************************38// 16-bit Horizontal Mirror3940void Mirror16bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)41{42if (mask == 0) return;4344DWORD mask_width = (1 << mask);45DWORD mask_mask = (mask_width-1) << 1;46if (mask_width >= max_width) return;47int count = max_width - mask_width;48if (count <= 0) return;49int line_full = real_width;50int line = line_full - count;51if (line < 0) return;52unsigned short * start = (unsigned short *)(tex) + mask_width;5354unsigned short * edi = start;55for(unsigned int ecx = height; ecx; --ecx)56{57for (int edx = 0; edx != count; ++edx)58{59unsigned short * esi = (unsigned short *)(tex);60if ((mask_width + edx) & mask_width)61{62esi += (mask_mask - ((edx >> 1) & mask_mask)) / 2;63}64else65{66esi += ((edx >> 1) & mask_mask) / 2;67}68*edi = *esi;69++edi;70}71edi += line;72tex += line_full * 2;73}74}7576//****************************************************************77// 16-bit Vertical Mirror7879void Mirror16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)80{81if (mask == 0) return;8283DWORD mask_height = (1 << mask);84DWORD mask_mask = mask_height-1;85if (max_height <= mask_height) return;86int line_full = real_width << 1;8788unsigned char * dst = tex + mask_height * line_full;8990for (DWORD y=mask_height; y<max_height; y++)91{92if (y & mask_height)93{94// mirrored95memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);96}97else98{99// not mirrored100memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);101}102103dst += line_full;104}105}106107//****************************************************************108// 16-bit Horizontal Wrap (like mirror)109110void Wrap16bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)111{112if (mask == 0) return;113114DWORD mask_width = (1 << mask);115DWORD mask_mask = (mask_width-1) >> 1;116if (mask_width >= max_width) return;117int count = (max_width - mask_width) >> 1;118if (count <= 0) return;119int line_full = real_width << 1;120int line = line_full - (count << 2);121if (line < 0) return;122unsigned char * start = tex + (mask_width << 1);123#if !defined(__GNUC__) && !defined(NO_ASM)124__asm {125mov edi,dword ptr [start]126127mov ecx,dword ptr [height]128loop_y:129130xor edx,edx131loop_x:132133mov esi,dword ptr [tex]134mov eax,edx135and eax,dword ptr [mask_mask]136shl eax,2137add esi,eax138mov eax,dword ptr [esi]139mov dword ptr [edi],eax140add edi,4141142inc edx143cmp edx,dword ptr [count]144jne loop_x145146add edi,dword ptr [line]147mov eax,dword ptr [tex]148add eax,dword ptr [line_full]149mov dword ptr [tex],eax150151dec ecx152jnz loop_y153}154#elif !defined(NO_ASM)155//printf("wrap16bS\n");156intptr_t fake_esi, fake_eax;157asm volatile (158"0: \n"159160"xor %%edx, %%edx \n"161"1: \n"162163"mov %[tex], %[S] \n"164"mov %%edx, %%eax \n"165"and %[mask_mask], %%eax \n"166"shl $2, %%eax \n"167"add %[a], %[S] \n"168"mov (%[S]), %%eax \n"169"mov %%eax, (%[start]) \n"170"add $4, %[start] \n"171172"inc %%edx \n"173"cmp %[count], %%edx \n"174"jne 1b \n"175176"add %[line], %[start] \n"177"add %[line_full], %[tex] \n"178179"dec %%ecx \n"180"jnz 0b \n"181: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r"(tex)182: [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)183: "memory", "cc", "edx"184);185#endif // _WIN32186}187188//****************************************************************189// 16-bit Vertical Wrap190191void Wrap16bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)192{193if (mask == 0) return;194195DWORD mask_height = (1 << mask);196DWORD mask_mask = mask_height-1;197if (max_height <= mask_height) return;198int line_full = real_width << 1;199200unsigned char * dst = tex + mask_height * line_full;201202for (DWORD y=mask_height; y<max_height; y++)203{204// not mirrored205memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);206207dst += line_full;208}209}210211//****************************************************************212// 16-bit Horizontal Clamp213214void Clamp16bS (unsigned char * tex, DWORD width, DWORD clamp_to, DWORD real_width, DWORD real_height)215{216if (real_width <= width) return;217218unsigned char * dest = tex + (width << 1);219unsigned char * constant = dest-2;220int count = clamp_to - width;221222int line_full = real_width << 1;223int line = width << 1;224225#if !defined(__GNUC__) && !defined(NO_ASM)226__asm {227mov esi,dword ptr [constant]228mov edi,dword ptr [dest]229230mov ecx,real_height231y_loop:232233mov ax,word ptr [esi]234235mov edx,dword ptr [count]236x_loop:237238mov word ptr [edi],ax // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)239add edi,2240241dec edx242jnz x_loop243244add esi,dword ptr [line_full]245add edi,dword ptr [line]246247dec ecx248jnz y_loop249}250#elif !defined(NO_ASM)251//printf("clamp16bS\n");252asm volatile (253//"y_loop10: \n"254"0: \n"255256"mov (%[constant]), %%ax \n"257258"mov %[count], %%edx \n"259//"x_loop10: \n"260"1: \n"261262"mov %%ax, (%[dest]) \n" // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)263"add $2, %[dest] \n"264265"dec %%edx \n"266//"jnz x_loop10 \n"267"jnz 1b \n"268269"add %[line_full], %[constant] \n"270"add %[line], %[dest] \n"271272"dec %%ecx \n"273//"jnz y_loop10 \n"274"jnz 0b \n"275: "+c"(real_height), [constant]"+S"(constant), [dest]"+D"(dest)276: [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)277: "memory", "cc", "eax", "edx"278);279#endif280}281282//****************************************************************283// 16-bit Vertical Clamp284285void Clamp16bT (unsigned char * tex, DWORD height, DWORD real_width, DWORD clamp_to)286{287int line_full = real_width << 1;288unsigned char * dst = tex + height * line_full;289unsigned char * const_line = dst - line_full;290291for (DWORD y=height; y<clamp_to; y++)292{293memcpy ((void*)dst, (void*)const_line, line_full);294dst += line_full;295}296}297298299300