mirror of
https://github.com/dborth/vbagx.git
synced 2024-11-22 18:49:18 +01:00
add USB/SD hot-swap, video changes, remove un-needed VBA file
This commit is contained in:
parent
1d17d3f185
commit
a68f67903d
@ -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;
|
||||
if(mounted)
|
||||
{
|
||||
fatSetDefaultInterface(part);
|
||||
#ifdef HW_RVL
|
||||
if(part == PI_INTERNAL_SD || part == PI_USBSTORAGE)
|
||||
fatEnableReadAhead (part, 6, 64);
|
||||
#endif
|
||||
}
|
||||
return false;
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
@ -375,15 +379,9 @@ void UpdateScaling()
|
||||
square[1] = square[4] = ( yscale + 7);
|
||||
square[7] = square[10] = (-yscale - 7);
|
||||
|
||||
GX_InvVtxCache (); // update vertex cache
|
||||
|
||||
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
|
||||
draw_init ();
|
||||
|
||||
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
|
||||
}
|
||||
|
@ -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 <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#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++;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user