diff --git a/source/ngc/fileop.cpp b/source/ngc/fileop.cpp index 6e86d9e..418edcd 100644 --- a/source/ngc/fileop.cpp +++ b/source/ngc/fileop.cpp @@ -28,75 +28,84 @@ FILE * fatfile; /**************************************************************************** - * fat_is_mounted - * to check whether FAT media are detected. + * MountFAT + * Attempts to mount the FAT device specified + * Sets libfat to use the device by default + * Enables read-ahead cache for SD/USB ***************************************************************************/ +bool MountFAT(PARTITION_INTERFACE part) +{ + bool mounted = fatMountNormalInterface(part, 8); -bool FatIsMounted(PARTITION_INTERFACE partition) { - char prefix[] = "fatX:/"; - prefix[3] = partition + '0'; - DIR_ITER *dir = diropen(prefix); - if (dir) { - dirclose(dir); - return true; - } - return false; + if(mounted) + { + fatSetDefaultInterface(part); + #ifdef HW_RVL + if(part == PI_INTERNAL_SD || part == PI_USBSTORAGE) + fatEnableReadAhead (part, 6, 64); + #endif + } + return mounted; } /**************************************************************************** - * changeFATInterface - * Checks if the device (method) specified is available, and - * sets libfat to use the device + * UnmountFAT + * Unmounts the FAT device specified + ***************************************************************************/ +void UnmountFAT(PARTITION_INTERFACE part) +{ + if(!fatUnmount(part)) + fatUnsafeUnmount(part); +} + +/**************************************************************************** + * UnmountAllFAT + * Unmounts all FAT devices + ***************************************************************************/ +void UnmountAllFAT() +{ +#ifdef HW_RVL + UnmountFAT(PI_INTERNAL_SD); + UnmountFAT(PI_USBSTORAGE); +#endif + UnmountFAT(PI_SDGECKO_A); + UnmountFAT(PI_SDGECKO_B); +} + +/**************************************************************************** + * ChangeFATInterface + * Unmounts all devices and attempts to mount/configure the device specified ***************************************************************************/ bool ChangeFATInterface(int method, bool silent) { - bool devFound = false; + bool mounted = false; + + // unmount all FAT devices + UnmountAllFAT(); if(method == METHOD_SD) { - // check which SD device is loaded - #ifdef HW_RVL - if (FatIsMounted(PI_INTERNAL_SD)) - { - devFound = true; - fatSetDefaultInterface(PI_INTERNAL_SD); - fatEnableReadAhead (PI_INTERNAL_SD, 6, 64); - } + mounted = MountFAT(PI_INTERNAL_SD); // try Wii internal SD #endif - if (!devFound && FatIsMounted(PI_SDGECKO_A)) - { - devFound = true; - } - if(!devFound && FatIsMounted(PI_SDGECKO_B)) - { - devFound = true; - } - if(!devFound) - { - if(!silent) - WaitPrompt ((char *)"SD card not found!"); - } + if(!mounted) // internal SD not found + mounted = MountFAT(PI_SDGECKO_A); // try SD Gecko on slot A + if(!mounted) // internal SD and SD Gecko (on slot A) not found + mounted = MountFAT(PI_SDGECKO_B); // try SD Gecko on slot B + if(!mounted && !silent) // no SD device found + WaitPrompt ((char *)"SD card not found!"); } else if(method == METHOD_USB) { #ifdef HW_RVL - if(FatIsMounted(PI_USBSTORAGE)) - { - devFound = true; - fatSetDefaultInterface(PI_USBSTORAGE); - fatEnableReadAhead (PI_USBSTORAGE, 6, 64); - } - else - { - if(!silent) - WaitPrompt ((char *)"USB flash drive not found!"); - } + mounted = MountFAT(PI_USBSTORAGE); + if(!mounted && !silent) + WaitPrompt ((char *)"USB drive not found!"); #endif } - return devFound; + return mounted; } /*************************************************************************** diff --git a/source/ngc/filesel.cpp b/source/ngc/filesel.cpp index 0313204..9f1a6f3 100644 --- a/source/ngc/filesel.cpp +++ b/source/ngc/filesel.cpp @@ -373,7 +373,7 @@ int FileSelector (int method) if (!maxfiles) { - WaitPrompt ((char*) "Error reading directory !"); + WaitPrompt ((char*) "Error reading directory!"); haverom = 1; // quit menu } } @@ -384,6 +384,11 @@ int FileSelector (int method) } else // this is a file { + // better do another unmount/remount, just in case + if(method == METHOD_SD || method == METHOD_USB) + if(!ChangeFATInterface(method, NOTSILENT)) + return 0; + // 7z file - let's open it up to select a file inside if(IsSz()) { @@ -391,7 +396,7 @@ int FileSelector (int method) if(!MakeROMPath(szpath, method)) { WaitPrompt((char*) "Maximum filepath length reached!"); - return -1; + return 0; } int szfiles = SzParse(szpath, method); if(szfiles) diff --git a/source/ngc/video.cpp b/source/ngc/video.cpp index b907044..a9a240d 100644 --- a/source/ngc/video.cpp +++ b/source/ngc/video.cpp @@ -184,10 +184,14 @@ static void draw_init(void) GX_SetTexCoordGen (GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); - GX_InvalidateTexAll(); + GX_SetTevOp (GX_TEVSTAGE0, GX_REPLACE); + GX_SetTevOrder (GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLORNULL); + memset (&view, 0, sizeof (Mtx)); guLookAt(view, &cam.pos, &cam.up, &cam.view); GX_LoadPosMtxImm (view, GX_PNMTX0); + + GX_InvVtxCache (); // update vertex cache } static void draw_vert(u8 pos, u8 c, f32 s, f32 t) @@ -251,9 +255,6 @@ void GX_Start() guPerspective(p, 60, 1.33F, 10.0F, 1000.0F); GX_LoadProjectionMtx(p, GX_PERSPECTIVE); - GX_SetTevOp(GX_TEVSTAGE0, GX_DECAL); - GX_SetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0); - GX_CopyDisp (xfb[whichfb], GX_TRUE); // reset xfb } @@ -327,6 +328,9 @@ void InitialiseVideo () xfb[0] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode)); xfb[1] = (u32 *) MEM_K0_TO_K1 (SYS_AllocateFramebuffer (vmode)); + // A console is always useful while debugging + console_init (xfb[0], 20, 64, vmode->fbWidth, vmode->xfbHeight, vmode->fbWidth * 2); + // Clear framebuffers etc. VIDEO_ClearFrameBuffer (vmode, xfb[0], COLOR_BLACK); VIDEO_ClearFrameBuffer (vmode, xfb[1], COLOR_BLACK); @@ -370,21 +374,15 @@ void UpdateScaling() yscale *= GCSettings.ZoomLevel; // Set new aspect (now with crap AR hack!) - square[0] = square[9] = (-xscale - 7); - square[3] = square[6] = (xscale + 7); - square[1] = square[4] = (yscale + 7); + square[0] = square[9] = (-xscale - 7); + square[3] = square[6] = ( xscale + 7); + square[1] = square[4] = ( yscale + 7); square[7] = square[10] = (-yscale - 7); - GX_InvVtxCache (); // update vertex cache + draw_init (); - GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); // initialize the texture obj we are going to use - - if (GCSettings.render == 1) - GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF - - GX_LoadTexObj (&texobj, GX_TEXMAP0); // load texture object so its ready to use - - updateScaling--; + if(updateScaling) + updateScaling--; } /**************************************************************************** @@ -400,6 +398,7 @@ ResetVideo_Emu () rmode = vmode; // same mode as menu + // reconfigure VI VIDEO_Configure (rmode); VIDEO_ClearFrameBuffer (vmode, xfb[whichfb], COLOR_BLACK); VIDEO_Flush(); @@ -410,21 +409,27 @@ ResetVideo_Emu () while (VIDEO_GetNextField()) VIDEO_WaitVSync(); + // reconfigure GX GX_SetViewport (0, 0, rmode->fbWidth, rmode->efbHeight, 0, 1); GX_SetDispCopyYScale ((f32) rmode->xfbHeight / (f32) rmode->efbHeight); GX_SetScissor (0, 0, rmode->fbWidth, rmode->efbHeight); - GX_SetDispCopySrc (0, 0, rmode->fbWidth, rmode->efbHeight); GX_SetDispCopyDst (rmode->fbWidth, rmode->xfbHeight); - GX_SetCopyFilter (rmode->aa, rmode->sample_pattern, (GCSettings.render == 0) ? GX_TRUE : GX_FALSE, rmode->vfilter); // AA on only for filtered mode - + GX_SetCopyFilter (rmode->aa, rmode->sample_pattern, (GCSettings.render == 1) ? GX_TRUE : GX_FALSE, rmode->vfilter); // deflickering filter only for filtered mode GX_SetFieldMode (rmode->field_rendering, ((rmode->viHeight == 2 * rmode->xfbHeight) ? GX_ENABLE : GX_DISABLE)); GX_SetPixelFmt (GX_PF_RGB8_Z24, GX_ZC_LINEAR); guPerspective(p, 60, 1.33F, 10.0F, 1000.0F); GX_LoadProjectionMtx(p, GX_PERSPECTIVE); - updateScaling = 20; + // reinitialize texture + GX_InvalidateTexAll (); + GX_InitTexObj (&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, GX_CLAMP, GX_CLAMP, GX_FALSE); // initialize the texture obj we are going to use + if (!(GCSettings.render&1)) + GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF + + // set aspect ratio + updateScaling = 5; } /**************************************************************************** @@ -511,6 +516,9 @@ void GX_Render(int width, int height, u8 * buffer, int pitch) if(updateScaling) UpdateScaling(); + // clear texture objects + GX_InvalidateTexAll(); + for (h = 0; h < vheight; h += 4) { for (w = 0; w < (vwidth >> 2); w++) @@ -539,13 +547,15 @@ void GX_Render(int width, int height, u8 * buffer, int pitch) } } + // load texture into GX DCFlushRange(texturemem, texturesize); - GX_InvalidateTexAll (); + GX_LoadTexObj (&texobj, GX_TEXMAP0); + // render textured quad draw_square(view); - GX_DrawDone(); + // EFB is ready to be copied into XFB VIDEO_SetNextFramebuffer(xfb[whichfb]); VIDEO_Flush(); copynow = GX_TRUE; @@ -570,12 +580,12 @@ zoom (float speed) else if (GCSettings.ZoomLevel > 2.0) GCSettings.ZoomLevel = 2.0; - updateScaling = 60; // update video + updateScaling = 5; // update video } void zoom_reset () { GCSettings.ZoomLevel = 1.0; - updateScaling = 60; // update video + updateScaling = 5; // update video } diff --git a/source/vba/interframe.cpp b/source/vba/interframe.cpp deleted file mode 100644 index 67de876..0000000 --- a/source/vba/interframe.cpp +++ /dev/null @@ -1,581 +0,0 @@ -// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator. -// Copyright (C) 1999-2003 Forgotten -// Copyright (C) 2004 Forgotten and the VBA development team - -// 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, or(at your option) -// 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 License -// along with this program; if not, write to the Free Software Foundation, -// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - -#include "System.h" -#include -#include - -#ifdef MMX -extern "C" bool cpu_mmx; -#endif - -/* - * Thanks to Kawaks' Mr. K for the code - - Incorporated into vba by Anthony Di Franco -*/ - -static u8 *frm1 = NULL; -static u8 *frm2 = NULL; -static u8 *frm3 = NULL; - -extern int RGB_LOW_BITS_MASK; -extern u32 qRGB_COLOR_MASK[2]; - -static void Init() -{ - frm1 = (u8 *)calloc(322*242,4); - // 1 frame ago - frm2 = (u8 *)calloc(322*242,4); - // 2 frames ago - frm3 = (u8 *)calloc(322*242,4); - // 3 frames ago -} - -void InterframeCleanup() -{ - if(frm1) - free(frm1); - if(frm2) - free(frm2); - if(frm3) - free(frm3); - frm1 = frm2 = frm3 = NULL; -} - -#ifdef MMX -static void SmartIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - u16 *src0 = (u16 *)srcPtr; - u16 *src1 = (u16 *)frm1; - u16 *src2 = (u16 *)frm2; - u16 *src3 = (u16 *)frm3; - - int count = width >> 2; - - for(int i = 0; i < height; i++) { -#ifdef __GNUC__ - asm volatile ( - "push %4\n" - "movq 0(%5), %%mm7\n" // colorMask - "0:\n" - "movq 0(%0), %%mm0\n" // src0 - "movq 0(%1), %%mm1\n" // src1 - "movq 0(%2), %%mm2\n" // src2 - "movq 0(%3), %%mm3\n" // src3 - "movq %%mm0, 0(%3)\n" // src3 = src0 - "movq %%mm0, %%mm4\n" - "movq %%mm1, %%mm5\n" - "pcmpeqw %%mm2, %%mm5\n" // src1 == src2 (A) - "pcmpeqw %%mm3, %%mm4\n" // src3 == src0 (B) - "por %%mm5, %%mm4\n" // A | B - "movq %%mm2, %%mm5\n" - "pcmpeqw %%mm0, %%mm5\n" // src0 == src2 (C) - "pcmpeqw %%mm1, %%mm3\n" // src1 == src3 (D) - "por %%mm3, %%mm5\n" // C|D - "pandn %%mm5, %%mm4\n" // (!(A|B))&(C|D) - "movq %%mm0, %%mm2\n" - "pand %%mm7, %%mm2\n" // color & colorMask - "pand %%mm7, %%mm1\n" // src1 & colorMask - "psrlw $1, %%mm2\n" // (color & colorMask) >> 1 (E) - "psrlw $1, %%mm1\n" // (src & colorMask) >> 1 (F) - "paddw %%mm2, %%mm1\n" // E+F - "pand %%mm4, %%mm1\n" // (E+F) & res - "pandn %%mm0, %%mm4\n" // color& !res - - "por %%mm1, %%mm4\n" - "movq %%mm4, 0(%0)\n" // src0 = res - - "addl $8, %0\n" - "addl $8, %1\n" - "addl $8, %2\n" - "addl $8, %3\n" - - "decl %4\n" - "jnz 0b\n" - "pop %4\n" - "emms\n" - : "+r" (src0), "+r" (src1), "+r" (src2), "+r" (src3) - : "r" (count), "r" (qRGB_COLOR_MASK) - ); -#else - __asm { - movq mm7, qword ptr [qRGB_COLOR_MASK]; - mov eax, src0; - mov ebx, src1; - mov ecx, src2; - mov edx, src3; - mov edi, count; - label0: - movq mm0, qword ptr [eax]; // src0 - movq mm1, qword ptr [ebx]; // src1 - movq mm2, qword ptr [ecx]; // src2 - movq mm3, qword ptr [edx]; // src3 - movq qword ptr [edx], mm0; // src3 = src0 - movq mm4, mm0; - movq mm5, mm1; - pcmpeqw mm5, mm2; // src1 == src2 (A) - pcmpeqw mm4, mm3; // src3 == src0 (B) - por mm4, mm5; // A | B - movq mm5, mm2; - pcmpeqw mm5, mm0; // src0 == src2 (C) - pcmpeqw mm3, mm1; // src1 == src3 (D) - por mm5, mm3; // C|D - pandn mm4, mm5; // (!(A|B))&(C|D) - movq mm2, mm0; - pand mm2, mm7; // color & colorMask - pand mm1, mm7; // src1 & colorMask - psrlw mm2, 1; // (color & colorMask) >> 1 (E) - psrlw mm1, 1; // (src & colorMask) >> 1 (F) - paddw mm1, mm2; // E+F - pand mm1, mm4; // (E+F) & res - pandn mm4, mm0; // color & !res - - por mm4, mm1; - movq qword ptr [eax], mm4; // src0 = res - - add eax, 8; - add ebx, 8; - add ecx, 8; - add edx, 8; - - dec edi; - jnz label0; - mov src0, eax; - mov src1, ebx; - mov src2, ecx; - mov src3, edx; - emms; - } -#endif - src0+=2; - src1+=2; - src2+=2; - src3+=2; - } - - /* Swap buffers around */ - u8 *temp = frm1; - frm1 = frm3; - frm3 = frm2; - frm2 = temp; -} -#endif - -void SmartIB(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - if(frm1 == NULL) { - Init(); - } -#ifdef MMX - if(cpu_mmx) { - SmartIB_MMX(srcPtr, srcPitch, width, height); - return; - } -#endif - - u16 colorMask = ~RGB_LOW_BITS_MASK; - - u16 *src0 = (u16 *)srcPtr; - u16 *src1 = (u16 *)frm1; - u16 *src2 = (u16 *)frm2; - u16 *src3 = (u16 *)frm3; - - int sPitch = srcPitch >> 1; - - int pos = 0; - for (int j = 0; j < height; j++) - for (int i = 0; i < sPitch; i++) { - u16 color = src0[pos]; - src0[pos] = - (src1[pos] != src2[pos]) && - (src3[pos] != color) && - ((color == src2[pos]) || (src1[pos] == src3[pos])) - ? (((color & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1)) : - color; - src3[pos] = color; /* oldest buffer now holds newest frame */ - pos++; - } - - /* Swap buffers around */ - u8 *temp = frm1; - frm1 = frm3; - frm3 = frm2; - frm2 = temp; -} - -#ifdef MMX -static void SmartIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - u32 *src0 = (u32 *)srcPtr; - u32 *src1 = (u32 *)frm1; - u32 *src2 = (u32 *)frm2; - u32 *src3 = (u32 *)frm3; - - int count = width >> 1; - - for(int i = 0; i < height; i++) { -#ifdef __GNUC__ - asm volatile ( - "push %4\n" - "movq 0(%5), %%mm7\n" // colorMask - "0:\n" - "movq 0(%0), %%mm0\n" // src0 - "movq 0(%1), %%mm1\n" // src1 - "movq 0(%2), %%mm2\n" // src2 - "movq 0(%3), %%mm3\n" // src3 - "movq %%mm0, 0(%3)\n" // src3 = src0 - "movq %%mm0, %%mm4\n" - "movq %%mm1, %%mm5\n" - "pcmpeqd %%mm2, %%mm5\n" // src1 == src2 (A) - "pcmpeqd %%mm3, %%mm4\n" // src3 == src0 (B) - "por %%mm5, %%mm4\n" // A | B - "movq %%mm2, %%mm5\n" - "pcmpeqd %%mm0, %%mm5\n" // src0 == src2 (C) - "pcmpeqd %%mm1, %%mm3\n" // src1 == src3 (D) - "por %%mm3, %%mm5\n" // C|D - "pandn %%mm5, %%mm4\n" // (!(A|B))&(C|D) - "movq %%mm0, %%mm2\n" - "pand %%mm7, %%mm2\n" // color & colorMask - "pand %%mm7, %%mm1\n" // src1 & colorMask - "psrld $1, %%mm2\n" // (color & colorMask) >> 1 (E) - "psrld $1, %%mm1\n" // (src & colorMask) >> 1 (F) - "paddd %%mm2, %%mm1\n" // E+F - "pand %%mm4, %%mm1\n" // (E+F) & res - "pandn %%mm0, %%mm4\n" // color& !res - - "por %%mm1, %%mm4\n" - "movq %%mm4, 0(%0)\n" // src0 = res - - "addl $8, %0\n" - "addl $8, %1\n" - "addl $8, %2\n" - "addl $8, %3\n" - - "decl %4\n" - "jnz 0b\n" - "pop %4\n" - "emms\n" - : "+r" (src0), "+r" (src1), "+r" (src2), "+r" (src3) - : "r" (count), "r" (qRGB_COLOR_MASK) - ); -#else - __asm { - movq mm7, qword ptr [qRGB_COLOR_MASK]; - mov eax, src0; - mov ebx, src1; - mov ecx, src2; - mov edx, src3; - mov edi, count; - label0: - movq mm0, qword ptr [eax]; // src0 - movq mm1, qword ptr [ebx]; // src1 - movq mm2, qword ptr [ecx]; // src2 - movq mm3, qword ptr [edx]; // src3 - movq qword ptr [edx], mm0; // src3 = src0 - movq mm4, mm0; - movq mm5, mm1; - pcmpeqd mm5, mm2; // src1 == src2 (A) - pcmpeqd mm4, mm3; // src3 == src0 (B) - por mm4, mm5; // A | B - movq mm5, mm2; - pcmpeqd mm5, mm0; // src0 == src2 (C) - pcmpeqd mm3, mm1; // src1 == src3 (D) - por mm5, mm3; // C|D - pandn mm4, mm5; // (!(A|B))&(C|D) - movq mm2, mm0; - pand mm2, mm7; // color & colorMask - pand mm1, mm7; // src1 & colorMask - psrld mm2, 1; // (color & colorMask) >> 1 (E) - psrld mm1, 1; // (src & colorMask) >> 1 (F) - paddd mm1, mm2; // E+F - pand mm1, mm4; // (E+F) & res - pandn mm4, mm0; // color & !res - - por mm4, mm1; - movq qword ptr [eax], mm4; // src0 = res - - add eax, 8; - add ebx, 8; - add ecx, 8; - add edx, 8; - - dec edi; - jnz label0; - mov src0, eax; - mov src1, ebx; - mov src2, ecx; - mov src3, edx; - emms; - } -#endif - - src0++; - src1++; - src2++; - src3++; - } - /* Swap buffers around */ - u8 *temp = frm1; - frm1 = frm3; - frm3 = frm2; - frm2 = temp; -} -#endif - -void SmartIB32(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - if(frm1 == NULL) { - Init(); - } -#ifdef MMX - if(cpu_mmx) { - SmartIB32_MMX(srcPtr, srcPitch, width, height); - return; - } -#endif - - u32 *src0 = (u32 *)srcPtr; - u32 *src1 = (u32 *)frm1; - u32 *src2 = (u32 *)frm2; - u32 *src3 = (u32 *)frm3; - - u32 colorMask = 0xfefefe; - - int sPitch = srcPitch >> 2; - int pos = 0; - - for (int j = 0; j < height; j++) - for (int i = 0; i < sPitch; i++) { - u32 color = src0[pos]; - src0[pos] = - (src1[pos] != src2[pos]) && - (src3[pos] != color) && - ((color == src2[pos]) || (src1[pos] == src3[pos])) - ? (((color & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1)) : - color; - src3[pos] = color; /* oldest buffer now holds newest frame */ - pos++; - } - - /* Swap buffers around */ - u8 *temp = frm1; - frm1 = frm3; - frm3 = frm2; - frm2 = temp; -} - -#ifdef MMX -static void MotionBlurIB_MMX(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - u16 *src0 = (u16 *)srcPtr; - u16 *src1 = (u16 *)frm1; - - int count = width >> 2; - - for(int i = 0; i < height; i++) { -#ifdef __GNUC__ - asm volatile ( - "push %2\n" - "movq 0(%3), %%mm7\n" // colorMask - "0:\n" - "movq 0(%0), %%mm0\n" // src0 - "movq 0(%1), %%mm1\n" // src1 - "movq %%mm0, 0(%1)\n" // src1 = src0 - "pand %%mm7, %%mm0\n" // color & colorMask - "pand %%mm7, %%mm1\n" // src1 & colorMask - "psrlw $1, %%mm0\n" // (color & colorMask) >> 1 (E) - "psrlw $1, %%mm1\n" // (src & colorMask) >> 1 (F) - "paddw %%mm1, %%mm0\n" // E+F - - "movq %%mm0, 0(%0)\n" // src0 = res - - "addl $8, %0\n" - "addl $8, %1\n" - - "decl %2\n" - "jnz 0b\n" - "pop %2\n" - "emms\n" - : "+r" (src0), "+r" (src1) - : "r" (count), "r" (qRGB_COLOR_MASK) - ); -#else - __asm { - movq mm7, qword ptr [qRGB_COLOR_MASK]; - mov eax, src0; - mov ebx, src1; - mov edi, count; - label0: - movq mm0, qword ptr [eax]; // src0 - movq mm1, qword ptr [ebx]; // src1 - movq qword ptr [ebx], mm0; // src1 = src0 - pand mm0, mm7; // color & colorMask - pand mm1, mm7; // src1 & colorMask - psrlw mm0, 1; // (color & colorMask) >> 1 (E) - psrlw mm1, 1; // (src & colorMask) >> 1 (F) - paddw mm0, mm1; // E+F - - movq qword ptr [eax], mm0; // src0 = res - - add eax, 8; - add ebx, 8; - - dec edi; - jnz label0; - mov src0, eax; - mov src1, ebx; - emms; - } -#endif - src0+=2; - src1+=2; - } -} -#endif - -void MotionBlurIB(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - if(frm1 == NULL) { - Init(); - } - -#ifdef MMX - if(cpu_mmx) { - MotionBlurIB_MMX(srcPtr, srcPitch, width, height); - return; - } -#endif - - u16 colorMask = ~RGB_LOW_BITS_MASK; - - u16 *src0 = (u16 *)srcPtr; - u16 *src1 = (u16 *)frm1; - - int sPitch = srcPitch >> 1; - - int pos = 0; - for (int j = 0; j < height; j++) - for (int i = 0; i < sPitch; i++) { - u16 color = src0[pos]; - src0[pos] = - (((color & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1)); - src1[pos] = color; - pos++; - } -} - -#ifdef MMX -static void MotionBlurIB32_MMX(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - u32 *src0 = (u32 *)srcPtr; - u32 *src1 = (u32 *)frm1; - - int count = width >> 1; - - for(int i = 0; i < height; i++) { -#ifdef __GNUC__ - asm volatile ( - "push %2\n" - "movq 0(%3), %%mm7\n" // colorMask - "0:\n" - "movq 0(%0), %%mm0\n" // src0 - "movq 0(%1), %%mm1\n" // src1 - "movq %%mm0, 0(%1)\n" // src1 = src0 - "pand %%mm7, %%mm0\n" // color & colorMask - "pand %%mm7, %%mm1\n" // src1 & colorMask - "psrld $1, %%mm0\n" // (color & colorMask) >> 1 (E) - "psrld $1, %%mm1\n" // (src & colorMask) >> 1 (F) - "paddd %%mm1, %%mm0\n" // E+F - - "movq %%mm0, 0(%0)\n" // src0 = res - - "addl $8, %0\n" - "addl $8, %1\n" - - "decl %2\n" - "jnz 0b\n" - "pop %2\n" - "emms\n" - : "+r" (src0), "+r" (src1) - : "r" (count), "r" (qRGB_COLOR_MASK) - ); -#else - __asm { - movq mm7, qword ptr [qRGB_COLOR_MASK]; - mov eax, src0; - mov ebx, src1; - mov edi, count; - label0: - movq mm0, qword ptr [eax]; // src0 - movq mm1, qword ptr [ebx]; // src1 - movq qword ptr [ebx], mm0; // src1 = src0 - pand mm0, mm7; // color & colorMask - pand mm1, mm7; // src1 & colorMask - psrld mm0, 1; // (color & colorMask) >> 1 (E) - psrld mm1, 1; // (src & colorMask) >> 1 (F) - paddd mm0, mm1; // E+F - - movq qword ptr [eax], mm0; // src0 = res - - add eax, 8; - add ebx, 8; - - dec edi; - jnz label0; - mov src0, eax; - mov src1, ebx; - emms; - } -#endif - src0++; - src1++; - } -} -#endif - -void MotionBlurIB32(u8 *srcPtr, u32 srcPitch, int width, int height) -{ - if(frm1 == NULL) { - Init(); - } - -#ifdef MMX - if(cpu_mmx) { - MotionBlurIB32_MMX(srcPtr, srcPitch, width, height); - return; - } -#endif - - u32 *src0 = (u32 *)srcPtr; - u32 *src1 = (u32 *)frm1; - - u32 colorMask = 0xfefefe; - - int sPitch = srcPitch >> 2; - int pos = 0; - - for (int j = 0; j < height; j++) - for (int i = 0; i < sPitch; i++) { - u32 color = src0[pos]; - src0[pos] = (((color & colorMask) >> 1) + - ((src1[pos] & colorMask) >> 1)); - src1[pos] = color; - pos++; - } -}