Path: blob/master/libmupen64plus/mupen64plus-video-glide64/src/MiClWr8b.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// 8-bit Horizontal Mirror3940void Mirror8bS (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);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 char * start = tex + (mask_width);53#if !defined(__GNUC__) && !defined(NO_ASM)54__asm {55mov edi,dword ptr [start]5657mov ecx,dword ptr [height]58loop_y:5960xor edx,edx61loop_x:62mov esi,dword ptr [tex]63mov ebx,dword ptr [mask_width]64add ebx,edx65and ebx,dword ptr [mask_width]66jnz is_mirrored6768mov eax,edx69and eax,dword ptr [mask_mask]70add esi,eax71mov al,byte ptr [esi]72mov byte ptr [edi],al73inc edi74jmp end_mirror_check75is_mirrored:76add esi,dword ptr [mask_mask]77mov eax,edx78and eax,dword ptr [mask_mask]79sub esi,eax80mov al,byte ptr [esi]81mov byte ptr [edi],al82inc edi83end_mirror_check:8485inc edx86cmp edx,dword ptr [count]87jne loop_x8889add edi,dword ptr [line]90mov eax,dword ptr [tex]91add eax,dword ptr [line_full]92mov dword ptr [tex],eax9394dec ecx95jnz loop_y96}97#elif !defined(NO_ASM)98//printf("Mirror8bS\n");99intptr_t fake_esi,fake_eax;100asm volatile (101"1: \n" // loop_y3102103"xor %%edx, %%edx \n"104"2: \n" // loop_x3105"mov %[tex], %[S] \n"106"mov %[mask_width], %%eax \n"107"add %%edx, %%eax \n"108"and %[mask_width], %%eax \n"109"jnz 3f \n" // is_mirrored2110111"mov %%edx, %%eax \n"112"and %[mask_mask], %[a] \n"113"add %[a], %[S] \n"114"mov (%[S]), %%al \n"115"mov %%al, (%[start]) \n"116"inc %[start] \n"117"jmp 4f \n" // end_mirror_check2118"3: \n" // is_mirrored2119"add %[mask_mask], %[S] \n"120"mov %%edx, %%eax \n"121"and %[mask_mask], %[a] \n"122"sub %[a], %[S] \n"123"mov (%[S]), %%al \n"124"mov %%al, (%[start]) \n"125"inc %[start] \n"126"4: \n" // end_mirror_check2127128"inc %%edx \n"129"cmp %[count], %%edx \n"130"jne 2b \n" // loop_x3131132"add %[line], %[start] \n"133"add %[line_full], %[tex] \n"134135"dec %%ecx \n"136"jnz 1b \n" // loop_y3137: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), "+c"(height), [tex] "+r" (tex)138: [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)139: "memory", "cc", "edx"140);141#endif // _WIN32142}143144//****************************************************************145// 8-bit Vertical Mirror146147void Mirror8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)148{149if (mask == 0) return;150151DWORD mask_height = (1 << mask);152DWORD mask_mask = mask_height-1;153if (max_height <= mask_height) return;154int line_full = real_width;155156unsigned char * dst = tex + mask_height * line_full;157158for (DWORD y=mask_height; y<max_height; y++)159{160if (y & mask_height)161{162// mirrored163memcpy ((void*)dst, (void*)(tex + (mask_mask - (y & mask_mask)) * line_full), line_full);164}165else166{167// not mirrored168memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);169}170171dst += line_full;172}173}174175//****************************************************************176// 8-bit Horizontal Wrap (like mirror) ** UNTESTED **177178void Wrap8bS (unsigned char * tex, DWORD mask, DWORD max_width, DWORD real_width, DWORD height)179{180if (mask == 0) return;181182DWORD mask_width = (1 << mask);183DWORD mask_mask = (mask_width-1) >> 2;184if (mask_width >= max_width) return;185int count = (max_width - mask_width) >> 2;186if (count <= 0) return;187int line_full = real_width;188int line = line_full - (count << 2);189if (line < 0) return;190unsigned char * start = tex + (mask_width);191#if !defined(__GNUC__) && !defined(NO_ASM)192__asm {193mov edi,dword ptr [start]194195mov ecx,dword ptr [height]196loop_y:197198xor edx,edx199loop_x:200201mov esi,dword ptr [tex]202mov eax,edx203and eax,dword ptr [mask_mask]204shl eax,2205add esi,eax206mov eax,dword ptr [esi]207mov dword ptr [edi],eax208add edi,4209210inc edx211cmp edx,dword ptr [count]212jne loop_x213214add edi,dword ptr [line]215mov eax,dword ptr [tex]216add eax,dword ptr [line_full]217mov dword ptr [tex],eax218219dec ecx220jnz loop_y221}222#elif !defined(NO_ASM)223//printf("wrap8bS\n");224intptr_t fake_esi,fake_eax;225asm volatile (226"1: \n" // loop_y4227228"xor %%edx, %%edx \n"229"2: \n" // loop_x4230231"mov %[tex], %[S] \n"232"mov %%edx, %%eax \n"233"and %[mask_mask], %%eax \n"234"shl $2, %%eax \n"235"add %[a], %[S] \n"236"mov (%[S]), %%eax \n"237"mov %%eax, (%[start]) \n"238"add $4, %[start] \n"239240"inc %%edx \n"241"cmp %[count], %%edx \n"242"jne 2b \n" // loop_x4243244"add %[line], %[start] \n"245"add %[line_full], %[tex] \n"246247"dec %%ecx \n"248"jnz 1b \n" // loop_y4249: [S] "=&S" (fake_esi), [a]"=&a"(fake_eax), [start]"+D"(start), [tex] "+r" (tex), "+c"(height)250: [mask_mask] "g" (mask_mask), [count] "g" (count), [line] "g" ((intptr_t)line), [line_full] "g" ((intptr_t)line_full)251: "memory", "cc", "edx"252);253#endif254}255256//****************************************************************257// 8-bit Vertical Wrap258259void Wrap8bT (unsigned char * tex, DWORD mask, DWORD max_height, DWORD real_width)260{261if (mask == 0) return;262263DWORD mask_height = (1 << mask);264DWORD mask_mask = mask_height-1;265if (max_height <= mask_height) return;266int line_full = real_width;267268unsigned char * dst = tex + mask_height * line_full;269270for (DWORD y=mask_height; y<max_height; y++)271{272// not mirrored273memcpy ((void*)dst, (void*)(tex + (y & mask_mask) * line_full), line_full);274275dst += line_full;276}277}278279//****************************************************************280// 8-bit Horizontal Clamp281282void Clamp8bS (unsigned char * tex, DWORD width, DWORD clamp_to, DWORD real_width, DWORD real_height)283{284if (real_width <= width) return;285286unsigned char * dest = tex + (width);287unsigned char * constant = dest-1;288int count = clamp_to - width;289290int line_full = real_width;291int line = width;292#if !defined(__GNUC__) && !defined(NO_ASM)293__asm {294mov esi,dword ptr [constant]295mov edi,dword ptr [dest]296297mov ecx,real_height298y_loop:299300mov al,byte ptr [esi]301302mov edx,dword ptr [count]303x_loop:304305mov byte ptr [edi],al // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)306inc edi307308dec edx309jnz x_loop310311add esi,dword ptr [line_full]312add edi,dword ptr [line]313314dec ecx315jnz y_loop316}317#elif !defined(NO_ASM)318//printf("clamp8bs\n");319asm volatile (320"0: \n"321322"mov (%[constant]), %%al \n"323324"mov %[count], %%edx \n"325"1: \n"326327"mov %%al, (%[dest]) \n" // don't unroll or make dword, it may go into next line (doesn't have to be multiple of two)328"inc %[dest] \n"329330"dec %%edx \n"331"jnz 1b \n"332333"add %[line_full], %[constant] \n"334"add %[line], %[dest] \n"335336"dec %%ecx \n"337"jnz 0b \n"338: [constant]"+S"(constant), [dest]"+D"(dest), "+c"(real_height)339: [count] "g" (count), [line] "g" ((uintptr_t)line), [line_full] "g" ((intptr_t)line_full)340: "memory", "cc", "eax", "edx"341);342#endif343}344345//****************************************************************346// 8-bit Vertical Clamp347348void Clamp8bT (unsigned char * tex, DWORD height, DWORD real_width, DWORD clamp_to)349{350int line_full = real_width;351unsigned char * dst = tex + height * line_full;352unsigned char * const_line = dst - line_full;353354for (DWORD y=height; y<clamp_to; y++)355{356memcpy ((void*)dst, (void*)const_line, line_full);357dst += line_full;358}359}360361362363