diff --git a/readme.txt b/readme.txt index de309e3..0109c18 100644 --- a/readme.txt +++ b/readme.txt @@ -284,9 +284,7 @@ Unzip the archive. You will find the following folders inside: apps Contains Homebrew Channel ready files (see Homebrew Channel instructions below) - -gamecube Contains GameCube DOL file (not required for Wii) - + vbagx Contains the directory structure required for storing roms and saves. By default, roms are loaded from "vbagx/roms/" and saves / preferences are stored in @@ -906,7 +904,7 @@ right analog stick = fast forward -=[ Credits ]=- Coding & menu design Tantric - Additional coding Carl Kenner + Additional coding Carl Kenner, dancinninjac Menu artwork the3seashells Menu sound Peter de Man diff --git a/source/ngc/Metaphrasis.cpp b/source/ngc/Metaphrasis.cpp index cc83cfc..a023b09 100644 --- a/source/ngc/Metaphrasis.cpp +++ b/source/ngc/Metaphrasis.cpp @@ -54,9 +54,9 @@ uint32_t* Metaphrasis::convertBufferToI4(uint32_t* rgbaBuffer, uint16_t bufferWi uint32_t *src = (uint32_t *)rgbaBuffer; uint8_t *dst = (uint8_t *)dataBufferI4; - for(uint16_t y = 0; y < bufferHeight; y += 8) { - for(uint16_t x = 0; x < bufferWidth; x += 8) { - for(uint16_t rows = 0; rows < 8; rows++) { + for(uint32_t y = 0; y < bufferHeight; y += 8) { + for(uint32_t x = 0; x < bufferWidth; x += 8) { + 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 + 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); @@ -88,17 +88,19 @@ uint32_t* Metaphrasis::convertBufferToI8(uint32_t* rgbaBuffer, uint16_t bufferWi uint32_t *src = (uint32_t *)rgbaBuffer; uint8_t *dst = (uint8_t *)dataBufferI8; - for(uint16_t y = 0; y < bufferHeight; y += 4) { - for(uint16_t x = 0; x < bufferWidth; x += 8) { - for(uint16_t rows = 0; rows < 4; rows++) { - *dst++ = src[((y + rows) * bufferWidth) + (x + 0)] & 0xff; - *dst++ = src[((y + rows) * bufferWidth) + (x + 1)] & 0xff; - *dst++ = src[((y + rows) * bufferWidth) + (x + 2)] & 0xff; - *dst++ = src[((y + rows) * bufferWidth) + (x + 3)] & 0xff; - *dst++ = src[((y + rows) * bufferWidth) + (x + 4)] & 0xff; - *dst++ = src[((y + rows) * bufferWidth) + (x + 5)] & 0xff; - *dst++ = src[((y + rows) * bufferWidth) + (x + 6)] & 0xff; - *dst++ = src[((y + rows) * bufferWidth) + (x + 7)] & 0xff; + for(uint32_t rows = 0; rows < 4; rows++) { + for(uint32_t y = 0; y < bufferHeight; y += 4) { + uint32_t bufWid = ((y + rows) * bufferWidth); + for(uint32_t x = 0; x < bufferWidth; x += 8) { + + *dst++ = src[bufWid + (x + 0)] & 0xff; + *dst++ = src[bufWid + (x + 1)] & 0xff; + *dst++ = src[bufWid + (x + 2)] & 0xff; + *dst++ = src[bufWid + (x + 3)] & 0xff; + *dst++ = src[bufWid + (x + 4)] & 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 i, a; - - i = (rgba >> 8) & 0xf0; - a = (rgba ) & 0xff; - + uint8_t i = (rgba >> 8) & 0xf0; + uint8_t a = (rgba ) & 0xff; return i | (a >> 4); } @@ -144,9 +143,9 @@ uint32_t* Metaphrasis::convertBufferToIA4(uint32_t* rgbaBuffer, uint16_t bufferW uint32_t *src = (uint32_t *)rgbaBuffer; uint8_t *dst = (uint8_t *)dataBufferIA4; - for(uint16_t y = 0; y < bufferHeight; y += 4) { - for(uint16_t x = 0; x < bufferWidth; x += 8) { - for(uint16_t rows = 0; rows < 4; rows++) { + for(uint32_t y = 0; y < bufferHeight; y += 4) { + for(uint32_t x = 0; x < bufferWidth; x += 8) { + 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 + 1)]); *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) { - uint8_t i, a; - - i = (rgba >> 8) & 0xff; - a = (rgba ) & 0xff; - - return (i << 8) | a; + return (((rgba >> 8) & 0xff) << 8) | ((rgba ) & 0xff); } /** @@ -200,13 +194,15 @@ uint32_t* Metaphrasis::convertBufferToIA8(uint32_t* rgbaBuffer, uint16_t bufferW uint32_t *src = (uint32_t *)rgbaBuffer; uint16_t *dst = (uint16_t *)dataBufferIA8; - for(uint16_t y = 0; y < bufferHeight; y += 4) { - for(uint16_t x = 0; x < bufferWidth; x += 4) { - for(uint16_t rows = 0; rows < 4; rows++) { - *dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 0)]); - *dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 1)]); - *dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 2)]); - *dst++ = Metaphrasis::convertRGBAToIA8(src[((y + rows) * bufferWidth) + (x + 3)]); + for(uint32_t rows = 0; rows < 4; ++rows) { + for(uint32_t y = 0; y < bufferHeight; y += 4) { + uint32_t bufWid = ((y + rows) * bufferWidth); + for(uint32_t x = 0; x < bufferWidth; x += 4) { + + *dst++ = Metaphrasis::convertRGBAToIA8(src[bufWid + (x + 0)]); + *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 *dst = (uint8_t *)dataBufferRGBA8; - for(uint16_t block = 0; block < bufferHeight; block += 4) { - for(uint16_t i = 0; i < bufferWidth; i += 4) { - for (uint16_t c = 0; c < 4; c++) { - for (uint16_t ar = 0; ar < 4; ar++) { - *dst++ = src[(((i + ar) + ((block + c) * bufferWidth)) * 4) + 3]; - *dst++ = src[((i + ar) + ((block + c) * bufferWidth)) * 4]; - } + for(uint32_t block = 0; block < bufferHeight; block += 4) { + for(uint32_t i = 0; i < bufferWidth; i += 4) { + for (uint32_t c = 0; c < 4; c++) { + uint32_t blockWid = (((block + c) * bufferWidth)+i)<<2 ; + + *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 (uint16_t gb = 0; gb < 4; gb++) { - *dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 1]; - *dst++ = src[(((i + gb) + ((block + c) * bufferWidth)) * 4) + 2]; - } + for (uint32_t c = 0; c < 4; c++) { + uint32_t blockWid = (((block + c) * bufferWidth)+i)<<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) { - uint8_t r, g, b; - - r = (((rgba >> 24) & 0xff) * 31) / 255; - g = (((rgba >> 16) & 0xff) * 63) / 255; - b = (((rgba >> 8) & 0xff) * 31) / 255; - + uint8_t r = (((rgba >> 24) & 0xff) * 31) / 255; + uint8_t g = (((rgba >> 16) & 0xff) * 63) / 255; + uint8_t b = (((rgba >> 8) & 0xff) * 31) / 255; 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; uint16_t *dst = (uint16_t *)dataBufferRGB565; - for(uint16_t y = 0; y < bufferHeight; y += 4) { - for(uint16_t x = 0; x < bufferWidth; x += 4) { - for(uint16_t rows = 0; rows < 4; rows++) { - *dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 0)]); - *dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 1)]); - *dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 2)]); - *dst++ = Metaphrasis::convertRGBAToRGB565(src[((y + rows) * bufferWidth) + (x + 3)]); + for(uint32_t rows = 0; rows < 4; rows++) { + for(uint32_t y = 0; y < bufferHeight; y += 4) { + uint32_t bufWid = ((y + rows) * bufferWidth); + for(uint32_t x = 0; x < bufferWidth; x += 4) { + *dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 0)]); + *dst++ = Metaphrasis::convertRGBAToRGB565(src[bufWid + (x + 1)]); + *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) { - 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; - r = (rgba >> 24) & 0xff; - g = (rgba >> 16) & 0xff; - b = (rgba >> 8) & 0xff; - a = (rgba ) & 0xff; - + // No predictive misses, faster shifting if (a > 0xe0) { - r = r >> 3; - g = g >> 3; - b = b >> 3; - + r >>= 3; + g >>= 3; + b >>= 3; + color = (r << 10) | (g << 5) | b; 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; } @@ -367,13 +370,14 @@ uint32_t* Metaphrasis::convertBufferToRGB5A3(uint32_t* rgbaBuffer, uint16_t buff uint32_t *src = (uint32_t *)rgbaBuffer; uint16_t *dst = (uint16_t *)dataBufferRGB5A3; - for(uint16_t y = 0; y < bufferHeight; y += 4) { - for(uint16_t x = 0; x < bufferWidth; x += 4) { - for(uint16_t rows = 0; rows < 4; rows++) { - *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 0)]); - *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 1)]); - *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 2)]); - *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[((y + rows) * bufferWidth) + (x + 3)]); + for(uint32_t rows = 0; rows < 4; rows++) { + for(uint32_t y = 0; y < bufferHeight; y += 4) { + uint32_t bufWid = ((y + rows) * bufferWidth); + for(uint32_t x = 0; x < bufferWidth; x += 4) { + *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 0)]); + *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 1)]); + *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 2)]); + *dst++ = Metaphrasis::convertRGBAToRGB5A3(src[bufWid + (x + 3)]); } } } diff --git a/source/ngc/menu.cpp b/source/ngc/menu.cpp index 90b3bea..fbe1983 100644 --- a/source/ngc/menu.cpp +++ b/source/ngc/menu.cpp @@ -749,7 +749,7 @@ static void WindowCredits(void * ptr) txt[i]->SetPosition(320,y); i++; y+=24; txt[i] = new GuiText("Additional coding"); 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] = new GuiText("Menu artwork"); txt[i]->SetPosition(50,y); i++; diff --git a/source/ngc/video.cpp b/source/ngc/video.cpp index 5d99493..1b4adac 100644 --- a/source/ngc/video.cpp +++ b/source/ngc/video.cpp @@ -125,7 +125,7 @@ copy_to_xfb (u32 arg) GX_Flush (); 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 *src1 = (long long int *) buffer; 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)); int rowpitch = (pitch >> 3) * 3; - int rowadjust = ( pitch % 8 ) * 4; - char *ra = NULL; + int rowadjust = ( pitch % 8 ) << 2; vwidth = width; vheight = height; + int vwid2 = (vwidth >> 2); + char *ra = NULL; + // Ensure previous vb has complete while ((LWP_ThreadIsSuspended (vbthread) == 0) || (copynow == GX_TRUE)) 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 (w = 0; w < (vwidth >> 2); w++) + for (w = 0; w < vwid2; ++w) { *dst++ = *src1++; *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); Mtx m,m1,m2, mv; - width *=.5; - height*=.5; + width >>= 1; + height >>= 1; + guMtxIdentity (m1); guMtxScaleApply(m1,m1,scaleX,scaleY,1.0); 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) { - u8 fmt; - long n; - int i; + long n = 4; f32 x2 = x+width; 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}}; + u8 fmt = GX_TRIANGLEFAN; if(!filled) { fmt = GX_LINESTRIP; n = 5; } - else - { - fmt = GX_TRIANGLEFAN; - n = 4; - } GX_Begin(fmt, GX_VTXFMT0, n); - for(i=0; i= x00 && i < x01); } } else { - for(int i = 0; i < 240; i++) { + for(int i = 0; i < 240; ++i) { gfxInWin0[i] = (i >= x00 || i < x01); } } @@ -542,11 +542,11 @@ void CPUUpdateWindow1() int x01 = WIN1H & 255; if(x00 <= x01) { - for(int i = 0; i < 240; i++) { + for(int i = 0; i < 240; ++i) { gfxInWin1[i] = (i >= x00 && i < x01); } } else { - for(int i = 0; i < 240; i++) { + for(int i = 0; i < 240; ++i) { gfxInWin1[i] = (i >= x00 || i < x01); } } @@ -2001,7 +2001,7 @@ void CPUCompareVCOUNT() } if (layerEnableDelay>0) { - layerEnableDelay--; + --layerEnableDelay; if (layerEnableDelay==1) layerEnable = layerSettings & DISPCNT; } @@ -2032,7 +2032,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32) while(c != 0) { CPUWriteMemory(d, 0); d += di; - c--; + --c; } } else { while(c != 0) { @@ -2040,7 +2040,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32) CPUWriteMemory(d, cpuDmaLast); d += di; s += si; - c--; + --c; } } } else { @@ -2051,7 +2051,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32) while(c != 0) { CPUWriteHalfWord(d, 0); d += di; - c--; + --c; } } else { while(c != 0) { @@ -2060,7 +2060,7 @@ void doDMA(u32 &s, u32 &d, u32 si, u32 di, u32 c, int transfer32) cpuDmaLast |= (cpuDmaLast<<16); d += di; s += si; - c--; + --c; } } } @@ -2858,7 +2858,7 @@ void CPUUpdateRegister(u32 address, u16 value) for(int i = 8; i < 15; i++) { memoryWait32[i] = memoryWait[i] + memoryWaitSeq[i] + 1; - memoryWaitSeq32[i] = memoryWaitSeq[i]*2 + 1; + memoryWaitSeq32[i] = (memoryWaitSeq[i]<<1) + 1; } if((value & 0x4000) == 0x4000) { @@ -3511,7 +3511,7 @@ void CPULoop(int ticks) // if in V-Blank mode, keep computing... if(DISPSTAT & 2) { lcdTicks += 1008; - VCOUNT++; + ++VCOUNT; UPDATE_REG(0x06, VCOUNT); DISPSTAT &= 0xFFFD; UPDATE_REG(0x04, DISPSTAT); @@ -3540,13 +3540,13 @@ void CPULoop(int ticks) if(DISPSTAT & 2) { // if in H-Blank, leave it and move to drawing mode - VCOUNT++; + ++VCOUNT; UPDATE_REG(0x06, VCOUNT); lcdTicks += 1008; DISPSTAT &= 0xFFFD; if(VCOUNT == 160) { - count++; + ++count; systemFrame(); if((count % 10) == 0) { @@ -3598,7 +3598,7 @@ void CPULoop(int ticks) capture = (ext & 2) ? true : false; if(capture && !capturePrevious) { - captureNumber++; + ++captureNumber; systemScreenCapture(captureNumber); } capturePrevious = capture; @@ -3615,7 +3615,7 @@ void CPULoop(int ticks) systemDrawScreen(); frameCount = 0; } else - frameCount++; + ++frameCount; if(systemPauseOnFrame()) ticks = 0; } @@ -3631,7 +3631,7 @@ void CPULoop(int ticks) case 16: { 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]; @@ -3658,8 +3658,8 @@ void CPULoop(int ticks) break; case 24: { - u8 *dest = (u8 *)pix + 240 * VCOUNT * 3; - for(int x = 0; x < 240;) { + u8 *dest = (u8 *)pix + VCOUNT * 720; + for(u32 x = 0; x < 240u;) { *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; dest += 3; *((u32 *)dest) = systemColorMap32[lineMix[x++] & 0xFFFF]; @@ -3701,7 +3701,7 @@ void CPULoop(int ticks) case 32: { 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]; @@ -3767,7 +3767,7 @@ void CPULoop(int ticks) if(timer1On) { if(TM1CNT & 4) { if(timerOverflow & 1) { - TM1D++; + ++TM1D; if(TM1D == 0) { TM1D += timer1Reload; timerOverflow |= 2; @@ -3798,7 +3798,7 @@ void CPULoop(int ticks) if(timer2On) { if(TM2CNT & 4) { if(timerOverflow & 2) { - TM2D++; + ++TM2D; if(TM2D == 0) { TM2D += timer2Reload; timerOverflow |= 4; @@ -3827,7 +3827,7 @@ void CPULoop(int ticks) if(timer3On) { if(TM3CNT & 4) { if(timerOverflow & 4) { - TM3D++; + ++TM3D; if(TM3D == 0) { TM3D += timer3Reload; if(TM3CNT & 0x40) { diff --git a/source/vba/gba/Mode0.cpp b/source/vba/gba/Mode0.cpp index 9a2dd26..dfa6682 100644 --- a/source/vba/gba/Mode0.cpp +++ b/source/vba/gba/Mode0.cpp @@ -1,7 +1,7 @@ /* Mode 0 is the tiled graphics mode, with all the layers available. 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. 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; 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; } @@ -46,11 +55,55 @@ void mode0RenderLine() backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(u32 x = 0; x < 240u; ++x) { u32 color = backdrop; u8 top = 0x20; - - if(line0[x] < color) { + //--DCN + // + // !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]; top = 0x01; } @@ -64,41 +117,49 @@ void mode0RenderLine() color = line2[x]; top = 0x04; } - - if((u8)(line3[x]>>24) < (u8)(color >> 24)) { + if((u8)(line3[x]>>24) < (u8)(color >> 24)) { color = line3[x]; top = 0x08; } - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { color = lineOBJ[x]; top = 0x10; } + //*/ if((top & 0x10) && (color & 0x00010000)) { // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((u8)(line0[x]>>24) < (u8)(back >> 24)) { - back = line0[x]; - top2 = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(back >> 24)) { - back = line1[x]; - top2 = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - back = line3[x]; - top2 = 0x08; - } + u8 li0 = (u8)(line0[x]>>24); + u8 li1 = (u8)(line1[x]>>24); + u8 li2 = (u8)(line2[x]>>24); + u8 li3 = (u8)(line3[x]>>24); + + u8 r = (li1 < li0) ? (li1) : (li0); + + if(li2 < r) { + 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)) color = gfxAlphaBlend(color, back, @@ -127,9 +188,20 @@ void mode0RenderLineNoWindow() u16 *palette = (u16 *)paletteRAM; 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; } @@ -162,32 +234,41 @@ void mode0RenderLineNoWindow() for(int x = 0; x < 240; x++) { u32 color = backdrop; - u8 top = 0x20; + u8 top = 0x20; - if(line0[x] < color) { - color = line0[x]; - top = 0x01; - } - - if(line1[x] < (color & 0xFF000000)) { - color = line1[x]; - top = 0x02; - } - - if(line2[x] < (color & 0xFF000000)) { - color = line2[x]; - top = 0x04; - } - - if(line3[x] < (color & 0xFF000000)) { - color = line3[x]; - top = 0x08; - } - - if(lineOBJ[x] < (color & 0xFF000000)) { - color = lineOBJ[x]; - top = 0x10; - } + 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; + } + } if(!(color & 0x00010000)) { switch(effect) { @@ -197,40 +278,30 @@ void mode0RenderLineNoWindow() { if(top & BLDMOD) { u32 back = backdrop; - u8 top2 = 0x20; - if(line0[x] < back) { - if(top != 0x01) { + u8 top2 = 0x20; + + if((top != 0x01) && line0[x] < back) { back = line0[x]; top2 = 0x01; - } } - - if(line1[x] < (back & 0xFF000000)) { - if(top != 0x02) { + if((top != 0x02) && line1[x] < (back & 0xFF000000)) { back = line1[x]; top2 = 0x02; - } } - if(line2[x] < (back & 0xFF000000)) { - if(top != 0x04) { + if((top != 0x04) && line2[x] < (back & 0xFF000000)) { back = line2[x]; top2 = 0x04; - } } - if(line3[x] < (back & 0xFF000000)) { - if(top != 0x08) { + if((top != 0x08) && line3[x] < (back & 0xFF000000)) { back = line3[x]; top2 = 0x08; - } } - if(lineOBJ[x] < (back & 0xFF000000)) { - if(top != 0x10) { + if((top != 0x10) && lineOBJ[x] < (back & 0xFF000000)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) @@ -253,27 +324,45 @@ void mode0RenderLineNoWindow() } else { // semi-transparent OBJ u32 back = backdrop; - u8 top2 = 0x20; + u8 top2 = 0x20; - if(line0[x] < back) { - back = line0[x]; - top2 = 0x01; - } - - if(line1[x] < (back & 0xFF000000)) { - back = line1[x]; - top2 = 0x02; - } - - if(line2[x] < (back & 0xFF000000)) { - back = line2[x]; - top2 = 0x04; - } - - if(line3[x] < (back & 0xFF000000)) { - back = line3[x]; - top2 = 0x08; - } + //--DCN + // This is pretty much the exact same result: + // line1[x] < (back & 0xFF000000) + // + // (u8)(line0[x]>>24) < (u8)(back >> 24) + // + // The only difference is that the first is stored in a u32, + // and the second is stored in a u8 + //* + u8 li0 = (u8)(line0[x]>>24); + u8 li1 = (u8)(line1[x]>>24); + u8 li2 = (u8)(line2[x]>>24); + u8 li3 = (u8)(line3[x]>>24); + + u8 r = (li1 < li0) ? (li1) : (li0); + + if(li2 < r) { + 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)) color = gfxAlphaBlend(color, back, @@ -302,9 +391,20 @@ void mode0RenderLineAll() u16 *palette = (u16 *)paletteRAM; 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; } @@ -380,7 +480,7 @@ void mode0RenderLineAll() } } - if((mask & 1) && (line0[x] < color)) { + if((mask & 1) && (line0[x] < color)) { color = line0[x]; top = 0x01; } @@ -456,39 +556,30 @@ void mode0RenderLineAll() if(top & BLDMOD) { u32 back = backdrop; 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]; top2 = 0x01; - } } - if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { - if(top != 0x02) { + if((mask & 2) && (top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { back = line1[x]; top2 = 0x02; - } } - if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { + if((mask & 4) && (top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { back = line2[x]; top2 = 0x04; - } } - if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { - if(top != 0x08) { + if((mask & 8) && (top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { back = line3[x]; top2 = 0x08; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) diff --git a/source/vba/gba/Mode1.cpp b/source/vba/gba/Mode1.cpp index fd15a03..814b474 100644 --- a/source/vba/gba/Mode1.cpp +++ b/source/vba/gba/Mode1.cpp @@ -16,9 +16,20 @@ void mode1RenderLine() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -49,49 +60,64 @@ void mode1RenderLine() backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(u32 x = 0; x < 240u; ++x) { u32 color = backdrop; u8 top = 0x20; - if(line0[x] < color) { - color = line0[x]; - top = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(color >> 24)) { - color = line1[x]; - top = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } + u8 li1 = (u8)(line1[x]>>24); + u8 li2 = (u8)(line2[x]>>24); + u8 li4 = (u8)(lineOBJ[x]>>24); + + u8 r = (li2 < li1) ? (li2) : (li1); + + 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 == li4){ + color = lineOBJ[x]; + top = 0x10; + } + } if((top & 0x10) && (color & 0x00010000)) { // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((u8)(line0[x]>>24) < (u8)(back >> 24)) { - back = line0[x]; - top2 = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(back >> 24)) { - back = line1[x]; - top2 = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } + u8 li0 = (u8)(line0[x]>>24); + u8 li1 = (u8)(line1[x]>>24); + u8 li2 = (u8)(line2[x]>>24); + u8 r = (li1 < li0) ? (li1) : (li0); + + if(li2 < r) { + r = (li2); + } + + if(r < (u8)(back >> 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; + } + } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, @@ -122,9 +148,20 @@ void mode1RenderLineNoWindow() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -156,29 +193,37 @@ void mode1RenderLineNoWindow() backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = backdrop; u8 top = 0x20; - if(line0[x] < color) { - color = line0[x]; - top = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(color >> 24)) { - color = line1[x]; - top = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } + u8 li1 = (u8)(line1[x]>>24); + u8 li2 = (u8)(line2[x]>>24); + u8 li4 = (u8)(lineOBJ[x]>>24); + + u8 r = (li2 < li1) ? (li2) : (li1); + + 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 == li4){ + color = lineOBJ[x]; + top = 0x10; + } + } if(!(color & 0x00010000)) { switch((BLDMOD >> 6) & 3) { @@ -189,33 +234,26 @@ void mode1RenderLineNoWindow() if(top & BLDMOD) { u32 back = backdrop; 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 != 0x02) { - back = line1[x]; - top2 = 0x02; - } - } + if((top != 0x01) && (u8)(line0[x]>>24) < (u8)(back >> 24)) { + back = line0[x]; + top2 = 0x01; + } - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { - back = line2[x]; - top2 = 0x04; - } - } + if((top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { + back = line1[x]; + top2 = 0x02; + } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } - } + if((top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { + back = line2[x]; + top2 = 0x04; + } + + if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { + back = lineOBJ[x]; + top2 = 0x10; + } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, @@ -234,24 +272,32 @@ void mode1RenderLineNoWindow() break; } } else { - // semi-transparent OBJ - u32 back = backdrop; - u8 top2 = 0x20; + // semi-transparent OBJ + u32 back = backdrop; + u8 top2 = 0x20; - if((u8)(line0[x]>>24) < (u8)(back >> 24)) { - back = line0[x]; - top2 = 0x01; - } - - if((u8)(line1[x]>>24) < (u8)(back >> 24)) { - back = line1[x]; - top2 = 0x02; - } - - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } + u8 li0 = (u8)(line0[x]>>24); + u8 li1 = (u8)(line1[x]>>24); + u8 li2 = (u8)(line2[x]>>24); + + u8 r = (li1 < li0) ? (li1) : (li0); + + if(li2 < r) { + r = (li2); + } + + if(r < (u8)(back >> 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; + } + } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, @@ -282,9 +328,20 @@ void mode1RenderLineAll() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -342,7 +399,7 @@ void mode1RenderLineAll() u8 inWin1Mask = WININ >> 8; u8 outMask = WINOUT & 0xFF; - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = backdrop; u8 top = 0x20; 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]; 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]; 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]; 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]; top = 0x10; } @@ -387,7 +445,7 @@ void mode1RenderLineAll() u32 back = backdrop; 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]; top2 = 0x01; } @@ -429,32 +487,24 @@ void mode1RenderLineAll() u32 back = backdrop; 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)(backdrop >> 24)) { back = line0[x]; top2 = 0x01; - } } - if((mask & 2) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { - if(top != 0x02) { + if((mask & 2) && (top != 0x02) && (u8)(line1[x]>>24) < (u8)(back >> 24)) { back = line1[x]; top2 = 0x02; - } } - if((mask & 4) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { + if((mask & 4) && (top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) diff --git a/source/vba/gba/Mode2.cpp b/source/vba/gba/Mode2.cpp index 96999dc..d61b0c3 100644 --- a/source/vba/gba/Mode2.cpp +++ b/source/vba/gba/Mode2.cpp @@ -15,9 +15,20 @@ void mode2RenderLine() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -51,40 +62,51 @@ void mode2RenderLine() backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = backdrop; u8 top = 0x20; - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(color >> 24)) { - color = line3[x]; - top = 0x08; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } + u8 li2 = (u8)(line2[x]>>24); + u8 li3 = (u8)(line3[x]>>24); + u8 li4 = (u8)(lineOBJ[x]>>24); + + u8 r = (li3 < li2) ? (li3) : (li2); + + if(li4 < r){ + r = (li4); + } + + if(r < (u8)(color >> 24)) { + 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((top & 0x10) && (color & 0x00010000)) { // semi-transparent OBJ u32 back = backdrop; u8 top2 = 0x20; - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - back = line3[x]; - top2 = 0x08; - } + u8 li2 = (u8)(line2[x]>>24); + u8 li3 = (u8)(line3[x]>>24); + u8 r = (li3 < li2) ? (li3) : (li2); + + if(r < (u8)(back >> 24)) { + if(r == li2){ + back = line2[x]; + top2 = 0x04; + }else if(r == li3){ + back = line3[x]; + top2 = 0x08; + } + } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, @@ -116,9 +138,20 @@ void mode2RenderLineNoWindow() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -152,25 +185,32 @@ void mode2RenderLineNoWindow() backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = backdrop; u8 top = 0x20; - - if((u8)(line2[x]>>24) < (u8)(color >> 24)) { - color = line2[x]; - top = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(color >> 24)) { - color = line3[x]; - top = 0x08; - } - - if((u8)(lineOBJ[x]>>24) < (u8)(color >> 24)) { - color = lineOBJ[x]; - top = 0x10; - } + u8 li2 = (u8)(line2[x]>>24); + u8 li3 = (u8)(line3[x]>>24); + u8 li4 = (u8)(lineOBJ[x]>>24); + + u8 r = (li3 < li2) ? (li3) : (li2); + + if(li4 < r){ + r = (li4); + } + + if(r < (u8)(color >> 24)) { + 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)) { switch((BLDMOD >> 6) & 3) { @@ -182,26 +222,20 @@ void mode2RenderLineNoWindow() u32 back = backdrop; u8 top2 = 0x20; - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - if(top != 0x04) { - back = line2[x]; - top2 = 0x04; - } + if((top != 0x04) && (u8)(line2[x]>>24) < (u8)(back >> 24)) { + back = line2[x]; + top2 = 0x04; } - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - if(top != 0x08) { - back = line3[x]; - top2 = 0x08; - } - } + if((top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { + back = line3[x]; + top2 = 0x08; + } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } - } + if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { + back = lineOBJ[x]; + top2 = 0x10; + } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, @@ -224,15 +258,19 @@ void mode2RenderLineNoWindow() u32 back = backdrop; u8 top2 = 0x20; - if((u8)(line2[x]>>24) < (u8)(back >> 24)) { - back = line2[x]; - top2 = 0x04; - } - - if((u8)(line3[x]>>24) < (u8)(back >> 24)) { - back = line3[x]; - top2 = 0x08; - } + u8 li2 = (u8)(line2[x]>>24); + u8 li3 = (u8)(line3[x]>>24); + u8 r = (li3 < li2) ? (li3) : (li2); + + if(r < (u8)(back >> 24)) { + if(r == li2){ + back = line2[x]; + top2 = 0x04; + }else if(r == li3){ + back = line3[x]; + top2 = 0x08; + } + } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, @@ -264,9 +302,20 @@ void mode2RenderLineAll() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -347,17 +396,17 @@ void mode2RenderLineAll() } } - if(line2[x] < color && (mask & 4)) { + if((mask & 4) && line2[x] < color) { color = line2[x]; 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]; 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]; top = 0x10; } @@ -404,25 +453,19 @@ void mode2RenderLineAll() u32 back = backdrop; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if((mask & 4) && (top != 0x04) && line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((mask & 8) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { - if(top != 0x08) { + if((mask & 8) && (top != 0x08) && (u8)(line3[x]>>24) < (u8)(back >> 24)) { back = line3[x]; top2 = 0x08; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) diff --git a/source/vba/gba/Mode3.cpp b/source/vba/gba/Mode3.cpp index fe5fb36..2d97265 100644 --- a/source/vba/gba/Mode3.cpp +++ b/source/vba/gba/Mode3.cpp @@ -14,9 +14,20 @@ void mode3RenderLine() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -43,7 +54,7 @@ void mode3RenderLine() background = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = background; u8 top = 0x20; @@ -62,7 +73,7 @@ void mode3RenderLine() u32 back = background; u8 top2 = 0x20; - if(line2[x] < back) { + if(line2[x] < background) { back = line2[x]; top2 = 0x04; } @@ -96,9 +107,20 @@ void mode3RenderLineNoWindow() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -125,11 +147,11 @@ void mode3RenderLineNoWindow() background = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = background; u8 top = 0x20; - if(line2[x] < color) { + if(line2[x] < background) { color = line2[x]; top = 0x04; } @@ -149,18 +171,14 @@ void mode3RenderLineNoWindow() u32 back = background; u8 top2 = 0x20; - if(line2[x] < back) { - if(top != 0x04) { - back = line2[x]; - top2 = 0x04; - } + if(top != 0x04 && (line2[x] < background) ) { + back = line2[x]; + top2 = 0x04; } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { - back = lineOBJ[x]; - top2 = 0x10; - } + if(top != 0x10 && ((u8)(lineOBJ[x]>>24) < (u8)(back >> 24))) { + back = lineOBJ[x]; + top2 = 0x10; } if(top2 & (BLDMOD>>8)) @@ -185,7 +203,7 @@ void mode3RenderLineNoWindow() u32 back = background; u8 top2 = 0x20; - if(line2[x] < back) { + if(line2[x] < background) { back = line2[x]; top2 = 0x04; } @@ -219,9 +237,20 @@ void mode3RenderLineAll() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -275,7 +304,7 @@ void mode3RenderLineAll() background = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = background; u8 top = 0x20; u8 mask = outMask; @@ -295,7 +324,7 @@ void mode3RenderLineAll() } } - if((mask & 4) && (line2[x] < color)) { + if((mask & 4) && line2[x] < background) { color = line2[x]; top = 0x04; } @@ -310,7 +339,7 @@ void mode3RenderLineAll() u32 back = background; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { + if((mask & 4) && line2[x] < background) { back = line2[x]; top2 = 0x04; } @@ -341,25 +370,20 @@ void mode3RenderLineAll() u32 back = background; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if((mask & 4) && (top != 0x04) && line2[x] < back) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, coeff[COLEV & 0x1F], coeff[(COLEV >> 8) & 0x1F]); - } } break; diff --git a/source/vba/gba/Mode4.cpp b/source/vba/gba/Mode4.cpp index 6234613..218f929 100644 --- a/source/vba/gba/Mode4.cpp +++ b/source/vba/gba/Mode4.cpp @@ -14,9 +14,20 @@ void mode4RenderLine() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -42,11 +53,11 @@ void mode4RenderLine() backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = backdrop; u8 top = 0x20; - if(line2[x] < color) { + if(line2[x] < backdrop) { color = line2[x]; top = 0x04; } @@ -61,7 +72,7 @@ void mode4RenderLine() u32 back = backdrop; u8 top2 = 0x20; - if(line2[x] < back) { + if(line2[x] < backdrop) { back = line2[x]; top2 = 0x04; } @@ -95,9 +106,20 @@ void mode4RenderLineNoWindow() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -123,11 +145,11 @@ void mode4RenderLineNoWindow() backdrop = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = backdrop; u8 top = 0x20; - if(line2[x] < color) { + if(line2[x] < backdrop) { color = line2[x]; top = 0x04; } @@ -147,18 +169,14 @@ void mode4RenderLineNoWindow() u32 back = backdrop; u8 top2 = 0x20; - if(line2[x] < back) { - if(top != 0x04) { + if((top != 0x04) && line2[x] < backdrop) { back = line2[x]; top2 = 0x04; - } } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) @@ -217,9 +235,20 @@ void mode4RenderLineAll() u16 *palette = (u16 *)paletteRAM; 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; return; } @@ -272,7 +301,7 @@ void mode4RenderLineAll() u8 inWin1Mask = WININ >> 8; u8 outMask = WINOUT & 0xFF; - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = backdrop; u8 top = 0x20; u8 mask = outMask; @@ -292,7 +321,7 @@ void mode4RenderLineAll() } } - if((mask & 4) && (line2[x] < color)) { + if((mask & 4) && (line2[x] < backdrop)) { color = line2[x]; top = 0x04; } @@ -338,25 +367,20 @@ void mode4RenderLineAll() u32 back = backdrop; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if((mask & 4) && (top != 0x04) && (line2[x] < backdrop)) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) color = gfxAlphaBlend(color, back, coeff[COLEV & 0x1F], coeff[(COLEV >> 8) & 0x1F]); - } } break; diff --git a/source/vba/gba/Mode5.cpp b/source/vba/gba/Mode5.cpp index 5f25b47..17ddf55 100644 --- a/source/vba/gba/Mode5.cpp +++ b/source/vba/gba/Mode5.cpp @@ -13,9 +13,20 @@ These routines only render a single line at a time, because of the way the GBA d void mode5RenderLine() { 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; return; } @@ -44,11 +55,11 @@ void mode5RenderLine() background = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = background; u8 top = 0x20; - if(line2[x] < color) { + if(line2[x] < background) { color = line2[x]; top = 0x04; } @@ -95,9 +106,20 @@ void mode5RenderLine() void mode5RenderLineNoWindow() { 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; return; } @@ -126,11 +148,11 @@ void mode5RenderLineNoWindow() background = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = background; u8 top = 0x20; - if(line2[x] < color) { + if(line2[x] < background) { color = line2[x]; top = 0x04; } @@ -150,18 +172,14 @@ void mode5RenderLineNoWindow() u32 back = background; u8 top2 = 0x20; - if(line2[x] < back) { - if(top != 0x04) { + if((top != 0x04) && line2[x] < background) { back = line2[x]; top2 = 0x04; - } } - if((u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) @@ -218,9 +236,19 @@ void mode5RenderLineNoWindow() void mode5RenderLineAll() { 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; return; } @@ -276,7 +304,7 @@ void mode5RenderLineAll() background = ((customBackdropColor & 0x7FFF) | 0x30000000); } - for(int x = 0; x < 240; x++) { + for(int x = 0; x < 240; ++x) { u32 color = background; u8 top = 0x20; u8 mask = outMask; @@ -296,7 +324,7 @@ void mode5RenderLineAll() } } - if((mask & 4) && (line2[x] < color)) { + if((mask & 4) && (line2[x] < background)) { color = line2[x]; top = 0x04; } @@ -342,18 +370,14 @@ void mode5RenderLineAll() u32 back = background; u8 top2 = 0x20; - if((mask & 4) && line2[x] < back) { - if(top != 0x04) { + if((mask & 4) && (top != 0x04) && (line2[x] < background)) { back = line2[x]; top2 = 0x04; - } } - if((mask & 16) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { - if(top != 0x10) { + if((mask & 16) && (top != 0x10) && (u8)(lineOBJ[x]>>24) < (u8)(back >> 24)) { back = lineOBJ[x]; top2 = 0x10; - } } if(top2 & (BLDMOD>>8)) diff --git a/source/vba/gba/Sound.cpp b/source/vba/gba/Sound.cpp index 025ec03..96f90fc 100644 --- a/source/vba/gba/Sound.cpp +++ b/source/vba/gba/Sound.cpp @@ -50,8 +50,8 @@ int soundTicks = SOUND_CLOCK_TICKS_; static float soundVolume = 1.0f; static int soundEnableFlag = 0x3ff; // emulator channels enabled -static float soundFiltering_ = -1; -static float soundVolume_ = -1; +static float soundFiltering_ = -1.0f; +static float soundVolume_ = -1.0f; void interp_rate() { /* empty for now */ } @@ -82,8 +82,8 @@ public: int readIndex; int count; int writeIndex; - u8 fifo [32]; int dac; + u8 fifo [32]; private: int timer; @@ -115,7 +115,7 @@ void Gba_Pcm::apply_control( int idx ) int ch = 0; 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; switch ( ch ) @@ -162,11 +162,10 @@ void Gba_Pcm::update( int dac ) int filter = 0; if ( soundInterpolation ) { - // base filtering on how long since last sample was output - int period = time - last_time; + unsigned period = unsigned(time - last_time); + unsigned idx = period >> 9; - int idx = (unsigned) period / 512; - if ( idx >= 3 ) + if ( idx > 3 ) idx = 3; 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 int reg = which ? FIFOB_L : FIFOA_L; - for ( int n = 4; n--; ) - { - soundEvent(reg , (u16)0); - soundEvent(reg+2, (u16)0); - } + + // No loops, yay! + 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); + // + soundEvent(reg , (u16)0); + soundEvent(reg+2, (u16)0); } } // Read next sample from FIFO - count--; + --count; dac = fifo [readIndex]; readIndex = (readIndex + 1) & 31; pcm.update( dac ); @@ -280,14 +287,17 @@ static void apply_volume( bool apu_only = false ) 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] ); } if ( !apu_only ) { - for ( int i = 0; i < 3; i++ ) - pcm_synth [i].volume( 0.66 / 256 * soundVolume_ ); + double tmpVol = 0.002578125 * soundVolume_; // 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. // 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. - int soundBufferLen = ( soundSampleRate / 60 ) * 4; + int soundBufferLen = ( soundSampleRate / 60 ) << 2; // 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 int const out_buf_size = soundBufferLen / sizeof *soundFinalWave; @@ -376,8 +386,10 @@ static void apply_filtering() { soundFiltering_ = soundFiltering; - int const base_freq = (int) (32768 - soundFiltering_ * 16384); - int const nyquist = stereo_buffer->sample_rate() / 2; + // Yes, I changed soundFiltering_ to soundFiltering, the reason is + // 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++ ) { @@ -584,8 +596,8 @@ static struct { gb_apu_state_t apu; // old state - u8 soundDSAValue; int soundDSBValue; + u8 soundDSAValue; } state; // Old GBA sound state format