- Do a whole bunch of code cleanup.
This commit is contained in:
rogerman 2015-06-10 03:45:58 +00:00
parent 1648b5f74d
commit 12342e21cc
12 changed files with 284 additions and 207 deletions

View File

@ -55,7 +55,10 @@ GPU::MosaicLookup GPU::mosaicLookup;
//#define DEBUG_TRI
CACHE_ALIGN u8 GPU_screen[4*256*192];
u16 *GPU_screen = NULL;
static size_t _gpuFramebufferWidth = 256;
static size_t _gpuFramebufferHeight = 192;
CACHE_ALIGN u8 sprWin[256];
@ -319,7 +322,7 @@ void GPU_setMasterBrightness (GPU *gpu, u16 val)
PROGINFO("Changing master brightness outside of vblank\n");
}
gpu->MasterBrightFactor = (val & 0x1F);
gpu->MasterBrightMode = (val>>14);
gpu->MasterBrightMode = (GPUMasterBrightMode)(val>>14);
//printf("MASTER BRIGHTNESS %d to %d at %d\n",gpu->core,gpu->MasterBrightFactor,nds.VCount);
}
@ -349,20 +352,20 @@ void GPU_setVideoProp(GPU * gpu, u32 p)
SetupFinalPixelBlitter (gpu);
gpu->dispMode = cnt->DisplayMode & ((gpu->core)?1:3);
gpu->dispMode = (GPUDisplayMode)( cnt->DisplayMode & ((gpu->core)?1:3) );
gpu->vramBlock = cnt->VRAM_Block;
switch (gpu->dispMode)
{
case 0: // Display Off
case GPUDisplayMode_Off: // Display Off
break;
case 1: // Display BG and OBJ layers
case GPUDisplayMode_Normal: // Display BG and OBJ layers
break;
case 2: // Display framebuffer
case GPUDisplayMode_VRAM: // Display framebuffer
gpu->VRAMaddr = (u8 *)MMU.ARM9_LCD + (gpu->vramBlock * 0x20000);
break;
case 3: // Display from Main RAM
case GPUDisplayMode_MainMemory: // Display from Main RAM
// nothing to be done here
// see GPU_RenderLine who gets data from FIFO.
break;
@ -560,13 +563,12 @@ FORCEINLINE void GPU::renderline_checkWindows(u16 x, bool &draw, bool &effect) c
/*****************************************************************************/
template<BlendFunc FUNC, bool WINDOW>
FORCEINLINE FASTCALL void GPU::_master_setFinal3dColor(int dstX, int srcX)
FORCEINLINE FASTCALL void GPU::_master_setFinal3dColor(int dstX, const FragmentColor src)
{
int x = dstX;
int passing = dstX<<1;
const FragmentColor color = _3dColorLine[srcX];
u8 alpha = color.a;
u8 *dst = currDst;
u8 alpha = src.a;
u16 *dst = currDst;
u16 final;
bool windowEffect = blend1; //bomberman land touch dialogbox will fail without setting to blend1
@ -591,19 +593,19 @@ FORCEINLINE FASTCALL void GPU::_master_setFinal3dColor(int dstX, int srcX)
//if the layer underneath is a blend bottom layer, then 3d always alpha blends with it
COLOR c2, cfinal;
c2.val = HostReadWord(dst, passing);
c2.val = HostReadWord((u8 *)dst, passing);
cfinal.bits.red = ((color.r * alpha) + ((c2.bits.red<<1) * (32 - alpha)))>>6;
cfinal.bits.green = ((color.g * alpha) + ((c2.bits.green<<1) * (32 - alpha)))>>6;
cfinal.bits.blue = ((color.b * alpha) + ((c2.bits.blue<<1) * (32 - alpha)))>>6;
cfinal.bits.red = ((src.r * alpha) + ((c2.bits.red<<1) * (32 - alpha)))>>6;
cfinal.bits.green = ((src.g * alpha) + ((c2.bits.green<<1) * (32 - alpha)))>>6;
cfinal.bits.blue = ((src.b * alpha) + ((c2.bits.blue<<1) * (32 - alpha)))>>6;
final = cfinal.val;
}
else final = R6G6B6TORGB15(color.r, color.g, color.b);
else final = R6G6B6TORGB15(src.r, src.g, src.b);
}
else
{
final = R6G6B6TORGB15(color.r, color.g, color.b);
final = R6G6B6TORGB15(src.r, src.g, src.b);
//perform the special effect
if(windowEffect)
switch(FUNC) {
@ -615,7 +617,7 @@ FORCEINLINE FASTCALL void GPU::_master_setFinal3dColor(int dstX, int srcX)
}
}
HostWriteWord(dst, passing, (final | 0x8000));
HostWriteWord((u8 *)dst, passing, (final | 0x8000));
bgPixels[x] = 0;
}
@ -651,7 +653,7 @@ FORCEINLINE FASTCALL bool GPU::_master_setFinalBGColor(u16 &color, const u32 x)
//perform the special effect
switch(FUNC) {
case Blend: if(blend2[bg_under]) color = blend(color,HostReadWord(currDst, x<<1)); break;
case Blend: if(blend2[bg_under]) color = blend(color, HostReadWord((u8 *)currDst, x << 1)); break;
case Increase: color = currentFadeInColors[color]; break;
case Decrease: color = currentFadeOutColors[color]; break;
case NoBlend: break;
@ -660,7 +662,7 @@ FORCEINLINE FASTCALL bool GPU::_master_setFinalBGColor(u16 &color, const u32 x)
}
template<BlendFunc FUNC, bool WINDOW>
static FORCEINLINE void _master_setFinalOBJColor(GPU *gpu, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
static FORCEINLINE void _master_setFinalOBJColor(GPU *gpu, u16 *dst, u16 color, u8 alpha, u8 type, u16 x)
{
const bool isObjTranslucentType = type == GPU_OBJ_MODE_Transparent || type == GPU_OBJ_MODE_Bitmap;
@ -717,13 +719,13 @@ static FORCEINLINE void _master_setFinalOBJColor(GPU *gpu, u8 *dst, u16 color, u
case Increase: color = gpu->currentFadeInColors[color&0x7FFF]; break;
case Decrease: color = gpu->currentFadeOutColors[color&0x7FFF]; break;
case Blend:
u16 backColor = HostReadWord(dst,x<<1);
u16 backColor = HostReadWord((u8 *)dst, x << 1);
color = _blend(color,backColor,&gpuBlendTable555[eva][evb]);
break;
}
}
HostWriteWord(dst, x<<1, (color | 0x8000));
HostWriteWord((u8 *)dst, x << 1, (color | 0x8000));
gpu->bgPixels[x] = 4;
}
@ -755,28 +757,28 @@ FORCEINLINE void GPU::setFinalColorBG(u16 color, const u32 x)
if(BACKDROP || draw) //backdrop must always be drawn
{
HostWriteWord(currDst, x<<1, color | 0x8000);
HostWriteWord((u8 *)currDst, x<<1, color | 0x8000);
if(!BACKDROP) bgPixels[x] = currBgNum; //lets do this in the backdrop drawing loop, should be faster
}
}
FORCEINLINE void GPU::setFinalColor3d(int dstX, int srcX)
FORCEINLINE void GPU::setFinalColor3d(int dstX, const FragmentColor src)
{
switch(setFinalColor3d_funcNum)
{
case 0x0: _master_setFinal3dColor<NoBlend,false>(dstX,srcX); break;
case 0x1: _master_setFinal3dColor<Blend,false>(dstX,srcX); break;
case 0x2: _master_setFinal3dColor<Increase,false>(dstX,srcX); break;
case 0x3: _master_setFinal3dColor<Decrease,false>(dstX,srcX); break;
case 0x4: _master_setFinal3dColor<NoBlend,true>(dstX,srcX); break;
case 0x5: _master_setFinal3dColor<Blend,true>(dstX,srcX); break;
case 0x6: _master_setFinal3dColor<Increase,true>(dstX,srcX); break;
case 0x7: _master_setFinal3dColor<Decrease,true>(dstX,srcX); break;
case 0x0: _master_setFinal3dColor<NoBlend,false>(dstX, src); break;
case 0x1: _master_setFinal3dColor<Blend,false>(dstX, src); break;
case 0x2: _master_setFinal3dColor<Increase,false>(dstX, src); break;
case 0x3: _master_setFinal3dColor<Decrease,false>(dstX, src); break;
case 0x4: _master_setFinal3dColor<NoBlend,true>(dstX, src); break;
case 0x5: _master_setFinal3dColor<Blend,true>(dstX, src); break;
case 0x6: _master_setFinal3dColor<Increase,true>(dstX, src); break;
case 0x7: _master_setFinal3dColor<Decrease,true>(dstX, src); break;
};
}
FORCEINLINE void setFinalColorSpr(GPU* gpu, u8 *dst, u16 color, u8 alpha, u8 type, u16 x)
FORCEINLINE void setFinalColorSpr(GPU *gpu, u16 *dst, u16 color, u8 alpha, u8 type, u16 x)
{
switch(gpu->setFinalColorSpr_funcNum)
{
@ -1533,14 +1535,14 @@ void GPU::_spriteRender(u8 * dst, u8 * dst_alpha, u8 * typeTab, u8 * prioTab)
struct _DISPCNT * dispCnt = &(gpu->dispx_st)->dispx_DISPCNT.bits;
u8 block = gpu->sprBoundary;
for(int i = 0; i<128; i++)
for (size_t i = 0; i < 128; i++)
{
_OAM_ oam;
_OAM_* spriteInfo = &oam;
SlurpOAM(spriteInfo, gpu->oam, i);
//for each sprite:
if(cost>=2130)
if (cost >= 2130)
{
//out of sprite rendering time
//printf("sprite overflow!\n");
@ -1874,13 +1876,14 @@ int Screen_Init()
MainScreen.gpu = GPU_Init(0);
SubScreen.gpu = GPU_Init(1);
memset(GPU_screen, 0, sizeof(GPU_screen));
for(int i = 0; i < (256*192*2); i++)
((u16*)GPU_screen)[i] = 0x7FFF;
disp_fifo.head = disp_fifo.tail = 0;
if (osd) {delete osd; osd =NULL; }
OSDCLASS *previousOSD = osd;
osd = new OSDCLASS(-1);
delete previousOSD;
gfx3d_init();
GPU_SetFramebufferSize(256, 192);
return 0;
}
@ -1892,9 +1895,10 @@ void Screen_Reset(void)
MainScreen.offset = 0;
SubScreen.offset = 192;
memset(GPU_screen, 0, sizeof(GPU_screen));
for(int i = 0; i < (256*192*2); i++)
((u16*)GPU_screen)[i] = 0x7FFF;
for (size_t i = 0; i < (_gpuFramebufferWidth * _gpuFramebufferHeight) * 2; i++)
{
GPU_screen[i] = 0x7FFF;
}
disp_fifo.head = disp_fifo.tail = 0;
osd->clear();
@ -1902,12 +1906,46 @@ void Screen_Reset(void)
void Screen_DeInit(void)
{
gfx3d_deinit();
GPU_DeInit(MainScreen.gpu);
GPU_DeInit(SubScreen.gpu);
if (osd) {delete osd; osd =NULL; }
delete osd;
osd = NULL;
free(GPU_screen);
GPU_screen = NULL;
}
size_t GPU_GetFramebufferWidth()
{
return _gpuFramebufferWidth;
}
size_t GPU_GetFramebufferHeight()
{
return _gpuFramebufferHeight;
}
void GPU_SetFramebufferSize(size_t w, size_t h)
{
if (w < 256 || h < 192)
{
return;
}
_gpuFramebufferWidth = w;
_gpuFramebufferHeight = h;
GPU_screen = (u16 *)realloc(GPU_screen, w * h * sizeof(u16) * 2);
for (size_t i = 0; i < (w * h) * 2; i++)
{
GPU_screen[i] = 0x7FFF;
}
gfx3d_setFramebufferSize(_gpuFramebufferWidth, _gpuFramebufferHeight);
}
/*****************************************************************************/
// GPU_RenderLine
@ -1988,18 +2026,18 @@ static void GPU_RenderLine_layer(NDS_Screen * screen, u16 l)
case 0:
case 1:
PLAIN_CLEAR:
memset_u16_le<256>(gpu->currDst,backdrop_color);
memset_u16_le<256>(gpu->currDst, backdrop_color);
break;
//for backdrops, fade in and fade out can be applied if it's a 1st target screen
case 2:
if(gpu->BLDCNT & 0x20) //backdrop is selected for color effect
memset_u16_le<256>(gpu->currDst,gpu->currentFadeInColors[backdrop_color]);
memset_u16_le<256>(gpu->currDst, gpu->currentFadeInColors[backdrop_color]);
else goto PLAIN_CLEAR;
break;
case 3:
if(gpu->BLDCNT & 0x20) //backdrop is selected for color effect
memset_u16_le<256>(gpu->currDst,gpu->currentFadeOutColors[backdrop_color]);
memset_u16_le<256>(gpu->currDst, gpu->currentFadeOutColors[backdrop_color]);
else goto PLAIN_CLEAR;
break;
@ -2083,18 +2121,16 @@ PLAIN_CLEAR:
gpu->currBgNum = 0;
const u16 hofs = gpu->getHOFS(i16);
gfx3d_GetLineData(l, &gpu->_3dColorLine);
const FragmentColor *colorLine = gpu->_3dColorLine;
const FragmentColor *colorLine = gfx3d_GetLineDataRGBA6665(l);
for (size_t k = 0; k < 256; k++)
{
const size_t q = ((k + hofs) & 0x1FF);
if (q > 255 || colorLine[q].a == 0)
if (q >= 256 || colorLine[q].a == 0)
continue;
gpu->setFinalColor3d(k, q);
gpu->setFinalColor3d(k, colorLine[q]);
}
continue;
@ -2139,11 +2175,11 @@ template<bool SKIP> static void GPU_RenderLine_DispCapture(u16 l)
switch(gpu->dispCapCnt.capx) { \
case DISPCAPCNT::_128: \
for (int i = 0; i < 128; i++) \
HostWriteWord(DST, i << 1, HostReadWord(SRC, i << 1) | (SETALPHABIT?(1<<15):0)); \
HostWriteWord(DST, i << 1, HostReadWord(SRC, i << 1) | (SETALPHABIT ? 0x8000 : 0x0000)); \
break; \
case DISPCAPCNT::_256: \
for (int i = 0; i < 256; i++) \
HostWriteWord(DST, i << 1, HostReadWord(SRC, i << 1) | (SETALPHABIT?(1<<15):0)); \
HostWriteWord(DST, i << 1, HostReadWord(SRC, i << 1) | (SETALPHABIT ? 0x8000 : 0x0000)); \
break; \
default: assert(false); \
}
@ -2201,27 +2237,26 @@ template<bool SKIP> static void GPU_RenderLine_DispCapture(u16 l)
case 0: // Capture screen (BG + OBJ + 3D)
{
//INFO("Capture screen (BG + OBJ + 3D)\n");
u8 *src = (u8*)(gpu->tempScanline);
u16 *src = gpu->tempScanline;
#ifdef LOCAL_BE
static u16 swapSrc[256];
const size_t swapSrcSize = (gpu->dispCapCnt.capx == DISPCAPCNT::_128) ? 128 : 256;
for(size_t i = 0; i < swapSrcSize; i++)
{
swapSrc[i] = LE_TO_LOCAL_16(((u16 *)src)[i]);
swapSrc[i] = LE_TO_LOCAL_16(src[i]);
}
CAPCOPY((u8 *)swapSrc,cap_dst,true);
CAPCOPY((u8 *)swapSrc, cap_dst, true);
#else
CAPCOPY(src,cap_dst,true);
CAPCOPY((u8 *)src, cap_dst, true);
#endif
}
break;
case 1: // Capture 3D
{
//INFO("Capture 3D\n");
u16* colorLine;
gfx3d_GetLineData15bpp(l, &colorLine);
const u16 *colorLine = gfx3d_GetLineDataRGBA5551(l);
CAPCOPY(((u8*)colorLine),cap_dst,false);
}
break;
@ -2246,20 +2281,21 @@ template<bool SKIP> static void GPU_RenderLine_DispCapture(u16 l)
}
}
break;
default: // Capture source is SourceA+B blended
{
//INFO("Capture source is SourceA+B blended\n");
u16 *srcA = NULL;
u16 *srcB = NULL;
const u16 *srcA = NULL;
const u16 *srcB = NULL;
if (gpu->dispCapCnt.srcA == 0)
{
// Capture screen (BG + OBJ + 3D)
srcA = (u16*)(gpu->tempScanline);
srcA = gpu->tempScanline;
}
else
{
gfx3d_GetLineData15bpp(l, &srcA);
srcA = gfx3d_GetLineDataRGBA5551(l);
}
static u16 fifoLine[256];
@ -2275,16 +2311,15 @@ template<bool SKIP> static void GPU_RenderLine_DispCapture(u16 l)
}
const int todo = (gpu->dispCapCnt.capx==DISPCAPCNT::_128?128:256);
const size_t todo = (gpu->dispCapCnt.capx==DISPCAPCNT::_128 ? 128 : 256);
for(u16 i = 0; i < todo; i++)
for (size_t i = 0; i < todo; i++)
{
u16 a,r,g,b;
u16 a_alpha = srcA[i] & 0x8000;
u16 b_alpha = srcB[i] & 0x8000;
if(a_alpha)
if (a_alpha)
{
a = 0x8000;
r = ((srcA[i] & 0x1F) * gpu->dispCapCnt.EVA);
@ -2292,9 +2327,11 @@ template<bool SKIP> static void GPU_RenderLine_DispCapture(u16 l)
b = (((srcA[i] >> 10) & 0x1F) * gpu->dispCapCnt.EVA);
}
else
{
a = r = g = b = 0;
}
if(b_alpha)
if (b_alpha)
{
a = 0x8000;
r += ((srcB[i] & 0x1F) * gpu->dispCapCnt.EVB);
@ -2318,7 +2355,7 @@ template<bool SKIP> static void GPU_RenderLine_DispCapture(u16 l)
}
}
if (l>=191)
if (l >= 191)
{
gpu->dispCapCnt.enabled = FALSE;
gpu->dispCapCnt.val &= 0x7FFFFFFF;
@ -2328,18 +2365,16 @@ template<bool SKIP> static void GPU_RenderLine_DispCapture(u16 l)
}
}
static INLINE void GPU_RenderLine_MasterBrightness(NDS_Screen * screen, u16 l)
static INLINE void GPU_RenderLine_MasterBrightness(NDS_Screen *screen, u16 l)
{
GPU * gpu = screen->gpu;
u8 * dst = GPU_screen + (screen->offset + l) * 512;
u16 i16;
GPU *gpu = screen->gpu;
u16 *dst = GPU_screen + (screen->offset + l) * _gpuFramebufferWidth;
//isn't it odd that we can set uselessly high factors here?
//factors above 16 change nothing. curious.
int factor = gpu->MasterBrightFactor;
if(factor==0) return;
if(factor>16) factor=16;
if (factor == 0) return;
if (factor > 16) factor = 16;
//Apply final brightness adjust (MASTER_BRIGHT)
@ -2347,49 +2382,47 @@ static INLINE void GPU_RenderLine_MasterBrightness(NDS_Screen * screen, u16 l)
switch (gpu->MasterBrightMode)
{
// Disabled
case 0:
case GPUMasterBrightMode_Disable:
break;
// Bright up
case 1:
case GPUMasterBrightMode_Up:
{
if(factor != 16)
if (factor != 16)
{
for(i16 = 0; i16 < 256; ++i16)
for (size_t i = 0; i < _gpuFramebufferWidth; ++i)
{
((u16*)dst)[i16] = fadeInColors[factor][((u16*)dst)[i16]&0x7FFF];
dst[i] = fadeInColors[factor][dst[i]&0x7FFF];
}
}
else
{
// all white (optimization)
for(i16 = 0; i16 < 256; ++i16)
((u16*)dst)[i16] = 0x7FFF;
for (size_t i = 0; i < _gpuFramebufferWidth; ++i)
{
dst[i] = 0x7FFF;
}
}
break;
}
// Bright down
case 2:
case GPUMasterBrightMode_Down:
{
if(factor != 16)
if (factor != 16)
{
for(i16 = 0; i16 < 256; ++i16)
for (size_t i = 0; i < _gpuFramebufferWidth; ++i)
{
((u16*)dst)[i16] = fadeOutColors[factor][((u16*)dst)[i16]&0x7FFF];
dst[i] = fadeOutColors[factor][dst[i]&0x7FFF];
}
}
else
{
// all black (optimization)
memset(dst, 0, 512);
memset(dst, 0, _gpuFramebufferWidth * sizeof(u16));
}
break;
}
// Reserved
case 3:
case GPUMasterBrightMode_Reserved:
break;
}
@ -2481,12 +2514,14 @@ void GPU::update_winh(int WIN_NUM)
}
}
void GPU_RenderLine(NDS_Screen * screen, u16 l, bool skip)
void GPU_RenderLine(NDS_Screen *screen, u16 l, bool skip)
{
GPU * gpu = screen->gpu;
GPU *gpu = screen->gpu;
u16 *dst = GPU_screen + (screen->offset + l) * 256;
//here is some setup which is only done on line 0
if(l == 0) {
if (l == 0)
{
//this is speculative. the idea is as follows:
//whenever the user updates the affine start position regs, it goes into the active regs immediately
//(this is handled on the set event from MMU)
@ -2501,7 +2536,7 @@ void GPU_RenderLine(NDS_Screen * screen, u16 l, bool skip)
gpu->refreshAffineStartRegs(-1,-1);
}
if(skip)
if (skip)
{
gpu->currLine = l;
if (gpu->core == GPU_MAIN)
@ -2513,18 +2548,17 @@ void GPU_RenderLine(NDS_Screen * screen, u16 l, bool skip)
}
//blacken the screen if it is turned off by the user
if(!CommonSettings.showGpu.screens[gpu->core])
if (!CommonSettings.showGpu.screens[gpu->core])
{
u8 * dst = GPU_screen + (screen->offset + l) * 512;
memset(dst,0,512);
memset(dst, 0, _gpuFramebufferWidth * sizeof(u16));
return;
}
// skip some work if master brightness makes the screen completely white or completely black
if(gpu->MasterBrightFactor >= 16 && (gpu->MasterBrightMode == 1 || gpu->MasterBrightMode == 2))
if (gpu->MasterBrightFactor >= 16 && (gpu->MasterBrightMode == GPUMasterBrightMode_Up || gpu->MasterBrightMode == GPUMasterBrightMode_Down))
{
// except if it could cause any side effects (for example if we're capturing), then don't skip anything
if(!(gpu->core == GPU_MAIN && (gpu->dispCapCnt.enabled || l == 0 || l == 191)))
if (!(gpu->core == GPU_MAIN && (gpu->dispCapCnt.enabled || l == 0 || l == 191)))
{
gpu->currLine = l;
GPU_RenderLine_MasterBrightness(screen, l);
@ -2553,52 +2587,52 @@ void GPU_RenderLine(NDS_Screen * screen, u16 l, bool skip)
gpu->setup_windows<1>();
//generate the 2d engine output
if(gpu->dispMode == 1) {
if (gpu->dispMode == GPUDisplayMode_Normal)
{
//optimization: render straight to the output buffer when thats what we are going to end up displaying anyway
gpu->tempScanline = screen->gpu->currDst = (u8 *)(GPU_screen) + (screen->offset + l) * 512;
} else {
gpu->tempScanline = screen->gpu->currDst = GPU_screen + (screen->offset + l) * 256;
}
else
{
//otherwise, we need to go to a temp buffer
gpu->tempScanline = screen->gpu->currDst = (u8 *)gpu->tempScanlineBuffer;
gpu->tempScanline = screen->gpu->currDst = gpu->tempScanlineBuffer;
}
GPU_RenderLine_layer(screen, l);
switch (gpu->dispMode)
{
case 0: // Display Off(Display white)
case GPUDisplayMode_Off: // Display Off(Display white)
{
u8 * dst = GPU_screen + (screen->offset + l) * 512;
for (int i=0; i<256; i++)
HostWriteWord(dst, i << 1, 0x7FFF);
for (size_t i = 0; i < _gpuFramebufferWidth; i++)
HostWriteWord((u8 *)dst, i << 1, 0x7FFF);
}
break;
case 1: // Display BG and OBJ layers
case GPUDisplayMode_Normal: // Display BG and OBJ layers
//do nothing: it has already been generated into the right place
break;
case 2: // Display vram framebuffer
case GPUDisplayMode_VRAM: // Display vram framebuffer
{
u8 * dst = GPU_screen + (screen->offset + l) * 512;
u8 * src = gpu->VRAMaddr + (l*512);
u16 *src = (u16 *)gpu->VRAMaddr + (l * 256);
#ifdef LOCAL_BE
for(size_t i = 0; i < 256; i++)
for (size_t i = 0; i < 256; i++)
{
((u16 *)dst)[i] = LE_TO_LOCAL_16(((u16 *)src)[i]);
dst[i] = LE_TO_LOCAL_16(src[i]);
}
#else
memcpy (dst, src, 512);
memcpy(dst, src, 256 * sizeof(u16));
#endif
}
break;
case 3: // Display memory FIFO
case GPUDisplayMode_MainMemory: // Display memory FIFO
{
//this has not been tested since the dma timing for dispfifo was changed around the time of
//newemuloop. it may not work.
u8 * dst = GPU_screen + (screen->offset + l) * 512;
for (int i=0; i < 128; i++)
T1WriteLong(dst, i << 2, DISP_FIFOrecv() & 0x7FFF7FFF);
for (size_t i = 0; i < 128; i++)
T1WriteLong((u8 *)dst, i << 2, DISP_FIFOrecv() & 0x7FFF7FFF);
}
break;
}
@ -2613,7 +2647,6 @@ void GPU_RenderLine(NDS_Screen * screen, u16 l, bool skip)
if (l == 191) { disp_fifo.head = disp_fifo.tail = 0; }
}
GPU_RenderLine_MasterBrightness(screen, l);
}
@ -2622,7 +2655,7 @@ void gpu_savestate(EMUFILE* os)
//version
write32le(1,os);
os->fwrite((char*)GPU_screen,sizeof(GPU_screen));
os->fwrite((u8 *)GPU_screen, 256 * 192 * sizeof(u16) * 2);
write32le(MainScreen.gpu->affineInfo[0].x,os);
write32le(MainScreen.gpu->affineInfo[0].y,os);
@ -2651,11 +2684,11 @@ bool gpu_loadstate(EMUFILE* is, int size)
if(read32le(&version,is) != 1) return false;
if(version<0||version>1) return false;
if(version > 1) return false;
is->fread((char*)GPU_screen,sizeof(GPU_screen));
is->fread((u8 *)GPU_screen, 256 * 192 * sizeof(u16) * 2);
if(version==1)
if(version == 1)
{
read32le(&MainScreen.gpu->affineInfo[0].x,is);
read32le(&MainScreen.gpu->affineInfo[0].y,is);

View File

@ -583,6 +583,23 @@ enum BGType {
BGType_AffineExt=4, BGType_AffineExt_256x16=5, BGType_AffineExt_256x1=6, BGType_AffineExt_Direct=7
};
enum GPUDisplayMode
{
GPUDisplayMode_Off = 0,
GPUDisplayMode_Normal = 1,
GPUDisplayMode_VRAM = 2,
GPUDisplayMode_MainMemory = 3
};
enum GPUMasterBrightMode
{
GPUMasterBrightMode_Disable = 0,
GPUMasterBrightMode_Up = 1,
GPUMasterBrightMode_Down = 2,
GPUMasterBrightMode_Reserved = 3
};
extern const BGType GPU_mode2type[8][4];
struct GPU
@ -636,7 +653,7 @@ struct GPU
u8 core;
u8 dispMode;
GPUDisplayMode dispMode;
u8 vramBlock;
u8 *VRAMaddr;
@ -685,9 +702,9 @@ struct GPU
bool blend2[8];
CACHE_ALIGN u16 tempScanlineBuffer[256];
u8 *tempScanline;
u16 *tempScanline;
u8 MasterBrightMode;
GPUMasterBrightMode MasterBrightMode;
u32 MasterBrightFactor;
CACHE_ALIGN u8 bgPixels[1024]; //yes indeed, this is oversized. map debug tools try to write to it
@ -695,10 +712,7 @@ struct GPU
u32 currLine;
u8 currBgNum;
bool blend1;
u8* currDst;
FragmentColor *_3dColorLine;
u16 *currDst;
static struct MosaicLookup {
@ -728,7 +742,7 @@ struct GPU
FORCEINLINE FASTCALL bool _master_setFinalBGColor(u16 &color, const u32 x);
template<BlendFunc FUNC, bool WINDOW>
FORCEINLINE FASTCALL void _master_setFinal3dColor(int dstX, int srcX);
FORCEINLINE FASTCALL void _master_setFinal3dColor(int dstX, const FragmentColor src);
int setFinalColorBck_funcNum;
int bgFunc;
@ -751,7 +765,7 @@ struct GPU
}
void setFinalColor3d(int dstX, int srcX);
void setFinalColor3d(int dstX, const FragmentColor src);
template<bool BACKDROP, int FUNCNUM> void setFinalColorBG(u16 color, const u32 x);
template<bool MOSAIC, bool BACKDROP> FORCEINLINE void __setFinalColorBck(u16 color, const u32 x, const int opaque);
@ -824,12 +838,14 @@ static void REG_DISPx_pack_test(GPU * gpu)
}
#endif
CACHE_ALIGN extern u8 GPU_screen[4*256*192];
extern u16 *GPU_screen;
GPU * GPU_Init(u8 l);
void GPU_Reset(GPU *g, u8 l);
void GPU_DeInit(GPU *);
size_t GPU_GetFramebufferWidth();
size_t GPU_GetFramebufferHeight();
void GPU_SetFramebufferSize(size_t w, size_t h);
//these are functions used by debug tools which want to render layers etc outside the context of the emulation
namespace GPU_EXT

View File

@ -161,8 +161,6 @@ int NDS_Init()
NDS_RunAdvansceneAutoImport();
}
gfx3d_init();
armcpu_new(&NDS_ARM9,0);
NDS_ARM9.SetBaseMemoryInterface(&arm9_base_memory_iface);
NDS_ARM9.SetBaseMemoryInterfaceData(NULL);
@ -190,8 +188,6 @@ void NDS_DeInit(void)
SPU_DeInit();
Screen_DeInit();
MMU_DeInit();
gfx3d_deinit();
WIFI_DeInit();
delete cheats;

View File

@ -72,6 +72,7 @@ void ENDGL()
bool (*oglrender_init)() = NULL;
bool (*oglrender_beginOpenGL)() = NULL;
void (*oglrender_endOpenGL)() = NULL;
bool (*oglrender_framebufferDidResizeCallback)(size_t w, size_t h) = NULL;
void (*OGLLoadEntryPoints_3_2_Func)() = NULL;
void (*OGLCreateRenderer_3_2_Func)(OpenGLRenderer **rendererPtr) = NULL;
@ -884,7 +885,7 @@ void OpenGLRenderer::SetVersion(unsigned int major, unsigned int minor, unsigned
this->versionRevision = revision;
}
Render3DError OpenGLRenderer::FlushFramebuffer(FragmentColor *dstBuffer)
Render3DError OpenGLRenderer::FlushFramebuffer(FragmentColor *dstRGBA6665, u16 *dstRGBA5551)
{
// Convert from 32-bit BGRA8888 format to 32-bit RGBA6665 reversed format. OpenGL
// stores pixels using a flipped Y-coordinate, so this needs to be flipped back
@ -896,10 +897,17 @@ Render3DError OpenGLRenderer::FlushFramebuffer(FragmentColor *dstBuffer)
// Use the correct endian format since OpenGL uses the native endian of
// the architecture it is running on.
#ifdef WORDS_BIGENDIAN
dstBuffer[iw].color = BGRA8888_32_To_RGBA6665_32(this->_framebufferColor[ir].color);
dstRGBA6665[iw].color = BGRA8888_32_To_RGBA6665_32(this->_framebufferColor[ir].color);
dstRGBA5551[iw] = R5G5B5TORGB15((this->_framebufferColor[ir].b >> 3) & 0x1F,
(this->_framebufferColor[ir].g >> 3) & 0x1F,
(this->_framebufferColor[ir].r >> 3) & 0x1F) |
((this->_framebufferColor[ir].a == 0) ? 0x0000 : 0x8000);
#else
dstBuffer[iw].color = BGRA8888_32Rev_To_RGBA6665_32Rev(this->_framebufferColor[ir].color);
dstRGBA6665[iw].color = BGRA8888_32Rev_To_RGBA6665_32Rev(this->_framebufferColor[ir].color);
dstRGBA5551[iw] = R5G5B5TORGB15((this->_framebufferColor[ir].b >> 3) & 0x1F,
(this->_framebufferColor[ir].g >> 3) & 0x1F,
(this->_framebufferColor[ir].r >> 3) & 0x1F) |
((this->_framebufferColor[ir].a == 0) ? 0x0000 : 0x8000);
#endif
}
}
@ -1405,7 +1413,7 @@ Render3DError OpenGLRenderer_1_2::CreateFBOs()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_NONE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8_EXT, GFX3D_FRAMEBUFFER_WIDTH, GFX3D_FRAMEBUFFER_HEIGHT, 0, GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT, NULL);
glBindTexture(GL_TEXTURE_2D, OGLRef.texCIDepthID);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
@ -2682,7 +2690,7 @@ Render3DError OpenGLRenderer_1_2::RenderFinish()
ENDGL();
this->FlushFramebuffer(gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_colorRGBA6665, gfx3d_colorRGBA5551);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;
@ -2702,6 +2710,11 @@ Render3DError OpenGLRenderer_1_2::SetFramebufferSize(size_t w, size_t h)
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
if (oglrender_framebufferDidResizeCallback != NULL)
{
oglrender_framebufferDidResizeCallback(w, h);
}
if (this->isFBOSupported)
{
glActiveTextureARB(GL_TEXTURE0_ARB + OGLTextureUnitID_GColor);
@ -2839,6 +2852,11 @@ Render3DError OpenGLRenderer_1_3::SetFramebufferSize(size_t w, size_t h)
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
if (oglrender_framebufferDidResizeCallback != NULL)
{
oglrender_framebufferDidResizeCallback(w, h);
}
if (this->isFBOSupported)
{
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
@ -3211,7 +3229,7 @@ Render3DError OpenGLRenderer_1_5::RenderFinish()
ENDGL();
this->FlushFramebuffer(gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_colorRGBA6665, gfx3d_colorRGBA5551);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;
@ -3994,7 +4012,7 @@ Render3DError OpenGLRenderer_2_1::RenderFinish()
ENDGL();
this->FlushFramebuffer(gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_colorRGBA6665, gfx3d_colorRGBA5551);
this->_pixelReadNeedsFinish = false;
return OGLERROR_NOERR;

View File

@ -531,6 +531,9 @@ extern bool (*oglrender_beginOpenGL)();
//This is called by OGLRender after it is done using opengl.
extern void (*oglrender_endOpenGL)();
//This is called by OGLRender whenever the framebuffer is resized.
extern bool (*oglrender_framebufferDidResizeCallback)(size_t w, size_t h);
// Helper functions for calling the above function pointers at the
// beginning and ending of OpenGL commands.
bool BEGINGL();
@ -575,7 +578,7 @@ protected:
bool _pixelReadNeedsFinish;
size_t _currentPolyIndex;
Render3DError FlushFramebuffer(FragmentColor *dstBuffer);
Render3DError FlushFramebuffer(FragmentColor *dstRGBA6665, u16 *dstRGBA5551);
// OpenGL-specific methods
virtual Render3DError CreateVBOs() = 0;

View File

@ -1564,6 +1564,11 @@ Render3DError OpenGLRenderer_3_2::SetFramebufferSize(size_t w, size_t h)
this->_framebufferColorSizeBytes = w * h * sizeof(FragmentColor);
this->_framebufferColor = (FragmentColor *)realloc(this->_framebufferColor, this->_framebufferColorSizeBytes);
if (oglrender_framebufferDidResizeCallback != NULL)
{
oglrender_framebufferDidResizeCallback(w, h);
}
glActiveTexture(GL_TEXTURE0 + OGLTextureUnitID_GColor);
glBindTexture(GL_TEXTURE_2D, OGLRef.texGDepthStencilID);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, w, h, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, NULL);

View File

@ -310,7 +310,8 @@ static float normalTable[1024];
#define fix10_2float(v) (((float)((s32)(v))) / (float)(1<<9))
// Color buffer that is filled by the 3D renderer and is read by the GPU engine.
FragmentColor *gfx3d_convertedScreen = NULL;
FragmentColor *gfx3d_colorRGBA6665 = NULL;
u16 *gfx3d_colorRGBA5551 = NULL;
static size_t gfx3d_framebufferWidth = GFX3D_FRAMEBUFFER_WIDTH;
static size_t gfx3d_framebufferHeight = GFX3D_FRAMEBUFFER_HEIGHT;
@ -565,8 +566,11 @@ void gfx3d_deinit()
vertlists = NULL;
vertlist = NULL;
free(gfx3d_convertedScreen);
gfx3d_convertedScreen = NULL;
free(gfx3d_colorRGBA6665);
gfx3d_colorRGBA6665 = NULL;
free(gfx3d_colorRGBA5551);
gfx3d_colorRGBA5551 = NULL;
}
void gfx3d_reset()
@ -641,7 +645,8 @@ void gfx3d_reset()
last_s = 0;
viewport = 0xBFFF0000;
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(FragmentColor)));
memset(gfx3d_colorRGBA6665, 0, gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(FragmentColor));
memset(gfx3d_colorRGBA5551, 0, gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(u16));
gfx3d.state.clearDepth = DS_DEPTH15TO24(0x7FFF);
@ -673,14 +678,15 @@ void gfx3d_setFramebufferSize(size_t w, size_t h)
// Check if we're calling this function from initialization.
// If we're not initializing, we need to finish rendering first.
if (gfx3d_convertedScreen != NULL)
if (gfx3d_colorRGBA6665 != NULL && gfx3d_colorRGBA5551 != NULL)
{
CurrentRenderer->RenderFinish();
}
gfx3d_framebufferWidth = w;
gfx3d_framebufferHeight = h;
gfx3d_convertedScreen = (FragmentColor *)realloc(gfx3d_convertedScreen, w * h * sizeof(FragmentColor));
gfx3d_colorRGBA6665 = (FragmentColor *)realloc(gfx3d_colorRGBA6665, w * h * sizeof(FragmentColor));
gfx3d_colorRGBA5551 = (u16 *)realloc(gfx3d_colorRGBA5551, w * h * sizeof(u16));
CurrentRenderer->SetFramebufferSize(w, h);
}
@ -2345,7 +2351,7 @@ void gfx3d_VBlankEndSignal(bool skipFrame)
if (!CommonSettings.showGpu.main)
{
memset(gfx3d_convertedScreen, 0, sizeof(gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(FragmentColor)));
memset(gfx3d_colorRGBA6665, 0, sizeof(gfx3d_framebufferWidth * gfx3d_framebufferHeight * sizeof(FragmentColor)));
return;
}
@ -2457,24 +2463,16 @@ void gfx3d_glGetLightColor(const size_t index, u32 &dst)
dst = lightColor[index];
}
void gfx3d_GetLineData(const size_t line, FragmentColor **dst)
const FragmentColor* gfx3d_GetLineDataRGBA6665(const size_t line)
{
CurrentRenderer->RenderFinish();
*dst = gfx3d_convertedScreen + (line * gfx3d_framebufferWidth);
return (gfx3d_colorRGBA6665 + (line * gfx3d_framebufferWidth));
}
void gfx3d_GetLineData15bpp(const size_t line, u16 **dst)
const u16* gfx3d_GetLineDataRGBA5551(const size_t line)
{
//TODO - this is not very thread safe!!!
static u16 buf[GFX3D_FRAMEBUFFER_WIDTH];
*dst = buf;
FragmentColor *lineData;
gfx3d_GetLineData(line, &lineData);
for (size_t i = 0; i < GFX3D_FRAMEBUFFER_WIDTH; i++)
{
buf[i] = R6G6B6TORGB15(lineData[i].r, lineData[i].g, lineData[i].b) | ((lineData[i].a == 0) ? 0x0000 : 0x8000);
}
CurrentRenderer->RenderFinish();
return (gfx3d_colorRGBA5551 + (line * gfx3d_framebufferWidth));
}
@ -2564,7 +2562,7 @@ SFORMAT SF_GFX3D[]={
{ "GTVC", 4, 1, &tempVertInfo.count},
{ "GTVM", 4, 4, tempVertInfo.map},
{ "GTVF", 4, 1, &tempVertInfo.first},
{ "G3CX", 1, 4*GFX3D_FRAMEBUFFER_WIDTH*GFX3D_FRAMEBUFFER_HEIGHT, gfx3d_convertedScreen},
{ "G3CX", 1, 4*GFX3D_FRAMEBUFFER_WIDTH*GFX3D_FRAMEBUFFER_HEIGHT, gfx3d_colorRGBA6665},
{ 0 }
};

View File

@ -750,7 +750,8 @@ extern CACHE_ALIGN const u8 material_3bit_to_8bit[8];
//these contain the 3d framebuffer converted into the most useful format
//they are stored here instead of in the renderers in order to consolidate the buffers
extern FragmentColor *gfx3d_convertedScreen;
extern FragmentColor *gfx3d_colorRGBA6665;
extern u16 *gfx3d_colorRGBA5551;
extern BOOL isSwapBuffers;
int _hack_getMatrixStackLevel(int);
@ -783,8 +784,8 @@ void gfx3d_glGetMatrix(const MatrixMode mode, int index, float *dst);
void gfx3d_glGetLightDirection(const size_t index, u32 &dst);
void gfx3d_glGetLightColor(const size_t index, u32 &dst);
void gfx3d_GetLineData(const size_t line, FragmentColor **dst);
void gfx3d_GetLineData15bpp(const size_t line, u16 **dst);
const FragmentColor* gfx3d_GetLineDataRGBA6665(const size_t line);
const u16* gfx3d_GetLineDataRGBA5551(const size_t line);
struct SFORMAT;
extern SFORMAT SF_GFX3D[];

View File

@ -2228,7 +2228,7 @@ public:
char temp [256];
sprintf(temp, " " /*"mismatch at "*/ "byte %d(0x%X at 0x%X): %d(0x%X) != %d(0x%X)\n", i, i, dst, *src,*src, *dst,*dst);
if(ptr == GPU_screen || ptr == gfx3d_convertedScreen) // ignore screen-only differences since frame skipping can cause them and it's probably ok
if(ptr == GPU_screen || ptr == gfx3d_colorRGBA6665) // ignore screen-only differences since frame skipping can cause them and it's probably ok
break;
differences.push_back(temp); // <-- probably the best place for a breakpoint

View File

@ -712,6 +712,7 @@ public:
float u = pLeft->u.curr;
float v = pLeft->v.curr;
float z = pLeft->z.curr;
float color[3] = {
pLeft->color[0].curr,
pLeft->color[1].curr,
@ -1961,7 +1962,7 @@ Render3DError SoftRasterizerRenderer::EndRender(const u64 frameCount)
this->RenderEdgeMarkingAndFog(this->postprocessParam[0]);
}
this->FlushFramebuffer(gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_colorRGBA6665, gfx3d_colorRGBA5551);
}
return RENDER3DERROR_NOERR;
@ -2001,7 +2002,7 @@ Render3DError SoftRasterizerRenderer::RenderFinish()
}
}
this->FlushFramebuffer(gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_colorRGBA6665, gfx3d_colorRGBA5551);
return RENDER3DERROR_NOERR;
}

View File

@ -210,9 +210,15 @@ Render3DError Render3D::EndRender(const u64 frameCount)
return RENDER3DERROR_NOERR;
}
Render3DError Render3D::FlushFramebuffer(FragmentColor *dstBuffer)
Render3DError Render3D::FlushFramebuffer(FragmentColor *dstRGBA6665, u16 *dstRGBA5551)
{
memcpy(dstBuffer, this->_framebufferColor, this->_framebufferColorSizeBytes);
memcpy(dstRGBA6665, this->_framebufferColor, this->_framebufferColorSizeBytes);
for (size_t i = 0; i < (this->_framebufferWidth * this->_framebufferHeight); i++)
{
dstRGBA5551[i] = R6G6B6TORGB15(this->_framebufferColor[i].r, this->_framebufferColor[i].g, this->_framebufferColor[i].b) | ((this->_framebufferColor[i].a == 0) ? 0x0000 : 0x8000);
}
return RENDER3DERROR_NOERR;
}
@ -369,7 +375,7 @@ Render3DError Render3D::Render(const GFX3D &engine)
Render3DError Render3D::RenderFinish()
{
this->FlushFramebuffer(gfx3d_convertedScreen);
this->FlushFramebuffer(gfx3d_colorRGBA6665, gfx3d_colorRGBA5551);
return RENDER3DERROR_NOERR;
}

View File

@ -102,7 +102,7 @@ protected:
virtual Render3DError RenderEdgeMarking(const u16 *colorTable, const bool useAntialias);
virtual Render3DError RenderFog(const u8 *densityTable, const u32 color, const u32 offset, const u8 shift, const bool alphaOnly);
virtual Render3DError EndRender(const u64 frameCount);
virtual Render3DError FlushFramebuffer(FragmentColor *dstBuffer);
virtual Render3DError FlushFramebuffer(FragmentColor *dstRGBA6665, u16 *dstRGBA5551);
virtual Render3DError ClearUsingImage(const u16 *__restrict colorBuffer, const u32 *__restrict depthBuffer, const bool *__restrict fogBuffer, const u8 *__restrict polyIDBuffer);
virtual Render3DError ClearUsingValues(const FragmentColor &clearColor, const FragmentAttributes &clearAttributes) const;