optimizations from dancinninjac

This commit is contained in:
dborth 2009-12-14 07:13:07 +00:00
parent 0f6d0f7b1b
commit 951b0bcb60
12 changed files with 830 additions and 563 deletions

View File

@ -284,9 +284,7 @@ Unzip the archive. You will find the following folders inside:
apps Contains Homebrew Channel ready files apps Contains Homebrew Channel ready files
(see Homebrew Channel instructions below) (see Homebrew Channel instructions below)
gamecube Contains GameCube DOL file (not required for Wii)
vbagx Contains the directory structure required for storing vbagx Contains the directory structure required for storing
roms and saves. By default, roms are loaded from roms and saves. By default, roms are loaded from
"vbagx/roms/" and saves / preferences are stored in "vbagx/roms/" and saves / preferences are stored in
@ -906,7 +904,7 @@ right analog stick = fast forward
-=[ Credits ]=- -=[ Credits ]=-
Coding & menu design Tantric Coding & menu design Tantric
Additional coding Carl Kenner Additional coding Carl Kenner, dancinninjac
Menu artwork the3seashells Menu artwork the3seashells
Menu sound Peter de Man Menu sound Peter de Man

View File

@ -54,9 +54,9 @@ uint32_t* Metaphrasis::convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWi
uint32_t *src = (uint32_t *)rgbaBuffer; uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI4; uint8_t *dst = (uint8_t *)dataBufferI4;
for(uint16_t y = 0; y < bufferHeight; y += 8) { for(uint32_t y = 0; y < bufferHeight; y += 8) {
for(uint16_t x = 0; x < bufferWidth; x += 8) { for(uint32_t x = 0; x < bufferWidth; x += 8) {
for(uint16_t rows = 0; rows < 8; rows++) { for(uint32_t rows = 0; rows < 8; rows++) {
*dst++ = (src[((y + rows) * bufferWidth) + (x + 0)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 1)] & 0xf0) >> 4); *dst++ = (src[((y + rows) * bufferWidth) + (x + 0)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 1)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 2)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 3)] & 0xf0) >> 4); *dst++ = (src[((y + rows) * bufferWidth) + (x + 2)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 3)] & 0xf0) >> 4);
*dst++ = (src[((y + rows) * bufferWidth) + (x + 4)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) >> 4); *dst++ = (src[((y + rows) * bufferWidth) + (x + 4)] & 0xf0) | ((src[((y + rows) * bufferWidth) + (x + 5)] & 0xf0) >> 4);
@ -88,17 +88,19 @@ uint32_t* Metaphrasis::convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWi
uint32_t *src = (uint32_t *)rgbaBuffer; uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferI8; uint8_t *dst = (uint8_t *)dataBufferI8;
for(uint16_t y = 0; y < bufferHeight; y += 4) { for(uint32_t rows = 0; rows < 4; rows++) {
for(uint16_t x = 0; x < bufferWidth; x += 8) { for(uint32_t y = 0; y < bufferHeight; y += 4) {
for(uint16_t rows = 0; rows < 4; rows++) { uint32_t bufWid = ((y + rows) * bufferWidth);
*dst++ = src[((y + rows) * bufferWidth) + (x + 0)] & 0xff; for(uint32_t x = 0; x < bufferWidth; x += 8) {
*dst++ = src[((y + rows) * bufferWidth) + (x + 1)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 2)] & 0xff; *dst++ = src[bufWid + (x + 0)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 3)] & 0xff; *dst++ = src[bufWid + (x + 1)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 4)] & 0xff; *dst++ = src[bufWid + (x + 2)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 5)] & 0xff; *dst++ = src[bufWid + (x + 3)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 6)] & 0xff; *dst++ = src[bufWid + (x + 4)] & 0xff;
*dst++ = src[((y + rows) * bufferWidth) + (x + 7)] & 0xff; *dst++ = src[bufWid + (x + 5)] & 0xff;
*dst++ = src[bufWid + (x + 6)] & 0xff;
*dst++ = src[bufWid + (x + 7)] & 0xff;
} }
} }
} }
@ -117,11 +119,8 @@ uint32_t* Metaphrasis::convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWi
*/ */
uint8_t Metaphrasis::convertRGBAToIA4(uint32_t rgba) { uint8_t Metaphrasis::convertRGBAToIA4(uint32_t rgba) {
uint8_t i, a; uint8_t i = (rgba >> 8) & 0xf0;
uint8_t a = (rgba ) & 0xff;
i = (rgba >> 8) & 0xf0;
a = (rgba ) & 0xff;
return i | (a >> 4); return i | (a >> 4);
} }
@ -144,9 +143,9 @@ uint32_t* Metaphrasis::convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferW
uint32_t *src = (uint32_t *)rgbaBuffer; uint32_t *src = (uint32_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferIA4; uint8_t *dst = (uint8_t *)dataBufferIA4;
for(uint16_t y = 0; y < bufferHeight; y += 4) { for(uint32_t y = 0; y < bufferHeight; y += 4) {
for(uint16_t x = 0; x < bufferWidth; x += 8) { for(uint32_t x = 0; x < bufferWidth; x += 8) {
for(uint16_t rows = 0; rows < 4; rows++) { for(uint32_t rows = 0; rows < 4; rows++) {
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 0)]); *dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 1)]); *dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 2)]); *dst++ = Metaphrasis::convertRGBAToIA4(src[((y + rows) * bufferWidth) + (x + 2)]);
@ -173,12 +172,7 @@ uint32_t* Metaphrasis::convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferW
*/ */
uint16_t Metaphrasis::convertRGBAToIA8(uint32_t rgba) { uint16_t Metaphrasis::convertRGBAToIA8(uint32_t rgba) {
uint8_t i, a; return (((rgba >> 8) & 0xff) << 8) | ((rgba ) & 0xff);
i = (rgba >> 8) & 0xff;
a = (rgba ) & 0xff;
return (i << 8) | a;
} }
/** /**
@ -200,13 +194,15 @@ uint32_t* Metaphrasis::convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferW
uint32_t *src = (uint32_t *)rgbaBuffer; uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferIA8; uint16_t *dst = (uint16_t *)dataBufferIA8;
for(uint16_t y = 0; y < bufferHeight; y += 4) { for(uint32_t rows = 0; rows < 4; ++rows) {
for(uint16_t x = 0; x < bufferWidth; x += 4) { for(uint32_t y = 0; y < bufferHeight; y += 4) {
for(uint16_t rows = 0; rows < 4; rows++) { uint32_t bufWid = ((y + rows) * bufferWidth);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 0)]); for(uint32_t x = 0; x < bufferWidth; x += 4) {
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 2)]); *dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 3)]); *dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 3)]);
} }
} }
} }
@ -234,19 +230,31 @@ uint32_t* Metaphrasis::convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t buffe
uint8_t *src = (uint8_t *)rgbaBuffer; uint8_t *src = (uint8_t *)rgbaBuffer;
uint8_t *dst = (uint8_t *)dataBufferRGBA8; uint8_t *dst = (uint8_t *)dataBufferRGBA8;
for(uint16_t block = 0; block < bufferHeight; block += 4) { for(uint32_t block = 0; block < bufferHeight; block += 4) {
for(uint16_t i = 0; i < bufferWidth; i += 4) { for(uint32_t i = 0; i < bufferWidth; i += 4) {
for (uint16_t c = 0; c < 4; c++) { for (uint32_t c = 0; c < 4; c++) {
for (uint16_t ar = 0; ar < 4; ar++) { uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ;
*dst++ = src[(((i + ar) + ((block + c) * bufferWidth)) * 4) + 3];
*dst++ = src[((i + ar) + ((block + c) * bufferWidth)) * 4]; *dst++ = src[blockWid+ 3]; // ar = 0
} *dst++ = src[blockWid+ 0];
*dst++ = src[blockWid+ 7]; // ar = 1
*dst++ = src[blockWid+ 4];
*dst++ = src[blockWid+ 11]; // ar = 2
*dst++ = src[blockWid+ 8];
*dst++ = src[blockWid+ 15]; // ar = 3
*dst++ = src[blockWid+ 12];
} }
for (uint16_t c = 0; c < 4; c++) { for (uint32_t c = 0; c < 4; c++) {
for (uint16_t gb = 0; gb < 4; gb++) { uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ;
*dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 1];
*dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 2]; *dst++ = src[blockWid+ 1]; // gb = 0
} *dst++ = src[blockWid+ 2];
*dst++ = src[blockWid+ 5]; // gb = 1
*dst++ = src[blockWid+ 6];
*dst++ = src[blockWid+ 9]; // gb = 2
*dst++ = src[blockWid+ 10];
*dst++ = src[blockWid+ 13]; // gb = 3
*dst++ = src[blockWid+ 14];
} }
} }
} }
@ -266,12 +274,9 @@ uint32_t* Metaphrasis::convertBufferToRGBA8(uint32_t* rgbaBuffer, uint16_t buffe
*/ */
uint16_t Metaphrasis::convertRGBAToRGB565(uint32_t rgba) { uint16_t Metaphrasis::convertRGBAToRGB565(uint32_t rgba) {
uint8_t r, g, b; uint8_t r = (((rgba >> 24) & 0xff) * 31) / 255;
uint8_t g = (((rgba >> 16) & 0xff) * 63) / 255;
r = (((rgba >> 24) & 0xff) * 31) / 255; uint8_t b = (((rgba >> 8) & 0xff) * 31) / 255;
g = (((rgba >> 16) & 0xff) * 63) / 255;
b = (((rgba >> 8) & 0xff) * 31) / 255;
return (((r << 6) | g ) << 5 ) | b; return (((r << 6) | g ) << 5 ) | b;
} }
@ -294,13 +299,14 @@ uint32_t* Metaphrasis::convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t buff
uint32_t *src = (uint32_t *)rgbaBuffer; uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB565; uint16_t *dst = (uint16_t *)dataBufferRGB565;
for(uint16_t y = 0; y < bufferHeight; y += 4) { for(uint32_t rows = 0; rows < 4; rows++) {
for(uint16_t x = 0; x < bufferWidth; x += 4) { for(uint32_t y = 0; y < bufferHeight; y += 4) {
for(uint16_t rows = 0; rows < 4; rows++) { uint32_t bufWid = ((y + rows) * bufferWidth);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 0)]); for(uint32_t x = 0; x < bufferWidth; x += 4) {
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 1)]); *dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 2)]); *dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 3)]); *dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 3)]);
} }
} }
} }
@ -320,31 +326,28 @@ uint32_t* Metaphrasis::convertBufferToRGB565(uint32_t* rgbaBuffer, uint16_t buff
*/ */
uint16_t Metaphrasis::convertRGBAToRGB5A3(uint32_t rgba) { uint16_t Metaphrasis::convertRGBAToRGB5A3(uint32_t rgba) {
uint32_t r, g, b, a; uint32_t r = (rgba >> 24) & 0xff;
uint32_t g = (rgba >> 16) & 0xff;
uint32_t b = (rgba >> 8) & 0xff;
uint32_t a = (rgba ) & 0xff;
uint16_t color; uint16_t color;
r = (rgba >> 24) & 0xff; // No predictive misses, faster shifting
g = (rgba >> 16) & 0xff;
b = (rgba >> 8) & 0xff;
a = (rgba ) & 0xff;
if (a > 0xe0) { if (a > 0xe0) {
r = r >> 3; r >>= 3;
g = g >> 3; g >>= 3;
b = b >> 3; b >>= 3;
color = (r << 10) | (g << 5) | b; color = (r << 10) | (g << 5) | b;
color |= 0x8000; color |= 0x8000;
return color;
} }
else {
r = r >> 4;
g = g >> 4;
b = b >> 4;
a = a >> 5;
color = (a << 12) | (r << 8) | (g << 4) | b; r >>= 4;
} g >>= 4;
b >>= 4;
a >>= 5;
color = (a << 12) | (r << 8) | (g << 4) | b;
return color; return color;
} }
@ -367,13 +370,14 @@ uint32_t* Metaphrasis::convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t buff
uint32_t *src = (uint32_t *)rgbaBuffer; uint32_t *src = (uint32_t *)rgbaBuffer;
uint16_t *dst = (uint16_t *)dataBufferRGB5A3; uint16_t *dst = (uint16_t *)dataBufferRGB5A3;
for(uint16_t y = 0; y < bufferHeight; y += 4) { for(uint32_t rows = 0; rows < 4; rows++) {
for(uint16_t x = 0; x < bufferWidth; x += 4) { for(uint32_t y = 0; y < bufferHeight; y += 4) {
for(uint16_t rows = 0; rows < 4; rows++) { uint32_t bufWid = ((y + rows) * bufferWidth);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 0)]); for(uint32_t x = 0; x < bufferWidth; x += 4) {
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 1)]); *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 0)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 2)]); *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 1)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 3)]); *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 2)]);
*dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 3)]);
} }
} }
} }

View File

@ -749,7 +749,7 @@ static void WindowCredits(void * ptr)
txt[i]->SetPosition(320,y); i++; y+=24; txt[i]->SetPosition(320,y); i++; y+=24;
txt[i] = new GuiText("Additional coding"); txt[i] = new GuiText("Additional coding");
txt[i]->SetPosition(50,y); i++; txt[i]->SetPosition(50,y); i++;
txt[i] = new GuiText("Carl Kenner"); txt[i] = new GuiText("Carl Kenner, dancinninjac");
txt[i]->SetPosition(320,y); i++; y+=24; txt[i]->SetPosition(320,y); i++; y+=24;
txt[i] = new GuiText("Menu artwork"); txt[i] = new GuiText("Menu artwork");
txt[i]->SetPosition(50,y); i++; txt[i]->SetPosition(50,y); i++;

View File

@ -125,7 +125,7 @@ copy_to_xfb (u32 arg)
GX_Flush (); GX_Flush ();
copynow = GX_FALSE; copynow = GX_FALSE;
} }
FrameTimer++; ++FrameTimer;
} }
/**************************************************************************** /****************************************************************************
@ -567,15 +567,17 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
long long int *dst = (long long int *) texturemem; long long int *dst = (long long int *) texturemem;
long long int *src1 = (long long int *) buffer; long long int *src1 = (long long int *) buffer;
long long int *src2 = (long long int *) (buffer + pitch); long long int *src2 = (long long int *) (buffer + pitch);
long long int *src3 = (long long int *) (buffer + (pitch * 2)); long long int *src3 = (long long int *) (buffer + (pitch << 1));
long long int *src4 = (long long int *) (buffer + (pitch * 3)); long long int *src4 = (long long int *) (buffer + (pitch * 3));
int rowpitch = (pitch >> 3) * 3; int rowpitch = (pitch >> 3) * 3;
int rowadjust = ( pitch % 8 ) * 4; int rowadjust = ( pitch % 8 ) << 2;
char *ra = NULL;
vwidth = width; vwidth = width;
vheight = height; vheight = height;
int vwid2 = (vwidth >> 2);
char *ra = NULL;
// Ensure previous vb has complete // Ensure previous vb has complete
while ((LWP_ThreadIsSuspended (vbthread) == 0) || (copynow == GX_TRUE)) while ((LWP_ThreadIsSuspended (vbthread) == 0) || (copynow == GX_TRUE))
usleep (50); usleep (50);
@ -593,7 +595,7 @@ void GX_Render(int width, int height, u8 * buffer, int pitch)
for (h = 0; h < vheight; h += 4) for (h = 0; h < vheight; h += 4)
{ {
for (w = 0; w < (vwidth >> 2); w++) for (w = 0; w < vwid2; ++w)
{ {
*dst++ = *src1++; *dst++ = *src1++;
*dst++ = *src2++; *dst++ = *src2++;
@ -780,8 +782,9 @@ void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, u8 data[],
GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT);
Mtx m,m1,m2, mv; Mtx m,m1,m2, mv;
width *=.5; width >>= 1;
height*=.5; height >>= 1;
guMtxIdentity (m1); guMtxIdentity (m1);
guMtxScaleApply(m1,m1,scaleX,scaleY,1.0); guMtxScaleApply(m1,m1,scaleX,scaleY,1.0);
guVector axis = (guVector) {0 , 0, 1 }; guVector axis = (guVector) {0 , 0, 1 };
@ -822,26 +825,20 @@ void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, u8 data[],
***************************************************************************/ ***************************************************************************/
void Menu_DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 filled) void Menu_DrawRectangle(f32 x, f32 y, f32 width, f32 height, GXColor color, u8 filled)
{ {
u8 fmt; long n = 4;
long n;
int i;
f32 x2 = x+width; f32 x2 = x+width;
f32 y2 = y+height; f32 y2 = y+height;
guVector v[] = {{x,y,0.0f}, {x2,y,0.0f}, {x2,y2,0.0f}, {x,y2,0.0f}, {x,y,0.0f}}; guVector v[] = {{x,y,0.0f}, {x2,y,0.0f}, {x2,y2,0.0f}, {x,y2,0.0f}, {x,y,0.0f}};
u8 fmt = GX_TRIANGLEFAN;
if(!filled) if(!filled)
{ {
fmt = GX_LINESTRIP; fmt = GX_LINESTRIP;
n = 5; n = 5;
} }
else
{
fmt = GX_TRIANGLEFAN;
n = 4;
}
GX_Begin(fmt, GX_VTXFMT0, n); GX_Begin(fmt, GX_VTXFMT0, n);
for(i=0; i<n; i++) for(long i=0; i<n; ++i)
{ {
GX_Position3f32(v[i].x, v[i].y, v[i].z); GX_Position3f32(v[i].x, v[i].y, v[i].z);
GX_Color4u8(color.r, color.g, color.b, color.a); GX_Color4u8(color.r, color.g, color.b, color.a);

View File

@ -526,11 +526,11 @@ void CPUUpdateWindow0()
int x01 = WIN0H & 255; int x01 = WIN0H & 255;
if(x00 <= x01) { if(x00 <= x01) {
for(int i = 0; i < 240; i++) { for(int i = 0; i < 240; ++i) {
gfxInWin0[i] = (i >= x00 && i < x01); gfxInWin0[i] = (i >= x00 && i < x01);
} }
} else { } else {
for(int i = 0; i < 240; i++) { for(int i = 0; i < 240; ++i) {
gfxInWin0[i] = (i >= x00 || i < x01); gfxInWin0[i] = (i >= x00 || i < x01);
} }
} }
@ -542,11 +542,11 @@ void CPUUpdateWindow1()
int x01 = WIN1H & 255; int x01 = WIN1H & 255;
if(x00 <= x01) { if(x00 <= x01) {
for(int i = 0; i < 240; i++) { for(int i = 0; i < 240; ++i) {
gfxInWin1[i] = (i >= x00 && i < x01); gfxInWin1[i] = (i >= x00 && i < x01);
} }
} else { } else {
for(int i = 0; i < 240; i++) { for(int i = 0; i < 240; ++i) {
gfxInWin1[i] = (i >= x00 || i < x01); gfxInWin1[i] = (i >= x00 || i < x01);
} }
} }
@ -2001,7 +2001,7 @@ void CPUCompareVCOUNT()
} }
if (layerEnableDelay>0) if (layerEnableDelay>0)
{ {
layerEnableDelay--; --layerEnableDelay;
if (layerEnableDelay==1) if (layerEnableDelay==1)
layerEnable = layerSettings & DISPCNT; layerEnable = layerSettings & DISPCNT;
} }
@ -2032,7 +2032,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
while(c != 0) { while(c != 0) {
CPUWriteMemory(d, 0); CPUWriteMemory(d, 0);
d += di; d += di;
c--; --c;
} }
} else { } else {
while(c != 0) { while(c != 0) {
@ -2040,7 +2040,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
CPUWriteMemory(d, cpuDmaLast); CPUWriteMemory(d, cpuDmaLast);
d += di; d += di;
s += si; s += si;
c--; --c;
} }
} }
} else { } else {
@ -2051,7 +2051,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
while(c != 0) { while(c != 0) {
CPUWriteHalfWord(d, 0); CPUWriteHalfWord(d, 0);
d += di; d += di;
c--; --c;
} }
} else { } else {
while(c != 0) { while(c != 0) {
@ -2060,7 +2060,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32)
cpuDmaLast |= (cpuDmaLast<<16); cpuDmaLast |= (cpuDmaLast<<16);
d += di; d += di;
s += si; s += si;
c--; --c;
} }
} }
} }
@ -2858,7 +2858,7 @@ void CPUUpdateRegister(u32 address, u16 value)
for(int i = 8; i < 15; i++) { for(int i = 8; i < 15; i++) {
memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1; memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1;
memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1; memoryWaitSeq32[i] = (memoryWaitSeq[i]<<1) + 1;
} }
if((value & 0x4000) == 0x4000) { if((value & 0x4000) == 0x4000) {
@ -3511,7 +3511,7 @@ void CPULoop(int ticks)
// if in V-Blank mode, keep computing... // if in V-Blank mode, keep computing...
if(DISPSTAT & 2) { if(DISPSTAT & 2) {
lcdTicks += 1008; lcdTicks += 1008;
VCOUNT++; ++VCOUNT;
UPDATE_REG(0x06, VCOUNT); UPDATE_REG(0x06, VCOUNT);
DISPSTAT &= 0xFFFD; DISPSTAT &= 0xFFFD;
UPDATE_REG(0x04, DISPSTAT); UPDATE_REG(0x04, DISPSTAT);
@ -3540,13 +3540,13 @@ void CPULoop(int ticks)
if(DISPSTAT & 2) { if(DISPSTAT & 2) {
// if in H-Blank, leave it and move to drawing mode // if in H-Blank, leave it and move to drawing mode
VCOUNT++; ++VCOUNT;
UPDATE_REG(0x06, VCOUNT); UPDATE_REG(0x06, VCOUNT);
lcdTicks += 1008; lcdTicks += 1008;
DISPSTAT &= 0xFFFD; DISPSTAT &= 0xFFFD;
if(VCOUNT == 160) { if(VCOUNT == 160) {
count++; ++count;
systemFrame(); systemFrame();
if((count % 10) == 0) { if((count % 10) == 0) {
@ -3598,7 +3598,7 @@ void CPULoop(int ticks)
capture = (ext & 2) ? true : false; capture = (ext & 2) ? true : false;
if(capture && !capturePrevious) { if(capture && !capturePrevious) {
captureNumber++; ++captureNumber;
systemScreenCapture(captureNumber); systemScreenCapture(captureNumber);
} }
capturePrevious = capture; capturePrevious = capture;
@ -3615,7 +3615,7 @@ void CPULoop(int ticks)
systemDrawScreen(); systemDrawScreen();
frameCount = 0; frameCount = 0;
} else } else
frameCount++; ++frameCount;
if(systemPauseOnFrame()) if(systemPauseOnFrame())
ticks = 0; ticks = 0;
} }
@ -3631,7 +3631,7 @@ void CPULoop(int ticks)
case 16: case 16:
{ {
u16 *dest = (u16 *)pix + 242 * (VCOUNT+1); u16 *dest = (u16 *)pix + 242 * (VCOUNT+1);
for(int x = 0; x < 240;) { for(u32 x = 0; x < 240u;) {
*dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
*dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
*dest++ = systemColorMap16[lineMix[x++]&0xFFFF]; *dest++ = systemColorMap16[lineMix[x++]&0xFFFF];
@ -3658,8 +3658,8 @@ void CPULoop(int ticks)
break; break;
case 24: case 24:
{ {
u8 *dest = (u8 *)pix + 240 * VCOUNT * 3; u8 *dest = (u8 *)pix + VCOUNT * 720;
for(int x = 0; x < 240;) { for(u32 x = 0; x < 240u;) {
*((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
dest += 3; dest += 3;
*((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF];
@ -3701,7 +3701,7 @@ void CPULoop(int ticks)
case 32: case 32:
{ {
u32 *dest = (u32 *)pix + 241 * (VCOUNT+1); u32 *dest = (u32 *)pix + 241 * (VCOUNT+1);
for(int x = 0; x < 240; ) { for(u32 x = 0; x < 240u; ) {
*dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
*dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
*dest++ = systemColorMap32[lineMix[x++] & 0xFFFF]; *dest++ = systemColorMap32[lineMix[x++] & 0xFFFF];
@ -3767,7 +3767,7 @@ void CPULoop(int ticks)
if(timer1On) { if(timer1On) {
if(TM1CNT & 4) { if(TM1CNT & 4) {
if(timerOverflow & 1) { if(timerOverflow & 1) {
TM1D++; ++TM1D;
if(TM1D == 0) { if(TM1D == 0) {
TM1D += timer1Reload; TM1D += timer1Reload;
timerOverflow |= 2; timerOverflow |= 2;
@ -3798,7 +3798,7 @@ void CPULoop(int ticks)
if(timer2On) { if(timer2On) {
if(TM2CNT & 4) { if(TM2CNT & 4) {
if(timerOverflow & 2) { if(timerOverflow & 2) {
TM2D++; ++TM2D;
if(TM2D == 0) { if(TM2D == 0) {
TM2D += timer2Reload; TM2D += timer2Reload;
timerOverflow |= 4; timerOverflow |= 4;
@ -3827,7 +3827,7 @@ void CPULoop(int ticks)
if(timer3On) { if(timer3On) {
if(TM3CNT & 4) { if(TM3CNT & 4) {
if(timerOverflow & 4) { if(timerOverflow & 4) {
TM3D++; ++TM3D;
if(TM3D == 0) { if(TM3D == 0) {
TM3D += timer3Reload; TM3D += timer3Reload;
if(TM3CNT & 0x40) { if(TM3CNT & 0x40) {

View File

@ -1,7 +1,7 @@
/* /*
Mode 0 is the tiled graphics mode, with all the layers available. Mode 0 is the tiled graphics mode, with all the layers available.
There is no rotation or scaling in this mode. There is no rotation or scaling in this mode.
It can be either 16 colours (with 16 different palettes) or 256 colours. It can be either 16 colours (with 16 different palettes) or 256 colors.
There are 1024 tiles available. There are 1024 tiles available.
These routines only render a single line at a time, because of the way the GBA does events. These routines only render a single line at a time, because of the way the GBA does events.
@ -15,9 +15,18 @@ void mode0RenderLine()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) { int x = 232; //240 - 8
lineMix[x] = 0x7fff; do{
} lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
return; return;
} }
@ -46,11 +55,55 @@ void mode0RenderLine()
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
//--DCN
if(line0[x] < color) { //
// !NON-PORTABLE!!NON-PORTABLE!
//
// This takes advantage of the fact that the Wii has far more registers
// (32 vs 8) than IA-32 based processors processors (Intel, AMD).
// This actually runs SLOWER on those. This code will only show
// improvements on a PowerPC machine! (19.5% improvement: isolated tests)
//*
u8 li1 = (u8)(line1[x]>>24);
u8 li2 = (u8)(line2[x]>>24);
u8 li3 = (u8)(line3[x]>>24);
u8 li4 = (u8)(lineOBJ[x]>>24);
u8 r = (li2 < li1) ? (li2) : (li1);
if(li3 < r) {
r = (li4 < li3) ? (li4) : (li3);
}else if(li4 < r){
r = (li4);
}
if(line0[x] < backdrop) {
color = line0[x];
top = 0x01;
}
if(r < (u8)(color >> 24)) {
if(r == li1){
color = line1[x];
top = 0x02;
}else if(r == li2){
color = line2[x];
top = 0x04;
}else if(r == li3){
color = line3[x];
top = 0x08;
}else if(r == li4){
color = lineOBJ[x];
top = 0x10;
}
}
//Original
/*
if(line0[x] < color) {
color = line0[x]; color = line0[x];
top = 0x01; top = 0x01;
} }
@ -64,41 +117,49 @@ void mode0RenderLine()
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
if((u8)(line3[x]>>24) < (u8)(color >> 24)) {
color = line3[x]; color = line3[x];
top = 0x08; top = 0x08;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x]; color = lineOBJ[x];
top = 0x10; top = 0x10;
} }
//*/
if((top & 0x10) && (color & 0x00010000)) { if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ // semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) { u8 li0 = (u8)(line0[x]>>24);
back = line0[x]; u8 li1 = (u8)(line1[x]>>24);
top2 = 0x01; u8 li2 = (u8)(line2[x]>>24);
} u8 li3 = (u8)(line3[x]>>24);
if((u8)(line1[x]>>24) < (u8)(back >> 24)) { u8 r = (li1 < li0) ? (li1) : (li0);
back = line1[x];
top2 = 0x02; if(li2 < r) {
} r = (li3 < li2) ? (li3) : (li2);
}else if(li3 < r){
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { r = (li3);
back = line2[x]; }
top2 = 0x04;
} if(r < (u8)(color >> 24)) {
if(r == li0){
if((u8)(line3[x]>>24) < (u8)(back >> 24)) { back = line0[x];
back = line3[x]; top2 = 0x01;
top2 = 0x08; }else if(r == li1){
} back = line1[x];
top2 = 0x02;
}else if(r == li2){
back = line2[x];
top2 = 0x04;
}else if(r == li3){
back = line3[x];
top2 = 0x08;
}
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -127,9 +188,20 @@ void mode0RenderLineNoWindow()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
return; return;
} }
@ -162,32 +234,41 @@ void mode0RenderLineNoWindow()
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; x++) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
if(line0[x] < color) { u8 li1 = (u8)(line1[x]>>24);
color = line0[x]; u8 li2 = (u8)(line2[x]>>24);
top = 0x01; u8 li3 = (u8)(line3[x]>>24);
} u8 li4 = (u8)(lineOBJ[x]>>24);
if(line1[x] < (color & 0xFF000000)) { u8 r = (li2 < li1) ? (li2) : (li1);
color = line1[x];
top = 0x02; if(li3 < r) {
} r = (li4 < li3) ? (li4) : (li3);
}else if(li4 < r){
if(line2[x] < (color & 0xFF000000)) { r = (li4);
color = line2[x]; }
top = 0x04;
} if(line0[x] < backdrop) {
color = line0[x];
if(line3[x] < (color & 0xFF000000)) { top = 0x01;
color = line3[x]; }
top = 0x08;
} if(r < (u8)(color >> 24)) {
if(r == li1){
if(lineOBJ[x] < (color & 0xFF000000)) { color = line1[x];
color = lineOBJ[x]; top = 0x02;
top = 0x10; }else if(r == li2){
} color = line2[x];
top = 0x04;
}else if(r == li3){
color = line3[x];
top = 0x08;
}else if(r == li4){
color = lineOBJ[x];
top = 0x10;
}
}
if(!(color & 0x00010000)) { if(!(color & 0x00010000)) {
switch(effect) { switch(effect) {
@ -197,40 +278,30 @@ void mode0RenderLineNoWindow()
{ {
if(top & BLDMOD) { if(top & BLDMOD) {
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line0[x] < back) {
if(top != 0x01) { if((top != 0x01) && line0[x] < back) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
}
} }
if((top != 0x02) && line1[x] < (back & 0xFF000000)) {
if(line1[x] < (back & 0xFF000000)) {
if(top != 0x02) {
back = line1[x]; back = line1[x];
top2 = 0x02; top2 = 0x02;
}
} }
if(line2[x] < (back & 0xFF000000)) { if((top != 0x04) && line2[x] < (back & 0xFF000000)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if(line3[x] < (back & 0xFF000000)) { if((top != 0x08) && line3[x] < (back & 0xFF000000)) {
if(top != 0x08) {
back = line3[x]; back = line3[x];
top2 = 0x08; top2 = 0x08;
}
} }
if(lineOBJ[x] < (back & 0xFF000000)) { if((top != 0x10) && lineOBJ[x] < (back & 0xFF000000)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
@ -253,27 +324,45 @@ void mode0RenderLineNoWindow()
} else { } else {
// semi-transparent OBJ // semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line0[x] < back) { //--DCN
back = line0[x]; // This is pretty much the exact same result:
top2 = 0x01; // line1[x] < (back & 0xFF000000)
} //
// (u8)(line0[x]>>24) < (u8)(back >> 24)
if(line1[x] < (back & 0xFF000000)) { //
back = line1[x]; // The only difference is that the first is stored in a u32,
top2 = 0x02; // and the second is stored in a u8
} //*
u8 li0 = (u8)(line0[x]>>24);
if(line2[x] < (back & 0xFF000000)) { u8 li1 = (u8)(line1[x]>>24);
back = line2[x]; u8 li2 = (u8)(line2[x]>>24);
top2 = 0x04; u8 li3 = (u8)(line3[x]>>24);
}
u8 r = (li1 < li0) ? (li1) : (li0);
if(line3[x] < (back & 0xFF000000)) {
back = line3[x]; if(li2 < r) {
top2 = 0x08; r = (li3 < li2) ? (li3) : (li2);
} }else if(li3 < r){
r = (li3);
}
if(r < (u8)(color >> 24)) {
if(r == li0){
back = line0[x];
top2 = 0x01;
}else if(r == li1){
back = line1[x];
top2 = 0x02;
}else if(r == li2){
back = line2[x];
top2 = 0x04;
}else if(r == li3){
back = line3[x];
top2 = 0x08;
}
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -302,9 +391,20 @@ void mode0RenderLineAll()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
return; return;
} }
@ -380,7 +480,7 @@ void mode0RenderLineAll()
} }
} }
if((mask & 1) && (line0[x] < color)) { if((mask & 1) && (line0[x] < color)) {
color = line0[x]; color = line0[x];
top = 0x01; top = 0x01;
} }
@ -456,39 +556,30 @@ void mode0RenderLineAll()
if(top & BLDMOD) { if(top & BLDMOD) {
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
if(top != 0x01) { if((mask & 1) && (top != 0x01) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
}
} }
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { if((mask & 2) && (top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
if(top != 0x02) {
back = line1[x]; back = line1[x];
top2 = 0x02; top2 = 0x02;
}
} }
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { if((mask & 4) && (top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { if((mask & 8) && (top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
if(top != 0x08) {
back = line3[x]; back = line3[x];
top2 = 0x08; top2 = 0x08;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))

View File

@ -16,9 +16,20 @@ void mode1RenderLine()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -49,49 +60,64 @@ void mode1RenderLine()
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(u32 x = 0; x < 240u; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
if(line0[x] < color) { u8 li1 = (u8)(line1[x]>>24);
color = line0[x]; u8 li2 = (u8)(line2[x]>>24);
top = 0x01; u8 li4 = (u8)(lineOBJ[x]>>24);
}
u8 r = (li2 < li1) ? (li2) : (li1);
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x]; if(li4 < r){
top = 0x02; r = (li4);
} }
if((u8)(line2[x]>>24) < (u8)(color >> 24)) { if(line0[x] < backdrop) {
color = line2[x]; color = line0[x];
top = 0x04; top = 0x01;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if(r < (u8)(color >> 24)) {
color = lineOBJ[x]; if(r == li1){
top = 0x10; color = line1[x];
} top = 0x02;
}else if(r == li2){
color = line2[x];
top = 0x04;
}else if(r == li4){
color = lineOBJ[x];
top = 0x10;
}
}
if((top & 0x10) && (color & 0x00010000)) { if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ // semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) { u8 li0 = (u8)(line0[x]>>24);
back = line0[x]; u8 li1 = (u8)(line1[x]>>24);
top2 = 0x01; u8 li2 = (u8)(line2[x]>>24);
} u8 r = (li1 < li0) ? (li1) : (li0);
if((u8)(line1[x]>>24) < (u8)(back >> 24)) { if(li2 < r) {
back = line1[x]; r = (li2);
top2 = 0x02; }
}
if(r < (u8)(back >> 24)) {
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { if(r == li0){
back = line2[x]; back = line0[x];
top2 = 0x04; top2 = 0x01;
} }else if(r == li1){
back = line1[x];
top2 = 0x02;
}else if(r == li2){
back = line2[x];
top2 = 0x04;
}
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -122,9 +148,20 @@ void mode1RenderLineNoWindow()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -156,29 +193,37 @@ void mode1RenderLineNoWindow()
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
if(line0[x] < color) { u8 li1 = (u8)(line1[x]>>24);
color = line0[x]; u8 li2 = (u8)(line2[x]>>24);
top = 0x01; u8 li4 = (u8)(lineOBJ[x]>>24);
}
u8 r = (li2 < li1) ? (li2) : (li1);
if((u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x]; if(li4 < r){
top = 0x02; r = (li4);
} }
if((u8)(line2[x]>>24) < (u8)(color >> 24)) { if(line0[x] < backdrop) {
color = line2[x]; color = line0[x];
top = 0x04; top = 0x01;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if(r < (u8)(color >> 24)) {
color = lineOBJ[x]; if(r == li1){
top = 0x10; color = line1[x];
} top = 0x02;
}else if(r == li2){
color = line2[x];
top = 0x04;
}else if(r == li4){
color = lineOBJ[x];
top = 0x10;
}
}
if(!(color & 0x00010000)) { if(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) { switch((BLDMOD >> 6) & 3) {
@ -189,33 +234,26 @@ void mode1RenderLineNoWindow()
if(top & BLDMOD) { if(top & BLDMOD) {
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) {
if(top != 0x01) {
back = line0[x];
top2 = 0x01;
}
}
if((u8)(line1[x]>>24) < (u8)(back >> 24)) { if((top != 0x01) && (u8)(line0[x]>>24) < (u8)(back >> 24)) {
if(top != 0x02) { back = line0[x];
back = line1[x]; top2 = 0x01;
top2 = 0x02; }
}
}
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { if((top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
if(top != 0x04) { back = line1[x];
back = line2[x]; top2 = 0x02;
top2 = 0x04; }
}
}
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) { back = line2[x];
back = lineOBJ[x]; top2 = 0x04;
top2 = 0x10; }
}
} if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
back = lineOBJ[x];
top2 = 0x10;
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -234,24 +272,32 @@ void mode1RenderLineNoWindow()
break; break;
} }
} else { } else {
// semi-transparent OBJ // semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line0[x]>>24) < (u8)(back >> 24)) { u8 li0 = (u8)(line0[x]>>24);
back = line0[x]; u8 li1 = (u8)(line1[x]>>24);
top2 = 0x01; u8 li2 = (u8)(line2[x]>>24);
}
u8 r = (li1 < li0) ? (li1) : (li0);
if((u8)(line1[x]>>24) < (u8)(back >> 24)) {
back = line1[x]; if(li2 < r) {
top2 = 0x02; r = (li2);
} }
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { if(r < (u8)(back >> 24)) {
back = line2[x]; if(r == li0){
top2 = 0x04; back = line0[x];
} top2 = 0x01;
}else if(r == li1){
back = line1[x];
top2 = 0x02;
}else if(r == li2){
back = line2[x];
top2 = 0x04;
}
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -282,9 +328,20 @@ void mode1RenderLineAll()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -342,7 +399,7 @@ void mode1RenderLineAll()
u8 inWin1Mask = WININ >> 8; u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF; u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
u8 mask = outMask; u8 mask = outMask;
@ -362,22 +419,23 @@ void mode1RenderLineAll()
} }
} }
if(line0[x] < color && (mask & 1)) { // At the very least, move the inexpensive 'mask' operation up front
if((mask & 1) && line0[x] < backdrop) {
color = line0[x]; color = line0[x];
top = 0x01; top = 0x01;
} }
if((u8)(line1[x]>>24) < (u8)(color >> 24) && (mask & 2)) { if((mask & 2) && (u8)(line1[x]>>24) < (u8)(color >> 24)) {
color = line1[x]; color = line1[x];
top = 0x02; top = 0x02;
} }
if((u8)(line2[x]>>24) < (u8)(color >> 24) && (mask & 4)) { if((mask & 4) && (u8)(line2[x]>>24) < (u8)(color >> 24)) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) { if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x]; color = lineOBJ[x];
top = 0x10; top = 0x10;
} }
@ -387,7 +445,7 @@ void mode1RenderLineAll()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) { if((mask & 1) && (u8)(line0[x]>>24) < (u8)(backdrop >> 24)) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
} }
@ -429,32 +487,24 @@ void mode1RenderLineAll()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 1) && (u8)(line0[x]>>24) < (u8)(back >> 24)) { if((mask & 1) && (top != 0x01) && (u8)(line0[x]>>24) < (u8)(backdrop >> 24)) {
if(top != 0x01) {
back = line0[x]; back = line0[x];
top2 = 0x01; top2 = 0x01;
}
} }
if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { if((mask & 2) && (top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) {
if(top != 0x02) {
back = line1[x]; back = line1[x];
top2 = 0x02; top2 = 0x02;
}
} }
if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { if((mask & 4) && (top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))

View File

@ -15,9 +15,20 @@ void mode2RenderLine()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -51,40 +62,51 @@ void mode2RenderLine()
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
u8 li2 = (u8)(line2[x]>>24);
if((u8)(line2[x]>>24) < (u8)(color >> 24)) { u8 li3 = (u8)(line3[x]>>24);
color = line2[x]; u8 li4 = (u8)(lineOBJ[x]>>24);
top = 0x04;
} u8 r = (li3 < li2) ? (li3) : (li2);
if((u8)(line3[x]>>24) < (u8)(color >> 24)) { if(li4 < r){
color = line3[x]; r = (li4);
top = 0x08; }
}
if(r < (u8)(color >> 24)) {
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if(r == li2){
color = lineOBJ[x]; color = line2[x];
top = 0x10; top = 0x04;
} }else if(r == li3){
color = line3[x];
top = 0x08;
}else if(r == li4){
color = lineOBJ[x];
top = 0x10;
}
}
if((top & 0x10) && (color & 0x00010000)) { if((top & 0x10) && (color & 0x00010000)) {
// semi-transparent OBJ // semi-transparent OBJ
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { u8 li2 = (u8)(line2[x]>>24);
back = line2[x]; u8 li3 = (u8)(line3[x]>>24);
top2 = 0x04; u8 r = (li3 < li2) ? (li3) : (li2);
}
if(r < (u8)(back >> 24)) {
if((u8)(line3[x]>>24) < (u8)(back >> 24)) { if(r == li2){
back = line3[x]; back = line2[x];
top2 = 0x08; top2 = 0x04;
} }else if(r == li3){
back = line3[x];
top2 = 0x08;
}
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -116,9 +138,20 @@ void mode2RenderLineNoWindow()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -152,25 +185,32 @@ void mode2RenderLineNoWindow()
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
u8 li2 = (u8)(line2[x]>>24);
if((u8)(line2[x]>>24) < (u8)(color >> 24)) { u8 li3 = (u8)(line3[x]>>24);
color = line2[x]; u8 li4 = (u8)(lineOBJ[x]>>24);
top = 0x04;
} u8 r = (li3 < li2) ? (li3) : (li2);
if((u8)(line3[x]>>24) < (u8)(color >> 24)) { if(li4 < r){
color = line3[x]; r = (li4);
top = 0x08; }
}
if(r < (u8)(color >> 24)) {
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { if(r == li2){
color = lineOBJ[x]; color = line2[x];
top = 0x10; top = 0x04;
} }else if(r == li3){
color = line3[x];
top = 0x08;
}else if(r == li4){
color = lineOBJ[x];
top = 0x10;
}
}
if(!(color & 0x00010000)) { if(!(color & 0x00010000)) {
switch((BLDMOD >> 6) & 3) { switch((BLDMOD >> 6) & 3) {
@ -182,26 +222,20 @@ void mode2RenderLineNoWindow()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { if((top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) {
if(top != 0x04) { back = line2[x];
back = line2[x]; top2 = 0x04;
top2 = 0x04;
}
} }
if((u8)(line3[x]>>24) < (u8)(back >> 24)) { if((top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
if(top != 0x08) { back = line3[x];
back = line3[x]; top2 = 0x08;
top2 = 0x08; }
}
}
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) { back = lineOBJ[x];
back = lineOBJ[x]; top2 = 0x10;
top2 = 0x10; }
}
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -224,15 +258,19 @@ void mode2RenderLineNoWindow()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((u8)(line2[x]>>24) < (u8)(back >> 24)) { u8 li2 = (u8)(line2[x]>>24);
back = line2[x]; u8 li3 = (u8)(line3[x]>>24);
top2 = 0x04; u8 r = (li3 < li2) ? (li3) : (li2);
}
if(r < (u8)(back >> 24)) {
if((u8)(line3[x]>>24) < (u8)(back >> 24)) { if(r == li2){
back = line3[x]; back = line2[x];
top2 = 0x08; top2 = 0x04;
} }else if(r == li3){
back = line3[x];
top2 = 0x08;
}
}
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
@ -264,9 +302,20 @@ void mode2RenderLineAll()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -347,17 +396,17 @@ void mode2RenderLineAll()
} }
} }
if(line2[x] < color && (mask & 4)) { if((mask & 4) && line2[x] < color) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
if((u8)(line3[x]>>24) < (u8)(color >> 24) && (mask & 8)) { if((mask & 8) && (u8)(line3[x]>>24) < (u8)(color >> 24)) {
color = line3[x]; color = line3[x];
top = 0x08; top = 0x08;
} }
if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24) && (mask & 16)) { if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) {
color = lineOBJ[x]; color = lineOBJ[x];
top = 0x10; top = 0x10;
} }
@ -404,25 +453,19 @@ void mode2RenderLineAll()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if((mask & 4) && (top != 0x04) && line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { if((mask & 8) && (top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) {
if(top != 0x08) {
back = line3[x]; back = line3[x];
top2 = 0x08; top2 = 0x08;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))

View File

@ -14,9 +14,20 @@ void mode3RenderLine()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -43,7 +54,7 @@ void mode3RenderLine()
background = ((customBackdropColor & 0x7FFF) | 0x30000000); background = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = background; u32 color = background;
u8 top = 0x20; u8 top = 0x20;
@ -62,7 +73,7 @@ void mode3RenderLine()
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if(line2[x] < background) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
} }
@ -96,9 +107,20 @@ void mode3RenderLineNoWindow()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -125,11 +147,11 @@ void mode3RenderLineNoWindow()
background = ((customBackdropColor & 0x7FFF) | 0x30000000); background = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = background; u32 color = background;
u8 top = 0x20; u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < background) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -149,18 +171,14 @@ void mode3RenderLineNoWindow()
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if(top != 0x04 && (line2[x] < background) ) {
if(top != 0x04) { back = line2[x];
back = line2[x]; top2 = 0x04;
top2 = 0x04;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if(top != 0x10 && ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))) {
if(top != 0x10) { back = lineOBJ[x];
back = lineOBJ[x]; top2 = 0x10;
top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
@ -185,7 +203,7 @@ void mode3RenderLineNoWindow()
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if(line2[x] < background) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
} }
@ -219,9 +237,20 @@ void mode3RenderLineAll()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x80) { if(DISPCNT & 0x80) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -275,7 +304,7 @@ void mode3RenderLineAll()
background = ((customBackdropColor & 0x7FFF) | 0x30000000); background = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = background; u32 color = background;
u8 top = 0x20; u8 top = 0x20;
u8 mask = outMask; u8 mask = outMask;
@ -295,7 +324,7 @@ void mode3RenderLineAll()
} }
} }
if((mask & 4) && (line2[x] < color)) { if((mask & 4) && line2[x] < background) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -310,7 +339,7 @@ void mode3RenderLineAll()
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if((mask & 4) && line2[x] < background) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
} }
@ -341,25 +370,20 @@ void mode3RenderLineAll()
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if((mask & 4) && (top != 0x04) && line2[x] < back) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F], coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]); coeff[(COLEV >> 8) & 0x1F]);
} }
} }
break; break;

View File

@ -14,9 +14,20 @@ void mode4RenderLine()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -42,11 +53,11 @@ void mode4RenderLine()
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < backdrop) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -61,7 +72,7 @@ void mode4RenderLine()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if(line2[x] < backdrop) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
} }
@ -95,9 +106,20 @@ void mode4RenderLineNoWindow()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -123,11 +145,11 @@ void mode4RenderLineNoWindow()
backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < backdrop) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -147,18 +169,14 @@ void mode4RenderLineNoWindow()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if((top != 0x04) && line2[x] < backdrop) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
@ -217,9 +235,20 @@ void mode4RenderLineAll()
u16 *palette = (u16 *)paletteRAM; u16 *palette = (u16 *)paletteRAM;
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -272,7 +301,7 @@ void mode4RenderLineAll()
u8 inWin1Mask = WININ >> 8; u8 inWin1Mask = WININ >> 8;
u8 outMask = WINOUT & 0xFF; u8 outMask = WINOUT & 0xFF;
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = backdrop; u32 color = backdrop;
u8 top = 0x20; u8 top = 0x20;
u8 mask = outMask; u8 mask = outMask;
@ -292,7 +321,7 @@ void mode4RenderLineAll()
} }
} }
if((mask & 4) && (line2[x] < color)) { if((mask & 4) && (line2[x] < backdrop)) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -338,25 +367,20 @@ void mode4RenderLineAll()
u32 back = backdrop; u32 back = backdrop;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if((mask & 4) && (top != 0x04) && (line2[x] < backdrop)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
color = gfxAlphaBlend(color, back, color = gfxAlphaBlend(color, back,
coeff[COLEV & 0x1F], coeff[COLEV & 0x1F],
coeff[(COLEV >> 8) & 0x1F]); coeff[(COLEV >> 8) & 0x1F]);
} }
} }
break; break;

View File

@ -13,9 +13,20 @@ These routines only render a single line at a time, because of the way the GBA d
void mode5RenderLine() void mode5RenderLine()
{ {
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -44,11 +55,11 @@ void mode5RenderLine()
background = ((customBackdropColor & 0x7FFF) | 0x30000000); background = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = background; u32 color = background;
u8 top = 0x20; u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < background) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -95,9 +106,20 @@ void mode5RenderLine()
void mode5RenderLineNoWindow() void mode5RenderLineNoWindow()
{ {
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -126,11 +148,11 @@ void mode5RenderLineNoWindow()
background = ((customBackdropColor & 0x7FFF) | 0x30000000); background = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = background; u32 color = background;
u8 top = 0x20; u8 top = 0x20;
if(line2[x] < color) { if(line2[x] < background) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -150,18 +172,14 @@ void mode5RenderLineNoWindow()
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if(line2[x] < back) { if((top != 0x04) && line2[x] < background) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))
@ -218,9 +236,19 @@ void mode5RenderLineNoWindow()
void mode5RenderLineAll() void mode5RenderLineAll()
{ {
if(DISPCNT & 0x0080) { if(DISPCNT & 0x0080) {
for(int x = 0; x < 240; x++) {
lineMix[x] = 0x7fff; int x = 232; //240 - 8
} do{
lineMix[x ] =
lineMix[x+1] =
lineMix[x+2] =
lineMix[x+3] =
lineMix[x+4] =
lineMix[x+5] =
lineMix[x+6] =
lineMix[x+7] = 0x7fff;
x-=8;
}while(x>=0);
gfxLastVCOUNT = VCOUNT; gfxLastVCOUNT = VCOUNT;
return; return;
} }
@ -276,7 +304,7 @@ void mode5RenderLineAll()
background = ((customBackdropColor & 0x7FFF) | 0x30000000); background = ((customBackdropColor & 0x7FFF) | 0x30000000);
} }
for(int x = 0; x < 240; x++) { for(int x = 0; x < 240; ++x) {
u32 color = background; u32 color = background;
u8 top = 0x20; u8 top = 0x20;
u8 mask = outMask; u8 mask = outMask;
@ -296,7 +324,7 @@ void mode5RenderLineAll()
} }
} }
if((mask & 4) && (line2[x] < color)) { if((mask & 4) && (line2[x] < background)) {
color = line2[x]; color = line2[x];
top = 0x04; top = 0x04;
} }
@ -342,18 +370,14 @@ void mode5RenderLineAll()
u32 back = background; u32 back = background;
u8 top2 = 0x20; u8 top2 = 0x20;
if((mask & 4) && line2[x] < back) { if((mask & 4) && (top != 0x04) && (line2[x] < background)) {
if(top != 0x04) {
back = line2[x]; back = line2[x];
top2 = 0x04; top2 = 0x04;
}
} }
if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) {
if(top != 0x10) {
back = lineOBJ[x]; back = lineOBJ[x];
top2 = 0x10; top2 = 0x10;
}
} }
if(top2 & (BLDMOD>>8)) if(top2 & (BLDMOD>>8))

View File

@ -50,8 +50,8 @@ int soundTicks = SOUND_CLOCK_TICKS_;
static float soundVolume = 1.0f; static float soundVolume = 1.0f;
static int soundEnableFlag = 0x3ff; // emulator channels enabled static int soundEnableFlag = 0x3ff; // emulator channels enabled
static float soundFiltering_ = -1; static float soundFiltering_ = -1.0f;
static float soundVolume_ = -1; static float soundVolume_ = -1.0f;
void interp_rate() { /* empty for now */ } void interp_rate() { /* empty for now */ }
@ -82,8 +82,8 @@ public:
int readIndex; int readIndex;
int count; int count;
int writeIndex; int writeIndex;
u8 fifo [32];
int dac; int dac;
u8 fifo [32];
private: private:
int timer; int timer;
@ -115,7 +115,7 @@ void Gba_Pcm::apply_control( int idx )
int ch = 0; int ch = 0;
if ( (soundEnableFlag >> idx & 0x100) && (ioMem [NR52] & 0x80) ) if ( (soundEnableFlag >> idx & 0x100) && (ioMem [NR52] & 0x80) )
ch = ioMem [SGCNT0_H+1] >> (idx * 4) & 3; ch = ioMem [SGCNT0_H+1] >> (idx <<2) & 3;
Blip_Buffer* out = 0; Blip_Buffer* out = 0;
switch ( ch ) switch ( ch )
@ -162,11 +162,10 @@ void Gba_Pcm::update( int dac )
int filter = 0; int filter = 0;
if ( soundInterpolation ) if ( soundInterpolation )
{ {
// base filtering on how long since last sample was output unsigned period = unsigned(time - last_time);
int period = time - last_time; unsigned idx = period >> 9;
int idx = (unsigned) period / 512; if ( idx > 3 )
if ( idx >= 3 )
idx = 3; idx = 3;
static int const filters [4] = { 0, 0, 1, 2 }; static int const filters [4] = { 0, 0, 1, 2 };
@ -191,16 +190,24 @@ void Gba_Pcm_Fifo::timer_overflowed( int which_timer )
{ {
// Not filled by DMA, so fill with 16 bytes of silence // Not filled by DMA, so fill with 16 bytes of silence
int reg = which ? FIFOB_L : FIFOA_L; int reg = which ? FIFOB_L : FIFOA_L;
for ( int n = 4; n--; )
{ // No loops, yay!
soundEvent(reg , (u16)0); soundEvent(reg , (u16)0);
soundEvent(reg+2, (u16)0); soundEvent(reg+2, (u16)0);
} //
soundEvent(reg , (u16)0);
soundEvent(reg+2, (u16)0);
//
soundEvent(reg , (u16)0);
soundEvent(reg+2, (u16)0);
//
soundEvent(reg , (u16)0);
soundEvent(reg+2, (u16)0);
} }
} }
// Read next sample from FIFO // Read next sample from FIFO
count--; --count;
dac = fifo [readIndex]; dac = fifo [readIndex];
readIndex = (readIndex + 1) & 31; readIndex = (readIndex + 1) & 31;
pcm.update( dac ); pcm.update( dac );
@ -280,14 +287,17 @@ static void apply_volume( bool apu_only = false )
if ( gb_apu ) if ( gb_apu )
{ {
static float const apu_vols [4] = { 0.25, 0.5, 1, 0.25 }; static float const apu_vols [4] = { 0.25f, 0.5f, 1.0f, 0.25f };
gb_apu->volume( soundVolume_ * apu_vols [ioMem [SGCNT0_H] & 3] ); gb_apu->volume( soundVolume_ * apu_vols [ioMem [SGCNT0_H] & 3] );
} }
if ( !apu_only ) if ( !apu_only )
{ {
for ( int i = 0; i < 3; i++ ) double tmpVol = 0.002578125 * soundVolume_; // 0.66 / 256 * soundVolume_
pcm_synth [i].volume( 0.66 / 256 * soundVolume_ );
pcm_synth[0].volume( tmpVol );
pcm_synth[1].volume( tmpVol );
pcm_synth[2].volume( tmpVol );
} }
} }
@ -352,10 +362,10 @@ void flush_samples(Multi_Buffer * buffer)
// that don't use the length parameter of the write method. // that don't use the length parameter of the write method.
// TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the // TODO: Update the Win32 audio drivers (DS, OAL, XA2), and flush all the
// samples at once to help reducing the audio delay on all platforms. // samples at once to help reducing the audio delay on all platforms.
int soundBufferLen = ( soundSampleRate / 60 ) * 4; int soundBufferLen = ( soundSampleRate / 60 ) << 2;
// soundBufferLen should have a whole number of sample pairs // soundBufferLen should have a whole number of sample pairs
assert( soundBufferLen % (2 * sizeof *soundFinalWave) == 0 ); assert( soundBufferLen % ((sizeof *soundFinalWave)<<1) == 0 );
// number of samples in output buffer // number of samples in output buffer
int const out_buf_size = soundBufferLen / sizeof *soundFinalWave; int const out_buf_size = soundBufferLen / sizeof *soundFinalWave;
@ -376,8 +386,10 @@ static void apply_filtering()
{ {
soundFiltering_ = soundFiltering; soundFiltering_ = soundFiltering;
int const base_freq = (int) (32768 - soundFiltering_ * 16384); // Yes, I changed soundFiltering_ to soundFiltering, the reason is
int const nyquist = stereo_buffer->sample_rate() / 2; // to eliminate a write-read dependency
int const base_freq = 32768 - (int) (soundFiltering * 16384.0f);
int const nyquist = stereo_buffer->sample_rate() >> 1;
for ( int i = 0; i < 3; i++ ) for ( int i = 0; i < 3; i++ )
{ {
@ -584,8 +596,8 @@ static struct {
gb_apu_state_t apu; gb_apu_state_t apu;
// old state // old state
u8 soundDSAValue;
int soundDSBValue; int soundDSBValue;
u8 soundDSAValue;
} state; } state;
// Old GBA sound state format // Old GBA sound state format