mirror of
https://github.com/melonDS-emu/melonDS.git
synced 2025-07-27 00:00:07 -06:00
add YUV conversion. lay base for cropping support.
This commit is contained in:
@ -31,6 +31,8 @@ Camera* Camera1; // 7A / selfie cam
|
|||||||
u16 ModuleCnt;
|
u16 ModuleCnt;
|
||||||
u16 Cnt;
|
u16 Cnt;
|
||||||
|
|
||||||
|
u32 CropStart, CropEnd;
|
||||||
|
|
||||||
/*u8 FrameBuffer[640*480*4];
|
/*u8 FrameBuffer[640*480*4];
|
||||||
u32 FrameLength;
|
u32 FrameLength;
|
||||||
u32 TransferPos;*/
|
u32 TransferPos;*/
|
||||||
@ -71,6 +73,9 @@ void Reset()
|
|||||||
ModuleCnt = 0; // CHECKME
|
ModuleCnt = 0; // CHECKME
|
||||||
Cnt = 0;
|
Cnt = 0;
|
||||||
|
|
||||||
|
CropStart = 0;
|
||||||
|
CropEnd = 0;
|
||||||
|
|
||||||
/*memset(FrameBuffer, 0, 640*480*4);
|
/*memset(FrameBuffer, 0, 640*480*4);
|
||||||
TransferPos = 0;
|
TransferPos = 0;
|
||||||
FrameLength = 256*192*2;*/ // TODO: make it check frame size, data type, etc
|
FrameLength = 256*192*2;*/ // TODO: make it check frame size, data type, etc
|
||||||
@ -131,12 +136,53 @@ void TransferScanline(u32 line)
|
|||||||
{
|
{
|
||||||
u32* dstbuf = &DataBuffer[BufferWritePos];
|
u32* dstbuf = &DataBuffer[BufferWritePos];
|
||||||
u32 maxlen = 1024 - BufferWritePos;
|
u32 maxlen = 1024 - BufferWritePos;
|
||||||
u32 datalen = CurCamera->TransferScanline(dstbuf, maxlen);
|
|
||||||
|
|
||||||
// TODO HERE:
|
u32 tmpbuf[1024];
|
||||||
// convert to RGB5 if needed
|
u32 datalen = CurCamera->TransferScanline(tmpbuf, 1024);
|
||||||
// crop if needed
|
|
||||||
// etc
|
// TODO: cropping
|
||||||
|
u32 copystart = 0;
|
||||||
|
u32 copylen = datalen;
|
||||||
|
if (copylen > maxlen) copylen = maxlen;
|
||||||
|
|
||||||
|
if (Cnt & (1<<13))
|
||||||
|
{
|
||||||
|
// convert to RGB
|
||||||
|
|
||||||
|
for (u32 i = 0; i < copylen; i++)
|
||||||
|
{
|
||||||
|
u32 val = tmpbuf[copystart + i];
|
||||||
|
|
||||||
|
int y1 = val & 0xFF;
|
||||||
|
int u = (val >> 8) & 0xFF;
|
||||||
|
int y2 = (val >> 16) & 0xFF;
|
||||||
|
int v = (val >> 24) & 0xFF;
|
||||||
|
|
||||||
|
int r1 = y1 + (((v-0x80) * 91881) >> 16);
|
||||||
|
int g1 = y1 - (((v-0x80) * 46793) >> 16) - (((u-0x80) * 22544) >> 16);
|
||||||
|
int b1 = y1 + (((u-0x80) * 116129) >> 16);
|
||||||
|
|
||||||
|
int r2 = y2 + (((v-0x80) * 91881) >> 16);
|
||||||
|
int g2 = y2 - (((v-0x80) * 46793) >> 16) - (((u-0x80) * 22544) >> 16);
|
||||||
|
int b2 = y2 + (((u-0x80) * 116129) >> 16);
|
||||||
|
|
||||||
|
#define CLAMP(v) if (v < 0) v = 0; else if (v > 255) v = 255;
|
||||||
|
CLAMP(r1); CLAMP(g1); CLAMP(b1);
|
||||||
|
CLAMP(r2); CLAMP(g2); CLAMP(b2);
|
||||||
|
#undef CLAMP
|
||||||
|
|
||||||
|
u32 col1 = (r1 >> 3) | ((g1 >> 3) << 5) | ((b1 >> 3) << 10) | 0x8000;
|
||||||
|
u32 col2 = (r2 >> 3) | ((g2 >> 3) << 5) | ((b2 >> 3) << 10) | 0x8000;
|
||||||
|
|
||||||
|
dstbuf[i] = col1 | (col2 << 16);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// return raw data
|
||||||
|
|
||||||
|
memcpy(dstbuf, &tmpbuf[copystart], copylen);
|
||||||
|
}
|
||||||
|
|
||||||
// data overrun
|
// data overrun
|
||||||
if (datalen > maxlen)
|
if (datalen > maxlen)
|
||||||
@ -204,6 +250,9 @@ u32 Read32(u32 addr)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case 0x04004210: return CropStart;
|
||||||
|
case 0x04004214: return CropEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("unknown DSi cam read32 %08X\n", addr);
|
printf("unknown DSi cam read32 %08X\n", addr);
|
||||||
@ -243,6 +292,9 @@ void Write16(u32 addr, u16 val)
|
|||||||
|
|
||||||
case 0x04004202:
|
case 0x04004202:
|
||||||
{
|
{
|
||||||
|
// TODO: during a transfer, clearing bit15 does not reflect immediately
|
||||||
|
// maybe it needs to finish the trasnfer or atleast the current block
|
||||||
|
|
||||||
// checkme
|
// checkme
|
||||||
u16 oldmask;
|
u16 oldmask;
|
||||||
if (Cnt & 0x8000)
|
if (Cnt & 0x8000)
|
||||||
@ -271,6 +323,23 @@ void Write16(u32 addr, u16 val)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
case 0x04004210:
|
||||||
|
if (Cnt & (1<<15)) return;
|
||||||
|
CropStart = (CropStart & 0x01FF0000) | (val & 0x03FE);
|
||||||
|
return;
|
||||||
|
case 0x04004212:
|
||||||
|
if (Cnt & (1<<15)) return;
|
||||||
|
CropStart = (CropStart & 0x03FE) | ((val & 0x01FF) << 16);
|
||||||
|
return;
|
||||||
|
case 0x04004214:
|
||||||
|
if (Cnt & (1<<15)) return;
|
||||||
|
CropEnd = (CropEnd & 0x01FF0000) | (val & 0x03FE);
|
||||||
|
return;
|
||||||
|
case 0x04004216:
|
||||||
|
if (Cnt & (1<<15)) return;
|
||||||
|
CropEnd = (CropEnd & 0x03FE) | ((val & 0x01FF) << 16);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("unknown DSi cam write16 %08X %04X\n", addr, val);
|
printf("unknown DSi cam write16 %08X %04X\n", addr, val);
|
||||||
@ -278,7 +347,17 @@ void Write16(u32 addr, u16 val)
|
|||||||
|
|
||||||
void Write32(u32 addr, u32 val)
|
void Write32(u32 addr, u32 val)
|
||||||
{
|
{
|
||||||
//
|
switch (addr)
|
||||||
|
{
|
||||||
|
case 0x04004210:
|
||||||
|
if (Cnt & (1<<15)) return;
|
||||||
|
CropStart = val & 0x01FF03FE;
|
||||||
|
return;
|
||||||
|
case 0x04004214:
|
||||||
|
if (Cnt & (1<<15)) return;
|
||||||
|
CropEnd = val & 0x01FF03FE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
printf("unknown DSi cam write32 %08X %08X\n", addr, val);
|
printf("unknown DSi cam write32 %08X %08X\n", addr, val);
|
||||||
}
|
}
|
||||||
@ -429,27 +508,35 @@ int Camera::TransferScanline(u32* buffer, int maxlen)
|
|||||||
sx = ((dx*2 + 1) * 640) / FrameWidth;
|
sx = ((dx*2 + 1) * 640) / FrameWidth;
|
||||||
u32 pixel2 = FrameBuffer[sy*640 + sx];
|
u32 pixel2 = FrameBuffer[sy*640 + sx];
|
||||||
|
|
||||||
u32 r1 = (pixel1 >> 16) & 0xFF;
|
int r1 = (pixel1 >> 16) & 0xFF;
|
||||||
u32 g1 = (pixel1 >> 8) & 0xFF;
|
int g1 = (pixel1 >> 8) & 0xFF;
|
||||||
u32 b1 = pixel1 & 0xFF;
|
int b1 = pixel1 & 0xFF;
|
||||||
|
|
||||||
u32 r2 = (pixel1 >> 16) & 0xFF;
|
int r2 = (pixel2 >> 16) & 0xFF;
|
||||||
u32 g2 = (pixel1 >> 8) & 0xFF;
|
int g2 = (pixel2 >> 8) & 0xFF;
|
||||||
u32 b2 = pixel1 & 0xFF;
|
int b2 = pixel2 & 0xFF;
|
||||||
|
|
||||||
u32 y1 = ((r1 * 19595) + (g1 * 38470) + (b1 * 7471)) >> 16;
|
int y1 = ((r1 * 19595) + (g1 * 38470) + (b1 * 7471)) >> 16;
|
||||||
u32 u1 = ((b1 - y1) * 32244) >> 16;
|
int u1 = ((b1 - y1) * 32244) >> 16;
|
||||||
u32 v1 = ((r1 - y1) * 57475) >> 16;
|
int v1 = ((r1 - y1) * 57475) >> 16;
|
||||||
|
|
||||||
u32 y2 = ((r2 * 19595) + (g2 * 38470) + (b2 * 7471)) >> 16;
|
int y2 = ((r2 * 19595) + (g2 * 38470) + (b2 * 7471)) >> 16;
|
||||||
u32 u2 = ((b2 - y2) * 32244) >> 16;
|
int u2 = ((b2 - y2) * 32244) >> 16;
|
||||||
u32 v2 = ((r2 - y2) * 57475) >> 16;
|
int v2 = ((r2 - y2) * 57475) >> 16;
|
||||||
|
|
||||||
|
u1 += 128; v1 += 128;
|
||||||
|
u2 += 128; v2 += 128;
|
||||||
|
|
||||||
|
#define CLAMP(v) if (v < 0) v = 0; else if (v > 255) v = 255;
|
||||||
|
CLAMP(y1); CLAMP(u1); CLAMP(v1);
|
||||||
|
CLAMP(y2); CLAMP(u2); CLAMP(v2);
|
||||||
|
#undef CLAMP
|
||||||
|
|
||||||
// huh
|
// huh
|
||||||
u1 = (u1 + u2) >> 1;
|
u1 = (u1 + u2) >> 1;
|
||||||
v1 = (v1 + v2) >> 1;
|
v1 = (v1 + v2) >> 1;
|
||||||
|
|
||||||
buffer[dx] = y1 | (u1 << 8) | (y2 << 16) | (u1 << 24);
|
buffer[dx] = y1 | (u1 << 8) | (y2 << 16) | (v1 << 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
TransferY++;
|
TransferY++;
|
||||||
|
Reference in New Issue
Block a user