parent
1648b5f74d
commit
12342e21cc
|
@ -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");
|
||||
|
@ -1873,15 +1875,16 @@ 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; }
|
||||
osd = new OSDCLASS(-1);
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
@ -2037,7 +2075,7 @@ PLAIN_CLEAR:
|
|||
gpu->spriteRender(spr, sprAlpha, sprType, sprPrio);
|
||||
mosaicSpriteLine(gpu, l, spr, sprAlpha, sprType, sprPrio);
|
||||
|
||||
for(int i = 0; i<256; i++)
|
||||
for(int i = 0; i<256; i++)
|
||||
{
|
||||
// assign them to the good priority item
|
||||
int prio = sprPrio[i];
|
||||
|
@ -2083,20 +2121,18 @@ 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,42 +2311,43 @@ 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);
|
||||
r = ((srcA[i] & 0x1F) * gpu->dispCapCnt.EVA);
|
||||
g = (((srcA[i] >> 5) & 0x1F) * gpu->dispCapCnt.EVA);
|
||||
b = (((srcA[i] >> 10) & 0x1F) * gpu->dispCapCnt.EVA);
|
||||
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);
|
||||
r += ((srcB[i] & 0x1F) * gpu->dispCapCnt.EVB);
|
||||
g += (((srcB[i] >> 5) & 0x1F) * gpu->dispCapCnt.EVB);
|
||||
b += (((srcB[i] >> 10) & 0x1F) * gpu->dispCapCnt.EVB);
|
||||
}
|
||||
|
||||
|
||||
r >>= 4;
|
||||
g >>= 4;
|
||||
b >>= 4;
|
||||
|
||||
|
||||
//freedom wings sky will overflow while doing some fsaa/motionblur effect without this
|
||||
r = std::min((u16)31,r);
|
||||
g = std::min((u16)31,g);
|
||||
b = std::min((u16)31,b);
|
||||
|
||||
|
||||
HostWriteWord(cap_dst, i << 1, a | (b << 10) | (g << 5) | r);
|
||||
}
|
||||
}
|
||||
|
@ -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,56 +2587,56 @@ 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;
|
||||
}
|
||||
|
||||
|
||||
//capture after displaying so that we can safely display vram before overwriting it here
|
||||
if (gpu->core == GPU_MAIN)
|
||||
{
|
||||
|
@ -2612,8 +2646,7 @@ void GPU_RenderLine(NDS_Screen * screen, u16 l, bool skip)
|
|||
GPU_RenderLine_DispCapture<false>(l);
|
||||
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);
|
||||
|
|
|
@ -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,11 +712,8 @@ struct GPU
|
|||
u32 currLine;
|
||||
u8 currBgNum;
|
||||
bool blend1;
|
||||
u8* currDst;
|
||||
|
||||
FragmentColor *_3dColorLine;
|
||||
|
||||
|
||||
u16 *currDst;
|
||||
|
||||
static struct MosaicLookup {
|
||||
|
||||
struct TableEntry {
|
||||
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
||||
|
|
|
@ -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[];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -712,11 +712,12 @@ 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,
|
||||
pLeft->color[2].curr };
|
||||
|
||||
|
||||
//our dx values are taken from the steps up until the right edge
|
||||
float invWidth = 1.0f / width;
|
||||
float dinvw_dx = (pRight->invw.curr - invw) * invWidth;
|
||||
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue